/* fonts.css is linked directly from views/layouts/main.ejs, ahead of this file.
   The @import that used to sit here was removed in Task 4: an @import serialises
   the font request behind this stylesheet's own request, which costs render time
   for no benefit once the <link> exists. */

/* ==========================================================================
   K12 PDTracker — public marketing site
   "Clear Path, Faculty Voice"

   Two layers:
     1. TOKENS   — every color, size, space, radius, shadow and focus value,
                   declared once on :root, plus the Bootstrap 5 bridge.
     2. COMPONENTS — built only from those tokens. No raw hex below :root.

   Source of truth for the visual result: docs/design/homepage-reference.html.
   Source of truth for the token values:  docs/plans/2026-07-29-marketing-site-redesign.md
   (Global Constraints).

   Load order in views/layouts/main.ejs is bootstrap.min.css, then fonts.css,
   then this file, so the :root block below re-points Bootstrap's own custom
   properties at these tokens rather than fighting them with !important.
   ========================================================================== */

/* ==========================================================================
   1. TOKENS
   ========================================================================== */

:root {
  /* --- Surfaces ------------------------------------------------------- */
  --paper: #FFFFFF;          /* primary ground */
  --mist: #F6F4FA;           /* alternating band ground; purple-biased, not grey */
  --mist-2: #EEEAF5;         /* recessed track, e.g. the progress bar */
  --paper-dim: #EDE9F2;      /* hover state of a white button on a dark band */

  /* --- Hairlines ------------------------------------------------------- */
  --line: #E3DEEC;
  --line-2: #D3CBE3;
  /* Brand grey. BORDER USE ONLY: measured 2.38:1 on paper, so it can never
     carry text and can never be the only boundary of an interactive control.
     Used once, on the decorative <hr>. */
  --grey-border: #A3A9AC;

  /* --- Ink.
         Ratios below are measured with the WCAG 2.x relative-luminance
         formula, not copied from the plan. Where the two disagree the
         measured figure is the one that governs use. -------------------- */
  --ink: #221F20;            /* 16.34:1 on paper (plan says 15.5) */
  --ink-2: #5A5560;          /*  7.23:1 on paper, 6.63:1 on mist */
  /* --ink-3 measures 4.36:1 on paper, NOT the 4.6:1 the plan states, so it
     is below the 4.5:1 AA threshold for text. It is therefore used for
     borders and icons only (both need 3:1), never for copy. Captions that
     the reference set in ink-3 use --ink-2 here. */
  --ink-3: #7D7688;

  /* --- Accent (single hue, no second color) ---------------------------- */
  --purple: #6E3DAE;         /* 7.14:1 on paper, 6.03:1 on chalk */
  --plum: #4D1979;           /* 12.13:1 on paper — eyebrows, labels, focus, year band */
  --lilac: #F0EAF9;          /* icon wells, badges, emphasized pricing column */
  --lilac-mark: #E0D2F3;     /* the hero underline */
  --lilac-light: #D9C7F2;    /* labels and markers on the plum band only, 7.74:1 there */

  /* --- The one warm note: the Trust band, and nowhere else --------------- */
  --chalk: #F2EBE1;          /* ink 13.81:1, purple 6.03:1, plum 10.25:1 */
  --chalk-line: #DED4C6;     /* hairlines inside the Trust band only */

  /* --- Copy on dark grounds -------------------------------------------- */
  --ink-inv: #B7AFBC;        /* body copy on the near-black final band, 7.68:1 */
  --ink-inv-2: #D6D0DA;      /* base copy on the near-black final band, 10.81:1 */
  --on-plum: #DCCDEE;        /* base copy on the plum band, 8.10:1 */
  --on-plum-2: #C6B2E0;      /* secondary copy on the plum band, 6.27:1 */

  /* --- Footer (near-black ground) --------------------------------------- */
  --ftr-text: #A9A2AC;       /* 6.58:1 on --ink */
  --ftr-link: #D2CBD7;       /* 10.32:1 on --ink */
  /* The reference used #8B8390 here; measured 4.47:1 on ink, which fails AA.
     Lightened to 4.84:1. */
  --ftr-head: #918995;
  /* The footer brand-text tint token was deleted with the hand-built CSS
     lockup: the footer mark is now the real white PNG, so no rule tints
     brand type and nothing consumed the token any more. */
  --ftr-line: #3A343C;
  --ftr-chip-line: #453E48;
  --ftr-chip-hover: #312B33;

  /* --- Status. Semantic, separate from the accent. Never color alone:
         each is always paired with an icon AND a word. -------------------- */
  --green: #1B6B3A;          /* approved,   5.70:1 on --green-tint (plan says 6.2) */
  --green-tint: #E4F3E9;
  --amber: #8A5A05;          /* in review,  5.37:1 on --amber-tint (plan says 5.8) */
  --amber-tint: #FDF3DE;
  --amber-line: #E9D3A4;     /* no consumer since .note-tag was deleted; kept so the
                                amber status pair has a border to match --green /
                                --rose usage if a bordered status chip is ever added */
  --rose: #A3243A;           /* due / returned, 6.26:1 on --rose-tint (plan says 7.0) */
  --rose-tint: #FBE9EC;

  /* --- Translucent overlays (no hex, so they stay readable as tokens) ---- */
  --hdr-bg: rgb(255 255 255 / 0.93);
  --bar-bg: rgb(255 255 255 / 0.96);
  --on-plum-line: rgb(255 255 255 / 0.30);
  --on-plum-line-2: rgb(255 255 255 / 0.17);
  --on-ink-line: rgb(255 255 255 / 0.50);
  --on-ink-wash: rgb(255 255 255 / 0.14);

  /* --- Families --------------------------------------------------------- */
  --font-sans: "Figtree", "Avenir Next", "Segoe UI", system-ui, Arial, sans-serif;
  --font-serif: "Source Serif 4", "Iowan Old Style", Palatino, Georgia, serif;
  --font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;

  /* --- Type scale. 11 / 12.5 / 13.5 / 14.5 / 16 / 17.5 / 19 / 22 / 24 / 41 / 57.
         Expressed in rem against a 16px root so a user's own font-size
         preference scales the whole page; the px comment is the value at the
         default root size. ------------------------------------------------ */
  --fs-11:    0.6875rem;  /* 11px    */
  --fs-12-5:  0.78125rem; /* 12.5px  */
  --fs-13-5:  0.84375rem; /* 13.5px  */
  --fs-14-5:  0.90625rem; /* 14.5px  */
  --fs-16:    1rem;       /* 16px — body minimum, so iOS does not zoom fields */
  --fs-17-5:  1.09375rem; /* 17.5px  */
  --fs-19:    1.1875rem;  /* 19px    */
  --fs-22:    1.375rem;   /* 22px    */
  --fs-24:    1.5rem;     /* 24px    */
  --fs-41:    2.5625rem;  /* 41px    */
  --fs-57:    3.5625rem;  /* 57px    */

  --lh-tight: 1.1;
  --lh-heading: 1.2;
  --lh-body: 1.6;

  --ls-tight: -0.022em;   /* sans headings */
  --ls-serif: -0.005em;   /* serif headings */
  --ls-caps: 0.15em;      /* eyebrows and small caps labels */

  /* --- Spacing, 4px base ------------------------------------------------ */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 20px;
  --sp-6: 24px;
  --sp-7: 28px;
  --sp-8: 32px;
  --sp-9: 36px;
  --sp-10: 40px;
  --sp-11: 44px;
  --sp-12: 48px;
  --sp-14: 56px;
  --sp-16: 64px;
  --sp-18: 72px;
  --sp-19: 76px;
  --sp-22: 88px;

  /* --- Radii. 6 / 10 / 14 / 16 only ------------------------------------- */
  --r-xs: 6px;
  --r-sm: 10px;
  --r-md: 14px;
  --r-lg: 16px;

  /* --- Elevation. Two shadows; everything else is a 1px border. --------- */
  --shadow-1: 0 18px 44px -30px rgb(34 31 32 / 0.45);
  --shadow-2: 0 24px 54px -34px rgb(34 31 32 / 0.45);
  --ring-lilac: 0 0 0 3px var(--lilac);

  /* --- Focus ------------------------------------------------------------ */
  --focus-outline: 3px solid var(--plum);
  --focus-offset: 3px;

  /* --- Layout ----------------------------------------------------------- */
  --wrap-max: 1140px;
  --measure: 68ch;
  --hit: 44px;   /* minimum interactive target */

  /* --- Brand lockup display widths.
         Off the 4px spacing grid on purpose: each is the exact intrinsic width
         of the 1x PNG it displays, so on a 1x screen the browser does no
         resampling and the artwork stays sharp. Heights follow from the
         width/height attributes in the markup (48px, 40px and 41px). --------- */
  --brand-w: 245px;         /* header, above 1240px */
  --brand-w-tight: 204px;   /* header, 1240px and below */
  --brand-w-ftr: 210px;     /* footer, all widths */

  /* --- Bootstrap 5.3 bridge.
         Bootstrap declares these on :root as well; this file loads after it,
         so equal specificity plus later source order wins. No !important. -- */
  --bs-font-sans-serif: var(--font-sans);
  --bs-body-font-family: var(--font-sans);
  --bs-body-font-size: var(--fs-16);
  --bs-body-font-weight: 400;
  --bs-body-line-height: var(--lh-body);
  --bs-body-color: var(--ink);
  --bs-body-color-rgb: 34, 31, 32;
  --bs-body-bg: var(--paper);
  --bs-body-bg-rgb: 255, 255, 255;
  --bs-emphasis-color: var(--ink);
  --bs-emphasis-color-rgb: 34, 31, 32;
  --bs-secondary-color: var(--ink-2);
  --bs-secondary-bg: var(--mist);
  --bs-tertiary-color: var(--ink-2);
  --bs-tertiary-bg: var(--mist-2);
  --bs-heading-color: var(--ink);
  --bs-border-color: var(--line);
  --bs-border-color-translucent: var(--line);
  --bs-border-radius: var(--r-sm);
  --bs-border-radius-sm: var(--r-xs);
  --bs-border-radius-lg: var(--r-md);
  --bs-border-radius-xl: var(--r-lg);
  --bs-border-radius-xxl: var(--r-lg);
  --bs-primary: var(--purple);
  --bs-primary-rgb: 110, 61, 174;
  --bs-primary-text-emphasis: var(--plum);
  --bs-primary-bg-subtle: var(--lilac);
  --bs-primary-border-subtle: var(--line-2);
  --bs-link-color: var(--purple);
  --bs-link-color-rgb: 110, 61, 174;
  --bs-link-hover-color: var(--plum);
  --bs-link-hover-color-rgb: 77, 25, 121;
  --bs-code-color: var(--plum);
  --bs-focus-ring-width: 3px;
  --bs-focus-ring-offset: 3px;
  --bs-focus-ring-color: var(--plum);
  --bs-success: var(--green);
  --bs-success-rgb: 27, 107, 58;
  --bs-warning: var(--amber);
  --bs-warning-rgb: 138, 90, 5;
  --bs-danger: var(--rose);
  --bs-danger-rgb: 163, 36, 58;
}

