Skip to content

Layout Audit — non-Chromium Browser Compatibility

Temporary audit document — supports the planning report at ../non-chromium-browser-compatibility-analysis.md. Delete once findings are tracked in tickets.

Focused investigation triggered by the user-reported bug: "On the home page's What's New section, dates overlap / spill on Safari and Firefox while rendering correctly on Chrome."

This audit drills into that bug, identifies the root cause, then sweeps the rest of the codebase for the same anti-pattern. All file paths are relative to src/services/web/.

Summary

  • Total findings: 2 (1 confirmed bug, 1 latent risk).
  • Severity: 1 major / 1 minor.
  • Browsers affected: Safari, Firefox.
  • Bug is isolated to one componentwhats-new is the only place in the whole web codebase that combines the offending pattern.

Findings

LAYOUT.F1 — Fixed-rem date column overflows into title on Safari and Firefox (the user-reported bug)

Symptom

In the "Earlier releases" timeline, each row has the structure <marker> <date> <title> <toggle>. On Chrome the date sits in its own column and the title sits in the next column. On Safari and Firefox the date text overflows its column rightwards and visually overlaps the start of the title, producing the "dates overlapping/spilling" symptom.

The bug is most pronounced for the longer dates in the feed (e.g. "28th February 2026", "14th September 2022") and least pronounced for the short ones ("2nd November 2023").

Cause

Three CSS choices combine to produce a metric-sensitive layout that Chromium renders narrowly enough to fit but Safari and Firefox don't:

  1. Fixed-width grid track for the date column. The summary's grid template at line 222 is:

    grid-template-columns: auto 7.5rem 1fr auto;
    //                          ^^^^^^^ <-- the date column, exactly 7.5rem
    

    7.5rem120px at default rem size. The longest date strings in whats-new.json are 17–19 characters ("28th February 2026", "14th September 2022").

  2. white-space: nowrap on .whats-new__past-date (line 292). With nowrap, the text cannot break to fit; it must overflow the cell when it doesn't fit on one line.

  3. font-variant-numeric: tabular-nums (line 287) plus font-feature-settings: 'ss01' 1 on the .whats-new container (line 29). These cause cross-browser glyph-width drift:

    • Roboto's tabular-nums glyphs are slightly wider than its default proportional digits. Browsers that fall back to a different font during FOUT (Helvetica on Safari, DejaVu Sans on Linux Firefox, Arial on Windows Firefox) produce much wider tabular digits.
    • 'ss01' is a Roboto Flex stylistic-set feature; the regular Roboto loaded by index.html:29 does not implement it. Chromium silently ignores unknown features without recomputing metrics; Safari and Firefox can shift glyph metrics by ~1–2 px per character when a feature is requested but absent. Over an 18-character date string that is enough to push past 120 px.
    • Roboto is loaded with display=swap (line 29 of index.html), so the fallback is shown then swapped. If a user expands a <details> during the swap window, layout is computed against the wider fallback metrics.

The result is that on Chrome, "28th February 2026" renders at ~115 px and just fits the 120 px column. On Safari it renders at ~125–130 px and overflows ~5–10 px into the title column.

There is also a latent contributing risk in the same template:

  1. The 1fr title track has no min-width: 0. Browsers default grid items to min-width: auto, which equals min-content (the longest unbreakable word). If a release title contains a long unbreakable token, the 1fr track can refuse to shrink. This doesn't cause today's bug (titles are short prose) but means any future long title would bleed into the toggle column. Same root concern as the :has() Issue F4 in the CSS audit — Safari and Firefox handle min-content sizing more strictly than Chrome.

Fix

Three coordinated changes — in the same file, all in one PR.

1. Replace the fixed date column with intrinsic sizing and let the title shrink.

// whats-new.component.scss:222
.whats-new__past-release > summary {
  display: grid;
-  grid-template-columns: auto 7.5rem 1fr auto;
+  // marker | date (sized to its content, capped) | title (allowed to shrink) | toggle
+  grid-template-columns: auto max-content minmax(0, 1fr) auto;
  // ...
}

max-content lets the date column expand to whatever the longest date in the feed actually needs, in each browser's rendering. minmax(0, 1fr) lets the title column shrink to 0 if necessary, so a long title cannot overflow the toggle column.

2. Defend the date itself against unforeseen content.

// whats-new.component.scss:286
.whats-new__past-date {
  font-variant-numeric: tabular-nums;
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--wn-ink-muted);
  white-space: nowrap;
