/* ==========================================================================
   components.css — shared, reusable pieces. Used on every page.
   Page-specific layout lives in pages.css.
   ========================================================================== */

/* --------------------------------------------------------------------------
   ICONS
   -------------------------------------------------------------------------- */
.icon {
  width: 24px; height: 24px;
  flex: none;
  color: var(--purple);
}
.icon--lg { width: 32px; height: 32px; }
.icon--sm { width: 20px; height: 20px; }

/* --------------------------------------------------------------------------
   BUTTONS
   .btn--primary is PURPLE, not orange. The old mockup's orange primary is
   retired: review slide 1 asked for more purple, and orange is an accent.
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--s-2);
  padding: 13px var(--s-6);
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-size: var(--small); font-weight: 600;
  letter-spacing: .01em;
  text-decoration: none;
  border: 2px solid transparent;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease),
              background-color var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease);
}
.btn--primary {
  background: var(--purple); color: var(--white);
}
.btn--primary:hover {
  background: var(--purple-deep); color: var(--white);
  transform: translateY(-2px);
}
.btn--ghost {
  border-color: var(--purple); color: var(--purple); background: transparent;
}
.btn--ghost:hover {
  background: var(--purple); color: var(--white); transform: translateY(-2px);
}
/* On dark grounds the ghost inverts to white. */
.band--ink .btn--ghost, .cta-purple .btn--ghost, .footer .btn--ghost {
  border-color: rgba(255,255,255,.7); color: var(--white);
}
.band--ink .btn--ghost:hover, .cta-purple .btn--ghost:hover {
  background: var(--white); color: var(--purple-deep); border-color: var(--white);
}
/* White pill on a purple card — review slide 7's "purple box". */
.btn--onpurple { background: var(--white); color: var(--purple-deep); }
.btn--onpurple:hover {
  background: var(--purple-tint); color: var(--purple-deep);
  transform: translateY(-2px);
}

.btn-row { display: flex; flex-wrap: wrap; gap: var(--s-3); align-items: center; }

/* --------------------------------------------------------------------------
   NAV
   -------------------------------------------------------------------------- */
.nav {
  position: sticky; top: 0; z-index: 100;
  background: rgba(253, 252, 250, .86);
  border-bottom: 1px solid var(--purple-line);
}
@supports (backdrop-filter: blur(12px)) {
  .nav { backdrop-filter: blur(12px); }
}
.nav__inner {
  display: flex; align-items: center; gap: var(--s-6);
  min-height: 86px;
}
.nav__brand { display: flex; align-items: center; flex: none; }
/* 62px desktop / 48px mobile. Grown from 48/40 on the mockup-changes deck
   ("Logo más grande"), which is the second time the logo has been called too
   small — the original review said the same of the old 44px JPG. At 62px the
   lockup is 173px wide, comfortably over the brand guide's 120px minimum. */
.nav__brand img { height: 62px; width: auto; }

.nav__links {
  display: flex; align-items: center; gap: var(--s-6);
  margin-left: auto;
}
.nav__links a {
  position: relative;
  font-size: var(--small); font-weight: 500;
  color: var(--ink-soft); text-decoration: none;
  padding-block: var(--s-2);
  transition: color var(--dur-fast) var(--ease);
}
.nav__links a:hover { color: var(--purple); }

/* Active page: purple text + a 3px purple→orange gradient underline.
   Driven by <body data-page="…">, so it needs no JS. */
body[data-page="home"]         .nav__links a[data-nav="home"],
body[data-page="approach"]     .nav__links a[data-nav="approach"],
body[data-page="services"]     .nav__links a[data-nav="services"],
body[data-page="case-studies"] .nav__links a[data-nav="case-studies"],
body[data-page="about"]        .nav__links a[data-nav="about"] {
  color: var(--purple); font-weight: 600;
}
body[data-page="home"]         .nav__links a[data-nav="home"]::after,
body[data-page="approach"]     .nav__links a[data-nav="approach"]::after,
body[data-page="services"]     .nav__links a[data-nav="services"]::after,
body[data-page="case-studies"] .nav__links a[data-nav="case-studies"]::after,
body[data-page="about"]        .nav__links a[data-nav="about"]::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -2px;
  height: 3px; border-radius: 2px;
  /* Flat colour only — the gradient underline became a solid orange rule,
     which is closer to the brand's single hand-drawn line anyway. */
  background: var(--nu-orange);
}
/* Same treatment in the overlay menu. */
body[data-page="home"]         .mobilemenu a[data-nav="home"],
body[data-page="approach"]     .mobilemenu a[data-nav="approach"],
body[data-page="services"]     .mobilemenu a[data-nav="services"],
body[data-page="case-studies"] .mobilemenu a[data-nav="case-studies"],
body[data-page="about"]        .mobilemenu a[data-nav="about"] { color: var(--purple); }