/* ==========================================================================
   2. BASE
   ========================================================================== */

html {
  height: 100%;
}

body {
  height: 100%;
  min-height: 100vh;
  margin: 0;
  display: flex;
  flex-direction: column;
  background-color: var(--paper);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--fs-16);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

main#content {
  flex: 1 0 auto;
}

h1, h2, h3, h4 {
  font-weight: 700;
  letter-spacing: var(--ls-tight);
  text-wrap: balance;
  color: var(--ink);
}

a {
  color: var(--purple);
  text-decoration: none;
}

a:hover {
  color: var(--plum);
  text-decoration: underline;
}

img,
svg {
  max-width: 100%;
}

/* The brand grey is a border color and nothing else. A decorative rule is
   the only thing on this site that uses it. */
hr {
  height: 0;
  margin: var(--sp-8) 0;
  border: 0;
  border-top: 1px solid var(--grey-border);
  opacity: 1;
}

/* Hours, dates and prices line up in columns. */
.tabular {
  font-variant-numeric: tabular-nums;
}

/* --- Focus. Visible on every interactive element. No rule in this file, or
       in fonts.css, ever suppresses an outline. -------------------------- */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: var(--focus-outline);
  outline-offset: var(--focus-offset);
  border-radius: var(--r-xs);
}

/* On the plum and near-black bands a plum ring is invisible, so the ring
   flips to the light label color there. */
.year a:focus-visible,
.year button:focus-visible,
.final a:focus-visible,
.final button:focus-visible,
.ftr a:focus-visible,
.ftr button:focus-visible {
  outline-color: var(--lilac-light);
}

/* --- Skip link -------------------------------------------------------- */
.skip-link {
  position: absolute;
  left: var(--sp-4);
  top: -200%;
  z-index: 1080;
  padding: var(--sp-3) var(--sp-4);
  min-height: var(--hit);
  display: inline-flex;
  align-items: center;
  background: var(--plum);
  color: var(--paper);
  font-size: var(--fs-16);
  font-weight: 600;
  border-radius: var(--r-xs);
  text-decoration: none;
}

.skip-link:focus {
  top: var(--sp-4);
  color: var(--paper);
  text-decoration: none;
}

/* ==========================================================================
   3. LAYOUT PRIMITIVES
   ========================================================================== */

.wrap {
  max-width: var(--wrap-max);
  margin-inline: auto;
  padding-inline: var(--sp-10);
}

.sec {
  padding-block: var(--sp-22);
}

.sec-head {
  max-width: 60ch;
}

.sec-head h2 {
  font-size: clamp(var(--fs-24), 3.1vw, var(--fs-41));
  line-height: var(--lh-tight);
  margin: var(--sp-3) 0 0;
}

.sec-head p {
  font-size: var(--fs-17-5);
  line-height: var(--lh-body);
  color: var(--ink-2);
  margin: var(--sp-4) 0 0;
}

.eyebrow {
  margin: 0;
  font-size: var(--fs-11);
  font-weight: 700;
  line-height: 1;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--plum);
}

/* The serif voice. Used only inside a .voice wrapper, which on the homepage
   wraps exactly two sections: "Solution" (#solution) and "How a year runs". */
