/* ==========================================================================
   Lunaris Finance — design system
   Two themes off one set of tokens. Light is the default; dark is opt-in via
   the header switch and applies when <html> carries data-theme="dark".
   The :root block below holds the DARK values; the block after it holds the
   light ones and is matched by :not([data-theme="dark"]), so it wins unless
   the visitor has asked for dark.
   ========================================================================== */

/* --- 1. Tokens ----------------------------------------------------------- */
:root {
  /* BRAND — sampled from the Lunaris logo artwork */
  --brand-navy:     #040718;  /* logo background — the page base            */
  --brand-navy-deep:#020214;  /* deepest: footer                            */
  --brand-navy-lift:#0A0F26;  /* raised surfaces: cards, panels             */
  --brand-silver:   #A8A9AD;  /* body text                                  */
  --brand-platinum: #DCDFE4;  /* headings, high-contrast text               */
  --brand-highlight:#F2F3F6;  /* the brightest facet of the mark            */

  /* Semantic */
  --bg:        var(--brand-navy);
  --bg-deep:   var(--brand-navy-deep);
  --surface:   var(--brand-navy-lift);
  --surface-2: #0E1430;

  --text:      var(--brand-silver);
  --heading:   var(--brand-platinum);
  --bright:    var(--brand-highlight);
  --muted:     #8A8D95;

  --line:      #1B2140;
  --line-soft: #121734;

  /* Metallic accent, used sparingly: rules, marks, the primary button */
  --metal: linear-gradient(135deg, #EFF1F4 0%, #D2D5DB 45%, #B4B8C0 100%);
  --metal-mark: linear-gradient(135deg, #F2F3F6 0%, #C3C6CC 34%, #8E9198 58%, #DCDFE4 78%, #A2A5AC 100%);
  /* The logo gradient is drawn by inline SVG in the markup, which cannot read
     a CSS gradient — it needs the five stops one at a time. */
  --mark-1: #F2F3F6; --mark-2: #C3C6CC; --mark-3: #8E9198;
  --mark-4: #DCDFE4; --mark-5: #A2A5AC;

  /* Anything that was a literal colour before the light theme existed. Each
     has a counterpart in the light block below; nothing in the stylesheet
     should hardcode a colour outside these two blocks. */
  --ink:       var(--brand-platinum);      /* line-art backdrops               */
  --hero-mark: #1B2140;                    /* the oversized watermark          */
  --cta-bg:    #333333;
  --danger:    #E4736B;
  --glow-1:    rgba(220,223,228,.09);
  --glow-2:    rgba(124,126,134,.07);
  --focus-ring:rgba(168,169,173,.14);
  --art-filter:none;                       /* the two supplied drawings        */

  /* Type */
  --serif: "Cormorant Garamond", "Newsreader", "Iowan Old Style", Georgia, serif;
  --sans:  "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

  --fs-xs:   0.75rem;
  --fs-sm:   0.875rem;
  --fs-base: 1rem;
  --fs-lg:   1.125rem;
  --fs-xl:   clamp(1.3rem, 0.6vw + 1.15rem, 1.6rem);
  --fs-2xl:  clamp(1.75rem, 1.4vw + 1.35rem, 2.4rem);
  --fs-3xl:  clamp(2.1rem, 2.6vw + 1.4rem, 3.4rem);
  --fs-4xl:  clamp(2.6rem, 4.4vw + 1.3rem, 4.8rem);

  /* Space */
  --s1: 0.25rem; --s2: 0.5rem;  --s3: 0.75rem; --s4: 1rem;
  --s5: 1.5rem;  --s6: 2rem;    --s7: 3rem;    --s8: 4rem;
  --s9: 6rem;    --s10: 8.5rem;

  --wrap: 1200px;
  --radius: 2px;
  --t: 200ms cubic-bezier(.4,0,.2,1);
}

/* --- 1b. Light theme — the default ----------------------------------------
   Matched by :not([data-theme="dark"]), so it applies when no attribute is
   set at all. That is what makes light the default: a first-time visitor gets
   it with no JavaScript, no flash and no stored preference. Dark is the
   opt-in, set by the header toggle, remembered in localStorage and written to
   <html> before the first paint by the inline script in the <head>.

   There is deliberately no prefers-color-scheme rule: a visitor whose laptop
   is in dark mode still gets the light site until they ask for otherwise.

   Everything below is a token. The six --brand-* values are redefined rather
   than only the semantic aliases, because a handful of rules reach for
   --brand-silver directly and would otherwise keep a dark-theme grey. */
:root:not([data-theme="dark"]) {
  --brand-navy:     #F7F8FA;  /* page base                                  */
  --brand-navy-deep:#EAEDF2;  /* footer                                     */
  --brand-navy-lift:#FFFFFF;  /* cards, panels, form fields                 */
  /* Body copy is near-black, not grey. A mid grey that reads as "secondary"
     on navy reads as "faded" on white, so the light theme sets body text one
     step off black and keeps the brand's cool cast rather than going to pure
     #000, which glares. 14.4:1 on the base. */
  --brand-silver:   #14192C;  /* body text                                  */
  --brand-platinum: #0A0F26;  /* headings                                   */
  --brand-highlight:#040718;  /* strongest text, the brand navy itself      */

  --surface-2: #EFF2F7;
  /* Eyebrows, field hints and small print: still secondary, but 8.2:1 rather
     than the 5:1 that looked washed out. */
  --muted:     #4A5061;
  --line:      #C6CCD8;
  --line-soft: #E3E7EE;

  /* The metal inverts: on a light ground the button, the active-nav rule and
     the snapshot rules all need to be the dark element, not the bright one. */
  --metal: linear-gradient(135deg, #1C2340 0%, #0A0F26 45%, #141A33 100%);
  --metal-mark: linear-gradient(135deg, #2E3552 0%, #10162E 34%, #4A5170 58%, #1B2240 78%, #363D5C 100%);
  --mark-1: #2E3552; --mark-2: #10162E; --mark-3: #4A5170;
  --mark-4: #1B2240; --mark-5: #363D5C;

  --ink:       var(--brand-platinum);
  /* The watermark was #E6E9F0, 1.14:1 against the page — all but invisible.
     The dark theme's cross sits at 1.28:1; this is a touch beyond that, which
     is where it reads as a mark rather than a smudge. */
  --hero-mark: #CCD4E4;
  --cta-bg:    #E7EAF1;
  --danger:    #A8231A;
  --glow-1:    rgba(16,22,46,.055);
  --glow-2:    rgba(16,22,46,.04);
  --focus-ring:rgba(16,22,46,.14);
  /* The two supplied drawings are platinum linework baked into the file.
     Inverting turns them near-navy; alpha is untouched, so the transparent
     ground stays transparent. */
  --art-filter:invert(1);
}

/* Light text on a dark ground optically gains weight; dark text on a light one
   loses it. At display sizes that does not show, but the small serif h3s — the
   step titles, the feature titles, the panel headings — went thin and grey in
   light mode. One weight up, in the darkest ink, puts them back. */
:root:not([data-theme="dark"]) h3 { font-weight: 500; color: var(--bright); }

/* The page opens and closes on the brand: the header, the CTA band and the
   footer stay navy in light mode. Two adjacent pale greys made the CTA and the
   footer read as one flat block, and the light theme lost the navy entirely.
   Redefining the tokens on these blocks flips them back to the dark palette
   without touching a single component rule — every child, the mobile menu
   included, already reads its colour from a token. */
:root:not([data-theme="dark"]) .site-header,
:root:not([data-theme="dark"]) .cta,
:root:not([data-theme="dark"]) .site-footer {
  --bg:            #040718;
  --bg-deep:       #020214;
  --surface:       #0A0F26;
  --brand-silver:  #A8A9AD;
  --text:          #A8A9AD;
  --heading:       #DCDFE4;
  --bright:        #F2F3F6;
  --muted:         #8A8D95;
  --line:          #262D4C;
  --line-soft:     #1B2140;
  --metal: linear-gradient(135deg, #EFF1F4 0%, #D2D5DB 45%, #B4B8C0 100%);
  --mark-1: #F2F3F6; --mark-2: #C3C6CC; --mark-3: #8E9198;
  --mark-4: #DCDFE4; --mark-5: #A2A5AC;
  --cta-bg: #0A0F26;
  /* `color` inherits as a resolved value, not as the var() that produced it,
     so body's light-theme grey would carry into these blocks untouched.
     Re-declaring it here restarts the chain with the tokens above. */
  color: var(--text);
}

/* --- 2. Reset ------------------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; background: var(--bg); }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
body {
  font-family: var(--sans);
  font-size: var(--fs-base);
  line-height: 1.65;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  font-feature-settings: "kern", "liga";
}
img, svg, video { display: block; max-width: 100%; height: auto; }
button, input, select, textarea { font: inherit; color: inherit; }
a { color: inherit; }

/* --- 3. Layout ----------------------------------------------------------- */
.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: var(--s5); }
.section { padding-block: var(--s9); }
.section--tight { padding-block: var(--s8); }
.section--lift { background: var(--surface); }
.section--deep { background: var(--bg-deep); }
.grid { display: grid; gap: var(--s6); }
/* Grid/flex children default to min-width:auto and refuse to shrink below
   their content, which lets wide content push the page sideways. Keep this. */
.grid > *, .stack > *, .stack-lg > * { min-width: 0; }
@media (min-width: 720px) {
  .grid--2 { grid-template-columns: repeat(2, 1fr); }
  .grid--3 { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1000px) {
  .grid--3 { grid-template-columns: repeat(3, 1fr); }
  .grid--sidebar { grid-template-columns: 1fr 340px; gap: var(--s8); }
}
.stack > * + * { margin-top: var(--s4); }
.stack-lg > * + * { margin-top: var(--s6); }

/* --- 4. Type ------------------------------------------------------------- */
h1, h2, h3 {
  font-family: var(--serif);
  font-weight: 300;
  line-height: 1.1;
  letter-spacing: -0.005em;
  color: var(--heading);
  text-wrap: balance;
}
h1 { font-size: var(--fs-4xl); }
h2 { font-size: var(--fs-3xl); }
h3 { font-size: var(--fs-xl); line-height: 1.3; letter-spacing: 0; }
h4 {
  font-family: var(--sans); font-size: var(--fs-sm); font-weight: 600;
  letter-spacing: 0.02em; color: var(--heading);
}
p { text-wrap: pretty; }
.lede { font-size: var(--fs-lg); line-height: 1.6; color: var(--text); max-width: 60ch; }
.eyebrow {
  display: block;
  font-size: var(--fs-xs); font-weight: 500;
  letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--muted); margin-bottom: var(--s5);
}
.small { font-size: var(--fs-sm); color: var(--muted); }
.section-head { max-width: 58ch; margin-bottom: var(--s8); }
.section-head h2 + .lede, .section-head h1 + .lede { margin-top: var(--s5); }
.rule { height: 1px; background: var(--line); border: 0; }
.rule--metal { height: 1px; border: 0; background: var(--metal); opacity: .5; }

/* --- 5. Header ----------------------------------------------------------- */
.site-header {
  position: sticky; top: 0; z-index: 60;
  background: color-mix(in srgb, var(--bg) 90%, transparent);
  backdrop-filter: saturate(160%) blur(14px);
  border-bottom: 1px solid var(--line-soft);
}
.site-header__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s5); min-height: 78px;
}
.logo { display: flex; align-items: center; gap: var(--s4); text-decoration: none; flex-shrink: 0; padding-block: var(--s2); }
.logo__mark { width: 30px; height: 30px; flex-shrink: 0; }
.logo__text { display: flex; flex-direction: column; line-height: 1; }
.logo__name {
  font-family: var(--serif); font-size: 1.22rem; font-weight: 400;
  letter-spacing: 0.26em; color: var(--heading); text-transform: uppercase;
}
.logo__sub {
  font-family: var(--serif); font-size: 0.56rem; letter-spacing: 0.42em;
  text-transform: uppercase; color: var(--muted); margin-top: 5px;
}

.nav { display: none; }
/* margin-left:auto groups the nav with the theme switch at the right rather
   than leaving the switch stranded on its own at the far edge. */
@media (min-width: 900px) { .nav { display: flex; align-items: center; gap: var(--s7); margin-left: auto; } }
.nav a {
  text-decoration: none; font-size: var(--fs-sm); font-weight: 500;
  letter-spacing: 0.04em; color: var(--text); padding-block: var(--s2);
  position: relative; transition: color var(--t);
}
.nav a:hover { color: var(--bright); }
.nav a[aria-current="page"] { color: var(--bright); }
.nav a[aria-current="page"]::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px;
  height: 1px; background: var(--metal);
}
/* .nav a outranks .btn on specificity, so the CTA needs these. */
.nav a.btn, .mobile-nav a.btn { color: var(--bg); }
.nav a.btn:hover { color: var(--bg); }
.nav a.btn::after { display: none; }

/* Theme switch. Sits between the nav and the menu button, so it is in the
   same place at every width. Both glyphs are in the markup; the one that
   shows is the theme you would get by pressing it. */
.theme-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; flex-shrink: 0;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: transparent; color: var(--heading); cursor: pointer;
  transition: border-color var(--t), color var(--t);
}
.theme-toggle:hover { border-color: var(--brand-silver); color: var(--bright); }
.theme-toggle svg { width: 18px; height: 18px; }
.theme-toggle .icon-sun { display: block; }
.theme-toggle .icon-moon { display: none; }
:root:not([data-theme="dark"]) .theme-toggle .icon-sun { display: none; }
:root:not([data-theme="dark"]) .theme-toggle .icon-moon { display: block; }
/* The header row is tight on a phone: logo, switch, menu. */
.site-header__actions { display: flex; align-items: center; gap: var(--s3); }

