/* =========================================================
   platform-experience — v12
   ---------------------------------------------------------
   v12: §04 mobile rework. Alerts lead — the exception feed
   now sits ABOVE the KPI strip (demoted to supporting proof);
   reveal groups renumbered so staging still cascades top-to-
   bottom. On phone the Riverbend margin-risk card is the
   flagship (full weight, floated first via CSS order); the
   other three collapse their "why this surfaced" paragraph
   behind a native <details>, force-opened on desktop via
   @supports(::details-content). (v8–v11: §01–§03 mobile
   passes + cache bumps — see git log.)

   v7: §04 See What's Happening redesign. Replaces the old
   .surface.reporting + .workflow-bullets pulse-card with an
   exceptions-led close: KPI strip (4 tiles) + ordered feed
   of 4 exception cards (Birchwood / Riverbend / Crew 03 /
   R-410A), with the 4th arriving live +3000ms post section
   first-intersection. (v18: §04 no longer terminates the page —
   the shared .zc close now follows it as a sibling before the
   footer and carries id="access".) Severity hierarchy via 1/2/3 tick marks
   + border + background tint (no title size bump). Arrival
   treatment uses neutral bright-ink (NOT settlement-green —
   that color is reserved for §03 PAID semantic and would
   collide). Reveal cadence: data-reveal-step="200" × 5
   single-element groups = 1000ms total, matching §03's
   200ms inward register. Mock data preserves the page spine
   (Birchwood/Riverbend/Crew 03 carry from §02/§03). Drives
   the platform-watch.v1.js arrival timer.

   v6: §03 Get Paid redesign. Replaces the old .surface.invoice
   with a .gp-doc article — invoice as a permanent artifact,
   inward register vs §02's outward sweep. Riverbend's
   INV-7402-A is the live protagonist: a single-shot transition
   advances "CLEARING" → "CLEARED" + PAID stamp drop + recon
   note flip + balance-row state shift, fired by
   js/platform-getpaid.v1.js 1900ms after section first-
   intersection. CSS handles two of the spec §5 state changes
   via [data-gp-status] attribute-selector cascade (pip colour)
   and intentional non-mutation (balance amount stays
   $6,912.00 — settled, not zeroed).

   v5: §02 Run the Work redesign. Replaces the old dispatch
   .surface with a board (header in .shell, board outside
   .shell at max-width 1480px), 4 crews × 10 hour rows × 13
   jobs, Riverbend Family Practice as the live protagonist
   (EN ROUTE → ON SITE transition fired by
   js/platform-runwork.v1.js after section enters viewport).
   Mobile lanes render statically (no entrance animation).
   Reveal staging uses 3 display:contents wrappers inside
   .rw-board--desktop > .rw-grid only, per the per-element-
   index staging shape of platform-section-reveal.v1.js. See
   TECH-DEBT.md for the module v2 follow-up.

   v4: case-consistency pass on column 3 of the §01 workbench.
   The "Total" row label was uppercased while every sibling
   (Estimate sent, Viewed, Approved, Deposit) was sentence
   case — read as shouting, not as the unified ledger that
   column 3 should feel like. Total now drops to sentence
   case. Also: the column's internal handoff line collapses
   to JOB-id + arrow only, so the ceremonial band's
   APPROVED → DISPATCH announcement carries the page-level
   moment without column-level duplication.

   v3: adds the §01 "Win the Work" three-column workbench
   (Inbound → Intake → Approval) and the §01→§02 ceremonial
   handoff band. Both reveal via section-scoped group-staged
   IO observer (js/platform-section-reveal.v1.js).

   Workbench layout: 22/38/40 desktop, 18/38/44 tablet,
   single-column stack ≤767. No card chrome on columns —
   reads as one tabletop, not three banners. Approved row in
   column 3 is the §01 emotional payoff; ceremonial band is
   the page's first proof that "the record carries through."

   v8: removed the retired router-hero CSS cluster — .hero,
   .hero-map, .hero-operating-field, and all .router-* (the v1
   Operating Record Router + its Fix 6 "operating field"). That
   hero was retired when the Command Board hero (js/command-
   board-*.v1.js) replaced the platform hero; its markup + driver
   (js/platform-scenarios.v1.js) were already gone, so the CSS
   was dead. The live sections (workbench, §02–§04) begin below.

   Companion module: js/platform-section-reveal.v1.js
   (workbench + ceremonial band reveal staging). Keep field
   names + class names in sync.
   ========================================================= */

/* =========================================================
   WORKBENCH (v3 §01) — "Win the Work" three-column layout
   ---------------------------------------------------------
   Inbound (22%) · Intake (38%) · Approval (40%), gap 24px.
   Headers baseline-aligned via grid align-items:start +
   uniform header block model. No backgrounds, no borders,
   no shadows on columns — the workbench reads as one
   tabletop, not three cards.

   Tokens consumed from operating-layer.v2.css: --ink,
   --ink-sub, --ink-mute, --ink-faint, --signal-ink, --mono,
   --gutter, --maxw. Verified via token-graph grep.
   ========================================================= */

.workbench {
  /* Scoped tokens — defined here, consumed below.
     Kept on .workbench rather than :root so the v3 surface
     doesn't leak custom-property names into the global
     namespace. */
  --wb-col-gap: 24px;
  --wb-rule: rgba(255, 250, 240, 0.08);
  --wb-rule-ceremonial: rgba(255, 250, 240, 0.10);
  --wb-header-color: var(--ink-mute);
  --wb-reveal-duration: 250ms;
  --wb-reveal-step: 250ms;

  display: grid;
  /* fr units — gaps are subtracted from available width before
     distribution, so the columns never overflow. With straight
     percentages, 22+38+40=100% leaves no room for the 24px gaps
     and the rightmost column gets clipped by the scrollbar at
     narrow viewports. */
  grid-template-columns: 22fr 38fr 40fr;
  column-gap: var(--wb-col-gap);
  align-items: start;
  margin-top: 28px;
}

.workbench-col {
  /* min-width: 0 — grid overflow guard so long mono strings
     can't push the column wider than its track. */
  min-width: 0;
}

.workbench-header {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--wb-header-color);
  padding-bottom: 14px;
  margin-bottom: 16px;
  border-bottom: 1px solid var(--wb-rule);
  line-height: 1;
}

.workbench-rule {
  border: 0;
  border-top: 1px solid var(--wb-rule);
  margin: 16px 0;
  height: 0;
}

.workbench-sublabel {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin-bottom: 6px;
}

/* ---- Column 1 · INBOUND ----------------------------------
   Vertical list of six channels. Active channel gets a filled
   teal node + kicker line; inactive channels get outline marker
   + faint label. Renders "Zaras handles all of these channels,
   this job came through the first one" without copy.
   --------------------------------------------------------- */
.inbound-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.inbound-channel {
  display: grid;
  grid-template-columns: 14px 1fr;
  align-items: baseline;
  column-gap: 10px;
  row-gap: 2px;
}

.inbound-marker {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  border: 1px solid var(--ink-faint);
  background: transparent;
  justify-self: center;
  align-self: center;
}

.inbound-label {
  font-size: 13px;
  color: var(--ink-faint);
  line-height: 1.3;
}

.inbound-kicker {
  /* Only present on the active channel — second-row entry,
     col 2, mono timestamp + duration. */
  grid-column: 2;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  color: var(--ink-mute);
  font-variant-numeric: tabular-nums;
}

.inbound-channel.is-active .inbound-marker {
  background: var(--signal-ink);
  border-color: var(--signal-ink);
  box-shadow: 0 0 8px rgba(118, 199, 178, 0.35);
}
.inbound-channel.is-active .inbound-label {
  color: var(--ink-sub);
  font-weight: 500;
}

/* ---- Inbound resolve cue (v13) ----------------------------
   The Inbound column is intentionally sparse (6 short channels),
   so under the workbench's align-items:start it ended ~196px
   short of the Estimate column — a ragged left void. Stretch
   THIS column to the row height and pin a quiet "call → estimate"
   disposition to the baseline, paralleling col-3's JOB-7402
   handoff (inbound → record … → job bookend). No-op when the
   workbench stacks (≤767): single-column rows make align-self:
   stretch resolve to content height, and margin-top:auto → 0. */
.workbench-col--inbound {
  align-self: stretch;
  display: flex;
  flex-direction: column;
}
.inbound-resolve {
  margin-top: auto;
  padding-top: 14px;
  border-top: 1px solid var(--wb-rule);
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  line-height: 1.4;
  color: var(--ink-mute);
}
.inbound-resolve .ir-from { color: var(--ink-sub); }
.inbound-resolve .ir-arrow { color: var(--signal-ink); margin-right: 5px; }

/* ---- Column 2 · INTAKE -----------------------------------
   Identity / Issue / Metadata / AI-Intake. The AI-Intake
   block is the differentiator — teal label + 1px low-opacity
   left rule. Substance over loudness.
   --------------------------------------------------------- */
.intake-identity {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.intake-name {
  font-size: 17px;
  font-weight: 500;
  letter-spacing: -0.005em;
  line-height: 1.25;
  color: var(--ink);
}

.intake-addr {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-sub);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}

.intake-trade {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 2px;
  font-family: var(--mono);
  font-size: 11px;
}