.voice h1,
.voice h2,
.voice h3 {
  font-family: var(--font-serif);
  font-weight: 600;
  letter-spacing: var(--ls-serif);
}

/* --- Band grounds ------------------------------------------------------ */

/* .band-mist is the general-purpose cool band and is used on ten views.
   .band-chalk, .band-plum and .band-ink were speculative siblings of it, added
   for a generic-band API no page ever called: the warm, plum and near-black
   grounds are only ever reached through .trust-band, .year and .final. They were
   deleted rather than kept as aliases, so there is one name per ground. */
.band-mist,
.ba,
.start {
  background: var(--mist);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.trust-band {
  background: var(--chalk);
  border-top: 1px solid var(--chalk-line);
  border-bottom: 1px solid var(--chalk-line);
}

/* Cards inside the Trust band stay white; only their hairlines go warm. */
.trust-band .tcard,
.trust-band .honest,
.trust-band .wslot {
  background: var(--paper);
  border-color: var(--chalk-line);
}

/* ==========================================================================
   4. BRAND LOCKUP

   One rule set, two consumers: the header (purple PNG) and the footer (white
   PNG). The hand-built CSS lockup this replaced (a bordered square holding
   type, beside two lines of set text) was a stand-in for the real artwork and
   has been deleted along with its four rules.

   The asset is a stacked lockup: a ruled K12 box beside two lines of type,
   5.096:1. Two things follow from that shape.

   1. Vertical centering is honest. In the master PNG the box bleeds to the top
      and bottom edges and is symmetric about the middle, so the artwork's
      optical center is its geometric center. `align-items: center` on the
      header row and on this anchor is therefore all that is needed; no nudge.

   2. Optical size is driven by the type, not the overall height. Two stacked
      lines mean each line's cap height is only about 0.31 of the image height,
      so 48px tall gives roughly a 15px cap height, about 1.4x the 14.5px nav
      items. That ratio is what makes the brand read as the brand rather than
      as a sixth nav item, and it is why the lockup is only shrunk when
      horizontal space actually forces it (see section 22).

   The anchor keeps its 44x44 minimum target through min-height even at the
   204px / 40px and 210px / 41px sizes, where the image alone is under 44 tall.
   ========================================================================== */

.brand {
  display: inline-flex;
  align-items: center;
  flex: none;
  min-height: var(--hit);
  text-decoration: none;
}

.brand img {
  display: block;
  width: var(--brand-w);
  /* height stays auto so the ratio comes from the width/height attributes in
     the markup. The box is reserved before the bytes land: no layout shift. */
  height: auto;
  /* A no-op in the header, where .brand is a flex: none item sized by this
     image. It bites in the footer, where .brand is an inline-flex box in normal
     flow and so shrinks to the grid column: on a very narrow phone the mark
     scales down instead of pushing the column wide. */
  max-width: 100%;
  transition: opacity 120ms ease;
}

/* The lockup is artwork, so hover cannot be a color change the way it was when
   the mark was type in currentColor. A slight lift of the ground through it
   reads as the whole anchor responding, and works on both the white header and
   the near-black footer. Focus is handled by the global :focus-visible ring. */
.brand:hover img {
  opacity: 0.82;
}

/* ==========================================================================
   5. BUTTONS
   Solid, outline, text. 48px minimum height; .btn-sm 44px, which is the
   smallest size that still satisfies the 44x44 target rule.
   ========================================================================== */

.btn,
a.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: var(--sp-12);
  padding: var(--sp-4) var(--sp-6);
  border: 1.5px solid transparent;
  border-radius: var(--r-sm);
  font-family: var(--font-sans);
  font-size: var(--fs-16);
  font-weight: 600;
  line-height: 1;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}

.btn:hover {
  text-decoration: none;
}

.btn svg,
.btn i {
  flex: none;
}

.btn-solid {
  background: var(--purple);
  border-color: var(--purple);
  color: var(--paper);
}

.btn-solid:hover {
  background: var(--plum);
  border-color: var(--plum);
  color: var(--paper);
}

.btn-line {
  background: var(--paper);
  border-color: var(--line-2);
  color: var(--ink);
}

.btn-line:hover {
  background: var(--mist);
  border-color: var(--purple);
  color: var(--purple);
}

.btn-text {
  background: none;
  border-color: transparent;
  padding-inline: var(--sp-2);
  color: var(--purple);
}

.btn-text:hover {
  background: var(--lilac);
  color: var(--plum);
}

.btn-sm {
  min-height: var(--hit);
  padding: var(--sp-3) var(--sp-4);
  font-size: var(--fs-14-5);
}

/* No view uses .btn-primary any more: every page has been rebuilt, and the only
   button classes in views/ are .btn with .btn-solid, .btn-line, .btn-text and
   .btn-sm. The rule is kept anyway, for the same reason as the --bs-* mapping in
   section 1: Bootstrap 5 is loaded site-wide and hard-codes its own
   --bs-btn-bg on .btn-primary, so the moment any markup or bundled widget emits
   that class it would ship Bootstrap blue. Re-pointing the component variables
   costs nothing, cannot raise specificity against anything, and keeps an
   off-brand default from being one class name away. Delete it only if Bootstrap
   itself is dropped. */
.btn-primary {
  --bs-btn-color: var(--paper);
  --bs-btn-bg: var(--purple);
  --bs-btn-border-color: var(--purple);
  --bs-btn-hover-color: var(--paper);
  --bs-btn-hover-bg: var(--plum);
  --bs-btn-hover-border-color: var(--plum);
  --bs-btn-active-color: var(--paper);
  --bs-btn-active-bg: var(--plum);
  --bs-btn-active-border-color: var(--plum);
  --bs-btn-disabled-color: var(--paper);
  --bs-btn-disabled-bg: var(--purple);
  --bs-btn-disabled-border-color: var(--purple);
}

/* ==========================================================================
   6. HEADER
   Mobile disclosure contract for Task 4: the trigger is `.nav-toggle`, and the
   open state is the class `.is-open` on the `.hdr` element. Below 1000px the
   nav and the header calls to action are hidden until that class is present.
   ========================================================================== */

.hdr {
  position: relative;
  background: var(--hdr-bg);
  border-bottom: 1px solid var(--line);
  backdrop-filter: blur(8px);
}

/* The row's height is set by the tallest child, which is now the 48px lockup
   rather than the 36px CSS mark, so 12px of block padding gives a 73px header.
   The padding was deliberately not increased to compensate: the lockup bleeds
   to its own edges, so 12px is real clearance, and the 44px Sign in button and
   44px nav items center inside the same 48px row with air to spare.

   flex-wrap is on at every width, not only below 1000px. Above 1000px nothing
   should ever wrap, and with the trial button removed nothing does. But .brand,
   .nav and .hdr-cta are all flex: none so they cannot be squeezed, and if a
   large user font size or an unexpectedly wide translation did overflow the
   row, wrapping to a second line is a graceful failure where a horizontal page
   scrollbar is not. row-gap keeps that fallback looking deliberate. */
