/* ==========================================================================
   Neovizio design system. Plain CSS, no build step.

   Tokens come in two layers, which is what keeps the site cohesive:

     Primitives  the raw scales - space, colour, type size. Meaningless on
                 their own; they only say what values exist.
     Semantic    named for the job they do - --field-gap, --section-gap. Every
                 component rule below uses these, never a raw scale value, so
                 changing one relationship changes it everywhere at once.

   No length, size or colour outside section 1 is a literal. tests/audit.py
   parses this file and fails on any raw value, which is the discipline a
   utility framework enforces by construction.

   Contents
     1. Tokens
     2. Reset
     3. Layout
     4. Typography
     5. Header
     6. Footer
     7. Sections
     8. Links and buttons
     9. Lists
    10. Forms
    11. Panels
    12. Motion and forced colours
   ========================================================================== */

/* 1. Tokens ================================================================ */
:root {
  /* ---- PRIMITIVES ----------------------------------------------------- */

  /* Type family and weight. Two weights, no webfonts. */
  --font-sans: "Helvetica Neue", Helvetica, Arial, "Liberation Sans", sans-serif;
  --regular: 400;
  --bold: 700;

  /* Colour. A deep forest green reads as considered and established without
     the finance-industry navy cliché, over a warm off-white rather than pure
     white to soften long reading. All prose is near-black; green is reserved
     for links, the primary action and one accented phrase in the hero, so
     colour carries a single consistent meaning.

     Contrast against --paper:
       ink      14.1:1  body copy, headings         (AA needs 4.5)
       accent   10.1:1  links, buttons, focus ring  (AA needs 4.5)
       error     7.2:1  error text                  (AA needs 4.5)
       control   4.3:1  input borders on white      (1.4.11 needs 3)
     --placeholder is 4.9:1 on white, since placeholder text is text and must
     meet 1.4.3. Browser defaults are around 2.5:1 and would fail.
       line      2.1:1  decorative rules            (no minimum applies)
     White on --accent is 10.4:1. On --wash, ink is 12.8:1, accent 9.1:1. */
  --paper: #fafaf7;
  --wash: #eef1ec;
  --ink: #1d2c26;
  --accent: #24463d;
  --accent-hover: #14332b;
  --error: #a52020;
  --control: #6f7d73;
  --placeholder: #66746a;
  --line: #a8b3a9;
  --white: #fff;

  /* Space. A 4px scale, as GOV.UK and utility frameworks use. */
  --space-1: 0.25rem; /*  4px */
  --space-2: 0.5rem;  /*  8px */
  --space-3: 0.75rem; /* 12px */
  --space-4: 1rem;    /* 16px */
  --space-5: 1.5rem;  /* 24px */
  --space-6: 2rem;    /* 32px */
  --space-7: 2.5rem;  /* 40px */
  --space-8: 3rem;    /* 48px */
  --space-9: 4rem;    /* 64px */
  --space-10: 5rem;   /* 80px */
  --space-11: 6rem;   /* 96px */

  /* Type scale. Seven sizes, fluid between a 320px and a 768px viewport. Both
     bounds are rem and most of each middle term is rem, so text still grows
     when a reader raises their browser font size (WCAG 1.4.4).

     One scale runs the whole site. Each role picks the step for its job, and
     the same step is reused across pages, which is what makes the pages feel
     like one site:

       token          320px -> 768px   homepage       every other page
       --hero           41  ->  64     h1             -
       --deck         27  ->  34     hero lead      -
       --title          32.5 -> 44     h2             h1
       --heading        26  ->  30     h3             h2
       --subheading     21  ->  24     -              h3, lead
       --body           17  ->  19     body copy      body copy
       --meta           16  ->  16     counter,       counter,
                                       buttons,       buttons,
                                       footer         footer

     So a homepage section heading is exactly the size of an inner page's h1,
     and a homepage sub-heading is exactly the size of an inner page's h2. Only
     the hero exceeds anything an inner page uses.

     The step from --title to --heading is the widest in the scale, about 1.47
     against about 1.25 lower down. GOV.UK's own scale is shaped the same way
     (36 -> 24 -> 19, so 1.50 then 1.26): the break between "this page" and "a
     section of this page" is the one a reader must not have to measure, while
     the steps below it only need to be legible. Evening the scale out is what
     made a homepage h3 read as a slightly smaller h2.

     --deck is the hero's opening sentence. It sits above --heading, so it
     outsizes anything on an inner page, and below --title, so it never competes
     with the section headings underneath it. Regular weight keeps it prose.

     Body settles at 19px, GOV.UK's body size, rather than 18px. Against the
     720px band that is about 70 characters per line instead of 76, which moves
     the measure from the top of the comfortable range into the middle of it. */
  --hero: clamp(2.5625rem, 1.536rem + 5.134vw, 4rem);
  --deck: clamp(1.6875rem, 1.375rem + 1.5625vw, 2.125rem);
  --title: clamp(2.03125rem, 1.518rem + 2.567vw, 2.75rem);
  --heading: clamp(1.625rem, 1.446rem + 0.893vw, 1.875rem);
  --subheading: clamp(1.3125rem, 1.179rem + 0.67vw, 1.5rem);
  --body: clamp(1.0625rem, 0.973rem + 0.446vw, 1.1875rem);
  --meta: 1rem;

  /* Line height and tracking, paired to the sizes above. */
  --leading-tight: 1.05;
  --leading-snug: 1.15;
  --leading-heading: 1.25;
  --leading-lead: 1.5;
  --leading-body: 1.6;
  --track-hero: -0.032em;
  --track-title: -0.025em;
  --track-heading: -0.018em;
  --track-subheading: -0.01em;

  /* Border, radius and interaction sizes. */
  --hairline: 1px;
  --rule: 2px;
  /* Link underlines. Set explicitly at rest, because the browser default of
     `auto` already renders near 2px at lead size and made the hover change
     imperceptible there. The hover value is in em so the change stays
     proportional at every type size. */
  --underline: 1px;
  --underline-hover: 0.14em;
  --radius: 2px;
  --focus-ring: 3px;      /* above the 2px minimum, for visibility */
  --focus-offset: 2px;
  --target-min: 2.75rem;  /* 44px, well above the 24px WCAG 2.2 floor */
  --target-lg: 3.25rem;   /* 52px for primary actions and inputs */

  /* ---- SEMANTIC ------------------------------------------------------- */

  /* One width: header, content and footer share it, so every page has the
     same left and right edge. 45rem holds roughly 75 characters per line at
     the body size, so prose needs no narrower column inside it. */
  --band: 45rem; /* 720px */

  /* Page frame */
  --gutter: var(--space-5);
  /* A 44px target plus 12px of shared-scale breathing room gives the mobile
     header 6px above and below its controls without wasting sticky viewport. */
  --header-h: calc(var(--target-min) + var(--space-3));
  --header-y: var(--space-1);
  --scroll-offset: calc(var(--header-h) + var(--space-5));
  --footer-y: var(--space-6);

  /* Section rhythm */
  --band-y: var(--space-9);
  --statement-y-top: var(--space-8);
  --statement-y-bottom: var(--space-10);
  --document-y-top: var(--space-7);
  --document-y-bottom: var(--space-10);
  --section-gap: var(--space-8);
  --block-gap: var(--space-7);
  --item-y: var(--space-5);

  /* Text rhythm */
  --lead-gap: var(--space-5);   /* h1 -> lead */
  --title-gap: var(--space-4);  /* h2 -> content */
  --heading-gap: var(--space-2); /* h3 -> content */
  --prose-gap: var(--space-4);  /* paragraph -> paragraph */
  --list-gap: var(--space-2);   /* list item -> list item */
  --action-gap: var(--space-6); /* lead -> button */

  /* Form rhythm */
  --field-gap: var(--space-5);      /* field group -> field group */
  --field-inner-gap: var(--space-2); /* label/error -> control */
  --panel-gap: var(--space-2);       /* inside a panel */
  --panel-pad: var(--space-4);

  /* Component internals */
  --btn-pad-y: var(--space-3);
  --btn-pad-x: var(--space-5);
  --field-pad-y: var(--space-3);
  --field-pad-x: var(--space-4);
  --textarea-h: 10rem;   /* about four lines, so the field invites a real answer */
  --skip-hidden: -7rem;  /* far enough off-screen to clear the skip link */
  --bullet-indent: var(--space-5);
  --z-header: 40;
  --z-skip: 50;
}