.intake-trade .trade-chip {
  padding: 2px 8px;
  border-radius: 999px;
  background: rgba(118, 199, 178, 0.10);
  border: 1px solid rgba(118, 199, 178, 0.28);
  color: var(--signal-ink);
  font-size: 9.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  line-height: 1.4;
}

.intake-trade .trade-suffix {
  color: var(--ink-mute);
  font-size: 11px;
  letter-spacing: 0.04em;
}

.intake-issue p {
  margin: 0;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-sub);
}

.intake-meta {
  display: grid;
  grid-template-columns: 110px 1fr;
  row-gap: 8px;
  column-gap: 12px;
  margin: 14px 0 0;
  padding: 0;
}

.intake-meta-row {
  /* display: contents so dt/dd participate in the parent
     grid columns directly. */
  display: contents;
}

.intake-meta dt {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-mute);
  line-height: 1.5;
}

.intake-meta dd {
  margin: 0;
  font-size: 13px;
  color: var(--ink-sub);
  line-height: 1.5;
}

.intake-ai {
  border-left: 1px solid rgba(118, 199, 178, 0.22);
  padding-left: 12px;
}

.intake-ai .intake-ai-label {
  color: var(--signal-ink);
}

.intake-ai p {
  margin: 0;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-sub);
}

/* ---- Column 3 · ESTIMATE / APPROVAL ----------------------
   Line items, totals, three-row timeline, handoff line.
   Approved row is the §01 emotional payoff — slightly
   stronger text, teal checkmark, one-shot pulse keyed to
   reveal completion. Handoff line points right toward
   the ceremonial band.
   --------------------------------------------------------- */
