From 490444032c53d8f4acb492765d92698d12728ee4 Mon Sep 17 00:00:00 2001 From: Felix Klement Date: Mon, 5 Oct 2026 10:33:58 +0200 Subject: [PATCH] Fix mobile --- src/components/Header.astro | 7 +++++-- src/components/home/Hero.astro | 2 +- src/components/home/Stages.astro | 2 +- src/components/team/Research.astro | 2 +- src/components/verifier/SoonHero.astro | 4 ++-- src/layouts/Base.astro | 6 ++++-- src/styles/base.css | 5 +++-- src/styles/tokens.css | 7 +++++++ 8 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/components/Header.astro b/src/components/Header.astro index 6e59927..5c94cca 100644 --- a/src/components/Header.astro +++ b/src/components/Header.astro @@ -56,7 +56,7 @@ const isCurrent = (href: string) => href.split('#')[0] === path && !href.include pointer-events: none; } .header__shell { - padding-block: var(--space-3); + padding-block: calc(var(--space-3) + var(--safe-top)) var(--space-3); transition: max-width var(--dur-slow) var(--ease), padding var(--dur-slow) var(--ease); @@ -68,8 +68,11 @@ const isCurrent = (href: string) => href.split('#')[0] === path && !href.include max-width: 100%; padding: 0; } + /* Docked, the glass also fills the status-bar strip, so scrolled content never shows behind the + clock; the bar's contents stay below it. */ .header[data-scrolled] .header__bar { - min-height: var(--header-height); + min-height: var(--header-offset); + padding-top: var(--safe-top); border-width: 0 0 var(--line); } .header[data-scrolled] .header__bar::after { content: none; } diff --git a/src/components/home/Hero.astro b/src/components/home/Hero.astro index 580a9e0..4d21ed8 100644 --- a/src/components/home/Hero.astro +++ b/src/components/home/Hero.astro @@ -48,7 +48,7 @@ const ui = t(lang); align-items: flex-end; /* Runs up under the floating header so the glass bar sits on the image, fills the screen, and is never less than the headline needs. */ - margin-top: calc(-1 * var(--header-height)); + margin-top: calc(-1 * var(--header-offset)); min-height: max(28rem, 100svh); overflow: hidden; } diff --git a/src/components/home/Stages.astro b/src/components/home/Stages.astro index 1fb6a93..361a652 100644 --- a/src/components/home/Stages.astro +++ b/src/components/home/Stages.astro @@ -35,7 +35,7 @@ const objects = ['sphere', 'cube', 'plane', 'wave'] as const; gap: var(--space-6); padding: var(--space-6) var(--space-6) var(--space-7); background: var(--paper-deep); - scroll-margin-top: calc(var(--header-height) + var(--space-5)); + scroll-margin-top: calc(var(--header-offset) + var(--space-5)); } .stages__title { font-size: var(--step-title); diff --git a/src/components/team/Research.astro b/src/components/team/Research.astro index 0c4be51..809baa8 100644 --- a/src/components/team/Research.astro +++ b/src/components/team/Research.astro @@ -216,7 +216,7 @@ const fieldStyle = (paper: (typeof papers)[number]) => gap: var(--space-4); } - .research__list { margin-top: var(--space-6); scroll-margin-top: calc(var(--header-height) + var(--space-5)); } + .research__list { margin-top: var(--space-6); scroll-margin-top: calc(var(--header-offset) + var(--space-5)); } .research__item[hidden] { display: none; } .paper__meta { diff --git a/src/components/verifier/SoonHero.astro b/src/components/verifier/SoonHero.astro index 8ca66f0..befe93d 100644 --- a/src/components/verifier/SoonHero.astro +++ b/src/components/verifier/SoonHero.astro @@ -98,7 +98,7 @@ const ridges = Array.from({ length: rows }, (_, r) => { .shero { position: relative; /* Runs up under the floating header, as the home hero does, so the bar takes the night tone. */ - margin-top: calc(-1 * var(--header-height)); + margin-top: calc(-1 * var(--header-offset)); overflow: hidden; } .shero__media { position: absolute; inset: 0; animation: shero-settle var(--dur-hero) var(--ease) both; transform-origin: 60% 50%; } @@ -121,7 +121,7 @@ const ridges = Array.from({ length: rows }, (_, r) => { position: relative; display: grid; gap: var(--space-8); - padding-top: calc(var(--header-height) + var(--space-7)); + padding-top: calc(var(--header-offset) + var(--space-7)); min-height: 100svh; align-content: end; } diff --git a/src/layouts/Base.astro b/src/layouts/Base.astro index 4466d44..e8331e0 100644 --- a/src/layouts/Base.astro +++ b/src/layouts/Base.astro @@ -28,12 +28,14 @@ const altDe = new URL(switchLang(Astro.url, 'de'), Astro.site); - + {fullTitle} {noindex && } - + + diff --git a/src/styles/base.css b/src/styles/base.css index 061fd8e..2e834cb 100644 --- a/src/styles/base.css +++ b/src/styles/base.css @@ -43,7 +43,7 @@ html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; } -[id] { scroll-margin-top: var(--header-height); } +[id] { scroll-margin-top: var(--header-offset); } body { min-height: 100dvh; background: var(--paper); @@ -146,7 +146,8 @@ p { overflow-wrap: break-word; } width: 100%; max-width: var(--container); margin-inline: auto; - padding-inline: var(--gutter); + padding-left: max(var(--gutter), var(--safe-left)); + padding-right: max(var(--gutter), var(--safe-right)); } .grid { display: grid; diff --git a/src/styles/tokens.css b/src/styles/tokens.css index 1021e97..e2e498d 100644 --- a/src/styles/tokens.css +++ b/src/styles/tokens.css @@ -137,6 +137,13 @@ /* Chrome */ --header-height: 4.5rem; + /* With viewport-fit=cover the page runs under the iOS status bar and notch; these are the + strips the system keeps for itself (zero everywhere else). */ + --safe-top: env(safe-area-inset-top, 0px); + --safe-left: env(safe-area-inset-left, 0px); + --safe-right: env(safe-area-inset-right, 0px); + /* What a full-bleed hero pulls up under: the header plus the status bar above it. */ + --header-offset: calc(var(--header-height) + var(--safe-top)); /* HUD frame (menu bar): one line width and colour for every line, borders and crosses alike. */ --hud-line-width: 1px;