/* ============================================================
   AMALAB — components.css
   Nav · buttons · cards · lists · footer · forms · FAQ
   ============================================================ */

/* ---------- Header / nav ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: color-mix(in srgb, var(--paper) 92%, transparent);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border);
}
.site-header .container {
  display: flex;
  align-items: center;
  gap: var(--s-6);
  height: var(--nav-h);
}
.brand {
  display: flex;
  align-items: center;
  gap: 14px;
  text-decoration: none;
  margin-right: auto;
}
.brand img { height: 28px; width: auto; }
.brand-word {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.375rem;
  color: var(--navy);
  letter-spacing: -0.01em;
}
/* Header wordmark carries the tertiary accent dot, echoing .title-dot on headlines */
.site-header .brand-word::after {
  content: ".";
  color: var(--orange);
}

.site-nav { display: flex; align-items: center; gap: var(--s-1); }
.site-nav a:not(.btn),
.nav-drop-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 10px 14px;
  min-height: 44px;
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--fg);
  text-decoration: none;
  border-radius: var(--radius-btn);
  transition: background var(--t-ui) var(--ease-out);
}
.site-nav a:not(.btn):hover,
.nav-drop-toggle:hover { background: var(--paper-2); }
.site-nav a:not(.btn)[aria-current="page"] {
  color: var(--navy);
  font-weight: 600;
  box-shadow: inset 0 -2px 0 var(--teal);
  border-radius: var(--radius-btn) var(--radius-btn) 0 0;
}

/* Solutions dropdown */
.nav-drop { position: relative; }
.nav-drop-toggle .caret {
  width: 8px; height: 8px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translateY(-2px);
  transition: transform var(--t-ui) var(--ease-out);
}
.nav-drop-toggle[aria-expanded="true"] .caret {
  transform: rotate(-135deg) translateY(-2px);
}
.nav-drop-menu {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  min-width: 300px;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card-hover);
  padding: var(--s-2);
  display: none;
}
.nav-drop-menu.is-open { display: block; }

/* Origin-aware entrance (desktop only). The panel is anchored under the
   trigger's left edge, so it scales out of the TRIGGER rather than its own
   centre — the default centre origin is wrong for every trigger-anchored
   popover. 150ms sits at the fast end of the dropdown budget because this is
   site chrome a visitor may open repeatedly.
   Scoped to ≥1120px on purpose: below that the same element becomes a static
   inline accordion (see the ≤1119px block), where a floating-panel scale would
   read wrong. Pure progressive enhancement — @starting-style and
   allow-discrete degrade to today's instant swap, and js/site.js is untouched. */
@media (min-width: 1120px) {
  .nav-drop-menu {
    opacity: 0;
    transform: scale(0.97);
    transform-origin: top left;
    transition: opacity var(--t-drop) var(--ease-out),
                transform var(--t-drop) var(--ease-out),
                display var(--t-drop);
    transition-behavior: allow-discrete;
    /* allow-discrete keeps display:block for the FULL exit duration while the
       opacity runs to 0 — an invisible 300px panel of links would stay
       hit-testable over the page for that whole window. Only the open state
       accepts pointer input. */
    pointer-events: none;
  }
  .nav-drop-menu.is-open {
    opacity: 1;
    transform: none;
    pointer-events: auto;
  }
  @starting-style {
    .nav-drop-menu.is-open {
      opacity: 0;
      transform: scale(0.97);
    }
  }
  /* Reduced motion: keep the fade, drop the scale. */
  @media (prefers-reduced-motion: reduce) {
    .nav-drop-menu,
    .nav-drop-menu.is-open {
      transform: none !important;
    }
  }
}

.site-nav .nav-drop-menu a {
  display: block;
  width: 100%;
  padding: 10px 14px;
  border-radius: var(--radius-btn);
}
.nav-drop-menu a .small {
  display: block;
  color: var(--fg-muted);
  font-weight: 400;
}

/* Mobile toggle */
.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  align-items: center;
  border-radius: var(--radius-btn);
}
.nav-toggle .bar {
  width: 20px; height: 2px;
  background: var(--navy);
  transition: transform var(--t-ui) var(--ease-out), opacity var(--t-ui);
}
/* Press feedback on the two icon-ish nav controls — same treatment as
   .btn:active below, same reduced-motion handling in the reduce block at the
   end of this file. background is re-listed because .nav-drop-toggle inherits
   a background transition from the shared nav rule — a bare shorthand here
   would clobber it (the exact .btn--ghost bug from the guardian round). */