.estimate-items {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.estimate-items li {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
  font-family: var(--mono);
  font-size: 13px;
  color: var(--ink-sub);
}

.estimate-items .ei-label {
  letter-spacing: 0.02em;
}

.estimate-items .ei-amt {
  color: var(--ink-sub);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  flex: 0 0 auto;
}

.estimate-totals {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.estimate-total,
.estimate-deposit {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
}

.estimate-total .et-label {
  /* Sentence case to match every other row in column 3
     (Estimate sent, Viewed, Approved, Deposit). Uppercasing
     "Total" alone read as shouting; sentence case across the
     column reads as a unified ledger. */
  font-size: 13px;
  color: var(--ink-sub);
  letter-spacing: 0.02em;
  font-family: var(--mono);
}
.estimate-total .et-amt {
  font-size: 17px;
  font-weight: 500;
  color: var(--ink);
  letter-spacing: -0.005em;
  font-variant-numeric: tabular-nums;
}
.estimate-deposit .et-label,
.estimate-deposit .et-amt {
  font-family: var(--mono);
  font-size: 12.5px;
  color: var(--ink-mute);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}

.estimate-timeline {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.estimate-timeline li {
  display: grid;
  grid-template-columns: 1fr auto 18px;
  gap: 12px;
  align-items: baseline;
}

.estimate-timeline .etl-label {
  font-size: 12.5px;
  color: var(--ink-sub);
  letter-spacing: 0.01em;
}

.estimate-timeline .etl-ts {
  font-family: var(--mono);
  font-size: 12.5px;
  color: var(--ink-mute);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  justify-self: end;
}

.estimate-timeline .etl-arrow {
  font-family: var(--mono);
  color: var(--ink-faint);
  font-size: 12.5px;
  justify-self: end;
}

.estimate-timeline .etl-approved .etl-label {
  color: var(--ink);
  font-weight: 500;
}
.estimate-timeline .etl-approved .etl-ts {
  color: var(--ink-sub);
}
.estimate-timeline .etl-approved .etl-check {
  color: var(--signal-ink);
  font-size: 14px;
  justify-self: end;
  line-height: 1;
  display: inline-block;
  transform-origin: center;
}

/* Approved checkmark one-shot pulse — fires after the
   approval column has fully revealed. Animation key + delay
   are tied to the group-3 reveal completion (group fades in
   over 250ms starting at +500ms; +200ms buffer = +950ms from
   section observe). Iteration count 1, no continuous motion. */
@keyframes wb-check-pulse {
  0%   { transform: scale(1);    filter: drop-shadow(0 0 0 rgba(118, 199, 178, 0)); }
  35%  { transform: scale(1.22); filter: drop-shadow(0 0 8px rgba(118, 199, 178, 0.6)); }
  70%  { transform: scale(1.06); filter: drop-shadow(0 0 4px rgba(118, 199, 178, 0.3)); }
  100% { transform: scale(1);    filter: drop-shadow(0 0 0 rgba(118, 199, 178, 0)); }
}
.workbench-col--approval.is-revealed .etl-approved .etl-check {
  animation: wb-check-pulse 600ms ease-out 200ms 1 both;
}

.estimate-handoff {
  /* v4: simplified to id + arrow only. The ceremonial band
     directly below carries "APPROVED → DISPATCH"; the column's
     internal handoff line is now just internal punctuation,
     not a competing announcement. */
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: 0.04em;
}

.estimate-handoff .eh-id {
  color: var(--signal-ink);
  font-variant-numeric: tabular-nums;
}
.estimate-handoff .eh-arrow {
  color: var(--signal-ink);
  font-size: 14px;
}

/* ---- Section header: scene label + proof chips ----------
   v9: replaces the former .workflow-microstat mono line
   (markup removed from all four heads in platform.html). The
   numbered scene label sits above the h2; three discrete proof
   chips sit below the intro. A single margin-top on the chip row
   reconciles the old per-section microstat margin overrides
   (runwork/getpaid/watch) — no per-section rule survives.
   v19: the eyebrow typography (.workflow-label / .workflow-label .n)
   moved to the shared css/section-eyebrow.v1.css and the markup
   now uses .section-eyebrow site-wide. The scene-label rule that
   lived here is gone — single-sourced, not duplicated.
   --------------------------------------------------------- */
.workflow-proof-chips {
  list-style: none;
  margin: 16px 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.workflow-proof-chip {
  display: inline-flex;
  align-items: baseline;
  padding: 5px 11px;
  border: 1px solid var(--rule);
  border-radius: 999px;
  font-family: var(--mono);
  font-size: 11px;
  line-height: 1;
  letter-spacing: 0.05em;
  color: var(--ink-sub);
  background: color-mix(in oklab, var(--ink) 3%, transparent);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ---- Section result line --------------------------------
   v9: one-sentence outcome after each section's artifact
   (§01–§04). A small signal dot marks it as a resolved state. */
.workflow-result {
  position: relative;
  margin: 32px 0 0;
  padding-left: 16px;
  max-width: 60ch;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-sub);
}
.workflow-result::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--signal);
  box-shadow: 0 0 6px var(--signal-weak);
}
.workflow-result strong {
  color: var(--signal);
  font-weight: 500;
}

/* =========================================================
   CEREMONIAL HANDOFF BAND (§01 → §02)
   ---------------------------------------------------------
   Audit-log entry feel — terse, accurate, slightly formal.
   No background fill, no shadow; thin top + bottom rules
   carry the "ceremonial" framing. The arrow is the only
   teal accent; the words stay mono ink-sub.

   Height target 64–72px desktop. The 1px rules + 24px
   vertical padding + ~24px inner row min-height lands at 72.

   Reveal: this band has its own data-reveal-section observer
   with data-reveal-delay="900". Timing is tied to the
   workbench's reveal sequence — see comment near the markup
   for the dependency note. The buffer keeps the band entering
   AFTER column 3's approved-check has settled.
   ========================================================= */
.handoff-ceremonial {
  --wb-rule-ceremonial: rgba(255, 250, 240, 0.10);
  margin: 48px 0;
  padding: 24px 0;
  border-top: 1px solid var(--wb-rule-ceremonial);
  border-bottom: 1px solid var(--wb-rule-ceremonial);
}

.handoff-ceremonial-row {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 24px;
  min-height: 24px;
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--ink-sub);
  font-variant-numeric: tabular-nums;
}

.handoff-ceremonial-row .hc-left {
  justify-self: start;
}
.handoff-ceremonial-row .hc-center {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  justify-self: center;
}
.handoff-ceremonial-row .hc-right {
  justify-self: end;
}
.handoff-ceremonial-row .hc-state {
  color: var(--ink-sub);
}
.handoff-ceremonial-row .hc-arrow {
  color: var(--signal-ink);
  opacity: 0.85;
  font-size: 13px;
}

/* =========================================================
   SECTION-SCOPED REVEAL — paired with
   js/platform-section-reveal.v1.js
   ---------------------------------------------------------
   Selector is scoped to descendants of [data-reveal-section]
   so it cannot collide with the global [data-reveal] used
   elsewhere on the page (different attribute).

   Initial state uses opacity + 8px translate — NOT
   display:none / height:0 — so columns reserve their final
   heights pre-reveal and no layout shift cascades during
   the 750ms staging window. (Test plan covers this.)
   ========================================================= */
[data-reveal-section] [data-reveal-group] {
  opacity: 0;
  transform: translate3d(0, 8px, 0);
  transition:
    opacity 250ms cubic-bezier(.2, .6, .1, 1),
    transform 250ms cubic-bezier(.2, .6, .1, 1);
  will-change: opacity, transform;
}
[data-reveal-section] [data-reveal-group].is-revealed,
[data-reveal-section] [data-reveal-group]:focus-within {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}

/* =========================================================
   v3 responsive
   ---------------------------------------------------------
   ≥1024 desktop : 22 / 38 / 40, gap 24px
   768–1023 tab  : 18 / 38 / 44, gap 18px
   ≤767 mobile   : single column stack, top divider per col
   ≤430 narrow   : intake-meta collapses to single column
   ========================================================= */
@media (max-width: 1023px) {
  .workbench {
    grid-template-columns: 18fr 38fr 44fr;
    --wb-col-gap: 18px;
    column-gap: 18px;
  }
  .handoff-ceremonial-row {
    font-size: 11px;
    gap: 18px;
  }
  .handoff-ceremonial-row .hc-left,
  .handoff-ceremonial-row .hc-right {
    font-size: 10.5px;
  }
}

@media (max-width: 767px) {
  .workbench {
    grid-template-columns: 1fr;
    row-gap: 24px;
  }
  .workbench-col + .workbench-col {
    border-top: 1px solid var(--wb-rule);
    padding-top: 20px;
  }
  .workbench-header {
    padding-bottom: 12px;
    margin-bottom: 14px;
  }
  .intake-meta {
    grid-template-columns: 130px 1fr;
  }

  /* Ceremonial band stacks to 3 lines. Three-line layout
     uses a 1-column grid; left and right cells get
     center-aligned via text-align since they're no longer
     justify-self:start/end participants. */
  .handoff-ceremonial {
    margin: 32px 0;
    padding: 20px 0;
  }
  .handoff-ceremonial-row {
    grid-template-columns: 1fr;
    row-gap: 6px;
    gap: 6px;
    text-align: center;
    font-size: 11px;
  }
  .handoff-ceremonial-row .hc-left,
  .handoff-ceremonial-row .hc-right {
    justify-self: center;
  }
  .handoff-ceremonial-row .hc-center {
    justify-self: center;
  }
}

@media (max-width: 430px) {
  .intake-name {
    font-size: 16px;
  }
  .intake-meta {
    grid-template-columns: 1fr;
    row-gap: 4px;
  }
  .intake-meta dt {
    margin-top: 6px;
  }
  .intake-meta-row:first-child dt {
    margin-top: 0;
  }
  .workflow-proof-chips {
    gap: 6px;
  }
  .workflow-proof-chip {
    font-size: 10.5px;
    padding: 4px 9px;
  }
  .handoff-ceremonial-row {
    font-size: 10.5px;
  }
}

/* =========================================================
   §01 MOBILE REWORK  (v10)
   ---------------------------------------------------------
   Desktop 3-column workbench is preserved. On phone the columns
   already stack (1fr ≤767px); this block makes the stack read as
   a SEQUENCE (Inbound → Intake → Estimate) and tames the Estimate
   "wall of numbers":
     · vertical flow connectors between stacked stages
     · Inbound collapsed to the active call + a "+5 channels" chip
     · Estimate line items behind a native <details> disclosure
   Shared DOM, no JS. The <details> is collapsed on phone and
   force-opened on desktop via ::details-content (below).
   ========================================================= */

/* Estimate line-items disclosure. Phone: native collapsed <details>,
   summary reads "5 lines · $8,640". Desktop: force open + hide the
   summary so the column is byte-for-byte the approved layout. */
.est-lines { margin: 0; }
.est-lines-summary {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; cursor: pointer; padding: 8px 0; list-style: none;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.04em;
  color: var(--ink-sub); -webkit-tap-highlight-color: transparent;
}
.est-lines-summary::-webkit-details-marker { display: none; }
.est-lines-summary::marker { content: ""; }
.est-lines-summary::after {
  content: "+"; color: var(--ink-mute); font-variant-numeric: tabular-nums;
  font-size: 13px; line-height: 1;
}
.est-lines[open] .est-lines-summary::after { content: "\2013"; } /* – when open */
.est-lines-k { text-transform: uppercase; letter-spacing: 0.08em; }
.est-lines-v { color: var(--ink); font-variant-numeric: tabular-nums; }

/* Desktop ≥768: line items always shown (preserve), summary hidden.
   Gated on ::details-content support so engines that lack it keep the
   summary visible+clickable instead of hiding the items entirely. */
@media (min-width: 768px) {
  @supports selector(::details-content) {
    .est-lines::details-content { content-visibility: visible; }
    .est-lines > summary { display: none; }
  }
}

/* The Inbound roll-up chip is phone-only (desktop renders the full list). */
.inbound-more { display: none; }

@media (max-width: 767px) {
  /* Stacked stages read as a sequence: a short vertical line + a down cue
     sits in the gap above stages 2 and 3 (not above the first). */
  .workbench-col { position: relative; }
  .workbench-col + .workbench-col { margin-top: 40px; }
  .workbench-col + .workbench-col::before {
    content: ""; position: absolute; left: 50%; top: -31px;
    width: 1px; height: 22px; transform: translateX(-50%);
    background: linear-gradient(to bottom, transparent, var(--signal));
  }
  .workbench-col + .workbench-col::after {
    content: "\2193"; /* ↓ */ position: absolute; left: 50%; top: -13px;
    transform: translateX(-50%); color: var(--signal);
    font-size: 12px; line-height: 1;
  }

  /* Inbound: show only the active call; roll the other five into a chip. */
  .inbound-channel:not(.is-active) { display: none; }
  .inbound-more {
    display: inline-flex; align-items: center; margin-top: 12px;
    padding: 5px 11px; border: 1px solid var(--rule); border-radius: 999px;
    font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.05em;
    color: var(--ink-mute);
  }
}

/* =========================================================
   v3 reduced motion
   ---------------------------------------------------------
   CSS-side belt-and-braces; the JS module also applies
   .is-revealed synchronously when the section first
   intersects. Keep both — users can toggle the OS
   preference between page load and scroll-in.
   ========================================================= */
@media (prefers-reduced-motion: reduce) {
  [data-reveal-section] [data-reveal-group] {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .workbench-col--approval .etl-approved .etl-check {
    animation: none !important;
  }
}


/* =============================================================
   §02 — Run the Work — v5
   -------------------------------------------------------------
   Board layout (header in .shell, board outside .shell at
   max-width 1480px), 4 crews × 10 hour rows × 13 jobs, Riverbend
   protagonist transitions EN ROUTE → ON SITE via
   js/platform-runwork.v1.js. Mobile lanes static.
   ============================================================= */

.workflow-runwork {
  --rw-board-bg: #0e0d0b;
  --rw-board-bg-soft: rgba(255, 250, 240, 0.012);
  --rw-rule: rgba(255, 250, 240, 0.085);
  --rw-rule-soft: rgba(255, 250, 240, 0.05);
  --rw-grid-line: rgba(255, 250, 240, 0.035);
  --rw-now-line: rgba(118, 199, 178, 0.45);
  --rw-now-line-glow: rgba(118, 199, 178, 0.12);

  --rw-c-onsite: var(--signal, #76c7b2);
  --rw-c-enroute: #e4c46b;
  --rw-c-hold:    #b06868;
  --rw-c-done:    var(--ink-faint, #3a3935);
  --rw-c-upcoming: var(--ink-mute, #a8a39a);

  --rw-bg-onsite:   rgba(118, 199, 178, 0.05);
  --rw-bg-enroute:  rgba(228, 196, 107, 0.06);
  --rw-bg-hold:     rgba(176, 104, 104, 0.05);
  --rw-bg-done:     rgba(255, 250, 240, 0.018);
  --rw-bg-upcoming: transparent;

  --rw-onsite-glow:
    0 0 0 1px rgba(118, 199, 178, 0.18),
    0 0 24px rgba(118, 199, 178, 0.18);

  padding-bottom: 88px;
}

.workflow-runwork .workflow-head {
  /* Header column lives inside .shell — keep narrative copy width
     constrained even though the board below breaks wider. */
  max-width: 64ch;
}

/* ---- BOARD WRAP -------------------------------------------- */
.rw-board-wrap {
  width: 100%;
  padding: 0 max(var(--gutter, 24px), calc((100vw - 1480px) / 2));
  margin-top: 48px;
  position: relative;
  z-index: 1; /* lift above .workflow-bg.bg-dispatch */
}

.rw-board {
  max-width: 1480px;
  margin: 0 auto;
  background: var(--rw-board-bg);
  border: 1px solid var(--rw-rule);
  border-radius: 4px;
  position: relative;
  overflow: hidden;
}

.rw-board--mobile { display: none; }

/* ---- BOARD HEAD -------------------------------------------- */
.rw-board-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 14px 20px;
  border-bottom: 1px solid var(--rw-rule);
  background: var(--rw-board-bg-soft);
}
.rw-board-head-l {
  display: inline-flex;
  align-items: baseline;
  gap: 16px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.rw-board-title {
  color: var(--ink-sub);
}
.rw-board-clock {
  color: var(--ink-mute);
  font-variant-numeric: tabular-nums;
}
.rw-board-legend {
  display: inline-flex;
  gap: 16px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-mute);
}
.rw-board-legend span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.rw-lg {
  width: 8px; height: 8px;
  border-radius: 2px;
  background: var(--ink-faint);
  display: inline-block;
}
.rw-lg-onsite  { background: var(--rw-c-onsite); }
.rw-lg-enroute { background: var(--rw-c-enroute); }
.rw-lg-hold    { background: var(--rw-c-hold); }
.rw-lg-done    { background: var(--rw-c-done); }

/* ---- GRID -------------------------------------------------- */
.rw-grid {
  display: grid;
  grid-template-columns: 72px repeat(4, minmax(0, 1fr));
  grid-template-rows: 32px repeat(10, 64px);
  gap: 0;
  position: relative;
  background-image:
    /* horizontal hour lines */
    linear-gradient(to bottom,
      transparent 32px,
      var(--rw-grid-line) 32px,
      var(--rw-grid-line) 33px,
      transparent 33px,
      transparent 96px,
      var(--rw-grid-line) 96px,
      var(--rw-grid-line) 97px,
      transparent 97px);
  background-size: 100% 64px;
  background-position: 0 0;
}

.rw-col-head {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-mute);
  padding: 9px 14px;
  border-bottom: 1px solid var(--rw-rule);
  border-right: 1px solid var(--rw-rule-soft);
  display: flex;
  align-items: center;
}
.rw-col-head:last-of-type { border-right: 0; }
.rw-col-head:first-of-type {
  background: var(--rw-board-bg-soft);
}

.rw-hour {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.06em;
  color: var(--ink-mute);
  padding: 8px 12px;
  border-right: 1px solid var(--rw-rule-soft);
  display: flex;
  align-items: flex-start;
  font-variant-numeric: tabular-nums;
}

/* ---- NOW-LINE — teal hairline above cells at 1:08 PM row -- */
.rw-nowline {
  height: 1px;
  background: var(--rw-now-line);
  align-self: start;
  margin-top: 8px; /* ~8min into the hour row */
  position: relative;
  z-index: 3; /* ABOVE cells (z-index 2) */
  box-shadow: 0 0 6px var(--rw-now-line-glow);
  pointer-events: none;
}
.rw-nowline-label {
  position: absolute;
  left: -64px;
  top: 14px;
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--rw-c-onsite);
  font-variant-numeric: tabular-nums;
  text-align: right;
  width: 56px;
}

/* ---- JOB CELLS --------------------------------------------- */
.rw-job {
  margin: 3px 4px;
  padding: 8px 11px 9px;
  border-radius: 3px;
  border: 1px solid var(--rw-rule);
  background: var(--rw-bg-done);
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-family: var(--sans);
  font-size: 12px;
  line-height: 1.35;
  position: relative;
  z-index: 2;
  overflow: hidden;
}
.rw-job-status {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-mute);
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.rw-status-pip {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--ink-faint);
  display: inline-block;
  flex-shrink: 0;
}
.rw-status-pip[data-state="onsite"]   { background: var(--rw-c-onsite); box-shadow: 0 0 0 2px rgba(118,199,178,0.18); }
.rw-status-pip[data-state="enroute"]  { background: var(--rw-c-enroute); }
.rw-status-pip[data-state="hold"]     { background: var(--rw-c-hold); }
.rw-status-pip[data-state="done"]     { background: var(--rw-c-done); }
.rw-status-pip[data-state="upcoming"] { background: var(--rw-c-upcoming); }

.rw-job-t {
  color: var(--ink);
  font-weight: 500;
  font-size: 12.5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.rw-job-m {
  color: var(--ink-sub);
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
}
.rw-job-money {
  color: var(--ink-mute);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.04em;
  font-variant-numeric: tabular-nums;
  margin-top: 1px;
}
.rw-tag {
  margin-left: 6px;
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.08em;
  color: var(--ink-mute);
  font-weight: 400;
  vertical-align: middle;
}

/* State modifiers */
.rw-job--done {
  opacity: 0.62;
  border-color: var(--rw-rule-soft);
}
.rw-job--done .rw-job-t { color: var(--ink-sub); }

.rw-job--enroute {
  background: var(--rw-bg-enroute);
  border-color: rgba(228, 196, 107, 0.22);
}
.rw-job--enroute .rw-job-status { color: var(--rw-c-enroute); }
.rw-job--enroute .rw-job-t { color: #f2dfa8; }

.rw-job--onsite {
  background: var(--rw-bg-onsite);
  border-color: rgba(118, 199, 178, 0.32);
  box-shadow: var(--rw-onsite-glow);
}
.rw-job--onsite .rw-job-status { color: var(--rw-c-onsite); }
.rw-job--onsite .rw-job-t { color: var(--signal-ink, #c5ebe0); }

.rw-job--hold {
  background: var(--rw-bg-hold);
  border-style: dashed;
  border-color: rgba(176, 104, 104, 0.28);
  opacity: 0.78;
}
.rw-job--hold .rw-job-status { color: #d8a3a3; }
.rw-job--hold .rw-job-t { color: #e8b5b5; }

.rw-job--upcoming {
  background: transparent;
  border-color: var(--rw-rule-soft);
  border-style: dashed;
  opacity: 0.78;
}
.rw-job--upcoming .rw-job-status { color: var(--rw-c-upcoming); }
.rw-job--upcoming .rw-job-t { color: var(--ink-sub); }

/* Compact modifier — used for single-row HOLD / UPCOMING cells that
   would otherwise lose their title to flex-shrink when the meta line
   wraps. Drops the standalone status line; inlines pip + state prefix
   into the title row so the cell renders as 2 lines fitting in 64px. */
.rw-job--compact { gap: 2px; }
.rw-job--compact .rw-job-status { display: none; }
.rw-job--compact .rw-job-t {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: nowrap;
  min-width: 0;
}
.rw-job--compact .rw-job-t .rw-status-pip {
  flex-shrink: 0;
}
.rw-job--compact .rw-state-prefix {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-mute);
  flex-shrink: 0;
}
.rw-job--compact .rw-job-customer {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
  flex: 1 1 auto;
}
.rw-job--hold.rw-job--compact     .rw-state-prefix { color: #d8a3a3; }
.rw-job--onsite.rw-job--compact   .rw-state-prefix { color: var(--rw-c-onsite); }
.rw-job--upcoming.rw-job--compact .rw-state-prefix { color: var(--rw-c-upcoming); }

/* SLA-tight inline chip */
.rw-sla-cluster { white-space: nowrap; }
.rw-sla-tag {
  display: inline-block;
  padding: 1px 5px;
  margin-right: 4px;
  background: rgba(228, 196, 107, 0.14);
  color: var(--rw-c-enroute);
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.1em;
  border-radius: 2px;
  font-variant-numeric: tabular-nums;
}

/* Travel-row indicator (Crew 01 12:30) */
.rw-travel {
  margin: 4px 6px;
  padding: 0 11px;
  height: 22px;
  align-self: center;
  border-top: 1px dashed var(--rw-rule-soft);
  border-bottom: 1px dashed var(--rw-rule-soft);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.04em;
  color: var(--ink-mute);
  font-variant-numeric: tabular-nums;
  opacity: 0.7;
  position: relative;
  z-index: 2;
}
.rw-travel-arr {
  color: var(--ink-faint);
}

/* Protagonist transition — CSS transitions for the class swap */
.rw-job[data-rw-protagonist] {
  transition:
    background-color 600ms ease,
    border-color 600ms ease,
    box-shadow 600ms ease;
}
.rw-job[data-rw-protagonist] .rw-status-pip {
  transition: background-color 600ms ease, box-shadow 600ms ease;
}

@keyframes rw-onsite-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(118, 199, 178, 0.42), var(--rw-onsite-glow); }
  60%  { box-shadow: 0 0 0 14px rgba(118, 199, 178, 0), var(--rw-onsite-glow); }
  100% { box-shadow: 0 0 0 0 rgba(118, 199, 178, 0), var(--rw-onsite-glow); }
}
.rw-job[data-rw-protagonist].rw-job--onsite.is-just-transitioned {
  animation: rw-onsite-pulse 700ms ease-out 1 both;
}

/* #2 (v14): persistent at-rest emphasis. Once the arrival animation settles,
   the protagonist would otherwise read identically to the other ON SITE cells
   (Pelham, Goldenrod), all sharing .rw-job--onsite. Out-weight it — stronger
   border, a crisper ring, a wider glow, a touch more fill — so the eye lands
   on the thread's focal job. Tasteful: same teal family, not a neon box.
   (Base --rw-onsite-glow is 0.18/24px with a 0.32 border.) */
.rw-job[data-rw-protagonist].rw-job--onsite {
  border-color: rgba(118, 199, 178, 0.62);
  background: rgba(118, 199, 178, 0.09);
  box-shadow:
    0 0 0 1.5px rgba(118, 199, 178, 0.38),
    0 0 30px rgba(118, 199, 178, 0.26);
}

/* ---- REVEAL INITIAL STATE ---------------------------------- */
/* Wrappers carry display:contents — initial state targets their
   .rw-job and .rw-travel descendants. */
.workflow-runwork .rw-board--desktop [data-reveal-group] > .rw-job,
.workflow-runwork .rw-board--desktop [data-reveal-group] > .rw-travel {
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 320ms ease, transform 320ms ease;
}
.workflow-runwork .rw-board--desktop [data-reveal-group].is-revealed > .rw-job,
.workflow-runwork .rw-board--desktop [data-reveal-group].is-revealed > .rw-travel {
  opacity: 1;
  transform: none;
}
/* Override default opacity for revealed --done cells so they
   don't fade into full opacity then drop back to 0.62 — keep
   the post-reveal opacity at the state's resting value. */
.workflow-runwork .rw-board--desktop [data-reveal-group].is-revealed > .rw-job--done {
  opacity: 0.62;
}
.workflow-runwork .rw-board--desktop [data-reveal-group].is-revealed > .rw-job--hold,
.workflow-runwork .rw-board--desktop [data-reveal-group].is-revealed > .rw-job--upcoming {
  opacity: 0.78;
}
.workflow-runwork .rw-board--desktop [data-reveal-group].is-revealed > .rw-travel {
  opacity: 0.7;
}

/* ---- MOBILE LANES (≤ 768px) -------------------------------- */
@media (max-width: 768px) {
  .workflow-runwork { padding-bottom: 56px; }
  .rw-board--desktop { display: none; }
  .rw-board--mobile  { display: block; }
  .rw-board-wrap { padding: 0 var(--gutter, 24px); margin-top: 32px; }
  .rw-board-head { padding: 12px 16px; }
  .rw-board-head-l { gap: 12px; }

  .rw-lane {
    border-top: 1px solid var(--rw-rule);
    padding: 14px 16px 16px;
  }
  .rw-lane:first-of-type { border-top: 0; }

  .rw-lane-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
    margin-bottom: 10px;
    flex-wrap: wrap;
  }
  .rw-lane-crew {
    font-family: var(--mono);
    font-size: 10.5px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--ink-sub);
  }
  .rw-lane-state {
    font-family: var(--mono);
    font-size: 10px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--rw-c-enroute);
    display: inline-flex;
    align-items: center;
    gap: 6px;
  }
  .rw-lane[data-rw-protagonist-lane] .rw-lane-state {
    color: var(--rw-c-enroute);
  }
  .rw-lane[data-rw-protagonist-lane] .rw-lane-state.is-onsite {
    color: var(--rw-c-onsite);
  }

  .rw-lane-jobs {
    list-style: none;
    padding: 0;
    margin: 0;
  }
  .rw-lane-job {
    display: grid;
    grid-template-columns: 48px 1fr;
    gap: 10px;
    padding: 10px 0;
    border-top: 1px solid var(--rw-grid-line);
  }
  .rw-lane-job:first-child { border-top: 0; }
  .rw-lane-job-time {
    font-family: var(--mono);
    font-size: 11px;
    letter-spacing: 0.04em;
    color: var(--ink-mute);
    font-variant-numeric: tabular-nums;
    padding-top: 1px;
  }
  .rw-lane-job-state {
    font-family: var(--mono);
    font-size: 9.5px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ink-mute);
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 4px;
  }
  .rw-lane-job-t {
    color: var(--ink);
    font-size: 13px;
    font-weight: 500;
    line-height: 1.3;
  }
  .rw-lane-job-m {
    color: var(--ink-sub);
    font-family: var(--mono);
    font-size: 10.5px;
    letter-spacing: 0.02em;
    margin-top: 2px;
    font-variant-numeric: tabular-nums;
  }
  .rw-lane-job-money {
    color: var(--ink-mute);
    font-family: var(--mono);
    font-size: 10px;
    margin-top: 2px;
    font-variant-numeric: tabular-nums;
  }
  .rw-lane-job--done       { opacity: 0.62; }
  .rw-lane-job--enroute    .rw-lane-job-state { color: var(--rw-c-enroute); }
  .rw-lane-job--onsite     .rw-lane-job-state { color: var(--rw-c-onsite); }
  .rw-lane-job--hold       .rw-lane-job-state { color: #d8a3a3; }
  .rw-lane-job--upcoming   .rw-lane-job-state { color: var(--rw-c-upcoming); }

  /* Protagonist mobile transition */
  .rw-lane-job[data-rw-protagonist] {
    transition:
      background-color 600ms ease,
      border-color 600ms ease,
      box-shadow 600ms ease;
  }

  /* #4 (v15): protagonist-first mobile. Four full crew lanes (13 cards) is too
     much narrative load on a phone, so collapse the three non-focal crews to a
     one-line summary (crew · live state · job count) — the header already
     carries the live state, the count keeps the busy-day credibility — while
     the Riverbend lane stays full and leads. The live protagonist card gets a
     persistent at-rest emphasis (teal fill + left accent), the mobile analogue
     of the desktop #2 treatment, so it out-reads the two done cards above it. */
  .rw-lane:not([data-rw-protagonist-lane]) .rw-lane-jobs { display: none; }
  .rw-lane:not([data-rw-protagonist-lane]) .rw-lane-head {
    justify-content: flex-start;
    margin-bottom: 0;
  }
  .rw-lane-count {
    font-family: var(--mono);
    font-size: 9.5px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ink-mute);
  }
  .rw-lane-job[data-rw-protagonist].rw-lane-job--onsite {
    margin: 2px -8px 0;
    padding: 10px 8px;
    background: rgba(118, 199, 178, 0.08);
    box-shadow: inset 3px 0 0 var(--rw-c-onsite);
    border-radius: 3px;
  }
}

@media (max-width: 430px) {
  .workflow-runwork .workflow-head h2 { font-size: 32px; }
  .rw-lane-head { gap: 4px; }
  .rw-board-head-l { flex-wrap: wrap; gap: 4px 12px; }
}

/* ---- §02 → §03 HANDOFF SIGNAL ------------------------------ */
.handoff-signal {
  padding: 28px 0 24px;
  background: transparent;
  border: 0;
}
.handoff-signal-line {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin: 0;
  opacity: 0;
  transition: opacity 600ms ease 100ms;
}
.handoff-signal.is-revealed .handoff-signal-line {
  opacity: 1;
}

/* ---- REDUCED MOTION ---------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .workflow-runwork .rw-board--desktop [data-reveal-group] > .rw-job,
  .workflow-runwork .rw-board--desktop [data-reveal-group] > .rw-travel {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .workflow-runwork .rw-board--desktop [data-reveal-group] > .rw-job--done {
    opacity: 0.62;
  }
  .workflow-runwork .rw-board--desktop [data-reveal-group] > .rw-job--hold,
  .workflow-runwork .rw-board--desktop [data-reveal-group] > .rw-job--upcoming {
    opacity: 0.78;
  }
  .workflow-runwork .rw-board--desktop [data-reveal-group] > .rw-travel {
    opacity: 0.7;
  }
  .rw-job[data-rw-protagonist],
  .rw-job[data-rw-protagonist] .rw-status-pip,
  .rw-lane-job[data-rw-protagonist] {
    transition: none !important;
  }
  .rw-job[data-rw-protagonist].rw-job--onsite.is-just-transitioned {
    animation: none !important;
  }
  .handoff-signal-line {
    opacity: 1 !important;
    transition: none !important;
  }
}


/* =============================================================
   §03 — Get Paid — v6
   -------------------------------------------------------------
   Settlement: invoice as permanent artifact. Inward register
   vs §02's outward sweep. One-shot transition advances
   "CLEARING" → "CLEARED" + PAID stamp drop + reconciliation
   note flip + balance-row state shift, fired by
   js/platform-getpaid.v1.js 1900ms after section first-
   intersection. CSS handles two of the spec §5 state changes
   via [data-gp-status] attribute cascade (pip colour) and
   intentional non-mutation (balance amount stays $6,912.00).
   ============================================================= */

.workflow-getpaid {
  --gp-doc-bg:        #11100d;
  --gp-doc-bg-elev:   #15140f;
  --gp-doc-rule:      rgba(255, 250, 240, 0.085);
  --gp-doc-rule-soft: rgba(255, 250, 240, 0.05);
  --gp-c-awaiting:    #e4c46b;
  --gp-c-paid:        var(--signal, #76c7b2);
  --gp-c-paid-soft:   rgba(118, 199, 178, 0.16);
  --gp-stamp-glow:    rgba(118, 199, 178, 0.28);
  padding-bottom: 88px;
}
.workflow-getpaid .workflow-getpaid-head { max-width: 64ch; }

/* .gp-doc — invoice card */
.gp-doc {
  margin-top: 48px;
  background: var(--gp-doc-bg);
  border: 1px solid var(--gp-doc-rule);
  border-radius: 4px;
  padding: 32px 36px 28px;
  position: relative;
}

/* Letterhead */
.gp-doc-letterhead {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding-bottom: 20px;
  border-bottom: 1px solid var(--gp-doc-rule);
}
.gp-doc-letterhead-l {
  display: flex;
  align-items: center;
  gap: 12px;
}
.gp-doc-mark {
  width: 28px; height: 28px;
  border-radius: 4px;
  background: var(--gp-doc-bg-elev);
  border: 1px solid var(--gp-doc-rule);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 600;
  color: var(--ink-sub);
  letter-spacing: 0.04em;
}
.gp-doc-issuer {
  font-size: 14px;
  color: var(--ink);
  letter-spacing: -0.005em;
}
.gp-doc-letterhead-r {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
  text-align: right;
}
.gp-doc-type {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-mute);
}
.gp-doc-id {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}

/* Meta strip */
.gp-doc-meta {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 28px;
  padding: 20px 0;
  border-bottom: 1px solid var(--gp-doc-rule);
}
.gp-doc-meta-cell {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.gp-doc-meta-k {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-label);
}
.gp-doc-meta-v {
  font-size: 13px;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
}

/* Status pip + text — driven by [data-gp-status] attribute cascade */
.gp-doc-status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  transition: color 600ms ease;
}
.gp-doc-status-pip {
  width: 8px; height: 8px;
  border-radius: 50%;
  display: inline-block;
  flex-shrink: 0;
  transition: background 600ms ease, box-shadow 600ms ease;
}
.gp-doc-status[data-gp-status="awaiting"] { color: var(--gp-c-awaiting); }
.gp-doc-status[data-gp-status="awaiting"] .gp-doc-status-pip {
  background: var(--gp-c-awaiting);
}
.gp-doc-status[data-gp-status="paid"] { color: var(--gp-c-paid); }
.gp-doc-status[data-gp-status="paid"] .gp-doc-status-pip {
  background: var(--gp-c-paid);
  box-shadow: 0 0 0 3px rgba(118, 199, 178, 0.2);
}