.nav__cta { flex: none; }

.nav__burger {
  display: none;
  width: 44px; height: 44px;
  flex: none;
  margin-left: auto;
  background: none; border: 0; padding: 10px;
  cursor: pointer;
}
.nav__burger span {
  display: block; height: 2px; border-radius: 2px;
  background: var(--purple);
  transition: transform var(--dur-fast) var(--ease),
              opacity var(--dur-fast) var(--ease);
}
.nav__burger span + span { margin-top: 5px; }

@media (max-width: 900px) {
  .nav__links, .nav__cta { display: none; }
  .nav__burger { display: block; }
  .nav__brand img { height: 48px; }
  .nav__inner { min-height: 72px; gap: var(--s-4); }
}

/* --- Mobile overlay menu --- */
.mobilemenu {
  position: fixed; inset: 0; z-index: 200;
  background: var(--paper);
  display: flex; flex-direction: column;
  overflow-y: auto;
}
.mobilemenu[hidden] { display: none; }
.mobilemenu__head {
  display: flex; align-items: center; justify-content: space-between;
  min-height: 72px;
  border-bottom: 1px solid var(--purple-line);
}
.mobilemenu__head img { height: 48px; width: auto; }
.mobilemenu__close {
  width: 44px; height: 44px;
  background: none; border: 0; color: var(--purple); cursor: pointer;
  display: grid; place-items: center;
}
.mobilemenu__links {
  display: flex; flex-direction: column; gap: var(--s-2);
  padding-block: var(--s-6);
}
.mobilemenu__links a {
  font-family: var(--font-display); font-size: 24px; font-weight: 700;
  color: var(--ink); text-decoration: none;
  padding-block: var(--s-3);
}
.mobilemenu__links a.btn {
  font-family: var(--font-body); font-size: var(--small);
  color: var(--white); margin-top: var(--s-4); align-self: flex-start;
}

/* --------------------------------------------------------------------------
   TAGLINE BAND — full-width purple-ink, arrow in orange.
   -------------------------------------------------------------------------- */
.tagline-band {
  background: var(--purple-ink);
  padding-block: var(--s-6);
  text-align: center;
}
.tagline-band p {
  margin: 0;
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(14px, 1.5vw, 18px);
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--white);
  line-height: 1.5;
}
.tagline-band .arrow { color: var(--orange); padding-inline: .3em; }

/* --------------------------------------------------------------------------
   "THE DIFFERENCE" CALLOUT — white card, 6px orange left rule.
   -------------------------------------------------------------------------- */
.difference {
  background: var(--white);
  border-left: 6px solid var(--orange);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  padding: var(--s-5) var(--s-6);
  /* Full content width, like the quote blocks. It was the last element still
     stopping short of the right margin. */
  max-width: none;
}
.difference__label {
  font-size: var(--micro); font-weight: 600;
  letter-spacing: var(--ls-micro); text-transform: uppercase;
  color: var(--purple);
  margin: 0 0 var(--s-2);
}
.difference__text {
  font-family: var(--font-display); font-size: var(--h3); font-weight: 700;
  line-height: 1.35; color: var(--ink);
  margin: 0;
}

/* --------------------------------------------------------------------------
   TESTIMONIAL / QUOTE
   Every quote carries the "Why our clients recommend us" lead-in — asked for
   on slides 3, 4, 5, 6, 9, 12 and 16, and confirmed by MV on slide 9.
   .measure on the paragraph above + .quote here share --maxw-read, which is
   the alignment those slides kept asking for.
   -------------------------------------------------------------------------- */
