/* ============================================================================
   Joshua de Freitas — visual system

   One neutral scale, no hue. The palette is cool silver-grey: paper, ink, and
   a narrow band of greys between them. The only "colour" in the document is a
   silver sheen gradient, used on hairlines and on the primary control, never
   on text that has to be read.

   Light is the source of truth. Dark is a remap of the same tokens, not a
   separate design — every rule below reads from custom properties, so nothing
   needs a `[data-theme]` override except the tokens themselves and the two
   places where a blend mode has to flip.
   ========================================================================= */

@font-face {
  font-family: "Newsreader Display";
  font-style: normal;
  font-weight: 300;
  font-display: optional;
  src: url("assets/fonts/newsreader-display-300.woff2") format("woff2");
}

@font-face {
  font-family: "Newsreader Text";
  font-style: normal;
  font-weight: 300;
  font-display: optional;
  src: url("assets/fonts/newsreader-text-300.woff2") format("woff2");
}

@font-face {
  font-family: "Newsreader Text";
  font-style: normal;
  font-weight: 400;
  font-display: optional;
  src: url("assets/fonts/newsreader-text-400.woff2") format("woff2");
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400 500;
  font-display: optional;
  src: url("assets/fonts/inter-latin.woff2") format("woff2");
}

@font-face {
  font-family: "DM Mono";
  font-style: normal;
  font-weight: 400;
  font-display: optional;
  src: url("assets/fonts/dm-mono-latin.woff2") format("woff2");
}

