/*
 * The marketing site's only stylesheet.
 *
 * Hand-written and deliberately small. ADR-005 decision 1 wants real HTML per page with no
 * application payload, so there is no framework, no CSS-in-JS and no build step - the file is
 * served exactly as it is written.
 *
 * The design commits to a single light palette. The SPA has its own theme and its own tokens
 * and the two are not meant to share a stylesheet - but ADR-005 splits one product across two
 * sites, so they must not look like two products. The VALUES below are therefore the SPA's
 * "Paper and Ink" values under this file's own shorter names, and the Inter files are
 * byte-identical copies of the SPA's. Change a colour or a face here and change it in
 * `src/client/src/styles/design-system.css` in the same commit.
 *
 * Legacy's brand colour was green and it is NOT carried over. Green did two jobs at once here -
 * it filled the button you press and it coloured the notice that says you succeeded - and one
 * colour cannot mean both. The brand is now blue, the call to action is ink, and green is left
 * to mean only "this succeeded".
 */

/* Inter, self-hosted. Byte-identical copies of the SPA's files at
 * `src/client/public/fonts/`, so the two sites render the same shapes. The licence travels
 * with the copy as Inter-OFL.txt and must stay beside them.
 *
 * These are VARIABLE files: `font-weight: 100 900` means one file covers every weight. Do not
 * replace them with a set of static weights.
 *
 * THE FILENAMES CARRY A YEAR AND THAT IS LOAD-BEARING. `deploy/nginx/apex-marketing.conf`
 * serves .woff2 with `max-age=31536000, immutable`, so a revised file published under the same
 * name never reaches a returning visitor for a year. A new cut of Inter needs a new filename
 * and this block updated with it - the same rule the example schedule follows.
 */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/inter-latin-2026.woff2") format("woff2");
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/inter-latin-ext-2026.woff2") format("woff2");
  unicode-range:
    U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
    U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* DaxRegular, the SPA's heading face, copied byte for byte from src/client/public/fonts with a
   year in the name for the reason above. It is --font-heading, as in the SPA: the headings,
   the brand name and the footer's "Call us today" (owner, 6 October 2026). FF Dax is a
   commercial face; the C8 deviation in docs/login-page-redesign/SPEC.md covers this copy with
   the other two. */
