/* ============================================================
   VoiceInsights Africa — Wave 2 public product surfaces
   ------------------------------------------------------------
   Research modes, collection channels, language capabilities,
   multi-country and the product catalogue.

   THE ONE STRUCTURAL IDEA: THE CAPABILITY LEDGER.

   Every Wave 2 page answers the same shape of question — "can you do
   this, and how sure are you". A card grid answers it badly: seven
   equal tiles say seven equal products, and the honest difference
   between a mode with its own tables and one that runs on shared
   structures disappears into identical rounded rectangles.

   So these pages are set as a LEDGER. Each row carries a status rule
   down its left edge, states its status in a word, and prints its own
   limits inline rather than in a footnote. A reader scanning the left
   edge sees the shape of the truth before reading a sentence, and a
   mode's caveat is impossible to skim past because it occupies the
   same visual weight as its promise.

   That is the product's own thesis applied to its marketing: a claim
   travels with its evidence.

   NOTHING HERE INVENTS A COLOUR. Every value resolves to a token in
   style.css or tokens.css. The three status treatments reuse the
   brand, the warm metallic and the neutral border precisely because
   the palette already separates identity from state — a status rule
   painted --success would say "this mode is the good one", which is
   not something the registry said.
   ============================================================ */

/* ---------- Page frame -------------------------------------------------- */

.w2-page { --w2-gutter: 5vw; }

.w2-band {
  background: var(--surface-emerald);
  color: var(--on-emerald);
  padding: 4.5rem var(--w2-gutter) 4rem;
}
.w2-band h1,
.w2-band h2 { color: var(--on-emerald); }
.w2-band p { color: var(--on-emerald-muted); }
.w2-band .w2-eyebrow { color: var(--vi-champagne-300); }

.w2-band-inner,
.w2-section-inner { max-width: var(--content-wide); margin: 0 auto; }

.w2-section { padding: 4rem var(--w2-gutter); }
.w2-section-soft { background: var(--surface-2); }
.w2-section-champagne { background: var(--surface-champagne-soft); }

.w2-eyebrow {
  display: block;
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--accent-2-text);
  margin-bottom: .9rem;
}

.w2-band h1 { font-size: var(--text-2xl); line-height: 1.05; max-width: 18ch; margin: 0; }
.w2-lead { font-size: var(--text-lg); line-height: 1.55; max-width: 62ch; margin: 1.2rem 0 0; }

.w2-section > .w2-section-inner > h2 {
  font-size: var(--text-xl);
  margin: 0 0 .6rem;
  max-width: 24ch;
}
.w2-section-intro { max-width: 68ch; color: var(--text-muted); margin: 0 0 2.5rem; }

/* ---------- Mode index ---------------------------------------------------
   Wayfinding for a page that is deliberately long. Each entry carries its
   status, so the shape of the answer is visible before any jump. */

.w2-mode-index { margin: 0 0 2rem; }
.w2-mode-index ol {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: .6rem;
}
.w2-mode-index a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  min-height: 44px;
  padding: .55rem .9rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  background: var(--surface);
  color: var(--text);
  text-decoration: none;
  font-size: var(--text-sm);
  font-weight: 600;
}
.w2-mode-index a:hover { border-color: var(--accent); }

/* Landing on an anchor should not tuck the row under a sticky header, and
   should not fling a reader who asked not to be moved. */
.w2-page { scroll-behavior: smooth; }
.w2-page [id^="mode-"],
.w2-page [id^="channel-"],
.w2-page [id^="area-"] { scroll-margin-top: 1.5rem; }
@media (prefers-reduced-motion: reduce) { .w2-page { scroll-behavior: auto; } }

/* ---------- The ledger -------------------------------------------------- */

.w2-ledger { display: grid; gap: 1.25rem; }

.w2-row {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 1.75rem 1.75rem 1.75rem 2.25rem;
  box-shadow: var(--elevation-1);
}

/* The status rule. Three states, three treatments, and the difference
   is legible without colour: the rule's WIDTH and the status word
   both carry it, so the row still reads correctly in monochrome and
   to anyone who cannot separate the two hues. */
.w2-row::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 5px;
  border-radius: var(--radius-lg) 0 0 var(--radius-lg);
  background: var(--border-strong);
}
.w2-row[data-status="LIVE"]::before { background: var(--accent); }
.w2-row[data-status="SUPPORTED"]::before {
  background: repeating-linear-gradient(
    180deg, var(--accent-warm) 0 8px, transparent 8px 14px);
}

