feat(ui): responsive layout for mobile and wide screens
- Add explicit viewport meta (device-width) for proper mobile scaling. - Widen the main container (720 -> 960, 1120 on >=1280px) with fluid clamp() padding so wide screens are used better. - Wrap the top nav and allow it to reflow on narrow screens. - Collapse the key/value grid to a single column and enlarge touch targets on small screens. - Keep single-form pages (login/signup/activate) in a readable narrow column instead of stretching full width.
This commit is contained in:
@@ -24,7 +24,7 @@ export default async function ActivatePage({
|
|||||||
.maybeSingle<{ subdomain: string }>();
|
.maybeSingle<{ subdomain: string }>();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="form-card">
|
||||||
<h1>Activate device</h1>
|
<h1>Activate device</h1>
|
||||||
<p className="muted">
|
<p className="muted">
|
||||||
Enter the code shown by your Home Assistant add-on to pair it with your
|
Enter the code shown by your Home Assistant add-on to pair it with your
|
||||||
|
|||||||
+56
-3
@@ -40,9 +40,22 @@ a:hover {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
max-width: 720px;
|
width: 100%;
|
||||||
|
max-width: 960px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 2rem 1rem;
|
padding: 2rem clamp(1rem, 4vw, 2.5rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Narrow column for single-form pages (login/signup/activate) that read
|
||||||
|
better when not stretched across a wide screen. */
|
||||||
|
.container.narrow {
|
||||||
|
max-width: 480px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1280px) {
|
||||||
|
.container {
|
||||||
|
max-width: 1120px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.stack {
|
.stack {
|
||||||
@@ -55,7 +68,9 @@ a:hover {
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 1rem;
|
gap: 0.75rem 1rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
padding: 0.85rem clamp(1rem, 4vw, 2.5rem);
|
||||||
border-bottom: 1px solid var(--border);
|
border-bottom: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,6 +82,14 @@ a:hover {
|
|||||||
margin: 1rem 0;
|
margin: 1rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Single-form cards (login / signup / activate) stay readable instead of
|
||||||
|
stretching across a wide screen. */
|
||||||
|
.form-card {
|
||||||
|
max-width: 460px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
h1,
|
h1,
|
||||||
h2,
|
h2,
|
||||||
h3 {
|
h3 {
|
||||||
@@ -170,6 +193,36 @@ button.secondary,
|
|||||||
display: flex;
|
display: flex;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
|
/* Mobile / small-screen refinements */
|
||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
|
@media (max-width: 520px) {
|
||||||
|
.kv {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
gap: 0.15rem 0;
|
||||||
|
}
|
||||||
|
.kv .k {
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
}
|
||||||
|
.card {
|
||||||
|
padding: 1.15rem;
|
||||||
|
}
|
||||||
|
/* Larger touch targets on touch devices. */
|
||||||
|
button,
|
||||||
|
.btn,
|
||||||
|
input[type='text'],
|
||||||
|
input[type='email'],
|
||||||
|
input[type='password'],
|
||||||
|
select {
|
||||||
|
min-height: 44px;
|
||||||
|
}
|
||||||
|
.nav button,
|
||||||
|
.nav .btn {
|
||||||
|
padding: 0.5rem 0.8rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|||||||
+6
-1
@@ -1,4 +1,4 @@
|
|||||||
import type { Metadata } from 'next';
|
import type { Metadata, Viewport } from 'next';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import './globals.css';
|
import './globals.css';
|
||||||
import { createSupabaseServerClient } from '@/lib/supabase/server';
|
import { createSupabaseServerClient } from '@/lib/supabase/server';
|
||||||
@@ -8,6 +8,11 @@ export const metadata: Metadata = {
|
|||||||
description: 'Remote access tunnels for Home Assistant',
|
description: 'Remote access tunnels for Home Assistant',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const viewport: Viewport = {
|
||||||
|
width: 'device-width',
|
||||||
|
initialScale: 1,
|
||||||
|
};
|
||||||
|
|
||||||
export const dynamic = 'force-dynamic';
|
export const dynamic = 'force-dynamic';
|
||||||
|
|
||||||
export default async function RootLayout({
|
export default async function RootLayout({
|
||||||
|
|||||||
+1
-1
@@ -85,7 +85,7 @@ export default function LoginPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="card">
|
<div className="card form-card">
|
||||||
<h1>Login</h1>
|
<h1>Login</h1>
|
||||||
<form onSubmit={onSubmit}>
|
<form onSubmit={onSubmit}>
|
||||||
<label htmlFor="email">Email</label>
|
<label htmlFor="email">Email</label>
|
||||||
|
|||||||
+2
-2
@@ -77,7 +77,7 @@ export default function SignupPage() {
|
|||||||
|
|
||||||
if (submitted) {
|
if (submitted) {
|
||||||
return (
|
return (
|
||||||
<div className="card">
|
<div className="card form-card">
|
||||||
<h1>Check your email</h1>
|
<h1>Check your email</h1>
|
||||||
<p>
|
<p>
|
||||||
We sent a confirmation link to <strong>{email}</strong>. Click the
|
We sent a confirmation link to <strong>{email}</strong>. Click the
|
||||||
@@ -106,7 +106,7 @@ export default function SignupPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="card">
|
<div className="card form-card">
|
||||||
<h1>Sign up</h1>
|
<h1>Sign up</h1>
|
||||||
<form onSubmit={onSubmit}>
|
<form onSubmit={onSubmit}>
|
||||||
<label htmlFor="email">Email</label>
|
<label htmlFor="email">Email</label>
|
||||||
|
|||||||
Reference in New Issue
Block a user