/* Aceogen — site stylesheet.
   Hand-written port of the design system. The JSX in design-system/ui_kits/website/
   and design-system/components/ is the visual specification only; its runtime never
   ships. Every value below is a DS token or a site variable derived from one. */

@import "./tokens/fonts.css";
@import "./tokens/colors.css";
@import "./tokens/typography.css";
@import "./tokens/spacing.css";
@import "./tokens/motion.css";

/* ── Site variables: layout metrics the DS tokens do not carry ───────────── */
:root{
  /* The site is light-only by design. Declaring it stops Android Chrome from
     force-darkening the page, which is the one case that would invalidate the
     contrast table in CSS-CONTRACT.md §2. */
  color-scheme:light;

  --container-max:1200px;
  --container-pad:var(--sp-10);              /* 40px gutter */
  --container-pad-sm:var(--sp-6);            /* 20px gutter on mobile */
  /* Band rhythm. Tighter than the kit at the small end so a phone screen carries
     less dead space between bands, more generous than the kit at the large end so
     a colored band reads as its own room. 40px → 96px. */
  --section-y:clamp(28px,3.6vw,56px);
  --grid-gap:var(--sp-5);                    /* 16px */
  --split-gap:clamp(24px,3vw,40px);
  --measure:62ch;

  --header-h:76px;
  --header-h-sm:60px;
  --logo-h:26px;
  --nav-gap:26px;
  --fs-nav:16px;

  /* Type sizes the kit hardcodes, clamped down for small screens */
  --fs-hero:clamp(32px,5.2vw,var(--fs-display));      /* 60px */
  --fs-page-title:clamp(28px,4.2vw,var(--fs-title));  /* 41px */
  --fs-section-title:clamp(24px,2.9vw,var(--fs-subhead)); /* 30px */
  --fs-cta-title:clamp(28px,4vw,44px);
  --fs-copy:clamp(15px,0.55vw + 11.5px,17px);  /* prose only — 15px token floor, 17px past ~1000px */

  /* Component metrics transcribed from components/forms/Button.jsx & Input.jsx */
  --btn-pad-sm:7px 12px;
  --btn-pad-md:10px 16px;
  --btn-pad-lg:13px 22px;
  --field-pad:var(--sp-3) var(--sp-4);       /* 10px 12px */
  --field-gap:6px;
  --icon-sm:15px;
  --icon-md:16px;
  --icon-lg:18px;
  --icon-box:46px;
  --step-num-col:34px;
  --spec-label-col:200px;

  /* Contrast overrides on two DS aliases. The palette is untouched; only the roles
     move. #a3a3a3 on white is 2.5:1 and #f45f00 is 3.2:1 — both below AA for the
     12-15px text they were carrying. Grey-700 is 7.2:1 and deep-orange 4.6:1; both
     are DS values. --accent keeps the brand orange for fills, buttons and the ring. */
  --text-muted:var(--aceogen-grey-700);
  --text-accent:var(--aceogen-deep-orange);

  --ring:0 0 0 3px color-mix(in srgb,var(--accent) 15%,transparent); /* rgba(244,95,0,.15) */
  --header-bg:color-mix(in srgb,var(--aceogen-white) 85%,transparent);
  --border-hover:var(--aceogen-grey-300);
}

/* ── Reset ───────────────────────────────────────────────────────────────── */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{
  margin:0;background:var(--surface);color:var(--text-body);
  font-family:var(--font-sans);font-size:var(--fs-copy);font-weight:var(--fw-medium);
  line-height:var(--lh-loose);letter-spacing:var(--ls-snug);
  -webkit-font-smoothing:antialiased;
}
h1,h2,h3,h4,p,figure,dl,dd,blockquote{margin:0}
ul,ol{margin:0;padding:0;list-style:none}
img,svg{display:block;max-width:100%}
[hidden]{display:none!important} /* keeps `hidden` winning over component display rules */
a{color:var(--accent-hover);text-decoration:none}
a:hover{color:var(--accent)}
button{font:inherit;color:inherit}
strong,b{font-weight:var(--fw-semibold);color:var(--text-strong)}
hr{border:0;border-top:var(--hairline);margin:var(--sp-8) 0}
:focus-visible{outline:2px solid var(--focus);outline-offset:2px}