.w2-row-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .75rem 1rem;
  margin-bottom: .75rem;
}
.w2-row-head h3 {
  font-size: 1.3rem;
  margin: 0;
  letter-spacing: -.015em;
}
.w2-row-aka {
  font-size: var(--text-sm);
  color: var(--text-dim);
}

.w2-status {
  display: inline-flex;
  align-items: center;
  gap: .45em;
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  padding: .34em .8em;
  border-radius: 999px;
  border: 1px solid transparent;
  white-space: nowrap;
}
.w2-status[data-status="LIVE"] { background: var(--accent); color: var(--accent-ink); }
.w2-status[data-status="SUPPORTED"] {
  background: transparent;
  color: var(--accent-warm-text);
  border-color: var(--accent-warm);
}
.w2-status[data-status="NOT_AVAILABLE"],
.w2-status[data-status="NOT_BUILT"],
.w2-status[data-status="OUTBOUND_ONLY"] {
  background: var(--surface-2);
  color: var(--text-muted);
  border-color: var(--border-strong);
}

/* THE LANGUAGE REGISTRY'S FIVE STATES.
   ------------------------------------------------------------------
   These are a DIFFERENT vocabulary from the mode/channel states above,
   and the first build did not style them. The language table writes
   `axis.state` straight into data-status, so VALIDATED,
   SUPPORTED_WITH_REVIEW, VOICE_CAPTURE_ONLY and IN_VALIDATION all fell
   through every rule and rendered as identical transparent pills.

   That is a quiet, complete defeat of the page's central claim. The
   whole point of a six-axis table is that a language can be Validated
   for text and In validation for transcription — and with four of five
   states looking the same, a reader could not see the difference the
   table exists to show.

   The treatments deliberately mirror the ledger's: measured-by-us is
   the brand fill, measured-with-review is the warm outline, and
   anything unmeasured is neutral. Weight and outline carry the
   distinction as well as hue, so the table still reads in monochrome. */
.w2-status[data-status="VALIDATED"] {
  background: var(--accent);
  color: var(--accent-ink);
}
.w2-status[data-status="SUPPORTED_WITH_REVIEW"] {
  background: transparent;
  color: var(--accent-warm-text);
  border-color: var(--accent-warm);
}
.w2-status[data-status="VOICE_CAPTURE_ONLY"] {
  background: var(--surface-2);
  color: var(--accent-2-text);
  border-color: var(--accent-2);
}
.w2-status[data-status="IN_VALIDATION"] {
  background: var(--surface);
  color: var(--text-muted);
  border-color: var(--border-strong);
  border-style: dashed;
}

.w2-row-summary { font-size: 1.02rem; line-height: 1.6; margin: 0 0 1.25rem; max-width: 72ch; }

/* The facts grid. Definition pairs, not cards — a mode's collection
   structure is a property of the mode, not a feature of its own. */
.w2-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 1.25rem 2rem;
  margin: 0 0 1.25rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--border);
}
.w2-facts > div { min-width: 0; }
.w2-facts dt {
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: .4rem;
}
.w2-facts dd { margin: 0; font-size: .92rem; line-height: 1.55; color: var(--text-muted); }

/* THE LIMIT BLOCK. Deliberately given the same weight as the promise
   above it. A caveat set in 11px grey is a caveat designed not to be
   read, and the whole point of the SUPPORTED status is that the
   reader plans around what it says. */
.w2-limits {
  background: var(--vi-champagne-100);
  border-left: 3px solid var(--accent-warm);
  border-radius: 0 var(--radius-xs) var(--radius-xs) 0;
  padding: 1rem 1.25rem;
  margin: 0 0 1.25rem;
}
.w2-limits p {
  margin: 0 0 .4rem;
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--accent-warm-text);
}
.w2-limits ul { margin: 0; padding-left: 1.1rem; }
.w2-limits li { font-size: .92rem; line-height: 1.55; color: var(--text); }
.w2-limits li + li { margin-top: .45rem; }

/* Channel chips. Carriage, stated as such. */
.w2-chips { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
.w2-chip {
  display: inline-flex;
  align-items: center;
  font-size: var(--text-xs);
  font-weight: 600;
  padding: .3em .7em;
  border-radius: var(--radius-xs);
  background: var(--surface-2);
  color: var(--text-muted);
  border: 1px solid var(--border);
}
.w2-chip-note { font-size: var(--text-xs); color: var(--text-dim); }

.w2-row-actions { display: flex; flex-wrap: wrap; gap: .75rem; }

/* ---------- What is not a mode ------------------------------------------ */

.w2-notmode {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1rem;
}
.w2-notmode-item {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  padding: 1.25rem 1.4rem;
}
.w2-notmode-item h3 { font-size: 1.02rem; margin: 0 0 .2rem; }
.w2-notmode-kind {
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--accent-2-text);
}
.w2-notmode-item p { margin: .5rem 0 0; font-size: .92rem; line-height: 1.55; color: var(--text-muted); }

