/**
 * DocuPOW — Zeroshot Extraction page styles (page-templates/extraction.php only).
 *
 * Scope: everything lives under .page-extraction (BEM). Global chrome,
 * container, buttons, links, scroll-reveal and the gradient border come from
 * main.css — this file adds the light-canvas layout, the hero extraction
 * mock, the obsidian traceability band and the page-specific motion only.
 *
 * Light-canvas contrast contract:
 *  - Canvas is var(--white); tonal bands/cards use var(--gray) with 1px
 *    var(--border) hairlines (flat design — tonal layers, not shadows).
 *  - Body copy is var(--text-muted) (9.34:1 on white, 8.70:1 on --gray).
 *  - Confidence chips (12px mono on tint): OK chips use #0A7B56 (darkened
 *    --ok, 4.80:1 on the rgba(16,185,129,.10) tint — raw --ok fails 4.5:1);
 *    WARN chips use #946300 (darkened --warn, 4.80:1 on the
 *    rgba(245,158,11,.10) tint — raw --warn fails 4.5:1). Same precedent as
 *    the #276CC1 button hover in main.css.
 *  - The hero eyebrow and the Zeroshot compare-card h3 are 13-14px semibold
 *    var(--techblue) on white — 4.54:1, passes AA.
 *  - The only shadow is var(--shadow) on the hero mock (floating product-UI
 *    exception per DESIGN.md); the warn review ring is status, not elevation.
 *
 * Dark band (S4) contrast contract:
 *  - Headings var(--white); body var(--text-muted-dark) (7.58:1 AA);
 *    hairlines var(--border-dark); panels rgba(255, 255, 255, .06).
 *  - The JSON "Score: 0.88" code comment is var(--text-muted-dark) (the
 *    export gray fails on obsidian); keys are var(--white).
 *  - Focus on obsidian gets a light halo (the 2px techblue ring alone is
 *    only 3.71:1 against the dark canvas).
 *
 * Motion contract (transform/opacity/filter only):
 *  - Hidden "entrance" base states sit inside
 *    @media (prefers-reduced-motion: no-preference), so with reduced motion
 *    (or if extraction.js never runs under that preference) everything is
 *    visible. NO floats, NO bobs, NO count-ups on this page.
 *  - extraction.js hooks: .is-ready on .page-extraction__hero (staged copy
 *    entrance); .is-active shows the [data-ext-pulse] dot row; .is-visible
 *    fades each [data-ext-field] in (staggered by JS timeouts); .is-flagged
 *    plays the one-shot warn pulse on [data-ext-warn]; .is-paired emphasises
 *    the two [data-ext-pair] highlights + the connector (works under reduced
 *    motion too — an instant state change, not motion). main.js owns
 *    [data-dp-reveal] and the stagger delays (extraction.js clears the
 *    inline delays post-reveal so hover lifts are never postponed).
 *  - A final prefers-reduced-motion: reduce block forces every animated
 *    element fully visible and static (belt-and-braces over main.css).
 */

/* =========================================================================
   Page scope — light canvas, section rhythm
   ========================================================================= */
.page-extraction {
  overflow-x: clip; /* insurance: nothing may cause horizontal scroll @320px */
}

/* 96px section padding on desktop, 64px under 768 (format strip is 48px). */
.page-extraction__hero,
.page-extraction__treadmill,
.page-extraction__how,
.page-extraction__trace,
.page-extraction__twoup,
.page-extraction__cta {
  padding-block: var(--space-7);
}

@media (max-width: 767.98px) {
  .page-extraction__hero,
  .page-extraction__treadmill,
  .page-extraction__how,
  .page-extraction__trace,
  .page-extraction__twoup,
  .page-extraction__cta {
    padding-block: var(--space-6);
  }
}

/* =========================================================================
   S1 — Hero (copy left, extraction mock right)
   ========================================================================= */
.page-extraction__hero-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-5);
  align-items: center;
}

.page-extraction__hero-grid > * {
  min-width: 0;
}

