/* public/css/site.css — GENERATED by scripts/build-css.mjs from lib/tokens.js.
 * Do not hand-edit; edit the tokens or the generator.
 */

:root {
  /* colour */
  --td-ink: #0A1628;
  --td-ink-deep: #060D1A;
  --td-ink-2: #243356;
  --td-ink-3: #3C4968;
  --td-ink-4: #4A556D;
  --td-ink-5: #616C84;
  --td-ink-6: #96A3BD;
  --td-ink-7: #C2CAD9;
  --td-paper: #FEFDFB;
  --td-paper-2: #FAF8F5;
  --td-paper-3: #F5F2ED;
  --td-line: #EBE7E0;
  --td-line-2: #D9D4CB;
  --td-accent: #2563EB;
  --td-accent-strong: #1D4ED8;
  --td-accent-command: #4D8DFF;
  --td-accent-command-soft: #7BA6FF;
  --td-success: #1B7A4A;
  --td-success-command: #36C98A;
  --td-warning: #8F6708;
  --td-warning-command: #E0B45C;
  --td-critical: #C23030;
  --td-critical-command: #FF8585;
  --td-tint-info: #EFF4FF;
  --td-tint-success: #E8F5EE;
  --td-tint-warning: #FFF8E7;
  --td-tint-critical: #FDECEC;
  --td-tint-warning-command: #3A2810;
  --td-tint-success-command: #10301F;
  --td-tint-critical-command: #3A1010;
  --td-on-success: #06140C;
  --td-on-critical: #1A0606;
  --td-code-fg: #E4E7EE;

  /* type */
  --td-text-9: 9px;
  --td-text-10: 10px;
  --td-text-11: 11px;
  --td-text-12: 12px;
  --td-text-13: 13px;
  --td-text-14: 14px;
  --td-text-15: 15px;
  --td-text-16: 16px;
  --td-text-18: 18px;
  --td-text-20: 20px;
  --td-text-22: 22px;
  --td-text-26: 26px;
  --td-text-32: 32px;
  --td-text-38: 38px;
  --td-text-46: 46px;
  --td-text-54: 54px;
  --td-text-60: 60px;
  --td-text-120: 120px;
  --td-display-1: clamp(38px, 5vw, 60px);
  --td-display-2: clamp(32px, 4vw, 46px);
  --td-display-3: clamp(28px, 3.3vw, 38px);
  --td-display-4: clamp(24px, 2.6vw, 32px);
  --td-font-display: 'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --td-font-mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  /* space */
  --td-space-0: 0px;
  --td-space-2: 2px;
  --td-space-4: 4px;
  --td-space-8: 8px;
  --td-space-12: 12px;
  --td-space-16: 16px;
  --td-space-20: 20px;
  --td-space-24: 24px;
  --td-space-32: 32px;
  --td-space-40: 40px;
  --td-space-48: 48px;
  --td-space-56: 56px;
  --td-space-64: 64px;
  --td-space-80: 80px;
  --td-space-96: 96px;
  --td-space-120: 120px;
  --td-section-none: 0px;
  --td-section-tight: 40px;
  --td-section-compact: 56px;
  --td-section-default: 80px;
  --td-section-generous: 96px;
  --td-section-hero: 120px;

  /* shape */
  --td-radius-0: 0px;
  --td-radius-2: 2px;
  --td-radius-4: 4px;
  --td-radius-8: 8px;
  --td-radius-12: 12px;
  --td-radius-16: 16px;
  --td-radius-20: 20px;
  --td-radius-pill: 999px;
  --td-radius-circle: 50%;
  --td-shadow-none: none;
  --td-shadow-sm: 0 1px 2px rgba(10,22,40,0.06);
  --td-shadow-md: 0 4px 12px rgba(10,22,40,0.08);
  --td-shadow-lg: 0 12px 32px rgba(10,22,40,0.10);
  --td-shadow-xl: 0 30px 80px rgba(10,22,40,0.12);
  --td-shadow-overlay: 0 8px 40px rgba(10,22,40,0.4);
  --td-shadow-lift: 0 30px 80px -36px rgba(10,22,40,0.24);
  --td-shadow-lift-dark: 0 30px 80px -40px rgba(0,0,0,0.60);
}

/* ─── base ──────────────────────────────────────────────────────────────────
 * The reset every page used to carry its own slightly different copy of.
 * Page-level <style> blocks still win on anything they set, so this is a floor,
 * not an override.
 */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
html, body { margin: 0; padding: 0; }
body {
  font-family: var(--td-font-display);
  background: var(--td-paper-2);
  color: var(--td-ink);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Archivo ships proportional figures. Tabular ones keep the count-up stat
     bands and the dashboard mockups from reflowing on every tick. */
  font-variant-numeric: normal;
}
a { color: inherit; text-decoration: none; }
img, svg, video { max-width: 100%; }
::selection { background: rgba(37, 99, 235, 0.18); }

/* Numerals that animate or sit in a table must not change width per digit. */
[data-count], .td-tabular, table td, table th { font-variant-numeric: tabular-nums; }

/* ─── keyframes shared across pages ─────────────────────────────────────── */
@keyframes td-pulse { 0%, 100% { opacity: .3; } 50% { opacity: .85; } }
@keyframes td-blink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: .2; } }

/* ─── focus ─────────────────────────────────────────────────────────────────
 * One visible ring, on both directions, for everything focusable. Keyboard
 * users on a security product are not a rounding error.
 */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--td-accent);
  outline-offset: 2px;
  border-radius: var(--td-radius-4);
}

/* ─── overflow containment ──────────────────────────────────────────────────
 * A grid or flex item defaults to min-width:auto, so one long unbreakable
 * string — an API token, a URL, a line of JSON — widens its track and pushes
 * the whole page sideways. These are the guards.
 */