.nav-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border: 1px solid var(--line);
  border-radius: var(--radius); background: transparent; cursor: pointer;
}
@media (min-width: 900px) { .nav-toggle { display: none; } }
.nav-toggle span { display: block; width: 18px; height: 1px; background: var(--heading); position: relative; }
.nav-toggle span::before, .nav-toggle span::after {
  content: ""; position: absolute; left: 0; width: 18px; height: 1px; background: var(--heading);
  transition: transform var(--t);
}
.nav-toggle span::before { top: -6px; }
.nav-toggle span::after  { top: 6px; }
.nav-toggle[aria-expanded="true"] span { background: transparent; }
.nav-toggle[aria-expanded="true"] span::before { transform: translateY(6px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span::after  { transform: translateY(-6px) rotate(-45deg); }

/* overflow:hidden contains the CTA's bottom margin. Without it that margin
   collapses out of the panel and shows the header's translucent background
   as a lighter strip under the menu — invisible on navy, obvious in light. */
.mobile-nav { display: none; border-top: 1px solid var(--line-soft); background: var(--bg); overflow: hidden; }
.mobile-nav.is-open { display: block; }
@media (min-width: 900px) { .mobile-nav { display: none !important; } }
.mobile-nav a {
  display: block; padding: var(--s4) 0; text-decoration: none;
  border-bottom: 1px solid var(--line-soft); font-weight: 500; color: var(--heading);
}
/* `.mobile-nav a` is one class plus one element and outranks `.btn`, so the
   CTA inherited display:block and `padding: var(--s4) 0` from the menu links.
   That left justify-content with nothing to centre and stripped the side
   padding, dropping the label flush against the button's left edge. Both have
   to be restated here, at this rule's own specificity. */
.mobile-nav .btn {
  display: flex; justify-content: center;
  padding: var(--s4) var(--s6);
  margin-block: var(--s5); width: 100%; border-bottom: 0;
}

/* --- 6. Buttons ---------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s3);
  padding: var(--s3) var(--s6);
  font-size: var(--fs-sm); font-weight: 600; letter-spacing: 0.08em;
  text-transform: uppercase; text-decoration: none;
  border: 1px solid transparent; border-radius: var(--radius);
  cursor: pointer; white-space: nowrap;
  transition: opacity var(--t), color var(--t), border-color var(--t), background var(--t);
}
.btn--primary { background: var(--metal); color: var(--bg); }
.btn--primary:hover { opacity: .86; }
/* Containers that restyle bare `a` (.panel, .prose, .site-footer, .check) beat
   .btn--primary on specificity and wash the label out to platinum-on-silver.
   Navy text is the correct colour on the metal gradient — keep this rule.  */
.panel a.btn--primary,
.prose a.btn--primary,
.site-footer a.btn--primary,
.check a.btn--primary { color: var(--bg); }
.btn--ghost { border-color: var(--line); color: var(--heading); background: transparent; }
.btn--ghost:hover { border-color: var(--brand-silver); color: var(--bright); }
.btn--lg { padding: var(--s4) var(--s7); }
.btn-row { display: flex; flex-wrap: wrap; gap: var(--s4); }

.link-arrow {
  display: inline-flex; align-items: center; gap: var(--s2);
  font-size: var(--fs-sm); font-weight: 600; letter-spacing: 0.04em;
  text-decoration: none; color: var(--heading);
  border-bottom: 1px solid var(--line); padding-bottom: 3px;
  transition: gap var(--t), border-color var(--t), color var(--t);
}
.link-arrow:hover { gap: var(--s3); color: var(--bright); border-bottom-color: var(--brand-silver); }

/* --- 7. Hero ------------------------------------------------------------- */
.hero { position: relative; overflow: hidden; border-bottom: 1px solid var(--line-soft); }
.hero::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(900px 520px at 78% -18%, var(--glow-1), transparent 68%),
    radial-gradient(620px 460px at 4% 118%, var(--glow-2), transparent 70%);
}
/* Oversized brand mark, bled off the right edge. Decorative only. */
.hero__mark {
  position: absolute; z-index: 0; pointer-events: none;
  right: -14%; top: 50%; transform: translateY(-50%);
  width: min(62vw, 720px); height: auto; opacity: 1;
}
@media (max-width: 900px) { .hero__mark { right: -32%; } }
.hero__inner { position: relative; z-index: 1; padding-block: var(--s10) var(--s9); }
.hero h1 { max-width: 15ch; }
.hero .lede { margin-top: var(--s6); }
.hero .btn-row { margin-top: var(--s8); }
.hero--page .hero__inner { padding-block: var(--s9) var(--s8); }
/* Inner pages carry far less in the hero than the home page, so the type is
   set about 30% above the base scale — it was reading small. Client's call,
   28 Aug 2026. Each value is --fs-3xl / --fs-lg / --fs-xs times 1.3. */
.hero--page h1      { font-size: clamp(2.73rem, 3.4vw + 1.8rem, 4.4rem); max-width: 20ch; }
.hero--page .lede   { font-size: clamp(1.2rem, .6vw + 1.05rem, 1.46rem); max-width: 52ch; }
.hero--page .eyebrow { font-size: 0.95rem; }
/* A one-sentence claim under the standfirst. At body size and body colour it
   read as small print trailing the lede, which is the opposite of the point.
   A hairline above it and the heading colour make it a statement of its own. */
.hero__claim {
  margin-top: var(--s6); padding-top: var(--s5);
  border-top: 1px solid var(--line);
  max-width: 44ch; font-size: var(--fs-lg); color: var(--heading);
}

/* --- 8. Stats ------------------------------------------------------------ */
.stats { display: grid; gap: var(--s6); grid-template-columns: 1fr; }
@media (min-width: 700px) { .stats { grid-template-columns: repeat(3, 1fr); } }
.stat { border-top: 1px solid var(--line); padding-top: var(--s5); }
.stat__value {
  font-family: var(--serif); font-weight: 300; font-size: var(--fs-2xl);
  line-height: 1; color: var(--heading);
}
.stat__label {
  margin-top: var(--s3); font-size: var(--fs-xs); letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--muted);
}

