fix(design): correct the font assertion (serif$ matched sans-serif) and make the Leaflet overrides win #88
@@ -722,9 +722,16 @@ test('the brand typefaces actually load and apply', async ({ page }) => {
|
||||
|
||||
const fonts = await page.evaluate(() => {
|
||||
const root = getComputedStyle(document.documentElement);
|
||||
// Only the FIRST family in the stack is the one actually asked for; the
|
||||
// rest are fallbacks and always end in a generic like sans-serif.
|
||||
const first = (el: Element) =>
|
||||
getComputedStyle(el).fontFamily.split(',')[0].replace(/["']/g, '').trim();
|
||||
const prose = document.querySelector('[class*="editorialText"] p');
|
||||
return {
|
||||
body: getComputedStyle(document.body).fontFamily,
|
||||
heading: getComputedStyle(document.querySelector('h1')!).fontFamily,
|
||||
body: first(document.body),
|
||||
heading: first(document.querySelector('h1')!),
|
||||
prose: prose ? first(prose) : null,
|
||||
bodyStack: getComputedStyle(document.body).fontFamily,
|
||||
displayToken: root.getPropertyValue('--font-display').trim(),
|
||||
uiToken: root.getPropertyValue('--font-ui').trim(),
|
||||
proseToken: root.getPropertyValue('--font-prose').trim(),
|
||||
@@ -732,15 +739,22 @@ test('the brand typefaces actually load and apply', async ({ page }) => {
|
||||
});
|
||||
|
||||
// An empty token means the var() chain broke, which is the exact failure
|
||||
// mode above — the computed font-family would look plausible either way.
|
||||
// mode this guards — the computed font-family would look plausible either
|
||||
// way, because an invalid font-family just inherits.
|
||||
expect(fonts.displayToken, '--font-display resolved').not.toBe('');
|
||||
expect(fonts.uiToken, '--font-ui resolved').not.toBe('');
|
||||
expect(fonts.proseToken, '--font-prose resolved').not.toBe('');
|
||||
|
||||
expect(fonts.body).toContain('Schibsted');
|
||||
expect(fonts.heading).toContain('Schibsted');
|
||||
// Times/serif anywhere in the interface means we fell back.
|
||||
expect(fonts.body).not.toMatch(/Times|serif$/);
|
||||
expect(fonts.body, 'body uses the UI face').toBe('Schibsted Grotesk');
|
||||
expect(fonts.heading, 'headings use the display face').toBe('Schibsted Grotesk');
|
||||
if (fonts.prose) {
|
||||
expect(fonts.prose, 'running prose uses the serif').toBe('Literata');
|
||||
}
|
||||
|
||||
// The Times fallback is the specific failure that shipped. Match the family
|
||||
// name only — a stack legitimately ends in sans-serif, so anchoring on
|
||||
// /serif$/ would flag a perfectly healthy page.
|
||||
expect(fonts.bodyStack).not.toMatch(/\bTimes\b/);
|
||||
});
|
||||
|
||||
test('no visible text falls back to the browser default black', async ({ page }) => {
|
||||
@@ -754,7 +768,7 @@ test('no visible text falls back to the browser default black', async ({ page })
|
||||
.filter((el) => {
|
||||
const r = el.getBoundingClientRect();
|
||||
if (r.width < 2 || r.height < 2) return false;
|
||||
if (el.closest('.leaflet-container')) return false;
|
||||
if (el.closest('.leaflet-tile-pane')) return false;
|
||||
return getComputedStyle(el).color === 'rgb(0, 0, 0)';
|
||||
})
|
||||
.map((el) => el.tagName.toLowerCase() + '.' + (el.getAttribute('class') || '').split(' ')[0])
|
||||
@@ -801,7 +815,7 @@ test('rendered colours all come from the token palette', async ({ page }) => {
|
||||
for (const el of document.querySelectorAll('body *')) {
|
||||
const box = el.getBoundingClientRect();
|
||||
if (box.width < 2 || box.height < 2) continue;
|
||||
if (el.closest('.leaflet-container')) continue; // OSM tiles are imagery
|
||||
if (el.closest('.leaflet-tile-pane')) continue; // OSM tiles are imagery, not palette
|
||||
const s = getComputedStyle(el);
|
||||
const checks: Array<[string, string]> = [['color', s.color]];
|
||||
if (s.backgroundColor !== 'rgba(0, 0, 0, 0)') checks.push(['background', s.backgroundColor]);
|
||||
|
||||
@@ -121,10 +121,17 @@
|
||||
--scrim: rgba(22, 32, 42, 0.55);
|
||||
|
||||
/* ── Type ───────────────────────────────────────────────────────── */
|
||||
--font-display: var(--font-schibsted), 'Schibsted Grotesk', -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
--font-ui: var(--font-schibsted), 'Schibsted Grotesk', -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
--font-data: var(--font-schibsted), 'Schibsted Grotesk', -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
--font-prose: var(--font-literata), 'Literata', Georgia, serif;
|
||||
/* next/font already expands --font-schibsted to the family plus its
|
||||
metric-matched fallback, so naming the family again here only made the
|
||||
stack say it twice. It read like a safety net but wasn't one: a var()
|
||||
with no fallback that resolves to nothing invalidates the whole
|
||||
declaration, so the literal after it never gets a turn. The real
|
||||
safeguard is that these classes sit on <html>, where :root can see
|
||||
them — see app/layout.tsx. */
|
||||
--font-display: var(--font-schibsted), -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
--font-ui: var(--font-schibsted), -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
--font-data: var(--font-schibsted), -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
--font-prose: var(--font-literata), Georgia, serif;
|
||||
|
||||
/* Type scale, 1.2 ratio off a 1rem base. New work should use these
|
||||
rather than inventing another font-size. */
|
||||
@@ -421,28 +428,33 @@ table,
|
||||
* bar would otherwise sit on a near-black page.
|
||||
*
|
||||
* The tiles themselves stay as OSM renders them; only the chrome is ours.
|
||||
*
|
||||
* Every selector here is prefixed with `html` on purpose. leaflet.css is
|
||||
* imported from a client component, so its chunk loads AFTER globals.css; at
|
||||
* equal specificity the later sheet wins and these overrides lose silently.
|
||||
* The `html` prefix takes them to 0,1,1 so load order stops mattering.
|
||||
*/
|
||||
.leaflet-container {
|
||||
html .leaflet-container {
|
||||
background: var(--bg-secondary);
|
||||
font-family: var(--font-ui);
|
||||
}
|
||||
|
||||
.leaflet-control-attribution {
|
||||
html .leaflet-control-attribution {
|
||||
background: rgba(var(--text-inverse-rgb), 0.82);
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.leaflet-control-attribution a {
|
||||
html .leaflet-control-attribution a {
|
||||
color: var(--brand);
|
||||
}
|
||||
|
||||
.leaflet-bar a {
|
||||
html .leaflet-bar a {
|
||||
background: var(--bg-card);
|
||||
color: var(--text-primary);
|
||||
border-bottom-color: var(--border);
|
||||
}
|
||||
|
||||
.leaflet-bar a:hover {
|
||||
html .leaflet-bar a:hover {
|
||||
background: var(--bg-secondary);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user