.quote {
  margin: var(--s-5) 0 0;
  /* The box spans the full content width: narrowed to the text it stopped
     short of the right margin and read as misaligned against the cards above
     it. But the line inside stays at a readable measure, which left a wide
     empty band down the right of the panel — Jaime, 15 Oct 2026: "no puede
     quedar centrado el texto? para que no se vea el gap a la derecha."
     So the whole block is centred. The panel keeps its full width and the
     leftover space falls evenly either side instead of all on one edge. */
  max-width: none;
  text-align: center;
}
.quote__eyebrow {
  font-size: var(--micro); font-weight: 600;
  letter-spacing: var(--ls-micro); text-transform: uppercase;
  color: var(--purple);
  margin: 0 0 var(--s-3);
}
.quote__body {
  position: relative;
  background: var(--purple-tint);
  border-radius: var(--radius-sm);
  /* Even padding. The glyph used to sit in the left margin, which cost an
     extra 40px of left padding and started the quotation 64px in from the
     eyebrow and the attribution chip — the same kind of line that does not
     line up with what is above it that Marta flagged on Approach. The glyph
     sits above the text now and the inset is an ordinary panel inset. */
  padding: var(--s-5);
  margin: 0;
}
.quote__body::before {
  content: "";
  display: block;
  width: 26px; height: 26px;
  margin: 0 auto var(--s-3);
  background: var(--purple);
  opacity: .22;
  /* Decorative quote glyph, masked so it takes the brand purple. */
  -webkit-mask: url("../img/quote-glyph.svg") no-repeat center / contain;
  mask: url("../img/quote-glyph.svg") no-repeat center / contain;
}
.quote__body p {
  /* The box is full width; the line is not. ~70 characters stays comfortable,
     and centring the block is what keeps the spare width off the right edge. */
  margin: 0 auto;
  font-size: var(--lede); line-height: 1.55; color: var(--ink);
  max-width: 70ch;
}
.quote figcaption { margin-top: var(--s-4); }
.quote__attrib {
  display: inline-block;
  background: var(--white);
  /* The hairline matters. A white pill on a tinted band reads as a pill; on
     a white band it disappears, and all a reader sees is the attribution
     text floating 16px in from the eyebrow above it — a third left edge, and
     the reason the block still looked misaligned after the quotation was
     fixed. The border makes the pill a pill on every background. */
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  padding: 7px var(--s-4);
  font-size: var(--micro); font-weight: 600;
  letter-spacing: var(--ls-micro); text-transform: uppercase;
  color: var(--purple-deep);
}
/* On the dark band the white fill carries it; the light hairline would not. */
.band--ink .quote__attrib { border-color: transparent; }
.band--ink .quote__body { background: rgba(255,255,255,.07); }
.band--ink .quote__body p { color: var(--white); }
.band--ink .quote__eyebrow { color: var(--orange); }

/* --------------------------------------------------------------------------
   CARDS
   -------------------------------------------------------------------------- */
.card {
  background: var(--white);
  border: 1px solid var(--purple-line);
  border-radius: var(--radius);
  padding: var(--s-5);
  transition: transform var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease);
}
.card:hover { transform: translateY(-3px); border-color: var(--nu-purple); }
.card__icon {
  width: 46px; height: 46px;
  display: grid; place-items: center;
  background: var(--purple-tint);
  border-radius: var(--radius-sm);
  margin-bottom: var(--s-3);
}
.card__icon .icon { width: 26px; height: 26px; }
.card h3 { margin-bottom: var(--s-2); }
.card p { color: var(--ink-soft); margin: 0; }

/* Horizontal card: icon beside the text rather than above it. Used where a
   card sits in a narrow column next to a photo — stacking three vertical
   cards there made the column 675px against a 444px image.

   REQUIRES exactly two children: .card__icon and .card__body. With the text
   nodes left as flat siblings, grid auto-placement dropped the <h3> into the
   46px icon column, where it wrapped one word per line and collided with the
   paragraph beside it. The wrapper is not decorative — it is the contract. */