@font-face {
  font-family: "DaxRegular";
  src: url("fonts/DaxRegular-2026.ttf") format("truetype");
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

:root {
  /* THE NAMES AND THE VALUES ARE THE SPA'S. They were this site's own - `--brand-700`,
     `--ink-900`, `--paper`, `--action` - until 31 August 2026, and the values already matched
     `design-system.css` step for step. What the private vocabulary cost is the only way a
     drift is ever noticed: two files holding the same palette under different words cannot be
     read against each other. ADR-005 accepts that this site duplicates the identity; it does
     not ask for the duplicate to be unrecognisable. Change one, change the other in the same
     commit - now you can see which one moved. */

  /* The brand. Identity, and since 31 August 2026 the call to action as well. */
  --color-primary-900: #042336;
  --color-primary-800: #09324b;
  --color-primary-700: #0d4262;
  --color-primary-600: #0d4f76;
  --color-primary-500: #1a618c;
  --color-primary-100: #bfd4e4; /* the footer's text on navy */
  --color-primary-50: #e5eef4;

  /* THE CALL TO ACTION IS THE BRAND BLUE (owner's instruction, 31 August 2026). It was ink,
     `#111418`, on the argument that the product prints a court document and the interface
     should look like the document it produces. What ink did not do is look like this product:
     the blue is the wordmark, the header and the login page, and the one control a visitor is
     meant to press was the only thing on the page refusing to wear it.

     Put `--color-action-text` on it, never plain white: it is the paper, so the label on a
     button and the page behind it are one colour. */
  --color-action: var(--color-primary-700);
  --color-action-hover: var(--color-primary-800);
  --color-action-text: #fbfaf8;

  /* Green means one thing: an outcome that went well. Nothing you press is green. */
  --color-success-800: #265b31;
  --color-success-700: #2f6e3b;
  --color-success-100: #e6f0e7;

  /* The one accent. It marks; it is never a fill. Declared and not yet used, exactly as in the
     SPA - these pages have no "current step" or "selected row" for it to mark. Reach for it
     before reaching for another hue: green, amber, red and blue all already mean something. */
  --color-accent: #1a8264;
  --color-accent-tint: #e6f6ef;
  /* The accent button's hover, the same shade taken further; paper on it is 6.70:1. */
  --color-accent-hover: #15654e;

  /* Warm greys. The paper is not white, and the darkest step is no longer what text is set in -
     see `--color-text-primary` below. */
  --color-gray-900: #111418;
  --color-gray-700: #57534c;
  --color-gray-600: #726c65;
  --color-gray-300: #d6d0c6;
  --color-gray-200: #e3dfd8;
  --color-gray-100: #ede9e1;

  /* Text. The SPA points this at the brand blue and so does this site, which is what turns
     every "black ink element" on the page brand blue in one line. The grey ramp above keeps
     its true values; nothing sets type in `--color-gray-900` any more. */
  --color-text-primary: var(--color-primary-700);

  /* Grounds. THE PAGE IS THE TINTED PAPER AND A PANEL IS WHAT IS WHITE - the same inversion
     the SPA and the Keycloak login theme made on 31 August 2026. `.section-alt` therefore
     flips to the paper, so an alternating band still alternates. */
  --color-background-primary: #fbfaf8;
  --color-background-secondary: #f4f1ec;
  /* Panels, cards, dropdowns, modals. Lifted from #fbfaf8 a quarter of the way to white on
     27 September 2026 (owner), keeping the warm cast; mirrored in the other site's copy. */
  --color-background-elevation: #fcfbf9;

  --color-warning-50: #faf1de;
  --color-warning-700: #8f5f00;
  --color-error-50: #f7ebeb;
  --color-error-700: #a4262c;
  --color-info-50: #e5eef4;
  --color-info-600: #0d4f76;

  --measure: 68ch;

  /* Radii and shadows are the SPA's scale. `--radius` was a single 8px step; the SPA's control
     default is 3px and its panel is 4px, because sharper corners read as precise and
     document-like where a rounder one reads as a consumer application. */
  --radius-md: 0.1875rem;
  --radius-lg: 0.25rem;
  --shadow-sm: 0 1px 2px 0 rgb(17 20 24 / 6%);
  --shadow-md: 0 2px 6px -1px rgb(17 20 24 / 8%);

  /* Inter, the SPA's body face, self-hosted above. ADR-005 splits one product across two
     sites and they must not look like two products, so the typeface is shared as well as the
     colours - change one, change the other in the same commit.
     The system stack behind it is what renders while the file loads and if it fails.
     --font-heading is the SPA's DaxRegular, falling back to the body stack. */
  --font-primary:
    "Inter", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
    Arial, sans-serif;
  --font-heading: "DaxRegular", var(--font-primary);
}

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

html {
  font-size: 100%;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  font-family: var(--font-primary);
  font-size: 1.0625rem;
  line-height: 1.65;
  color: var(--color-text-primary);
  background: var(--color-background-secondary);
}

/* Headings resolve to `--color-text-primary`, which the SPA's own h1-h6 rule does too - so
   they follow it wherever it points. Both were ink until 31 August 2026 and both are the brand
   blue now. Since 6 October 2026 they are also the SPA's heading face, DaxRegular. */
h1,
h2,
h3 {
  font-family: var(--font-heading);
  line-height: 1.2;
  margin: 0 0 0.5em;
  color: var(--color-text-primary);
  letter-spacing: -0.01em;
}

/* Nothing renders below h3 today. The rule is here so that a legal document which gains a
   fourth level does not silently fall back to the body face. */
h4,
h5,
h6 {
  font-family: var(--font-heading);
}

h1 {
  font-size: clamp(2rem, 1.4rem + 2.4vw, 3rem);
}
h2 {
  font-size: clamp(1.5rem, 1.2rem + 1.2vw, 2rem);
}
h3 {
  font-size: 1.1875rem;
}

p {
  margin: 0 0 1rem;
}

a {
  color: var(--color-primary-700);
  text-underline-offset: 0.15em;
}

a:hover {
  color: var(--color-primary-900);
}

:focus-visible {
  outline: 3px solid var(--color-primary-500);
  outline-offset: 2px;
  border-radius: 2px;
}

img {
  max-width: 100%;
  height: auto;
}

address {
  font-style: normal;
}

/* ---------------------------------------------------------------- layout */

.container {
  width: min(72rem, 100% - 2.5rem);
  margin-inline: auto;
}

.container.narrow {
  width: min(48rem, 100% - 2.5rem);
}

.center {
  text-align: center;
}

.section {
  padding: clamp(2.5rem, 5vw, 4.5rem) 0;
}

/* The page ground is the tint, so an alternating band is the PAPER - this rule was the other
   way round until 31 August 2026 and flipping the ground without flipping the band would have
   made every `.section-alt` invisible. */
.section-alt {
  background: var(--color-background-primary);
  border-block: 1px solid var(--color-gray-200);
}

.section-cta {
  background: var(--color-primary-50);
  border-top: 1px solid var(--color-gray-200);
}

.prose {
  max-width: var(--measure);
}

.lead {
  font-size: 1.1875rem;
  color: var(--color-gray-700);
}

/* Ink rather than brand blue: this is a control the reader activates, and it has to read as
   one against whatever it lands on top of. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--color-action);
  color: var(--color-action-text);
  padding: 0.75rem 1rem;
  z-index: 100;
}

.skip-link:focus {
  left: 0;
}

/* Text for a screen reader only - the name of a control whose face is an icon. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---------------------------------------------------------------- header */

/* THE APPLICATION'S TOP BAR (owner, 5 October 2026: "use the same style as the one in the React
   app"). The class names are the SPA's own - `.top-bar`, `.brand-logo`, `.nav-item` - for the
   reason the tokens above share names: two copies under different words cannot be read against
   each other. The SPA's rules are in src/client/src/index.css; change one, change the other.

   THE MEASUREMENTS ARE THE SPA'S AT A 14px ROOT. The SPA sets everything in rem against a
   root that grows with the window - 13px to 1255px, 14px to 1325px, 15px from 1326px
   (10 October 2026) - and this site's root is 16px. `--app-rem` is fixed at 14px, the SPA's
   widest root until that day, so `calc(0.875 * var(--app-rem))` here is `var(--font-size-sm)`
   there, to the pixel, only from 1256px to 1325px. From 1326px the SPA's chrome is the larger
   of the two. The header and the footer use it; page content
   does not. Measured against the SPA's built stylesheet at 1500px on 5 October 2026. */
:root {
  --app-rem: 14px;
}

/* Sticky, as the SPA's is. z-index 10 rather than its 1000: nothing on this site competes. */
.top-bar {
  position: sticky;
  top: 0;
  z-index: 10;
  background: linear-gradient(
    135deg,
    var(--color-primary-700) 0%,
    var(--color-primary-800) 100%
  );
  color: #fff;
  border-bottom: 1px solid var(--color-primary-600);
  box-shadow: 0 8px 24px -6px rgb(17 20 24 / 14%);
  font-size: var(--app-rem);
  /* The SPA's body line height. This site's is 1.65, which made every row of the chrome a
     pixel or three taller than the SPA's. */
  line-height: 1.5;
}

.top-bar-container {
  /* 1600px, wider than the page content's 1440px (owner, 10 October 2026): on the SPA's wide
     roots, 1440px no longer fitted the bar's items beside each other. The footer matches. */
  max-width: 1600px;
  margin: 0 auto;
  padding: 0 var(--app-rem);
  /* 70px, as the SPA's (owner, 10 October 2026). */
  min-height: 70px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--app-rem);
}