/* ── Accessibility helpers ───────────────────────────────────────────────── */
.visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.skip-link{
  position:absolute;left:var(--sp-2);top:var(--sp-2);z-index:40;transform:translateY(-250%);
  background:var(--surface);border:var(--hairline);border-radius:var(--radius-sm);
  padding:var(--sp-3) var(--sp-5);color:var(--text-strong);font-size:var(--fs-caption);
}
.skip-link:focus{transform:none;color:var(--text-strong)}

/* ── Layout ──────────────────────────────────────────────────────────────── */
.container{width:100%;max-width:var(--container-max);margin:0 auto;padding-inline:var(--container-pad)}
.section{padding-block:var(--section-y)}
.section+.section{border-top:var(--hairline)}
.section--muted{background:var(--aceogen-off-blue)}  /* same band as .section--offblue */
.section--hero{padding-block:clamp(24px,3.2vw,48px) clamp(24px,3vw,44px)}
.section--tight{padding-block:clamp(22px,2.6vw,38px)}
.section-head{max-width:620px;margin-bottom:clamp(18px,2vw,28px)}
.section-head--wide{max-width:820px}
.stack>*+*{margin-top:var(--sp-5)}
.stack--sm>*+*{margin-top:var(--sp-2)}
.stack--lg>*+*{margin-top:var(--sp-7)}
.stack--xl>*+*{margin-top:var(--sp-9)}
.prose{max-width:var(--measure)}
.prose>*+*{margin-top:var(--sp-5)}
.measure{max-width:var(--measure)}

.grid{display:grid;gap:var(--grid-gap)}
.grid--2{grid-template-columns:repeat(2,1fr)}
.grid--3{grid-template-columns:repeat(3,1fr)}
.split{display:grid;grid-template-columns:0.9fr 1.1fr;gap:var(--split-gap);align-items:start}
.split--even{grid-template-columns:1fr 1fr}
.split--media{grid-template-columns:1.05fr 0.95fr}  /* copy left, .figure right (Hero.jsx) */
.split--center{align-items:center}

/* ── Bands ───────────────────────────────────────────────────────────────────
   A band is a .section that paints its own full-bleed background and, with it, a
   text-color context: every component inside resolves its colors from the tokens
   the band re-binds, so no component is duplicated per band. The .container inside
   still holds the 1200px measure.

   Page order on the homepage: white → sky → white → navy → white → white → orange.
   The company block before the CTA is white, not a tint: no coloured band may touch the
   orange CTA, and two whites in a row get the hairline divider back automatically.

   Contrast was computed, not eyeballed (sRGB relative luminance, WCAG 2.1 ratios).
   Every ratio below is stated against that band's own background.
     sky  #deeefe  ink #2c2825 12.36:1 · grey-700 #575757 6.11:1 · navy #1e3d59 9.52:1
     off-blue #e8ebef  ink 12.22:1 · grey-700 6.04:1 · navy 9.41:1
   Deep-orange #cd4900 is 4.62:1 on white but only 3.91:1 on sky and 3.86:1 on
   off-blue — under AA for the 12–15px text --text-accent carries (.eyebrow, list
   markers, .mono, step numerals). On tinted bands the accent role therefore moves
   to navy (9.52:1 / 9.41:1); orange stays on those bands as a button fill only. */
.section--sky,.section--offblue,.section--muted{
  --text-accent:var(--aceogen-navy);          /* 9.52:1 on sky, 9.41:1 on off-blue */
  --surface-muted:var(--aceogen-white);       /* .callout/.icon-box must not melt into the tint */
  --border-solid:color-mix(in srgb,var(--aceogen-navy) 25%,transparent);
  --border-hover:color-mix(in srgb,var(--aceogen-navy) 45%,transparent);
  color:var(--text-body);                     /* grey-700: 6.11:1 sky, 6.04:1 off-blue */
}
/* A tinted band remaps --surface-muted to white so .callout and .icon-box keep a visible
   surface. .btn--secondary is white already and hovers to --surface-muted, so on those
   bands the hover resolved to the same white and the button had no hover state at all
   (.btn--ghost, transparent over the tint, has the same problem). Restore the default
   off-blue for those two components only; the callout keeps the white it was given. */
