/* ==========================================================================
   THROUGHLINE — HOME
   Load order: fonts → base → motion → brand → home. Everything here overrides.

   Five component families the rebuilt homepage introduces:
     .hp     the product-led hero (replaces the photographic mesh hero)
     .lq     the live sample queue that IS the hero image
     .dist   the distribution view (PRD 7.4's third required chart)
     .px     the pricing teaser
     .dform  the demo request, carrying the ROI calculator's inputs

   No new colours, no new fonts, no hardcoded hex: everything below reads the
   tokens defined in brand.css so both themes and the validated chart hues come
   along for free.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. HERO — product-led
   The old hero was a near-black photograph, so it forced its own dark tokens.
   This one sits on the page ground and works in both themes untouched.
   LCP is now the headline text, not an image. Budget the payload by hand:
   Lighthouse will not warn you when the LCP moves to text.
   -------------------------------------------------------------------------- */
.hp {
  position: relative;
  isolation: isolate;
  padding-block: var(--sp-12) var(--sp-16);
  border-bottom: var(--rule) solid var(--border);
  overflow: clip;                       /* the aurora must never widen the page */
}
@media (min-width: 900px) {
  .hp { padding-block: var(--sp-20) var(--sp-24); }
}

.hp .aurora { z-index: -1; }

/* Mobile ranking, decided before any wider layout:
   eyebrow → headline → sub → proof number → actions → micro → queue.
   The queue is last on a phone because the words have to land first. */
.hp__grid { display: grid; gap: var(--sp-6); }
@media (min-width: 1024px) {
  .hp__grid {
    grid-template-columns: 5fr 7fr;     /* asymmetric, per the house grid */
    grid-template-areas:
      "tag   queue"
      "title queue"
      "lead  queue";
    align-items: start;
    column-gap: var(--sp-12);
    row-gap: var(--sp-5);
  }
  .hp__tag   { grid-area: tag; }
  .hp__title { grid-area: title; }
  .hp__lead  { grid-area: lead; }
  .hp__queue { grid-area: queue; align-self: center; }
}

/* SplitText wraps each line in an unclassed div with overflow: clip. At 0.85
   leading that clips descenders, so the g in "Nothing" lost its tail. 0.16em of
   room below each line keeps them whole, and is still less than the 110% start
   offset of the masked reveal so no cap-tops leak at t=0. The old hero had this
   rule; the rebuilt one uses a different class and never inherited it. */
.hp__title > div { padding-block: 0 0.16em; margin-block: 0 -0.16em; }
.hp__title {
  font-family: var(--font-display);
  font-size: var(--t-title);
  line-height: var(--lh-h1);
  letter-spacing: var(--tr-h1);
  font-weight: 800;
  text-wrap: balance;
  margin: 0;
}
/* The hero title shares the row with the queue, so it cannot take the full
   page scale: at --t-title's 96px ceiling it ran to five lines in a 5fr column
   and pushed both CTAs below the fold at 1440x950. Re-tuned for this column
   rather than shrinking the type everywhere. */
@media (min-width: 1024px) {
  .hp__title { font-size: clamp(3rem, 1rem + 3.6vw, 4.75rem); }
}
.hp__sub { font-size: var(--t-lead); line-height: 1.45; color: var(--muted); max-width: 42ch; }

.hp__lead { display: grid; gap: var(--sp-5); }
.hp__cta  { display: grid; gap: var(--sp-4); }

/* The one trust signal above the fold is a client-outcome number, not a
   compliance badge. A SOC 2 mark in a hero is wasted; the same claim next to a
   data-handling statement on /trust is decisive. */
.hp__proof {
  display: grid; gap: var(--sp-1);
  padding-top: var(--sp-4);
  border-top: var(--rule) solid var(--border);
}
.hp__num {
  font-size: clamp(2rem, 1.2rem + 3vw, 3rem);
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--fg);
  font-variant-numeric: tabular-nums lining-nums;
}
.hp__num > span { font-variant-numeric: inherit; }

.hp__actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
.hp__actions .btn { flex: 1 1 auto; justify-content: center; }
@media (min-width: 560px) { .hp__actions .btn { flex: 0 0 auto; } }
.hp__micro { color: var(--muted); }