.card--row {
  display: grid;
  grid-template-columns: 46px 1fr;
  gap: var(--s-4);
  align-items: start;
}
.card--row > .card__body { min-width: 0; }
.card--row .card__icon { margin-bottom: 0; }
.card--row h3 { font-size: 17px; }
.card--row p { font-size: var(--small); }

/* Question-framed eyebrow — review slide 3: "build on typical business/client
   questions, it makes it more appealing". Invented copy; see INVENTED_COPY.md */
.card__question {
  font-size: var(--micro); font-weight: 600;
  letter-spacing: .04em;
  color: var(--orange-deep);
  font-style: italic;
  margin: 0 0 var(--s-2);
}

/* --------------------------------------------------------------------------
   CHIPS — frameworks, focus areas, method groups, case-study method tags.
   -------------------------------------------------------------------------- */
.chips { display: flex; flex-wrap: wrap; gap: var(--s-2); padding: 0; margin: 0; list-style: none; }
.chip {
  display: inline-flex; align-items: center; gap: var(--s-2);
  border: 1.5px solid var(--purple-line);
  border-radius: var(--radius-pill);
  padding: 8px var(--s-4);
  font-size: var(--small); color: var(--purple-deep);
  background: var(--white);
  margin: 0;
}
.chip .icon { width: 17px; height: 17px; }

/* --------------------------------------------------------------------------
   PROOF BAR — numbers count up once, on first scroll into view.
   -------------------------------------------------------------------------- */
.proof {
  display: flex; flex-wrap: wrap; gap: var(--s-7);
  justify-content: center; align-items: baseline;
  text-align: center;
}
.proof__item { min-width: 150px; }
.proof__num {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(30px, 3.4vw, 42px);
  color: var(--purple);
  line-height: 1.1;
  display: block;
}
.proof__label {
  font-size: var(--small); color: var(--ink-soft); display: block;
  margin-top: var(--s-1);
}

/* --------------------------------------------------------------------------
   AS SEEN AT — desaturated to ~40%, full colour on hover.
   Industry/publication badges ONLY. No client or brand logos (slide 11).
   -------------------------------------------------------------------------- */
/* AS SEEN AT.
   Each badge sits on its own white card. The artwork arrives at five
   different sizes on three different backgrounds (white, near-black, deep
   purple), so a card is what makes them read as one set rather than five
   loose cut-outs. The first version laid them bare on the tinted band under
   `saturate(.4) opacity(.72)` — deliberately quiet, and exactly the "not
   eye-catching" Marta reported on 14 Oct 2026. Full colour now, bigger, on
   cards, and the three with an article behind them are links. */
/* Each strip gets a heading and a one-line subhead, 15 Oct 2026. */
.strip-head { text-align: center; margin-top: var(--s-7); }
.strip-head p {
  margin: var(--s-2) 0 0;
  font-size: var(--small); color: var(--ink-muted);
}

.badges {
  list-style: none; margin: var(--s-5) 0 0; padding: 0;
  /* A grid, not a wrapping flex row: the five badges differ by more than 2:1
     in width, so left to size themselves they overflow one row and break 3+2
     at ordinary laptop widths. Equal columns keep them a wall. */
  display: grid; grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: var(--s-4);
}
/* Three badges rather than five since 15 Oct 2026. Capped and centred so a
   three-up row does not stretch each card to a third of 1100px. */
.badges--3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  max-width: 760px; margin-inline: auto;
}
.badge { display: flex; }
.badge__card {
  flex: 1;
  display: flex; flex-direction: column;
  align-items: center; justify-content: space-between; gap: var(--s-3);
  padding: var(--s-4) var(--s-4) var(--s-3);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: transform var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease);
}
/* width:100% matters: the card centres its children on the cross axis, so
   without it this box takes its content width and the image's own width:100%
   resolves against itself — leaving a badge narrower than the card at its
   intrinsic size instead of filling it. */
/* The art box carries the aspect of the TALLEST lockup — Greenbook at
   287:120 — so every card reserves the same shape and the three come out
   identical. A ratio rather than a pixel height, so it scales with the card
   from three columns down to one. Same trick as the footer chips; this is
   the responsive version of it. */