main, article, section, header, footer { min-width: 0; }
pre { max-width: 100%; overflow-x: auto; }
.doc pre, .doc pre code { max-width: 100%; }
.doc p, .doc li, .doc td { overflow-wrap: break-word; }
.doc code { overflow-wrap: anywhere; }

/* ─── docs shell ────────────────────────────────────────────────────────────
 * Sidebar + content + table of contents. The column counts are set inline on
 * each page, so the responsive collapse has to out-specify an inline
 * declaration: !important in a stylesheet beats a normal inline one, and
 * a stylesheet !important beats a normal inline one, and the descendant
 * selector out-specifies the page's own .api-grid rule.
 */
@media (max-width: 1180px) {
  body .api-grid { grid-template-columns: minmax(0, 240px) minmax(0, 1fr) !important; }
  body .toc { display: none !important; }
}

@media (max-width: 900px) {
  body .api-grid,
  body .docs-shell { grid-template-columns: minmax(0, 1fr) !important; }

  /* Stacked above the content it navigates. Bounded and scrollable so a
     forty-link sidebar does not become the page. */
  body .api-grid > aside[aria-label="Documentation"],
  body .docs-shell > aside[aria-label="Documentation"] {
    position: static !important;
    max-height: min(46vh, 320px) !important;
    border-right: 0 !important;
    border-bottom: 1px solid var(--td-line) !important;
    padding-bottom: var(--td-space-16) !important;
  }
}

/* ─── headline rag ──────────────────────────────────────────────────────────
 * Balanced lines. Without this the browser fills each line greedily and drops
 * whatever is left onto the last one, so a headline ends on a single orphaned
 * word — measured on 26 headings across the site. Balancing is capped by the
 * engine at a handful of lines, which is exactly the range headings live in,
 * and it applies between forced breaks so an authored <br> still governs.
 */
h1, h2, h3, [data-balance] { text-wrap: balance; }
p { text-wrap: pretty; }

/* ─── touch targets ─────────────────────────────────────────────────────────
 * A bare <a> in a flex column is only as tall as its line box — the footer's
 * navigation measured 14px per link across every route. WCAG 2.5.8 asks for 24;
 * the padding goes on the link rather than the column so the visual rhythm is
 * unchanged and only the hit area grows.
 */
.td-foot-links a { display: block; padding: 6px 0; }

/* Navigation links that set no padding of their own — breadcrumbs, tables of
 * contents, sidebar trails — render at their line box, about 14px. Block
 * padding grows the hit rectangle; on an inline link it does not affect line
 * height, so nothing moves. A link that already sets its own padding inline
 * keeps it: an inline declaration outranks this one. */
header a, nav a, aside a { padding-block: 5px; }

/* Carousel dots are a 4px bar, and the bar is the button. Padding would fatten
 * the bar itself, so the hit area is extended with a transparent overlay — the
 * control becomes 24px tall while still looking like a 4px rule. */
[role="group"][aria-label="Customer quotes"] button { position: relative; }
[role="group"][aria-label="Customer quotes"] button::after {
  content: ''; position: absolute; inset: -10px 0;
}

/* Everything else that sets no padding of its own: the mono utility links
 * ("EDIT ON GITHUB", "CHANGELOG →") that sit in meta rows. An inline link's
 * layout is unaffected by block padding, so this only grows hit areas. */
:is(a, button):not([style*="padding"]):not([style*="height"]) { padding-block: 5px; }

/* A range input's box is its 4px track. The thumb is grabbable but the control
 * is not, and the ROI calculator is built from four of them. */
input[type="range"] { min-height: 24px; }
.td-foot-meta a { display: inline-flex; align-items: center; min-height: 24px; }

/* ─── narrow-viewport reflow ────────────────────────────────────────────────
 * Rows that read as a single line on a laptop and cannot on a phone. Each of
 * these was measured pushing past the viewport edge at 390px.
 */
@media (max-width: 760px) {
  /* The API endpoint list: method and path stay paired, the description drops
     to its own line rather than shouldering the row 19px past the edge. */
  .ep .desc { flex: 1 1 100%; }
  /* The coverage page's matrix + detail split. A 1.5fr/1fr grid holds its ratio
     at every width, so on a phone the detail column was 129px wide and its
     technique rows hung 94px past the viewport edge. */
  .cov-split { grid-template-columns: minmax(0, 1fr) !important; }
  /* ATT&CK coverage rows: the score and tier chip stack under the technique
     name instead of holding two fixed columns the width cannot pay for. */
  .cov-row { grid-template-columns: minmax(0, 1fr) 72px !important; row-gap: 8px !important; }
}

/* ─── tables ────────────────────────────────────────────────────────────────
 * A comparison table is wider than a phone. Scroll it inside its own box
 * rather than letting it set the page width.
 */
@media (max-width: 760px) {
  .doc table { display: block; overflow-x: auto; white-space: nowrap; }
  .doc table th, .doc table td { white-space: normal; min-width: 128px; }
}

/* ─── motion ────────────────────────────────────────────────────────────────
 * The scroll-reveal keeps its end state; only the travel is removed. Killing
 * the transition outright would leave every revealed section at opacity 0.
 */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ─── print ─────────────────────────────────────────────────────────────────
 * Enterprise buyers print the pricing page and the trust center for review
 * packets. Give them the content without the chrome.
 */
@media print {
  nav, aside, .toc, [aria-label="Theme direction"] { display: none !important; }
  body { background: #fff !important; color: #000 !important; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 10px; }
  section, div { break-inside: avoid-page; }
}