/* --- 8b. Snapshot band ---------------------------------------------------
   Three figures on raised tiles, sitting between two sections as a divider.
   Distinct from .stats above: a display numeral, a short metallic rule, and
   a sentence-case label rather than uppercase micro-type. */
.snapshot { padding-block: var(--s6) var(--s7); }
/* The section above already ends with its own generous padding, which stacked
   with the band's to leave ~144px of dead space. Pull it in so the band reads
   as a divider rather than a stranded row. Browsers without :has() simply keep
   the roomier gap. */
.section:has(+ .snapshot) { padding-bottom: var(--s6); }
.snapshot__grid { display: grid; gap: var(--s4); grid-template-columns: 1fr; }
@media (min-width: 700px) { .snapshot__grid { grid-template-columns: repeat(3, 1fr); } }
.snapshot__item {
  min-width: 0;
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: clamp(var(--s5), 2.2vw, var(--s6));
}
.snapshot__value {
  font-family: var(--serif); font-weight: 300; line-height: 1;
  font-size: clamp(2rem, 1.8vw + 1.1rem, 2.6rem);
  color: var(--heading);
}
.snapshot__rule {
  width: 40px; height: 2px; border: 0;
  margin: var(--s4) 0; background: var(--metal);
}
/* Declared before the phone block below, so that block's overrides win. */
.snapshot__label { color: var(--text); max-width: 24ch; font-size: var(--fs-sm); }
/* Stacked as three full tiles, the band ran to most of a phone screen for
   figures that are supporting evidence rather than the argument. Same three
   figures, one compact row instead: a single card, hairline dividers, type
   stepped down. Costs about a fifth of the height. */