.badge__art {
  width: 100%; aspect-ratio: 287 / 120;
  display: grid; place-items: center;
}
/* Normalised on WIDTH, not height. Matching heights looked right in theory
   and wrong on screen: the Greenbook lockup is three stacked lines plus a
   shield where the other two are a wide two-line wordmark, so at an equal
   52px its lettering came out at half the size of theirs. The cards are all
   the same width, so filling that width is what actually makes the three
   read as one set — it brings the lettering within about 20% of each other.
   The cards stretch to a common height regardless. */
/* The <picture> has to fill the box as well. Left to itself it shrinks to
   the image's intrinsic width, and then the image's own width:100% resolves
   against that — which is why the narrowest badge kept rendering at its
   natural size while the two wider ones filled the card. */
.badges picture { display: block; width: 100%; height: 100%; }
/* contain, not cover: each badge fills the box's WIDTH and keeps its own
   height, so the lettering stays matched across the row while the shorter
   two simply carry more white above and below. */
.badges img {
  width: 100%; height: 100%;
  object-fit: contain; display: block;
}
/* Two columns all the way down. One column was legible but turned the strip
   into 870px of scrolling on a phone for five badges. */
@media (max-width: 900px) {
  .badges, .badges--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-3); }
  .badge__card { padding: var(--s-3); }
}
/* Three cards in a two-column grid leave one alone on the second row; one
   column keeps the strip even at phone width. */
@media (max-width: 560px) { .badges--3 { grid-template-columns: 1fr; } }
.badge__label {
  font-size: var(--micro); font-weight: 700; letter-spacing: .02em;
  color: var(--ink-muted); text-align: center; line-height: 1.35;
  /* Room for two lines whether or not the label needs them. "Quirk's
     Marketing Research Media" wraps and the other two do not, which left the
     cards a line apart wherever the grid is one column and cannot stretch
     them to match. */
  min-height: 2.7em;
  display: flex; align-items: center; justify-content: center;
}
a.badge__card:hover, a.badge__card:focus-visible {
  transform: translateY(-3px);
  border-color: var(--purple);
}
a.badge__card:hover .badge__label,
a.badge__card:focus-visible .badge__label { color: var(--purple-ink); }

/* RECENT STAGES — the five event cards from Imagenes Adicionales.docx.
   Promo artwork, not logos: five different aspect ratios normalised to one
   height by tools/build_events.py, laid out like a rail of press clippings.
   It scrolls horizontally rather than wrapping, so the row keeps its shape
   on a phone. */
.stages {
  list-style: none; margin: var(--s-5) 0 0; padding: 0 0 var(--s-3);
  /* Six cards since 15 Oct 2026. One row no longer fits a laptop, and
     shrinking them enough to fit made the type on the cards unreadable. So
     three columns and two rows on desktop, sized to their content and
     centred: left to wrap, flexbox filled greedily and broke 4 + 2. The
     order in the markup pairs the two widest cards into one column so the
     columns come out even. The snap rail stays for phones. */
  display: grid; grid-template-columns: repeat(3, auto);
  justify-content: center; justify-items: center; align-items: center;
  gap: var(--s-4);
  -webkit-overflow-scrolling: touch;
  /* One row at every width: centred while the five fit, scrolled when they
     do not. `safe` is what stops a plain `center` from cutting the first card
     off the left edge once the row overflows; browsers that do not know the
     keyword drop the declaration and start the row at the left, which is the
     behaviour we would have asked for anyway. */
  justify-content: safe center;
}
.stages li { display: flex; flex: 0 0 auto; scroll-snap-align: start; }
/* Height tracks the viewport so the five cards stay on one row without a
   scrollbar on a laptop, and fall back to scrolling on a phone. */
.stages img {
  height: clamp(112px, 10.5vw, 150px); width: auto; display: block;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
}


/* --------------------------------------------------------------------------
   HANDOFF LINE — the italic bridge sentence closing each page.
   -------------------------------------------------------------------------- */