.nav-toggle:active,
.nav-drop-toggle:active {
  transform: scale(0.97);
  transition: transform 100ms var(--ease-out),
              background var(--t-ui) var(--ease-out);
}
.nav-toggle[aria-expanded="true"] .bar:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .bar:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .bar:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* Breakpoint raised 1023 → 1119. The desktop row needs 965px (brand 159 +
   32 gap + nav 774); at 1024px the container leaves 922px, so the links
   squeezed and the wordmark's accent dot ran under the first tab. 1120px is
   the first width where the row fits with room to spare — which also means
   iPad Pro portrait (1024) now gets the touch menu it wanted. */
@media (max-width: 1119px) {
  .nav-toggle { display: flex; }
  .site-nav {
    display: none;
    position: absolute;
    top: var(--nav-h);
    left: 0; right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--paper);
    border-bottom: 1px solid var(--border);
    padding: var(--s-4) var(--gutter) var(--s-6);
    max-height: calc(100dvh - var(--nav-h));
    overflow-y: auto;
  }
  .site-nav.is-open { display: flex; }
  /* Entrance — the panel is spatially anchored under the header, so it slides
     down from it instead of materialising. transform/opacity ONLY: the panel
     carries max-height + overflow-y:auto, and animating height would fight
     that scroll container. Same allow-discrete + @starting-style pattern as
     the desktop dropdown; pointer-events gated for the same reason (the exit
     holds display:flex while opacity runs out — an invisible full-width panel
     of links must not stay hit-testable). Degrades to today's instant swap. */
  .site-nav {
    opacity: 0;
    transform: translateY(-8px);
    transition: opacity 200ms var(--ease-out),
                transform 200ms var(--ease-out),
                display 200ms;
    transition-behavior: allow-discrete;
    pointer-events: none;
  }
  .site-nav.is-open {
    opacity: 1;
    transform: none;
    pointer-events: auto;
  }
  @starting-style {
    .site-nav.is-open {
      opacity: 0;
      transform: translateY(-8px);
    }
  }
  @media (prefers-reduced-motion: reduce) {
    .site-nav,
    .site-nav.is-open {
      transform: none !important;
    }
  }
  .site-nav a:not(.btn), .nav-drop-toggle { width: 100%; padding: 14px 12px; }
  .nav-drop-menu {
    position: static;
    display: none;
    box-shadow: none;
    border: none;
    border-left: 1px solid var(--border);
    border-radius: 0;
    margin-left: var(--s-3);
    background: transparent;
  }
  .nav-drop-menu.is-open { display: block; }
  .site-nav .btn { margin-top: var(--s-4); justify-content: center; }
}

/* ---------- Buttons (brand/components/button-primary.html + button-secondary.html) ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  /* V23 (owner): CTAs bigger site-wide — was 14px 28px / 1rem. */
  padding: 16px 32px;
  border-radius: var(--radius-btn);
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 1.0625rem;
  line-height: 1.2;
  text-decoration: none;
  transition: transform var(--t-ui) ease-out,
              box-shadow var(--t-ui) ease-out,
              background var(--t-ui) ease-out,
              color var(--t-ui) ease-out;
}
.btn .arrow { display: inline-block; transition: transform var(--t-ui) ease-out; }

/* Primary — orange fill, white text, subtle lift, arrow nudge */
.btn--primary {
  background: var(--orange);
  color: var(--white);
  border: none;
  box-shadow: 0 1px 2px rgba(10, 26, 32, 0.08);
}
.btn--primary:hover {
  box-shadow: 0 4px 12px rgba(230, 95, 29, 0.25);
}

/* Hover MOTION (lift + arrow nudge) on fine pointers only — touch fires
   :hover on tap and leaves it stuck, parking the button 2px up until the next
   tap elsewhere. The colour/shadow changes above stay ungated: they are the
   touch affordance and they are not motion. Declared here, ahead of
   `.btn:active` below, so the press state still outranks the lift on click. */
