/* ===========================================================================
   Tessen — payment infrastructure template
   ---------------------------------------------------------------------------
   Design tokens are the single source of truth. Every colour on this page
   resolves through a custom property declared in :root. If you need a new
   colour, add a token here rather than writing a hex value inline.
   =========================================================================== */

:root {
  /* ---- colour ---- */
  --ts-bg-primary: #F6F8FB;
  --ts-bg-secondary: #EDF0F5;
  --ts-bg-deep: #16181D;
  --ts-text-primary: #16181D;
  --ts-text-secondary: #5A6070;
  --ts-line: #D8DDE6;
  --ts-accent: #0F6E58;

  /* ---- type ---- */
  --ts-font-display: "Manrope", system-ui, sans-serif;
  --ts-font-body: "Manrope", system-ui, sans-serif;
  --ts-font-mono: "IBM Plex Mono", ui-monospace, monospace;

  --ts-fs-1: 12px;
  --ts-fs-2: 13px;
  --ts-fs-3: 15px;
  --ts-fs-4: 17px;
  --ts-fs-5: 22px;
  --ts-fs-6: 30px;
  --ts-fs-7: 44px;
  --ts-fs-8: 64px;

  /* ---- shape ---- */
  --ts-radius-0: 0px;
  --ts-radius-1: 2px;

  /* ---- space ---- */
  --ts-space-sm: 80px;
  --ts-space-lg: 140px;
  --ts-gutter: 24px;
  --ts-shell: 1512px;

  /* ---- motion ---- */
  --ts-dur-hero: 1s;
  --ts-dur-section: 0.7s;
  --ts-dur-micro: 0.25s;
  --ts-ease: cubic-bezier(0.25, 0.46, 0.45, 0.94); /* power2.out equivalent */

  /* ---- resolved surface (overridden per tone below) ---- */
  --sf-bg: var(--ts-bg-primary);
  --sf-fg: var(--ts-text-primary);
  --sf-muted: var(--ts-text-secondary);
  --sf-line: var(--ts-line);
  --sf-accent: var(--ts-accent);
  --sf-panel: var(--ts-bg-secondary);
  --sf-ink: var(--ts-bg-primary);
}

/* ---------------------------------------------------------------------------
   Tone engine. A section declares its own tone and every descendant reads the
   resolved --sf-* surface set. Light carries the page; deep is the accent.
   Derived values use color-mix so no colour escapes the token set above.
   --------------------------------------------------------------------------- */
[data-ts-tone="light"] {
  --sf-bg: var(--ts-bg-primary);
  --sf-fg: var(--ts-text-primary);
  --sf-muted: var(--ts-text-secondary);
  --sf-line: var(--ts-line);
  --sf-accent: var(--ts-accent);
  --sf-panel: var(--ts-bg-secondary);
  --sf-ink: var(--ts-bg-primary);
}

[data-ts-tone="deep"] {
  --sf-bg: var(--ts-bg-deep);
  --sf-fg: var(--ts-bg-primary);
  --sf-muted: color-mix(in oklab, var(--ts-bg-primary) 66%, var(--ts-bg-deep));
  --sf-line: color-mix(in oklab, var(--ts-bg-primary) 22%, var(--ts-bg-deep));
  --sf-accent: color-mix(in oklab, var(--ts-accent) 46%, var(--ts-bg-primary));
  --sf-panel: color-mix(in oklab, var(--ts-bg-primary) 7%, var(--ts-bg-deep));
  --sf-ink: var(--ts-bg-deep);
}

/* ===========================================================================
   Base
   =========================================================================== */
*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--ts-bg-primary);
  color: var(--ts-text-primary);
  font-family: var(--ts-font-body);
  font-size: var(--ts-fs-4);
  line-height: 1.6;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}

img,
video { display: block; max-width: 100%; height: auto; }

a { color: inherit; }

button,
input { font: inherit; color: inherit; }

h1, h2, h3, h4, p, figure, ul, ol, dl, dd { margin: 0; }
ul, ol { padding: 0; list-style: none; }

:focus-visible {
  outline: 2px solid var(--sf-accent);
  outline-offset: 3px;
}

::selection { background: var(--ts-accent); color: var(--ts-bg-primary); }

.ts-skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 12px 18px;
  background: var(--ts-bg-deep);
  color: var(--ts-bg-primary);
}
.ts-skip:focus { left: 12px; top: 12px; }

/* ===========================================================================
   Layout primitives
   =========================================================================== */
.ts-shell {
  width: 100%;
  max-width: var(--ts-shell);
  margin: 0 auto;
  padding-inline: var(--ts-gutter);
}

.ts-zone {
  position: relative;
  background: var(--sf-bg);
  color: var(--sf-fg);
  padding-block: var(--ts-space-lg);
  transition: background var(--ts-dur-section) var(--ts-ease),
              color var(--ts-dur-section) var(--ts-ease);
}

.ts-zone--tight { padding-block: var(--ts-space-sm); }

.ts-kicker {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--ts-font-mono);
  font-size: var(--ts-fs-1);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--sf-accent);
}
.ts-kicker::before {
  content: "";
  width: 22px;
  height: 1px;
  background: currentColor;
}

.ts-heading {
  font-family: var(--ts-font-display);
  font-weight: 600;
  letter-spacing: -0.025em;
  text-wrap: balance;
}

.ts-h1 { font-size: clamp(var(--ts-fs-7), 5.2vw, var(--ts-fs-8)); line-height: 1.06; }
.ts-h2 { font-size: clamp(var(--ts-fs-6), 3.4vw, var(--ts-fs-7)); line-height: 1.12; }
.ts-h3 { font-size: clamp(var(--ts-fs-5), 2.1vw, var(--ts-fs-6)); line-height: 1.2; }

.ts-lede {
  font-size: clamp(var(--ts-fs-4), 1.35vw, var(--ts-fs-5));
  line-height: 1.62;
  color: var(--sf-muted);
  max-width: 58ch;
  text-wrap: pretty;
}

.ts-note {
  font-size: var(--ts-fs-3);
  line-height: 1.68;
  color: var(--sf-muted);
  text-wrap: pretty;
}

.ts-tag {
  font-family: var(--ts-font-mono);
  font-size: var(--ts-fs-1);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--sf-muted);
}

/* section header: label column on the left, statement on the right */
.ts-masthead {
  display: grid;
  grid-template-columns: minmax(0, 3fr) minmax(0, 9fr);
  gap: var(--ts-gutter);
  align-items: start;
  padding-bottom: 56px;
  border-bottom: 1px solid var(--sf-line);
  margin-bottom: 56px;
}
.ts-masthead__body { display: grid; gap: 20px; max-width: 62ch; }

/* ===========================================================================
   Buttons
   =========================================================================== */
.ts-btn {
  --btn-fg: var(--sf-ink);
  --btn-bg: var(--sf-accent);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 48px;
  padding: 0 22px;
  border: 1px solid var(--btn-bg);
  border-radius: var(--ts-radius-1);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-size: var(--ts-fs-3);
  font-weight: 600;
  letter-spacing: -0.01em;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--ts-dur-micro) var(--ts-ease),
              border-color var(--ts-dur-micro) var(--ts-ease);
}
.ts-btn:hover { background: color-mix(in oklab, var(--sf-accent) 84%, var(--sf-ink)); }