@media (max-width: 700px) {
  .snapshot { padding-block: var(--s5) var(--s6); }
  .snapshot__grid {
    grid-template-columns: repeat(3, 1fr);
    gap: 0;
    background: var(--surface);
    border: 1px solid var(--line-soft);
    border-radius: var(--radius);
  }
  .snapshot__item {
    background: none; border: 0; border-radius: 0;
    padding: var(--s5) var(--s3);
    text-align: center;
  }
  .snapshot__item + .snapshot__item { border-left: 1px solid var(--line-soft); }
  .snapshot__value { font-size: clamp(1.3rem, 5.2vw, 1.6rem); }
  .snapshot__rule { width: 28px; margin: var(--s3) auto; }
  .snapshot__label { font-size: .75rem; line-height: 1.45; max-width: none; }
}

/* --- 9. Cards ------------------------------------------------------------ */
.card {
  border: 1px solid var(--line-soft); border-radius: var(--radius);
  padding: var(--s6); background: var(--surface);
  display: flex; flex-direction: column; gap: var(--s3);
  transition: border-color var(--t), background var(--t);
}
a.card { text-decoration: none; }
a.card:hover, .card:hover { border-color: var(--line); background: var(--surface-2); }
.card p { font-size: var(--fs-sm); color: var(--text); }
.card__mark { width: 22px; height: 22px; opacity: .75; margin-bottom: var(--s2); }