.brand-logo {
  display: flex;
  align-items: center;
  gap: calc(0.75 * var(--app-rem));
  text-decoration: none;
  color: #fff;
  transition: opacity 150ms ease-in-out;
}

.brand-logo:hover {
  color: #fff;
  opacity: 0.9;
}

/* Byte-identical to the SPA's public/images/fcl-bullet-2026.png, which a test checks. 40px
   (owner, 10 October 2026), drawn from a 114px source so it stays sharp at a 2x density. */
.brand-icon {
  display: block;
  height: 40px;
  width: auto;
  border: 2px solid #fff;
  border-radius: 3px;
}

.brand-text {
  display: flex;
  flex-direction: column;
}

/* DaxRegular, as in the SPA. */
.brand-name {
  font-size: calc(1.5 * var(--app-rem));
  font-weight: 700;
  line-height: 1.2;
  font-family: var(--font-heading);
}

.brand-tagline {
  font-size: calc(0.75 * var(--app-rem));
  line-height: 1;
  opacity: 0.9;
}

.main-navigation {
  flex: 1;
  min-width: 0;
  display: flex;
  justify-content: center;
  max-width: 600px;
  margin: 0 calc(2 * var(--app-rem));
}

.nav-group {
  display: flex;
  align-items: center;
  gap: calc(0.5 * var(--app-rem));
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: calc(0.5 * var(--app-rem));
  min-height: 47px;
  padding: 0 var(--app-rem);
  border-radius: calc(0.1875 * var(--app-rem));
  color: #fff;
  text-decoration: none;
  /* No font-size: the item takes the bar's, one --app-rem, the SPA's 1rem (owner,
     10 October 2026). */
  font-weight: 500;
  white-space: nowrap;
  transition: background-color 150ms ease-in-out;
}

.nav-item:hover {
  color: #fff;
  background-color: rgb(255 255 255 / 10%);
}

/* The selected item: a soft pill, a semibold label and a short accent bar beneath, exactly the
   SPA's `.nav-item.active`. The accent is the teal, which is what the SPA draws there. */
.nav-item[aria-current="page"] {
  background-color: rgb(255 255 255 / 15%);
  font-weight: 600;
}

.nav-item[aria-current="page"]::after {
  content: "";
  position: absolute;
  bottom: -2px;
  left: 50%;
  transform: translateX(-50%);
  width: 80%;
  height: 2px;
  background: var(--color-accent);
  border-radius: 1px;
}

.nav-item .icon {
  flex-shrink: 0;
}

/* The focus ring on navy is paper. The site-wide ring is --color-primary-500, which measures
   1.59:1 on the bar's #0d4262 and 2.41:1 on the footer bar's #042336 - under the 3:1 WCAG
   1.4.11 asks of a focus indicator. Paper is 10.2:1 at the worst point. The phone menu's panel
   is paper itself, so its items keep the blue ring. */
.top-bar :focus-visible,
.site-footer-band :focus-visible,
.site-footer-bar :focus-visible {
  outline-color: var(--color-background-primary);
}

.mobile-menu-panel :focus-visible {
  outline-color: var(--color-primary-500);
}

/* Register sits where the SPA puts its user menu, at its height. It is the one thing to press,
   so it is filled - in paper, because the brand-blue fill every other primary action uses would
   vanish on this navy. Sign in stood beside it in the user menu's translucent box until
   10 October 2026, and came back on 18 October as an outlined button (owner) - see
   .top-bar-button-outline. */
