/* ─────────────────────────────────────────────────────────────
   Alpha Foundation — Design Tokens
   Single source of truth. Import into any page with:
     <link rel="stylesheet" href="./tokens.css">
   Mirrors the values used across company_page, research, daily_brief,
   knowledge_map and the ACE decks in Prototype web design 2/.
   Light mode only — no prefers-color-scheme:dark blocks.
   ───────────────────────────────────────────────────────────── */

:root {
  /* ── Surfaces ────────────────────────────────── */
  --bg:      #F7F6F2;   /* page background — warm off-white */
  --bg2:     #EEEDEA;   /* secondary surface (row hover, chips) */
  --bg3:     #E5E4DF;   /* tertiary surface (tracks, wells) */
  --paper:   #FDFCF9;   /* elevated card surface */
  --ink:     #1E1E1C;   /* dark fill (verdict cards, dark buttons) */

  /* ── Text ────────────────────────────────────── */
  --tx:      #1E1E1C;   /* primary */
  --tx2:     #5A5956;   /* secondary */
  --tx3:     #8C8B87;   /* tertiary / labels */
  --tx4:     #9A9995;   /* muted — decorative only, fails AA on paper */

  /* ── Borders (all 0.5px) ─────────────────────── */
  --bd:      rgba(0,0,0,0.09);  /* standard hairline */
  --bd2:     rgba(0,0,0,0.20);  /* emphasized card edges, headers */

  /* ── Semantic accents ────────────────────────── */
  --green:   #1B7A4A;   /* logo / label green (deep) */
  --green2:  #2A9E62;   /* primary positive / LONG */
  --amber:   #BA7517;   /* WATCH / caution */
  --red:     #C4302B;   /* AVOID / negative */
  --blue:    #378ADD;   /* informational */
  --teal:    #1D9E75;
  --purple:  #5F3DC4;

  /* ── Tinted backgrounds (semantic wells) ─────── */
  --bgGreen:  #E8F5EC;
  --bgAmber:  #FBF0DC;
  --bgRed:    #FCEBEB;
  --bgInfo:   #E6F1FB;
  --bgPurple: #EEEDFE;
  --bgTeal:   #E1F5EE;

  /* Directional helpers — override inline on a row/card */
  --direction-color: var(--green2);
  --direction-bg:    var(--bgGreen);

  /* ── Type ────────────────────────────────────── */
  --ff-serif: 'DM Serif Display', Georgia, serif;   /* headings, tickers, large numbers */
  --ff-sans:  'DM Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; /* body, UI */
  --ff-mono:  'DM Mono', ui-monospace, 'SF Mono', Menlo, monospace; /* prices, data, timestamps */

  /* Type scale — collapsed to a strict ladder.
     UI copy lives on 10/11/12/13/14/16/18.
     Serif display has exactly TWO sizes: display & hero.
     The gap between them carries the drama — do not invent sizes in between. */
  --fs-eyebrow:  10px;  /* uppercase labels */
  --fs-caption:  11px;
  --fs-micro:    12px;  /* dense tables, metadata */
  --fs-body:     13px;  /* default UI */
  --fs-body-lg:  14px;  /* report body */
  --fs-h5:       16px;
  --fs-h4:       18px;
  --fs-display:  24px;  /* metric tiles, section ticker numbers, card headers */
  --fs-hero:     48px;  /* EV returns, cover tickers — one per viewport, ideally */

  /* Back-compat aliases — prefer --fs-display / --fs-hero in new code. */
  --fs-h3: var(--fs-display);
  --fs-h2: var(--fs-display);
  --fs-h1: var(--fs-hero);

  /* Eyebrow convention */
  --eyebrow-weight: 600;
  --eyebrow-tracking: 1px;

  /* ── Radii ───────────────────────────────────── */
  --r-xs:  4px;    /* tiny chips */
  --r-sm:  6px;    /* buttons, filter selects */
  --r-md:  8px;    /* hinge boxes */
  --r-lg:  10px;   /* data wells, stat strips */
  --r-xl:  12px;   /* cards (default) */
  --r-2xl: 14px;   /* stacked research cards */
  --r-pill: 999px;

  /* ── Spacing (4px baseline) ──────────────────── */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 20px;
  --sp-6: 24px;
  --sp-7: 28px;   /* page gutter (left/right) */
  --sp-8: 32px;
  --sp-10: 40px;
  --sp-12: 48px;  /* nav gap between logo + links */
  --sp-16: 60px;

  /* Layout rails */
  --page-max:      960px;   /* tab content (Research, Financials, Full Report) */
  --brief-max:    1080px;   /* Daily Brief two-col */
  --nav-height:     56px;
  --subnav-height:  46px;

  /* ── Elevation ───────────────────────────────── */
  --sh-1: 0 1px 4px rgba(0,0,0,0.04);
  --sh-2: 0 1px 8px rgba(0,0,0,0.04);
  --sh-3: 0 2px 12px rgba(0,0,0,0.05);                             /* default card */
  --sh-4: 0 4px 16px rgba(0,0,0,0.08);                             /* hover */
  --sh-5: 0 4px 20px rgba(0,0,0,0.05), 0 1px 3px rgba(0,0,0,0.04); /* stacked research card — stack implies elevation, shadow is supporting */
  --sh-6: 0 8px 28px rgba(0,0,0,0.08), 0 2px 5px rgba(0,0,0,0.05); /* stacked card hover */

  /* ── Motion ──────────────────────────────────── */
  --ease:        cubic-bezier(.4, 0, .2, 1);        /* default UI */
  --ease-out:    cubic-bezier(0.34, 1.56, 0.64, 1); /* slight overshoot — pills, chips */
  --ease-ink:    cubic-bezier(.2, .7, .2, 1);       /* editorial, page-turn feel */
  --ease-paper:  cubic-bezier(.22, 1, .36, 1);      /* card settle, bar fill */
  --dur-fast:    120ms;
  --dur-med:     200ms;
  --dur-slow:    350ms;
  --dur-xslow:   1000ms;  /* bar-fill reveal on card load */

  /* ── Texture ─────────────────────────────────── */
  --grain-opacity: 0.035;   /* whisper grain; raise to ~0.08 for "editorial" intensity */
}