/* Numbered rows — the "how it works" pattern */
.steps { counter-reset: step; display: grid; gap: 0; border-top: 1px solid var(--line); }
.step {
  display: grid; gap: var(--s3); padding: var(--s6) 0;
  border-bottom: 1px solid var(--line-soft);
}
@media (min-width: 800px) { .step { grid-template-columns: 80px 280px 1fr; gap: var(--s6); align-items: start; } }
.step::before {
  counter-increment: step; content: "0" counter(step);
  font-family: var(--serif); font-size: var(--fs-lg); color: var(--muted);
}
.step h3 { font-size: var(--fs-lg); }
.step p { font-size: var(--fs-sm); }
/* On a full desktop the rows have room to breathe, so the step type steps up.
   The measure is capped at the same time — at this width the third column is
   ~780px, which at the larger size would run to a hundred characters a line. */
@media (min-width: 1100px) {
  .step { grid-template-columns: 90px 320px 1fr; }
  .step::before { font-size: 1.3rem; }
  .step h3 { font-size: 1.32rem; }
  .step p  { font-size: 1.0625rem; line-height: 1.6; max-width: 66ch; }
}

/* --- 10. Feature list ---------------------------------------------------- */
.features { display: grid; gap: var(--s6); }
@media (min-width: 800px) { .features { grid-template-columns: repeat(2, 1fr); gap: var(--s7) var(--s8); } }
/* An odd item out would sit alone in the left column and read as an
   afterthought. The fee line is the one people look for, so it spans instead. */
@media (min-width: 800px) { .feature--wide { grid-column: 1 / -1; } }
.feature { border-top: 1px solid var(--line); padding-top: var(--s5); }
/* 18px -> 20px, client's call 28 Aug 2026. */
.feature h3 { font-size: 1.25rem; margin-bottom: var(--s3); }
/* Was --fs-sm; raised to the body size, it was hard to read. 28 Aug 2026. */
.feature p { font-size: var(--fs-base); }

/* --- 11. Forms ----------------------------------------------------------- */
.form { display: grid; gap: var(--s5); }
.form__grid { display: grid; gap: var(--s5); }
@media (min-width: 640px) { .form__grid--2 { grid-template-columns: 1fr 1fr; } }
/* align-content:start stops a field that is stretched to its grid row's
   height from stretching its input along with it — otherwise a field with
   no hint renders a taller box than the one beside it. */