:is(.section--sky,.section--offblue,.section--muted) :is(.btn--secondary,.btn--ghost){
  --surface-muted:var(--aceogen-off-blue);
}

/* Link colors inside bands live with the other band-context rules, below .link. */
.section--sky{background:var(--aceogen-sky)}
.section--offblue{background:var(--aceogen-off-blue)}
.section--navy{background:var(--surface-dark)}
.section--accent{background:var(--accent)}

/* ── Band dividers ──────────────────────────────────────────────────────────
   With colored bands the hairline between sections is redundant: the color change
   is the divider. Keep the rule only where two same-colored bands meet. */
.section+.section{border-top:0}
:where(.section:not(.section--sky,.section--offblue,.section--muted,.section--navy,.section--accent))
  +.section:not(.section--sky,.section--offblue,.section--muted,.section--navy,.section--accent){
  border-top:var(--hairline);
}
.section--sky+.section--sky,
.section--navy+.section--navy,
.section--accent+.section--accent{border-top:var(--hairline)}
:is(.section--offblue,.section--muted)+:is(.section--offblue,.section--muted){border-top:var(--hairline)}

/* ── Figure slots ────────────────────────────────────────────────────────────
   Hero.jsx layers the artwork over a 135° amber→navy gradient in one background
   shorthand; the same idea, split in two so the gradient is written once: the
   element paints the gradient, ::after paints the artwork on top of it. A missing
   file therefore degrades to the gradient — never to a broken
   image icon. Add a slot by adding one --figure-img line, never an inline style. */
.figure{
  position:relative;overflow:hidden;border-radius:var(--radius-sm);
  background:linear-gradient(135deg,var(--aceogen-amber),var(--aceogen-navy));
}
.figure::after{
  content:"";position:absolute;inset:0;
  background-image:var(--figure-img,none);
  background-size:cover;background-position:center;background-repeat:no-repeat;
}
.figure--wide{aspect-ratio:16/9}
.figure--flat{aspect-ratio:3/2}
.figure--banner{aspect-ratio:21/9}
.figure--square{aspect-ratio:1/1}
.figure--tall{aspect-ratio:3/4}
.figure>img{width:100%;height:100%;object-fit:cover}  /* optional real <img> layer */
/* Slots. One per generated file; the aspect class must match the ratio the artwork
   was drawn at, or background-size:cover crops the negative space it was composed
   around. Names come from assets-src/img/PROMPTS.md, but the ratios below are the
   files' REAL ratios, not the ones the prompts asked for: gpt-image-2 returned
   roughly 16:9 for everything except the 21:9 banner, so catalogue (asked 3:2, got
   1.82) and contact (asked 1:1, got 1.50) were cropping at the sides until the
   markup was moved onto the classes that match. Re-check the ratio of any file that
   is regenerated before trusting the prompt. */
.figure--hero{--figure-img:url("/assets/img/hero.webp")}                     /* 1.82  --wide   */
.figure--catalogue{--figure-img:url("/assets/img/catalogue.webp")}           /* 1.82  --wide   */
/* audit.webp is the only artwork drawn on its own navy ground, sitting in a rounded slot on
   the navy band. gpt-image-2 returned it on #022c56, so scripts/normalize-navy.py repainted
   the ground to exactly #1e3d59 and it is stored lossless — lossy WebP drifts a flat field by
   a value or two and the seam comes back. The slot also paints flat navy underneath, so a
   stray transparent pixel degrades to an invisible edge rather than a rounded-rectangle seam. */
.figure--audit{--figure-img:url("/assets/img/audit.webp");background:var(--aceogen-navy)} /* 1.87 --wide; ground normalized to #1e3d59 by scripts/normalize-navy.py */
.figure--services{--figure-img:url("/assets/img/services-header.webp")}      /* 21:9  --banner */
.figure--contact{--figure-img:url("/assets/img/contact.webp")}               /* 3:2   --flat   */