/* Events rail */
.gp-doc-events {
  padding: 18px 0 22px;
  border-bottom: 1px solid var(--gp-doc-rule);
}
.gp-events-rail {
  list-style: none;
  margin: 0; padding: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 4px;
  position: relative;
}
.gp-events-rail::before {
  content: "";
  position: absolute;
  top: 11px;
  left: 10px; right: 10px;
  height: 1px;
  background: var(--gp-doc-rule);
  z-index: 0;
}
.gp-event {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  padding: 0 12px 0 4px;
  position: relative;
  z-index: 1;
  background: var(--gp-doc-bg);
  min-width: 0;
}
.gp-event-pip {
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--ink-faint);
  border: 2px solid var(--gp-doc-bg);
  transition: background 600ms ease, box-shadow 600ms ease;
  margin-left: 4px;
}
.gp-event-k {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-mute);
  transition: color 600ms ease;
}
.gp-event-v {
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--ink-sub);
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
  transition: color 600ms ease;
}
.gp-event--done .gp-event-pip { background: var(--ink-mute); }
.gp-event--pending .gp-event-pip {
  background: var(--gp-c-awaiting);
  box-shadow: 0 0 0 2px rgba(228, 196, 107, 0.16);
  animation: gp-pending-pulse 2.4s ease-in-out infinite;
}
.gp-event--pending .gp-event-k { color: var(--gp-c-awaiting); }
.gp-event--cleared .gp-event-pip {
  background: var(--gp-c-paid);
  box-shadow: 0 0 0 2px var(--gp-c-paid-soft);
  animation: none;
}
.gp-event--cleared .gp-event-k { color: var(--gp-c-paid); }
.gp-event--cleared .gp-event-v { color: var(--ink); }
@keyframes gp-pending-pulse {
  0%, 100% { box-shadow: 0 0 0 2px rgba(228, 196, 107, 0.16); }
  50%      { box-shadow: 0 0 0 6px rgba(228, 196, 107, 0); }
}

