/* shared.css — The Desk design system v2 (editorial / Swiss-modernist) */
@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;600;700&family=JetBrains+Mono:wght@300;400;500;700&display=swap');

:root {
  /* ── Surface ── */
  --bg:        #ffffff;
  --bg-soft:   #fafafa;
  --bg-warm:   #f6f3ed;        /* faint cream — used sparingly */
  --bg-inv:    #000000;        /* inverted dark blocks */
  --bg-inv-2:  #141414;

  /* ── Ink ── */
  --ink:       #000000;
  --ink-2:     #3a3a3a;
  --ink-3:     #707070;
  --ink-4:     #a8a8a8;
  --ink-on-dark:     #fafafa;
  --ink-on-dark-2:   rgba(250,250,250,0.72);
  --ink-on-dark-3:   rgba(250,250,250,0.42);

  /* ── Rules ── */
  --rule:      #000000;
  --rule-2:    #d4d4d4;
  --rule-3:    #ececec;

  /* ── Type stack ── */
  --font-display: 'Space Grotesk', sans-serif;
  --font-sans:    'Space Grotesk', sans-serif;
  --font-mono:    'JetBrains Mono', monospace;

  /* ── Legacy aliases (so older inline CSS still resolves) ── */
  --bg2:       var(--bg-soft);
  --bg3:       var(--bg-warm);
  --bg4:       var(--bg-inv);
  --text:      var(--ink);
  --muted:     var(--ink-3);
  --border:    var(--rule-2);
  --border2:   var(--rule-3);
  --green:     var(--ink);
  --blue:      var(--ink);
  --red:       var(--ink);
  --amber:     var(--ink);
  --cyan:      var(--ink);
  --glow-g:    transparent;
  --glow-b:    transparent;
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }

/* ── Dark mode ── a single full-page invert. The site is monochrome, so
   inverting the root flips paper→black, ink→white, the gridlines, the tape
   boxes, the nav, and the (line-art) logo all at once — "the other way".
   Applied to <html> specifically so position:fixed (the nav) keeps working. */
html.theme-dark { background: #ffffff; filter: invert(1) hue-rotate(180deg); }
body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-sans);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  min-height: 100vh;
}
::selection { background: var(--ink); color: var(--bg); }
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: var(--bg); }
::-webkit-scrollbar-thumb { background: var(--ink-4); }
::-webkit-scrollbar-thumb:hover { background: var(--ink-3); }

a { color: inherit; }

/* ── Typography helpers ── */
.font-mono    { font-family: var(--font-mono); }
.font-display { font-family: var(--font-display); }
.font-sans    { font-family: var(--font-sans); }

/* Editorial section mark: "—— 01" */
.section-mark {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink);
  display: inline-flex;
  align-items: center;
  gap: 14px;
}
.section-mark::before {
  content: '';
  width: 28px; height: 1px;
  background: var(--ink);
  display: inline-block;
}

/* Small caps editorial label */
.label {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink);
  font-weight: 500;
}
.label--muted { color: var(--ink-3); }

/* Display headings */
.display-xl {
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: -0.035em;
  line-height: 0.95;
}
.display-l {
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 1.0;
}
.display-m {
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: -0.025em;
  line-height: 1.05;
}

/* Editorial big number (à la Goldman annual report) */
.editorial-num {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -0.04em;
  line-height: 0.9;
  font-variant-numeric: tabular-nums lining-nums;
}

/* Hairline rules */
.hairline      { border: none; border-top: 1px solid var(--rule-2); }
.hairline-bold { border: none; border-top: 1px solid var(--ink); }

/* Buttons (editorial, no rounded, no shadow) */
.btn-primary {
  display: inline-block;
  padding: 16px 36px;
  background: var(--ink);
  color: var(--bg);
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-decoration: none;
  border: 1px solid var(--ink);
  cursor: pointer;
  transition: background 0.2s, color 0.2s;
}
.btn-primary:hover { background: transparent; color: var(--ink); }

.btn-ghost {
  display: inline-block;
  padding: 16px 36px;
  background: transparent;
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-decoration: none;
  border: 1px solid var(--ink);
  cursor: pointer;
  transition: background 0.2s, color 0.2s;
}
.btn-ghost:hover { background: var(--ink); color: var(--bg); }

/* Inverted variants for dark sections */
.btn-primary--inv { background: var(--bg); color: var(--ink); border-color: var(--bg); }
.btn-primary--inv:hover { background: transparent; color: var(--bg); }
.btn-ghost--inv   { color: var(--bg); border-color: var(--bg); }
.btn-ghost--inv:hover { background: var(--bg); color: var(--ink); }

/* Stat directions — communicated by glyph, not color */
.stat-up::before   { content: '↑ '; font-family: var(--font-mono); }
.stat-down::before { content: '↓ '; font-family: var(--font-mono); }
.stat-neu          { font-family: var(--font-mono); }

/* Cards */
.card {
  background: var(--bg);
  border: 1px solid var(--rule-2);
  padding: 32px 36px;
  transition: border-color 0.2s;
}
.card:hover { border-color: var(--ink); }

/* Page scaffolding */
.page-wrap {
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 56px;
}

.page-header {
  border-bottom: 1px solid var(--ink);
  padding: 56px 0 40px;
}
.page-header .label { margin-bottom: 14px; }
.page-header h1 {
  font-family: var(--font-display);
  font-size: 56px;
  font-weight: 500;
  letter-spacing: -0.035em;
  line-height: 1.0;
  color: var(--ink);
  margin-bottom: 18px;
}
.page-header p {
  font-size: 15px;
  color: var(--ink-2);
  max-width: 640px;
  line-height: 1.65;
  font-weight: 400;
}