.ts-btn--quiet {
  --btn-bg: transparent;
  --btn-fg: var(--sf-fg);
  border-color: var(--sf-line);
}
.ts-btn--quiet:hover {
  background: transparent;
  border-color: var(--sf-fg);
}

.ts-btn--wide { width: 100%; }

/* ===========================================================================
   Navigation
   TODO(nav-pending): the navigation scene component has not been sourced yet.
   What ships here is the token translation of the base header only. Replace
   the markup inside <header class="ts-mast"> once the scene lands.
   =========================================================================== */
.ts-mast {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 40;
  background: color-mix(in oklab, var(--sf-bg) 88%, transparent);
  border-bottom: 1px solid var(--sf-line);
  backdrop-filter: blur(14px);
  color: var(--sf-fg);
  transition: background var(--ts-dur-section) var(--ts-ease),
              color var(--ts-dur-section) var(--ts-ease),
              border-color var(--ts-dur-section) var(--ts-ease),
              transform var(--ts-dur-section) var(--ts-ease);
}
.ts-mast[data-ts-mast="away"] { transform: translateY(-101%); }

/* The bar crossfades its own surface above, and anything painting from
   currentColor rides along with it because an inherited value is already the
   interpolated one. Two marks did not: they read a --sf-* custom property
   directly, and a custom property substitution is not interpolated — it cuts.
   The button label was the visible one, flipping between light and dark ink in
   a single frame over a bar that was still fading. Colour only: background and
   border keep their micro timing so a hover still answers immediately. */
.ts-mast .ts-btn { transition: background var(--ts-dur-micro) var(--ts-ease),
                               border-color var(--ts-dur-micro) var(--ts-ease),
                               color var(--ts-dur-section) var(--ts-ease); }
.ts-mast .ts-mark__glyph { transition: border-color var(--ts-dur-section) var(--ts-ease); }

.ts-mast__grid {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ts-gutter);
  min-height: 68px;
}

.ts-mark {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  gap: 8px;
  font-family: var(--ts-font-display);
  font-size: var(--ts-fs-4);
  font-weight: 700;
  letter-spacing: -0.03em;
  text-decoration: none;
}
.ts-mark__glyph {
  width: 14px;
  height: 14px;
  border: 1.5px solid var(--sf-accent);
  border-bottom-color: transparent;
  border-right-color: transparent;
  transform: rotate(45deg);
  translate: 0 -1px;
}

.ts-mast__links {
  display: none;
  gap: 28px;
  font-size: var(--ts-fs-3);
}
.ts-mast__links a {
  text-decoration: none;
  color: var(--sf-muted);
  padding-block: 6px;
  transition: color var(--ts-dur-micro) var(--ts-ease);
}
.ts-mast__links a:hover { color: var(--sf-fg); }

/* The document you are on. Shared by all five pages — the nav is page-to-page,
   so this marker belongs to the common sheet, not to any one page's stylesheet. */
.ts-mast__links a[aria-current="page"] { color: var(--sf-fg); }
.ts-sheet__nav a[aria-current="page"] { color: var(--sf-accent); }

.ts-mast__side { display: flex; align-items: center; gap: 12px; }

.ts-burger {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  /* the CTA next to it is 176px wide; without this the burger loses the flex
     fight at 375 and the declared 44 shrinks to 37 — the one control that
     opens the whole menu on a phone */
  flex: none;
  width: 44px;
  height: 44px;
  padding: 0 10px;
  border: 0;
  background: none;
  cursor: pointer;
}
.ts-burger span {
  display: block;
  height: 1.5px;
  background: currentColor;
  transition: transform var(--ts-dur-micro) var(--ts-ease),
              opacity var(--ts-dur-micro) var(--ts-ease);
}
body[data-ts-sheet="open"] .ts-burger span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
body[data-ts-sheet="open"] .ts-burger span:nth-child(2) { opacity: 0; }
body[data-ts-sheet="open"] .ts-burger span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

/* full-height sheet (menu) */
.ts-sheet {
  position: fixed;
  inset: 0;
  z-index: 39;
  background: var(--ts-bg-deep);
  color: var(--ts-bg-primary);
  display: grid;
  align-content: space-between;
  padding: 96px 0 40px;
  clip-path: inset(0 0 100% 0);
  transition: clip-path 0.55s var(--ts-ease), visibility 0s linear 0.55s;
  visibility: hidden;
}
body[data-ts-sheet="open"] .ts-sheet {
  clip-path: inset(0 0 0 0);
  visibility: visible;
  transition: clip-path 0.55s var(--ts-ease), visibility 0s;
}
body[data-ts-sheet="open"] { overflow: hidden; }

.ts-sheet__nav { display: grid; gap: 4px; }
.ts-sheet__nav a {
  display: flex;
  align-items: baseline;
  gap: 16px;
  padding-block: 10px;
  min-height: 52px;
  font-family: var(--ts-font-display);
  font-size: clamp(var(--ts-fs-6), 5vw, var(--ts-fs-7));
  font-weight: 600;
  letter-spacing: -0.03em;
  text-decoration: none;
  border-bottom: 1px solid color-mix(in oklab, var(--ts-bg-primary) 16%, var(--ts-bg-deep));
}
.ts-sheet__nav a span {
  font-family: var(--ts-font-mono);
  font-size: var(--ts-fs-1);
  color: color-mix(in oklab, var(--ts-bg-primary) 60%, var(--ts-bg-deep));
}
.ts-sheet__foot {
  display: flex;
  flex-wrap: wrap;
  gap: 20px 40px;
  justify-content: space-between;
  align-items: flex-end;
  padding-top: 32px;
  color: color-mix(in oklab, var(--ts-bg-primary) 66%, var(--ts-bg-deep));
  font-size: var(--ts-fs-3);
}
.ts-sheet__foot a { min-height: 44px; display: inline-flex; align-items: center; }

/* ===========================================================================
   1. Hero — the metric panel is the hero, not an image
   =========================================================================== */
.ts-hero {
  padding-top: 156px;
  padding-bottom: var(--ts-space-lg);
  overflow: hidden;
}

.ts-hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 64px var(--ts-gutter);
  align-items: end;
}

.ts-hero__stated { display: grid; gap: 26px; align-content: start; }
.ts-hero__actions { display: flex; flex-wrap: wrap; gap: 12px; padding-top: 6px; }

/* the ledger: four gauges on a ruled grid */
.ts-ledger {
  border-top: 1px solid var(--sf-line);
  border-left: 1px solid var(--sf-line);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.ts-gauge {
  border-right: 1px solid var(--sf-line);
  border-bottom: 1px solid var(--sf-line);
  padding: 24px 22px 26px;
  display: grid;
  gap: 8px;
  align-content: start;
  min-height: 148px;
}

.ts-gauge__value {
  font-family: var(--ts-font-mono);
  font-size: clamp(28px, 3vw, var(--ts-fs-7));
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  color: var(--sf-fg);
}
.ts-gauge__value small {
  font-size: 0.52em;
  font-weight: 400;
  color: var(--sf-muted);
  margin-left: 2px;
}
.ts-gauge__label {
  font-size: var(--ts-fs-2);
  line-height: 1.5;
  color: var(--sf-muted);
}
.ts-gauge__meta {
  font-family: var(--ts-font-mono);
  font-size: var(--ts-fs-1);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sf-accent);
}

.ts-hero__foot {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 28px;
  align-items: center;
  margin-top: 28px;
  padding-top: 20px;
  border-top: 1px solid var(--sf-line);
}