/* ── Typography ──────────────────────────────────────────────────────────── */
.eyebrow{
  font-family:var(--font-label);font-size:var(--fs-label);font-weight:var(--fw-semibold);
  letter-spacing:0.04em;text-transform:uppercase;color:var(--text-accent);
  margin-bottom:var(--sp-4);
}
.display,.page-title,.section-title{
  font-weight:var(--fw-medium);letter-spacing:var(--ls-tight);
  color:var(--text-heading);text-wrap:balance;
}
.display{font-size:var(--fs-hero);line-height:var(--lh-display);max-width:18ch}
.page-title{font-size:var(--fs-page-title);line-height:var(--lh-display);max-width:24ch}
.section-title{font-size:var(--fs-section-title);line-height:1.15}
.sub-title,.card-title{
  font-size:var(--fs-h4);font-weight:var(--fw-semibold);letter-spacing:var(--ls-snug);
  line-height:1.25;color:var(--text-strong);
}
.mini-title,.callout-title,.step-title{
  font-size:var(--fs-copy);font-weight:var(--fw-semibold);letter-spacing:var(--ls-snug);
  color:var(--text-strong);
}
.lead{
  font-size:var(--fs-lead);font-weight:var(--fw-medium);line-height:var(--lh-loose);
  letter-spacing:var(--ls-snug);color:var(--text-body);
}
.body,.card-text,.step-body,.spec-body{font-size:var(--fs-copy);font-weight:var(--fw-medium);line-height:var(--lh-loose);color:var(--text-body)}
.muted{font-size:var(--fs-caption);color:var(--text-muted)}
.mono{font-family:var(--font-mono);font-size:var(--fs-caption);color:var(--text-accent)}
.link{color:var(--accent-hover);text-decoration:underline;text-underline-offset:3px}
.link-arrow{display:inline-flex;align-items:center;gap:var(--sp-2);font-weight:var(--fw-medium);color:var(--accent-hover)}
.link-arrow svg{width:var(--icon-md);height:var(--icon-md)}
.link-arrow:hover{color:var(--accent)}

/* ── Lists, steps, spec rows ─────────────────────────────────────────────── */
.list{display:flex;flex-direction:column;gap:var(--sp-2)}
.list--loose{gap:var(--sp-4)}
.list>li{position:relative;padding-left:var(--sp-6);font-size:var(--fs-copy);line-height:var(--lh-loose);color:var(--text-body)}
.list>li::before{content:"—";position:absolute;left:0;color:var(--text-accent)}

.steps{counter-reset:step;display:flex;flex-direction:column;gap:var(--sp-6)}
.step{display:grid;grid-template-columns:var(--step-num-col) 1fr;column-gap:var(--sp-5)}
.step::before{
  counter-increment:step;content:counter(step,decimal-leading-zero);
  font-family:var(--font-mono);font-size:var(--fs-caption);color:var(--text-accent);
  line-height:var(--lh-loose);
}
.step-title{grid-column:2}
.step-body{grid-column:2;margin-top:var(--sp-1)}

.spec{display:grid;grid-template-columns:var(--spec-label-col) 1fr;gap:var(--sp-7) var(--sp-9)}
.spec-label{
  font-family:var(--font-label);font-size:var(--fs-label);font-weight:var(--fw-semibold);
  letter-spacing:0.04em;text-transform:uppercase;color:var(--text-muted);padding-top:3px;
}
.spec-body>*+*{margin-top:var(--sp-4)}

/* ── Cards, callouts, badges ─────────────────────────────────────────────── */
.card{
  display:flex;flex-direction:column;gap:var(--sp-3);background:var(--surface);
  border:var(--hairline);border-radius:var(--radius-sm);padding:var(--sp-6);
  transition:border-color var(--dur-base) var(--ease-standard);
}
.card:hover{border-color:var(--border-hover)}
.card--plain{border:0;border-top:var(--hairline);border-radius:var(--radius-none);padding:var(--sp-7) 0 0}
.card--plain:hover{border-color:var(--border-hairline)}
a.card{color:inherit}
a.card:hover{color:inherit;border-color:var(--border-hover)}
.card-list{margin-top:var(--sp-1)}
.icon-box{
  width:var(--icon-box);height:var(--icon-box);border-radius:var(--radius-sm);
  background:var(--surface-muted);color:var(--text-accent);
  display:flex;align-items:center;justify-content:center;flex:0 0 auto;
}
.icon-box svg{width:var(--sp-7);height:var(--sp-7)}