.hdr-in {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3) var(--sp-6);
  max-width: var(--wrap-max);
  margin-inline: auto;
  padding: var(--sp-3) var(--sp-10);
}

/* No margin-left here any more. It existed to buy space beside the old CSS
   lockup; the 24px row gap plus each item's own 12px inset already reads as
   36px of separation from the artwork, which is enough. */
.nav {
  display: flex;
  flex: none;
  gap: var(--sp-1);
}

.nav a {
  display: inline-flex;
  align-items: center;
  min-height: var(--hit);
  padding: 0 var(--sp-3);
  border-radius: var(--r-sm);
  color: var(--ink-2);
  font-size: var(--fs-14-5);
  font-weight: 500;
  /* Keeps a multi-word item such as "How It Works" on one line, so the row's
     required width is predictable and the wrap fallback above is the only way
     the header can ever change shape. */
  white-space: nowrap;
  text-decoration: none;
}

.nav a:hover {
  background: var(--mist);
  color: var(--ink);
  text-decoration: none;
}

.nav a[aria-current] {
  background: var(--lilac);
  color: var(--purple);
}

/* Two items now instead of three. At the old 12px gap a bare text link sitting
   12px from a bordered button reads as one attached control, and the phone
   number looked like a label on the Sign in box. 20px separates them into the
   two distinct affordances they are, and there is room for it. */
.hdr-cta {
  margin-left: auto;
  display: flex;
  flex: none;
  align-items: center;
  gap: var(--sp-5);
}

.hdr-tel {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: var(--hit);
  padding-inline: var(--sp-1);
  color: var(--ink);
  font-size: var(--fs-14-5);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}

.hdr-tel svg,
.hdr-tel i {
  flex: none;
  color: var(--plum);
}

.hdr-tel:hover {
  color: var(--plum);
  text-decoration: none;
}

.nav-toggle {
  display: none;
  width: var(--hit);
  height: var(--hit);
  margin-left: auto;
  place-items: center;
  background: var(--paper);
  border: 1px solid var(--line-2);
  border-radius: var(--r-sm);
  color: var(--ink);
  cursor: pointer;
}

.nav-toggle:hover {
  border-color: var(--purple);
  color: var(--purple);
}

/* ==========================================================================
   7. HERO AND MODULE MAP
   ========================================================================== */

.hero {
  padding: var(--sp-19) 0 var(--sp-18);
  background:
    radial-gradient(120% 90% at 88% 6%, var(--lilac) 0%, transparent 46%),
    radial-gradient(110% 90% at 4% 0%, var(--lilac) 0%, transparent 52%),
    var(--paper);
}

.hero-in {
  display: grid;
  grid-template-columns: 1fr 0.88fr;
  gap: var(--sp-14);
  align-items: center;
}

.hero h1 {
  font-size: clamp(var(--fs-41), 4.3vw, var(--fs-57));
  line-height: 1.04;
  margin: var(--sp-4) 0 0;
}

.hero h1 mark {
  background: linear-gradient(180deg, transparent 62%, var(--lilac-mark) 62%);
  color: inherit;
  padding: 0 2px;
}

.hero-lede {
  max-width: 47ch;
  margin: var(--sp-6) 0 0;
  font-size: var(--fs-19);
  line-height: 1.58;
  color: var(--ink-2);
}

.hero-acts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3);
  margin-top: var(--sp-8);
}

.hero-fine {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-6);
  margin: var(--sp-6) 0 0;
  font-size: var(--fs-13-5);
  color: var(--ink-2);
}

.hero-fine span {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}

.hero-fine svg,
.hero-fine i {
  flex: none;
  color: var(--plum);
}

.mapcard {
  padding: var(--sp-2);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-2);
}

.mapcard-h {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
}

.mapcard-h p {
  margin: 0;
  font-size: var(--fs-11);
  font-weight: 700;
  line-height: 1;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--ink-2);
}

.mapcard-h span {
  padding: var(--sp-1) var(--sp-2);
  background: var(--lilac);
  border-radius: var(--r-xs);
  font: 600 var(--fs-11) / 1 var(--font-mono);
  color: var(--plum);
}

.mapcard-f {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4) var(--sp-2);
  margin: 0;
  font-size: var(--fs-12-5);
  color: var(--ink-2);
}

.mapcard-f svg,
.mapcard-f i {
  flex: none;
  color: var(--plum);
}

/* --- Module tile ------------------------------------------------------- */
.mods {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-2);
}

.mod {
  padding: var(--sp-4);
  background: var(--mist);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
}

.mod svg,
.mod i {
  color: var(--purple);
}

.mod h4 {
  margin: var(--sp-3) 0 var(--sp-1);
  font-size: var(--fs-14-5);
  font-weight: 600;
  line-height: 1.3;
}

.mod p {
  margin: 0;
  font-size: var(--fs-12-5);
  line-height: 1.5;
  color: var(--ink-2);
}

/* ==========================================================================
   8. BEFORE / AFTER
   ========================================================================== */

.ba {
  padding-block: var(--sp-19);
}

.ba-grid {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: var(--sp-8);
  align-items: stretch;
  margin-top: var(--sp-11);
}

.ba-col {
  padding: var(--sp-7) var(--sp-6);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}

.ba-col.now {
  border-color: var(--purple);
  box-shadow: var(--ring-lilac);
}

.ba-col .cap {
  margin: 0 0 var(--sp-4);
  font-size: var(--fs-11);
  font-weight: 700;
  line-height: 1;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
}

.ba-col.was .cap {
  color: var(--ink-2);
}

.ba-col.now .cap {
  color: var(--purple);
}

.ba-col h3 {
  margin: 0;
  font-size: var(--fs-19);
}

.ba-col ul {
  list-style: none;
  margin: var(--sp-4) 0 0;
  padding: 0;
  font-size: var(--fs-14-5);
}

.ba-col li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--sp-3);
  padding: var(--sp-3) 0;
  border-top: 1px solid var(--line);
  color: var(--ink-2);
}

.ba-col li svg,
.ba-col li i {
  margin-top: 3px;
}

.ba-col.was li svg,
.ba-col.was li i {
  color: var(--ink-3);
}

.ba-col.now li svg,
.ba-col.now li i {
  color: var(--plum);
}

.ba-arrow {
  display: grid;
  place-items: center;
  color: var(--purple);
}

/* ==========================================================================
   9. AUDIENCE COLUMNS ("Solution" band, #solution)
   Editorial: hairlines, no cards, no shadows.
   ========================================================================== */

.aud {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  margin-top: var(--sp-14);
  border-top: 1px solid var(--line-2);
}

.aud > div {
  padding: var(--sp-8) var(--sp-8) var(--sp-7);
  border-right: 1px solid var(--line);
}

.aud > div:first-child {
  padding-left: 0;
}

.aud > div:last-child {
  padding-right: 0;
  border-right: 0;
}

.aud .who {
  margin: 0;
  font-size: var(--fs-11);
  font-weight: 700;
  line-height: 1;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--plum);
}

.aud h3 {
  margin: var(--sp-3) 0 var(--sp-2);
  font-size: var(--fs-24);
  line-height: 1.18;
}

.aud > div > p {
  margin: 0;
  font-size: var(--fs-16);
  line-height: 1.62;
  color: var(--ink-2);
}