/* <1024 — single column; copy stacks first (source order). */
@media (max-width: 1023.98px) {
  .page-extraction__hero-grid {
    grid-template-columns: 1fr;
    gap: var(--space-4);
  }
}

/* Eyebrow — mono technical label; techblue semibold is 4.54:1 on white
   (passes AA for this 13px weight-600 label). */
.page-extraction__eyebrow {
  display: block;
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 1.4;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--techblue);
  margin-bottom: var(--space-3);
}

/* The single h1 — headline-xl (64/1.1/-0.02em/700) in Royal Indigo. */
.page-extraction__title {
  font-size: 64px;
  line-height: 1.1;
  letter-spacing: -0.02em;
  font-weight: 700;
  color: var(--indigo);
  margin-bottom: var(--space-3);
}

/* Designed line break — always shown per the export (every width). */
.page-extraction__title-break {
  display: inline;
}

/* body-lg lead. */
.page-extraction__lead {
  font-size: 18px;
  line-height: 1.6;
  color: var(--text-muted);
  max-width: 672px;
  margin-bottom: var(--space-5);
}

/* CTA pair — shared by the hero and S7 (S7 centers it below). */
.page-extraction__cta-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

/* <640 — the button pair stacks full-width. */
@media (max-width: 639.98px) {
  .page-extraction__cta-row {
    flex-direction: column;
    align-items: stretch;
  }
}

/* -------------------------------------------------------------------------
   Hero mock — glass panel (carries data-dp-gradient-border)
   ------------------------------------------------------------------------- */
.page-extraction__mock,
.page-extraction [data-ext-mock] {
  background-color: rgba(255, 255, 255, .8); /* glass */
  border: 1px solid var(--border);
  border-radius: 12px; /* outranks .dp-gradient-border-active (later sheet) */
  padding: var(--space-3);
  box-shadow: var(--shadow); /* soft shadow allowed — floating product UI */
  display: flex;
  gap: var(--space-3);
}

/* <640 — document skeleton stacks above the field cards. */
@media (max-width: 639.98px) {
  .page-extraction__mock,
  .page-extraction [data-ext-mock] {
    flex-direction: column;
  }
}

/* Document skeleton (decorative, aria-hidden) — muted tonal page. */
.page-extraction__doc {
  flex: 1 1 0;
  min-width: 0;
  background-color: var(--gray);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: var(--space-2);
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* Skeleton bars — display:block so width/height always apply (spans as
   inline boxes ignore both; the platform build shipped that bug once).
   Widths 75% / 100% / 83% / 50% via the sibling chain below. */
.page-extraction__doc-line {
  display: block;
  height: 8px;
  width: 100%;
  background-color: var(--border); /* export surface-dim -> --border (mapping) */
  border-radius: 4px;
}

/* Line 1 — taller title bar. */
.page-extraction__doc > .page-extraction__doc-line:first-child {
  height: 16px;
  width: 75%;
  margin-bottom: 4px;
}

/* Line 3 — the third consecutive bar. */
.page-extraction__doc-line + .page-extraction__doc-line + .page-extraction__doc-line {
  width: 83%;
}

/* The bar after the thumb — half width (the :last-child mirror keeps the
   final bar at 50% whatever side of the thumb it lands on). */
.page-extraction__doc-thumb + .page-extraction__doc-line,
.page-extraction__doc > .page-extraction__doc-line:last-child {
  width: 50%;
}

/* Receipt thumb — tall centered block. */
.page-extraction__doc-thumb {
  height: 128px;
  background-color: var(--border); /* surface-container-highest -> --border */
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-block: 4px;
}

.page-extraction__doc-thumb svg {
  width: 24px;
  height: 24px;
  color: var(--text-muted);
  flex: none;
}

/* Extracted-field column. */
.page-extraction__fields {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* Field cards — key/value left, confidence chip right. */
.page-extraction__field,
.page-extraction [data-ext-field] {
  background-color: var(--white);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: var(--space-2);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-1);
}

/* Key + value stack (the field's first child wraps them). */
.page-extraction__field-col,
.page-extraction__field > :first-child,
.page-extraction [data-ext-field] > :first-child {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.page-extraction__field-key {
  display: block; /* spans — inline boxes would still size, but keep uniform */
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.4;
  font-weight: 500;
  color: var(--text-muted);
}

.page-extraction__field-value {
  display: block;
  font-family: var(--font-mono);
  font-size: 14px;
  line-height: 1.4;
  font-weight: 600;
  color: var(--ink);
}

/* Confidence chips — 12px mono on a status tint (hex contract in header). */
.page-extraction__chip {
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.4;
  font-weight: 500;
  padding: 4px var(--space-1);
  border-radius: 4px;
  flex: none;
}

.page-extraction__chip--ok {
  background-color: rgba(16, 185, 129, .10); /* --ok tint */
  color: #0A7B56; /* darkened --ok, 4.80:1 on the tint — raw --ok fails */
}

.page-extraction__chip--warn {
  background-color: rgba(245, 158, 11, .10); /* --warn tint */
  color: #946300; /* darkened --warn, 4.80:1 on the tint — raw --warn fails */
}

/* Agent pulse row — hidden until extraction.js shows it (established
   pattern: home/platform pulse rows). */
.page-extraction__pulse,
.page-extraction [data-ext-pulse] {
  display: none;
  align-items: center;
  gap: var(--space-1);
}

.page-extraction__pulse.is-active,
.page-extraction [data-ext-pulse].is-active {
  display: flex;
}

.page-extraction__pulse-dot,
.page-extraction__pulse > *,
.page-extraction [data-ext-pulse] > * {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: var(--indigo);
  flex: none;
}

/* =========================================================================
   S2 — The end of the template treadmill (gray band + compare cards)
   ========================================================================= */
.page-extraction__treadmill {
  background-color: var(--gray);
  border-block: 1px solid var(--border);
}

.page-extraction__treadmill-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-7);
  align-items: center;
}