/* Context */
.gp-doc-context {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 32px;
  padding: 22px 0;
  border-bottom: 1px solid var(--gp-doc-rule);
}
.gp-doc-billto, .gp-doc-jobctx {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.gp-doc-context-k {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-label);
  margin-bottom: 6px;
}
.gp-doc-context-v {
  font-size: 13px;
  color: var(--ink);
  letter-spacing: -0.005em;
}
.gp-doc-context-sub {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-sub);
  letter-spacing: 0.02em;
}

/* Line items */
.gp-doc-lines {
  padding: 20px 0;
  border-bottom: 1px solid var(--gp-doc-rule);
}
.gp-line {
  display: grid;
  grid-template-columns: 1fr 64px 88px 100px;
  gap: 16px;
  padding: 8px 0;
  align-items: baseline;
  font-size: 13px;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.gp-line > span:nth-child(2),
.gp-line > span:nth-child(3) {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink-sub);
  text-align: right;
  letter-spacing: 0.02em;
}
.gp-line > span:last-child {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--ink);
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.gp-line--head {
  border-bottom: 1px solid var(--gp-doc-rule-soft);
  padding-bottom: 10px;
  margin-bottom: 6px;
}
.gp-line--head > span {
  font-family: var(--mono) !important;
  font-size: 9.5px !important;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-label) !important;
}