.field { display: grid; gap: var(--s2); align-content: start; }
.field label { font-size: var(--fs-sm); font-weight: 600; color: var(--heading); }
.field label .req { color: var(--brand-silver); }
.field input, .field select, .field textarea {
  width: 100%; padding: var(--s3) var(--s4);
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--surface); color: var(--bright); font-size: var(--fs-base);
  transition: border-color var(--t), box-shadow var(--t);
}
.field select { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%), linear-gradient(135deg, var(--muted) 50%, transparent 50%); background-position: calc(100% - 20px) 50%, calc(100% - 15px) 50%; background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; padding-right: var(--s8); }
.field textarea { min-height: 140px; resize: vertical; }
.field input::placeholder, .field textarea::placeholder { color: var(--muted); }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--brand-silver);
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.field .hint { font-size: var(--fs-xs); color: var(--muted); }
.field .error { font-size: var(--fs-xs); color: var(--danger); display: none; }
.field.is-invalid input, .field.is-invalid select, .field.is-invalid textarea { border-color: var(--danger); }
.field.is-invalid .error { display: block; }
.check { display: flex; gap: var(--s3); align-items: flex-start; }
.check input { width: 22px; height: 22px; margin-top: 2px; flex-shrink: 0; accent-color: var(--brand-silver); }
.check label { font-size: var(--fs-sm); font-weight: 400; color: var(--text); }
.check a { color: var(--heading); }
.form__status {
  font-size: var(--fs-sm); padding: var(--s4); border-radius: var(--radius); display: none;
}
.form__status.is-ok { display: block; background: var(--surface); border: 1px solid var(--line); color: var(--bright); }
.form__status.is-error { display: block; background: var(--surface); border: 1px solid var(--danger); color: var(--bright); }
.form__status a { color: var(--bright); }
.hp { position: absolute; left: -9999px; opacity: 0; height: 0; }

/* --- 12. Panel ----------------------------------------------------------- */
.panel {
  border: 1px solid var(--line-soft); border-radius: var(--radius);
  padding: var(--s6); background: var(--surface); align-self: start;
}
.panel h3 { font-size: var(--fs-lg); margin-bottom: var(--s3); }
.panel dl { display: grid; gap: var(--s4); margin-top: var(--s5); }
.panel dt { font-size: var(--fs-xs); letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); }
.panel dd { margin: var(--s1) 0 0; font-size: var(--fs-sm); color: var(--heading); }
.panel a { color: var(--heading); text-decoration-color: var(--muted); text-underline-offset: 3px; }
/* The phone and email in the contact panel are the two things a visitor on
   a phone actually taps. Inline they were 16px tall; give them a real box. */
.panel dd a { display: inline-block; padding-block: var(--s3); margin-block: calc(var(--s3) * -1); }

/* --- 13. CTA band -------------------------------------------------------- */
.cta { background: var(--cta-bg); border-top: 1px solid var(--line-soft); }
.cta__inner { padding-block: var(--s9); display: grid; gap: var(--s6); align-items: center; }
@media (min-width: 900px) { .cta__inner { grid-template-columns: 1.6fr auto; gap: var(--s8); } }
.cta h2 { font-size: var(--fs-2xl); max-width: 22ch; }
.cta p { margin-top: var(--s4); max-width: 54ch; }

/* --- 14. Footer ---------------------------------------------------------- */
.site-footer { background: var(--bg-deep); border-top: 1px solid var(--line-soft); }
.site-footer__grid { display: grid; gap: var(--s7); padding-block: var(--s8) var(--s7); }
@media (min-width: 800px) { .site-footer__grid { grid-template-columns: 2fr 1fr 1fr; } }
.site-footer h4 {
  font-size: var(--fs-xs); letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--heading); margin-bottom: var(--s4); font-weight: 500;
}
.site-footer ul { list-style: none; padding: 0; display: grid; gap: 0; margin: calc(var(--s3) * -1) 0; }
.site-footer a { text-decoration: none; font-size: var(--fs-sm); color: var(--text); transition: color var(--t); }
/* The footer list links were 16px-tall inline boxes with the spacing coming
   from the grid gap, so a thumb landing between two of them hit nothing.
   Block display plus vertical padding makes the target match the spacing. */
.site-footer ul a { display: block; padding-block: var(--s3); }
.site-footer a:hover { color: var(--bright); }
.footer-legal {
  border-top: 1px solid var(--line-soft); padding-block: var(--s5) var(--s7);
  font-size: var(--fs-xs); line-height: 1.75; color: var(--muted);
  display: grid; gap: var(--s4);
}
.footer-legal p { max-width: 92ch; }
.footer-legal .row { display: flex; flex-wrap: wrap; gap: var(--s5); justify-content: space-between; }

/* --- 15. Prose ----------------------------------------------------------- */
.prose { max-width: 68ch; }
.prose h2 { font-size: var(--fs-2xl); margin-top: var(--s8); margin-bottom: var(--s4); }
/* The gap above an h2 separates it from the section before it. On the first
   child there is nothing to separate from, and it drops the whole column
   below the panel sitting beside it. */