.page-extraction__treadmill-grid > * {
  min-width: 0;
}

/* <1024 — single column; copy stacks first (source order). */
@media (max-width: 1023.98px) {
  .page-extraction__treadmill-grid {
    grid-template-columns: 1fr;
    gap: var(--space-5);
  }
}

/* headline-lg (36/1.2/-0.01em/600) in Royal Indigo. */
.page-extraction__treadmill h2 {
  font-size: 36px;
  line-height: 1.2;
  letter-spacing: -0.01em;
  font-weight: 600;
  color: var(--indigo);
  margin-bottom: var(--space-3);
}

.page-extraction__treadmill h2 + p {
  font-size: 16px;
  line-height: 1.6;
  color: var(--text-muted);
}

/* Compare grid — the data-dp-reveal-stagger container. */
.page-extraction__compare {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3);
}

.page-extraction__compare > * {
  min-width: 0;
}

@media (max-width: 639.98px) {
  .page-extraction__compare {
    grid-template-columns: 1fr;
  }
}

/* Shared card shell. Hover lifts via the standalone `translate` property so
   it never fights the reveal's `transform`; border + lift only, ~180ms, NO
   shadows. (The reveal stagger's inline transition-delay would postpone the
   first hover — extraction.js clears it post-reveal.) */
.page-extraction__compare-card--legacy,
.page-extraction__compare-card--zeroshot {
  position: relative; /* corner-accent anchor */
  overflow: hidden;
  background-color: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-3);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
  transition:
    opacity .6s ease,
    transform .6s ease,
    translate .18s ease,
    border-color .18s ease;
}

.page-extraction__compare-card--legacy:hover,
.page-extraction__compare-card--zeroshot:hover {
  translate: 0 -6px;
  border-color: var(--techblue);
}

/* Legacy card — the export's opacity/grayscale wash fails AA on the copy;
   the muted look is carried by the icon colour + hairline border instead
   (text containers keep full opacity). */
.page-extraction__compare-card--legacy svg {
  width: 28px;
  height: 28px;
  color: var(--text-muted);
  flex: none;
}

.page-extraction__compare-card--legacy h3 {
  font-size: 14px;
  line-height: 20px;
  font-weight: 600;
  color: var(--ink);
}