/* Totals */
.gp-doc-totals {
  padding: 20px 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  border-bottom: 1px solid var(--gp-doc-rule);
  position: relative;
}
.gp-total-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 32px;
  align-items: baseline;
  padding-left: 50%;
}
.gp-total-row > span:first-child {
  font-size: 12.5px;
  color: var(--ink-mute);
  text-align: right;
  letter-spacing: 0.01em;
}
.gp-total-row > span:last-child {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  text-align: right;
  min-width: 108px;
}
.gp-total-row--grand {
  padding-top: 8px;
  border-top: 1px solid var(--gp-doc-rule-soft);
  margin-top: 4px;
}
.gp-total-row--grand > span:first-child {
  color: var(--ink);
  font-weight: 500;
}
.gp-total-row--grand > span:last-child {
  font-size: 15px;
}
.gp-total-row--deposit > span:last-child {
  color: var(--ink-sub);
}
.gp-total-row--balance > span:last-child {
  color: var(--gp-c-awaiting);
  transition: color 600ms ease;
}
/* Balance settled: colour shift only — strikethrough dropped per
   design feedback (strikethrough reads as cancelled / void, not
   settled). Color shift + label flip carry the state change. */
.gp-total-row--balance.is-cleared > span:first-child {
  color: var(--gp-c-paid);
}
.gp-total-row--balance.is-cleared > span:last-child {
  color: var(--gp-c-paid);
}

/* PAID stamp — anchored into the EMPTY LEFT HALF of .gp-doc-totals.
   The total rows are padding-left:50% (right-aligned figures), so the
   left half is open space — the stamp reads as stamped on the document
   without ever covering the Deposit/Balance figures (the payoff). Sits
   at the balance-row height, left side. (Was bottom-right, which landed
   ON TOP of the −$1,728 / $6,912 figures.) */
.gp-doc-stamp {
  position: absolute;
  bottom: 8px;
  left: 18px;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 9px 18px 6px;
  border: 2.5px solid var(--gp-c-paid);
  border-radius: 5px;
  color: var(--gp-c-paid);
  font-family: var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  transform: rotate(-6deg) scale(0.92);
  opacity: 0;
  pointer-events: none;
  transition:
    opacity 700ms ease 80ms,
    transform 700ms cubic-bezier(.34, 1.56, .64, 1) 80ms;
}
.gp-doc-stamp.is-stamped {
  opacity: 0.88;
  transform: rotate(-6deg) scale(1);
}
.gp-doc-stamp-text {
  font-size: 22px;
  font-weight: 600;
  line-height: 1;
}
.gp-doc-stamp-sub {
  font-size: 9px;
  letter-spacing: 0.18em;
  margin-top: 2px;
  opacity: 0.7;
}

/* Payment methods */
.gp-doc-methods {
  padding: 22px 0;
  border-bottom: 1px solid var(--gp-doc-rule);
}
.gp-doc-methods-k {
  display: block;
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-label);
  margin-bottom: 12px;
}
.gp-doc-methods-rail {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}
.gp-method {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 16px;
  border: 1px solid var(--gp-doc-rule);
  border-radius: 4px;
  background: var(--gp-doc-bg-elev);
  opacity: 0.5;
  transition: opacity 600ms ease, border-color 600ms ease, background 600ms ease;
}
.gp-method--active {
  opacity: 1;
  border-color: rgba(118, 199, 178, 0.32);
  background: rgba(118, 199, 178, 0.04);
}
.gp-method-mark {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  color: var(--ink-sub);
  padding: 2px 6px;
  background: rgba(255, 250, 240, 0.04);
  border-radius: 2px;
  align-self: flex-start;
  margin-bottom: 4px;
}
.gp-method--active .gp-method-mark--instant {
  color: var(--gp-c-paid);
  background: var(--gp-c-paid-soft);
}
.gp-method-label {
  font-size: 13px;
  color: var(--ink);
}
.gp-method-note {
  font-family: var(--mono);
  font-size: 10.5px;
  color: var(--ink-mute);
  letter-spacing: 0.02em;
  transition: color 600ms ease;
}
.gp-method--active .gp-method-note { color: var(--ink-sub); }
.gp-method--active.is-settled-fast .gp-method-note { color: var(--gp-c-paid); }

/* Reconciliation footer */
.gp-doc-recon {
  padding-top: 18px;
  display: flex;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
}
.gp-recon-l, .gp-recon-r {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.gp-recon-r { text-align: right; }
.gp-recon-k {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-label);
}
.gp-recon-v {
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-mute);
  letter-spacing: 0.02em;
  transition: color 600ms ease;
}
.gp-doc-recon.is-reconciled .gp-recon-l .gp-recon-v {
  color: var(--gp-c-paid);
}

/* Reveal initial state — 3 single-element groups */
.workflow-getpaid [data-reveal-group] {
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 320ms ease, transform 320ms ease;
}
.workflow-getpaid [data-reveal-group].is-revealed {
  opacity: 1;
  transform: none;
}