.aud ul {
  list-style: none;
  margin: var(--sp-4) 0 0;
  padding: 0;
  font-size: var(--fs-14-5);
}

.aud li {
  position: relative;
  padding: var(--sp-2) 0 var(--sp-2) var(--sp-6);
  border-top: 1px dotted var(--line-2);
  color: var(--ink-2);
}

.aud li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 17px;
  width: 9px;
  height: 9px;
  border: 1.5px solid var(--purple);
  border-radius: 50%;
}

/* ==========================================================================
   10. YEAR BAND AND TIMELINE STEP ("How a year runs")
   The only numbered or sequenced device on the homepage.
   ========================================================================== */

.year {
  background: var(--plum);
  color: var(--on-plum);
}

.year .sec-head h2 {
  color: var(--paper);
}

.year .sec-head p {
  color: var(--on-plum-2);
}

.year .eyebrow {
  color: var(--lilac-light);
}

.tl {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  margin-top: var(--sp-14);
  border-top: 1px solid var(--on-plum-line);
}

.tl > div {
  position: relative;
  padding: var(--sp-7) var(--sp-7) var(--sp-1);
  border-right: 1px solid var(--on-plum-line-2);
}

.tl > div:first-child {
  padding-left: 0;
}

.tl > div:last-child {
  border-right: 0;
}

.tl .mon {
  margin: 0;
  font-size: var(--fs-11);
  font-weight: 700;
  line-height: 1;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--lilac-light);
}

.tl h3 {
  margin: var(--sp-3) 0 var(--sp-2);
  font-family: var(--font-serif);
  font-size: var(--fs-22);
  font-weight: 600;
  line-height: var(--lh-heading);
  color: var(--paper);
}

.tl p {
  margin: 0;
  font-size: var(--fs-14-5);
  line-height: var(--lh-body);
  color: var(--on-plum-2);
}

.tl .dot {
  position: absolute;
  top: -6px;
  left: 0;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--lilac-light);
}

.tl > div:not(:first-child) .dot {
  left: var(--sp-7);
}

/* ==========================================================================
   11. PRODUCT PROOF — interface panel, status chip, proof list
   The panel is hand-built markup carrying role="img" and a descriptive
   aria-label. Every figure in it is illustrative and labelled as such.
   ========================================================================== */

.proof {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: var(--sp-14);
  align-items: center;
  margin-top: var(--sp-12);
}

.dev {
  overflow: hidden;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-1);
}

.dev-bar {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  background: var(--mist);
  border-bottom: 1px solid var(--line);
}

/* Decorative window dots. */
.dev-bar i {
  display: block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--line-2);
}

.dev-bar span {
  margin-left: var(--sp-1);
  font: 600 var(--fs-12-5) / 1 var(--font-mono);
  letter-spacing: 0.04em;
  color: var(--ink-2);
}

.dev-body {
  padding: var(--sp-4);
}

.dev-meter {
  padding: var(--sp-1) var(--sp-1) var(--sp-4);
}

.dev-meter-h {
  display: flex;
  justify-content: space-between;
  gap: var(--sp-3);
  font-size: var(--fs-13-5);
}

.dev-meter-h span {
  color: var(--ink-2);
}

.dev-meter-h b {
  font-variant-numeric: tabular-nums;
}

.prog {
  display: block;
  height: 8px;
  margin-top: var(--sp-2);
  overflow: hidden;
  background: var(--mist-2);
  border-radius: var(--r-xs);
}

.prog i {
  display: block;
  height: 100%;
  background: var(--purple);
  border-radius: var(--r-xs);
}

.frow {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--sp-3);
  align-items: center;
  padding: var(--sp-3) var(--sp-1);
  border-bottom: 1px solid var(--line);
}

.frow:last-child {
  border-bottom: 0;
}

.frow .nm {
  font-size: var(--fs-14-5);
  font-weight: 600;
}

.frow .sm {
  font-size: var(--fs-12-5);
  color: var(--ink-2);
}

.devfoot {
  display: flex;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  background: var(--mist);
  border-top: 1px solid var(--line);
  font-size: var(--fs-12-5);
  color: var(--ink-2);
}

/* --- Status chip. Color is never the only carrier: every chip pairs an
       icon with a word. --------------------------------------------------- */
.st {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-xs);
  font: 600 var(--fs-12-5) / 1 var(--font-sans);
  white-space: nowrap;
}

.st svg,
.st i {
  flex: none;
}

.st-ok {
  background: var(--green-tint);
  color: var(--green);
}

.st-wait {
  background: var(--amber-tint);
  color: var(--amber);
}

.st-due {
  background: var(--rose-tint);
  color: var(--rose);
}

/* --- Proof list -------------------------------------------------------- */
.plist {
  list-style: none;
  margin: var(--sp-6) 0 0;
  padding: 0;
}

.plist li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--sp-4);
  padding: var(--sp-4) 0;
  border-top: 1px solid var(--line);
}

.plist svg,
.plist i {
  flex: none;
  margin-top: 2px;
  color: var(--plum);
}

.plist h4 {
  margin: 0 0 var(--sp-1);
  font-size: var(--fs-17-5);
  font-weight: 600;
  line-height: 1.3;
}

.plist p {
  margin: 0;
  font-size: var(--fs-14-5);
  line-height: var(--lh-body);
  color: var(--ink-2);
}

/* ==========================================================================
   12. GETTING STARTED
   First / Then / From day one. No numerals: the year band owns sequence.
   ========================================================================== */

.starts {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-6);
  margin-top: var(--sp-11);
}

.scard {
  padding: var(--sp-6);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}

.scard .when {
  margin: 0 0 var(--sp-3);
  font-size: var(--fs-11);
  font-weight: 700;
  line-height: 1;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--plum);
}

.scard h3 {
  margin: 0 0 var(--sp-2);
  font-size: var(--fs-19);
}

.scard p {
  margin: 0;
  font-size: var(--fs-14-5);
  line-height: 1.62;
  color: var(--ink-2);
}

/* ==========================================================================
   13. TRUST CARDS AND THE LOGO PLACEHOLDER WALL
   ========================================================================== */

.trust-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-6);
  margin-top: var(--sp-11);
}

.tcard {
  padding: var(--sp-6);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}

.tcard .ti {
  display: grid;
  place-items: center;
  width: var(--hit);
  height: var(--hit);
  margin-bottom: var(--sp-4);
  background: var(--lilac);
  border-radius: var(--r-sm);
  color: var(--plum);
}

.tcard h3 {
  margin: 0 0 var(--sp-2);
  font-size: var(--fs-19);
}

.tcard p {
  margin: 0;
  font-size: var(--fs-14-5);
  line-height: 1.62;
  color: var(--ink-2);
}

.honest {
  max-width: 82ch;
  margin-top: var(--sp-6);
  padding: var(--sp-5) var(--sp-6);
  background: var(--mist);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  font-size: var(--fs-14-5);
  line-height: 1.62;
  color: var(--ink-2);
}

.wall {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--sp-4);
  margin-top: var(--sp-9);
}

