/* Base layer: reset, typography, shared layout, helpers, motion guards, print.
   Owned by Agent 1. Everyone builds on these. */

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html {
  font-size: calc(100% * var(--text-scale));
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  color-scheme: dark;
  /* Keep anchor targets and focused items clear of the fixed deck (WCAG 2.4.11). */
  scroll-padding-top: calc(var(--deck-h, 4.5rem) + 1rem);
  scroll-padding-bottom: 2rem;
}
:root[data-motion="full"]:not([data-calm="on"]) { scroll-behavior: smooth; }

body {
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.6;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}
img, picture, video, canvas, svg { display: block; max-width: 100%; }
img, video { height: auto; }
input, button, textarea, select { font: inherit; color: inherit; }
button { cursor: pointer; }
p, h1, h2, h3, h4, h5, h6 { overflow-wrap: break-word; }
p, li, dd { max-width: var(--measure); }
h1, h2, h3, h4 {
  font-family: var(--font-display);
  line-height: 1.15;
  letter-spacing: -0.01em;
  text-wrap: balance;
}
p { text-wrap: pretty; }
ul[role="list"], ol[role="list"] { list-style: none; padding: 0; }
strong, b { font-weight: 600; }
hr { border: 0; border-top: 1px solid var(--line); }
::selection { background: var(--accent-3); color: var(--on-accent); }

a { color: var(--accent-2); text-decoration-thickness: 1px; text-underline-offset: 0.2em; }
a:hover { text-decoration-thickness: 2px; }

/* ---------- Readable font mode ---------- */
:root[data-font="readable"] {
  --font-body: var(--font-readable);
  --font-display: var(--font-readable);
}
:root[data-font="readable"] body {
  letter-spacing: 0.02em;
  word-spacing: 0.08em;
  line-height: 1.8;
}
:root[data-font="readable"] h1,
:root[data-font="readable"] h2,
:root[data-font="readable"] h3,
:root[data-font="readable"] h4 { letter-spacing: 0.01em; line-height: 1.3; }

/* ---------- Helpers ---------- */
.visually-hidden:not(:focus):not(:active) {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0 0 0 0) !important;
  clip-path: inset(50%) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

.skip-link {
  position: fixed;
  top: var(--space-3);
  left: var(--space-3);
  z-index: 1000;
  padding: var(--space-3) var(--space-5);
  background: var(--focus-ring);
  color: #000;
  font-weight: 600;
  border-radius: var(--radius-sm);
  text-decoration: none;
  transform: translateY(calc(-100% - 2rem));
}
.skip-link:focus { transform: none; }

:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 3px;
}
:focus:not(:focus-visible) { outline: none; }
#main:focus { outline: none; }

/* Unfilled facts Jon needs to supply. Loud on purpose. */
.placeholder {
  display: inline;
  padding: 0.05em 0.4em;
  border: 1px dashed var(--placeholder-text);
  border-radius: 4px;
  background: var(--placeholder-bg);
  color: var(--placeholder-text);
  font-family: var(--font-mono);
  font-size: 0.85em;
  font-weight: 400;
  letter-spacing: 0;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 2.75rem;
  min-width: 2.75rem;
  padding: 0.6rem 1.2rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--text);
  font-family: var(--font-body);
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  transition: border-color var(--dur-fast) ease, background-color var(--dur-fast) ease, scale var(--dur-fast) var(--ease-out);
}
.btn:hover { border-color: var(--accent-2); }
.btn:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 3px; }
.btn svg { width: 1.15em; height: 1.15em; flex: none; }
.btn--primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.btn--primary:hover { border-color: var(--text); }
.btn--ghost { background: transparent; }
:root[data-motion="full"]:not([data-calm="on"]) .btn:active { scale: 0.97; }
:root[data-contrast="high"] .btn { border-width: 2px; border-color: var(--text); }

/* ---------- Track (section) layout ----------
   .track centres its content with inline padding, so backgrounds can still
   run full bleed. Wrap content in .track__inner if you prefer a box. */