.prose > :first-child { margin-top: 0; }
.prose h3 { font-size: var(--fs-lg); margin-top: var(--s6); margin-bottom: var(--s2); }
.prose p + p { margin-top: var(--s4); }
.prose ul, .prose ol { margin: var(--s4) 0; padding-left: var(--s5); display: grid; gap: var(--s3); }
.prose a { color: var(--heading); text-decoration-color: var(--muted); text-underline-offset: 3px; }
/* The legal page carries three separate documents; the rule divides them. */
.prose hr { margin-block: var(--s8); }

/* --- 16. Utilities ------------------------------------------------------- */
.skip { position: absolute; left: -9999px; z-index: 999; background: var(--surface); color: var(--bright); padding: var(--s3) var(--s5); }
.skip:focus { left: var(--s4); top: var(--s4); }
:focus-visible { outline: 1px solid var(--brand-silver); outline-offset: 3px; }
.reveal { opacity: 0; transform: translateY(16px); transition: opacity .6s ease, transform .6s ease; }
.reveal.is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .reveal { opacity: 1; transform: none; } }

/* --- 17. Section backdrops ----------------------------------------------- */
/* Decorative line art behind a section. The SVG is the section's first child
   and sits at z-index 0; .wrap is lifted above it. Both are aria-hidden and
   carry no meaning — safe to remove. */
.backdrop { position: relative; isolation: isolate; overflow: hidden; }
.backdrop > .wrap { position: relative; z-index: 1; }
/* The inline line-art strokes with currentColor, so one token flips all four
   backdrops with the theme. */
.backdrop__fx { position: absolute; z-index: 0; pointer-events: none; color: var(--ink); }

