From 0fbabdad3172162397cdd742bd370b0b7046cc88 Mon Sep 17 00:00:00 2001 From: Gerhard Scheikl Date: Mon, 1 Jun 2026 21:06:18 +0200 Subject: [PATCH] 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. --- app/activate/page.tsx | 2 +- app/globals.css | 59 ++++++++++++++++++++++++++++++++++++++++--- app/layout.tsx | 7 ++++- app/login/page.tsx | 2 +- app/signup/page.tsx | 4 +-- 5 files changed, 66 insertions(+), 8 deletions(-) diff --git a/app/activate/page.tsx b/app/activate/page.tsx index bee60d6..b800edc 100644 --- a/app/activate/page.tsx +++ b/app/activate/page.tsx @@ -24,7 +24,7 @@ export default async function ActivatePage({ .maybeSingle<{ subdomain: string }>(); return ( -
+

Activate device

Enter the code shown by your Home Assistant add-on to pair it with your diff --git a/app/globals.css b/app/globals.css index bd6c665..8339d44 100644 --- a/app/globals.css +++ b/app/globals.css @@ -40,9 +40,22 @@ a:hover { } .container { - max-width: 720px; + width: 100%; + max-width: 960px; 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 { @@ -55,7 +68,9 @@ a:hover { display: flex; justify-content: space-between; 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); } @@ -67,6 +82,14 @@ a:hover { 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, h2, h3 { @@ -170,6 +193,36 @@ button.secondary, display: flex; gap: 0.5rem; 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; + } } /* ----------------------------------------------------------------------- */ diff --git a/app/layout.tsx b/app/layout.tsx index b9e8e6e..1686ef5 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,4 +1,4 @@ -import type { Metadata } from 'next'; +import type { Metadata, Viewport } from 'next'; import Link from 'next/link'; import './globals.css'; import { createSupabaseServerClient } from '@/lib/supabase/server'; @@ -8,6 +8,11 @@ export const metadata: Metadata = { description: 'Remote access tunnels for Home Assistant', }; +export const viewport: Viewport = { + width: 'device-width', + initialScale: 1, +}; + export const dynamic = 'force-dynamic'; export default async function RootLayout({ diff --git a/app/login/page.tsx b/app/login/page.tsx index e35cce7..b67eb42 100644 --- a/app/login/page.tsx +++ b/app/login/page.tsx @@ -85,7 +85,7 @@ export default function LoginPage() { } return ( -

+

Login

diff --git a/app/signup/page.tsx b/app/signup/page.tsx index f1c8019..2308efe 100644 --- a/app/signup/page.tsx +++ b/app/signup/page.tsx @@ -77,7 +77,7 @@ export default function SignupPage() { if (submitted) { return ( -
+

Check your email

We sent a confirmation link to {email}. Click the @@ -106,7 +106,7 @@ export default function SignupPage() { } return ( -

+

Sign up