.header-actions {
  display: flex;
  align-items: center;
  gap: calc(0.5 * var(--app-rem));
  flex-shrink: 0;
}

.top-bar-button {
  display: inline-flex;
  align-items: center;
  min-height: 47px;
  padding: 0 calc(1.25 * var(--app-rem));
  border-radius: calc(0.1875 * var(--app-rem));
  /* No font-size: the bar's, as the nav items' (owner, 10 October 2026). */
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  transition:
    background-color 150ms ease-in-out,
    border-color 150ms ease-in-out;
}

.top-bar-button-primary {
  color: var(--color-primary-700);
  background: var(--color-background-primary);
  border: 1px solid var(--color-background-primary);
}

.top-bar-button-primary:hover {
  color: var(--color-primary-900);
  background: var(--color-primary-50);
  border-color: var(--color-primary-50);
}

/* Sign in / Open the calculator (owner, 18 October 2026): white type and a white outline on the
   navy, so Register stays the one filled thing to press. */
.top-bar-button-outline {
  color: #fff;
  background: transparent;
  border: 1px solid #fff;
}

.top-bar-button-outline:hover {
  color: #fff;
  background: rgba(255, 255, 255, 0.12);
  border-color: #fff;
}

/* THE MOBILE MENU IS A <details> DISCLOSURE, NOT A SCRIPT. The SPA opens its menu from a React
   handler; this site may carry no inline script (the apex CSP), and a menu that needs a script
   file to open is a menu that stays shut whenever the file fails. <summary> is a native button
   with its own expanded state. The panel is the SPA's `.mobile-menu`: the elevation ground,
   items with their icons, and a divider before the account links. */
.mobile-menu {
  display: none;
}

.mobile-menu-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  list-style: none;
  cursor: pointer;
  color: #fff;
  background: rgb(255 255 255 / 10%);
  border: 1px solid rgb(255 255 255 / 20%);
  border-radius: calc(0.1875 * var(--app-rem));
}

.mobile-menu-toggle::-webkit-details-marker {
  display: none;
}

.mobile-menu-toggle:hover {
  background: rgb(255 255 255 / 20%);
}

.mobile-menu[open] .mobile-menu-toggle .icon-menu,
.mobile-menu:not([open]) .mobile-menu-toggle .icon-x {
  display: none;
}

/* The bar is sticky, so scrolling the page does not move this panel. On a landscape phone it
   was taller than the screen and its last item could not be reached; it scrolls inside itself
   now. 71px is the bar: 70px and its 1px rule. */
.mobile-menu-panel {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  max-height: calc(100dvh - 71px);
  overflow-y: auto;
  padding: var(--app-rem);
  background: var(--color-background-elevation);
  border-top: 1px solid var(--color-gray-200);
  box-shadow: 0 8px 24px -6px rgb(17 20 24 / 14%);
}

.mobile-menu-panel ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.mobile-nav-item {
  display: flex;
  align-items: center;
  gap: calc(0.75 * var(--app-rem));
  padding: calc(0.75 * var(--app-rem)) var(--app-rem);
  margin-bottom: calc(0.5 * var(--app-rem));
  border-radius: calc(0.1875 * var(--app-rem));
  color: var(--color-text-primary);
  text-decoration: none;
  font-size: var(--app-rem);
}

.mobile-nav-item:hover,
.mobile-nav-item[aria-current="page"] {
  color: var(--color-text-primary);
  background: var(--color-background-secondary);
}

.mobile-nav-item[aria-current="page"] {
  font-weight: 600;
}

/* Sign in / Open the calculator, below a divider, only where the bar has dropped it. */
.mobile-menu-account {
  display: none;
  padding-top: calc(0.5 * var(--app-rem));
  border-top: 1px solid var(--color-gray-200);
}

/* The SPA's breakpoints, in the SPA's order, moved where this bar's contents need it. The SPA
   hides the brand text at 1620px because six or seven items on its larger roots need the room;
   five items and two buttons here need it at 1100px. The tagline goes at 1024px; the SPA's has
   shown at every width since 10 October 2026. The bar collapses into the menu at 900px; the
   SPA's collapses at 1410px. At 1rem (owner, 10 October 2026) the
   five items need 551px and get 501px at 801px; they fit from 851px (measured 10 October 2026).
   It was 800px while the items were 0.875rem, and 860px until "Open the calculator" joined
   Register: at 861px it overlapped Contact by 10px, and it clears it from about 881px
   (measured 18 October 2026). */
@media (max-width: 1320px) {
  .top-bar-container {
    padding: 0 calc(0.75 * var(--app-rem));
  }

  .main-navigation {
    margin: 0 var(--app-rem);
  }
}

@media (max-width: 1100px) {
  .brand-text {
    display: none;
  }
}

@media (max-width: 1024px) {
  .brand-tagline {
    display: none;
  }
}

@media (max-width: 900px) {
  .main-navigation {
    display: none;
  }

  .mobile-menu {
    display: block;
  }

  .brand-text {
    display: flex;
  }
}