.backdrop__fx--contours {
  inset: 0; width: 100%; height: 100%; opacity: .075;
  -webkit-mask-image: radial-gradient(112% 86% at 50% 54%, #000 28%, transparent 84%);
          mask-image: radial-gradient(112% 86% at 50% 54%, #000 28%, transparent 84%);
}
/* Arched fan tessellation. Covers the whole block and fades upward so the
   headline sits on clean ground. */
.backdrop__fx--fan {
  inset: 0; width: 100%; height: 100%; opacity: .075;
}
/* Deco diamond lattice — spans the block edge to edge, no fade. */
.backdrop__fx--deco {
  inset: 0; width: 100%; height: 100%; opacity: .08;
}

/* Art Deco arch-and-fan lattice — the introducers hero. Client-supplied
   AI artwork, traced to vector and set as a 700px SVG <pattern> tile so it
   repeats seamlessly at any width instead of being stretched. Strokes use
   currentColor, so it follows the theme without the invert filter the two
   photographic drawings need. Denser than the other backdrops, so it sits a
   step lower in opacity. */
.backdrop__fx--arches {
  inset: 0; width: 100%; height: 100%; opacity: .075;
}
/* Ribbed deco fan — spans the block top to bottom, no fade. */
/* The skyline needs a clear band beneath the last step row, or the drawing
   sits under the text instead of behind it. */
.section--skyline { padding-bottom: min(50vw, 860px); }
.section--city    { padding-bottom: min(46vw, 860px); }
.section--globe   { padding-bottom: min(45vw, 860px); }

/* The three pen drawings — the South Bank skyline behind 'How it works', the
   globe and jet on the About page, and St Paul's with the Millennium Bridge at
   the foot of the introducers page — share one treatment. Their sky and paper
   are dropped to transparency and the linework recoloured to platinum, so they
   composite onto the ground instead of sitting on a white card. Each is
   anchored to the bottom of its own band and eased out at the top: strong
   where there is no copy, gone by the time it reaches the text.

   The first two are potrace vectors. The city is a WebP with an alpha channel,
   because tracing it destroyed the drawing: potrace is bilevel, and this
   artwork is drawn in grey at a range of stroke weights, so a threshold turned
   the cloud hairlines into crumbs and the heavier strokes into blobs. Mapping
   ink darkness to alpha instead keeps every stroke exactly as drawn. See the
   README.

   Sizing: width 100% with height auto, so a drawing is never distorted and
   never cropped. The 820px ceiling used to be a max-height paired with
   object-fit: cover, which quietly broke on wide monitors — past the width at
   which the box grew taller than the ceiling, cover sliced the difference off
   the bottom. On a 2560px screen the introducers drawing lost a quarter of its
   height, straight through the bridge deck and the river. The ceiling is now a
   max-width per drawing, its ratio multiplied by 820, so growth stops before a
   crop is possible and the drawing centres in the band instead. */
.backdrop__fx--skyline,
.backdrop__fx--globe,
.backdrop__fx--city {
  left: 50%;
  transform: translateX(-50%);
  bottom: 0;
  width: 100%;
  height: auto;
  opacity: .55;
  filter: var(--art-filter);
  /* Only the last few pixels are eased, to avoid a hard cut across a contrail
     or a spire. A deeper fade erases exactly the features worth seeing. */
  -webkit-mask-image: linear-gradient(to top, #000 95%, transparent 100%);
          mask-image: linear-gradient(to top, #000 95%, transparent 100%);
}
.backdrop__fx--skyline { max-width: 1730px; }  /* 2.11:1 trimmed */
.backdrop__fx--globe   { max-width: 1960px; }  /* 2.39:1 trimmed */
.backdrop__fx--city    { max-width: 1865px; }  /* 2.2744:1 trimmed */

.backdrop__fx--ribs {
  inset: 0; width: 100%; height: 100%; opacity: .085;
}
@media (max-width: 700px) {
  .backdrop__fx--contours { opacity: .055; }
  .backdrop__fx--fan { opacity: .06; }
  .backdrop__fx--ribs { opacity: .06; }
  .backdrop__fx--deco { opacity: .06; }
  .backdrop__fx--arches { opacity: .06; }
  .backdrop__fx--city { opacity: .45; }
  .backdrop__fx--skyline { opacity: .45; }
  .backdrop__fx--globe { opacity: .45; }
}

/* The patterned hero sits on the raised surface — the same tone as the
   solutions block on the home page — with headroom under the text. */
.hero--fan { background: var(--surface); }
/* No radial bloom on this hero — the pattern carries the whole block evenly. */
.hero--fan::before { background: none; }
/* The fan hero was given a deep skirt so the pattern had room below the
   standfirst. Stacked with the next section's own top padding it left ~465px
   of dead space between the title and the first heading. */
.hero--fan .hero__inner { padding-bottom: clamp(var(--s6), 5vw, 76px); }

/* Same raised tone as the About hero, and no bloom — the pattern carries it. */
.hero--ribs { background: var(--surface); }
.hero--ribs::before { background: none; }
.hero--ribs .hero__inner { padding-bottom: clamp(var(--s8), 12vw, 180px); }

/* Same treatment on the privacy hero: raised ground, no bloom, pattern edge to edge. */
.hero--deco { background: var(--surface); }
.hero--deco::before { background: none; }
.hero--deco .hero__inner { padding-bottom: clamp(var(--s8), 12vw, 180px); }

/* Introducers hero: same raised ground and no bloom as the other patterned heroes. */
.hero--arches { background: var(--surface); }
.hero--arches::before { background: none; }
/* The arch pattern needed a skirt below the standfirst, but stacked with the
   next section's own top padding it read as dead space rather than air. */
.hero--arches .hero__inner { padding-bottom: clamp(var(--s6), 5vw, 76px); }

/* Stats sit inside the hero rather than in a section of their own. */
.hero__stats { margin-top: clamp(var(--s8), 8vw, var(--s10)); }

/* --- 18. Phone spacing ----------------------------------------------------
   The vertical rhythm is set for a desktop column. Carried unchanged onto a
   390px screen the same figures read as dead space: two stacked sections put
   192px of nothing between the last line of one and the first of the next,
   which is most of a thumb-scroll. Everything here is the same scale one or
   two steps down — the proportions hold, the page just stops being mostly gap.

   Last in the file on purpose: several of these override rules declared later
   than the layout section, and equal specificity means source order decides. */
/* On a phone the watermark crosses the hero buttons, and a ghost button is
   transparent, so at the desktop strength the mark reads through the label.
   Half a step back: still clearly a cross, no longer competing with the CTA. */
@media (max-width: 700px) {
  :root:not([data-theme="dark"]) { --hero-mark: #DDE2EC; }
}

@media (max-width: 700px) {
  .section        { padding-block: var(--s7); }
  .section--tight { padding-block: var(--s6); }
  .section-head   { margin-bottom: var(--s6); }

  /* Cards stacked with the desktop 32px gutter turned a three-card row into
     most of a phone screen. Tighter gutter and slightly shallower cards keep
     the group readable as one block instead of three separate screens. */
  .grid { gap: var(--s4); }
  .card { padding: var(--s5); }

  .hero__inner            { padding-block: var(--s8) var(--s7); }
  .hero--page .hero__inner{ padding-block: var(--s7) var(--s6); }
  .hero .btn-row          { margin-top: var(--s6); }

  .cta__inner { padding-block: var(--s7); }

  /* The band and the section above it are already tightened; take them down
     one more step so the snapshot reads as a divider, not an interlude. */
  .snapshot { padding-block: var(--s4) var(--s5); }
  .section:has(+ .snapshot) { padding-bottom: var(--s5); }

  .site-footer__grid { padding-block: var(--s7) var(--s6); }
  .footer-legal      { padding-block: var(--s5) var(--s6); }

  /* The illustration bands keep their viewport-relative depth — that padding
     is the picture, not spacing. Re-asserted because the `.section` shorthand
     above sets padding-bottom too, at equal specificity and later in the file,
     which otherwise collapses the band and drops the drawing under the copy. */
  .section--skyline { padding-bottom: min(50vw, 860px); }
  .section--city    { padding-bottom: min(46vw, 860px); }
  .section--globe   { padding-bottom: min(45vw, 860px); }
}