/* ===========================================================================
   2. Assurance — a reading section. No motion here on purpose.
   =========================================================================== */
.ts-brief {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 48px var(--ts-gutter);
  align-items: start;
}
.ts-brief__text { display: grid; gap: 22px; max-width: 62ch; }

.ts-brief__figures {
  display: grid;
  gap: 34px;
  border-left: 1px solid var(--sf-line);
  padding-left: 26px;
}
.ts-brief__figures .ts-gauge__value { font-size: clamp(24px, 2.4vw, 34px); }

.ts-seals {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 1px;
  margin-top: 64px;
  background: var(--sf-line);
  border: 1px solid var(--sf-line);
}
.ts-seal {
  background: var(--sf-bg);
  padding: 22px 20px 24px;
  display: grid;
  gap: 8px;
  align-content: start;
}
.ts-seal__name {
  font-family: var(--ts-font-display);
  font-size: var(--ts-fs-4);
  font-weight: 600;
  letter-spacing: -0.02em;
}
.ts-seal__ref {
  font-family: var(--ts-font-mono);
  font-size: var(--ts-fs-1);
  letter-spacing: 0.06em;
  color: var(--sf-accent);
}
.ts-seal__note { font-size: var(--ts-fs-2); color: var(--sf-muted); line-height: 1.55; }

/* ===========================================================================
   3. Flow — the signature. Five blocks in one section:
      entry mesh, the five legs, the checks, the audit trail, the stamps.
      Every block shares the label-left / body-right bay so the eye keeps the
      same reading line all the way down. Two behaviours only: sticky-split
      (route diagram, trail index) and reveal-mask (block entry).
   =========================================================================== */
.ts-flow { overflow: clip; }

/* label column on the left, body on the right — the spine of this section */
.ts-bay {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 24px;
  align-items: start;
}

.ts-kicker--bay { margin: 0; }

.ts-flow__block { padding-block: 56px; border-top: 1px solid var(--sf-line); }
.ts-flow__block:first-of-type { border-top: 0; padding-top: 0; }

/* the trail runs deeper than the blocks around it — the one dark centre.
   The fill stays inside the shell; a full-bleed version pushed past the
   viewport edge on 1440 and read as horizontal overflow. */
.ts-flow__block--deep {
  background: var(--sf-ink);
  padding-inline: 20px;
}

/* ---- 3.1 entry mesh ------------------------------------------------------ */
.ts-mesh { display: grid; gap: 40px; }
.ts-mesh__lede {
  font-size: clamp(var(--ts-fs-4), 1.35vw, var(--ts-fs-5));
  line-height: 1.62;
  color: var(--sf-muted);
  max-width: 58ch;
  text-wrap: pretty;
}

.ts-mesh__board { display: flex; }
.ts-endpoint { margin: 0; flex: none; width: 52%; min-width: 0; }
.ts-endpoint--offset { margin-left: -8%; }
.ts-endpoint__img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border: 1px solid var(--sf-line);
  border-radius: var(--ts-radius-1);
  background: var(--sf-panel);
}
.ts-endpoint__cap {
  font-family: var(--ts-font-mono);
  font-size: var(--ts-fs-1);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sf-muted);
  padding-top: 12px;
}

.ts-flow__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 48px var(--ts-gutter);
  align-items: start;
}

.ts-route {
  position: relative;
  border: 1px solid var(--sf-line);
  background: var(--sf-panel);
  padding: 28px 26px;
  display: grid;
  gap: 18px;
}
.ts-route__head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--sf-line);
}
.ts-route__canvas { width: 100%; height: auto; display: block; }

.ts-route__line { fill: none; stroke: var(--sf-line); stroke-width: 1.5; }
.ts-route__trace {
  fill: none;
  stroke: var(--sf-accent);
  stroke-width: 2;
  stroke-linecap: square;
  stroke-dasharray: var(--trace-len, 1000);
  stroke-dashoffset: calc(var(--trace-len, 1000) - (var(--trace-len, 1000) * var(--ts-progress, 0)));
}
.ts-route__node circle { fill: var(--sf-bg); stroke: var(--sf-line); stroke-width: 1.5; }
.ts-route__node text {
  font-family: var(--ts-font-mono);
  font-size: 11px;
  fill: var(--sf-muted);
  letter-spacing: 0.04em;
}
.ts-route__node[data-ts-node-on="true"] circle { stroke: var(--sf-accent); stroke-width: 2.5; }
.ts-route__node[data-ts-node-on="true"] text { fill: var(--sf-fg); }

.ts-route__meter {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-family: var(--ts-font-mono);
  font-size: var(--ts-fs-1);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sf-muted);
  padding-top: 14px;
  border-top: 1px solid var(--sf-line);
}

/* ---- 3.2 the five legs --------------------------------------------------- */
.ts-steps { display: grid; gap: 6px; }
.ts-step {
  position: relative;
  background: var(--sf-bg);
  border: 1px solid var(--sf-line);
  border-radius: var(--ts-radius-1);
  padding: 26px 24px 28px 22px;
  display: grid;
  grid-template-columns: 52px minmax(0, 1fr);
  grid-template-areas:
    "mark no"
    "mark name"
    "mark body"
    "mark stat";
  column-gap: 18px;
  row-gap: 10px;
  align-content: start;
  transition: background var(--ts-dur-section) var(--ts-ease),
              opacity var(--ts-dur-section) var(--ts-ease),
              border-color var(--ts-dur-micro) var(--ts-ease);
}
.ts-step[data-ts-step-on="false"] { opacity: 0.42; }
.ts-step[data-ts-step-on="true"] { background: var(--sf-panel); }
.ts-step:hover { border-color: var(--sf-accent); }

.ts-step__mark { grid-area: mark; width: 52px; }
.ts-step__mark img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: contain;
  opacity: 0.85;
}
.ts-step__no {
  grid-area: no;
  font-family: var(--ts-font-mono);
  font-size: var(--ts-fs-1);
  letter-spacing: 0.1em;
  font-variant-numeric: tabular-nums;
  color: var(--sf-accent);
}
.ts-step__name {
  grid-area: name;
  font-family: var(--ts-font-display);
  font-size: var(--ts-fs-5);
  font-weight: 600;
  letter-spacing: -0.02em;
}
.ts-step__body { grid-area: body; font-size: var(--ts-fs-3); line-height: 1.65; color: var(--sf-muted); }
.ts-step__stat {
  grid-area: stat;
  font-family: var(--ts-font-mono);
  font-size: var(--ts-fs-2);
  font-variant-numeric: tabular-nums;
  color: var(--sf-fg);
  padding-top: 6px;
}