.callout{background:var(--surface-muted);border-radius:var(--radius-sm);padding:var(--sp-7)}
.callout--hairline{background:var(--surface);border:var(--hairline)}

.badge{
  display:inline-flex;align-items:center;gap:var(--sp-1);font-family:var(--font-label);
  font-weight:var(--fw-semibold);font-size:var(--fs-label);line-height:1;letter-spacing:0.02em;
  text-transform:uppercase;padding:var(--sp-1) var(--sp-2);border-radius:var(--radius-sm);
  white-space:nowrap;background:var(--surface);color:var(--text-strong);
  border:1px solid var(--border-solid);
}
.badge--subtle{background:var(--surface-muted);color:var(--text-body);border-color:transparent}
.badge--accent{background:var(--accent);color:var(--aceogen-white);border-color:transparent}

/* ── Buttons (components/forms/Button.jsx) ───────────────────────────────── */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:var(--sp-2);
  font-family:var(--font-sans);font-weight:var(--fw-medium);font-size:var(--fs-body);
  letter-spacing:var(--ls-snug);line-height:1;padding:var(--btn-pad-md);
  border:1px solid transparent;border-radius:var(--radius-sm);cursor:pointer;
  white-space:nowrap;text-decoration:none;
  transition:background var(--dur-base) var(--ease-standard),
             border-color var(--dur-base) var(--ease-standard),
             opacity var(--dur-base) var(--ease-standard);
}
.btn--sm{padding:var(--btn-pad-sm);font-size:var(--fs-caption)}
.btn--lg{padding:var(--btn-pad-lg)}
.btn--block{width:100%}
.btn svg{width:var(--icon-md);height:var(--icon-md);flex:0 0 auto}
.btn--sm svg{width:var(--icon-sm);height:var(--icon-sm)}
.btn--lg svg{width:var(--icon-lg);height:var(--icon-lg)}
.btn[disabled],.btn[aria-disabled="true"]{opacity:.45;cursor:not-allowed}
.btn--primary,.btn--primary:hover{color:var(--aceogen-white)}
.btn--primary{background:var(--accent)}
.btn--primary:hover{background:var(--accent-hover)}
.btn--secondary,.btn--secondary:hover,.btn--ghost,.btn--ghost:hover{color:var(--text-strong)}
.btn--secondary{background:var(--surface);border-color:var(--border-solid)}
.btn--secondary:hover{background:var(--surface-muted)}
.btn--ghost{background:transparent}
.btn--ghost:hover{background:var(--surface-muted)}
.btn--dark,.btn--dark:hover{color:var(--text-on-dark)}
.btn--dark{background:var(--surface-dark)}
.btn--dark:hover{background:color-mix(in srgb,var(--surface-dark) 72%,var(--aceogen-black))}
.btn--on-accent,.btn--on-accent:hover{color:var(--aceogen-white)}
.btn--on-accent{background:color-mix(in srgb,var(--aceogen-white) 15%,transparent)}
.btn--on-accent:hover{background:color-mix(in srgb,var(--aceogen-white) 26%,transparent)}
.btn-row{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-4)}
.btn-row--center{justify-content:center}

/* ── Forms (components/forms/Input.jsx, Textarea.jsx) ────────────────────── */
.form{display:flex;flex-direction:column;gap:var(--sp-6)}
.field{display:flex;flex-direction:column;gap:var(--field-gap)}
.field-label{font-size:var(--fs-caption);font-weight:var(--fw-medium);letter-spacing:var(--ls-snug);color:var(--text-strong)}
.input,.textarea{
  width:100%;font-family:var(--font-sans);font-size:var(--fs-body);font-weight:var(--fw-medium);
  letter-spacing:var(--ls-snug);line-height:var(--lh-body);color:var(--text-strong);
  background:var(--surface);border:1px solid var(--border-solid);border-radius:var(--radius-sm);
  padding:var(--field-pad);outline:none;
  transition:border-color var(--dur-base) var(--ease-standard),
             box-shadow var(--dur-base) var(--ease-standard);
}
.textarea{resize:vertical;line-height:var(--lh-loose)}
/* Placeholders keep the lighter grey on purpose: every field has a real label,
   so this is an example, not content, and it must not read as a filled value. */