@media (hover: hover) and (pointer: fine) {
  .btn:hover .arrow { transform: translateX(4px); }
  .btn--primary:hover { transform: translateY(-2px); }
}
.btn--primary:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 3px;
}
.on-dark .btn--primary:focus-visible { outline-color: var(--inv-fg); }

/* Secondary — navy outline, fills navy on hover, never orange */
.btn--ghost {
  background: transparent;
  color: var(--navy);
  border: 1.5px solid var(--navy);
  padding: 15px 30px; /* V23 size bump minus ~1px border compensation */
}
.btn--ghost:hover {
  background: var(--navy);
  color: var(--paper);
}
.btn--ghost:focus-visible {
  outline: 2px solid var(--orange);
  outline-offset: 3px;
}
.on-dark .btn--ghost {
  color: var(--inv-fg);
  border-color: var(--inv-fg);
}
.on-dark .btn--ghost:hover {
  background: var(--paper);
  color: var(--navy);
}

.btn--sm {
  padding: 10px 18px;
  font-size: var(--step-small);
  /* The nav CTA is the only btn--sm on the site, and padding alone left it at
     37px -- the one element in .site-nav under the house 44px rule
     (design-system.html: "Cible tactile - 44px nav"), because
     `.site-nav a:not(.btn)` deliberately excludes buttons from the min-height
     that every other nav link gets. .btn is inline-flex with centred items, so
     min-height grows the hit area without touching padding, type or rhythm. */
  min-height: 44px;
}

/* V23 (owner): the hero's single CTA gets a full size up — the page's one
   conversion action, closing the centered copy. Large-text weight/size keeps
   it inside the same brand button spec, just scaled. */
.btn--lg {
  padding: 19px 44px;
  font-size: 1.1875rem;
}

/* Press feedback — instant tactile confirmation on click/tap. Comes after
   both hover variants so it wins the same-specificity tie while pressed.
   The three inherited properties are re-listed deliberately: a bare
   `transition: transform …` here would REPLACE the whole shorthand from `.btn`
   above, so pressing a .btn--ghost mid-hover made its navy fill jump. They keep
   `.btn`'s own bare `ease-out` — promoting them to var(--ease-out) would
   silently change a feel this pass never set out to touch. */
.btn:active {
  transform: scale(0.97);
  transition: transform 100ms var(--ease-out),
              box-shadow var(--t-ui) ease-out,
              background var(--t-ui) ease-out,
              color var(--t-ui) ease-out;
}

/* Nav CTA — pushed right, clearly separated from the tabs (desktop only) */
@media (min-width: 1120px) {
  .site-nav .btn { margin-left: var(--s-6); }
}

/* Text link with drawn underline */
.link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 600;
  color: var(--navy);
  text-decoration: none;
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 0% 1px;
  background-repeat: no-repeat;
  background-position: 0 calc(100% - 10px);
  transition: background-size var(--t-ui) var(--ease-out);
  /* 28px tall as a bare text box — too small to tap reliably. The padding
     lifts the hit area to ~44px; the underline is pulled back up by the same
     amount so it still sits 2px under the text, visually unchanged. */
  padding-block: 8px 12px;
}
.link:hover { background-size: 100% 1px; }
.link .arrow { transition: transform var(--t-ui) var(--ease-out); }
/* Arrow nudge is motion — fine pointers only (see .btn note above). The
   drawn underline stays ungated as the touch affordance. */
@media (hover: hover) and (pointer: fine) {
  .link:hover .arrow { transform: translateX(4px); }
}
.on-dark .link { color: var(--teal-bright); }

/* ---------- Cards (brand/components/card-default.html — lift + shadow on hover) ---------- */
.card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  padding: var(--s-6);
  transition: transform var(--t-ui) var(--ease-out), box-shadow var(--t-ui) var(--ease-out);
}
.card:hover,
/* every card also carries .reveal for scroll-in; its settled state
   (html.js .reveal.is-visible { transform: none }) outspecifies a plain
   .card:hover, so this combo needs to be named explicitly to win */
.card.reveal.is-visible:hover {
  box-shadow: var(--shadow-card-hover);
}
/* The lift is motion — fine pointers only, so a tap does not park the card
   2px up on touch. Shadow above stays ungated as the touch affordance.
   MIRRORED in css/motion.css §6 for the stagger system — change both. */