/* ---------- Capability matrix ------------------------------------------- */

.w2-matrix-scroll { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface); }
.w2-matrix { width: 100%; border-collapse: collapse; min-width: 640px; font-size: .9rem; }
.w2-matrix caption { text-align: left; padding: 1rem 1.1rem; font-size: var(--text-sm); color: var(--text-muted); }
.w2-matrix th, .w2-matrix td { padding: .8rem 1.1rem; text-align: left; border-bottom: 1px solid var(--border); }
.w2-matrix thead th {
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-dim);
  background: var(--surface-2);
}
.w2-matrix tbody tr:last-child th,
.w2-matrix tbody tr:last-child td { border-bottom: 0; }
.w2-matrix tbody th { font-weight: 600; color: var(--text); }
/* A row header that is a link gets a real target rather than the height of
   its own line. WCAG 2.2 2.5.8 exempts a link inline in a sentence, and
   these qualify — but the exemption exists because prose cannot be made
   taller without damaging it, and a table row can. */
.w2-matrix tbody th a { display: inline-block; padding: .3rem 0; }

/* ---------- Product capture ---------------------------------------------
   A screenshot of the real product, with its own provenance attached.
   The caption is not optional styling: an image of a workspace with no
   route, role and environment beside it is indistinguishable from an
   illustration, which is the failure this whole wave exists to avoid. */

.w2-capture { margin: 0; }
.w2-capture img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--surface-2);
  box-shadow: var(--elevation-2);
}
.w2-capture figcaption {
  margin-top: .85rem;
  font-size: var(--text-xs);
  line-height: 1.6;
  color: var(--text-dim);
}
.w2-capture figcaption b { color: var(--text-muted); font-weight: 600; }
.w2-capture-meta {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem .9rem;
  margin-top: .4rem;
  font-variant-numeric: tabular-nums;
}

.w2-demo-flag {
  display: inline-flex;
  align-items: center;
  gap: .4em;
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  padding: .3em .75em;
  border-radius: var(--radius-xs);
  background: var(--vi-champagne-200);
  color: var(--accent-warm-text);
  border: 1px solid var(--accent-warm);
}

/* ---------- The device composition ---------------------------------------
   Three real captures of the deployed product, at the three form factors
   the product is actually used on: a command centre on a laptop, a
   regional portfolio on a tablet, a field workspace on a phone.

   THE FRAMING IS DELIBERATELY THIN. A drawn laptop bezel with a hinge and
   a camera notch is an illustration wrapped around a photograph, and it
   invites the reader to treat the whole composition as artwork. A 1px
   border and a shadow say "this is a screen" without pretending to be a
   device, which is the honest amount of chrome for an image whose entire
   value is that it was not drawn. */

/* THE THREE SCREENS ARE A GRID, NOT A PILE.
   The first pass overlapped a tablet and a phone across the laptop, which
   is the standard device-mockup collage — and it covered the middle of the
   one screen a reader can actually read, left a large empty band beneath,
   and identified none of the three. Here the command centre gets the width
   it needs to be legible and the two smaller surfaces sit beneath it, each
   NAMED. Naming them is the point: three anonymous screens say "we have a
   product"; three named ones say which product, on which device, for whom. */
/* ============================================================
   WAVE 4 BLOCK 1 — THE DEVICES ARE NOW DEVICES

   WHAT WAS HERE BEFORE, AND WHY IT HAD TO CHANGE.

   Three elements named .w2-device-laptop, -tablet and -phone, each
   drawing a 1px border and a shadow around a picture. Nothing in the
   composition said laptop, tablet or phone; the class names carried
   the whole claim and the CSS never honoured it.

   Worse was the crop. The tablet and phone screenshots are portrait —
   520x693 and 400x866 — and both were forced to `height: 190px` with
   `object-fit: cover`. That is not a small compromise: the phone
   capture is 866px tall, so the reader was shown the TOP 22% of it and
   nothing else. The Field Workspace's assignment cards, its completion
   count and its "Start interview" action were all below the cut. Two of
   the three product proofs on the most important page of the site were
   cropped past the point of proving anything, directly above a caption
   promising "unretouched captures of the deployed platform".

   THE RULE THIS COMPOSITION FOLLOWS: the chrome may never cost the
   screen. Every value below is chosen so the product stays the largest,
   brightest thing in the figure — thin bezels, one flat graphite, no
   gradients, no reflections, no perspective, and no drawn UI of any
   kind. Nothing is ever painted ON the screen, only around it, which is
   what keeps the "unretouched" caption true.
   ============================================================ */