.input::placeholder,.textarea::placeholder{color:var(--aceogen-grey-500)}
.input:focus,.textarea:focus{border-color:var(--accent);box-shadow:var(--ring)}
.input:focus-visible,.textarea:focus-visible{outline:none}
.input:disabled,.textarea:disabled{background:var(--surface-muted);opacity:.6}
.field--error .input,.field--error .textarea{border-color:var(--aceogen-red)}
.field--error .input:focus,.field--error .textarea:focus{box-shadow:none}
.field-hint{font-size:var(--fs-caption);letter-spacing:var(--ls-snug);color:var(--text-muted)}
.field-error{font-size:var(--fs-caption);letter-spacing:var(--ls-snug);color:var(--aceogen-red)}
.form-status{
  font-size:var(--fs-body);border:1px solid var(--border-solid);border-radius:var(--radius-sm);
  padding:var(--sp-4) var(--sp-5);color:var(--text-body);
}
.form-status--ok{background:var(--surface-muted);border-color:transparent;color:var(--text-strong)}
.form-status--error{border-color:var(--aceogen-red);color:var(--aceogen-red)}
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

/* ── Header (ui_kits/website/SiteHeader.jsx) ─────────────────────────────── */
.site-header{
  position:sticky;top:0;z-index:20;background:var(--header-bg);
  -webkit-backdrop-filter:saturate(180%) blur(12px);
  backdrop-filter:saturate(180%) blur(12px);
  border-bottom:var(--hairline);
}
.header-row{display:flex;align-items:center;gap:var(--sp-9);height:var(--header-h)}
.logo,.logo:hover{color:var(--text-strong)}
.logo{display:inline-flex;align-items:center}
.logo-mark{width:var(--logo-h);height:var(--logo-h)}
.logo-word{
  font-weight:var(--fw-semibold);font-size:calc(var(--logo-h)*0.9);letter-spacing:var(--ls-tight);
  line-height:1;margin-left:calc(var(--logo-h)*0.2);white-space:nowrap;
}
.site-nav{display:flex;align-items:center;gap:var(--nav-gap);margin-left:auto}
.nav-link{font-size:var(--fs-nav);font-weight:var(--fw-medium);letter-spacing:var(--ls-snug);color:var(--text-strong)}
.nav-link:hover{color:var(--accent-hover)}
.nav-cta{padding:var(--btn-pad-md);font-size:var(--fs-body)}
.nav-link[aria-current="page"]{
  color:var(--accent-hover);text-decoration:underline;
  text-underline-offset:6px;text-decoration-thickness:2px;
}
.nav-toggle{
  display:none;align-items:center;justify-content:center;width:var(--sp-10);height:var(--sp-10);
  background:transparent;border:1px solid transparent;border-radius:var(--radius-sm);
  color:var(--text-strong);cursor:pointer;margin-left:auto;
}
.nav-toggle:hover{background:var(--surface-muted)}
.nav-toggle svg{width:var(--sp-7);height:var(--sp-7)}
.nav-toggle .i-close{display:none}
.nav-toggle[aria-expanded="true"] .i-menu{display:none}
.nav-toggle[aria-expanded="true"] .i-close{display:block}

/* ── CTA band (ui_kits/website/CTA.jsx) ──────────────────────────────────── */
.cta-card{
  background:var(--accent);border-radius:var(--radius-sm);text-align:center;
  padding:clamp(40px,6vw,72px) clamp(24px,4vw,56px);
}
.cta-inner{max-width:640px;margin:0 auto}
.cta-title{
  font-size:var(--fs-cta-title);font-weight:var(--fw-medium);line-height:var(--lh-display);
  letter-spacing:var(--ls-tight);color:var(--aceogen-white);text-wrap:balance;
}
/* Was white at 90% opacity: over #f45f00 that composites to 2.88:1, under even the
   3:1 large-text floor. Full white is 3.24:1, which clears AA-large but not the 4.5:1
   body threshold — so this line has to qualify as large text at every width. WCAG counts
   14pt bold (18.66px at weight 700) as large, so the phone floor is bold: 20px/700 is
   large text, 3.24:1, AA. From 24px the weight no longer matters and it steps back down
   to medium. This was the one measured shortfall on the site; nothing else small is
   allowed on the accent band. See CSS-CONTRACT §2 "Contrast". */