/* --------------------------------------------------------------------------
   2. LIVE QUEUE — the hero artefact
   Real <table> markup computing real state from the rows beneath it. The
   counts in the strip are written by js/home.js from the same six shipments,
   and the static values in the HTML are already correct, so a script failure
   or a crawler sees the true numbers rather than zeroes.
   -------------------------------------------------------------------------- */
.lq {
  border: var(--rule) solid var(--border-strong);
  border-radius: var(--r-md);
  background: var(--surface);
  overflow: clip;
  /* Hairlines OR shadows, never both. This one is hairline. */
}

.lq__top {
  display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap;
  padding: var(--sp-3) var(--sp-4);
  border-bottom: var(--rule) solid var(--border);
  background: var(--surface-2);
}
.lq__crumb {
  font-family: var(--font-mono);
  font-size: var(--t-tag);
  letter-spacing: 0.06em;
  color: var(--muted);
}
.lq__tag { margin-inline-start: auto; }

.lq__strip {
  display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap;
  padding: var(--sp-4) var(--sp-4) var(--sp-3);
}
.lq__strip .chip b { margin-inline-start: 4px; font-weight: 500; }
.lq__open { margin-inline-start: auto; color: var(--muted); }
.lq__open b { color: var(--fg); font-weight: 500; }

.lq__t { width: 100%; border-collapse: collapse; font-size: 0.8125rem; }
.lq__t th, .lq__t td {
  text-align: left;
  padding: var(--sp-3) var(--sp-2);
  border-top: var(--rule) solid var(--border);
  white-space: nowrap;
}
.lq__t th:first-child, .lq__t td:first-child { padding-inline-start: var(--sp-4); }
.lq__t th:last-child,  .lq__t td:last-child  { padding-inline-end: var(--sp-4); text-align: right; }
.lq__t thead th {
  font-family: var(--font-mono);
  font-size: var(--t-tag);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  border-top: 0;
}
.lq__t tbody tr.is-hot td { background: var(--accent-wash); }
.lq__t tbody tr.is-hot td:first-child { box-shadow: inset 2px 0 0 var(--accent); }

/* Narrow phones: the two least load-bearing columns go, rather than shrinking
   the type or forcing the page to scroll sideways. The sr-only caption still
   describes the full data, and /platform shows every column. */
@media (max-width: 599px) {
  .lq__t .c-owner, .lq__t .c-lane { display: none; }
  .lq__t { font-size: 0.75rem; }
}

.lq__foot {
  padding: var(--sp-3) var(--sp-4) var(--sp-4);
  border-top: var(--rule) solid var(--border);
  color: var(--muted);
}

/* --------------------------------------------------------------------------
   3. DISTRIBUTION VIEW — PRD 7.4's third chart
   Identity is carried by the chip label in ink; the hue is a mark beside it,
   never the text. Bars are mark-only tokens, validated as a categorical set in
   both themes. A sibling sr-only table carries the same figures.
   -------------------------------------------------------------------------- */
.dist-card {
  margin: 0;
  padding: var(--sp-6);
  border: var(--rule) solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface);
  display: grid;
  gap: var(--sp-5);
  align-content: start;
}
.dist-card__tag { color: var(--muted); }

/* Chart-section placement lives in brand.css, next to .chart-sec__grid. */

.dist { display: grid; gap: var(--sp-4); }
.dist__row {
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  align-items: center;
  gap: var(--sp-3);
}
.dist__track {
  block-size: 10px;
  border-radius: var(--r-xs);
  background: color-mix(in oklab, var(--fg) 8%, transparent);
  overflow: clip;
}
.dist__bar {
  display: block;
  block-size: 100%;
  border-radius: var(--r-xs);
}
.dist__bar--late     { background: var(--hue-late); }
.dist__bar--short    { background: var(--hue-short); }
.dist__bar--misroute { background: var(--hue-misroute); }

/* Text wears text tokens, never the series colour. */
.dist__val { color: var(--fg); font-size: 0.9375rem; }
.dist__pct { color: var(--muted); font-size: 0.8125rem; min-inline-size: 4.5ch; text-align: right; }

@media (max-width: 479px) {
  .dist__row { grid-template-columns: auto 1fr auto; }
  .dist__pct { display: none; }          /* the sr-only table still has it */
}