.w2-devices {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.6rem 1.1rem;
  align-items: start;
  justify-items: center;

  /* Scoped to the composition rather than added to the global token
     file: a graphite that reads as hardware is not a brand colour and
     should not become one. Overridden once inside the emerald band
     below, where the same value would disappear into the ground. */
  --device-chrome: #14181c;
  --device-chrome-edge: #2b3238;
  --device-screen-radius: 3px;
}
.w2-device {
  min-width: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* The bezel. `padding` IS the bezel width, which is why each device
   overrides only that and inherits everything else. */
.w2-device-frame {
  position: relative;
  width: 100%;
  background: var(--device-chrome);
  border: 1px solid var(--device-chrome-edge);
  box-shadow: var(--elevation-2);
}
.w2-device-frame img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--device-screen-radius);
  background: var(--surface);
}

/* ---- Laptop ------------------------------------------------------
   A wide, shallow bezel with a deeper chin, and a base that is wider
   than the lid — the two cues that read as "laptop" at a glance and
   cost four declarations. The base is a pseudo-element so it adds no
   markup and is invisible to assistive technology. */
.w2-device-laptop { grid-column: 1 / -1; }
.w2-device-laptop .w2-device-frame {
  padding: 10px 10px 20px;
  border-radius: 12px 12px 6px 6px;
  box-shadow: var(--elevation-3);
  margin-bottom: 9px;
}
.w2-device-laptop .w2-device-frame::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -9px;
  transform: translateX(-50%);
  width: 112%;
  height: 9px;
  background: var(--device-chrome);
  border: 1px solid var(--device-chrome-edge);
  border-top: 0;
  border-radius: 0 0 8px 8px;
}

/* ---- Tablet ------------------------------------------------------
   An even bezel on all four sides. That evenness is the entire visual
   difference from the phone below, so it is worth stating plainly
   rather than relying on size to communicate it. */
.w2-device-tablet .w2-device-frame {
  padding: 12px;
  border-radius: 16px;
}

/* ---- Android phone -----------------------------------------------
   A thin bezel, a large corner radius, and a centred punch-hole camera.
   The punch-hole is the specifically ANDROID cue the brief asks for —
   a notch would read as a different manufacturer's hardware, and this
   screenshot is of the Android field app. */
.w2-device-phone .w2-device-frame {
  padding: 7px;
  border-radius: 22px;
}
.w2-device-phone .w2-device-frame::before {
  content: "";
  position: absolute;
  top: 12px;
  left: 50%;
  transform: translateX(-50%);
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #05070a;
  z-index: 1;
}

/* ---- Composition -------------------------------------------------
   NARROW FIRST, and stacked rather than shrunk. Three devices squeezed
   into one narrow row is the arrangement that produced the 190px crop
   in the first place: the row stays even and every screen becomes
   unreadable. Stacked, each device gets the full column width and the
   portrait screens are capped at a width that keeps their real height
   sensible. The hero is taller on a phone; the product is legible on
   one, which is the trade this figure exists to make. */
.w2-device-tablet { max-width: 268px; }
.w2-device-phone { max-width: 186px; }

@media (min-width: 720px) {
  /* The laptop takes the full width it needs to be read, and the two
     portrait devices sit beneath it in a centred row — near enough the
     same rendered height as each other, because their caps are derived
     from their real aspect ratios rather than picked to look tidy. */
  .w2-devices { grid-template-columns: repeat(2, minmax(0, auto)); }
  .w2-device-laptop { justify-self: stretch; }
  .w2-device-tablet { max-width: 260px; justify-self: end; }
  .w2-device-phone { max-width: 172px; justify-self: start; }
}
.w2-device-label {
  display: block;
  margin-top: .5rem;
  font-size: var(--text-xs);
  line-height: 1.45;
  color: var(--text-muted);
}
.w2-device-label b { color: var(--text); font-weight: 600; display: block; }