@media (max-width: 420px) {
  .brand-text {
    display: none;
  }
}

/* "Open the calculator" beside Register overflowed the bar up to 441px and squeezed the logo
   at 320px (measured 18 October 2026), so at 460px and below the button moves into the menu. */
@media (max-width: 460px) {
  .top-bar-button-outline {
    display: none;
  }

  .mobile-menu-account {
    display: block;
  }
}

/* ---------------------------------------------------------------- buttons */

/* ONE SIZE, THE HERO'S (owner, 10 October 2026). The content buttons were 0.5rem x 1.125rem at
   1rem and read a touch small beside the hero's; the `.button-large` modifier that made the
   difference is gone, so no button can be sized apart again. A test fails if another rule
   resizes a `.button`. */
.button {
  display: inline-block;
  padding: 0.75rem 1.75rem;
  border-radius: var(--radius-lg);
  font-weight: 600;
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
  font-size: 1.0625rem;
  font-family: inherit;
  line-height: 1.5;
}

/* Register, Get started, Send - the thing the reader is here to press. Ink, never a hue. */
.button-primary {
  background: var(--color-action);
  border-color: var(--color-action);
  color: var(--color-action-text);
}

.button-primary:hover {
  background: var(--color-action-hover);
  border-color: var(--color-action-hover);
  color: var(--color-action-text);
}

/* The second choice beside it. Ink text on paper inside a rule, which is how the SPA draws its
   own secondary button; the hover firms the rule up exactly as a text input's does. */
.button-quiet {
  background: transparent;
  border-color: var(--color-gray-200);
  color: var(--color-text-primary);
}

.button-quiet:hover {
  border-color: var(--color-gray-600);
  color: var(--color-text-primary);
}

.button:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

/* ---------------------------------------------------------------- hero */

.hero {
  padding: clamp(3rem, 8vw, 6rem) 0;
  background: linear-gradient(
    180deg,
    var(--color-primary-50),
    var(--color-background-primary)
  );
  border-bottom: 1px solid var(--color-gray-200);
}

.hero-eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--color-primary-500);
  margin-bottom: 0.75rem;
}

.hero h1 {
  max-width: 18ch;
}

.hero-lead {
  font-size: clamp(1.0625rem, 1rem + 0.4vw, 1.3125rem);
  color: var(--color-gray-700);
  max-width: 46ch;
}

.hero-actions {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-top: 1.5rem;
}

/* A band carrying the telephone number, not a control. Brand, therefore, not ink. */
.strip {
  background: var(--color-primary-900);
  color: var(--color-action-text);
  padding: 0.875rem 0;
}

.strip a {
  color: var(--color-action-text);
  font-weight: 600;
}

/* The global ring, primary-500, is 2.41:1 on this navy - under the 3:1 a focus indicator needs.
   Paper is 15.5:1 on it (measured 7 October 2026). */
.strip :focus-visible {
  outline-color: var(--color-background-primary);
}

.strip-inner p {
  margin: 0;
}

/* ---------------------------------------------------------------- content */

/* Every other page opens on the homepage hero's band (5 October 2026), smaller: the same
   gradient and the same rule beneath it, so a visitor moving from the homepage to About lands
   on the same ground. It was a bare heading on the page tint until then. */
.page-head {
  padding: clamp(2rem, 5vw, 3.5rem) 0;
  background: linear-gradient(
    180deg,
    var(--color-primary-50),
    var(--color-background-primary)
  );
  border-bottom: 1px solid var(--color-gray-200);
}

.page-head h1 {
  margin-bottom: 0.25em;
}

.page-head-lead {
  font-size: 1.1875rem;
  color: var(--color-gray-600);
  margin: 0;
}

.heading-block {
  max-width: var(--measure);
  margin-bottom: 2rem;
}

.heading-block.center {
  margin-inline: auto;
  text-align: center;
}

.section-actions {
  margin-top: 1.5rem;
}

.card-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
}

/* THE SHARED SURFACES, ported from the SPA's `styles/surfaces.css` (31 August 2026).
 *
 * Four names, and every panel, form panel, table panel and card on this site is built from
 * them - exactly as in the application. They are restated rather than imported because no one
 * origin serves both sites; that is the same reason each surface holds its own copy of Inter.
 *
 *   .surface          the box: paper, a hairline border, a soft shadow
 *   .surface-header   the bar across its top: tinted ground, a brand rule beneath it
 *   .surface-body     the content area inside it: paper, padded
 *   .surface-card     the box with padding where the header bar would be
 *
 * A TABLE PANEL AND A HEADED CARD ARE THE SAME THING - there is no separate name for either,
 * only `.surface` with something in its body.
 */

.surface {
  background: var(--color-background-elevation);
  border: 1px solid var(--color-gray-200);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}

/* The bar's ground is the same token as the PAGE ground, so it reads as a recess cut into the
   panel rather than as a second card stacked on the first. The brand rule separates the two. */
.surface-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem 1.25rem;
  background: var(--color-background-secondary);
  border-bottom: 1px solid var(--color-primary-700);
}

.surface-header h2,
.surface-header h3 {
  margin: 0;
  color: var(--color-primary-700);
  font-size: 1.25rem;
}