@media (min-width: 40rem) {
  :root {
    --gutter: var(--space-6);
    --header-h: 4rem;
    --header-y: var(--space-2);
    --footer-y: var(--space-7);
    --band-y: var(--space-11);
    --statement-y-top: var(--space-11);
    --statement-y-bottom: var(--space-11);
    --document-y-top: var(--space-9);
    --document-y-bottom: var(--space-11);
    --section-gap: var(--space-9);
    --item-y: var(--space-6);
    --heading-gap: var(--space-3);
    --field-gap: var(--space-6);
    --action-gap: var(--space-7);
  }
}

/* 2. Reset ================================================================= */
*,
*::before,
*::after {
  box-sizing: border-box;
}

* {
  margin: 0;
}

html {
  -webkit-text-size-adjust: 100%;
  /* Keeps anchor targets and keyboard-focused elements clear of the sticky
     header (WCAG 2.2 SC 2.4.11 Focus Not Obscured). */
  scroll-padding-top: var(--scroll-offset);
}

ul {
  padding: 0;
  list-style: none;
}

a {
  color: inherit;
}

button,
input,
textarea {
  font: inherit;
  color: inherit;
}

button {
  cursor: pointer;
  border: 0;
  background: none;
}

[hidden] {
  display: none !important;
}

/* 3. Layout ================================================================ */
body {
  display: flex;
  min-height: 100svh;
  flex-direction: column;
  background-color: var(--paper);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--body);
  font-weight: var(--regular);
  line-height: var(--leading-body);
  overflow-wrap: anywhere;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