.w2-devices-note {
  margin: 1.1rem 0 0;
  font-size: var(--text-xs);
  line-height: 1.6;
  /* On the light homepage hero. Inside an emerald band the rule below
     swaps both colours — the first pass used the emerald-safe muted token
     here unconditionally and put #95DCC2 on a near-white background. */
  color: var(--text-muted);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem .9rem;
}
.w2-devices-note a { color: var(--accent-text); }
.w2-band .w2-devices-note { color: var(--on-emerald-muted); }
.w2-band .w2-devices-note a { color: var(--vi-champagne-300); }
.w2-band .w2-device-label { color: var(--on-emerald-muted); }
.w2-band .w2-device-label b { color: var(--on-emerald); }
/* Inside the emerald band the graphite above goes nearly invisible and the
   devices read as holes rather than hardware. One step lighter and one step
   warmer restores the edge without turning the chrome into a brand colour. */
.w2-band .w2-devices { --device-chrome: #101a17; --device-chrome-edge: #35544a; }

/* ---------- Split feature ----------------------------------------------- */

.w2-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 3rem;
  align-items: center;
}
.w2-split-text h2 { font-size: var(--text-xl); margin: 0 0 .9rem; }
.w2-split-text p { color: var(--text-muted); line-height: 1.65; }

/* The sector chip rules MOVED to components.css in Block 1.1 — the same
   component is rendered on nine sector pages that do not load this file,
   so it shipped as an unstyled bullet list on every one of them. The rules
   and the full account are in components.css under "Sector chips". */


/* ---------- Unavailable state -------------------------------------------
   Used when a page reads live data and the data is not there. It says
   what is missing and what to do, and never renders an empty table that
   reads as "nothing is supported". */
.w2-unavailable {
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--surface-2);
  padding: 1.5rem;
  color: var(--text-muted);
  font-size: .95rem;
  line-height: 1.6;
}
.w2-unavailable strong { color: var(--text); }

/* ---------- Responsive --------------------------------------------------- */

@media (max-width: 900px) {
  .w2-split { grid-template-columns: minmax(0, 1fr); gap: 2rem; }
  .w2-band { padding: 3.25rem var(--w2-gutter) 2.75rem; }
  .w2-section { padding: 3rem var(--w2-gutter); }
}

@media (max-width: 640px) {
  .w2-page { --w2-gutter: 1.25rem; }
  .w2-row { padding: 1.35rem 1.25rem 1.35rem 1.65rem; }
  .w2-facts { grid-template-columns: minmax(0, 1fr); gap: 1rem; }
  .w2-row-head h3 { font-size: 1.15rem; }

  /* A MATRIX BECOMES A LIST ON A PHONE.
     ------------------------------------------------------------------
     The first build put a 640px-minimum table inside an overflow-x
     scroller and called that responsive. Measured at 390px it was not:
     the page itself scrolled 199px sideways — window.scrollX genuinely
     moved — and axe reported the scroller as a keyboard trap because a
     region you can scroll must be reachable by keyboard.

     Both are symptoms of the same wrong decision. A five-column matrix
     read 350 pixels at a time is not readable however well it scrolls.
     So at phone width each row becomes a labelled block: the mode name
     as a heading, then one line per channel carrying its own column
     name. No sideways scroll, nothing hidden, and the same facts. */
  .w2-matrix-scroll { overflow-x: visible; border: 0; background: none; }
  .w2-matrix { min-width: 0; display: block; }
  .w2-matrix caption { padding: 0 0 1rem; }
  /* A <caption> keeps `display: table-caption` when the table becomes a
     block, so it generates an anonymous table wrapper and shrinks to fit —
     which rendered a 60-word sentence in a 60px column, one word per line,
     on every stacked matrix on the site.

     Found by the Wave 3 design critique against the deployed origin. Four
     pages carry a matrix caption and all four were affected, two of them
     since Wave 2: the page reports no overflow, axe reports no violation,
     and at full-page scale the broken caption reads as a smudge. */
  .w2-matrix caption { display: block; }
  .w2-matrix thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .w2-matrix tbody,
  .w2-matrix tbody tr { display: block; }
  .w2-matrix tbody tr {
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface);
    padding: .35rem .9rem .6rem;
  }
  .w2-matrix tbody tr + tr { margin-top: .75rem; }
  .w2-matrix tbody th,
  .w2-matrix tbody td { display: block; padding: .45rem 0; border-bottom: 1px solid var(--border); }
  .w2-matrix tbody th { font-size: 1rem; border-bottom: 1px solid var(--border-strong); }
  .w2-matrix tbody tr td:last-child { border-bottom: 0; }
  /* The column name travels with the cell, because a cell with no
     header beside it is a value with no question. */
  .w2-matrix tbody td::before {
    content: attr(data-label);
    display: inline;
    font-weight: 600;
    color: var(--text-dim);
    margin-right: .5rem;
  }
}