/* Visible, labelled placeholder. Never filled with invented content. */
.wslot {
  display: grid;
  place-items: center;
  height: var(--sp-22);
  padding: var(--sp-3);
  background: var(--mist);
  border: 1.5px dashed var(--line-2);
  border-radius: var(--r-sm);
  text-align: center;
}

.wslot p {
  margin: 0;
  font: 600 var(--fs-11) / 1.4 var(--font-sans);
  letter-spacing: 0.04em;
  color: var(--ink-2);
}

/* ==========================================================================
   14. PRICING CARD
   ========================================================================== */

.price {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-6);
  margin-top: var(--sp-11);
}

.pcard {
  padding: var(--sp-8) var(--sp-7);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
}

.pcard.lead {
  border: 2px solid var(--purple);
  background: linear-gradient(180deg, var(--lilac), var(--paper) 42%);
}

.pcard h3 {
  margin: 0 0 var(--sp-1);
  font-size: var(--fs-19);
}

.pcard .pd {
  margin: 0;
  font-size: var(--fs-14-5);
  color: var(--ink-2);
}

.pcard .amt {
  margin: var(--sp-6) 0 var(--sp-1);
  font: 700 var(--fs-41) / 1 var(--font-sans);
  letter-spacing: -0.035em;
  color: var(--plum);
  font-variant-numeric: tabular-nums;
}

.pcard .amt small {
  margin-left: var(--sp-2);
  font: 500 var(--fs-14-5) / 1 var(--font-sans);
  letter-spacing: 0;
  color: var(--ink-2);
}

.pcard ul {
  list-style: none;
  margin: var(--sp-6) 0;
  padding: 0;
  font-size: var(--fs-14-5);
}

.pcard li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--sp-3);
  padding: var(--sp-3) 0;
  border-top: 1px solid var(--line);
  color: var(--ink-2);
}

.pcard li svg,
.pcard li i {
  margin-top: 3px;
  color: var(--plum);
}

/* ==========================================================================
   15. CONVERSION BAND
   ========================================================================== */

.final {
  background: var(--ink);
  color: var(--ink-inv-2);
  text-align: center;
}

.final h2 {
  max-width: 23ch;
  margin: 0 auto;
  font-size: clamp(var(--fs-24), 3.4vw, var(--fs-41));
  line-height: 1.08;
  color: var(--paper);
}

.final p {
  max-width: 54ch;
  margin: var(--sp-5) auto 0;
  font-size: var(--fs-17-5);
  color: var(--ink-inv);
}

.final .hero-acts {
  justify-content: center;
  margin-top: var(--sp-8);
}

.final .btn-solid {
  background: var(--paper);
  border-color: var(--paper);
  color: var(--ink);
}

.final .btn-solid:hover {
  background: var(--paper-dim);
  border-color: var(--paper-dim);
  color: var(--ink);
}

.final .btn-line {
  background: transparent;
  border-color: var(--on-ink-line);
  color: var(--paper);
}

.final .btn-line:hover {
  background: var(--on-ink-wash);
  border-color: var(--paper);
  color: var(--paper);
}

/* ==========================================================================
   16. FOOTER
   ========================================================================== */

.ftr {
  background: var(--ink);
  color: var(--ftr-text);
  padding: 52px 0 var(--sp-7);
  font-size: var(--fs-14-5);
}

.ftr-grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1fr;
  gap: var(--sp-10);
}

/* The footer lockup is the white PNG, so nothing here sets a color. It also
   stays 210px at every width: this selector outranks the `.brand img` width in
   section 22, so the header's responsive shrink does not reach the footer,
   where the column is never the constraint. */
.ftr .brand img {
  width: var(--brand-w-ftr);
}

.ftr-note {
  max-width: 34ch;
  margin: var(--sp-4) 0 0;
  font-size: var(--fs-13-5);
  line-height: var(--lh-body);
}

.ftr h2 {
  margin: 0 0 var(--sp-4);
  font-size: var(--fs-11);
  font-weight: 700;
  line-height: 1;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--ftr-head);
}

.ftr ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.ftr li {
  margin-bottom: var(--sp-2);
}

.ftr a {
  display: inline-block;
  padding: var(--sp-1) 0;
  color: var(--ftr-link);
  text-decoration: none;
}

.ftr a:hover {
  color: var(--paper);
  text-decoration: underline;
}

.ftr-base {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-top: var(--sp-10);
  padding-top: var(--sp-6);
  border-top: 1px solid var(--ftr-line);
  font-size: var(--fs-12-5);
  color: var(--ftr-head);
}

.soc {
  display: flex;
  gap: var(--sp-3);
  margin-top: var(--sp-4);
}

.soc a {
  display: grid;
  place-items: center;
  width: var(--hit);
  height: var(--hit);
  padding: 0;
  border: 1px solid var(--ftr-chip-line);
  border-radius: var(--r-sm);
  color: var(--ftr-link);
}

.soc a:hover {
  background: var(--ftr-chip-hover);
  color: var(--paper);
}

/* ==========================================================================
   17. FORM FIELD, WITH HELPER AND ERROR STATES
   ========================================================================== */

.field {
  margin-bottom: var(--sp-5);
}

.field > label,
.field > .label {
  display: block;
  margin-bottom: var(--sp-2);
  font-size: var(--fs-14-5);
  font-weight: 600;
  color: var(--ink);
}

.field .req {
  color: var(--plum);
}

.field .help {
  margin: 0 0 var(--sp-2);
  font-size: var(--fs-13-5);
  line-height: 1.5;
  color: var(--ink-2);
}

.field input,
.field select,
.field textarea {
  width: 100%;
  min-height: var(--sp-12);
  padding: var(--sp-3) var(--sp-4);
  background: var(--paper);
  border: 1px solid var(--ink-3);
  border-radius: var(--r-sm);
  font-family: var(--font-sans);
  font-size: var(--fs-16);
  line-height: 1.5;
  color: var(--ink);
}

.field textarea {
  min-height: 160px;
  resize: vertical;
}

.field input::placeholder,
.field textarea::placeholder {
  color: var(--ink-2);
}

.field input:hover,
.field select:hover,
.field textarea:hover {
  border-color: var(--ink-2);
}

.field .err {
  display: none;
  align-items: flex-start;
  gap: var(--sp-2);
  margin: var(--sp-2) 0 0;
  font-size: var(--fs-13-5);
  font-weight: 600;
  color: var(--rose);
}

.field .err svg,
.field .err i {
  flex: none;
  margin-top: 2px;
}

.field.is-invalid input,
.field.is-invalid select,
.field.is-invalid textarea,
.field [aria-invalid="true"] {
  border-color: var(--rose);
  box-shadow: 0 0 0 3px var(--rose-tint);
}

.field.is-invalid .err {
  display: flex;
}

/* ==========================================================================
   18. BACK TO TOP
   public/js/custom.js toggles this element's inline `display` between "none"
   and "block", so nothing here may depend on a flex or grid display value.
   ========================================================================== */

#btn-back-to-top {
  position: fixed;
  right: var(--sp-5);
  bottom: var(--sp-5);
  z-index: 1030;
  display: none;
  width: var(--sp-12);
  height: var(--sp-12);
  padding: 0;
  background-color: var(--plum);
  border: 1.5px solid var(--plum);
  border-radius: var(--r-sm);
  color: var(--paper);
  line-height: var(--sp-11);
  text-align: center;
  box-shadow: var(--shadow-1);
  cursor: pointer;
}