.page-extraction__compare-card--legacy p {
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-muted);
}

/* Zeroshot card — 2px techblue frame. */
.page-extraction__compare-card--zeroshot {
  border-width: 2px;
  border-color: var(--techblue);
}

.page-extraction__compare-card--zeroshot svg {
  width: 28px;
  height: 28px;
  color: var(--techblue);
  flex: none;
}

/* 14px semibold techblue — 4.54:1 on white, passes AA. */
.page-extraction__compare-card--zeroshot h3 {
  font-size: 14px;
  line-height: 20px;
  font-weight: 600;
  color: var(--techblue);
}

.page-extraction__compare-card--zeroshot p {
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-muted);
}

/* Corner accent — 64px quarter circle in the top-right (decorative). */
.page-extraction__corner {
  position: absolute;
  top: 0;
  right: 0;
  width: 64px;
  height: 64px;
  background-color: rgba(43, 118, 210, .10); /* techblue tint */
  border-bottom-left-radius: 100%;
  pointer-events: none;
}

/* =========================================================================
   S3 — How it works (three centered columns)
   ========================================================================= */
.page-extraction__how h2 {
  font-size: 36px;
  line-height: 1.2;
  letter-spacing: -0.01em;
  font-weight: 600;
  color: var(--indigo);
  text-align: center;
  margin-bottom: var(--space-7);
}

@media (max-width: 767.98px) {
  .page-extraction__how h2 {
    margin-bottom: var(--space-5);
  }
}

/* The data-dp-reveal-stagger container. */
.page-extraction__how-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-5);
}

@media (max-width: 767.98px) {
  .page-extraction__how-grid {
    grid-template-columns: 1fr;
  }
}