+  // Safety net in case the editorial team writes a date longer than
+  // the design assumes; truncates with ellipsis instead of overlapping.
+  overflow: hidden;
+  text-overflow: ellipsis;
+  min-width: 0;
}

3. Drop the 'ss01' stylistic-set request that Roboto doesn't support.

// whats-new.component.scss:23
.whats-new {
  margin: clamp(2.75rem, 6vw, 4.5rem) 0 clamp(2.5rem, 5vw, 3.5rem);
  color: var(--wn-ink);
-
-  // Tabular numerals for the date and numeral columns. Real editorial
-  // typography trick  not the same thing as monospace.
-  font-feature-settings: 'ss01' 1;
}

The font-variant-numeric: tabular-nums on the date and numeral elements is the actual mechanism delivering the editorial effect; 'ss01' is doing nothing in regular Roboto and only contributing metric noise. Remove it.

Effort

Trivial — three small edits in one SCSS file. Recommended QA: spin up a preview deploy, open the home page on Safari (macOS) and Firefox (any platform), expand each release in the "Earlier releases" timeline, confirm dates sit cleanly in their column for every entry in whats-new.json. Also verify on a 720 px viewport (the responsive breakpoint at line 399) where the layout switches to a stacked grid-template-areas — that mode is unaffected and should still work.


  • File: src/app/info/home/whats-new/whats-new.component.scss:63-92.
  • Browsers: Safari, Firefox (more sensitive than Chromium to large-font-size column collapse).
  • Severity: minor — only affects narrow desktop / tablet-landscape viewports between 720 px (the mobile breakpoint) and roughly 900 px.

Symptom

The "Latest update" masthead at the top of the section uses a 2-column grid where the left column is the masthead (eyebrow text + the large date label) and the right column is the numbered highlights list:

// whats-new.component.scss:63-68
.whats-new__latest {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 2.6fr);
  gap: clamp(1.5rem, 4vw, 3.25rem);
  align-items: start;
}

The release-label uses a fluid-clamped font-size that maxes at 2.25rem (line 86). On viewports between 720 px (just above the mobile breakpoint) and ~900 px, the masthead column is roughly 220–280 px wide, and the date text ("28th February 2026" at 2.25 rem with letter-spacing -0.025em and tabular-nums) is around 280–310 px in Safari/Firefox. With minmax(0, 1fr) the column is allowed to shrink and the date text overflows into the highlights column.

Chrome shrinks the same date text marginally tighter and usually clears the column boundary. Safari and Firefox tend to overlap.

Fix

Either let the label wrap (currently it is treated as a heading-style block), or constrain the font-size to fit the column width. The simplest fix is to allow it to wrap:

// whats-new.component.scss:84
.whats-new__release-label {
  margin: 0;
  font-size: clamp(1.625rem, 3.2vw, 2.25rem);
  font-weight: 800;
  letter-spacing: -0.025em;
  line-height: 1.05;
  color: var(--wn-ink-muted);
  font-variant-numeric: tabular-nums;
+  overflow-wrap: anywhere;
}

Or push the responsive breakpoint up from 720 px to ~900 px so the column-collapse to a single column happens earlier. Less surgical, broader implication for the design.

Effort

Trivial — one line. QA: open Safari, set viewport to 768 px (iPad portrait) and 820 px (iPad mini portrait); confirm date sits inside its column.


Sweep — same anti-pattern elsewhere?

Searched for the combination that produced LAYOUT.F1: fixed-rem grid columns, white-space: nowrap, font-variant-numeric: tabular-nums. Results:

  • grid-template-columns: with a fixed rem track — exactly one occurrence anywhere in the codebase: the bug above. All other grid templates use auto, 1fr, min-content, max-content, or minmax(0, 1fr). Good.
  • white-space: nowrap — 8 occurrences, of which 4 are in legacy Bootstrap button styles (no flex/grid context), 1 is the bug above, 1 is in the impersonation admin chip, 1 in a select form-control, and 1 in project-options. None of those latter three are inside a fixed-width parent track, so they will not exhibit the same overflow.
  • font-variant-numeric: tabular-nums — 3 occurrences, all in the whats-new component. No other surface forces tabular numerals.

Conclusion: the bug is isolated. No further audit-wide changes needed beyond the two findings above.

The architectural lesson is preserved in the existing CSS audit: prefer min-content / max-content / minmax(0, 1fr) for grid tracks and reserve fixed rem widths for chrome (icons, indicators) where the content is genuinely fixed-width.