/* ===========================================================================
   PORTFOLEO DESIGN SYSTEM v1 — "THE INSTRUMENT"  ·  BASE LAYER
   ---------------------------------------------------------------------------
   Reset · typography defaults · focus rings · selection · scrollbars ·
   reduced motion · reduced transparency · print.

   REQUIRES tokens.css to be loaded FIRST. This file declares no colours of its
   own except the two literals the token layer cannot express (a pure-black
   shadow and a mask stop); every other value is a var().

   Load order on both surfaces:
       tokens.css  ->  base.css  ->  components.css  ->  page css
   =========================================================================== */

/* ---------------------------------------------------------------------------
   1. RESET
   Minimal and explicit. No normalize.css, no vendor reset — one more file to
   audit for a CDN reference and a pile of rules for elements we never ship.
   --------------------------------------------------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; }

html,
body,
h1, h2, h3, h4, h5, h6,
p, figure, blockquote, dl, dd,
ul, ol, fieldset, legend, pre { margin: 0; padding: 0; }

ul[role="list"],
ol[role="list"] { list-style: none; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  tab-size: 2;
  color-scheme: dark;                 /* form controls + scrollbars follow    */
}

img, svg, video, canvas, audio, iframe, embed, object {
  display: block;
  max-width: 100%;
}
img, video { height: auto; }

input, button, textarea, select {
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
}
button { background: none; border: 0; }

table { border-collapse: collapse; border-spacing: 0; }
th { text-align: left; font-weight: inherit; }

hr {
  border: 0;
  border-top: var(--bw-hair) solid var(--ln-200);
  height: 0;
}

[hidden] { display: none !important; }


/* ---------------------------------------------------------------------------
   2. TYPOGRAPHY DEFAULTS  (spec s3.2, s3.4)

   MONO IS THE DEFAULT FOR THE ENTIRE PRODUCT. Sans appears in exactly four
   places: copilot/EXPLAIN prose >= 2 sentences, docs and legal pages,
   marketing display headings, and marketing body copy. On the marketing site
   the rule that makes the two surfaces feel like one product is:
       anything the PRODUCT would say is mono;
       anything PORTFOLEO-THE-COMPANY says is sans.

   LIGATURES OFF, GLOBALLY, IN MONO. The vendored JetBrains Mono ships GSUB
   ['calt','ccmp','frac','locl'] and `calt` drives its programming ligatures
   (-> => != <= >= -- //). A headline containing "->", a filing snippet, a
   filter expression or a range containing "<=" MUST render as typed. This is
   a data-fidelity bug in a product whose brand is "the numbers are true", not
   a taste preference.
   --------------------------------------------------------------------------- */
:root,
body {
  font-variant-ligatures: none;
}

body {
  background: var(--s-000);
  color: var(--t-100);
  font: var(--ti-sm);
  font-variant-ligatures: none;
  font-feature-settings: "tnum" 1, "calt" 0, "liga" 0, "clig" 0, "dlig" 0, "frac" 0;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-wrap: break-word;
}

/* THE DATA PLANE — every table cell, every numeric readout.
   "frac" 0 matters: 1/2 in a ratio column must not become a vulgar fraction. */
.dt,
.dt td,
.dt th,
.num,
.mono,
.prov-chip,
.cmd-badge,
.rail-tile .px,
input,
textarea,
select,
pre,
code,
kbd,
samp {
  font-family: var(--f-mono);
  font-variant-ligatures: none;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1, "calt" 0, "liga" 0, "clig" 0, "dlig" 0, "frac" 0;
}

/* THE PROSE PLANE — sans. Figures inside prose still align.                  */
.prose,
.copilot-answer,
.doc,
.legal,
.marketing-body,
.sans {
  font-family: var(--f-sans);
  font-variation-settings: "wght" 400, "wdth" 100;
  font-size: var(--td-body-size);
  line-height: var(--td-body-lh);
  letter-spacing: var(--td-body-track);
  font-variant-numeric: tabular-nums;
  color: var(--t-200);
}
.prose > * + *,
.marketing-body > * + * { margin-top: var(--sp-4); }
.prose strong,
.marketing-body strong { color: var(--t-100); font-variation-settings: "wght" 600, "wdth" 100; }