.page-extraction__how-col {
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

/* Icon roundel — techblue on its own tint (icon-only accent). */
.page-extraction__how-icon {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background-color: rgba(43, 118, 210, .10); /* techblue tint */
  color: var(--techblue);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: var(--space-2);
  flex: none;
}

.page-extraction__how-icon svg {
  width: 28px;
  height: 28px;
  flex: none;
}

/* Numbered h3s are the sequence markers — kept verbatim in the markup. */
.page-extraction__how-col h3 {
  font-size: 18px;
  line-height: 1.4;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: var(--space-1);
}

.page-extraction__how-col p {
  font-size: 16px;
  line-height: 1.6;
  color: var(--text-muted);
}

/* =========================================================================
   S4 — Traceability band (the ONE obsidian section)
   ========================================================================= */
.page-extraction__trace {
  background-color: var(--obsidian);
  color: var(--white);
}

/* Focus on obsidian: the global 2px techblue ring is only 3.71:1 against
   the dark canvas — add a light halo so the ring reads everywhere. */
.page-extraction__trace :focus-visible {
  outline-color: var(--techblue);
  box-shadow: 0 0 0 4px rgba(255, 255, 255, .25); /* light halo on obsidian */
}

/* Centered header. */
.page-extraction__trace h2 {
  font-size: 36px;
  line-height: 1.2;
  letter-spacing: -0.01em;
  font-weight: 600;
  color: var(--white);
  text-align: center;
  max-width: 672px;
  margin-inline: auto;
  margin-bottom: var(--space-2);
}

.page-extraction__trace h2 + p {
  font-size: 16px;
  line-height: 1.6;
  color: var(--text-muted-dark);
  text-align: center;
  max-width: 672px;
  margin-inline: auto;
  margin-bottom: var(--space-5);
}

/* The paired-panels mock (carries data-dp-gradient-border). */
.page-extraction__panels,
.page-extraction [data-ext-trace] {
  position: relative;
  display: flex;
  background-color: rgba(255, 255, 255, .06); /* panel on obsidian */
  border: 1px solid var(--border-dark);
  border-radius: 12px; /* outranks .dp-gradient-border-active (later sheet) */
  overflow: hidden;
}

/* Panels — 50/50 on desktop. */
.page-extraction__panel--doc,
.page-extraction__panel--json {
  flex: 1 1 0;
  min-width: 0;
  padding: var(--space-3);
}

.page-extraction__panel--doc {
  border-right: 1px solid var(--border-dark);
}

.page-extraction__panel--json {
  display: flex;
  align-items: center;
  background-color: rgba(255, 255, 255, .04); /* darker inner panel on obsidian */
}

/* Connector — decorative dashed pairing line between the panels. Sits above
   the panel surfaces (z-index 1) but below the highlight spans (z-index 2). */
.page-extraction__connector {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 128px;
  height: 0;
  border-top: 2px dashed var(--techblue);
  transform: translate(-50%, -50%);
  z-index: 1;
  pointer-events: none;
  opacity: .8; /* resting — brightens while a pairing is active */
  transition: opacity .2s ease, filter .2s ease;
}

.page-extraction__connector.is-paired {
  opacity: 1;
  filter: brightness(1.3);
}

/* <1024 — panels stack; the connector becomes a short vertical dashed
   segment centered between them (order pins doc / connector / json). */
@media (max-width: 1023.98px) {
  .page-extraction__panels,
  .page-extraction [data-ext-trace] {
    flex-direction: column;
  }

  .page-extraction__panel--doc {
    order: -1;
    border-right: 0;
    border-bottom: 1px solid var(--border-dark);
  }

  .page-extraction__panel--json {
    order: 1;
  }

  .page-extraction__connector {
    position: static;
    width: 0;
    height: 32px;
    border-top: 0;
    border-left: 2px dashed var(--techblue);
    transform: none;
    margin: var(--space-2) auto;
  }
}

/* Source document card — light island resets the band's white text. */
.page-extraction__doc-card {
  background-color: var(--white);
  color: var(--ink);
  border-radius: 4px;
  padding: var(--space-3);
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.8;
}

/* Source highlight — warn fill + border on the light card; ink text keeps
   AA at both fill strengths. Focusable (tabindex) for the pairing. */
.page-extraction__hl-doc,
.page-extraction [data-ext-pair="doc"] {
  position: relative;
  z-index: 2; /* above the connector */
  background-color: rgba(245, 158, 11, .30); /* --warn tint */
  border: 1px solid var(--warn);
  border-radius: 4px;
  padding: 2px 4px;
  color: var(--ink);
  transition: background-color .2s ease;
}

.page-extraction__hl-doc.is-paired,
.page-extraction [data-ext-pair="doc"].is-paired {
  background-color: rgba(245, 158, 11, .45); /* --warn tint, emphasised */
}

/* JSON block — obsidian-on-obsidian code panel. */
.page-extraction__json {
  width: 100%;
  background-color: var(--obsidian);
  border: 1px solid var(--border-dark);
  border-radius: 4px;
  padding: var(--space-2);
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.8;
  color: var(--text-muted-dark); /* string/number values */
}

/* Keys pop in white against the muted values. */
.page-extraction__json-key {
  color: var(--white);
}

/* JSON highlight — techblue fill, white semibold value. */
.page-extraction__hl-json,
.page-extraction [data-ext-pair="json"] {
  position: relative;
  z-index: 2; /* above the connector */
  background-color: rgba(43, 118, 210, .20); /* techblue tint */
  border-radius: 4px;
  padding: 2px 4px;
  color: var(--white);
  font-weight: 600;
  transition: background-color .2s ease;
}

.page-extraction__hl-json.is-paired,
.page-extraction [data-ext-pair="json"].is-paired {
  background-color: rgba(43, 118, 210, .35); /* techblue tint, emphasised */
}

/* Score comment — muted, never the export gray (fails on obsidian). */
.page-extraction__json-comment {
  color: var(--text-muted-dark);
}

/* =========================================================================
   S5 — Two-up (Schemas, your way / Confidence & control)
   ========================================================================= */
.page-extraction__twoup-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-7);
}

/* Each column stacks; the mocks are pushed to the bottom (margin-top:auto)
   so the two panels bottom-align whatever the copy length. */
.page-extraction__twoup-col,
.page-extraction__twoup-grid > * {
  min-width: 0;
  display: flex;
  flex-direction: column;
}