/* ---- 3.3 the checks ------------------------------------------------------ */
.ts-rail { display: grid; gap: 40px; }
.ts-rail__lede {
  font-size: clamp(var(--ts-fs-4), 1.35vw, var(--ts-fs-5));
  line-height: 1.62;
  color: var(--sf-muted);
  max-width: 58ch;
  text-wrap: pretty;
}
.ts-railboard { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; }
.ts-railcard {
  min-width: 0;
  background: var(--sf-panel);
  color: var(--sf-fg);
  border: 1px solid transparent;
  border-radius: var(--ts-radius-1);
  padding: 20px 18px 18px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  transition: border-color var(--ts-dur-micro) var(--ts-ease),
              background var(--ts-dur-micro) var(--ts-ease);
}
.ts-railcard:hover { border-color: var(--sf-line); background: var(--sf-bg); }
.ts-railcard__name {
  font-family: var(--ts-font-display);
  font-size: var(--ts-fs-5);
  font-weight: 600;
  letter-spacing: -0.02em;
}
.ts-railcard__body { font-size: var(--ts-fs-3); line-height: 1.62; color: var(--sf-muted); }
.ts-railcard__marks { display: flex; flex-wrap: wrap; gap: 4px; margin-top: auto; padding-top: 14px; }
.ts-railcard__marks li {
  font-family: var(--ts-font-mono);
  font-size: var(--ts-fs-1);
  letter-spacing: 0.04em;
  color: var(--sf-ink);
  background: var(--sf-accent);
  border-radius: var(--ts-radius-1);
  padding: 6px 8px;
  line-height: 1;
}
.ts-railcall {
  min-width: 0;
  border: 1px solid var(--sf-accent);
  border-radius: var(--ts-radius-1);
  padding: 24px 20px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 24px;
  text-decoration: none;
  color: var(--sf-fg);
  transition: background var(--ts-dur-micro) var(--ts-ease),
              color var(--ts-dur-micro) var(--ts-ease);
}
.ts-railcall__text {
  font-family: var(--ts-font-display);
  font-size: var(--ts-fs-5);
  font-weight: 600;
  letter-spacing: -0.02em;
}
.ts-railcall__mark { font-family: var(--ts-font-mono); font-size: var(--ts-fs-5); color: var(--sf-accent); }
.ts-railcall:hover { background: var(--sf-accent); color: var(--sf-ink); }
.ts-railcall:hover .ts-railcall__mark { color: var(--sf-ink); }

/* ---- 3.4 audit trail ----------------------------------------------------- */
.ts-trail { display: grid; gap: 40px; }
.ts-trail__lede {
  font-size: clamp(var(--ts-fs-4), 1.35vw, var(--ts-fs-5));
  line-height: 1.62;
  color: var(--sf-muted);
  max-width: 58ch;
  text-wrap: pretty;
}
.ts-trailboard { display: grid; grid-template-columns: minmax(0, 1fr); gap: 32px; align-items: start; }

.ts-trailindex { display: flex; flex-direction: column; gap: 6px; }
.ts-trailindex__link {
  font-family: var(--ts-font-mono);
  font-size: var(--ts-fs-2);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--sf-muted);
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 12px 0;
  border-top: 1px solid var(--sf-line);
  transition: color var(--ts-dur-micro) var(--ts-ease);
}
.ts-trailindex__link[data-ts-trail-on="true"] { color: var(--sf-accent); }
.ts-trailindex__link:hover { color: var(--sf-fg); }

.ts-trailfeed { display: grid; gap: 36px; }
.ts-trailentry {
  display: grid;
  gap: 12px;
  grid-template-areas: "fig" "code" "name" "text";
  justify-items: start;
  padding-bottom: 28px;
  border-bottom: 1px solid var(--sf-line);
}
.ts-trailentry:last-child { border-bottom: 0; padding-bottom: 0; }
.ts-trailentry__figure { grid-area: fig; width: 46%; }
.ts-trailentry__figure img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: contain;
  border: 1px solid var(--sf-line);
  border-radius: var(--ts-radius-1);
  background: var(--sf-panel);
}
.ts-trailentry__code {
  grid-area: code;
  font-family: var(--ts-font-mono);
  font-size: var(--ts-fs-1);
  letter-spacing: 0.12em;
  font-variant-numeric: tabular-nums;
  color: var(--sf-accent);
}
.ts-trailentry__name {
  grid-area: name;
  font-family: var(--ts-font-display);
  font-size: var(--ts-fs-5);
  font-weight: 600;
  letter-spacing: -0.02em;
}
.ts-trailentry__text {
  grid-area: text;
  font-family: var(--ts-font-display);
  font-size: clamp(var(--ts-fs-5), 2.1vw, var(--ts-fs-6));
  font-weight: 400;
  line-height: 1.28;
  letter-spacing: -0.015em;
  color: var(--sf-muted);
  max-width: 36ch;
  transition: color var(--ts-dur-section) var(--ts-ease);
}
.ts-trailentry[data-ts-trail-on="true"] .ts-trailentry__text { color: var(--sf-fg); }

/* ---- 3.5 stamps ---------------------------------------------------------- */
.ts-stampzone { display: grid; gap: 40px; }
.ts-stampzone__lede {
  font-size: clamp(var(--ts-fs-4), 1.35vw, var(--ts-fs-5));
  line-height: 1.62;
  color: var(--sf-muted);
  max-width: 58ch;
  text-wrap: pretty;
}
.ts-stampboard { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.ts-stamp {
  display: grid;
  gap: 8px;
  justify-items: start;
  align-content: start;
  border: 1px solid transparent;
  border-radius: var(--ts-radius-1);
  padding: 18px 16px 20px;
  transition: border-color var(--ts-dur-micro) var(--ts-ease);
}
.ts-stamp:hover { border-color: var(--sf-line); }
.ts-stamp__icon {
  width: 44px;
  aspect-ratio: 1;
  object-fit: contain;
  opacity: 0.85;
  margin-bottom: 4px;
}
.ts-stamp__code {
  font-family: var(--ts-font-mono);
  font-size: var(--ts-fs-1);
  letter-spacing: 0.12em;
  font-variant-numeric: tabular-nums;
  color: var(--sf-accent);
}
.ts-stamp__name { font-size: var(--ts-fs-4); font-weight: 600; letter-spacing: -0.01em; }
.ts-stamp__note { font-size: var(--ts-fs-2); line-height: 1.55; color: var(--sf-muted); }

/* ===========================================================================
   4. Capabilities — cards stack as you scroll
   =========================================================================== */
.ts-slabs { display: grid; gap: 20px; }

.ts-slab {
  border: 1px solid var(--sf-line);
  background: var(--sf-bg);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  overflow: hidden;
}
.ts-slab__text {
  padding: 34px 30px 36px;
  display: grid;
  gap: 14px;
  align-content: center;
}
.ts-slab__figure { position: relative; background: var(--sf-panel); min-height: 220px; }
.ts-slab__figure img { width: 100%; height: 100%; object-fit: cover; }
.ts-slab__list { display: grid; gap: 8px; padding-top: 6px; }
.ts-slab__list li {
  display: grid;
  grid-template-columns: 16px 1fr;
  gap: 10px;
  font-size: var(--ts-fs-3);
  color: var(--sf-muted);
  line-height: 1.6;
}
.ts-slab__list li::before {
  content: "";
  width: 7px;
  height: 7px;
  margin-top: 9px;
  border: 1px solid var(--sf-accent);
}

/* ===========================================================================
   5. Security — numbered rows, detail pins on hover
   =========================================================================== */
.ts-index { display: grid; counter-reset: ts-index; }

.ts-index__row {
  position: relative;
  counter-increment: ts-index;
  border-bottom: 1px solid var(--sf-line);
}
.ts-index__row:first-child { border-top: 1px solid var(--sf-line); }

.ts-index__hit {
  display: grid;
  grid-template-columns: 46px minmax(0, 1fr);
  gap: 16px;
  align-items: center;
  width: 100%;
  min-height: 64px;
  padding: 14px 0;
  border: 0;
  background: none;
  text-align: left;
  cursor: pointer;
  transition: color var(--ts-dur-micro) var(--ts-ease);
}
.ts-index__hit::before {
  content: counter(ts-index, decimal-leading-zero);
  font-family: var(--ts-font-mono);
  font-size: var(--ts-fs-1);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.06em;
  color: var(--sf-muted);
}
.ts-index__name {
  font-family: var(--ts-font-display);
  font-size: clamp(var(--ts-fs-4), 1.8vw, var(--ts-fs-5));
  font-weight: 500;
  letter-spacing: -0.02em;
}
.ts-index__row:hover .ts-index__name,
.ts-index__row:focus-within .ts-index__name { color: var(--sf-accent); }

.ts-index__detail {
  display: grid;
  gap: 8px;
  padding: 0 0 22px 62px;
  max-width: 64ch;
}
.ts-index__detail p { font-size: var(--ts-fs-3); line-height: 1.65; color: var(--sf-muted); }

/* the pin: a thumbnail that drops in at the right edge of the row */
.ts-index__pin {
  position: absolute;
  right: 0;
  top: 8px;
  width: 168px;
  height: 112px;
  overflow: hidden;
  clip-path: inset(0 0 100% 0);
  transition: clip-path 0.5s var(--ts-ease);
  pointer-events: none;
  z-index: 2;
}
.ts-index__pin img { width: 100%; height: 100%; object-fit: cover; }
.ts-index__row:hover .ts-index__pin,
.ts-index__row:focus-within .ts-index__pin { clip-path: inset(0 0 0 0); }

.ts-index__lead {
  position: absolute;
  right: 168px;
  top: 64px;
  height: 1px;
  width: 0;
  background: var(--sf-accent);
  transition: width 0.5s var(--ts-ease) 0.08s;
  pointer-events: none;
}
.ts-index__row:hover .ts-index__lead,
.ts-index__row:focus-within .ts-index__lead { width: 84px; }

/* ===========================================================================
   6. Integrations — one image tracks the hovered row
   =========================================================================== */
.ts-swap {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 40px var(--ts-gutter);
  align-items: start;
}

.ts-swap__rows { display: grid; }
.ts-swap__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 16px;
  align-items: center;
  min-height: 78px;
  padding: 16px 0;
  border-bottom: 1px solid var(--sf-line);
  cursor: pointer;
  transition: opacity var(--ts-dur-micro) var(--ts-ease);
}
.ts-swap__row:first-child { border-top: 1px solid var(--sf-line); }
.ts-swap__name {
  font-family: var(--ts-font-display);
  font-size: clamp(var(--ts-fs-4), 1.7vw, var(--ts-fs-5));
  font-weight: 500;
  letter-spacing: -0.02em;
}
.ts-swap__kind {
  font-family: var(--ts-font-mono);
  font-size: var(--ts-fs-1);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sf-muted);
}
.ts-swap__count {
  font-family: var(--ts-font-mono);
  font-size: var(--ts-fs-2);
  font-variant-numeric: tabular-nums;
  color: var(--sf-muted);
}

