From 29f655aacd7ee8f1b2843adf9eac6ea747b0bd53 Mon Sep 17 00:00:00 2001 From: Ilia Denisov Date: Thu, 11 Jun 2026 15:37:06 +0200 Subject: [PATCH] UI: tg-fullscreen header gap +10px (was +20) + font-scale regression test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The +20px gap was too far; use +10px (padding-top safe-top+16). The gap is fixed px, so the clearance from Telegram's native nav stays constant when the user scales the font up — the title grows downward and the bar with it, no overflow. Locked by a new e2e test that asserts the title top is unchanged across font sizes and never overflows the bar. --- ui/e2e/telegram.spec.ts | 31 +++++++++++++++++++++++++++++++ ui/src/components/Header.svelte | 6 ++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/ui/e2e/telegram.spec.ts b/ui/e2e/telegram.spec.ts index 0700bd2..8a1188a 100644 --- a/ui/e2e/telegram.spec.ts +++ b/ui/e2e/telegram.spec.ts @@ -35,6 +35,37 @@ test('Telegram launch auto-authenticates into the lobby and applies the theme', .toBe('#101418'); }); +test('tg-fullscreen header keeps a constant native-nav gap as the font scales', async ({ page }) => { + await page.goto('/'); + await page.getByRole('button', { name: /guest/i }).click(); + await expect(page.getByText('Your turn')).toBeVisible(); // the lobby header is present + settled + + // Emulate Telegram fullscreen: the class + safe-area vars our header positions against. + await page.evaluate(() => { + const h = document.documentElement; + h.classList.add('tg-fullscreen'); + h.style.setProperty('--tg-safe-top', '47px'); + h.style.setProperty('--tg-content-top', '50px'); + }); + const probe = () => + page.evaluate(() => { + const bar = document.querySelector('.bar')!.getBoundingClientRect(); + const h1 = document.querySelector('.bar h1')!.getBoundingClientRect(); + return { h1Top: Math.round(h1.top), overflows: h1.bottom > bar.bottom + 0.5 }; + }); + + const normal = await probe(); + // Scale the root font up (an OS / Telegram "larger text" setting scales rem-based text). + await page.evaluate(() => (document.documentElement.style.fontSize = '28px')); + const large = await probe(); + + // The gap to Telegram's native controls is a fixed px, so the title's top does not move… + expect(large.h1Top).toBe(normal.h1Top); + // …the title grows downward inside the bar (which grows with it), never overflowing it. + expect(normal.overflows).toBe(false); + expect(large.overflows).toBe(false); +}); + test('outside Telegram, the /telegram/ entry redirects to the site root', async ({ page }) => { await page.goto('/telegram/'); diff --git a/ui/src/components/Header.svelte b/ui/src/components/Header.svelte index 3467414..0e11a25 100644 --- a/ui/src/components/Header.svelte +++ b/ui/src/components/Header.svelte @@ -109,12 +109,14 @@ back chevron is hidden), so min-height (the nav-band height) doesn't bind. Without the (removed) hamburger that content shrank and the bar sat flush under Telegram's native nav band. So **padding-top** is the lever: it drops the title clear of the band — the notch - plus a **+20px** gap (was +6). (Owner-tunable: bump the +20px.) */ + plus a **10px** gap (was 6). A fixed px (not rem/em) gap so the clearance from Telegram's + native controls stays constant if the user scales up the font (the title then grows + downward and the bar with it). (Owner-tunable: the 10px.) */ min-height: var(--tg-content-top); box-sizing: border-box; align-items: center; justify-content: center; - padding-top: calc(var(--tg-safe-top) + 26px); + padding-top: calc(var(--tg-safe-top) + 16px); padding-bottom: 6px; } :global(html.tg-fullscreen) .spacer {