@media (max-width: 1023.98px) {
  .page-extraction__twoup-grid {
    grid-template-columns: 1fr;
    gap: var(--space-5);
  }
}

/* headline-md (24/1.3/500) in Royal Indigo — does not scale down. */
.page-extraction__twoup h2 {
  font-size: 24px;
  line-height: 1.3;
  letter-spacing: normal;
  font-weight: 500;
  color: var(--indigo);
  margin-bottom: var(--space-2);
}

.page-extraction__twoup h2 + p {
  font-size: 16px;
  line-height: 1.6;
  color: var(--text-muted);
  margin-bottom: var(--space-3);
}

/* -------------------------------------------------------------------------
   Schema mock — nested tree
   ------------------------------------------------------------------------- */
.page-extraction__schema {
  margin-top: auto; /* bottom-aligns with the review mock */
  background-color: var(--gray);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-2);
}

.page-extraction__tree {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  font-family: var(--font-mono);
  font-size: 14px;
  line-height: 1.4;
  color: var(--ink);
}

.page-extraction__tree-row {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  min-width: 0;
}

.page-extraction__tree-row svg {
  width: 16px;
  height: 16px;
  color: var(--text-muted);
  flex: none;
}

/* Indent levels. */
.page-extraction__tree-row--l1 {
  margin-left: var(--space-2);
}

.page-extraction__tree-row--l2 {
  margin-left: var(--space-4);
  /* Darkened --techblue #276CC1: 4.89:1 on --gray — raw --techblue is
     4.23:1 at 14px mono and fails AA (same derivation as the .dp-btn
     primary hover in main.css). Icon keeps the brand --techblue (non-text). */
  color: #276CC1;
}

.page-extraction__tree-row--l2 svg {
  color: var(--techblue);
}

/* Type chip — mono microcopy on the darker tonal chip surface. */
.page-extraction__type {
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.4;
  font-weight: 500;
  background-color: var(--border); /* export surface-container-highest -> --border */
  color: var(--text-muted);
  padding: 2px 4px;
  border-radius: 4px;
  flex: none;
}

/* -------------------------------------------------------------------------
   Review mock — straight-through row + flagged row
   ------------------------------------------------------------------------- */
.page-extraction__review,
.page-extraction [data-ext-review] {
  margin-top: auto; /* bottom-aligns with the schema mock */
  background-color: var(--gray);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* Shared row shell — mono field rows. */
.page-extraction__review-row--ok,
.page-extraction__review-row--warn {
  background-color: var(--white);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: var(--space-1) 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  font-family: var(--font-mono);
  font-size: 14px;
  line-height: 1.4;
  color: var(--ink);
}

/* Right-hand cluster (chip + icon) in both rows — every non-first child
   except the sr-only status text (clip-hidden either way). */
.page-extraction__review-cluster,
.page-extraction__review-row--ok > :not(:first-child):not(.dp-visually-hidden),
.page-extraction__review-row--warn > :not(:first-child):not(.dp-visually-hidden) {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex: none;
}

/* Verified check icon — icon-only status (also announced via sr-only text). */
.page-extraction__review-row--ok svg {
  width: 16px;
  height: 16px;
  color: #0A7B56; /* darkened --ok — 5.28:1 on white (raw --ok fails) */
  flex: none;
}

/* Flagged row — warn border + status ring. */
.page-extraction__review-row--warn,
.page-extraction [data-ext-warn] {
  border-color: var(--warn);
  box-shadow: 0 0 0 1px rgba(245, 158, 11, .30); /* status ring, not elevation */
}

/* Key + flagged value stack (the warn row's first child wraps them). */
.page-extraction__review-col,
.page-extraction__review-row--warn > :first-child {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

/* Flagged value — a styled span (NOT an input: illustrative mock only);
   the underline suggests the editable field without the a11y trap. */
.page-extraction__review-value {
  display: block;
  font-family: var(--font-mono);
  font-size: 14px;
  line-height: 1.4;
  color: #946300; /* darkened --warn — raw --warn fails on white */
  border-bottom: 1px solid var(--border);
}

/* Decorative edit affordance — aria-hidden span, not a button (mock UI). */
.page-extraction__edit {
  width: 28px;
  height: 28px;
  background-color: var(--border);
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
}

.page-extraction__edit svg {
  width: 14px;
  height: 14px;
  color: var(--text-muted);
  flex: none;
}

/* =========================================================================
   S6 — Format strip
   ========================================================================= */
.page-extraction__formats {
  background-color: var(--white);
  border-block: 1px solid var(--border);
  padding-block: var(--space-5);
  text-align: center;
}

.page-extraction__formats-label {
  display: block;
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 1.4;
  font-weight: 500;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: var(--space-3);
}

/* The data-dp-reveal-stagger container. */
.page-extraction__format-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-5);
}