.ts-swap__col { position: relative; }

.ts-swap__stage {
  position: relative;
  border: 1px solid var(--sf-line);
  background: var(--sf-panel);
  aspect-ratio: 4 / 3;
  overflow: hidden;
  will-change: transform;
}
.ts-swap__plate {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity var(--ts-dur-micro) var(--ts-ease);
}
.ts-swap__plate[data-ts-swap-on="true"] { opacity: 1; }
.ts-swap__plate img { width: 100%; height: 100%; object-fit: cover; }

/* ===========================================================================
   7. Metrics — figures count in on entry
   =========================================================================== */
.ts-metrics {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 1px;
  background: var(--sf-line);
  border: 1px solid var(--sf-line);
}
.ts-metric {
  background: var(--sf-bg);
  padding: 30px 26px 34px;
  display: grid;
  gap: 10px;
  align-content: start;
}
.ts-metric__value {
  font-family: var(--ts-font-mono);
  font-size: clamp(30px, 3.2vw, var(--ts-fs-7));
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.ts-metric__label { font-size: var(--ts-fs-2); color: var(--sf-muted); line-height: 1.55; }

/* ── 8.1 plan board── */
.ts-planboard {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 20px;
  /* three blocks share one section, so the seams between them run tighter
     than a section break would — density is the axis this page is on */
  margin-bottom: 40px;
}
.ts-plancard {
  display: grid;
  align-content: start;
  gap: 12px;
  padding: 24px 22px 26px;
  border: 1px solid var(--sf-line);
  border-radius: var(--ts-radius-1);
  background: var(--sf-bg);
}
/* one card carries the recommendation — a rule, not a badge */
.ts-plancard--lead {
  background: var(--sf-panel);
  box-shadow: inset 0 2px 0 var(--sf-accent);
}
.ts-plancard__mark {
  width: 12px;
  height: 12px;
  background: var(--sf-accent);
  border-radius: var(--ts-radius-0);
}
.ts-plancard--lead .ts-plancard__mark { background: var(--sf-fg); }

.ts-planshot {
  display: block;
  width: 100%;
  height: 96px;
  object-fit: contain;
  object-position: left center;
  margin-bottom: 4px;
}
.ts-plancard__name {
  font-family: var(--ts-font-display);
  font-size: var(--ts-fs-5);
  font-weight: 600;
  letter-spacing: -0.02em;
}
.ts-plancard__terms {
  font-family: var(--ts-font-mono);
  font-size: var(--ts-fs-1);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sf-muted);
  font-variant-numeric: tabular-nums;
}
.ts-plancard__body {
  font-size: var(--ts-fs-3);
  line-height: 1.62;
  color: var(--sf-muted);
  text-wrap: pretty;
}
.ts-plancard .ts-act { margin-top: 6px; }

/* ── 8.1b inline action── */
.ts-act {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--sf-fg);
  font-family: var(--ts-font-mono);
  font-size: var(--ts-fs-2);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  text-align: left;
  cursor: pointer;
  transition: color var(--ts-dur-micro) var(--ts-ease);
}
.ts-act__text {
  padding-bottom: 3px;
  box-shadow: inset 0 -1px 0 var(--sf-line);
  transition: box-shadow var(--ts-dur-micro) var(--ts-ease);
}
.ts-act__icon {
  display: flex;
  flex: none;
  transition: transform var(--ts-dur-micro) var(--ts-ease);
}
.ts-act:hover,
.ts-act:focus-visible { color: var(--sf-accent); }
.ts-act:hover .ts-act__text,
.ts-act:focus-visible .ts-act__text { box-shadow: inset 0 -1px 0 var(--sf-accent); }
.ts-act:hover .ts-act__icon { transform: translateX(4px); }

.ts-act--desk {
  font-family: var(--ts-font-body);
  font-size: var(--ts-fs-4);
  letter-spacing: -0.01em;
  text-transform: none;
}

/* ── 8.2 the table ── */
.ts-plan { width: 100%; border-collapse: collapse; text-align: left; }
.ts-plan caption { text-align: left; padding-bottom: 20px; color: var(--sf-muted); font-size: var(--ts-fs-3); }

.ts-plan th,
.ts-plan td {
  border: 1px solid var(--sf-line);
  padding: 16px 18px;
  vertical-align: top;
  font-size: var(--ts-fs-3);
  transition: border-color var(--ts-dur-micro) var(--ts-ease);
}
.ts-plan thead th { background: var(--sf-panel); vertical-align: bottom; }
.ts-plan thead th:first-child { width: 30%; }

