/* GENERATED FILE — do not edit.
   Source: brand/tokens.json · Regenerate: node brand/build-tokens.js
   components.css · tokens v2.0.0 (2026-07-30) */

/* The nine component families. One anatomy each, no local variants.
   Depends on tokens.css being loaded first. */

/* ---- section header & eyebrow -------------------------------------
   Eyebrow is always muted. Gold appears on exactly ONE section per page,
   the signature view, and when it does the heading stays ink. Emphasis comes
   from the eyebrow color and a thicker rule, never from washing out the head. */
.ts-section { max-width: 640px; }
.ts-section__eyebrow {
  border-top: var(--border-hairline, 1px) solid var(--line); padding-top: 14px;
  font-family: var(--font-sans); font-size: var(--fs-eyebrow); line-height: var(--lh-eyebrow);
  font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--muted);
}
.ts-section--signature .ts-section__eyebrow { border-top: 2px solid var(--gold); color: var(--gold-deep); }
.ts-section__head { font-family: var(--font-serif); font-size: var(--fs-section-head); line-height: var(--lh-section-head); font-weight: 600; color: var(--ink); margin-top: 10px; }
.ts-section__lede { font-family: var(--font-sans); font-size: var(--fs-body); line-height: var(--lh-body); color: var(--slate); margin-top: 8px; }

/* ---- KPI tile: one anatomy, four states --------------------------
   Fixed order, every time:
   eyebrow -> metric name -> figure -> delta -> sparkline -> one sentence of meaning.
   The italic serif sentence belongs in the meaning slot, never in place of the name. */
.ts-kpi { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-card); padding: var(--space-5); }
.ts-kpi__eyebrow { font-family: var(--font-sans); font-size: var(--fs-eyebrow); font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--muted); display: flex; align-items: center; gap: var(--space-1); }
.ts-kpi__name { font-family: var(--font-sans); font-size: var(--fs-label); line-height: var(--lh-label); font-weight: 600; color: var(--ink); margin-top: var(--space-2); }
.ts-kpi__name .ts-kpi__dir { font-weight: 400; color: var(--muted); }
.ts-kpi__row { display: flex; align-items: baseline; gap: var(--space-3); margin-top: 10px; }
.ts-kpi__figure { font-family: var(--font-serif); font-size: var(--fs-figure-x-l); line-height: var(--lh-figure-x-l); font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }
.ts-kpi__spark { height: 44px; margin-top: 14px; }
.ts-kpi__meaning { font-family: var(--font-sans); font-size: var(--fs-caption); line-height: 1.55; color: var(--muted); margin-top: 10px; }
.ts-kpi__meaning--serif { font-family: var(--font-serif); font-style: italic; font-size: 17px; color: var(--slate); }

/* ---- delta chip --------------------------------------------------
   Direction is carried by the ENCODING, not by a text suffix. A metric where
   lower is better still gets .is-favorable when it falls. Arrow + color +
   words, so it never depends on color alone. */
.ts-delta { display: inline-flex; align-items: center; gap: 5px; border-radius: var(--radius-chip); padding: 3px 9px; border: 1px solid; }
.ts-delta__val { font-family: var(--font-mono); font-size: 12.5px; font-variant-numeric: tabular-nums; }
.ts-delta.is-favorable { background: var(--favorable-bg); border-color: var(--favorable-line); color: var(--favorable); }
.ts-delta.is-adverse   { background: var(--adverse-bg);   border-color: var(--adverse-line);   color: var(--adverse); }
.ts-delta.is-flat      { background: var(--paper);        border-color: var(--line);           color: var(--muted); }

/* ---- buttons & controls ------------------------------------------
   One primary per screen. Focus is a 2px gold ring at 2px offset on every
   interactive element, no exceptions. */