.handoff {
  text-align: center;
  font-style: italic;
  color: var(--gray);
  font-size: var(--lede);
  max-width: 640px;
  margin-inline: auto;
}
.handoff a {
  color: var(--purple);
  text-decoration: none;
  border-bottom: 2px solid var(--orange);
  padding-bottom: 1px;
  font-style: normal; font-weight: 500;
}
.handoff a:hover { border-bottom-color: var(--purple); }

/* --------------------------------------------------------------------------
   CTA BLOCKS
   -------------------------------------------------------------------------- */
.cta-purple {
  /* Was a three-stop gradient. The guide is explicit: flat colour only,
     "depth comes from overlapping color fields". */
  background: var(--nu-purple);
  border-radius: var(--radius-lg);
  padding: clamp(26px, 3.4vw, 42px);
  color: var(--white);
}
.cta-purple h2, .cta-purple h3 { color: var(--white); }
.cta-purple p { color: rgba(255,255,255,.86); max-width: 60ch; }

/* Compact mid-page variant of the final CTA. Review slide 8, MV: "That
   sounds good" — the CTA is surfaced twice, same copy, two treatments. */
.cta-compact {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: var(--s-5);
}
.cta-compact h2 { font-size: clamp(24px, 2.6vw, 32px); margin: 0; }
.cta-compact p { margin: var(--s-2) 0 0; }

/* --------------------------------------------------------------------------
   SECTION HEADER
   -------------------------------------------------------------------------- */
.sec-head { max-width: var(--maxw-read); margin-bottom: var(--s-6); }
.sec-head p { color: var(--ink-soft); font-size: var(--lede); margin: 0; }

/* Text link with the arrow, e.g. "See all services →" */
.arrow-link {
  display: inline-flex; align-items: center; gap: var(--s-2);
  font-weight: 600; font-size: var(--small);
  color: var(--purple); text-decoration: none;
}
.arrow-link .icon { width: 18px; height: 18px; transition: transform var(--dur-fast) var(--ease); }
.arrow-link:hover .icon { transform: translateX(3px); }

/* --------------------------------------------------------------------------
   FOOTER
   -------------------------------------------------------------------------- */
.footer {
  background: var(--purple-ink);
  color: rgba(255,255,255,.75);
  padding-block: var(--s-8) var(--s-6);
}
.footer__top {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr;
  gap: var(--s-7);
  padding-bottom: var(--s-7);
  border-bottom: 1px solid rgba(255,255,255,.14);
}
.footer__brand img { height: 48px; width: auto; margin-bottom: var(--s-4); }
.footer__tagline {
  font-size: var(--small); color: rgba(255,255,255,.72);
  max-width: 34ch; margin: 0;
}
.footer__tagline span[aria-hidden] { color: var(--orange); }
.footer__h {
  font-family: var(--font-body);
  font-size: var(--micro); font-weight: 600;
  letter-spacing: var(--ls-micro); text-transform: uppercase;
  color: var(--orange);
  margin: 0 0 var(--s-4);
}
.footer__nav { display: flex; flex-direction: column; gap: var(--s-3); align-items: flex-start; }
.footer a { color: rgba(255,255,255,.82); text-decoration: none; font-size: var(--small); }
.footer a:hover { color: var(--white); text-decoration: underline; }
.footer__contact p { margin: 0 0 var(--s-3); font-size: var(--small); }
/* Matched on WIDTH, like the Published Thinking strip upstairs and for the
   same reason: the Greenbook lockup is three stacked lines plus a shield
   where the other two are a wide two-line wordmark, so at an equal 30px
   height its lettering came out at about half the size of theirs. Equal-width
   chips bring it to roughly three quarters, which is as close as these three
   artworks get. Their heights differ as a result; centring the row is what
   makes that read as deliberate. */