/* DISPLAY. Weight is set with font-variation-settings, never font-weight —
   it is the only way to reach 380 / 420 / 560 on the Archivo wght axis.
   BUT font-weight must still be neutralised. The UA stylesheet sets
   `h1..h6 { font-weight: bold }`, and font-variation-settings only overrides
   the axis on the VARIABLE font. Under `font-display: swap` the first paint is
   the FALLBACK (system-ui) rendered at 700, which then snaps to Archivo at
   380 — a heavy-to-light jump on the LCP element plus the reflow that comes
   with it. Declaring 400 makes the fallback match the intended optical weight
   and leaves font-variation-settings in sole charge of the real axis.        */
h1, h2, h3, h4, h5, h6 {
  font-family: var(--f-display);
  color: var(--t-100);
  font-weight: 400;
}

h1 {
  font-size: var(--td-1-size);
  font-variation-settings: "wght" var(--td-1-wght), "wdth" var(--td-1-wdth);
  letter-spacing: var(--td-1-track);
  line-height: var(--td-1-lh);
}
h2 {
  font-size: var(--td-2-size);
  font-variation-settings: "wght" var(--td-2-wght), "wdth" var(--td-2-wdth);
  letter-spacing: var(--td-2-track);
  line-height: var(--td-2-lh);
}
h3 {
  font-size: var(--td-3-size);
  font-variation-settings: "wght" var(--td-3-wght), "wdth" var(--td-3-wdth);
  letter-spacing: var(--td-3-track);
  line-height: var(--td-3-lh);
}
h4 {
  font-size: var(--td-4-size);
  font-variation-settings: "wght" var(--td-4-wght), "wdth" var(--td-4-wdth);
  letter-spacing: var(--td-4-track);
  line-height: var(--td-4-lh);
}
h5, h6 {
  font-size: var(--td-small-size);
  font-variation-settings: "wght" 600, "wdth" 100;
  letter-spacing: 0;
  line-height: var(--td-small-lh);
}

/* The eyebrow is MONO — it is the voice of the machine.                      */
.eyebrow {
  font-family: var(--f-mono);
  font-size: var(--td-eyebrow-size);
  font-weight: var(--td-eyebrow-wt);
  letter-spacing: var(--td-eyebrow-track);
  line-height: var(--td-eyebrow-lh);
  text-transform: uppercase;
  color: var(--t-300);
}

small, .small {
  font-size: var(--td-small-size);
  line-height: var(--td-small-lh);
  color: var(--t-300);
}

/* Links. --info is the prose link colour (9.10:1 on void, 8.36:1 on --s-100);
   amber links are reserved for the eleven rationed uses.                     */
a {
  color: var(--info);
  text-decoration: none;
  text-underline-offset: 2px;
  transition: color var(--dur-1) var(--ease);
}
a:hover { color: var(--t-100); text-decoration: underline; }
a.a-amber { color: var(--ac); }
a.a-amber:hover { color: var(--ac-bri); }

b, strong { font-weight: 600; }

code, kbd, samp, pre { font-size: .95em; }
pre {
  background: var(--s-void);
  box-shadow: var(--sh-well);
  padding: var(--sp-3);
  overflow-x: auto;
  color: var(--t-200);
}

abbr[title] { text-decoration: underline dotted; cursor: help; }

/* Numbers. The direction glyph is a LAW, not a decoration: colour is
   redundant reinforcement because no green/red pair survives deuteranopia.
   Signed numbers always print the sign, including "+".                       */
.num { font-variant-numeric: tabular-nums; text-align: right; }
.up  { color: var(--up); }
.dn,
.down { color: var(--down); }
.dir-up::before   { content: "\25B2"; font-size: .78em; margin-right: .28em; }
.dir-down::before { content: "\25BC"; font-size: .78em; margin-right: .28em; }