@media (max-width: 767.98px) {
  .page-extraction__format-row {
    gap: var(--space-3);
  }
}

/* Format chips — icon + mono label. Hover lifts via `translate` so it never
   fights the reveal's `transform`; the transition list keeps main.css's
   reveal pair and adds the lift. */
.page-extraction__format {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  font-family: var(--font-mono);
  font-size: 14px;
  line-height: 1.4;
  font-weight: 600;
  color: var(--text-muted);
  transition:
    opacity .6s ease,
    transform .6s ease,
    translate .18s ease;
}

.page-extraction__format:hover {
  translate: 0 -4px;
}

.page-extraction__format svg {
  width: 28px;
  height: 28px;
  flex: none;
}

/* =========================================================================
   S7 — Final CTA
   ========================================================================= */
.page-extraction__cta {
  text-align: center;
}

.page-extraction__cta h2 {
  font-size: 36px;
  line-height: 1.2;
  letter-spacing: -0.01em;
  font-weight: 600;
  color: var(--indigo);
  max-width: 768px;
  margin-inline: auto;
  margin-bottom: var(--space-3);
}

.page-extraction__cta h2 + p {
  font-size: 18px;
  line-height: 1.6;
  color: var(--text-muted);
  max-width: 672px;
  margin-inline: auto;
  margin-bottom: var(--space-5);
}

.page-extraction__cta .page-extraction__cta-row {
  justify-content: center;
}

/* =========================================================================
   Mobile type scale (<768) — 64->44 and 36->28 (two-up h2 stays 24)
   ========================================================================= */
@media (max-width: 767.98px) {
  .page-extraction__title {
    font-size: 44px;
    line-height: 1.1;
  }

  .page-extraction__treadmill h2,
  .page-extraction__how h2,
  .page-extraction__trace h2,
  .page-extraction__cta h2 {
    font-size: 28px;
    line-height: 1.2;
  }
}

/* =========================================================================
   Motion — entrance base states, one-shots (no-preference only)
   ========================================================================= */