/* ── Paper texture ──────────────────────────────
   A 1–2% fractal-noise grain painted over the page background.
   SVG is inlined as a data URL so no network hit. Opacity is
   variable so a page can dial it up locally. Layered via ::before
   on the <body> so it sits behind everything. */
body { position: relative; }
body::before {
  content: '';
  position: fixed; inset: 0;
  pointer-events: none;
  z-index: 0;
  opacity: var(--grain-opacity);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.12  0 0 0 0 0.12  0 0 0 0 0.10  0 0 0 0.9 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  mix-blend-mode: multiply;
}
body > * { position: relative; z-index: 1; }

@media (prefers-reduced-motion: reduce) {
  body::before { display: none; }
}

/* Reset primitives used everywhere */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body { background: var(--bg); color: var(--tx); }
body { font-family: var(--ff-sans); -webkit-font-smoothing: antialiased; line-height: 1.5; }

/* ── Conventions (reference implementations) ─────────────────
   These are not a component library — they are the baseline
   shapes that every page re-uses. Mirror, don't import blind.
   ───────────────────────────────────────────────────────────── */

/* Eyebrow label — the ubiquitous 10px uppercase divider */
.eyebrow {
  font-size: var(--fs-eyebrow);
  font-weight: var(--eyebrow-weight);
  text-transform: uppercase;
  letter-spacing: var(--eyebrow-tracking);
  color: var(--tx3);
}
.eyebrow.with-rule {
  display: flex; align-items: center; gap: 8px;
}
.eyebrow.with-rule::after {
  content: ''; flex: 1; height: 0.5px;
  background: linear-gradient(90deg, var(--bd2), transparent);
}

/* Card — default elevated surface */
.card {
  background: var(--paper);
  border: 0.5px solid var(--bd2);
  border-radius: var(--r-xl);
  box-shadow: var(--sh-3);
}

/* Note / hinge box — thesis commentary and interpretive callouts.
   Four variants by role: good / warn / bad / info. The left-bar is
   the note pattern's signature — tinted pills elsewhere stay flat
   and do not borrow this treatment. */