.footer__badges {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 120px));
  align-items: center; gap: var(--s-4);
  padding-block: var(--s-6);
}
.footer__badges img {
  /* A fixed height makes all three chips identical rectangles, and
     object-fit:contain keeps each badge filling the chip's WIDTH rather than
     being scaled down to its height — so the boxes are even and the lettering
     still matches. 56px is what the tallest lockup (Greenbook, 2.39:1) needs
     at 104px of content width; the other two simply carry more white above
     and below, which is how a logo card is meant to look. */
  width: 100%; height: 56px; object-fit: contain;
  /* These are wordmark badges, not silhouette logos. The previous
     brightness(0) invert(1) knocked them into solid white rectangles —
     unreadable blocks rather than credentials. They sit on a light chip,
     which also matches the brand's rounded, flat-colour shapes. */
  background: var(--surface);
  border-radius: var(--radius-sm);
  padding: 6px 8px;
  opacity: .82;
  transition: opacity var(--dur) var(--ease);
}
.footer__badges picture { display: block; width: 100%; }
.footer__badges img:hover { opacity: 1; }
.footer__legal {
  font-size: 13px; color: rgba(255,255,255,.5);
  margin: 0; padding-top: var(--s-4);
  border-top: 1px solid rgba(255,255,255,.14);
}

@media (max-width: 860px) {
  .footer__top { grid-template-columns: 1fr; gap: var(--s-6); }
  /* Narrower columns on a phone, so the chip height follows them down. */
  .footer__badges { gap: var(--s-4); grid-template-columns: repeat(3, minmax(0, 104px)); }
  .footer__badges img { height: 49px; }
}

/* --------------------------------------------------------------------------
   FORM
   Every field has a real <label> — never a placeholder standing in for one,
   which disappears the moment someone starts typing and is lost entirely to
   anyone using voice control.
   -------------------------------------------------------------------------- */
.form { max-width: 620px; }
.field { margin-bottom: var(--s-5); border: 0; padding: 0; }
.field > label,
.field > legend {
  display: block;
  font-size: var(--small); font-weight: 700;
  color: var(--ink);
  margin-bottom: var(--s-2);
  padding: 0;
}
.req { color: var(--text-orange); }
.field__opt { font-weight: 400; color: var(--ink-muted); }
.field__hint { font-size: 13px; color: var(--ink-muted); margin: var(--s-2) 0 0; }

.field input[type="text"],
.field input[type="email"],
.field input[type="tel"],
.field select,
.field textarea {
  width: 100%;
  font: inherit;
  color: var(--ink);
  background: var(--surface);
  border: 2px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 12px var(--s-4);
  transition: border-color var(--dur-fast) var(--ease);
}
.field textarea { resize: vertical; min-height: 120px; }
.field input:focus, .field select:focus, .field textarea:focus {
  border-color: var(--nu-purple);
}
.field input.is-invalid, .field textarea.is-invalid { border-color: var(--text-orange); }

.field__error {
  margin: var(--s-2) 0 0;
  font-size: 13px; font-weight: 600;
  color: var(--text-orange);   /* 5.7:1 — never --nu-orange for text */
}

.checks { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--s-2); }
.checks label {
  display: flex; align-items: flex-start; gap: var(--s-3);
  font-size: var(--small); font-weight: 400; color: var(--ink);
  cursor: pointer;
  min-height: 44px;            /* touch target, not just the box */
  align-items: center;
}
.checks input { width: 20px; height: 20px; accent-color: var(--nu-purple); flex: none; }

/* Honeypot: off-screen rather than display:none, because some bots skip
   hidden inputs. aria-hidden + tabindex="-1" keep it away from real users. */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.form__status { margin-bottom: var(--s-4); font-size: var(--small); font-weight: 600; }
.form__status:empty { display: none; }
.form__status--error { color: var(--text-orange); }
.form__status--busy  { color: var(--ink-muted); }
.form__promise { margin-top: var(--s-3); font-size: 13px; color: var(--ink-muted); }
/* The privacy notice sits directly under the promise line, quieter still. */
.form__privacy { margin-top: var(--s-2); font-size: 13px; color: var(--ink-muted); }
.form__privacy a { color: var(--purple); }

.form__done {
  background: var(--purple-100);
  border-radius: var(--radius-md);
  padding: var(--s-7) var(--s-6);
}
.form__done h2 { font-size: var(--h3); margin-bottom: var(--s-2); }
.form__done p { margin: 0; color: var(--ink-soft); }

@media (max-width: 900px) {
  .stages {
    display: flex; flex-wrap: nowrap;
    overflow-x: auto; scroll-snap-type: x mandatory;
  }
}