.ts-btn { display: inline-flex; align-items: center; justify-content: center; font-family: var(--font-sans); font-size: 15px; font-weight: 600; border-radius: var(--radius-control); padding: 11px 20px; border: 1px solid; cursor: pointer; text-decoration: none; }
.ts-btn--primary { background: var(--ink-deep); border-color: var(--ink-deep); color: #fff; }
.ts-btn--primary:hover { background: var(--ink); border-color: var(--ink); }
.ts-btn--secondary { background: transparent; border-color: #C6BFB2; color: var(--ink); }
.ts-btn--secondary:hover { background: #F2EEE6; border-color: var(--gold); }
.ts-btn[disabled] { background: var(--line); border-color: var(--line); color: #9A9285; cursor: not-allowed; }
/* On the stone ground the primary inverts. Gold-fill-with-white-text measures
   2.56:1 and is not a button, it is a bug: gold is a decorative token. */
.ts-btn--primary-on-ink { background: var(--gold-light); border-color: var(--gold-light); color: var(--ink); }
.ts-btn--primary-on-ink:hover { background: #F6E2AF; border-color: #F6E2AF; }
.ts-btn--ghost-on-ink { background: transparent; border-color: rgba(255,255,255,.45); color: #fff; font-weight: 600; }
.ts-btn--ghost-on-ink:hover { border-color: var(--gold-light); color: var(--gold-light); }
.ts-link { color: var(--ink); font-weight: 600; text-decoration: none; border-bottom: 2px solid var(--gold); padding-bottom: 1px; }
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: var(--focus-ring) solid var(--focus-color); outline-offset: var(--focus-offset);
}
/* The selected segment is FILLED, not merely darker text. A light active state
   reads as disabled, which is the bug this replaces. */
.ts-segment { display: inline-flex; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-chip); padding: 3px; gap: 2px; }
.ts-segment button { border: 0; background: transparent; padding: 6px 14px; border-radius: var(--radius-chip); font-family: var(--font-sans); font-size: 13.5px; font-weight: 600; color: var(--muted); cursor: pointer; }
.ts-segment button[aria-selected="true"] { background: var(--ink); color: #fff; }

/* ---- logic-model pipeline ----------------------------------------
   No arrow glyphs. Adjacency plus the value ramp already says "sequence",
   and arrows are the first thing to break when this wraps on a phone or
   gets pasted into PowerPoint. */
.ts-pipeline { display: grid; grid-template-columns: repeat(4, 1fr); gap: 2px; }
.ts-pipeline__stage { background: var(--surface); border: 1px solid var(--line); border-right: none; padding: 18px var(--space-5); }
.ts-pipeline__stage:first-child { border-radius: var(--radius-card) 0 0 var(--radius-card); }
.ts-pipeline__stage:last-child { border-radius: 0 var(--radius-card) var(--radius-card) 0; border: 1px solid var(--ink); }
.ts-pipeline__n { font-family: var(--font-mono); font-size: 12px; color: #C6BFB2; }
.ts-pipeline__label { font-family: var(--font-sans); font-size: 12px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; margin-top: var(--space-2); color: var(--muted); }
.ts-pipeline__gloss { font-family: var(--font-sans); font-size: var(--fs-body-s); line-height: 1.5; color: var(--muted); margin-top: 6px; }
.ts-pipeline__ramp { height: 3px; border-radius: 2px; margin-top: 14px; background: var(--ramp1); }
.ts-pipeline__stage:nth-child(2) .ts-pipeline__ramp { background: var(--ramp2); }
.ts-pipeline__stage:nth-child(3) .ts-pipeline__ramp { background: var(--ramp3); }
.ts-pipeline__stage:nth-child(3) .ts-pipeline__gloss { color: var(--slate); }
.ts-pipeline__stage:last-child .ts-pipeline__n { color: var(--gold-deep); }
.ts-pipeline__stage:last-child .ts-pipeline__label,
.ts-pipeline__stage:last-child .ts-pipeline__gloss { color: var(--ink); }
.ts-pipeline__stage:last-child .ts-pipeline__gloss { font-weight: 600; }
.ts-pipeline__stage:last-child .ts-pipeline__ramp { background: var(--ink); }
/* The :first-child and :last-child radius rules above out-specify a bare
   .ts-pipeline__stage in a media query, so the stacked overrides have to match
   their specificity or the end stages keep their side-rounded desktop corners. */
@media (max-width: 899px) {
  .ts-pipeline { grid-template-columns: 1fr; }
  .ts-pipeline__stage,
  .ts-pipeline__stage:first-child,
  .ts-pipeline__stage:last-child { border: 1px solid var(--line); border-radius: var(--radius-card); }
  .ts-pipeline__stage:last-child { border-color: var(--ink); }
}

/* ---- data table: rules, not boxes -------------------------------
   No zebra striping. It fights the sparklines and prints badly.
   At most ONE clay cell per table: color in a data column means
   "this is the number the reader must not miss". */
.ts-table { width: 100%; border-collapse: collapse; }
.ts-table thead th { font-family: var(--font-sans); font-size: 12.5px; font-weight: 600; color: var(--ink); text-align: left; border-bottom: 1px solid #8A94A3; padding: 0 0 8px; }
.ts-table th.num, .ts-table td.num { text-align: right; font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.ts-table thead th.num { font-family: var(--font-sans); }
.ts-table tbody td { font-family: var(--font-sans); font-size: var(--fs-body-s); color: var(--slate); border-bottom: 1px solid #EFEAE0; padding: 9px 0; height: 40px; }
.ts-table tbody td.num { color: var(--ink); font-size: 13.5px; }
.ts-table--compact tbody td { height: 32px; padding: 5px 0; }
.ts-table tbody tr.is-total td { border-top: 2px solid #14263F; border-bottom: 0; color: var(--ink); font-weight: 600; padding-top: 10px; }
.ts-table td.is-flagged { color: var(--adverse); }
.ts-table__note { font-family: var(--font-sans); font-size: var(--fs-caption); color: var(--muted); margin-top: 12px; }

/* ---- charts ------------------------------------------------------
   Three types, that is the whole library: sparkline, column, line-with-baseline.
   Every chart carries a caption sentence. No gridlines except a single zero
   rule. Series labelled in place when two; a legend is a lookup task. */
.ts-chart { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-card); padding: var(--space-5); }
.ts-chart__title { font-family: var(--font-sans); font-size: var(--fs-label); font-weight: 600; color: var(--ink); margin-bottom: 14px; }
.ts-chart__axis { display: flex; justify-content: space-between; margin-top: 6px; font-family: var(--font-mono); font-size: 11.5px; color: var(--chart-axis); }
.ts-chart__caption { font-family: var(--font-sans); font-size: var(--fs-caption); line-height: 1.55; color: var(--muted); margin-top: 10px; }
.ts-chart__label-inline { font-family: var(--font-sans); font-size: 12px; font-weight: 600; background: var(--surface); padding: 1px 4px; }

/* ---- form fields -------------------------------------------------
   Real labels, not placeholder-as-label. Asking a stranger to compose a cold
   email is a bigger request than filling in three boxes, so the form has to
   look like three boxes. */
.ts-form { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-card); padding: 22px; display: flex; flex-direction: column; gap: 14px; }
.ts-field label { display: block; font-family: var(--font-sans); font-size: 13px; font-weight: 600; color: var(--ink); margin-bottom: 5px; }
.ts-field label .ts-field__opt { font-weight: 400; color: var(--muted); }
.ts-field input, .ts-field textarea {
  width: 100%; font-family: var(--font-sans); font-size: 15px; color: var(--ink);
  padding: 10px 12px; border: 1px solid var(--field-line);
  border-radius: var(--radius-control); background: var(--field-ground);
}
.ts-field textarea { resize: vertical; }
.ts-field input:focus-visible, .ts-field textarea:focus-visible { border-color: var(--gold-deep); background: var(--surface); }
.ts-form__fine { font-family: var(--font-sans); font-size: var(--fs-caption); color: var(--muted); line-height: 1.5; }

/* ---- tooltip: the one place a shadow is allowed ------------------ */
.ts-tooltip {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-control);
  box-shadow: var(--shadow-tooltip); padding: 10px 12px; max-width: 260px;
}
.ts-tooltip__head { font-family: var(--font-sans); font-size: var(--fs-eyebrow); font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--muted); }
.ts-tooltip__row { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin-top: 6px; }
.ts-tooltip__key { font-family: var(--font-sans); font-size: 13px; color: var(--slate); display: flex; align-items: center; gap: 6px; }
.ts-tooltip__swatch { width: 8px; height: 8px; border-radius: 2px; flex: none; }
.ts-tooltip__val { font-family: var(--font-mono); font-size: 13px; font-variant-numeric: tabular-nums; color: var(--ink); }
.ts-tooltip__note { font-family: var(--font-sans); font-size: 12px; line-height: 1.45; color: var(--muted); margin-top: 8px; }

/* ---- marketing cards: three variants of one shell --------------- */
.ts-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-card); padding: 22px; }
.ts-card__eyebrow { font-family: var(--font-sans); font-size: var(--fs-eyebrow); font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--muted); }
.ts-card--service .ts-card__eyebrow { color: var(--gold-deep); }
.ts-card__title { font-family: var(--font-serif); font-size: 26px; line-height: 1.2; font-weight: 600; color: var(--ink); margin-top: var(--space-2); }
.ts-card__body { font-family: var(--font-sans); font-size: 15px; line-height: 1.6; color: var(--slate); margin-top: 10px; }
.ts-card__foot { border-top: 1px solid var(--line-soft); margin-top: var(--space-4, 16px); padding-top: 12px; display: flex; gap: var(--space-2); align-items: baseline; }
/* Credential items are a ruled list, not cards. Five bordered boxes of bio
   text is a wall. */
.ts-creds { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-card); padding: 6px 22px; }
.ts-creds__row { display: flex; gap: 16px; padding: 14px 0; border-bottom: 1px solid var(--line-soft); }
.ts-creds__row:last-child { border-bottom: 0; }
.ts-creds__when { font-family: var(--font-mono); font-size: 13px; color: var(--gold-deep); width: 64px; flex: none; padding-top: 2px; }

/* ---- timeline rail: replaces the two-peer-cards + arrow band ----
   Two peer cards say "choose one". An arrow says "these are steps". The rail
   makes the sequence the layout, and the interstitial copy becomes a real node
   instead of an orphan with nowhere to sit on mobile. */
.ts-rail { display: grid; grid-template-columns: 130px 1fr; }
.ts-rail__meta { padding: 0 24px 0 0; text-align: right; border-right: 2px solid var(--line); }
.ts-rail__node:first-of-type + .ts-rail__meta, .ts-rail__meta.is-active { border-right-color: var(--ink); }
.ts-rail__when { font-family: var(--font-mono); font-size: 12px; color: var(--gold-deep); }
.ts-rail__dur { font-family: var(--font-sans); font-size: var(--fs-caption); color: var(--muted); margin-top: 4px; }
.ts-rail__node { padding: 0 0 32px 28px; position: relative; }
.ts-rail__dot { position: absolute; left: -7px; top: 4px; width: 12px; height: 12px; border-radius: var(--radius-chip); background: var(--ink); }
.ts-rail__dot--fork { left: -6px; top: 5px; width: 10px; height: 10px; background: var(--paper); border: 2px solid var(--gold); }
.ts-rail__dot--end { background: var(--gold); }
.ts-rail__title { font-family: var(--font-serif); font-size: 26px; line-height: 1.2; font-weight: 600; color: var(--ink); }
.ts-rail__body { font-family: var(--font-sans); font-size: var(--fs-body); line-height: var(--lh-body); color: var(--slate); margin-top: var(--space-2); max-width: 600px; }
.ts-rail__fork { font-family: var(--font-serif); font-size: 19px; line-height: 1.45; font-style: italic; color: var(--slate); max-width: 600px; }
@media (max-width: 899px) {
  .ts-rail { grid-template-columns: 1fr; }
  .ts-rail__meta { text-align: left; border-right: 0; border-left: 2px solid var(--line); padding: 0 0 6px 28px; }
  .ts-rail__node { border-left: 2px solid var(--line); padding-left: 28px; }
}

/* ---- nav & footer ----------------------------------------------- */
.ts-nav { background: var(--surface); border-bottom: 1px solid var(--line); padding: 16px 24px; display: flex; align-items: center; justify-content: space-between; gap: 24px; }
.ts-nav__brand { font-family: var(--font-serif); font-size: 19px; font-weight: 600; color: var(--ink); letter-spacing: .01em; text-decoration: none; }
.ts-nav a { font-family: var(--font-sans); font-size: 14.5px; color: var(--slate); text-decoration: none; }
.ts-nav a[aria-current="page"] { color: var(--ink); border-bottom: 2px solid var(--gold); padding-bottom: 2px; }
.ts-footer { background: var(--ink-deep); padding: 24px; display: flex; align-items: center; justify-content: space-between; gap: 24px; }
.ts-footer, .ts-footer a { font-family: var(--font-sans); font-size: 13.5px; color: #B9C4D1; }
.ts-footer strong { color: #fff; font-weight: 600; }

/* ---- every card grid collapses to ONE column below the breakpoint.
        No two-up squeeze. ---------------------------------------- */
@media (max-width: 899px) {
  .ts-grid-2, .ts-grid-3, .ts-grid-4 { grid-template-columns: 1fr !important; }
}