.note {
  background: var(--bg2);
  border-left: 3px solid var(--green2);
  border-radius: var(--r-md);
  padding: 11px 13px;
  font-size: var(--fs-body);
  color: var(--tx2);
  line-height: 1.55;
}
.note.good { background: var(--bgGreen); border-left-color: var(--green2); }
.note.warn { background: var(--bgAmber); border-left-color: var(--amber); }
.note.bad  { background: var(--bgRed);   border-left-color: var(--red); }
.note.info { background: var(--bgInfo);  border-left-color: var(--blue); }

/* Legacy alias — prefer .note in new code. */
.hinge { background: var(--bg2); border-left: 3px solid var(--green2); border-radius: var(--r-md); padding: 11px 13px; font-size: var(--fs-body); color: var(--tx2); line-height: 1.55; }
.hinge.amber { background: var(--bgAmber); border-left-color: var(--amber); }
.hinge.red   { background: var(--bgRed);   border-left-color: var(--red); }

/* Status pills — the four-state direction system.
   LONG / WATCH / AVOID are filled; NEUTRAL is outlined so "covered but
   no active verdict" doesn't overload WATCH's "thesis-at-risk" meaning. */
.pill {
  display: inline-flex; align-items: center;
  font-family: var(--ff-sans);
  font-size: var(--fs-eyebrow);
  font-weight: 500;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  padding: 4px 10px;
  border-radius: var(--r-sm);
}
.pill.long    { background: var(--bgGreen); color: var(--green); }
.pill.watch   { background: var(--bgAmber); color: var(--amber); }
.pill.avoid   { background: var(--bgRed);   color: var(--red); }
.pill.info    { background: var(--bgInfo);  color: var(--blue); }
.pill.neutral { background: var(--paper);   color: var(--tx2); border: 0.5px solid var(--bd2); padding: 3px 9px; }

/* ACE mono tag — the tiny code-like badge on ACE deck tabs.
   Quieted down: tinted fill OR border, not both. */
.ace-tag {
  font-family: var(--ff-mono);
  font-size: 8px;
  font-weight: 600;
  letter-spacing: 0.4px;
  background: var(--bgGreen);
  color: var(--green);
  padding: 2px 5px;
  border-radius: 3px;
  text-transform: uppercase;
}
.ace-tag.amber { background: var(--bgAmber); color: var(--amber); }

/* Buttons */
.btn-ghost {
  font-family: var(--ff-sans);
  font-size: var(--fs-micro);
  font-weight: 500;
  color: var(--tx2);
  background: none;
  border: 0.5px solid var(--bd2);
  border-radius: var(--r-sm);
  padding: 6px 14px;
  cursor: pointer;
  transition: background var(--dur-fast);
}
.btn-ghost:hover { background: var(--bg2); }

.btn-dark {
  font-family: var(--ff-sans);
  font-size: var(--fs-micro);
  font-weight: 500;
  color: var(--paper);
  background: var(--ink);
  border: none;
  border-radius: var(--r-sm);
  padding: 7px 16px;
  cursor: pointer;
}

/* Data / price numerals — always monospace */
.num { font-family: var(--ff-mono); font-variant-numeric: tabular-nums; }
.num.pos { color: var(--green2); }
.num.neg { color: var(--red); }
.num.wat { color: var(--amber); }

/* Serif display — tickers, EV returns, cover headings.
   Only two sizes by design: .display (24px) and .display.hero (48px).
   .xl/.lg/.md kept as legacy aliases mapping onto the two real sizes. */
.display     { font-family: var(--ff-serif); letter-spacing: -0.4px; line-height: 1; font-size: var(--fs-display); }
.display.hero{ font-size: var(--fs-hero); letter-spacing: -1.2px; }
.display.xl  { font-size: var(--fs-hero); letter-spacing: -1.2px; }
.display.lg  { font-size: var(--fs-display); letter-spacing: -0.4px; }
.display.md  { font-size: var(--fs-display); letter-spacing: -0.4px; }