/* Bars grow from zero once, on entry. transform only: animating width would
   count fully against CLS, because scroll gets no hadRecentInput grace. */
@supports (animation-timeline: view()) and (animation-range: 0% 100%) {
  @media (prefers-reduced-motion: no-preference) {
    .dist__bar {
      transform-origin: left center;
      animation: dist-grow linear both;
      animation-timeline: view();
      animation-range: entry 10% cover 34%;
    }
  }
}
@keyframes dist-grow { from { transform: scaleX(0.02); } to { transform: scaleX(1); } }

/* --------------------------------------------------------------------------
   4. PRICING TEASER — a ladder, not three identical cards
   The craft floor refuses symmetric three-up card rows, so these are rows on a
   shared hairline with the price set in mono at the end of each.
   -------------------------------------------------------------------------- */
.px__grid { row-gap: var(--sp-8); }
.px__rows { list-style: none; margin: 0; padding: 0; border-top: var(--rule) solid var(--border); }
.px__row {
  display: grid;
  gap: var(--sp-1) var(--sp-4);
  grid-template-columns: 1fr auto;
  grid-template-areas: "tag price" "name price" "for price";
  align-items: baseline;
  padding-block: var(--sp-5);
  border-bottom: var(--rule) solid var(--border);
}
.px__row > .tag { grid-area: tag; }
.px__name  { grid-area: name; font-family: var(--font-display); font-weight: 700; font-size: 1.25rem; letter-spacing: -0.02em; }
.px__for   { grid-area: for; color: var(--muted); font-size: 0.9375rem; max-width: 44ch; }
.px__price {
  grid-area: price;
  align-self: center;
  font-size: clamp(1.5rem, 1rem + 2vw, 2.25rem);
  line-height: 1;
  letter-spacing: -0.02em;   /* mono tabular figures track wide by default */
  font-variant-numeric: tabular-nums lining-nums;
  white-space: nowrap;
}
.px__price small { font-size: 0.5em; color: var(--muted); letter-spacing: 0; margin-inline-start: 2px; }
.px__note { margin-top: var(--sp-4); color: var(--muted); }

/* --------------------------------------------------------------------------
   5. DEMO REQUEST — four fields, carrying the calculator across
   The old form was one field submitting nowhere, which maximises raw
   submissions and gives sales nothing to route on, one click from a calculator
   that already collected the routing data.
   -------------------------------------------------------------------------- */
.demo__alt { color: var(--muted); margin-top: var(--sp-4); max-width: 44ch; }
.demo__alt a { color: var(--accent-text); text-underline-offset: 3px; }

.dform { display: grid; gap: var(--sp-4); }
@media (min-width: 640px) {
  .dform { grid-template-columns: 1fr 1fr; column-gap: var(--sp-4); }
  .dform__full, .dform__actions, .dform__carried { grid-column: 1 / -1; }
}
.dform__carried {
  padding: var(--sp-3) var(--sp-4);
  border: var(--rule) dashed color-mix(in oklab, var(--accent) 45%, transparent);
  border-radius: var(--r-sm);
  background: var(--accent-wash);
}
.dform__carried[hidden] { display: none; }
.dform__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3) var(--sp-4); }
.dform__actions .small { color: var(--muted); max-width: 34ch; }

/* --------------------------------------------------------------------------
   6. Reduced motion — replace, do not delete
   base.css floors every duration at 0.01ms so animationend still fires. The
   distribution bars must arrive at full width rather than sitting at 2%.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .dist__bar { animation: none !important; transform: none !important; }
}

/* --------------------------------------------------------------------------
   7. STORY WRAP — the grid min-content trap
   .story__frame is a grid and its .wrap child defaults to min-width: auto, so
   the wrap sized itself to the product mock's min-content (the mock forces
   .app__body to 760px so the table keeps its columns and scrolls inside
   .app__scroll). That pushed the whole page to 812px at a 320px viewport.
   The mock still scrolls horizontally inside its own container; only the page
   stops doing so.
   -------------------------------------------------------------------------- */
.story__frame > .wrap { min-width: 0; }
.story__frame .app { max-inline-size: 100%; }