/* ---- Mobile (≤768px) ------------------------------ */
@media (max-width: 768px) {
  .workflow-getpaid { padding-bottom: 56px; }
  .gp-doc { padding: 24px 20px 22px; margin-top: 32px; }
  .gp-doc-letterhead {
    flex-direction: column;
    align-items: flex-start;
    gap: 14px;
    padding-bottom: 16px;
  }
  .gp-doc-letterhead-r {
    align-items: flex-start;
    text-align: left;
  }
  .gp-doc-meta {
    grid-template-columns: 1fr 1fr;
    gap: 16px 20px;
    padding: 16px 0;
  }
  .gp-events-rail {
    grid-template-columns: 1fr;
    gap: 10px;
  }
  .gp-events-rail::before {
    top: 6px; bottom: 6px;
    left: 9px; right: auto;
    width: 1px; height: auto;
  }
  .gp-event {
    flex-direction: row;
    align-items: baseline;
    gap: 10px;
    padding: 4px 0 4px 26px;
    position: relative;
  }
  .gp-event-pip {
    position: absolute;
    left: 4px;
    top: 4px;
    margin-left: 0;
  }
  .gp-event-v {
    margin-left: auto;
  }
  .gp-doc-context {
    grid-template-columns: 1fr;
    gap: 18px;
    padding: 18px 0;
  }
  .gp-line {
    grid-template-columns: 1fr auto;
    gap: 12px;
    padding: 10px 0;
    border-bottom: 1px dashed var(--gp-doc-rule-soft);
  }
  .gp-line:last-of-type { border-bottom: 0; }
  .gp-line > span:nth-child(2),
  .gp-line > span:nth-child(3) { display: none; }
  .gp-line--head { display: none; }
  .gp-total-row { padding-left: 0; }
  .gp-doc-stamp {
    bottom: 4px;
    left: 16px;
    right: auto;
    padding: 7px 14px 5px;
  }
  .gp-doc-stamp-text { font-size: 19px; }
  .gp-doc-methods-rail {
    grid-template-columns: 1fr;
    gap: 10px;
  }
  .gp-doc-recon {
    flex-direction: column;
    gap: 12px;
  }
  .gp-recon-r { text-align: left; }
}

@media (max-width: 430px) {
  .workflow-getpaid .workflow-getpaid-head h2 { font-size: 32px; }
  .gp-doc { padding: 20px 16px 18px; }
}

/* =========================================================
   §03 MOBILE REWORK  (v11)
   ---------------------------------------------------------
   Desktop invoice-as-artifact preserved. On phone the invoice
   read as a full accounting document and buried the climax
   (status → PAID). Lead with the payment beats, demote the
   document: 7 line items behind a native <details>, payment
   methods as a chip row (fee notes dropped), recon + bill-to/
   scope trimmed to one line, subtotal/tax rows hidden so Total /
   Deposit / Balance lead. Shared DOM, no JS. The status flip
   (platform-getpaid) is untouched — its data-gp-* targets all
   remain in the DOM.
   ========================================================= */
.gp-lines-disc { margin: 0; }
.gp-lines-summary {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; cursor: pointer; padding: 12px 0; list-style: none;
  border-top: 1px solid var(--gp-doc-rule);
  border-bottom: 1px solid var(--gp-doc-rule);
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.04em;
  color: var(--ink-sub); -webkit-tap-highlight-color: transparent;
}
.gp-lines-summary::-webkit-details-marker { display: none; }
.gp-lines-summary::marker { content: ""; }
.gp-lines-summary::after {
  content: "+"; color: var(--ink-mute); font-size: 13px; line-height: 1;
}
.gp-lines-disc[open] .gp-lines-summary::after { content: "\2013"; } /* – open */
.gp-lines-k { text-transform: uppercase; letter-spacing: 0.08em; }
.gp-lines-v { color: var(--ink); font-variant-numeric: tabular-nums; }

/* Desktop: line items always shown (preserve), summary hidden.
   @supports-gated so engines without ::details-content keep the
   summary clickable instead of hiding the rows. */
@media (min-width: 768px) {
  @supports selector(::details-content) {
    .gp-lines-disc::details-content { content-visibility: visible; }
    .gp-lines-disc > summary { display: none; }
  }
}

@media (max-width: 767px) {
  /* Bill-to / scope → one line each. */
  .gp-doc-context-sub { display: none; }
  /* Lead with Total / Deposit / Balance; hide the subtotal + tax
     detail rows — the collapsed line items carry that breakdown, so
     the totals block stays the three payment-relevant numbers. */
  .gp-doc-totals .gp-total-row:not(.gp-total-row--grand):not(.gp-total-row--deposit):not(.gp-total-row--balance) {
    display: none;
  }
  /* Payment methods → compact chip row; fee schedules dropped. */
  .gp-doc-methods-rail { display: flex; flex-wrap: wrap; gap: 8px; }
  .gp-method {
    flex-direction: row; align-items: center; gap: 8px;
    padding: 6px 11px; border-radius: 999px;
  }
  .gp-method-mark { margin-bottom: 0; align-self: center; }
  .gp-method-label { font-size: 12px; }
  .gp-method-note { display: none; }
  /* Reconciliation → single line (drop the ledger half; the result
     line below already names the ledger). */
  .gp-recon-r { display: none; }
}

/* §03 → §04 handoff mark — text-only single line */
.handoff-mark {
  padding: 28px 0 24px;
  background: transparent;
  border: 0;
}
.handoff-mark-line {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin: 0;
  opacity: 0;
  transition: opacity 600ms ease 100ms;
}
.handoff-mark.is-revealed .handoff-mark-line {
  opacity: 1;
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  .workflow-getpaid [data-reveal-group] {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .gp-doc-status-pip,
  .gp-event-pip,
  .gp-event-k,
  .gp-event-v,
  .gp-recon-v,
  .gp-method-note,
  .gp-total-row--balance > span:last-child {
    transition: none !important;
  }
  .gp-doc-stamp { transition: none !important; }
  .gp-event--pending .gp-event-pip { animation: none !important; }
  .handoff-mark-line {
    opacity: 1 !important;
    transition: none !important;
  }
}


/* =========================================================
   §04 — SEE WHAT'S HAPPENING
   ---------------------------------------------------------
   Scoped to .workflow-watch. KPI strip + exception feed +
   terminal close. Single new color: --w-sev-high (warm
   concern-orange). Trend-up green + settled-green reused
   from §03 palette discipline. Arrival treatment uses
   neutral bright-ink to avoid colliding with §03's PAID
   semantic. (v18: the terminal CTA moved OUT of §04 into the
   shared .zc close, a true sibling before the footer; §04 now
   ends at the margin-drift result line. id="access" lives on
   the .zc section, not here.)
   ========================================================= */
.workflow-watch {
  /* Scoped tokens */
  --w-card-bg:        rgba(255, 250, 240, 0.02);
  --w-card-bg-elev:   rgba(255, 250, 240, 0.035);
  --w-card-rule:      rgba(255, 250, 240, 0.09);
  --w-card-rule-strong: rgba(255, 250, 240, 0.16);

  --w-sev-high:       #d97a5f;  /* warm concern-orange — only new color introduced */
  --w-sev-med:        #d8a23c;  /* §02 EN ROUTE amber */
  --w-sev-watch:      rgba(255, 250, 240, 0.42);

  --w-trend-up:       #6db896;  /* settlement-green (KPI arrows only) */
  --w-trend-down:     #d97a5f;
  --w-trend-flat:     rgba(255, 250, 240, 0.42);

  /* Arrival treatment — neutral bright-ink, not settlement-green */
  --w-incoming-edge:  rgba(255, 250, 240, 0.55);
  --w-incoming-glow:  0 0 0 1px rgba(255, 250, 240, 0.32),
                      0 0 24px rgba(255, 250, 240, 0.10);

  padding-bottom: 96px;
}

/* HEADER BAND */
.workflow-watch-head { /* default block flow — label/h2/intro/chips stack */ }
.workflow-watch-head h2 {
  /* inherits .workflow h2 sizing from operating-layer.v5.css */
}

/* KPI STRIP — strip rule uses higher alpha than card-rule
   (0.14 vs 0.09) so the hairlines containing the strip read as
   "strip" not "loose tiles" at typical pixel density. */
.watch-kpis {
  --w-strip-rule: rgba(255, 250, 240, 0.14);
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0;
  margin-top: 32px;
  border-top: 1px solid var(--w-strip-rule);
  border-bottom: 1px solid var(--w-strip-rule);
}
.watch-kpi {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 20px 24px;
  border-right: 1px solid var(--w-strip-rule);
  min-width: 0;
}
.watch-kpi:last-child { border-right: 0; }
.watch-kpi-k {
  font: 9.5px/1 var(--mono);
  letter-spacing: 0.14em;
  color: var(--ink-label);
  text-transform: uppercase;
}
.watch-kpi-v {
  font: 500 22px/1 var(--sans);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}
.watch-kpi-trend {
  display: flex;
  align-items: center;
  gap: 6px;
  font: 11px/1 var(--mono);
  letter-spacing: 0.02em;
}
.watch-kpi-arrow {
  width: 0; height: 0;
  display: inline-block;
}
.watch-kpi-trend--up { color: var(--w-trend-up); }
.watch-kpi-trend--up .watch-kpi-arrow {
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-bottom: 5px solid var(--w-trend-up);
}
.watch-kpi-trend--down { color: var(--w-trend-down); }
.watch-kpi-trend--down .watch-kpi-arrow {
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid var(--w-trend-down);
}
.watch-kpi-trend--flat { color: var(--w-trend-flat); }
.watch-kpi-trend--flat .watch-kpi-arrow {
  width: 8px; height: 1px;
  background: var(--w-trend-flat);
}

/* FEED HEADER */
.watch-feed-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin: 40px 0 16px;
}
.watch-feed-k {
  font: 10px/1 var(--mono);
  letter-spacing: 0.14em;
  color: var(--ink-label);
  text-transform: uppercase;
}
.watch-feed-count {
  font: 11px/1 var(--mono);
  letter-spacing: 0.08em;
  color: var(--ink-mute);
}