/* Standard 52W range bar (schematic) */
.range-track {
  height: 4px; background: var(--bg3); border-radius: 2px;
  position: relative; overflow: visible;
}
.range-fill {
  position: absolute; left: 0; top: 0; bottom: 0;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--green2), #3DB87A);
  transition: width var(--dur-xslow) 300ms var(--ease);
}
.range-fill.watch { background: linear-gradient(90deg, var(--amber), #E0A030); }
.range-fill.avoid { background: linear-gradient(90deg, var(--red),   #E05050); }
.range-thumb {
  position: absolute; top: 50%; width: 11px; height: 11px;
  border-radius: 50%;
  border: 2px solid var(--paper);
  box-shadow: 0 1px 4px rgba(0,0,0,0.2);
  transform: translate(-50%, -50%);
  background: var(--green2);
}

/* Conviction dots (5-step) */
.dots { display: flex; gap: 4px; align-items: center; }
.dot {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--bg3); border: 0.5px solid var(--bd);
  transition: transform var(--dur-med) var(--ease-out), background-color var(--dur-med) var(--ease);
}
.dot.on        { background: var(--green2); border-color: var(--green2); }
.dot.on.amber  { background: var(--amber);  border-color: var(--amber); }
.dot.on.red    { background: var(--red);    border-color: var(--red); }

/* ── Motion primitives ─────────────────────────────
   Shared utility classes + keyframes used across pages.
   Every motion respects prefers-reduced-motion at the bottom. */

/* Arrival: fade + 4px rise, 260ms. Stagger via animation-delay inline. */
@keyframes af-arrive {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.af-arrive { animation: af-arrive 340ms var(--ease-paper) both; }

/* Ink-bleed: used by the αf· logo on load — mark settles from
   slightly blurred + transparent to crisp + full colour. */
@keyframes af-ink {
  0%   { opacity: 0; filter: blur(6px); transform: translateY(2px); letter-spacing: -0.6em; }
  55%  { opacity: 1; filter: blur(1px); letter-spacing: normal; }
  100% { opacity: 1; filter: blur(0);   transform: translateY(0); letter-spacing: normal; }
}
.af-ink { animation: af-ink 820ms var(--ease-ink) both; }

/* Hairline pulse: border weight briefly thickens then releases — the
   "look haptic" click response. Applied by JS on mousedown. */
@keyframes af-pulse {
  0%   { box-shadow: 0 0 0 0   rgba(0,0,0,0);    }
  40%  { box-shadow: 0 0 0 2px rgba(0,0,0,0.14); }
  100% { box-shadow: 0 0 0 0   rgba(0,0,0,0);    }
}
.af-pulsing { animation: af-pulse 420ms var(--ease-paper); }

/* Ripple: cousin of hairline-pulse, for larger click targets. Uses a
   child span positioned by JS at the click point. */
.af-ripple-host { position: relative; overflow: hidden; }
.af-ripple {
  position: absolute; width: 6px; height: 6px; border-radius: 50%;
  background: currentColor; opacity: 0.18;
  transform: translate(-50%, -50%) scale(0);
  animation: af-ripple 480ms var(--ease-paper) forwards;
  pointer-events: none;
}
@keyframes af-ripple {
  to { transform: translate(-50%, -50%) scale(28); opacity: 0; }
}

/* Count-up: number flips through increments. JS fills innerText; this
   just smooths the transition if the number is swapped atomically. */
@keyframes af-count-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}
.af-count { display: inline-block; animation: af-count-in 320ms var(--ease-paper); }

/* Reveal a stroke (used for sparkline + chart line draw-in). Set
   stroke-dasharray / stroke-dashoffset inline to the path length. */
@keyframes af-draw {
  to { stroke-dashoffset: 0; }
}
.af-draw { animation: af-draw 900ms var(--ease-paper) 80ms forwards; }

/* Reduced motion: keep fades, lose translations, scales and overshoot.
   Durations shortened so state changes still feel responsive. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 120ms !important;
  }
  .af-ink, .af-arrive, .af-count { animation: none; opacity: 1; transform: none; }
  .af-ripple, .af-pulsing { display: none; }
}
