/* css/base.css — the reset, the page, the focus ring, type, links, utilities and reduced motion.
   One of the files src/index.html links in order; see tokens.css for why. */

*,*::before,*::after{box-sizing:border-box}

html{
  /* rem, so a browser's own font size scales everything. A px root would break
     the 200% zoom requirement (WCAG 1.4.4) at the first breakpoint. */
  font-size:100%;
  background:var(--paper);
}

body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font-family:var(--ui);
  font-size:1rem;              /* 16px body, top of the spec's 15-16 range */
  line-height:1.55;
  /* Hours are columns and columns must align. Global, per the spec. */
  font-variant-numeric:tabular-nums;
  -webkit-font-smoothing:antialiased;
}

/* ==========================================================================
   Focus — VERBATIM, and applied to everything focusable (WCAG 2.4.7)
   ==========================================================================
   :focus-visible ONLY. The ring itself is untouched — same 3px, same --ink,
   same offset — and every keyboard user still gets it on every control.

   WHAT CHANGED AND WHY. The old `:focus:not(:focus-visible)` fallback painted
   the ring on ANY focus including a programmatic one, and app.js moves focus to
   the page heading after every route change. That is not decoration and must
   not be removed: focusHeading() in ui/dom.js is HOW a screen reader is told
   the route changed, and deleting it would make navigation silent (WCAG 2.4.3).
   But it meant a mouse user saw a heavy black box drawn around the <h1> on
   every single click through the app, which reads as an error state.

   THAT WAS NOT ENOUGH AND THE BOX CAME BACK. The claim above — that a
   programmatically focused <h1 tabindex="-1"> never matches :focus-visible —
   is not what engines actually do. The heuristic in the spec says an element
   focused by script matches :focus-visible when the element that HAD focus
   matched it, and, crucially, when nothing had focus at all. app.js's route
   change calls mount(), which CLEARS the container first: any focused control
   inside the old screen is destroyed, focus falls to <body>, and only then does
   focusHeading() run. Script focus from nowhere is exactly the case an engine
   resolves in favour of showing the ring. Hence a black box round the <h1> on
   every route change, blinking off and back as the screen repainted.

   SO THE RING IS SILENCED ON THE HEADING ITSELF, and only there. This is the
   one documented exception to the rule on the line below, and it costs a
   keyboard user nothing that can be measured: tabindex="-1" is what makes an
   element focusable BY SCRIPT AND NOT BY TAB, so no keyboard user can ever
   arrive here by tabbing and find the ring missing. The only way to focus this
   element is the route change, and the ring is not what a route change is for.

   THE ANNOUNCEMENT IS UNTOUCHED, which is the whole point of doing it this way
   rather than deleting focusHeading(). Focus still lands on the new heading, so
   a screen reader still reads the page it has arrived at (WCAG 2.4.3). Only the
   paint is suppressed, and a screen reader does not read outlines.

   The fallback is kept behind @supports for an engine that has no
   :focus-visible at all, where a ring on every focus is the right failure. That
   is Safari before 15.4; everything current implements the selector.
   ========================================================================== */
:focus-visible{outline:3px solid var(--ink);outline-offset:2px}

@supports not selector(:focus-visible){
  :focus{outline:3px solid var(--ink);outline-offset:2px}
}
/* Never removed anywhere EXCEPT on the two elements focusHeading() touches, and
   the paragraph above is the argument. Specificity (0,2,1) beats both rules
   above it, so this holds in the @supports branch too. If any OTHER rule below
   sets outline:none, that is a bug. */
h1[tabindex="-1"]:focus,h2[tabindex="-1"]:focus{outline:none}

/* ==========================================================================
   Type
   ========================================================================== */
h1,h2,h3{margin:0 0 .4em;text-wrap:balance}

.display{
  font-size:clamp(2.5rem,5vw,3.625rem);   /* 40 - 58 */
  font-weight:800;letter-spacing:-.034em;line-height:1.05;
}
/* 36px per GOV.UK's type scale, line height on the 5px grid (40px) — CIT-15.
   margin:0 — the air under a title is .page-head's to give, not the element's. */
h1{font-size:2.25rem;font-weight:800;letter-spacing:-.02em;line-height:1.12;margin:0}
.h2{
  font-size:clamp(1.75rem,3.4vw,2.5rem);  /* 28 - 40 */
  font-weight:800;letter-spacing:-.028em;line-height:1.12;
}
h2{font-size:1.4rem;font-weight:800;letter-spacing:-.024em;line-height:1.3}
h3,.h3{font-size:1.1875rem;font-weight:700;letter-spacing:-.016em}   /* 19 */

/* Eyebrow labels: mono, uppercase, tracked. Per the spec, mono carries labels
   as well as numbers. */
.label{
  font-family:var(--data);
  font-size:.6875rem;                     /* 11 */
  font-weight:500;
  letter-spacing:.13em;
  text-transform:uppercase;
  color:var(--ink-soft);
}

/* Numbers, dates, category codes, ISD numbers. */
.mono,.num,td.num,th.num{font-family:var(--data);font-variant-numeric:tabular-nums}
/* nowrap because a clock-hour figure is a statutory quantity and must never be
   broken across two lines. At 1280px the ledger's HOURS column was narrow enough
   that "24.00" rendered as "24.0" over "0" — tabular-nums lines the digits up
   beautifully and then the wrap undoes the whole point of the column. Found by
   looking at a desktop screenshot; a markup assertion cannot see it. */
.num{text-align:right;white-space:nowrap}

/* Long-form policy and help text, in Atkinson Hyperlegible — the accessibility
   claim showing up in the product rather than only in a VPAT. Every quotation of
   the rule uses this. */
.policy,.statute,.help{font-family:var(--legible)}
.statute{
  font-size:.9375rem;line-height:1.6;color:var(--ink);
  border-left:3px solid var(--rule-strong);   /* meaningful, so not --rule */
  padding:.55rem 0 .55rem .9rem;margin:.6rem 0;
  background:transparent;
}
.statute cite{display:block;margin-top:.4rem;font-family:var(--data);
  font-size:.6875rem;letter-spacing:.08em;text-transform:uppercase;
  color:var(--ink-soft);font-style:normal}
.help{font-size:.875rem;color:var(--ink-soft);margin:.35rem 0 0}

/* An unverified statutory label must never be presented as statute. */
.unverified{
  font-family:var(--data);font-size:.625rem;letter-spacing:.1em;
  text-transform:uppercase;color:var(--pending);
  border:1px solid var(--pending);border-radius:var(--r-xs);
  padding:.05rem .3rem;margin-left:.4rem;white-space:nowrap;
}

a{color:var(--ink);text-decoration-thickness:1px;text-underline-offset:2px}
a:hover{text-decoration-thickness:2px}

/* ==========================================================================
   Utility
   ========================================================================== */
.visually-hidden{
  position:absolute;width:1px;height:1px;margin:-1px;padding:0;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}
.muted{color:var(--ink-soft)}
.nowrap{white-space:nowrap}
.grow{flex:1 1 auto}

@media (prefers-reduced-motion:reduce){
  *{transition:none!important;animation:none!important}
}