/* Every interactive element in these surfaces keeps the platform focus
   ring rather than defining its own. Stated here because a new stylesheet
   is exactly where a custom outline gets introduced by accident. */
.w2-page a:focus-visible,
.w2-page button:focus-visible,
.w2-page summary:focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
}

/* ============================================================
   CONTACT INTENT RIBBON
   ------------------------------------------------------------
   The reader's receipt. A changed heading alone is ambiguous — it could
   simply be the page's normal heading — so the ribbon names what was
   carried across the click, in the buyer's own vocabulary.

   Styled as a quiet acknowledgement rather than an alert: this is not a
   warning, a status or a promotion, and giving it any of those
   treatments would make the form look like it had a problem.
   ============================================================ */
.contact-intent-ribbon {
  margin: 0 0 1.25rem;
  padding: .6rem .85rem;
  border-left: 3px solid var(--accent-2, #2E7D6B);
  background: var(--surface-2, rgba(46,125,107,.06));
  border-radius: 0 var(--radius-xs) var(--radius-xs) 0;
  font-size: var(--text-sm);
  line-height: 1.55;
  color: var(--text-muted);
}

/* A STATUS PILL MUST NEVER PUSH THE PAGE SIDEWAYS.
 * On a 360px screen a long label ran to 324px inside a row that had already
 * spent its width, and the document scrolled horizontally. The pill wraps now
 * instead — a two-line pill is legible; a page that scrolls sideways to reach
 * the rest of a sentence is not. */
.w2-status { max-width: 100%; white-space: normal; overflow-wrap: anywhere; }

/* ── FINAL PUBLIC WEBSITE PASS ───────────────────────────────────────────────
   Two measured defects, fixed at the rule that caused them.

   1. A PHONE SCREEN IS NOT A DESKTOP PANEL. `.w2-capture img { width: 100% }`
      is correct for a 1200x750 laptop capture in a 1176px column and wrong for
      a 400x866 phone capture in the same column: production rendered
      field-workspace.webp at 1176x2544, a 2.94x upscale, and it looked exactly
      as soft as that number predicts. Portrait captures are now capped near
      their intrinsic width, centred, and framed as the phone product they are.
      The cap is below the 400px source width, so the image is never upscaled at
      1x and still has headroom on a 2x display.

   2. THE BRAND SIGNATURE IS A LOCKUP, NOT A HEADLINE. It opens the identity
      block BELOW the two actions - signature, short stroke, institutional
      sentence - set small and letterspaced so it reads as who VoiceInsights is
      rather than as a claim about what the software does. Above the headline
      it competed with the promise for the same weight; below the actions it
      signs the argument the hero has just finished making. */
.w2-capture-portrait img {
  width: auto;
  max-width: min(320px, 100%);
  margin-inline: auto;
}
.w2-capture-portrait figcaption { text-align: center; }

.hero-brandline {
  /* Opens the identity block beneath the actions. Its ::before stroke sits
     above it and carries the gap down to the signature, so the margin here is
     only the distance from the action row to that stroke. */
  margin: 1.7rem 0 0;
  font-family: var(--font-display, inherit);
  font-size: var(--text-sm, .92rem);
  font-weight: 600;
  letter-spacing: .06em;
  line-height: 1.5;
  color: var(--accent-text, var(--brand-primary, #064E3B));
  text-wrap: balance;
}
@media (min-width: 900px) {
  /* Unequal columns: align to the top rather than centring, so the shorter
     column can never be pushed down by the taller one. That centring is what
     put 540px of nothing above the headline. */
  .phase1-hero-grid { align-items: start; }
}

/* The footer carries the signature above the descriptive brandline: identity
   first, then what the company does. Same lockup treatment as the hero. */
.footer-signature {
  margin: 0 0 .45rem;
  font-family: var(--font-display, inherit);
  font-size: var(--text-sm, .92rem);
  font-weight: 600;
  letter-spacing: .06em;
  line-height: 1.5;
  color: var(--vi-champagne-300, var(--accent-text, inherit));
}

/* WIDGET EXITS. A reader who has just worked through an interactive surface has
   demonstrated intent; the previous build left them with nowhere to go. One row
   per surface, two actions at most, sitting quietly under the widget rather than
   interrupting it. */
.widget-exit {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .75rem 1.1rem;
  margin-top: 1.35rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--border-subtle, #D8D5CE);
}
.widget-exit-prompt {
  margin: 0;
  font-weight: 600;
  font-size: var(--text-sm, .92rem);
  color: var(--text-muted, inherit);
}
.widget-exit-actions { display: flex; flex-wrap: wrap; gap: .6rem; }

/* THE APPLICATION'S FRONT DOOR, IN THE FOOTER. A returning user is not a buyer:
   they want in, not a demonstration. This sits beside the contact affordances
   as a quiet utility rather than in the CTA row, and is deliberately not a
   .btn — an outlined control there would compete with Request a demo, which is
   the one thing the footer's action hierarchy exists to protect.
   Every custom property carries a literal fallback: an undefined token here
   fails silently and the link loses its box without anything reporting it. */
.footer-workspace {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  margin: 0 0 1.15rem;
  padding: .42rem .85rem;
  border: 1px solid var(--border-subtle, #D8D5CE);
  border-radius: var(--radius-sm, 6px);
  color: var(--text-muted, inherit);
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .01em;
  text-decoration: none;
  width: max-content;
  max-width: 100%;
  transition: border-color .18s ease, color .18s ease;
}
.footer-workspace::before {
  content: "";
  width: .5rem;
  height: .5rem;
  border-radius: 50%;
  background: var(--accent-2, #2E7D6B);
  flex: none;
}
.footer-workspace:hover,
.footer-workspace:focus-visible {
  border-color: var(--accent-2, #2E7D6B);
  color: var(--accent-2, #2E7D6B);
}

/* THE SECONDARY SECTOR BAND. Eleven published sector pages that the landing
   page was not offering. They are deliberately a tier below the fourteen
   flagship cards — measurably so, 9-12 sections against 16-17 — so the card is
   quieter: no buyer line, no outputs strip, a tighter grid and a smaller
   footprint. It reads as "also covered", which is exactly what it is.
   Literal fallbacks on every token: an undefined custom property here would
   collapse the card silently rather than reporting anything. */
.industry-grid-compact {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15.5rem, 1fr));
  gap: .8rem;
}
.industry-card-compact {
  display: flex;
  flex-direction: column;
  gap: .4rem;
  padding: 1rem 1.1rem;
}
.industry-card-compact h3 {
  margin: 0;
  font-size: .95rem;
  line-height: 1.3;
}
.industry-card-compact p {
  margin: 0;
  color: var(--text-muted, inherit);
  font-size: .82rem;
  line-height: 1.55;
  /* The page's own opening line. It is the longest thing in the card and the
     reason the card exists, so it gets the room and wraps rather than clips. */
  overflow-wrap: anywhere;
}
.industry-card-compact a {
  margin-top: auto;
  padding-top: .5rem;
  color: var(--accent-2, #2E7D6B);
  font-size: .76rem;
  font-weight: 700;
  text-decoration: none;
}
.industry-card-compact a:hover,
.industry-card-compact a:focus-visible { text-decoration: underline; }
@media (max-width: 640px) {
  .industry-grid-compact { grid-template-columns: 1fr; }
}

/* THE BRAND LOCKUP. Signature and promise are one unit: the signature names
   what the company is, the promise names what it does. The promise sits a step
   quieter than the signature — it is the longer line and reads as support, not
   as a second headline competing with the first. */
.footer-promise {
  margin: .35rem 0 0;
  max-width: 46ch;
  color: var(--text-muted, inherit);
  font-size: .84rem;
  line-height: 1.55;
  letter-spacing: .002em;
}

/* THE SIX INPUT FORMS. A definition, not a slogan — so it is set quieter than
   either brand asset and sits inside the collection section it explains. The
   chip row is the scannable part; the note under it is the part that keeps the
   row honest, and it is deliberately not hidden behind a disclosure. */
.input-forms {
  margin: 1.4rem 0 0;
  padding: 1.1rem 1.2rem;
  border: 1px solid var(--border-subtle, #D8D5CE);
  border-radius: var(--radius-md, 10px);
}
.input-forms-title {
  margin: 0;
  font-family: var(--font-display, inherit);
  font-size: 1.05rem;
  font-weight: 650;
  letter-spacing: -.01em;
}
.input-forms-lede {
  margin: .4rem 0 0;
  max-width: 68ch;
  color: var(--text-muted, inherit);
  font-size: .88rem;
  line-height: 1.6;
}
.input-forms-row {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  margin: .85rem 0 0;
  padding: 0;
  list-style: none;
}
.input-forms-row li {
  padding: .3rem .7rem;
  border: 1px solid var(--border-subtle, #D8D5CE);
  border-radius: 999px;
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .01em;
  white-space: nowrap;
}
.input-forms-note {
  margin: .8rem 0 0;
  max-width: 78ch;
  color: var(--text-dim, var(--text-muted, inherit));
  font-size: .78rem;
  line-height: 1.6;
}
@media (max-width: 560px) {
  .input-forms-row { gap: .35rem; }
  .input-forms-row li { font-size: .74rem; padding: .26rem .6rem; }
}

/* ==========================================================================
   STUDY TYPES — A THIRD STATE VOCABULARY, STYLED AS A THIRD ONE.
   --------------------------------------------------------------------------
   The page carries two enumerations neither of the vocabularies above
   defines: a study type's capability status (PROVEN / SUPPORTED_BOUNDED) and
   a collection route's suitability for it (PRIMARY / SUPPORTED / BOUNDED /
   NOT_SUITABLE). Both write their enum straight into a data attribute, and
   the language-registry block twenty lines up records exactly what happens
   when a new vocabulary reuses the shared pill without being styled: every
   state falls through to the base rule and renders identically, which
   silently merges distinctions the page exists to draw.

   So the statuses are given their own treatments, deliberately mirroring the
   ledger's logic — proven-by-us takes the brand fill, supported-with-limits
   takes the warm outline — and suitability gets a SEPARATE component rather
   than a fourth set of values on .w2-status, because a route rating and a
   capability status are different questions and a reader should not have to
   work out which pill they are looking at.
   ========================================================================== */

.w2-status[data-status="PROVEN"] { background: var(--accent); color: var(--accent-ink); }
.w2-status[data-status="SUPPORTED_BOUNDED"] {
  background: transparent;
  color: var(--accent-warm-text);
  border-color: var(--accent-warm);
}
.w2-status[data-status="NOT_IMPLEMENTED"] {
  background: var(--surface-2);
  color: var(--text-muted);
  border-color: var(--border-strong);
  border-style: dashed;
}
/* The index's per-category count. A number, not a state — so it is set as a
   neutral counter and never borrows a capability colour. */
.w2-status[data-status="COUNT"] {
  background: var(--surface-2);
  color: var(--text-dim);
  border-color: var(--border);
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}

/* ---------- Route suitability ------------------------------------------- */

.w2-suitability {
  display: inline-flex;
  align-items: center;
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  padding: .22em .7em;
  border-radius: var(--radius-sm, 6px);
  border: 1px solid transparent;
  white-space: nowrap;
}
.w2-suitability[data-suitability="PRIMARY"] { background: var(--accent); color: var(--accent-ink); }
.w2-suitability[data-suitability="SUPPORTED"] {
  background: var(--surface-2);
  color: var(--accent-2-text);
  border-color: var(--accent-2);
}
.w2-suitability[data-suitability="BOUNDED"] {
  background: transparent;
  color: var(--accent-warm-text);
  border-color: var(--accent-warm);
}
.w2-suitability[data-suitability="NOT_SUITABLE"] {
  background: transparent;
  color: var(--text-muted);
  border-color: var(--border-strong);
  border-style: dashed;
}

.w2-suit-heading {
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin: 1.25rem 0 .7rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--border);
}
.w2-suitability-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: .7rem 1.5rem;
}
/* Each rating is one row: route, rating, and the sentence saying why. The
   sentence is required on BOUNDED and NOT_SUITABLE by the registry's own
   verification, so the layout always reserves a line for it rather than
   collapsing when it is absent. */
.w2-suitability-list li { min-width: 0; align-self: start; }
.w2-suit-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .5rem .7rem;
}
.w2-suit-channel { font-size: .92rem; font-weight: 600; color: var(--text); }
.w2-suit-note {
  margin: .35rem 0 0;
  font-size: .85rem;
  line-height: 1.5;
  color: var(--text-muted);
}

/* ---------- Category grouping ------------------------------------------- */

.w2-category + .w2-category { margin-top: 2.75rem; padding-top: 2.25rem; border-top: 1px solid var(--border); }
.w2-category > h3 { font-size: 1.35rem; margin: 0 0 .4rem; }
.w2-sub { font-size: 1.1rem; margin: 2rem 0 .4rem; }
.w2-notmode-nearest { margin-top: .7rem !important; font-size: .9rem; }