::selection {
  background-color: var(--accent);
  color: var(--white);
}

main {
  flex: 1;
}

/* The one width. */
.band {
  width: 100%;
  max-width: var(--band);
  margin-inline: auto;
}

/* Containers focused programmatically draw no ring; every component that
   receives focus defines its own below. */
[tabindex="-1"]:focus {
  outline: none;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: fixed;
  top: var(--space-3);
  left: var(--space-3);
  z-index: var(--z-skip);
  padding: var(--btn-pad-y) var(--btn-pad-x);
  background-color: var(--ink);
  color: var(--white);
  font-size: var(--meta);
  text-decoration: none;
  transform: translateY(var(--skip-hidden));
}

.skip-link:focus {
  outline: var(--focus-ring) solid var(--accent);
  outline-offset: var(--focus-offset);
  transform: translateY(0);
}

/* 4. Typography ============================================================
   Headings take their size from the element, so a page gets the right scale by
   using the right level. The homepage carries .home on <body>. */
h1,
h2,
h3 {
  font-weight: var(--bold);
  text-wrap: balance;
}

h1 {
  font-size: var(--title);
  line-height: var(--leading-snug);
  letter-spacing: var(--track-title);
}

h2 {
  font-size: var(--heading);
  line-height: var(--leading-heading);
  letter-spacing: var(--track-heading);
}

h3 {
  font-size: var(--subheading);
  line-height: var(--leading-heading);
  letter-spacing: var(--track-subheading);
}

.home h1 {
  font-size: var(--hero);
  line-height: var(--leading-tight);
  letter-spacing: var(--track-hero);
}

.home h2 {
  font-size: var(--title);
  line-height: var(--leading-snug);
  letter-spacing: var(--track-title);
}

.home h3 {
  font-size: var(--heading);
  letter-spacing: var(--track-heading);
}

/* The hero's opening sentence. Larger than any heading an inner page carries,
   smaller than the section headings below it, and set at heading leading rather
   than prose leading because at this size 1.5 opens the lines too far apart to
   read as one sentence. Section leads on the same page keep the standard size. */
.home .section--statement .lead {
  font-size: var(--deck);
  line-height: var(--leading-heading);
  letter-spacing: var(--track-heading);
}

p {
  text-wrap: pretty;
}

/* Opening paragraph. Same size as the lowest heading, told apart by weight
   rather than by colour. */
.lead {
  font-size: var(--subheading);
  line-height: var(--leading-lead);
  letter-spacing: var(--track-subheading);
}

/* Vertical rhythm. One rule per relationship, so the same pair of elements is
   spaced identically on every page. */
.stack > * + * {
  margin-top: var(--prose-gap);
}

p + p {
  margin-top: var(--prose-gap);
}

h1 + .lead {
  margin-top: var(--lead-gap);
}

h2 + p,
h2 + .lead,
h2 + .stack,
h2 + ul {
  margin-top: var(--title-gap);
}

h3 + p,
h3 + .stack {
  margin-top: var(--heading-gap);
}

/* 5. Header ================================================================
   Sticky, so the primary action stays reachable on a long page. Short and
   opaque, closed by a full-bleed rule that marks the boundary once content
   scrolls beneath it. */
.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  padding-inline: var(--gutter);
  background-color: var(--paper);
  border-bottom: var(--hairline) solid var(--line);
}