@media (hover: hover) and (pointer: fine) {
  .card:hover,
  .card.reveal.is-visible:hover {
    transform: translateY(-2px);
  }
}
.card h3, .card h4 { margin-bottom: var(--s-3); }
.card p + p { margin-top: var(--s-3); }
/* White-on-white: a .card nested inside .on-dark would inherit inv-fg
   (white) from `.on-dark p`, leaving paragraphs invisible on the
   card's white background. Force the dark foreground back inside cards. */
.on-dark .card { color: var(--fg); }
.on-dark .card p,
.on-dark .card .muted { color: var(--fg); }
.on-dark .card .muted { color: var(--fg-muted); }

/* Tinted card — paper base washed with the secondary (teal) at low alpha.
   Used on navy bands where a plain white card would punch a hole, and on
   light bands where a quiet accent is preferred over white. */
.card--accent {
  background: color-mix(in srgb, var(--teal) 14%, var(--paper));
  border-color: color-mix(in srgb, var(--teal) 34%, transparent);
}
.card--accent .mono { color: var(--navy); }
.card--accent p,
.card--accent .muted { color: var(--fg); }

.card-kpi {
  margin-top: var(--s-5);
  padding-top: var(--s-4);
  border-top: 1px solid var(--border);
}
.card-kpi .mono { color: var(--teal); display: block; margin-bottom: var(--s-2); }
.card-kpi p { font-size: var(--step-small); color: var(--fg-muted); }

/* Numbered editorial item (01 / 02 / 03) */
.num-item { position: relative; padding-top: var(--s-4); }
.num-item::before {
  content: "";
  position: absolute;
  top: 0; left: 0;
  width: 100%;
  height: 1px;
  background: var(--border);
}
.num-item .num {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 22px;
  letter-spacing: 0.08em;
  color: var(--orange);
  display: block;
  margin-bottom: var(--s-4);
}
.num-item h3, .num-item h4 { margin-bottom: var(--s-3); }

/* Editorial list with hairlines */
.rule-list { border-top: 1px solid var(--border); }
.rule-list > li {
  display: flex;
  align-items: center;
  gap: var(--s-5);
  padding-block: var(--s-4);
  border-bottom: 1px solid var(--border);
  font-size: var(--step-lead);
  line-height: 1.5;
}
.rule-list .idx {
  flex: 0 0 48px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.5rem;
  line-height: 1.5;
  color: var(--orange);
  letter-spacing: 0.08em;
}
.on-dark .rule-list { border-color: var(--inv-border); }
.on-dark .rule-list > li { border-color: var(--inv-border); }
.on-dark .rule-list .idx { color: var(--orange); }

/* Check list (deliverables) */
.check-list li {
  position: relative;
  padding-left: 26px;
  margin-bottom: var(--s-2);
}
.check-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 12px;
  height: 6px;
  border-left: 2px solid var(--orange);
  border-bottom: 2px solid var(--orange);
  transform: rotate(-45deg) translateY(-2px);
}
.on-dark .check-list li::before { border-color: var(--orange); }
/* Deliverable/impact lists are read as content, not metadata — keep them body-sized */
.check-list.small { font-size: var(--step-body); }

/* Sequence chips: S → A → C */
.seq {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  flex-wrap: wrap;
}
.seq .chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px; height: 36px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-btn);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.9375rem;
  color: var(--navy);
  background: var(--white);
}
.seq .sep {
  color: var(--teal);
  font-family: var(--font-mono);
  font-size: var(--step-small);
}

/* ---------- Foundation bar (Defend) ---------- */
.foundation-bar {
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-btn);
  background: var(--paper-2);
  padding: var(--s-3) var(--s-5);
  display: flex;
  align-items: center;
  gap: var(--s-4);
}
.foundation-bar .mono { color: var(--navy); }
.foundation-bar .tick {
  flex: 1;
  height: 1px;
  background: var(--border-strong);
  min-width: 24px;
}
.on-dark .foundation-bar {
  background: var(--navy-dark);
  border-color: var(--inv-border);
}
.on-dark .foundation-bar .mono { color: var(--teal-bright); }
.on-dark .foundation-bar .tick { background: var(--inv-border); }