.ts-plan__tier {
  display: grid;
  gap: 6px;
}
.ts-plan__tier b {
  font-family: var(--ts-font-display);
  font-size: var(--ts-fs-5);
  font-weight: 600;
  letter-spacing: -0.02em;
}
.ts-plan__rate {
  font-family: var(--ts-font-mono);
  font-size: var(--ts-fs-3);
  font-variant-numeric: tabular-nums;
  color: var(--sf-accent);
}

.ts-plan tbody th {
  font-weight: 500;
  color: var(--sf-fg);
  background: transparent;
}
.ts-plan tbody tr {
  transition: background var(--ts-dur-micro) var(--ts-ease);
  cursor: default;
}
.ts-plan tbody tr:hover { background: var(--sf-panel); }
.ts-plan tbody tr:hover th { box-shadow: inset 3px 0 0 var(--sf-accent); }
.ts-plan tbody tr:focus-visible { outline: 2px solid var(--sf-accent); outline-offset: -2px; }

/* the signature: the row being read is ruled in the accent across every
   column, so the eye can follow one capability the whole way across */
.ts-plan tbody tr[data-ts-plan-on="true"] { background: var(--sf-panel); }
.ts-plan tbody tr[data-ts-plan-on="true"] th { box-shadow: inset 3px 0 0 var(--sf-accent); }
.ts-plan tbody tr[data-ts-plan-on="true"] th,
.ts-plan tbody tr[data-ts-plan-on="true"] td {
  border-top-color: var(--sf-accent);
  border-bottom-color: var(--sf-accent);
}

.ts-plan__mark { font-family: var(--ts-font-mono); color: var(--sf-accent); }
.ts-plan__none { font-family: var(--ts-font-mono); color: var(--sf-muted); }
.ts-plan__scroll { overflow-x: auto; }

/* ── 8.3 case reader── */
.ts-cases {
  margin-top: 36px;
  padding-top: 32px;
  border-top: 1px solid var(--sf-line);
}
.ts-casewrap {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 26px;
  align-items: start;
}
.ts-case {
  display: grid;
  gap: 16px;
  align-content: start;
  transition: opacity var(--ts-dur-micro) var(--ts-ease);
}
.ts-case[data-ts-case-fade="out"] { opacity: 0; }
.ts-case[data-ts-case-fade="in"] { opacity: 1; }
.ts-case__row { color: var(--sf-accent); }
.ts-case__text {
  font-family: var(--ts-font-display);
  font-size: clamp(var(--ts-fs-5), 2.1vw, var(--ts-fs-6));
  font-weight: 500;
  line-height: 1.32;
  letter-spacing: -0.02em;
  text-wrap: pretty;
  max-width: 34ch;
}
.ts-case__kind {
  font-family: var(--ts-font-mono);
  font-size: var(--ts-fs-1);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sf-muted);
}

.ts-caseplate {
  display: grid;
  gap: 10px;
  align-content: start;
  padding: 20px;
  border: 1px solid var(--sf-line);
  border-radius: var(--ts-radius-1);
  background: var(--sf-panel);
}
.ts-caseplate__label {
  font-family: var(--ts-font-mono);
  font-size: var(--ts-fs-1);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--sf-muted);
}
.ts-caseplate__plan {
  font-family: var(--ts-font-display);
  font-size: var(--ts-fs-5);
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--sf-accent);
}
.ts-caseplate__note { font-size: var(--ts-fs-2); line-height: 1.55; color: var(--sf-muted); }
.ts-caseplate__count {
  margin-top: 4px;
  padding-top: 12px;
  border-top: 1px solid var(--sf-line);
  font-family: var(--ts-font-mono);
  font-size: var(--ts-fs-1);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.1em;
  color: var(--sf-muted);
}

.ts-off { display: none; }

/* ── 8.4 desk strip — where Negotiated lands ── */
.ts-dealstrip {
  margin-top: 40px;
  padding-top: 32px;
  border-top: 1px solid var(--sf-line);
}
.ts-dealstrip__body { display: grid; gap: 20px; justify-items: start; }
.ts-dealstrip__text {
  font-family: var(--ts-font-display);
  font-size: clamp(var(--ts-fs-4), 1.7vw, var(--ts-fs-5));
  font-weight: 500;
  line-height: 1.42;
  letter-spacing: -0.02em;
  text-wrap: pretty;
  max-width: 46ch;
}

/* ===========================================================================
   9. FAQ — folds
   =========================================================================== */
.ts-folds { display: grid; }
.ts-fold {
  border-bottom: 1px solid var(--sf-line);
}
.ts-fold:first-child { border-top: 1px solid var(--sf-line); }

.ts-fold__hit {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 24px;
  gap: 20px;
  align-items: center;
  width: 100%;
  min-height: 72px;
  padding: 18px 0;
  border: 0;
  background: none;
  text-align: left;
  cursor: pointer;
  font-family: var(--ts-font-display);
  font-size: clamp(var(--ts-fs-4), 1.5vw, var(--ts-fs-5));
  font-weight: 500;
  letter-spacing: -0.02em;
  transition: color var(--ts-dur-micro) var(--ts-ease);
}
.ts-fold__hit:hover { color: var(--sf-accent); }

.ts-fold__sign { position: relative; width: 16px; height: 16px; justify-self: end; }
.ts-fold__sign::before,
.ts-fold__sign::after {
  content: "";
  position: absolute;
  inset: 50% 0 auto 0;
  height: 1.5px;
  background: currentColor;
  transition: transform var(--ts-dur-micro) var(--ts-ease);
}
.ts-fold__sign::after { transform: rotate(90deg); }
.ts-fold[data-ts-fold="open"] .ts-fold__sign::after { transform: rotate(0deg); }

.ts-fold__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.4s var(--ts-ease);
}
.ts-fold[data-ts-fold="open"] .ts-fold__panel { grid-template-rows: 1fr; }
.ts-fold__inner { overflow: hidden; }
.ts-fold__inner p {
  padding: 0 0 26px;
  max-width: 74ch;
  font-size: var(--ts-fs-3);
  line-height: 1.7;
  color: var(--sf-muted);
}

/* ===========================================================================
   10. CTA
   =========================================================================== */
.ts-hail__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 44px var(--ts-gutter);
  align-items: end;
}
.ts-hail__form { display: grid; gap: 12px; }
.ts-hail__row {
  display: flex;
  gap: 8px;
  align-items: center;
  border: 1px solid var(--sf-line);
  border-radius: var(--ts-radius-1);
  background: var(--sf-panel);
  padding: 5px 5px 5px 16px;
}
.ts-hail__row:focus-within { border-color: var(--sf-accent); }
.ts-hail__row input {
  flex: 1;
  min-width: 0;
  min-height: 44px;
  border: 0;
  background: transparent;
  font-size: var(--ts-fs-3);
}
.ts-hail__row input::placeholder { color: var(--sf-muted); }
.ts-hail__send {
  position: relative;
  flex: 0 0 auto;
  min-height: 44px;
  padding: 0 20px;
  border: 1px solid var(--sf-accent);
  border-radius: var(--ts-radius-1);
  background: var(--sf-accent);
  color: var(--sf-ink);
  font-size: var(--ts-fs-3);
  font-weight: 600;
  cursor: pointer;
  will-change: transform;
}
.ts-hail__help {
  min-height: 1lh;
  font-size: var(--ts-fs-2);
  color: var(--sf-muted);
  padding-left: 0;
  border-left: 0 solid transparent;
  transition: padding-left var(--ts-dur-micro) var(--ts-ease);
}
/* The failed state carries weight and a rule rather than a warning colour:
   the palette has one accent and spending a second one here would break it. */