/* ---------------------------------------------------------------------------
   3. FOCUS  (spec s5.3)
   Vercel's two-ring pattern: an inner ring in the surface colour so the accent
   ring never touches the control's own edge. Zero layout shift — it is a
   box-shadow, not an outline width change.
   Note the :focus-visible / :focus split: pointer users never see a ring,
   keyboard users always do.
   --------------------------------------------------------------------------- */
:focus { outline: none; }

:focus-visible {
  outline: none;
  box-shadow: var(--sh-focus-ring);
  border-radius: inherit;
}

/* Forced-colors (Windows high contrast) removes box-shadows entirely, so the
   ring must come back as a real outline or keyboard focus disappears.        */
@media (forced-colors: active) {
  :focus-visible { outline: 2px solid Highlight; outline-offset: 1px; }
}

/* Skip link — visible only on focus, and it lands ON the accent so it is
   unmissable. --on-ac on --ac measures 9.68:1.                               */
.skip-link {
  position: absolute;
  left: var(--sp-2);
  top: calc(-1 * var(--sp-12));
  z-index: var(--z-tooltip);
  background: var(--ac);
  color: var(--on-ac);
  font: var(--ti-xs);
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-0);
  transition: top var(--dur-2) var(--ease);
}
.skip-link:focus { top: var(--sp-2); }


/* ---------------------------------------------------------------------------
   4. SELECTION  (one of the eleven rationed amber uses)
   --------------------------------------------------------------------------- */
::selection {
  background: var(--ac);
  color: var(--on-ac);
  text-shadow: none;
}


/* ---------------------------------------------------------------------------
   5. PLACEHOLDERS
   --t-400 is NON-TEXT ONLY (3.55:1 on --s-100), and a placeholder is not
   information — it is a hint that disappears the moment it matters. It is the
   one approved use of --t-400 on a text-shaped element. Never put a REQUIRED
   instruction in a placeholder; use a label.
   --------------------------------------------------------------------------- */
::placeholder { color: var(--t-400); opacity: 1; }


/* ---------------------------------------------------------------------------
   6. SCROLLBARS
   Standards-track first, WebKit fallback second. Thin, neutral, and NEVER
   amber — a scrollbar is not one of the eleven.
   --------------------------------------------------------------------------- */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--ln-400) transparent;
}
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--ln-400);
  border: 3px solid transparent;
  background-clip: content-box;
  border-radius: var(--r-pill);
}
::-webkit-scrollbar-thumb:hover { background: var(--t-400); background-clip: content-box; }
::-webkit-scrollbar-corner { background: transparent; }

/* The data well keeps a darker track so the scrollbar does not glow against
   pure black.                                                               */
.well::-webkit-scrollbar-track,
.win-body-data::-webkit-scrollbar-track { background: var(--s-void); }


/* ---------------------------------------------------------------------------
   7. THE GRAIN  (spec s5.6) — INSTRUMENT PLANE ONLY
   One fixed div, inline SVG turbulence as a data URI: no request, no CDN.
   It must never composite over a table, a chart canvas or a number — grain
   over a 12px digit is a legibility cost paid for an aesthetic. In the
   terminal it is scoped to `.desktop > .grain` and sits BELOW `.win`.
   --------------------------------------------------------------------------- */
.grain {
  position: fixed;
  inset: 0;
  z-index: var(--z-grain);
  pointer-events: none;
  mix-blend-mode: overlay;
  opacity: var(--grain-opacity);
  background-size: var(--grain-size) var(--grain-size);
  background-image: var(--grain-url);
}
@media (prefers-reduced-transparency: reduce) {
  .grain { display: none; }
}


/* ---------------------------------------------------------------------------
   8. LAYOUT HELPERS the two surfaces both need
   --------------------------------------------------------------------------- */
.wrap {
  width: 100%;
  max-width: var(--site-maxw);
  margin-inline: auto;
  padding-inline: var(--site-gutter);
}
.stack > * + * { margin-top: var(--sp-4); }
.row { display: flex; align-items: center; gap: var(--sp-2); }
.spacer { flex: 1 1 auto; }
.scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.fade-x {
  -webkit-mask-image: var(--m-fade-x);
  mask-image: var(--m-fade-x);
}
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