@media (prefers-reduced-motion: no-preference) {

  /* Hero entrance — extraction.js adds .is-ready to the hero on init
     (double rAF); copy rises in with 0/80/160/240ms delays. */
  .page-extraction__hero .page-extraction__eyebrow,
  .page-extraction__hero .page-extraction__title,
  .page-extraction__hero .page-extraction__lead,
  .page-extraction__hero .page-extraction__cta-row {
    opacity: 0;
    transform: translateY(12px);
    transition:
      opacity .5s cubic-bezier(0.16, 1, 0.3, 1),
      transform .5s cubic-bezier(0.16, 1, 0.3, 1);
  }

  .page-extraction__hero .page-extraction__title {
    transition-delay: 80ms;
  }

  .page-extraction__hero .page-extraction__lead {
    transition-delay: 160ms;
  }

  .page-extraction__hero .page-extraction__cta-row {
    transition-delay: 240ms;
  }

  .page-extraction__hero.is-ready .page-extraction__eyebrow,
  .page-extraction__hero.is-ready .page-extraction__title,
  .page-extraction__hero.is-ready .page-extraction__lead,
  .page-extraction__hero.is-ready .page-extraction__cta-row {
    opacity: 1;
    transform: none;
  }

  /* Field cards — hidden until extraction.js staggers .is-visible onto each
     after the pulse beat (visible from the start under reduced motion
     because this base state only exists here). */
  .page-extraction__field,
  .page-extraction [data-ext-field] {
    opacity: 0;
    transition: opacity .5s ease;
  }

  /* Pulse dots — staggered opacity loop while the row is shown. */
  .page-extraction__pulse > *,
  .page-extraction [data-ext-pulse] > * {
    animation: dp-ext-dot 1.2s ease-in-out infinite;
  }

  .page-extraction__pulse > :nth-child(2),
  .page-extraction [data-ext-pulse] > :nth-child(2) {
    animation-delay: .2s;
  }

  .page-extraction__pulse > :nth-child(3),
  .page-extraction [data-ext-pulse] > :nth-child(3) {
    animation-delay: .4s;
  }

  /* Format chips — pop-in entrance rides main.js's reveal: the base state
     swaps the plain rise for scale(.96) + fade (the shown-state hook below
     restores scale(1)). */
  .page-extraction__format[data-dp-reveal] {
    transform: scale(.96);
  }

  /* Flagged review row — ONE soft opacity pulse (<=1s) when extraction.js
     adds .is-flagged on section reveal. */
  .page-extraction__review-row--warn.is-flagged,
  .page-extraction [data-ext-warn].is-flagged {
    animation: dp-ext-flag .9s ease-in-out 1;
  }
}

/* Shown-state class hooks (outside the media query: harmless no-ops when
   reduced motion already forces everything visible). */
.page-extraction__field.is-visible,
.page-extraction [data-ext-field].is-visible {
  opacity: 1;
}

.page-extraction__format.is-revealed {
  transform: none; /* scale(.96) -> 1 */
}

/* Keyframes (only ever attached inside the no-preference block above). */
@keyframes dp-ext-dot {
  0%,
  100% {
    opacity: .25;
  }

  50% {
    opacity: 1;
  }
}

@keyframes dp-ext-flag {
  0%,
  100% {
    opacity: 1;
  }

  50% {
    opacity: .55;
  }
}

/* =========================================================================
   Reduced motion — every animated element visible and static
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  .page-extraction__hero .page-extraction__eyebrow,
  .page-extraction__hero .page-extraction__title,
  .page-extraction__hero .page-extraction__lead,
  .page-extraction__hero .page-extraction__cta-row,
  .page-extraction__field,
  .page-extraction [data-ext-field],
  .page-extraction__format[data-dp-reveal] {
    opacity: 1;
    transform: none;
  }

  .page-extraction__pulse > *,
  .page-extraction [data-ext-pulse] > *,
  .page-extraction__review-row--warn.is-flagged,
  .page-extraction [data-ext-warn].is-flagged {
    animation: none;
  }

  /* The "thinking" pulse row is purely decorative — never shown. */
  .page-extraction__pulse,
  .page-extraction [data-ext-pulse] {
    display: none !important;
  }

  /* No hover lift — :hover included so this outweighs the hover rules.
     (The .is-paired pairing emphasis stays: an instant state change, not
     motion; main.css already kills its transitions globally.) */
  .page-extraction__compare-card--legacy,
  .page-extraction__compare-card--legacy:hover,
  .page-extraction__compare-card--zeroshot,
  .page-extraction__compare-card--zeroshot:hover,
  .page-extraction__format,
  .page-extraction__format:hover {
    translate: none;
  }
}

/* -------------------------------------------------------------------------
   Named markup hooks that intentionally carry no styles of their own:
   block-flow divs or text styled contextually by their parents. Named here
   so every markup class resolves in this sheet (build rule).
   ------------------------------------------------------------------------- */
.page-extraction__hero-copy,
.page-extraction__treadmill-copy,
.page-extraction__trace-header,
.page-extraction__doc-card-line,
.page-extraction__json-line,
.page-extraction__review-key,
.page-extraction__format-name,
.page-extraction__cta-sub {
  /* no-op: inherits/contextual */
}