.track {
  position: relative;
  padding-block: clamp(4.5rem, 10vw, 8rem);
  padding-inline: max(var(--space-4), calc((100% - var(--content-max)) / 2));
  scroll-margin-top: 0;
}
.track__inner { width: 100%; max-width: var(--content-max); margin-inline: auto; }
.track__header { max-width: 48rem; margin-bottom: clamp(2.5rem, 5vw, 4rem); }
.track__number {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  margin-bottom: var(--space-4);
  padding: 0.3em 0.9em 0.3em 0.45em;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: 0.875rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
/* A tiny record label before the track number. */
.track__number::before {
  content: "";
  width: 1.2em;
  height: 1.2em;
  flex: none;
  border-radius: 50%;
  background:
    radial-gradient(circle, var(--bg) 0 12%, var(--accent) 13% 38%, var(--vinyl) 39% 100%);
  box-shadow: 0 0 0 1px var(--vinyl-groove);
}
.track__title {
  font-family: var(--font-display);
  font-size: clamp(2.25rem, 1.6rem + 3.4vw, 4.5rem);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.02em;
}
:root[data-font="readable"] .track__title { letter-spacing: 0; line-height: 1.15; }
.track__lede {
  margin-top: var(--space-4);
  max-width: 60ch;
  color: var(--text-muted);
  font-size: clamp(1.125rem, 1rem + 0.5vw, 1.375rem);
  line-height: 1.5;
}

/* ---------- Decorative film grain ---------- */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .9 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
:root[data-calm="on"] body::before,
:root[data-contrast="high"] body::before { display: none; }

/* ---------- Ambient glow that re-tints with the active track ----------
   --track-hue is a registered <number> (js/motion.js), so it animates.
   Decorative only: it sits behind everything. */
:root[data-motion="full"]:not([data-calm="on"]) { transition: --track-hue 900ms var(--ease-out); }
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background:
    radial-gradient(60vmax 45vmax at 88% 6%, var(--tint, transparent), transparent 70%),
    radial-gradient(50vmax 40vmax at 6% 96%, var(--tint, transparent), transparent 70%);
  background:
    radial-gradient(60vmax 45vmax at 88% 6% in oklch, var(--tint, transparent), transparent 70%),
    radial-gradient(50vmax 40vmax at 6% 96% in oklch, var(--tint, transparent), transparent 70%);
}
:root[data-contrast="high"] body::after { display: none; }

/* ---------- Glass utility ----------
   Fill, blur, 1px gradient border, inset bezel highlight, shadow and a specular
   hotspot at var(--mx) var(--my) (set by js/motion.js under a fine pointer).
   Put body text on .glass--strong (or var(--glass-fill-strong)) so it passes 4.5:1. */