:root {
  /* type */
  --serif: "Newsreader Text", ui-serif, Georgia, "Times New Roman", serif;
  --serif-display: "Newsreader Display", ui-serif, Georgia, "Times New Roman", serif;
  --sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  --mono: "DM Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* measure */
  --shell: 1120px;
  --gutter: clamp(24px, 5vw, 56px);
  --rail: 168px;
  --section-y: clamp(76px, 9vw, 136px);
  --anchor-offset: 96px;

  /* motion */
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* -- light ---------------------------------------------------------------- */
:root,
[data-theme="light"] {
  color-scheme: light;

  --paper: #fafafb;
  --surface: #ffffff;
  --surface-2: #f2f3f5;
  --plate: #101114;

  --ink: #121417;
  --ink-2: #494d54;
  --ink-3: #676c74;

  --line: #cfd4db;
  --line-2: #aeb5bf;
  --line-3: #858d98;
  --silver-edge: #aab1bb;
  --silver-glint: rgba(255, 255, 255, 0.78);

  --sheen: linear-gradient(100deg, #c3c8cf 0%, #f4f5f7 20%, #adb3bb 46%, #eceef1 70%, #bcc1c9 100%);
  --sheen-hair: linear-gradient(90deg, transparent 0%, #c8cdd4 10%, #9da5af 34%, #eef0f3 50%, #969faa 66%, #cbd0d6 90%, transparent 100%);

  --on-accent: #fafafb;
  --accent: #17191d;

  --field-blend: multiply;
  --field-opacity: 0.62;
  --notation-blend: multiply;
  --notation-ink: #272a2f;
  --notation-opacity: 0.47;
  --plate-image: grayscale(1) contrast(1.04);
  --study-image: grayscale(1) invert(1) contrast(0.96);

  /* Raised and inverted blocks. In light these are a real step in value; the
     dark theme redefines them below, because a page that is already dark
     cannot go darker to signal "different". */
  /* Section grounds. Faint enough to read as paper rather than pattern. */
  --hair: rgba(18, 20, 23, 0.07);
  --sheen-soft: rgba(18, 20, 23, 0.06);
  --contour-opacity: 0.72;

  --raised: #f0f1f4;
  --invert-bg: #101114;
  --invert-ink: #f4f5f7;
  --invert-ink-2: #b9bec6;
  --invert-ink-3: #8b9199;
  --invert-line: #393d44;
  --invert-line-2: #555b64;
  --invert-line-3: #757d88;
}

/* -- dark ----------------------------------------------------------------- */
[data-theme="dark"] {
  color-scheme: dark;

  --paper: #0c0d0f;
  --surface: #121316;
  --surface-2: #17191d;
  --plate: #101114;

  --ink: #edeef1;
  --ink-2: #a7acb4;
  --ink-3: #83888f;

  --line: #353941;
  --line-2: #505660;
  --line-3: #737b87;
  --silver-edge: #737b86;
  --silver-glint: rgba(255, 255, 255, 0.11);

  --sheen: linear-gradient(100deg, #565b63 0%, #aab0b9 20%, #6a7079 46%, #c1c7cf 70%, #616770 100%);
  --sheen-hair: linear-gradient(90deg, transparent 0%, #3b4048 10%, #858d98 34%, #c8cdd4 50%, #777f8a 66%, #3e434b 90%, transparent 100%);

  --on-accent: #0c0d0f;
  --accent: #e6e8eb;

  --field-blend: screen;
  --field-opacity: 0.72;
  --notation-blend: screen;
  --notation-ink: var(--ink-2);
  --notation-opacity: 0.38;
  --plate-image: grayscale(1) contrast(1.02) brightness(0.96);
  --study-image: grayscale(1) contrast(1.05);

  --hair: rgba(237, 238, 241, 0.065);
  --sheen-soft: rgba(237, 238, 241, 0.055);
  --contour-opacity: 0.62;

  --raised: #131418;
  --invert-bg: #16181c;
  --invert-ink: #f2f3f5;
  --invert-ink-2: #aeb3bb;
  --invert-ink-3: #888d95;
  --invert-line: #393d44;
  --invert-line-2: #555b64;
  --invert-line-3: #757d88;
}

/* ============================================================================
   Base
   ========================================================================= */

* { box-sizing: border-box; }

/* The `hidden` attribute has to win over any author `display`. Without this,
   a rule like `.field-fallback { display: block }` silently un-hides it. */
[hidden] { display: none !important; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

:where(main[id], section[id]) { scroll-margin-top: var(--anchor-offset); }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink-2);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.65;
  font-feature-settings: "kern" 1, "liga" 1, "calt" 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  transition: background-color 260ms var(--ease), color 260ms var(--ease);
}

h1, h2, h3, h4 {
  margin: 0;
  color: var(--ink);
  font-family: var(--serif);
  font-weight: 300;
  letter-spacing: -0.014em;
  line-height: 1.12;
  text-wrap: balance;
}

h1 { font-family: var(--serif-display); font-size: clamp(46px, 6.4vw, 84px); letter-spacing: -0.028em; line-height: 1.02; }
h2 { font-family: var(--serif-display); font-size: clamp(30px, 3.4vw, 42px); }
h3 { font-size: clamp(21px, 2.1vw, 26px); }
h4 { font-size: 20px; letter-spacing: -0.008em; }

h1 em, h2 em, h3 em { font-style: italic; }

p { margin: 0 0 1.05em; }
p:last-child { margin-bottom: 0; }

a { color: inherit; }

code {
  font-family: var(--mono);
  font-size: 0.88em;
  color: var(--ink);
}

::selection { background: var(--ink); color: var(--paper); }

:focus-visible {
  outline: 1px solid var(--ink);
  outline-offset: 3px;
  border-radius: 1px;
}

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  left: 16px;
  top: -80px;
  z-index: 20;
  padding: 10px 16px;
  background: var(--ink);
  color: var(--paper);
  font-size: 13px;
  text-decoration: none;
  transition: top 180ms var(--ease);
}
.skip-link:focus { top: 14px; }

.shell {
  width: min(var(--shell), calc(100% - (var(--gutter) * 2)));
  margin: 0 auto;
}

.ext {
  display: inline-block;
  font-size: 0.78em;
  vertical-align: 0.12em;
  opacity: 0.5;
}

/* Small technical label. Used for every eyebrow on the page, so there is one
   voice for metadata rather than four. */
.rail-label {
  margin: 0;
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: 11px;
  line-height: 1.5;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* ============================================================================
   Header
   ========================================================================= */

.site-header {
  position: sticky;
  top: 0;
  z-index: 10;
  border-bottom: 1px solid var(--line);
  background: var(--paper); /* fallback where color-mix is unsupported */
  background: color-mix(in srgb, var(--paper) 86%, transparent);
  backdrop-filter: saturate(140%) blur(14px);
  -webkit-backdrop-filter: saturate(140%) blur(14px);
}

.header-inner {
  display: flex;
  align-items: center;
  gap: 32px;
  min-height: 72px;
}

.wordmark {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 11px;
  margin-right: auto;
  color: var(--ink);
  font-family: var(--serif);
  font-size: 19px;
  font-weight: 400;
  letter-spacing: -0.012em;
  text-decoration: none;
  white-space: nowrap;
}
.wordmark-mark {
  width: 36px;
  height: 36px;
  flex: 0 0 auto;
  object-fit: contain;
  transition: filter 260ms var(--ease), opacity 260ms var(--ease);
}
[data-theme="light"] .wordmark-mark { filter: brightness(0.24) contrast(1.18); }
[data-theme="dark"] .wordmark-mark { filter: none; }
.wordmark:hover .wordmark-mark,
.wordmark:focus-visible .wordmark-mark { opacity: 0.82; }
.wordmark::after {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -5px;
  height: 1px;
  background: var(--sheen-hair);
  opacity: 0;
  content: "";
  transition: opacity 220ms var(--ease);
}
.wordmark:hover::after,
.wordmark:focus-visible::after { opacity: 1; }

.site-nav {
  display: flex;
  gap: 30px;
}
.site-nav a {
  position: relative;
  padding: 4px 0;
  color: var(--ink-3);
  font-size: 13px;
  letter-spacing: 0.005em;
  text-decoration: none;
  transition: color 200ms var(--ease);
}
.site-nav a::after {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  content: "";
  transition: transform 240ms var(--ease);
}
.site-nav a:hover,
.site-nav a:focus-visible,
.site-nav a.is-current { color: var(--ink); }
.site-nav a:hover::after,
.site-nav a.is-current::after { transform: scaleX(1); }

.theme-toggle {
  min-width: 74px;
  padding: 7px 14px;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  background: transparent;
  color: var(--ink-3);
  cursor: pointer;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  transition: border-color 200ms var(--ease), color 200ms var(--ease), background-color 200ms var(--ease);
}
.theme-toggle:hover {
  border-color: var(--line-3);
  color: var(--ink);
  background: var(--surface-2);
}

/* ============================================================================
   Hero
   ========================================================================= */

.hero {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: min(900px, 94vh);
  overflow: hidden;
  padding-top: clamp(56px, 9vh, 104px);
  border-bottom: 1px solid var(--line);
}

/* -- the ground ----------------------------------------------------------- */

.hero-field {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

/* The canvas is sized in device pixels by the script; these rules only give
   it a box to measure. */
.hero-field > * {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: var(--field-opacity);
  /* Screen over black in dark, multiply over white in light: either way the
     substrate cancels exactly and only the structure survives. */
  mix-blend-mode: var(--field-blend);
  /* Two masks, intersected. The first thins the field out under the column of
     text and lets it gather on the open right-hand side; the second keeps it
     off the header and dissolves it before the section edge, so it reads as
     ground rather than as a picture with a border. */
  -webkit-mask-image:
    linear-gradient(90deg, transparent 0%, rgba(0,0,0,0.1) 20%, rgba(0,0,0,0.5) 48%, rgba(0,0,0,0.92) 74%, #000 100%),
    linear-gradient(180deg, transparent 0%, #000 20%, #000 66%, transparent 98%);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(90deg, transparent 0%, rgba(0,0,0,0.1) 20%, rgba(0,0,0,0.5) 48%, rgba(0,0,0,0.92) 74%, #000 100%),
    linear-gradient(180deg, transparent 0%, #000 20%, #000 66%, transparent 98%);
  mask-composite: intersect;
}
.hero-field canvas {
  opacity: 0;
  transition: opacity 520ms var(--ease);
}
.hero-field .field-fallback {
  filter: var(--study-image);
  transition: opacity 520ms var(--ease);
}
.hero-field.is-live canvas { opacity: var(--field-opacity); }
.hero-field.is-live .field-fallback { opacity: 0; }

/* -- the copy ------------------------------------------------------------- */

.hero-inner {
  position: relative;
  z-index: 1;
  display: flex;
  flex: 1;
  flex-direction: column;
  justify-content: center;
  padding: clamp(32px, 5vh, 64px) 0;
}

.hero-eyebrow { margin-bottom: clamp(24px, 3vh, 38px); }
.hero-eyebrow i {
  margin: 0 10px;
  color: var(--line-3);
  font-style: normal;
}

.hero h1 {
  max-width: 12ch;
  margin-bottom: clamp(30px, 4vh, 48px);
}

.hero-lede {
  max-width: 22em;
  margin-bottom: 24px;
  color: var(--ink);
  font-family: var(--serif);
  font-size: clamp(21px, 2.15vw, 27px);
  font-weight: 300;
  line-height: 1.42;
  letter-spacing: -0.008em;
  text-wrap: pretty;
}

.hero-supporting {
  max-width: 31em;
  margin-bottom: clamp(32px, 4vh, 46px);
  color: var(--ink-2);
  font-size: 15px;
  line-height: 1.72;
  text-wrap: pretty;
}

/* -- the readout ---------------------------------------------------------- */

.hero-meta {
  position: relative;
  z-index: 1;
  display: flex;
  flex: 0 0 auto;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px 24px;
  padding: 15px 0 20px;
  border-top: 1px solid var(--line);
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.03em;
}

.field-readout {
  display: grid;
  flex: 0 1 auto;
  gap: 5px;
  min-width: 150px;
}

.field-name {
  color: var(--ink);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.field-note { font-size: 9px; letter-spacing: 0.04em; }

.field-controls {
  display: flex;
  flex: 1 1 700px;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 10px 16px;
  margin-left: auto;
}

/* Named field selectors: the label is the control, while the silver rule
   underneath still carries dwell progress. */
.field-segments {
  display: grid;
  grid-template-columns: repeat(4, minmax(92px, 1fr));
  gap: 5px;
}
.field-segments button {
  display: grid;
  min-width: 92px;
  min-height: 35px;
  align-content: space-between;
  gap: 8px;
  padding: 7px 8px 5px;
  border: 1px solid transparent;
  background: none;
  color: var(--ink-3);
  cursor: pointer;
  font: inherit;
  font-size: 9px;
  letter-spacing: 0.04em;
  text-align: left;
  text-decoration: none;
  transition: border-color 180ms var(--ease), color 180ms var(--ease), background-color 180ms var(--ease);
}
.field-segments button:hover,
.field-segments button:focus-visible {
  border-color: var(--line-2);
  color: var(--ink);
  background: var(--surface);
}
.field-segments button:focus-visible {
  outline: 1px solid var(--ink-2);
  outline-offset: 2px;
}
.field-segments button.is-active {
  border-color: var(--line-2);
  color: var(--ink);
  background: var(--surface);
}
.field-segments i {
  position: relative;
  display: block;
  height: 1px;
  background: var(--line-2);
  transition: background-color 200ms var(--ease);
}
.field-segments i::after {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: calc(var(--p, 0) * 100%);
  background: var(--ink-2);
  content: "";
}
.field-segments button:hover i { background: var(--line-3); }
.field-segments button.is-active i::after { background: var(--ink); }

.field-seed-editor {
  display: flex;
  min-height: 35px;
  align-items: center;
  gap: 7px;
  padding: 0 8px;
  border: 1px solid var(--line-2);
  background: var(--surface);
}
.field-seed-editor label {
  color: var(--ink-3);
  font-size: 8px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.field-seed-editor input {
  width: 9.5ch;
  padding: 3px 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-variant-numeric: tabular-nums;
}
.field-seed-editor input[aria-invalid="true"] { color: #a63f3f; }

.field-controls > button,
.field-seed-editor button {
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink-3);
  cursor: pointer;
  font: inherit;
  text-decoration: underline;
  text-decoration-color: var(--line-2);
  text-underline-offset: 0.28em;
  transition: color 200ms var(--ease), text-decoration-color 200ms var(--ease);
}
.field-controls > button:hover,
.field-seed-editor button:hover {
  color: var(--ink);
  text-decoration-color: currentColor;
}

/* ============================================================================
   Controls
   ========================================================================= */

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.button {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  min-height: 44px;
  padding: 0 20px;
  border: 1px solid var(--line-2);
  color: var(--ink);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.004em;
  text-decoration: none;
  white-space: nowrap;
  transition: border-color 220ms var(--ease), background-color 220ms var(--ease), color 220ms var(--ease);
}

.button-primary {
  border-color: transparent;
  background: var(--accent);
  color: var(--on-accent);
  overflow: hidden;
}
/* The one place the silver is allowed to be literal: a sheen that crosses the
   primary control on hover, then leaves. */
.button-primary::after {
  position: absolute;
  inset: 0;
  background: var(--sheen);
  opacity: 0;
  content: "";
  transition: opacity 320ms var(--ease);
  mix-blend-mode: overlay;
}
.button-primary:hover::after,
.button-primary:focus-visible::after { opacity: 0.55; }

.button-secondary { background: transparent; }
.button-secondary:hover,
.button-secondary:focus-visible {
  border-color: var(--line-3);
  background: var(--surface-2);
}

.text-link {
  color: var(--ink);
  font-size: 14px;
  text-decoration: underline;
  text-decoration-color: var(--line-3);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.24em;
  transition: text-decoration-color 200ms var(--ease);
}
.text-link:hover,
.text-link:focus-visible { text-decoration-color: currentColor; }

/* ============================================================================
   Sections — a numbered rail on the left, content on the right

   Separation is carried three ways at once, so the boundaries read even at a
   glance: a step in surface value, a silver hairline across the measure, and
   a numbered rule that sits above each heading.
   ========================================================================= */

.section {
  position: relative;
  isolation: isolate;
  padding: var(--section-y) 0;
  background: var(--paper);
}

/* A hairline that lives inside the measure and fades at both ends, rather
   than a full-width border cutting the page in half. */
.section + .section::before {
  position: absolute;
  top: 0;
  left: 50%;
  z-index: 3;
  width: min(var(--shell), calc(100% - (var(--gutter) * 2)));
  height: 2px;
  background: var(--sheen-hair);
  opacity: 0.82;
  transform: translateX(-50%);
  content: "";
}

.section-raised { background: var(--raised); }

.section-invert {
  background: var(--invert-bg);
  color: var(--invert-ink-2);
  --paper: var(--invert-bg);
  --surface: var(--invert-bg);
  --surface-2: #1d1f24;
  --ink: var(--invert-ink);
  --ink-2: var(--invert-ink-2);
  --ink-3: var(--invert-ink-3);
  --line: var(--invert-line);
  --line-2: var(--invert-line-2);
  --line-3: var(--invert-line-3);
  --accent: var(--invert-ink);
  --on-accent: var(--invert-bg);
  --notation-blend: screen;
  --notation-ink: var(--ink-2);
  --notation-opacity: 0.40;
}
.section-invert::before { background: none; }

.section-inner {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: var(--rail) minmax(0, 1fr);
  gap: 0 clamp(24px, 4vw, 56px);
}

/* ---------------------------------------------------------------------------
   Section grounds

   Each section carries its own quiet texture so the page has somewhere to go
   after the hero. All four are one composited pseudo-element with a transform
   animation — no repaints, no second canvas, nothing for the CPU to do. They
   are deliberately at the edge of visibility: if you notice one, it is wrong.

   `overflow: clip` rather than `hidden`, because `hidden` would make each
   section a scroll container and break the sticky rail labels inside it.
   ------------------------------------------------------------------------- */

.ground { overflow: clip; }
.ground::after {
  position: absolute;
  top: -12%;
  left: -22%;
  z-index: 0;
  width: 148%;
  height: 128%;
  pointer-events: none;
  content: "";
  animation: ground-drift 96s cubic-bezier(0.4, 0, 0.6, 1) infinite alternate;
}

@keyframes ground-drift {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(4.5%, -1.6%, 0); }
}

/* Work — a measured grid, gathered to the open corner. */
.ground-grid::after {
  background-image:
    linear-gradient(to right, var(--hair) 1px, transparent 1px),
    linear-gradient(to bottom, var(--hair) 1px, transparent 1px);
  background-size: 104px 104px;
  -webkit-mask-image: radial-gradient(88% 74% at 84% 22%, #000 0%, transparent 74%);
  mask-image: radial-gradient(88% 74% at 84% 22%, #000 0%, transparent 74%);
}

/* Practice — a single slow band of silver crossing the plate. */
.ground-sheen::after {
  background: linear-gradient(102deg, transparent 8%, var(--sheen-soft) 46%, transparent 82%);
  animation-duration: 64s;
}

/* About — thin topographic rings from crossed centres. The field keeps its
   geometry irregular without placing solid tone beneath long-form copy. */
.ground-contour::after {
  opacity: var(--contour-opacity);
  background-image:
    repeating-radial-gradient(ellipse at 78% 28%, transparent 0 58px, var(--hair) 59px 60px, transparent 61px 96px),
    repeating-radial-gradient(ellipse at 24% 76%, transparent 0 74px, var(--hair) 75px 76px, transparent 77px 122px);
  background-size: 100% 100%;
  background-repeat: no-repeat;
  -webkit-mask-image: linear-gradient(100deg, transparent 6%, #000 46%, #000 72%, transparent 96%);
  mask-image: linear-gradient(100deg, transparent 6%, #000 46%, #000 72%, transparent 96%);
  animation-duration: 120s;
}

/* Contact — one soft light on the dark plate, moving very slightly. */
.ground-glow::after {
  background: radial-gradient(52% 66% at 78% 18%, rgba(196, 202, 210, 0.075), transparent 68%);
  animation-duration: 52s;
}

/* ---------------------------------------------------------------------------
   Technical murmuration

   The notation is generated from a fixed local vocabulary. Each mark follows
   its own deterministic harmonic path, so the motion curls and changes depth
   instead of translating as one flat sheet. Nothing is fetched and the marks
   stay on compositor-friendly transform and opacity animations.
   ------------------------------------------------------------------------- */

.notation-field {
  position: absolute;
  inset: -7% -5%;
  z-index: 1;
  overflow: hidden;
  color: var(--notation-ink);
  opacity: var(--notation-opacity);
  mix-blend-mode: var(--notation-blend);
  pointer-events: none;
  user-select: none;
  contain: paint;
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 7%, #000 93%, transparent 100%);
  mask-image: linear-gradient(180deg, transparent 0%, #000 7%, #000 93%, transparent 100%);
}

.notation-layer {
  position: absolute;
  inset: 0;
}

.notation-mark {
  position: absolute;
  top: var(--y);
  left: var(--x);
  max-width: min(46vw, 560px);
  opacity: 0.72;
  font-family: var(--mono);
  font-size: var(--size);
  font-weight: 400;
  line-height: 1.25;
  letter-spacing: 0.035em;
  white-space: nowrap;
  transform: translate3d(0, 0, 0) rotate(var(--tilt)) scale(0.9);
  transform-origin: 50% 50%;
  will-change: transform, opacity;
}
.notation-mark.is-equation {
  font-family: var(--serif);
  font-size: var(--size);
  font-style: italic;
  letter-spacing: 0.015em;
}
.notation-mark.is-code { letter-spacing: 0.01em; }
.notation-mark.is-tensor {
  padding: 4px 9px;
}
.notation-mark.is-tensor::before,
.notation-mark.is-tensor::after {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 5px;
  border-top: 1px solid currentColor;
  border-bottom: 1px solid currentColor;
  content: "";
}
.notation-mark.is-tensor::before {
  left: 0;
  border-left: 1px solid currentColor;
}
.notation-mark.is-tensor::after {
  right: 0;
  border-right: 1px solid currentColor;
}
.notation-mark.is-split { padding-top: 7px; }
.notation-mark.is-split::before,
.notation-mark.is-split::after {
  position: absolute;
  top: 0;
  height: 1px;
  background: currentColor;
  content: "";
}
.notation-mark.is-split::before { left: 0; width: 43%; }
.notation-mark.is-split::after { right: 0; width: 39%; }

.rail { position: relative; }
.section-inner > .rail .rail-label {
  position: sticky;
  top: 104px;
}

.column { min-width: 0; }

.section-head {
  margin-bottom: clamp(44px, 5vw, 68px);
  padding-top: 22px;
  border-top: 1.5px solid var(--line-2);
}
.section-head h2 { margin-bottom: 18px; }

.section-summary {
  max-width: 34em;
  color: var(--ink-2);
  font-size: 16px;
  line-height: 1.7;
  text-wrap: pretty;
}

/* ============================================================================
   Work
   ========================================================================= */

.stream + .stream { margin-top: clamp(56px, 6vw, 88px); }

.stream-head {
  margin-bottom: 30px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--line);
}
.stream-head h3 {
  margin-bottom: 8px;
  font-size: 22px;
  letter-spacing: -0.006em;
}
.stream-head p {
  max-width: 40em;
  color: var(--ink-3);
  font-size: 14px;
  line-height: 1.65;
}

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: clamp(20px, 2.4vw, 32px);
}

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  border: 1.5px solid var(--line-2);
  background: var(--surface);
  box-shadow:
    inset 0 1px 0 var(--silver-glint),
    0 0 0 0.5px color-mix(in srgb, var(--silver-edge) 24%, transparent);
  transition: border-color 260ms var(--ease), background-color 260ms var(--ease), box-shadow 260ms var(--ease);
}
.card:hover {
  border-color: var(--line-3);
  box-shadow:
    inset 0 1px 0 var(--silver-glint),
    0 0 0 0.5px color-mix(in srgb, var(--silver-edge) 48%, transparent);
}

.card-visual {
  position: relative;
  display: grid;
  min-height: 188px;
  margin: 0;
  overflow: hidden;
  padding: 18px;
  border-bottom: 1.5px solid var(--line-2);
  background: var(--plate);
}
.card-visual img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.study-visual img { filter: grayscale(1) contrast(1.06); opacity: 0.9; }
.tool-visual { padding: 0; }
.tool-visual img { position: relative; filter: var(--plate-image); }

.visual-kicker,
.visual-caption {
  position: relative;
  z-index: 1;
  color: #8f959d;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.visual-caption { align-self: end; }

/* DeepLOB plate: the actual evaluation failure, not a generic market chart.
   The vertical rule is the train/validation boundary. Randomly scattered,
   near-duplicate windows cross it; a purge and embargo leave a visible gap. */
.lob-visual {
  background:
    radial-gradient(circle at 74% 12%, rgba(196, 202, 210, 0.08), transparent 44%),
    var(--plate);
}
.lob-study {
  position: absolute;
  top: 48px;
  right: 18px;
  bottom: 34px;
  left: 18px;
  display: grid;
  grid-template-rows: 1fr 1fr;
  gap: 12px;
}
.lob-boundary {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 63%;
  z-index: 2;
  width: 1px;
  border-left: 1px dashed rgba(214, 219, 226, 0.34);
  pointer-events: none;
}
.lob-boundary span {
  position: absolute;
  top: -13px;
  color: rgba(196, 202, 210, 0.56);
  font-family: var(--mono);
  font-size: 8px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.lob-boundary span:first-child { right: 9px; }
.lob-boundary span:last-child { left: 9px; }
.lob-protocol {
  position: relative;
  min-height: 0;
}
.lob-protocol-label {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  color: rgba(214, 219, 226, 0.72);
  font-family: var(--mono);
  font-size: 8.5px;
  letter-spacing: 0.06em;
  line-height: 1;
  text-transform: uppercase;
}
.lob-protocol-label b {
  color: #d7dbe1;
  font-weight: 400;
}
.lob-windows {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  height: 24px;
}
.lob-windows i {
  position: absolute;
  display: block;
  height: 7px;
  border: 1px solid rgba(196, 202, 210, 0.2);
  background: rgba(196, 202, 210, 0.13);
}
.lob-protocol-random .lob-windows i::after {
  position: absolute;
  top: -1px;
  right: -1px;
  bottom: -1px;
  width: 31%;
  border: 1px solid rgba(232, 235, 239, 0.34);
  background: rgba(232, 235, 239, 0.24);
  content: "";
}
.lob-protocol-random .lob-windows i:nth-child(1) { top: 0; left: 4%; width: 72%; }
.lob-protocol-random .lob-windows i:nth-child(2) { top: 5px; left: 18%; width: 67%; }
.lob-protocol-random .lob-windows i:nth-child(3) { top: 10px; left: 31%; width: 61%; }
.lob-protocol-random .lob-windows i:nth-child(4) { top: 15px; left: 43%; width: 52%; }
.lob-protocol-purged .lob-windows i:nth-child(1) { top: 0; left: 3%; width: 43%; }
.lob-protocol-purged .lob-windows i:nth-child(2) { top: 7px; left: 14%; width: 37%; }
.lob-protocol-purged .lob-windows i:nth-child(3) { top: 0; left: 70%; width: 26%; }
.lob-protocol-purged .lob-windows i:nth-child(4) { top: 7px; left: 76%; width: 20%; }
.lob-protocol-purged .lob-windows::after {
  position: absolute;
  top: -2px;
  bottom: 4px;
  left: 54%;
  width: 10%;
  background: repeating-linear-gradient(135deg, transparent 0 4px, rgba(196, 202, 210, 0.11) 4px 5px);
  content: "";
}

/* dbx-core plate */
.core-grid {
  position: absolute;
  inset: 0;
  opacity: 0.5;
  background-image:
    linear-gradient(rgba(170, 177, 186, 0.1) 1px, transparent 1px),
    linear-gradient(90deg, rgba(170, 177, 186, 0.1) 1px, transparent 1px);
  background-size: 32px 32px;
  mask-image: linear-gradient(to top right, #000, transparent 74%);
}
.core-pipeline {
  position: relative;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  align-content: center;
  gap: 10px;
  color: #dfe2e7;
  font-family: var(--mono);
  font-size: clamp(13px, 1.5vw, 17px);
  letter-spacing: 0.04em;
}
.core-pipeline i {
  flex: 1 1 20px;
  min-width: 20px;
  height: 1px;
  background: rgba(196, 202, 210, 0.45);
}

.card-body {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 14px;
  padding: clamp(22px, 2.4vw, 30px);
}

.card-heading {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px 16px;
}
.card-tag {
  display: inline-flex;
  align-items: baseline;
  gap: 10px;
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}
.live-badge {
  padding: 2px 7px;
  border: 1px solid var(--line-2);
  color: var(--ink-2);
  font-weight: 400;
  letter-spacing: 0.05em;
  text-transform: none;
}

.card-body > p {
  margin: 0;
  color: var(--ink-2);
  font-size: 15px;
  line-height: 1.68;
  text-wrap: pretty;
}

.card-body > .card-limit {
  padding-top: 14px;
  border-top: 1px solid var(--line);
  color: var(--ink-3);
  font-size: 13.5px;
  line-height: 1.6;
}
.card-limit span {
  color: var(--ink);
  font-weight: 500;
}

.card-terminal {
  position: relative;
  margin: 0;
  padding: 14px 62px 14px 16px;
  overflow-x: auto;
  border: 1px solid var(--line-2);
  background: var(--surface-2);
  font-family: var(--mono);
  font-size: 12.5px;
  line-height: 1.5;
}
.card-terminal code { color: var(--ink-2); white-space: pre; }
.copy-btn {
  position: absolute;
  top: 9px;
  right: 9px;
  padding: 4px 9px;
  border: 1px solid var(--line-2);
  background: var(--surface);
  color: var(--ink-3);
  cursor: pointer;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  transition: color 200ms var(--ease), border-color 200ms var(--ease);
}
.copy-btn:hover { color: var(--ink); border-color: var(--line-3); }

.card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.06em;
}
.card-meta span { position: relative; }
.card-meta span + span::before {
  position: absolute;
  left: -10px;
  content: "·";
  color: var(--line-3);
}

.card-links {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 24px;
  margin-top: auto;
  padding-top: 6px;
}

/* ============================================================================
   Practice
   ========================================================================= */

.principles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: clamp(24px, 3vw, 40px);
  margin: 0 0 clamp(64px, 7vw, 100px);
  padding: 0;
  list-style: none;
}
.principle {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  gap: 0 8px;
  padding-top: 18px;
  border-top: 1.5px solid var(--line-2);
}
.principle-no {
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
}
.principle strong {
  display: block;
  margin-bottom: 8px;
  color: var(--ink);
  font-family: var(--serif);
  font-size: 19px;
  font-weight: 400;
  letter-spacing: -0.008em;
}
.principle p {
  margin: 0;
  color: var(--ink-2);
  font-size: 14.5px;
  line-height: 1.65;
}

/* ============================================================================
   About
   ========================================================================= */

.prose {
  max-width: 38em;
  color: var(--ink-2);
  font-size: 16.5px;
  line-height: 1.78;
  text-wrap: pretty;
}
.prose p + p { margin-top: 1.15em; }
.prose .professional-boundary {
  margin-top: 1.65em;
  padding-top: 1.25em;
  border-top: 1.5px solid var(--line-2);
  color: var(--ink-3);
  font-size: 14px;
  line-height: 1.65;
}

.facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 0 clamp(24px, 3vw, 44px);
  margin: clamp(44px, 5vw, 64px) 0 0;
}
.facts > div {
  padding: 18px 0;
  border-top: 1px solid var(--line);
}
.facts dt {
  margin-bottom: 6px;
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.facts dd {
  margin: 0;
  color: var(--ink-2);
  font-size: 14.5px;
  line-height: 1.65;
}
.facts-date {
  display: block;
  margin-top: 4px;
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.06em;
}

/* ============================================================================
   Contact
   ========================================================================= */

.contact-address {
  margin-bottom: 26px;
  font-family: var(--mono);
  font-size: clamp(15px, 1.7vw, 19px);
  letter-spacing: -0.01em;
}
.contact-address .text-link { font-size: inherit; }

/* ============================================================================
   Footer
   ========================================================================= */

/* The footer continues the inverted block the contact section opens, so the
   page closes on one dark plate instead of two stacked edges. */
.site-footer {
  padding: 30px 0 44px;
  background: var(--invert-bg);
  color: var(--invert-ink-3);
}
.footer-inner {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 10px 32px;
  padding-top: 26px;
  border-top: 1px solid var(--invert-line);
  font-size: 12.5px;
}

/* ============================================================================
   Reveal — opacity and a two-pixel lift, nothing more
   ========================================================================= */

.reveal {
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 620ms var(--ease), transform 620ms var(--ease);
}
.reveal.is-in {
  opacity: 1;
  transform: none;
}

/* ============================================================================
   Responsive
   ========================================================================= */

@media (max-width: 900px) {
  :root { --rail: 0px; --anchor-offset: 124px; }

  .section-inner {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
  }
  .rail { margin-bottom: 26px; }
  .hero { min-height: 0; padding-bottom: 8px; }
  .hero h1 { max-width: none; }
  .section-inner > .rail .rail-label { position: static; }

  /* The nav stays — it just moves to its own row and scrolls sideways if it
     has to. Hiding it behind a menu would be one more thing to open. */
  .header-inner {
    flex-wrap: wrap;
    gap: 0 16px;
    padding: 14px 0 0;
  }
  .wordmark { order: 1; }
  .theme-toggle { order: 2; }
  .site-nav {
    order: 3;
    width: 100%;
    gap: 22px;
    margin-top: 12px;
    padding-bottom: 10px;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .site-nav::-webkit-scrollbar { display: none; }
  .site-nav a { white-space: nowrap; }
}

@media (max-width: 560px) {
  body { font-size: 15.5px; }
  .notation-field { inset-inline: -18%; opacity: calc(var(--notation-opacity) * 0.78); }
  .notation-layer .notation-mark:nth-child(n + 7) { display: none; }
  .ground-contour::after { display: none; }
  .card-visual { min-height: 148px; }
  .lob-study { top: 43px; right: 16px; bottom: 29px; left: 16px; gap: 9px; }
  .lob-protocol-label { font-size: 7.8px; }
  .lob-boundary span { font-size: 7px; }
  .principle { grid-template-columns: minmax(0, 1fr); gap: 6px; }
  .field-readout { flex: 1 1 100%; }
  .field-controls { margin-left: 0; justify-content: flex-start; }
  .field-segments { flex: 1 1 100%; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .field-segments button { width: 100%; min-width: 0; }
  .hero-inner .button-primary { flex: 1 1 100%; }
  .hero-inner .button-secondary { flex: 1 1 calc(50% - 5px); }
}

@media (max-width: 380px) {
  .field-controls {
    width: 100%;
    flex-wrap: wrap;
    justify-content: flex-start;
    gap: 10px 18px;
  }
  .field-seed-editor { flex: 1 1 auto; }
}

/* ============================================================================
   Print and reduced motion
   ========================================================================= */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .notation-field { display: none; }
  .reveal { opacity: 1; transform: none; }
}

@media print {
  .site-header, .hero-field, .hero-meta, .notation-field, .theme-toggle, .copy-btn { display: none; }
  body { background: #fff; color: #000; }
}