/* ---------- FAQ (native details) ---------- */
.faq { border-top: 1px solid var(--border); max-width: 780px; }
.faq details { border-bottom: 1px solid var(--border); }
.faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  padding: var(--s-5) var(--s-2);
  cursor: pointer;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step-h4);
  color: var(--navy);
  list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+";
  font-family: var(--font-mono);
  font-size: 1.25rem;
  color: var(--teal);
  flex-shrink: 0;
  transition: transform var(--t-ui) var(--ease-out);
}
.faq details[open] summary::after { transform: rotate(45deg); }
.faq .faq-body { padding: 0 var(--s-2) var(--s-5); }
.faq .faq-body p + p { margin-top: var(--s-3); }

/* ---------- Forms ---------- */
/* The transition here is the exit half of the confirmation moment. js/site.js
   sets `hidden` on the form the same frame it reveals .form-success, and a tall
   form leaving the flow instantly is the harsher half of that swap — the
   arrival was never the problem. allow-discrete holds the form displayed while
   its opacity runs out, so the two halves cross over instead of one snapping.
   Symmetric with .form-success, and NO js change: this keys off the `hidden`
   attribute js/site.js already sets. Browsers without allow-discrete keep
   today's instant hide. */
.form-grid {
  display: grid;
  gap: var(--s-5);
  max-width: 720px;
  opacity: 1;
  transition: opacity var(--t-reveal) var(--ease-out),
              display var(--t-reveal);
  transition-behavior: allow-discrete;
}
.form-grid[hidden] {
  display: none;
  opacity: 0;
}
.field { display: flex; flex-direction: column; gap: var(--s-2); }
.field label {
  font-weight: 600;
  font-size: var(--step-small);
  color: var(--navy);
}
.field .hint { font-size: var(--step-small); color: var(--fg-muted); }
.field input,
.field select,
.field textarea {
  padding: 12px 14px;
  min-height: 48px;
  font-size: 1rem;
  background: var(--white);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-btn);
  transition: border-color var(--t-ui) var(--ease-out);
  width: 100%;
}
.field textarea { min-height: 120px; resize: vertical; }
.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: 2px solid var(--navy);
  outline-offset: 1px;
  border-color: var(--navy);
}
.field.is-invalid input,
.field.is-invalid select,
.field.is-invalid textarea { border-color: var(--orange); }
.field .error {
  display: none;
  font-size: var(--step-small);
  font-weight: 600;
  color: color-mix(in srgb, var(--orange) 80%, var(--navy-deep));
  /* Entrance — resolves an internal contradiction: the field's border already
     eases to orange over --t-ui on the SAME .is-invalid toggle, while this
     message snapped in. A transition (not keyframes) because js/site.js
     re-validates on every input event, so this can toggle repeatedly while
     typing and must retarget mid-flight. No aria-live on this <p> (aria-invalid
     sits on the input), so the 150ms fade delays nothing for AT. */
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity var(--t-drop) var(--ease-out),
              transform var(--t-drop) var(--ease-out),
              display var(--t-drop);
  transition-behavior: allow-discrete;
}
.field.is-invalid .error {
  display: block;
  opacity: 1;
  transform: none;
}
@starting-style {
  .field.is-invalid .error {
    opacity: 0;
    transform: translateY(-4px);
  }
}
.form-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
  gap: var(--s-5);
}
.form-success {
  display: none;
  background: var(--white);
  border: 1px solid var(--teal);
  border-radius: var(--radius-card);
  padding: var(--s-6);
  /* Entrance. This is the highest-emotion moment in the whole site — a prospect
     has just asked for a meeting — and it used to hard-cut in on a bare
     display:none→block swap, with the form vanishing underneath it in the same
     frame. Fade + rise instead, so the confirmation reads as arriving.
     `allow-discrete` lets the display flip participate in the transition and
     @starting-style supplies the from-state; both are progressive enhancements,
     so a browser without them keeps exactly today's instant swap. No JS change:
     js/site.js still just adds .is-visible. */
  opacity: 0;
  transform: translateY(12px);
  /* `display` sits in the shorthand (valid everywhere, inert on its own) while
     allow-discrete stays a separate longhand — so a browser that lacks it drops
     only that one line instead of invalidating the whole shorthand. */
  transition: opacity var(--t-reveal) var(--ease-out),
              transform var(--t-reveal) var(--ease-out),
              display var(--t-reveal);
  transition-behavior: allow-discrete;
}
.form-success.is-visible {
  display: block;
  opacity: 1;
  transform: none;
}
@starting-style {
  .form-success.is-visible {
    opacity: 0;
    transform: translateY(12px);
  }
}
/* Reduced motion: keep the fade (it aids comprehension — something new has
   arrived) and drop the travel. base.css also zeroes the duration globally. */