.ts-hail__help[data-ts-state="bad"] {
  color: var(--sf-fg);
  font-weight: 600;
  padding-left: 10px;
  border-left: 2px solid var(--sf-fg);
}
.ts-hail__help[data-ts-state="ok"] { color: var(--sf-accent); }

/* ===========================================================================
   11. Footer — three layers drift at different rates
   =========================================================================== */
.ts-foot {
  position: relative;
  background: var(--ts-bg-deep);
  color: var(--ts-bg-primary);
  overflow: clip;
  --sf-bg: var(--ts-bg-deep);
  --sf-fg: var(--ts-bg-primary);
  --sf-muted: color-mix(in oklab, var(--ts-bg-primary) 66%, var(--ts-bg-deep));
  --sf-line: color-mix(in oklab, var(--ts-bg-primary) 22%, var(--ts-bg-deep));
  --sf-accent: color-mix(in oklab, var(--ts-accent) 46%, var(--ts-bg-primary));
  --sf-ink: var(--ts-bg-deep);
}
.ts-foot__atlas {
  position: absolute;
  inset: -18% 0 auto 0;
  height: 62%;
  opacity: 0.16;
  will-change: transform;
}
.ts-foot__atlas img { width: 100%; height: 100%; object-fit: cover; }
.ts-foot__plate { position: relative; z-index: 1; padding-block: 96px 40px; will-change: transform; }

.ts-foot__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 48px var(--ts-gutter);
  padding-bottom: 64px;
  border-bottom: 1px solid var(--sf-line);
}
.ts-foot__cols { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 32px var(--ts-gutter); }
.ts-foot__col { display: grid; gap: 12px; align-content: start; }
.ts-foot__col h3 {
  font-family: var(--ts-font-mono);
  font-size: var(--ts-fs-1);
  font-weight: 400;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--sf-muted);
}
.ts-foot__col a {
  font-size: var(--ts-fs-3);
  text-decoration: none;
  color: var(--sf-fg);
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  transition: color var(--ts-dur-micro) var(--ts-ease);
}
.ts-foot__col a:hover { color: var(--sf-accent); }

.ts-foot__bridge {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 28px;
  justify-content: space-between;
  align-items: center;
  padding-top: 28px;
  font-size: var(--ts-fs-2);
  color: var(--sf-muted);
  will-change: transform;
}
.ts-foot__legal { display: flex; flex-wrap: wrap; gap: 6px 20px; }
.ts-foot__legal a { text-decoration: none; min-height: 44px; display: inline-flex; align-items: center; }
.ts-foot__legal a:hover { color: var(--sf-accent); }

/* ===========================================================================
   Cursor
   Desktop pointers only. Buyers can switch it off by adding
   data-ts-pointer-off to <body>; the runtime reads that attribute and never
   overwrites it.
   =========================================================================== */
.ts-pointer {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 60;
  display: none;
  align-items: center;
  justify-content: center;
  width: 12px;
  height: 12px;
  margin: -6px 0 0 -6px;
  border: 1px solid var(--ts-text-primary);
  border-radius: var(--ts-radius-1);
  background: transparent;
  pointer-events: none;
  will-change: transform;
  transition: width 0.28s var(--ts-ease), height 0.28s var(--ts-ease),
              margin 0.28s var(--ts-ease), background 0.28s var(--ts-ease),
              border-radius 0.28s var(--ts-ease);
}
.ts-pointer__label {
  font-family: var(--ts-font-mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ts-bg-primary);
  opacity: 0;
  white-space: nowrap;
  transition: opacity 0.2s var(--ts-ease);
}
.ts-pointer[data-ts-pointer="live"],
.ts-pointer[data-ts-pointer="live-edge"] {
  width: 76px;
  height: 76px;
  margin: -38px 0 0 -38px;
  background: var(--ts-text-primary);
  border-color: var(--ts-text-primary);
  border-radius: var(--ts-radius-1);
}
.ts-pointer[data-ts-pointer="live-edge"] { margin-left: -76px; }
.ts-pointer[data-ts-pointer="live"] .ts-pointer__label,
.ts-pointer[data-ts-pointer="live-edge"] .ts-pointer__label { opacity: 1; }

body[data-ts-pointer-on="true"] .ts-pointer { display: flex; }
body[data-ts-pointer-on="true"] a,
body[data-ts-pointer-on="true"] button { cursor: none; }
body[data-ts-pointer-off] .ts-pointer { display: none !important; }
body[data-ts-pointer-off] a,
body[data-ts-pointer-off] button { cursor: pointer; }

/* ===========================================================================
   Scroll entry — mask reveal
   =========================================================================== */
[data-ts-mask] {
  clip-path: inset(0 0 var(--mask-from, 18%) 0);
  opacity: 0;
  transition: clip-path 0.85s var(--ts-ease), opacity 0.6s var(--ts-ease);
}
[data-ts-mask][data-ts-shown="true"] { clip-path: inset(0 0 0 0); opacity: 1; }

/* The largest panels open with the scroll instead of on a trigger: the same
   mask driven by a fraction, so scrolling back closes it again. The runtime
   adds the attribute and only where the stage is wide enough to be worth it,
   which keeps this inert without script, under reduced motion and on a phone.
   Declared after the binary rule on purpose — equal specificity, later wins.
   Opacity stays on the flag: a panel held half-transparent for a whole
   viewport pass reads as a loading state, not as a reveal. */
[data-ts-mask][data-ts-mask-scrub] {
  clip-path: inset(0 0 calc(var(--mask-from, 18%) * (1 - var(--ts-mask-p, 0))) 0);
  transition: opacity 0.6s var(--ts-ease);
}

[data-ts-enter] {
  opacity: 0;
  transform: translateY(16px);
}
body[data-ts-ready="true"] [data-ts-enter] {
  opacity: 1;
  transform: none;
  transition: opacity var(--ts-dur-hero) var(--ts-ease) var(--enter-delay, 0s),
              transform var(--ts-dur-hero) var(--ts-ease) var(--enter-delay, 0s);
}

/* ===========================================================================
   Responsive — the layouts split apart from here up
   =========================================================================== */