:where(.glass) { position: relative; isolation: isolate; border-radius: var(--radius); }
.glass {
  background: var(--glass-fill);
  border: 1px solid var(--glass-border);
  box-shadow: var(--glass-highlight), var(--glass-shadow);
}
.glass--strong { background: var(--glass-fill-strong); }
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .glass {
    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.4);
    backdrop-filter: blur(var(--glass-blur)) saturate(1.4);
  }
}
@supports ((mask-composite: exclude) or (-webkit-mask-composite: xor)) {
  .glass { border-color: transparent; }
  .glass::before {
    content: "";
    position: absolute;
    inset: -1px;
    z-index: -1;
    padding: 1px;
    border-radius: inherit;
    pointer-events: none;
    background: linear-gradient(160deg, rgb(255 255 255 / .4), var(--glass-border) 35%, rgb(255 255 255 / .03) 70%, rgb(255 255 255 / .18));
    background: linear-gradient(in oklch 160deg, rgb(255 255 255 / .4), var(--glass-border) 35%, rgb(255 255 255 / .03) 70%, rgb(255 255 255 / .18));
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  }
}
.glass::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  pointer-events: none;
  background: radial-gradient(circle 16rem at var(--mx, 30%) var(--my, 0%), rgb(255 255 255 / .1), transparent 70%);
  transition: opacity var(--dur) ease;
}
:root[data-calm="on"] .glass::after,
:root[data-contrast="high"] .glass::before,
:root[data-contrast="high"] .glass::after { display: none; }
:root[data-contrast="high"] .glass {
  background: #000;
  border: 1px solid #fff;
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
:root[data-calm="on"] .glass { box-shadow: var(--glass-highlight); }

/* Root view transition (used by JR.motion.transition, e.g. contrast and calm changes). */
::view-transition-old(root),
::view-transition-new(root) { animation-duration: 420ms; animation-timing-function: var(--ease-out); }

/* ---------- Scroll reveal (driven by js/motion.js) ----------
   Content is visible by default. Only when motion.js adds .reveal-ready
   (motion OK) are un-revealed items hidden. Uses the individual translate
   and scale properties so your own transform is left alone. */
.reveal-ready [data-reveal] {
  transition:
    opacity var(--dur-slow) var(--ease-out),
    translate var(--dur-slow) var(--ease-out),
    scale var(--dur-slow) var(--ease-out);
}
.reveal-ready [data-reveal]:not(.is-revealed) { opacity: 0; translate: 0 1.75rem; }
.reveal-ready [data-reveal="left"]:not(.is-revealed) { translate: -2.5rem 0; }
.reveal-ready [data-reveal="right"]:not(.is-revealed) { translate: 2.5rem 0; }
.reveal-ready [data-reveal="scale"]:not(.is-revealed) { translate: none; scale: 0.94; }
[data-reveal].is-revealed { opacity: 1; translate: none; scale: none; }

/* ---------- Motion guards ----------
   Reduced motion or calm mode: everything stills. Focus styles are outlines,
   so they stay visible. */
:root[data-motion="reduced"] *,
:root[data-motion="reduced"] *::before,
:root[data-motion="reduced"] *::after,
:root[data-calm="on"] *,
:root[data-calm="on"] *::before,
:root[data-calm="on"] *::after {
  animation-duration: 0.001ms !important;
  animation-delay: 0s !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.001ms !important;
  transition-delay: 0s !important;
  scroll-behavior: auto !important;
}
/* Safety net when scripts are off and the OS asks for less motion. */
@media (prefers-reduced-motion: reduce) {
  :root:not(.js) *,
  :root:not(.js) *::before,
  :root:not(.js) *::after {
    animation-duration: 0.001ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    transition-delay: 0s !important;
    scroll-behavior: auto !important;
  }
}

/* ---------- Windows high contrast ---------- */
@media (forced-colors: active) {
  .placeholder { border: 1px dashed CanvasText; }
  body::before { display: none; }
}

/* ---------- Print: a clean CV ---------- */
@media print {
  :root {
    --bg: #fff; --bg-deep: #fff; --surface: #fff; --surface-2: #fff;
    --text: #000; --text-muted: #222; --line: #999;
    --accent: #000; --accent-2: #000; --accent-3: #000;
    --text-scale: 1;
  }
  html { font-size: 11pt; }
  body { background: #fff !important; color: #000 !important; line-height: 1.45; }
  body::before, body::after, .glass::before, .glass::after,
  .skip-link, .deck, .booth, .booth-trigger,
  [data-parallax], [data-print="hide"],
  canvas, video { display: none !important; }
  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
    box-shadow: none !important;
    text-shadow: none !important;
  }
  .glass { background: #fff !important; border: 1px solid #999 !important; backdrop-filter: none !important; }
  [data-reveal] { opacity: 1 !important; translate: none !important; scale: none !important; }
  .track { padding: 0 0 1.5rem; break-inside: auto; }
  .track__header { margin-bottom: 0.75rem; }
  .track__title { font-size: 20pt; }
  .track__number { border: 0; padding: 0; color: #000; }
  .track__number::before { display: none; }
  h2, h3 { break-after: avoid; }
  li, figure, blockquote { break-inside: avoid; }
  a { color: #000; text-decoration: underline; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 0.85em; word-break: break-all; }
  .placeholder { background: #fff; color: #000; border-color: #000; }
}