.surface-body {
  padding: 1.5rem;
  background: var(--color-background-primary);
}

.surface-body--flush {
  padding: 0;
}

/* A card is the same box with padding instead of a bar. `.card` is kept as the name the
   markup already uses and now carries only what is specific to it. */
.surface-card,
.card {
  background: var(--color-background-elevation);
  border: 1px solid var(--color-gray-200);
  border-radius: var(--radius-lg);
  padding: 1.25rem;
  box-shadow: var(--shadow-sm);
}

.card h3 {
  margin-bottom: 0.35rem;
}

.card p {
  margin: 0;
  color: var(--color-gray-700);
  font-size: 0.9375rem;
}

/* ---------------------------------------------------------------- homepage */

/* The hero in two columns, the product on the right (owner, 5 October 2026: mock-up version B).
   Below 60rem the laptop goes under the text. */
.hero-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: 3rem;
  align-items: center;
}

@media (max-width: 60rem) {
  .hero-split {
    grid-template-columns: 1fr;
  }
}

/* The rotated base of the laptop is wider than its column; clip it rather than let it widen
   the page on a phone. */
.hero {
  overflow-x: clip;
}

/* THE LAPTOP IS DRAWN, NOT PHOTOGRAPHED. A stock photo is an image licence (C8), it blurs at
   some width, and it goes stale the day the schedule changes; this is markup and needs none of
   that. The screen is a size container, so everything on it is sized in `cqi` and the whole
   picture scales as one at any width. */
.laptop {
  margin: 0;
}

.laptop-lid {
  position: relative;
  padding: 2.2% 2.2% 3%;
  background: #1c2026;
  border-radius: 14px 14px 4px 4px;
  box-shadow:
    0 24px 48px -16px rgb(13 66 98 / 35%),
    inset 0 0 0 1px #2c323a;
}

/* The camera. */
.laptop-lid::before {
  content: "";
  position: absolute;
  top: 1%;
  left: 50%;
  width: 0.45rem;
  height: 0.45rem;
  margin-left: -0.225rem;
  border-radius: 50%;
  background: #3a414b;
}

.laptop-screen {
  display: flex;
  flex-direction: column;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  border-radius: 2px;
  background: #e8e6e3;
  container-type: inline-size;
}

.laptop-base {
  position: relative;
  height: 14px;
  margin: 0 -7%;
  background: linear-gradient(#d9d6d1, #b9b5ae);
  border-radius: 0 0 14px 14px;
  box-shadow: 0 10px 20px -8px rgb(17 20 24 / 35%);
}

/* The notch you open the lid with. */
.laptop-base::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  width: 16%;
  height: 5px;
  margin-left: -8%;
  background: #a9a49c;
  border-radius: 0 0 6px 6px;
}

/* A PDF viewer's bar, so the screen reads as the downloaded document. */
.viewer-bar {
  flex: none;
  display: flex;
  align-items: center;
  gap: 1.4cqi;
  padding: 1.1cqi 2cqi;
  background: #323639;
  color: #e8eaed;
  font-size: 1.7cqi;
  line-height: 1.4;
}

.viewer-dots {
  display: flex;
  gap: 0.8cqi;
}

.viewer-dots i {
  display: block;
  width: 1.3cqi;
  height: 1.3cqi;
  border-radius: 50%;
  background: #5f6368;
}

.viewer-name {
  flex: 1;
}

.viewer-zoom {
  opacity: 0.75;
}

.viewer-body {
  flex: 1;
  overflow: hidden;
  padding: 2.6cqi 9cqi 0;
}

/* THE SHEET IS INK ON WHITE, NOT THE SITE'S BLUE ON PAPER. It is a picture of the downloaded
   schedule, and that document is Word's default black (owner ruling, 5 September 2026). The one
   accent marks the total, which is what the accent is for. */
.sheet {
  min-height: 100%;
  padding: 3.2em 3.6em 3em;
  background: #fff;
  color: #111418;
  box-shadow: 0 1px 3px rgb(0 0 0 / 25%);
  font-size: 1.55cqi;
  line-height: 1.4;
}

.sheet-heading {
  margin: 0 0 0.45em;
  font-size: 1.2em;
  font-weight: 700;
}

.sheet table {
  width: 100%;
  margin-bottom: 1.1em;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}

.sheet th,
.sheet td {
  padding: 0.28em 0.5em;
  border: 1px solid #111418;
  text-align: left;
}

.sheet .num {
  text-align: right;
}

.sheet .total td {
  font-weight: 700;
}

.sheet .total .num {
  background: var(--color-accent-tint);
}

.laptop-caption {
  margin-top: 1.5rem;
  font-size: 0.875rem;
  color: var(--color-gray-600);
  text-align: center;
}

.laptop-caption a {
  display: block;
  margin-top: 0.25rem;
  font-weight: 600;
}

/* Two short sections side by side as cards, so neither leaves an empty right half. */
.two-col {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 2.5rem;
}

@media (max-width: 48rem) {
  .two-col {
    grid-template-columns: 1fr;
  }
}

.two-col .surface-card {
  padding: 1.75rem;
}