/* EXCEPTION FEED */
.watch-feed {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.watch-card {
  background: var(--w-card-bg);
  border: 1px solid var(--w-card-rule);
  border-radius: 4px;
  padding: 20px 24px 18px;
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas:
    "head head"
    "body body"
    ".    foot";
  gap: 12px;
  position: relative;
}

/* Severity tiers — border + tint do the weight, NO title size bump */
.watch-card--high {
  border-color: rgba(217, 122, 95, 0.32);
  background: rgba(217, 122, 95, 0.025);
}
.watch-card--med {
  border-color: rgba(216, 162, 60, 0.22);
}
.watch-card--watch {
  /* baseline appearance */
}

.watch-card-head {
  grid-area: head;
  display: flex;
  align-items: center;
  gap: 12px;
  font: 10px/1 var(--mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.watch-card-sev {
  display: inline-flex;
  gap: 2px;
}
.watch-sev-tick {
  width: 3px;
  height: 10px;
  display: inline-block;
  border-radius: 1px;
  background: currentColor;
}
.watch-card--high .watch-card-sev { color: var(--w-sev-high); }
.watch-card--med  .watch-card-sev { color: var(--w-sev-med); }
.watch-card--watch .watch-card-sev { color: var(--w-sev-watch); }

.watch-card-kind { color: var(--ink-mute); }
.watch-card--high .watch-card-kind { color: var(--w-sev-high); }
.watch-card--med  .watch-card-kind { color: var(--w-sev-med); }

.watch-card-when {
  margin-left: auto;
  color: var(--ink-faint);
  font: 10px/1 var(--mono);
}

.watch-card-body {
  grid-area: body;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.watch-card-t {
  font: 500 15px/1.3 var(--sans);
  color: var(--ink);
  letter-spacing: -0.005em;
  margin: 0;
}
.watch-card-why {
  font: 13px/1.5 var(--sans);
  color: var(--ink-sub);
  margin: 0;
  max-width: 76ch;
}
.watch-card-action {
  display: flex;
  gap: 12px;
  font: 12px/1.4 var(--mono);
  margin: 4px 0 0;
}
.watch-card-action-k {
  color: var(--ink-label);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  flex-shrink: 0;
}
.watch-card-action-v {
  color: var(--ink-sub);
  letter-spacing: 0;
  font-family: var(--sans);
  font-size: 13px;
}

/* WHY DISCLOSURE — native <details> wrapping each SECONDARY card's
   "why this surfaced" paragraph. Collapsed on phone so the secondaries
   read as compact rows; force-open with the summary hidden on desktop
   so the full analysis reads as it always did. The flagship card has
   NO <details> — its why is a bare <p>, always visible. Mirrors the
   §03 gp-lines disclosure pattern. */
.watch-why { margin: 0; }
.watch-why .watch-card-why { margin-top: 8px; }
.watch-why-summary {
  display: inline-flex; align-items: center; gap: 7px;
  cursor: pointer; list-style: none; width: max-content;
  font: 10px/1 var(--mono); letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink-mute); padding: 2px 0;
  -webkit-tap-highlight-color: transparent;
}
.watch-why-summary::-webkit-details-marker { display: none; }
.watch-why-summary::marker { content: ""; }
.watch-why-summary::after {
  content: "+"; color: var(--ink-faint); font-size: 12px; line-height: 1;
}
.watch-why[open] .watch-why-summary::after { content: "\2013"; } /* – open */

/* Desktop: the analysis is always shown (preserve the full read), the
   summary hidden. @supports-gated so engines without ::details-content
   keep the summary clickable instead of permanently hiding the prose. */
@media (min-width: 768px) {
  @supports selector(::details-content) {
    .watch-why::details-content { content-visibility: visible; }
    .watch-why > summary { display: none; }
  }
  .watch-why .watch-card-why { margin-top: 0; }
}

.watch-card-foot {
  grid-area: foot;
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--ink-mute);
  font: 11px/1 var(--mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding-top: 4px;
}
.watch-card--high .watch-card-foot { color: var(--w-sev-high); }
.watch-card-route-chev {
  width: 0; height: 0;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  border-left: 5px solid currentColor;
  display: inline-block;
}

/* INCOMING CARD — arrival treatment, neutral bright-ink */
.watch-card--incoming {
  opacity: 0;
  transform: translateY(-8px);
  pointer-events: none;
}
.watch-card--incoming.is-arrived {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
  transition:
    opacity 600ms ease,
    transform 600ms cubic-bezier(0.34, 1.4, 0.64, 1);
  border-color: var(--w-incoming-edge);
  box-shadow: var(--w-incoming-glow);
  animation: w-incoming-settle 1800ms ease forwards;
}
@keyframes w-incoming-settle {
  0%   { box-shadow: 0 0 0 1px var(--w-incoming-edge), 0 0 32px rgba(255, 250, 240, 0.18); }
  100% { box-shadow: none; border-color: var(--w-card-rule); }
}
.watch-card-arrival {
  position: absolute;
  top: -1px;
  right: 16px;
  transform: translateY(-50%);
  padding: 3px 8px;
  background: rgba(255, 250, 240, 0.88);
  color: #0a0a08;
  font: 600 9.5px/1 var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  border-radius: 2px;
  opacity: 0;
  transition: opacity 400ms ease 600ms;
}
.watch-card--incoming.is-arrived .watch-card-arrival { opacity: 1; }
.watch-card--incoming.is-settled .watch-card-arrival {
  opacity: 0;
  transition: opacity 600ms ease;
}

/* TERMINAL CLOSE — the page-terminal CTA is now the shared .zc close
   (home-close.v5.css + access-close.v1.css), rendered as a true sibling
   before the footer. The old .watch-close / .watch-cta block was retired.

   Footer-gap adaptation: the home rule `.zc + .site-footer` (home-close.v5.css)
   can't match here — platform's footer is wrapped (<div class="shell"><footer>),
   so .zc's adjacent sibling is the .shell wrapper, not the footer. Re-target it
   to platform's DOM so the close out-weighs the footer (footer's own padding-top
   is 104px). Breakpoints mirror home-close.v5.css (72 / 56). */
.zc + .shell .site-footer { padding-top: 72px; }
@media (max-width: 960px) {
  .zc + .shell .site-footer { padding-top: 56px; }
}

/* REVEAL initial state — 5 single-element groups */
.workflow-watch [data-reveal-group] {
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 320ms ease, transform 320ms ease;
}
.workflow-watch [data-reveal-group].is-revealed {
  opacity: 1;
  transform: none;
}

/* MOBILE (≤768px) */
@media (max-width: 768px) {
  .workflow-watch { padding-bottom: 64px; }

  .watch-kpis { grid-template-columns: 1fr 1fr; }
  .watch-kpi {
    padding: 16px 18px;
    border-right: 1px solid var(--w-strip-rule);
    border-bottom: 1px solid var(--w-strip-rule);
  }
  .watch-kpi:nth-child(2),
  .watch-kpi:nth-child(4) { border-right: 0; }
  .watch-kpi:nth-child(3),
  .watch-kpi:nth-child(4) { border-bottom: 0; }
  .watch-kpi-v { font-size: 20px; }

  .watch-feed-head {
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
    margin: 28px 0 12px;
  }

  .watch-card {
    padding: 16px 18px 14px;
    grid-template-columns: 1fr;
    grid-template-areas:
      "head"
      "body"
      "foot";
  }
  .watch-card-head {
    flex-wrap: wrap;
    gap: 8px;
  }
  .watch-card-when {
    margin-left: 0;
    flex-basis: 100%;
    order: 3;
  }
  .watch-card-action {
    flex-direction: column;
    gap: 4px;
  }
  .watch-card-foot { justify-content: flex-start; }
}

/* MOBILE FEED — secondaries compact. Scoped <=767px so the 768px desktop
   force-open (above) never overlaps at the boundary. */
@media (max-width: 767px) {
  /* Margin-risk flagship leads the feed in DOM order on BOTH viewports (the
     card is source-first — no CSS order needed). On mobile it also gets a
     subtle bg lift so it reads as the lead alert in the single column. */
  .watch-card--flagship {
    background: var(--w-card-bg-elev);
  }

  /* Secondary cards = compact rows: conclusion first (headline + action),
     the "why" tucked behind its disclosure last. Timestamp + route foot
     dropped to keep them tight. The flagship keeps all of these. */
  .watch-card:not(.watch-card--flagship) .watch-card-action { order: 1; }
  .watch-card:not(.watch-card--flagship) .watch-why { order: 2; }
  .watch-card:not(.watch-card--flagship) .watch-card-when { display: none; }
  .watch-card:not(.watch-card--flagship) .watch-card-foot { display: none; }
}

/* REDUCED MOTION */
@media (prefers-reduced-motion: reduce) {
  .workflow-watch [data-reveal-group] {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .watch-card--incoming {
    opacity: 1 !important;
    transform: none !important;
    pointer-events: auto !important;
    animation: none !important;
    transition: none !important;
  }
  .watch-card-arrival {
    opacity: 1 !important;
    transition: none !important;
  }
}