/* Section header */
.section-header { margin-bottom: 64px; }
.section-header .section-mark { margin-bottom: 24px; }
.section-header h2 {
  font-family: var(--font-display);
  font-size: 48px;
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 1.05;
  color: var(--ink);
}
.section-header p {
  margin-top: 18px;
  font-size: 15px;
  color: var(--ink-2);
  max-width: 580px;
  line-height: 1.65;
}

/* Animations */
@keyframes ticker {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes pulse-dot {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.3; }
}
@keyframes drift-grid {
  from { background-position: 0 0; }
  to   { background-position: 0 80px; }
}

/* Wireframe-grid background utility */
.wire-grid {
  background-image:
    linear-gradient(to right,  rgba(10,10,10,0.06) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(10,10,10,0.06) 1px, transparent 1px);
  background-size: 80px 80px;
}

/* Taped label — black box, white text, inverted grid texture. Reusable on any
   headline (wrap the word/phrase in <span class="tape">). box-decoration-break
   clones the tape across wrapped lines. Grid scales with font-size (em). */
.tape {
  background-color: var(--ink);
  color: var(--bg);
  background-image:
    linear-gradient(to right,  rgba(250,250,250,0.15) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(250,250,250,0.15) 1px, transparent 1px);
  background-size: 0.5em 0.5em;
  padding: 0.02em 0.18em;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

/* ───────────────────────────────────────────────────────────────────────────
   Scroll-reveal — elements rise + fade in as they enter the viewport.
   Gated behind .js-reveal (set by reveal.js) so content is NEVER hidden if the
   script fails or is absent. reveal.js skips hiding entirely under reduced-motion.
   ─────────────────────────────────────────────────────────────────────────── */
.js-reveal .reveal {
  opacity: 0;
  transform: translateY(34px);
  filter: blur(10px);
  transition: opacity 0.8s cubic-bezier(0.2, 0.7, 0.2, 1),
              transform 0.8s cubic-bezier(0.2, 0.7, 0.2, 1),
              filter 0.8s cubic-bezier(0.2, 0.7, 0.2, 1);
  will-change: opacity, transform, filter;
}
.js-reveal .reveal.in { opacity: 1; transform: none; filter: blur(0); }
.js-reveal .reveal.d1 { transition-delay: 0.08s; }
.js-reveal .reveal.d2 { transition-delay: 0.16s; }
.js-reveal .reveal.d3 { transition-delay: 0.24s; }
.js-reveal .reveal.d4 { transition-delay: 0.32s; }

@media (prefers-reduced-motion: reduce) {
  .js-reveal .reveal { opacity: 1; transform: none; filter: none; transition: none; }
}

/* ───────────────────────────────────────────────────────────────────────────
   Page-header entrance — a drastic load-in so each page's header "arrives".
   Pure CSS (auto-plays on load), so it works on every page incl. static ones.
   ─────────────────────────────────────────────────────────────────────────── */
@keyframes header-in {
  from { opacity: 0; transform: translateY(48px); filter: blur(18px); }
  to   { opacity: 1; transform: none;             filter: blur(0); }
}
.page-header .label,
.page-header h1,
.page-header p {
  animation: header-in 0.85s cubic-bezier(0.2, 0.75, 0.2, 1) both;
}
.page-header h1 { animation-delay: 0.06s; }
.page-header p  { animation-delay: 0.18s; }

/* Cross-page transition — a quick crossfade between documents in browsers that
   support cross-document View Transitions (Chromium). Degrades to an instant
   nav elsewhere. The header-in above supplies the drama on arrival. */
@view-transition { navigation: auto; }
@keyframes vt-out { to   { opacity: 0; } }
@keyframes vt-in  { from { opacity: 0; } }
::view-transition-old(root) { animation: vt-out 0.22s ease both; }
::view-transition-new(root) { animation: vt-in  0.34s ease both; }

@media (prefers-reduced-motion: reduce) {
  .page-header .label, .page-header h1, .page-header p { animation: none; }
  ::view-transition-old(root), ::view-transition-new(root) { animation: none; }
}

/* ───────────────────────────────────────────────────────────────────────────
   iPhone-portrait breakpoint. ≤640px catches every iPhone in portrait
   (375 SE, 390 14, 393 14 Pro, 402 15 Pro Max, 430 14 Pro Max landscape on
   narrow). Tablet portrait (~768px) and the existing per-page 900px
   breakpoint sit above this and still apply.
   ─────────────────────────────────────────────────────────────────────────── */
@media (max-width: 640px) {
  .page-wrap          { padding: 0 18px; }
  .page-header        { padding: 32px 0 24px; }
  .page-header h1     { font-size: 34px; line-height: 1.05; margin-bottom: 12px; }
  .page-header p      { font-size: 14px; line-height: 1.55; }
  .section-header     { margin-bottom: 36px; }
  .section-header h2  { font-size: 28px; line-height: 1.1; }
  .section-header p   { font-size: 14px; margin-top: 12px; }

  .card               { padding: 20px 22px; }

  .btn-primary,
  .btn-ghost          { padding: 14px 22px; font-size: 10px; letter-spacing: 0.14em; }
  .btn-primary--inv,
  .btn-ghost--inv     { padding: 14px 22px; font-size: 10px; letter-spacing: 0.14em; }

  /* Allow long mono strings (IDs, hashes) to wrap instead of overflowing. */
  .font-mono          { word-break: break-word; }
}