@media (max-width: 820px) {
  :root { --section-y: var(--sp-14); }
}

/* Hairlines get physically thinner on hi-dpi panels (Linear's
   --border-hairline). 1px on a 2dppx display is 2 device px and reads heavy. */
@media (min-resolution: 2dppx) {
  .win { box-shadow: var(--sh-panel-hidpi); }
}


/* ---------------------------------------------------------------------------
   9. REDUCED MOTION  (spec s6.5)
   The tape and the hero cold-open are the two that matter — both are the kind
   of persistent motion that triggers vestibular symptoms. Every bespoke
   animation must add its own line here.
   --------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  html { scroll-behavior: auto; }

  .tape-track { animation: none !important; }        /* the marquee stops     */
  .hero-cold-open { --co-autoplay: 0; }              /* hero types nothing    */

  /* The value flash becomes a static 2px left mark instead of a decay.       */
  .dt td[data-tick] {
    animation: none !important;
    box-shadow: inset 2px 0 0 0 currentColor;
  }
  /* The indeterminate panel loader freezes at a static 30% bar.              */
  .panel-loading::after { animation: none !important; width: 30%; }
  /* The prose skeleton stops sweeping but stays visible.                     */
  .skeleton { animation: none !important; }
}

/* ADDITIONAL INSTRUMENT RULE: every infinite animation pauses on :hover and
   when the document is hidden. There is exactly one infinite animation in the
   product (the tape) and one on the site (the tape). JS sets data-hidden on
   <html> from a visibilitychange listener.                                   */
.tape:hover .tape-track,
html[data-hidden="1"] .tape-track { animation-play-state: paused; }


/* ---------------------------------------------------------------------------
   10. PRINT  (spec s2.10 exception 2)
   Statements and risk reports get printed and emailed. Invert to a light
   ground, drop every shadow / grain / gradient, force hairline rules, and
   expand link targets so a printed page is self-describing.
   MEASURED on #ffffff: ink 18.88:1 · ink-2 7.46:1 · ink-3 4.54:1.
   --------------------------------------------------------------------------- */
@media print {
  @page { margin: 14mm; }

  html, body {
    background: var(--print-bg) !important;
    color: var(--print-ink) !important;
  }
  * {
    background-image: none !important;
    box-shadow: none !important;
    text-shadow: none !important;
    backdrop-filter: none !important;
    color-adjust: exact;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  .grain,
  .tape,
  .hintbar,
  .cmdbar,
  .toast-stack,
  .modal-scrim,
  .palette-overlay,
  .skip-link,
  nav,
  .no-print { display: none !important; }

  a { color: var(--print-ink) !important; text-decoration: underline; }
  a[href^="http"]::after {
    content: " <" attr(href) ">";
    font-size: 9px;
    color: var(--print-ink-2);
  }

  .win,
  .panel,
  .card {
    background: var(--print-bg) !important;
    border: 1px solid var(--print-rule) !important;
    break-inside: avoid;
  }
  .win-title { background: var(--print-bg) !important; color: var(--print-ink) !important; }

  /* The table keeps its metronome but loses the well. NO ZEBRA in print
     either — the previous #fafafa print zebra is deleted by design.          */
  .dt { background: var(--print-bg) !important; }
  .dt th,
  .dt td {
    background: var(--print-bg) !important;
    color: var(--print-ink) !important;
    border-color: var(--print-rule) !important;
  }
  .dt thead th { border-bottom: 1px solid var(--print-ink-2) !important; }
  .dt tbody tr { break-inside: avoid; }

  .up, .dn, .down { color: var(--print-ink) !important; }   /* glyph carries it */
  .t-300, .meta, .prov-chip { color: var(--print-ink-3) !important; }

  /* Provenance survives printing — it is the whole point of the product.     */
  .prov-chip {
    border: 1px solid var(--print-rule) !important;
    color: var(--print-ink-2) !important;
  }
  .prov-chip::before { background: var(--print-ink-2) !important; }

  thead { display: table-header-group; }
  tfoot { display: table-footer-group; }
}