#btn-back-to-top:hover {
  background-color: var(--purple);
  border-color: var(--purple);
  color: var(--paper);
}

#btn-back-to-top svg,
#btn-back-to-top i {
  vertical-align: middle;
}

/* ==========================================================================
   19. MISCELLANEOUS
   ========================================================================== */

/* A reserved aspect ratio so an embedded video never shifts the layout. */
.youtube-video {
  aspect-ratio: 16 / 9;
  width: 100%;
  border: 0;
  border-radius: var(--r-md);
}

/* Wide content scrolls inside its own container so the page never does.

   MARKUP CONTRACT. Because this container scrolls, every use of it must also
   carry tabindex="0", role="region" and an accessible name. Without the
   tabindex the container is not a tab stop, and a keyboard-only user has no way
   at all to reach whatever is clipped off the right edge (WCAG 2.1.1, Level A).
   The [tabindex]:focus-visible rule in section 2 already gives the tab stop its
   focus ring, so no focus style is needed here. */
.scroller {
  overflow-x: auto;
}

/* Comfortable reading measure for the long policy pages. */
.prose {
  max-width: var(--measure);
}

.prose p,
.prose li {
  font-size: var(--fs-16);
  line-height: 1.7;
  color: var(--ink-2);
}

/* Sticky mobile action bar, shown at the narrowest breakpoint only. */
.mobile-bar {
  display: none;
  position: sticky;
  bottom: 0;
  z-index: 1020;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  background: var(--bar-bg);
  border-top: 1px solid var(--line);
  backdrop-filter: blur(8px);
}

/* ==========================================================================
   20. POLICY PAGES
   views/privacy.ejs, views/sla.ejs and views/terms.ejs.

   The legal text on all three is fixed and cannot be edited, so everything here is
   about making a long, dense document readable: a bounded measure, a visible
   structure, and a table of contents that is reachable from the keyboard and
   legible without color vision.
   ========================================================================== */

/* The reading measure. --measure is 68ch, the site-wide value .prose already
   uses, which sits inside the 65 to 75 character target. Before this, the
   agreement ran the full width of the viewport. */
.policy {
  max-width: var(--measure);
}

.policy p,
.policy li {
  font-size: var(--fs-16);
  line-height: 1.7;
  color: var(--ink-2);
}

/* Direct children only, so the lettered clauses inside a .policy-sec keep
   their own tighter rhythm below. */
.policy > p {
  margin: 0 0 var(--sp-5);
}

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

/* --- One numbered section of the agreement ------------------------------- */
.policy-sec {
  scroll-margin-top: var(--sp-6);   /* breathing room at a jump target */
}

.policy-sec + .policy-sec {
  margin-top: var(--sp-12);
  padding-top: var(--sp-12);
  border-top: 1px solid var(--line);
}

.policy-sec h2 {
  margin: 0 0 var(--sp-5);
  font-size: var(--fs-24);
  line-height: var(--lh-heading);
}

/* The lettered clauses (a., b., c.) sit in from the margin so a section reads
   as an outline. The letter itself is part of the text, so the indent is
   purely visual and drops away at the narrowest breakpoint. */
.policy-sub {
  margin: 0 0 var(--sp-4);
  padding-inline-start: var(--sp-5);
}

.policy-list {
  margin: 0 0 var(--sp-5);
  padding-inline-start: var(--sp-10);
}

.policy-list li {
  margin-bottom: var(--sp-2);
}

.policy-list li::marker {
  color: var(--ink-2);
}

/* --- The credit schedule table. Always inside a .scroller, so a narrow
       viewport scrolls the table and never the page. --------------------- */
.policy-table {
  width: 100%;
  margin: 0 0 var(--sp-5);
  border-collapse: collapse;
  font-size: var(--fs-14-5);
}

.policy-table th,
.policy-table td {
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--line);
  text-align: left;
  white-space: nowrap;
}

.policy-table th {
  background: var(--mist);
  color: var(--ink);
  font-weight: 700;
}

.policy-table td {
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}

/* --- Table of contents --------------------------------------------------- */
.toc {
  max-width: var(--measure);
  margin: 0 0 var(--sp-12);
  padding: var(--sp-5) var(--sp-6);
  background: var(--mist);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}

.toc-label {
  margin: 0 0 var(--sp-2);
  font-size: var(--fs-11);
  font-weight: 700;
  line-height: 1;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--plum);
}

.toc-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Each entry fills a 44px row, which is both the minimum target size and what
   stops two adjacent entries being hard to hit with a thumb. Underlined at
   rest, so an entry is identifiable as a link without relying on its color. */