.two-col h2 {
  font-size: 1.5rem;
}

.two-col .section-actions {
  margin-bottom: 0;
}

/* A grid with no empty slot. Eight cards since ASHE joined on 7 October 2026: at three columns
   the first spans two, so they fill three rows of three; at two columns it spans one, so they
   fill four rows of two; then one column. (Seven cards filled two rows of four until then.) The
   class keeps its name so the design options need not chase a rename. */
.card-grid-4 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.card-grid-4 .card-feature {
  grid-column: span 2;
  border-top: 3px solid var(--color-primary-700);
}

.card-feature h3 {
  font-size: 1.375rem;
}

.card-feature p {
  font-size: 1rem;
}

@media (max-width: 60rem) {
  .card-grid-4 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .card-grid-4 .card-feature {
    grid-column: auto;
  }
}

@media (max-width: 36rem) {
  .card-grid-4 {
    grid-template-columns: 1fr;
  }

  .card-grid-4 .card-feature {
    grid-column: auto;
  }
}

/* What kind of tool a card is, over its name. */
.card .card-kind {
  margin-bottom: 0.35rem;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-gray-600);
}

/* THE SPA'S SECTION ICON CIRCLE (`.surface-header-icon-circle` in styles/surfaces.css), on a
   card. The Contact page's three cards use it. */
.icon-circle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  margin-bottom: 0.75rem;
  border-radius: 50%;
  background: var(--color-primary-50);
  color: var(--color-primary-700);
}

.icon-circle .icon {
  width: 24px;
  height: 24px;
}

/* The homepage's service cards carry legacy's own icons (owner, 6 October 2026). The artwork
   is white on a transparent ground, so the ground behind it is drawn here, as legacy's
   `.feature-box .fbox-icon img` drew it. Legacy's was a 64px circle in its blue. The size,
   the padding, the corners and the lighter ground are the owner's, the same day: 150px with
   15px of padding, so the artwork is 120px (box-sizing is border-box), and the brand blue mixed
   15% towards white for texture. White on it measures 6.97:1. */
.service-icon {
  display: block;
  width: 150px;
  height: 150px;
  padding: 15px;
  margin-bottom: 0.75rem;
  /* 3px and !important by owner instruction; legacy drew a circle. */
  border-radius: 3px !important;
  background: color-mix(in srgb, var(--color-primary-700) 85%, white);
}

/* Contact's three ways to reach us, as one complete row. */
.card-grid-3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

@media (max-width: 52rem) {
  .card-grid-3 {
    grid-template-columns: 1fr;
  }
}

.card-grid-3 .card h2 {
  font-size: 1.25rem;
  margin-bottom: 0.5rem;
}

.card-grid-3 .card p,
.card-grid-3 .card address {
  font-size: 1rem;
}

.card-grid-3 .card p + p {
  margin-top: 0.5rem;
}

.card-grid-3 .contact-large {
  font-size: 1.1875rem;
  overflow-wrap: anywhere;
}

/* Two columns of feature bullets on the pricing page. Legacy split its eighteen across
   two hand-written `col_half` divs, which fixes the split point and cannot reflow; CSS
   columns let the browser choose, so a narrow screen gets one column without a media
   query and the list stays one <ul> in the markup. */
.feature-list {
  list-style: none;
  margin: 0;
  padding: 0;
  columns: 2;
  column-gap: 2.5rem;
  max-width: 52rem;
  margin-inline: auto;
}

.feature-list li {
  break-inside: avoid;
  padding: 0.5rem 0 0.5rem 1.5rem;
  position: relative;
  color: var(--color-gray-700);
}

.feature-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 1.1rem;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--color-primary-500);
}

@media (max-width: 40rem) {
  .feature-list {
    columns: 1;
  }
}

/* The same bullets as one column at the start of its container: the homepage's two legacy
   lists, "The complete loss of earnings calculator" and "You can". */
.feature-list.feature-list-single {
  columns: 1;
  margin-inline: 0;
}

/* Legacy's Benefits page on About: its own icon beside each benefit, two to a row. The icons are
   legacy's 512px files drawn at 56px, with the size in the markup so nothing moves as they
   load. */
.benefit-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.75rem 2.5rem;
}

.benefit {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
}

.benefit img {
  flex: none;
  width: 56px;
  height: 56px;
}

.benefit h3 {
  font-size: 1.125rem;
  margin-bottom: 0.25rem;
}

.benefit p {
  font-size: 1rem;
  color: var(--color-gray-700);
}

@media (max-width: 48rem) {
  .benefit-grid {
    grid-template-columns: 1fr;
  }
}

.contact-large {
  font-size: 1.375rem;
  font-weight: 600;
}

/* ---------------------------------------------------------------- notices */

.notice {
  border-radius: var(--radius-lg);
  padding: 1rem 1.25rem;
  margin-bottom: 1.5rem;
  border: 1px solid;
}

.notice p:last-child {
  margin-bottom: 0;
}

/* Each rule is a mix of the notice's own two tokens rather than a fourth hand-picked literal,
   so a family cannot end up with a border that belongs to no palette. Where `color-mix` is not
   supported the shorthand above leaves the border at `currentColor`, which is that notice's
   text colour - heavier than intended, still the right family. */