.header-row {
  display: flex;
  min-height: var(--header-h);
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-1) var(--space-5);
  padding-block: var(--header-y);
}

/* The mark shares the favicon's vector geometry. Its size follows the wordmark
   type step, so the pair reads as one identity without increasing the sticky
   header's height or reducing its 44px target. */
.wordmark {
  display: inline-flex;
  min-height: var(--target-min);
  align-items: center;
  gap: var(--space-2);
  font-size: var(--subheading);
  font-weight: var(--bold);
  letter-spacing: var(--track-subheading);
  text-decoration: none;
}

.wordmark-mark {
  width: var(--subheading);
  height: var(--subheading);
  flex: none;
}

/* 6. Footer ================================================================
   The rule spans the viewport, matching the header, so the page is framed
   symmetrically rather than one edge full-bleed and the other inset. */
.site-footer {
  margin-top: auto;
  padding-inline: var(--gutter);
  background-color: var(--paper);
  border-top: var(--hairline) solid var(--line);
}

.footer-row {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding-block: var(--footer-y);
  font-size: var(--meta);
  line-height: var(--leading-lead);
}

.footer-nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-5);
}

@media (min-width: 40rem) {
  .footer-row {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-6);
  }

  .footer-nav ul {
    gap: var(--space-6);
  }
}

/* 7. Sections ============================================================== */
.section {
  padding-inline: var(--gutter);
  background-color: var(--paper);
}

.section--wash {
  background-color: var(--wash);
}

.section > .band {
  padding-block: var(--band-y);
}

/* The homepage hero and the 404: one statement and one action. */
.section--statement > .band {
  padding-block: var(--statement-y-top) var(--statement-y-bottom);
}

/* Careers, terms and privacy: a document to read. */
.section--document > .band {
  padding-block: var(--document-y-top) var(--document-y-bottom);
}

.doc-section + .doc-section,
.page-header + .doc-section {
  margin-top: var(--section-gap);
}

.blocks {
  margin-top: var(--block-gap);
}

.blocks > * + * {
  margin-top: var(--block-gap);
}

/* 8. Links and buttons ===================================================== */
.hero-title span {
  display: block;
}

.hero-title .accent {
  color: var(--accent);
}

/* Inline text link. Underlined, because colour alone must not carry meaning.
   Vertical padding lifts the touch area past the 24px floor in SC 2.5.8
   without affecting layout: padding on an inline box does not grow the line. */
a:not(.skip-link, .wordmark, .btn) {
  color: var(--accent);
  padding-block: var(--space-1);
  text-decoration: underline;
  text-decoration-thickness: var(--underline);
  text-underline-offset: var(--space-1);
}

a:not(.skip-link, .wordmark, .btn):hover {
  text-decoration-thickness: var(--underline-hover);
}

a:focus-visible,
button:focus-visible {
  outline: var(--focus-ring) solid var(--accent);
  outline-offset: var(--focus-offset);
}

.nav-link {
  display: inline-flex;
  min-height: var(--target-min);
  align-items: center;
}

.nav-link[aria-current="page"] {
  font-weight: var(--bold);
}

/* Solid action. Full size by default; --sm for the header, still above the
   44px guideline. */
.btn {
  display: inline-flex;
  max-width: 100%;
  min-height: var(--target-lg);
  align-items: center;
  justify-content: center;
  padding: var(--btn-pad-y) var(--btn-pad-x);
  border-radius: var(--radius);
  background-color: var(--accent);
  color: var(--white);
  font-size: var(--meta);
  font-weight: var(--bold);
  line-height: var(--leading-lead);
  text-decoration: none;
}

.btn:hover {
  background-color: var(--accent-hover);
}

.btn:disabled {
  cursor: progress;
}

/* Header action. Sized to the 44px target exactly rather than to the label plus
   the full button padding, so the sticky bar stays short. */
.btn--sm {
  min-height: var(--target-min);
  padding-block: var(--space-2);
  padding-inline: var(--field-pad-x);
}

.lead + .btn {
  margin-top: var(--action-gap);
}

/* 9. Lists ================================================================= */
.bullets {
  list-style: disc;
  padding-left: var(--bullet-indent);
}

.bullets > li {
  padding-left: var(--space-1);
}

.bullets > li + li {
  margin-top: var(--list-gap);
}

/* A sentence introducing a list, or closing one, is one prose step away from it:
   close enough to belong to the list, not so close as to look like an item. */
p + .bullets,
.bullets + p {
  margin-top: var(--prose-gap);
}