.toc-list a {
  display: flex;
  align-items: center;
  min-height: var(--hit);
  font-size: var(--fs-16);
  color: var(--purple);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.toc-list a:hover {
  color: var(--plum);
}

/* ==========================================================================
   21. ERROR PAGES
   400 / 401 / 403 / 404 / 500. One shell, one centered column, two actions.
   ========================================================================== */

.err {
  max-width: 52ch;
  margin-inline: auto;
  text-align: center;
}

.err-icon {
  display: grid;
  place-items: center;
  width: var(--sp-14);
  height: var(--sp-14);
  margin: 0 auto var(--sp-6);
  background: var(--lilac);
  border-radius: var(--r-md);
  color: var(--plum);
}

/* Tinted variants. The tint is a second signal only, never the first: the
   status code and the heading beneath it already say what happened, so the
   page loses nothing in grayscale. Measured on their own grounds, the rose
   pair is 6.26:1 and the amber pair 5.37:1, both well past the 3:1 an icon
   needs. */
.err-icon-alert {
  background: var(--rose-tint);
  color: var(--rose);
}

.err-icon-caution {
  background: var(--amber-tint);
  color: var(--amber);
}

.err-code {
  margin: 0;
  font-size: var(--fs-13-5);
  font-weight: 700;
  line-height: 1;
  letter-spacing: var(--ls-caps);
  color: var(--plum);
}

.err h1 {
  margin: var(--sp-3) 0 0;
  font-size: clamp(var(--fs-24), 3.1vw, var(--fs-41));
  line-height: var(--lh-tight);
}

.err-lede {
  margin: var(--sp-4) 0 0;
  font-size: var(--fs-17-5);
  line-height: var(--lh-body);
  color: var(--ink-2);
}

.err .hero-acts {
  justify-content: center;
}

/* ==========================================================================
   22. BREAKPOINTS. 1240 / 1000 / 640, and no others.
   ========================================================================== */

@media (max-width: 1240px) {
  /* HEADER, 1001px to 1240px. This is the band the old header handled worst.
     The wrapper is capped at 1140px but its inline padding is 40px a side, so
     at 1001px there are only 921px of content to place a 245px lockup, five
     nav items, a phone number and a button in. Three cuts, in the order they
     cost the least:

       1. the lockup drops to 204px / 40px, freeing 41px;
       2. nav items tighten from 12px to 8px of inset, freeing 40px;
       3. the phone number is withdrawn, freeing about 150px.

     The phone goes last because it is the one the owner asked about, and it is
     not lost: below 1000px it reappears inside the open disclosure panel, and
     it is on every page in the footer base bar and on /contact. Above 1240px it
     stays in the header, which is where the room for it exists.

     Below 1000px the shrink is no longer about crowding, since the nav has
     collapsed behind the trigger. It is kept anyway: at 320px the content box
     is 280px and a 204px lockup plus the 12px gap plus the 44px trigger comes
     to 260px, which fits with room, where 245px would leave 19px. A slightly
     smaller mark on a small screen is also simply proportionate. */
  .brand img {
    width: var(--brand-w-tight);
  }

  .nav a {
    padding: 0 var(--sp-2);
  }

  .hdr-tel {
    display: none;
  }

  .sec {
    padding-block: var(--sp-18);
  }

  .hero {
    padding: var(--sp-16) 0 var(--sp-16);
  }

  .ba {
    padding-block: var(--sp-16);
  }

  .hero-in,
  .proof {
    gap: var(--sp-10);
  }
}

@media (max-width: 1000px) {
  .wrap {
    padding-inline: var(--sp-6);
  }

  /* flex-wrap is declared on .hdr-in unconditionally now, so it is not repeated
     here. What this needs to do is shorten the row gap: the collapsed panel
     wraps onto its own line and 24px above it is too much. */
  .hdr-in {
    padding-inline: var(--sp-6);
    gap: var(--sp-3);
  }

  /* Nav and header actions collapse behind the disclosure trigger.
     Task 4 toggles `.is-open` on `.hdr` and `aria-expanded` on `.nav-toggle`.
     The row above the panel is just the lockup and the trigger: at 204px wide
     the lockup leaves at least 32px of clear space before the 44px trigger even
     at 320px, so a wide mark and a hamburger share the row without touching. */
  .nav-toggle {
    display: grid;
  }

  .nav,
  .hdr-cta {
    display: none;
    width: 100%;
    margin-left: 0;
  }

  .hdr.is-open .nav,
  .hdr.is-open .hdr-cta {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--sp-2);
    padding-bottom: var(--sp-2);
  }

  .hdr.is-open .nav a {
    min-height: var(--sp-12);
  }

  /* The phone number is withdrawn from the header at 1240px and below, but the
     disclosure panel is not the header row: there is a full-width line for it
     here, and tap to call is worth more on a phone than anywhere else. Centered
     to match the full-width Sign in button it stacks with. */
  .hdr.is-open .hdr-tel {
    display: flex;
    justify-content: center;
  }

  .hero-in,
  .proof,
  .ba-grid {
    grid-template-columns: 1fr;
    gap: var(--sp-9);
  }

  .ba-arrow {
    transform: rotate(90deg);
  }

  .aud,
  .tl,
  .starts,
  .trust-grid,
  .price {
    grid-template-columns: 1fr;
  }

  .aud > div {
    padding-inline: 0;
    border-right: 0;
    border-bottom: 1px solid var(--line);
  }

  .tl > div {
    padding-inline: 0;
    border-right: 0;
    border-bottom: 1px solid var(--on-plum-line-2);
  }

  .tl > div:not(:first-child) .dot {
    left: 0;
  }

  .wall,
  .ftr-grid {
    grid-template-columns: 1fr 1fr;
  }
}

@media (max-width: 640px) {
  .wrap {
    padding-inline: var(--sp-5);
  }

  .hdr-in {
    padding-inline: var(--sp-5);
  }

  .sec,
  .ba,
  .hero {
    padding-block: var(--sp-14);
  }

  /* Buttons go full width on mobile, one primary call to action per region. */
  .btn {
    width: 100%;
  }

  .mobile-bar {
    display: flex;
  }

  .mobile-bar .btn {
    flex: 1 1 0;
    width: auto;
  }

  .hero-acts,
  .final .hero-acts {
    flex-direction: column;
    align-items: stretch;
  }

  .mods {
    gap: var(--sp-2);
  }

  /* The timeline becomes a vertical rail rather than four columns. */
  .tl {
    margin-top: var(--sp-6);
    padding-left: var(--sp-5);
    border-top: 0;
    border-left: 2px solid var(--on-plum-line);
  }

  .tl > div {
    padding: 0 0 var(--sp-6);
    border-bottom: 0;
  }

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

  .tl .dot,
  .tl > div:not(:first-child) .dot {
    left: calc(-1 * var(--sp-6) - 2px);
    top: 5px;
    width: 10px;
    height: 10px;
  }

  .aud h3 {
    font-size: var(--fs-22);
  }

  .wall,
  .ftr-grid {
    grid-template-columns: 1fr;
  }

  .ftr-base {
    gap: var(--sp-2);
  }

  .pcard {
    padding: var(--sp-6) var(--sp-5);
  }

  /* The lettered-clause indent is decoration; on a phone it is width the
     agreement needs for its own text. The letter stays, since it is part of
     the sentence. */
  .policy-sub {
    padding-inline-start: 0;
  }

  .policy-list {
    padding-inline-start: var(--sp-6);
  }

  .toc {
    padding: var(--sp-4) var(--sp-5);
  }
}

/* ==========================================================================
   23. REDUCED MOTION
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ==========================================================================
   ICON SIZES
   ==========================================================================

   Font Awesome scales from font-size, where the icon sprite this replaced was
   sized by width/height attributes at each call site. These classes carry those
   exact values across, one class per size the design actually uses, so no icon
   changed size in the migration and the size stays readable at the call site
   rather than being inferred from an ancestor.

   Every icon element also inherits `color` from its context rule above; these
   classes set size only. Add a new step only when the design needs one.
   ========================================================================== */

.ico-12 { font-size: 12px; }
.ico-15 { font-size: 15px; }
.ico-16 { font-size: 16px; }
.ico-17 { font-size: 17px; }
.ico-18 { font-size: 18px; }
.ico-20 { font-size: 20px; }
.ico-21 { font-size: 21px; }
.ico-22 { font-size: 22px; }
.ico-26 { font-size: 26px; }
.ico-34 { font-size: 34px; }

/* ==========================================================================
   FRAGMENT NAVIGATION
   ==========================================================================

   Bootstrap's reboot sets `:root { scroll-behavior: smooth }` inside
   `@media (prefers-reduced-motion: no-preference)`. With that in force this
   browser does not perform fragment navigation at all: loading /#solution, and
   clicking a link to it, both leave the page at scrollY 0 with the target
   1679px below the fold. Proven by isolation: the same minimal document scrolls
   correctly with the property absent and not at all with it present, one
   variable changed, no Bootstrap and no App Connect involved.

   Three things depend on fragment navigation, in order of how much it matters:
     1. the skip link (href="#content"), which is the first control a keyboard
        user reaches on every page,
     2. the "Solution" and "How It Works" header nav items,
     3. every /platform#<module> link in the footer.

   `:root` rather than `html`, because Bootstrap's selector is `:root` and a
   type selector would lose on specificity. This file loads after Bootstrap, so
   at equal specificity this wins.
   ========================================================================== */

:root {
  scroll-behavior: auto;
}