.notice-info {
  background: var(--color-info-50);
  border-color: color-mix(
    in srgb,
    var(--color-info-600) 30%,
    var(--color-info-50)
  );
  color: var(--color-info-600);
}

.notice-warning {
  background: var(--color-warning-50);
  border-color: color-mix(
    in srgb,
    var(--color-warning-700) 30%,
    var(--color-warning-50)
  );
  color: var(--color-warning-700);
}

.notice-error {
  background: var(--color-error-50);
  border-color: color-mix(
    in srgb,
    var(--color-error-700) 30%,
    var(--color-error-50)
  );
  color: var(--color-error-700);
}

/* The one green left on the site, and the reason green is no longer allowed on a button. */
.notice-success {
  background: var(--color-success-100);
  border-color: color-mix(
    in srgb,
    var(--color-success-700) 30%,
    var(--color-success-100)
  );
  color: var(--color-success-800);
}

.notice h2 {
  margin-top: 0;
  font-size: 1.25rem;
  color: inherit;
}

/* ---------------------------------------------------------------- forms */

.form {
  max-width: 34rem;
}

.field {
  margin-bottom: 1.125rem;
}

.field label {
  display: block;
  font-weight: 600;
  margin-bottom: 0.3rem;
}

.field-optional {
  font-weight: 400;
  color: var(--color-gray-600);
}

.field input {
  width: 100%;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--color-gray-300);
  border-radius: var(--radius-md);
  font: inherit;
  color: inherit;
  background: var(--color-background-primary);
  transition:
    border-color 150ms ease-in-out,
    box-shadow 150ms ease-in-out;
}

.field input:hover {
  border-color: var(--color-gray-600);
}

/* The SPA's focus treatment. This input had none at all, so a keyboard user got whatever the
   browser draws by default - which on a bordered input is easy to miss. */
.field input:focus {
  outline: none;
  border-color: var(--color-primary-700);
  box-shadow: 0 0 0 3px rgb(0 67 92 / 12%);
}

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

.field-error {
  color: var(--color-error-700);
  font-size: 0.9375rem;
  margin: 0.35rem 0 0;
  font-weight: 500;
}

.form-actions {
  margin-top: 1.5rem;
}

.form-status {
  margin-top: 0.75rem;
  color: var(--color-gray-600);
  min-height: 1.5rem;
}

/* ---------------------------------------------------------------- legal */

.legal-body {
  font-size: 1rem;
}

.legal-body h2 {
  margin-top: 2rem;
  font-size: 1.375rem;
}

.legal-body h3 {
  margin-top: 1.5rem;
}

.legal-body ul,
.legal-body ol {
  padding-left: 1.5rem;
}

.legal-body li {
  margin-bottom: 0.4rem;
}

/* THE SPA'S `.data-table`. The Cookie Policy is the only table this site renders - it comes
   from `docs/legal/cookie-policy.md` through the markdown pipeline, so there is no markup to
   put a class on and the treatment has to hang off the element. A tinted head with small
   uppercase labels over a heavier rule, then paper rows separated by hairlines.

   `display: block` is what makes a too-wide table scroll rather than widen the page, and it is
   why the box lives on the table itself rather than on a container the markdown cannot emit. */
.legal-body table {
  width: 100%;
  border-collapse: collapse;
  margin: 1.5rem 0;
  display: block;
  overflow-x: auto;
  background: var(--color-background-primary);
  border: 1px solid var(--color-gray-200);
  border-radius: var(--radius-md);
}

.legal-body thead {
  background: var(--color-background-secondary);
}

.legal-body th {
  padding: 0.65rem;
  text-align: left;
  vertical-align: top;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--color-gray-700);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  border-bottom: 2px solid var(--color-gray-300);
}

.legal-body td {
  padding: 0.5rem 0.65rem;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--color-gray-200);
}

.legal-body tbody tr:last-child td {
  border-bottom: none;
}

/* ---------------------------------------------------------------- footer */

/* THE FOOTER'S RULES ARE IN src/shared/site-footer.css, shared with the SPA and linked after
   this file (owner, 6 October 2026). A change there reaches both sites. The markup is two
   copies - layout.njk here, Footer.tsx in the SPA - so change one, change the other.
   Below is only what is this site's own. --app-rem, which sizes the shared rules, is set
   with the header. */
:root {
  --site-footer-band-image: url("/assets/images/footer-bg.jpg");
}

/* The SPA's body line height, as on the top bar. */
.site-footer {
  line-height: 1.5;
}

/* A page that ends in its closing band runs straight into the footer. The margin above is for
   a page that ends in plain content; under a coloured band it showed as a strip of the page
   ground between two bands, which read as a gap nobody meant. */
main:has(> .section-cta:last-child) + .site-footer {
  margin-top: 0;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

@media (max-height: 768px) {
  html {
    font-size: 14px;
  }

  .hero,
  .chapter {
    padding-top: 1rem !important;
  }

  .page-head {
    padding: 1rem;
  }
}