/* Ruled rows. A rule between items rather than a box around each, so nothing is
   boxed that does not need a box. Written against the children rather than
   against li, so the pattern is not tied to one element. */
.rows > * {
  padding-block: var(--item-y);
  border-top: var(--hairline) solid var(--line);
}

.rows > :first-child {
  padding-top: 0;
  border-top: 0;
}

.rows > :last-child {
  padding-bottom: 0;
}

.lead + .rows {
  margin-top: var(--block-gap);
}

/* 10. Forms ================================================================
   Order within a field group is label, hint, error, control, so the control is
   reached last and everything describing it has already been read (GOV.UK text
   input and error message patterns). */
.inquiry {
  width: 100%;
  min-width: 0;
  margin-top: var(--block-gap);
}

.fields {
  min-width: 0;
  padding: 0;
  border: 0;
}

.fields > * + * {
  margin-top: var(--field-gap);
}

/* The legend is sr-only and out of flow, so the first visible group must not
   inherit a gap from it. */
.fields > legend + * {
  margin-top: 0;
}

/* Label and error message are set at body size, not at --meta. A label is the
   question being asked and an error message is the instruction for answering
   it, so neither is secondary information; GOV.UK sets both at body size for
   the same reason. --meta stays for genuinely secondary text: the counter, the
   footer and button labels. */
.field-label {
  display: block;
  font-size: var(--body);
  font-weight: var(--bold);
  line-height: var(--leading-lead);
}

.field-error {
  margin-top: var(--field-inner-gap);
  color: var(--error);
  font-size: var(--body);
  font-weight: var(--bold);
  line-height: var(--leading-lead);
}

.field {
  display: block;
  width: 100%;
  min-width: 0;
  min-height: var(--target-lg);
  margin-top: var(--field-inner-gap);
  padding: var(--field-pad-y) var(--field-pad-x);
  border: var(--hairline) solid var(--control);
  border-radius: var(--radius);
  background-color: var(--white);
  font-size: var(--body);
  line-height: var(--leading-body);
}

.field:focus {
  border-color: var(--accent);
  outline: var(--focus-ring) solid var(--accent);
  outline-offset: var(--focus-offset);
}

.field::placeholder {
  color: var(--placeholder);
  opacity: 1;
}

.field[aria-invalid="true"] {
  border-width: var(--rule);
  border-color: var(--error);
}

textarea.field {
  min-height: var(--textarea-h);
  resize: vertical;
}

.counter {
  margin-top: var(--field-inner-gap);
  min-height: var(--space-5);
  font-size: var(--meta);
  font-variant-numeric: tabular-nums;
  line-height: var(--leading-lead);
}

.counter[data-over="true"] {
  color: var(--error);
  font-weight: var(--bold);
}

/* 11. Panels ===============================================================
   A heavy left rule rather than a tinted box, so the state reads at any
   contrast setting and needs no extra colour. */
.panel {
  padding-left: var(--panel-pad);
  border-left: var(--focus-ring) solid var(--accent);
}

.panel > * + * {
  margin-top: var(--panel-gap);
}

.panel:focus {
  outline: var(--focus-ring) solid var(--accent);
  outline-offset: var(--focus-offset);
}

.panel--error {
  border-color: var(--error);
}

.panel--error:focus {
  outline-color: var(--error);
}

/* Validation summary. Bordered rather than ruled, because it sits above the
   form and has to be found immediately. */
.error-summary {
  margin-bottom: var(--field-gap);
  padding: var(--panel-pad);
  border: var(--rule) solid var(--error);
}

.error-summary:focus {
  outline: var(--focus-ring) solid var(--error);
  outline-offset: var(--focus-offset);
}

.error-summary ul {
  margin-top: var(--title-gap);
  color: var(--error);
}

.error-summary li + li {
  margin-top: var(--panel-gap);
}

.error-summary a {
  color: var(--error);
}

.error-summary a:focus-visible {
  outline-color: var(--ink);
}

.form-status {
  margin-top: var(--field-gap);
}

/* Sent confirmation, shown in place of the form. */
.sent {
  margin-top: var(--block-gap);
}

/* 12. Motion and forced colours ============================================ */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}

@media (forced-colors: active) {
  .btn {
    border: var(--rule) solid;
  }

  .field {
    border: var(--hairline) solid;
  }

  .site-header {
    border-bottom: var(--hairline) solid;
  }

  .site-footer {
    border-top: var(--hairline) solid;
  }
}