@media (prefers-reduced-motion: reduce) {
  .form-success,
  .form-success.is-visible {
    transform: none !important;
  }
}
.form-success h3 { color: var(--navy); margin-bottom: var(--s-3); }

/* ---------- Footer — primary navy, continuous with the final CTA band. Never black. ---------- */
.site-footer {
  background: var(--navy);
  color: var(--inv-fg);
  border-top: 1px solid var(--inv-border);
}
.site-footer .foundation-bar {
  background: var(--navy-dark);
  border-color: var(--inv-border);
  margin-bottom: var(--s-8);
}
.site-footer .foundation-bar .mono { color: var(--teal-bright); }
.site-footer .foundation-bar .tick { background: var(--inv-border); }
.footer-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
  gap: var(--s-7);
  padding-bottom: var(--s-8);
}
.footer-brand p {
  color: var(--inv-fg-muted);
  font-size: var(--step-small);
  margin-top: var(--s-4);
  max-width: 34ch;
}
.footer-brand .brand-word { color: var(--paper); }
.site-footer .footer-col .mono {
  color: var(--orange);
  display: block;
  margin-bottom: var(--s-4);
}
.footer-col ul { list-style: none; padding: 0; margin: 0; }
.footer-col ul li { margin-bottom: var(--s-2); }
.footer-col a {
  /* The link box was the text box: 20px tall, under the 24×24 minimum for a
     touch target (WCAG 2.5.8). Padding grows the hit area to 34px without
     changing the visual rhythm — the extra height is absorbed by the smaller
     li margin above. */
  display: inline-block;
  padding-block: 7px;
  color: var(--inv-fg-muted);
  text-decoration: none;
  font-size: var(--step-small);
  transition: color var(--t-ui) var(--ease-out);
}
.footer-col a:hover { color: var(--paper); }
.footer-bottom {
  border-top: 1px solid var(--inv-border);
  padding-block: var(--s-5);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4);
  justify-content: space-between;
  align-items: center;
}
.footer-bottom p {
  font-size: var(--step-small);
  color: var(--inv-fg-muted);
}

@media (max-width: 640px) {
  .footer-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: var(--s-5) var(--s-4);
    padding-bottom: var(--s-5);
  }
  .footer-brand { grid-column: 1 / -1; }
  .footer-brand p { max-width: none; }
  .site-footer .section { padding-block: var(--s-6); }
  .footer-col .mono { margin-bottom: var(--s-3); }
  .footer-col ul li { margin-bottom: 0; }
}

/* ---------- CTA band ---------- */
.cta-band { text-align: left; }
.cta-band .cta-inner {
  display: grid;
  gap: var(--s-7);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr));
  align-items: center;
}
.cta-band .btn-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-4);
  margin-top: var(--s-6);
}
.cta-band .mention {
  font-size: var(--step-small);
  color: var(--inv-fg-muted);
  margin-top: var(--s-3);
}

/* ---------- CTA band, hero variant (V24) ----------
   The home's closing ask, rebuilt as a hero: one centred title at display
   scale over one large button. The default band is a two-column grid (copy +
   agenda details); with the details column gone, auto-fit would stretch the
   lone column across the full container and the title would run to ~90ch, so
   the column is capped and centred here instead. */