.cta-text{
  font-size:clamp(20px,2.6vw,24px);font-weight:var(--fw-bold);line-height:var(--lh-loose);
  color:var(--text-on-dark);
}
@media (min-width:924px){  /* 24px = 2.6vw; at and above it the size alone carries AA-large */
  .cta-text{font-weight:var(--fw-medium)}
}

/* ── On-dark context ─────────────────────────────────────────────────────────
   One selector re-binds the color tokens for everything inside a dark band; the
   components below it (.card, .callout, .badge, .icon-box, .list, .steps, .spec,
   .btn--secondary, hr) already read those tokens, so none of them is redefined here.

   Ratios against navy #1e3d59:
     white #ffffff .................... 11.25:1  ✔ AA any size
     --text-on-dark-muted (white 65%) .. 5.76:1  ✔ AA any size (resolves to #b0bbc5)
     --aceogen-amber #fa9819 ........... 5.13:1  ✔ AA any size — the on-navy accent
     --aceogen-orange #f45f00 .......... 3.47:1  ✘ 12–15px text; large only. Never
                                                   the accent role on navy.
     --aceogen-steel #48749e ........... 2.29:1  ✘ text at any size on navy
   Ratios against a card on navy (--surface = white 4%, resolves to #274560):
     white 9.97:1 ✔ · muted 5.11:1 ✔ · amber 4.54:1 ✔ (4% is the ceiling: at 6%
     the fill lifts to #2c4963 and amber drops to 4.27:1, under AA).
   Ratios against orange #f45f00:
     white ............................. 3.24:1  ✔ AA large (≥24px) only
     navy (a .btn--dark chip) .......... 3.47:1  ✔ ≥3:1 boundary against the band
     amber ............................. 1.48:1  ✘ — on this band the accent is white */
:is(.section--navy,.section--accent,.cta-card){
  color:var(--text-on-dark);
  --text-heading:var(--text-on-dark);
  --text-strong:var(--text-on-dark);
  --text-body:var(--text-on-dark);
  --text-muted:var(--text-on-dark-muted);
  --surface:color-mix(in srgb,var(--aceogen-white) 4%,transparent);
  --surface-muted:color-mix(in srgb,var(--aceogen-white) 8%,transparent);
  --hairline:1px solid var(--border-on-dark);
  --border-hairline:var(--border-on-dark);
  --border-solid:var(--border-on-dark);
  --border-hover:color-mix(in srgb,var(--aceogen-white) 34%,transparent);
}
.section--navy{--text-accent:var(--aceogen-amber)}
/* On orange nothing but white clears 3:1, so the accent and muted roles collapse to
   white and the band carries no 12–15px text at all (see CSS-CONTRACT §2 bands). */
:is(.section--accent,.cta-card){--text-accent:var(--text-on-dark);--text-muted:var(--text-on-dark)}

/* ── Link colors inside bands ────────────────────────────────────────────────
   These sit below .link on purpose: they and .link are both one class deep, so the
   later rule is the one that wins. .btn is excluded — buttons carry their own color.
   An inline link inherits --accent-hover (#cd4900): 3.91:1 on sky and 3.86:1 on
   off-blue, under AA at 15px, so on a tinted band links take the navy accent role
   (9.52:1 / 9.41:1) and darken to near-black on hover (17.8:1). */
:is(.section--sky,.section--offblue,.section--muted) :where(a:not(.btn)){color:var(--aceogen-navy)}
:is(.section--sky,.section--offblue,.section--muted) :where(a:not(.btn)):hover{color:var(--text-strong)}
:is(.section--navy,.section--accent,.cta-card) :where(a:not(.btn)){color:var(--text-on-dark)}
.section--navy :where(a:not(.btn)):hover{color:var(--aceogen-amber)}      /* 5.13:1 */
:is(.section--accent,.cta-card) :where(a:not(.btn)):hover{color:var(--text-on-dark);opacity:.82}

/* The quiet buttons on the orange band. The DS translucent fill puts a 15px white
   label on #f67726 at 2.77:1; a solid white chip with a deep-orange label is
   #cd4900 on #ffffff = 4.62:1 ✔ AA, and the hover flips to navy/white = 11.25:1 ✔. */