@media (min-width: 700px) {
  .ts-slab { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
  .ts-foot__cols { grid-template-columns: repeat(3, minmax(0, 1fr)); }

  .ts-railboard { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ts-stampboard { grid-template-columns: repeat(3, minmax(0, 1fr)); }

  /* three plans read as three columns from tablet up — two-up would leave
     one plan orphaned on its own row, which reads as a fourth tier */
  .ts-planboard { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }
}

@media (min-width: 1000px) {
  .ts-mast__links { display: flex; }
  .ts-burger { display: none; }

  .ts-hero { padding-top: 190px; }
  .ts-hero__grid { grid-template-columns: minmax(0, 6fr) minmax(0, 6fr); gap: 72px 56px; }
  .ts-ledger { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* Hero drift. The two columns leave at different rates as the section
     scrolls out — the figures are the heavier object and travel further, which
     is the only reason the difference reads at all. Percentages of each
     element's own box, so the widest screen does not get a bigger shove.

     This is the standalone translate property, not transform: the entry
     animation owns transform on these same elements, and two writers on one
     property flicker. Unset, the variable resolves to 0, so the pair is inert
     without script and under reduced motion — no reset rule needed. */
  .ts-hero__stated { translate: 0 calc(var(--ts-hero-drift, 0) * -4%); }
  .ts-ledger { translate: 0 calc(var(--ts-hero-drift, 0) * -10%); }

  .ts-brief { grid-template-columns: minmax(0, 7fr) minmax(0, 4fr); gap: 64px 72px; }

  
  .ts-bay { grid-template-columns: minmax(0, 1fr) minmax(0, 5fr); gap: 32px; }
  .ts-flow__block { padding-block: 64px; }
  .ts-flow__block--deep { padding-inline: 36px; }

  .ts-mesh, .ts-rail, .ts-trail, .ts-stampzone { gap: 40px; }

  .ts-flow__grid { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 64px 56px; }
  .ts-flow__stage { position: sticky; top: 108px; }
  .ts-steps { grid-template-columns: minmax(0, 1fr); }
  
  .ts-step {
    padding: 26px 26px 28px 22px;
    grid-template-columns: 52px minmax(0, 1fr) minmax(0, 18.25rem);
    grid-template-areas:
      "mark no   body"
      "mark name body"
      "mark stat body";
    column-gap: 28px;
  }
  .ts-step__body { align-self: center; }

  .ts-railboard { grid-template-columns: repeat(3, minmax(0, 1fr)); }

  .ts-trailboard { grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); gap: 48px; }
  .ts-trailindex { position: sticky; top: 108px; }
  .ts-trailfeed { gap: 32px; }
  
  .ts-trailentry {
    grid-template-columns: 168px minmax(0, 1fr);
    grid-template-areas:
      "fig code"
      "fig name"
      "fig text";
    column-gap: 28px;
    row-gap: 10px;
    align-items: start;
  }
  .ts-trailentry__figure { width: 168px; }

  .ts-stampboard { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 20px; }

  /* the plate column stretches to the height of the row list so the stage has
     somewhere to travel; without the stretch it collapses and the slide is a
     no-op that still looks like a working crossfade */
  .ts-swap { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: 56px; align-items: stretch; }
  .ts-swap__stage { position: absolute; inset: 0 0 auto 0; }

  .ts-hail__grid { grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); gap: 72px; }
  .ts-foot__grid { grid-template-columns: minmax(0, 4fr) minmax(0, 7fr); gap: 72px; }

  .ts-planboard { gap: 20px; }
  .ts-plancard { padding: 28px 26px 30px; }
  .ts-planshot { height: 120px; }

  
  .ts-casewrap {
    grid-template-columns: minmax(0, 3fr) minmax(0, 1fr);
    grid-template-areas:
      "read plate"
      "next plate";
    column-gap: 48px;
    row-gap: 24px;
  }
  .ts-case { grid-area: read; }
  .ts-caseplate { grid-area: plate; }
  .ts-act--case { grid-area: next; justify-self: start; }
  
  .ts-cases { cursor: pointer; }
}

@media (max-width: 999px) {
  /* the pin has nowhere to sit on narrow screens, so the detail stays open */
  .ts-index__pin,
  .ts-index__lead { display: none; }
  .ts-swap__stage { display: none; }
  /* nothing to hold the trail index against, and every entry already carries
     its own name — so the index goes rather than duplicating the headings */
  .ts-trailindex { display: none; }
}

@media (max-width: 699px) {
  :root {
    --ts-space-lg: 84px;
    --ts-space-sm: 56px;
  }
  .ts-ledger { grid-template-columns: minmax(0, 1fr); }
  .ts-masthead { grid-template-columns: minmax(0, 1fr); gap: 20px; padding-bottom: 36px; margin-bottom: 36px; }
  .ts-hero { padding-top: 124px; }
  .ts-btn { width: 100%; }
  .ts-hail__row { flex-wrap: wrap; padding: 12px; }
  .ts-hail__send { width: 100%; }

  .ts-step { grid-template-columns: 40px minmax(0, 1fr); column-gap: 14px; padding: 22px 18px 24px 16px; }
  .ts-step__mark { width: 40px; }
  .ts-endpoint { width: 54%; }
  .ts-endpoint--offset { margin-left: -8%; }
  .ts-trailentry__figure { width: 62%; }
  .ts-stampboard { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .ts-stamp { padding: 14px 12px 16px; }

  /* a four-column comparison squeezed into 375px is unreadable, so the table
     keeps its width and scrolls inside its own container — the page does not.
     The capability column pins to the left so a value never loses its row. */
  .ts-plan { min-width: 620px; }

  /* A sticky cell cannot paint over a collapsed border: the seam belongs to
     the table, not the cell, so the column scrolling underneath leaks through
     it as stray glyphs. Separating the borders gives the pinned cell a solid
     background of its own. Mobile only — the desktop table has no sticky
     column and keeps its collapsed rules. */
  .ts-plan { border-collapse: separate; border-spacing: 0; }
  .ts-plan th,
  .ts-plan td {
    border: 0;
    border-right: 1px solid var(--sf-line);
    border-bottom: 1px solid var(--sf-line);
  }
  .ts-plan tr > *:first-child { border-left: 1px solid var(--sf-line); }
  .ts-plan thead th { border-top: 1px solid var(--sf-line); }

  .ts-plan th[scope="row"] {
    position: sticky;
    left: 0;
    z-index: 1;
    min-width: 176px;
    background: var(--sf-bg);
    background-clip: padding-box;
  }
  /* the row rule survives the separated borders as an accent seam. With one
     border per cell the seam above a row belongs to the row before it, so
     both neighbours have to be addressed to close the rule on both sides. */
  .ts-plan tbody tr[data-ts-plan-on="true"] > *,
  .ts-plan tbody tr:hover > *,
  .ts-plan tbody tr:has(+ tr[data-ts-plan-on="true"]) > *,
  .ts-plan tbody tr:has(+ tr:hover) > * { border-bottom-color: var(--sf-accent); }
  /* the first row's upper seam belongs to the head and stays neutral —
     the left accent bar carries the rule there */
  .ts-plan thead th:first-child {
    position: sticky;
    left: 0;
    z-index: 2;
    background: var(--sf-panel);
  }
  .ts-plan tbody tr:hover th[scope="row"],
  .ts-plan tbody tr[data-ts-plan-on="true"] th[scope="row"] { background: var(--sf-panel); }
  .ts-plan th,
  .ts-plan td { padding: 14px 14px; }

  .ts-planshot { height: 84px; }
  .ts-case__text { max-width: none; }
}

/* ===========================================================================
   Reduced motion — everything resolves to its finished state
   =========================================================================== */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }

  [data-ts-mask],
  [data-ts-enter] {
    clip-path: none !important;
    opacity: 1 !important;
    transform: none !important;
  }

  .ts-index__pin { clip-path: inset(0 0 0 0); }
  .ts-step[data-ts-step-on="false"] { opacity: 1; }
  .ts-flow__stage,
  .ts-trailindex,
  .ts-swap__stage { position: static; }
  .ts-trailentry__text { color: var(--sf-fg); }
  .ts-pointer { display: none !important; }
}