.cta-band--hero { text-align: center; }
.cta-band--hero .cta-inner {
  grid-template-columns: minmax(0, 1fr);
  justify-items: center;
}
.cta-band--hero h2 {
  font-size: var(--step-display);
  line-height: 1.12;
  /* 22ch lands this 95-character title on 3 lines at full display scale
     (20ch broke it to 4). Font-relative, so the line count holds as the
     clamp scales the type down on narrower windows. */
  max-width: 22ch;
  margin-inline: auto;
  text-wrap: balance;
}
.cta-band--hero .btn-row {
  justify-content: center;
  margin-top: var(--s-7);
}
@media (max-width: 640px) {
  .cta-band--hero .section { padding-block: var(--s-8); }
  .cta-band--hero h2 { font-size: clamp(1.5rem, 6vw, 2rem); }
}

/* ---------- Home: centered editorial blocks ----------
   The blocks sit on the page centreline; their contents keep the original
   left alignment for scanning. Navigation and footer lists are excluded. */
.home main .rule-list {
  margin-inline: auto;
}
.home main .editorial-list-block {
  width: 100%;
  max-width: 780px;
  margin-inline: auto;
}
/* V24: .autonomy-list and .cta-details rules removed with their markup — the
   autonomy navy band and the CTA agenda column were both cut from the home. */
.home main .faq {
  margin-inline: auto;
}
.home main .section-action--center {
  display: flex;
  justify-content: center;
}

/* ---------- Reduced motion: drop EVERY hover/press position change ----------
   base.css zeroes transition-duration globally, but a zero-duration transform
   still APPLIES — the lift/nudge just jumps instantly instead of easing. Per
   the pattern already established in css/results-tiles.css (§reduced motion),
   remove the movement and keep the colour/shadow as the motion-free affordance.

   `.btn:active`'s scale goes too, per [[amalab-design-motion]] §"Reduced motion
   behavior", which is unqualified: "No transforms." Worth recording WHY the
   "it's only 3% direct-manipulation feedback" exemption was wrong on craft
   grounds as well as brand grounds — with the duration zeroed there is no 100ms
   compression left to feel, only an instant 3% snap down and an instant snap
   back on release. That reads as a twitch, not a press: worse than either
   keeping the easing or having no press state at all.
   The feedback itself is preserved, without motion: an inset shadow presses the
   surface instead of moving it, using the navy ink already in the file. */
@media (prefers-reduced-motion: reduce) {
  .btn--primary:hover,
  .card:hover,
  .card.reveal.is-visible:hover,
  .btn:active,
  .nav-toggle:active,
  .nav-drop-toggle:active {
    transform: none !important;
  }
  .btn:hover .arrow,
  .link:hover .arrow {
    transform: none !important;
  }
  .btn--primary:active {
    box-shadow: inset 0 1px 3px rgba(10, 26, 32, 0.28);
  }
  /* Error message: keep the fade (something new arrived), drop the travel. */
  .field .error,
  .field.is-invalid .error {
    transform: none !important;
  }
}

/* ---------- Cookie consent — Google Analytics stays blocked until accepted ---------- */
.cookie-consent {
  position: fixed;
  z-index: 200;
  right: var(--s-5);
  bottom: var(--s-5);
  width: min(440px, calc(100% - (var(--s-5) * 2)));
  padding: var(--s-5);
  background: var(--paper);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
}
.cookie-consent[hidden] { display: none; }
.cookie-consent h2 {
  margin-bottom: var(--s-2);
  font-size: var(--step-h4);
}
.cookie-consent p {
  color: var(--fg-muted);
  font-size: var(--step-small);
}
.cookie-consent__actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-3);
  margin-top: var(--s-5);
}
.cookie-consent__choice {
  min-height: 44px;
  padding: var(--s-3) var(--s-4);
  background: var(--white);
  border: 1.5px solid var(--navy);
  border-radius: var(--radius-btn);
  color: var(--navy);
  font-family: var(--font-body);
  font-size: var(--step-body);
  font-weight: 600;
}
.cookie-consent__choice:hover { background: var(--paper-2); }
.cookie-consent__choice:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 3px;
}
.cookie-consent__settings {
  min-height: 44px;
  padding: var(--s-2) 0;
  color: var(--inv-fg-muted);
  font-size: var(--step-small);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
.cookie-consent__settings:hover { color: var(--paper); }
.cookie-consent__settings:focus-visible {
  outline: 2px solid var(--paper);
  outline-offset: 3px;
}
@media (max-width: 640px) {
  .cookie-consent {
    position: static;
    width: auto;
    margin: var(--s-4);
  }
}