:is(.section--accent,.cta-card) :is(.btn--secondary,.btn--ghost,.btn--on-accent){
  background:var(--aceogen-white);border-color:transparent;color:var(--accent-hover);
}
:is(.section--accent,.cta-card) :is(.btn--secondary,.btn--ghost,.btn--on-accent):hover{
  background:var(--surface-dark);color:var(--text-on-dark);
}
/* ── Footer (ui_kits/website/SiteFooter.jsx) ─────────────────────────────── */
.site-footer{border-top:var(--hairline);background:var(--surface)}
.footer-grid{display:grid;grid-template-columns:1.4fr 1fr 1fr;gap:var(--sp-10);padding-block:var(--sp-12) var(--sp-10)}
.footer-col{min-width:0}
.footer-text{font-size:var(--fs-body);max-width:280px;margin-top:var(--sp-5)}
.footer-head{
  font-family:var(--font-label);font-size:var(--fs-label);font-weight:var(--fw-semibold);
  letter-spacing:0.04em;text-transform:uppercase;color:var(--text-muted);margin-bottom:var(--sp-5);
}
.footer-links{display:flex;flex-direction:column;gap:var(--sp-4);align-items:flex-start}
.footer-link{font-size:var(--fs-body);font-weight:var(--fw-medium);letter-spacing:var(--ls-snug);color:var(--text-body)}
.footer-link:hover{color:var(--accent-hover)}
.footer-bottom{border-top:var(--hairline)}
.footer-bottom-row{display:flex;align-items:center;flex-wrap:wrap;gap:var(--sp-5);padding-block:var(--sp-6)}
.footer-meta{font-size:var(--fs-caption);font-weight:var(--fw-medium);color:var(--text-muted)}

/* ── Responsive: 900px (tablet / mobile nav) ─────────────────────────────── */
@media (max-width:900px){
  :root{--logo-h:22px;--fs-nav:15px}
  .container{padding-inline:var(--container-pad-sm)}
  .header-row{height:var(--header-h-sm);gap:var(--sp-5)}
  /* The drop panel is opened by js/site.js alone, so it — and the control that
     opens it — exist only under the `js` marker the page head sets. Without
     JavaScript the toggle never renders and the links wrap under the logo. */
  .js .nav-toggle{display:inline-flex}
  .js .site-nav{
    display:none;position:absolute;top:100%;left:0;right:0;margin-left:0;
    flex-direction:column;align-items:stretch;gap:var(--sp-5);
    background:var(--surface);border-top:var(--hairline);
    padding:var(--sp-5) var(--container-pad-sm) var(--sp-7);
  }
  .js .site-header[data-nav-open="true"] .site-nav{display:flex}
  html:not(.js) .header-row{flex-wrap:wrap;height:auto;padding-block:var(--sp-4)}
  html:not(.js) .site-nav{flex-wrap:wrap;margin-left:0;gap:var(--sp-5)}
  /* SiteHeader.jsx puts the panel CTA at size md, full width: a 44px tap target. */
  .nav-toggle{width:44px;height:44px}
  .nav-cta{padding:var(--btn-pad-md);font-size:var(--fs-body)}
  .js .nav-cta{width:100%}
  .grid--3{grid-template-columns:repeat(2,1fr)}
  .split,.split--even,.split--media{grid-template-columns:1fr}
  .spec{display:block}
  .spec-label{padding-top:0;margin-top:var(--sp-7)}
  .spec>.spec-label:first-child{margin-top:0}
  .spec-body{margin-top:var(--sp-2)}
  .footer-grid{grid-template-columns:1fr 1fr;gap:var(--sp-8);padding-block:var(--sp-10) var(--sp-8)}
  .footer-brand{grid-column:1/-1}
}

/* ── Responsive: 560px (phone) ───────────────────────────────────────────── */
@media (max-width:560px){
  .grid--2,.grid--3{grid-template-columns:1fr}
  .footer-grid{grid-template-columns:1fr}
  .footer-text{max-width:none}
  .btn-row>.btn{width:100%}
  .step{grid-template-columns:var(--sp-8) 1fr;column-gap:var(--sp-4)}
}

/* ── Motion preferences ──────────────────────────────────────────────────── */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{transition-duration:1ms!important;animation-duration:1ms!important}
}
