@font-face {
  font-family: "Baskervville";
  src: url("/fonts/baskervville.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Baskervville";
  src: url("/fonts/baskervville-600.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Baskervville";
  src: url("/fonts/baskervville-italic.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Jost";
  src: url("/fonts/jost-300.woff2") format("woff2");
  font-weight: 300;
  size-adjust: 113%;
  font-style: normal;
  font-display: swap;
}

/* Black is Lane. Blue is the agent, on nothing Lane wrote. */
:root {
  --ink: #202526;
  --quiet: #59636a;
  --line: #202526;
  --paper: #fff;
  --accent: #1e3fae;
  --gutter: clamp(1.25rem, 4vw, 3.5rem);
  --serif: "Baskervville", "Libre Baskerville", Baskerville, Georgia, serif;
  --label: "Jost", "Futura", "Helvetica Neue", Arial, sans-serif;
}

*, *::before, *::after { box-sizing: border-box; }

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

body {
  margin: 0;
  overflow-x: hidden;
  background: var(--paper);
  color: var(--ink);
  font: 400 1.25rem/1.55 var(--serif);
  font-variant-numeric: lining-nums;
}

a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 0.16em; }
a:hover { text-decoration-thickness: 2px; }
a:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }

.top {
  position: relative;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.25rem 1.5rem;
  padding: 1rem var(--gutter);
  font: 300 0.8125rem/1.5 var(--label);
}
.top, .reach, .log dt, .axis, .mark b, .foot { letter-spacing: 0.06em; }
.top .name { text-decoration: none; }
.top nav { display: flex; flex-wrap: wrap; gap: 0.25rem 1.25rem; }
.top nav a { text-decoration: none; white-space: nowrap; }
.top nav a:hover, .top nav a[aria-current] { text-decoration: underline; text-underline-offset: 0.3em; }

/* Home: a white plane, one close-set claim, and the wheel. */
.plane {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 100svh;
  overflow: hidden;
}

.plane-body {
  position: relative;
  z-index: 1;
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 1.25rem;
  padding: 1rem var(--gutter) clamp(1.5rem, 4vh, 3rem);
}

.claim-line {
  max-width: 44vw;
  margin: 0;
  font-size: clamp(2.1rem, min(3.9vw, 7.5vh), 4.25rem);
  font-weight: 400;
  line-height: 1.08;
  letter-spacing: -0.025em;
}

.plane-detail { max-width: min(36rem, 44vw); }
.plane-detail p { margin: 0; }
.credits {
  list-style: none;
  margin: 0 0 1.1rem;
  padding: 0;
  border-top: 1px solid var(--line);
  font: 300 0.875rem/1.45 var(--label);
  letter-spacing: 0.02em;
}
.credits li { padding: 0.55rem 0; border-bottom: 1px solid var(--line); }
.reach { font: 300 0.9375rem/1.4 var(--label); }

/* The wheel. Constructed in one fine line; only the name's trace is blue. */
.wheel {
  position: absolute;
  top: 50%;
  right: var(--gutter);
  width: min(86vmin, 46vw);
  height: auto;
  transform: translateY(-50%);
  color: var(--ink);
}
.wheel circle, .wheel .disc path, .wheel .spines { fill: none; stroke: var(--line); stroke-width: 1.1; }
.wheel .guide, .wheel .disc .guide { fill: none; stroke: none; }
.wheel text { fill: var(--line); font: 300 22px var(--label); }
.wheel .words { font: 400 27px var(--serif); font-variant-numeric: lining-nums; paint-order: stroke; stroke: var(--paper); stroke-width: 7px; }
.wheel .provider { font-size: 27px; }
.wheel .disc { transform-origin: 500px 500px; }
.wheel .ontology .relations { fill: none; stroke: var(--line); stroke-width: 1.1; }
.wheel .ontology .clearing { fill: var(--paper); stroke: none; }
.wheel .ontology .symbol { fill: var(--paper); stroke: var(--line); stroke-width: 1.5; }
.wheel .ontology .symbol-dot, .wheel .person-dot { fill: var(--ink); stroke: none; }
.wheel .ontology .symbol-post { fill: none; stroke: var(--ink); stroke-width: 2.6; }
.wheel .ontology .symbol-model { fill: var(--accent); stroke: none; }
.wheel .ontology .symbol-agent { fill: var(--accent); stroke: none; }
.wheel .wall { fill: none; stroke: var(--ink); stroke-width: 3.2; }
.wheel .merge { fill: none; stroke: var(--ink); stroke-width: 3.2; }
.wheel .merge-gate { fill: none; stroke: var(--accent); stroke-width: 4; stroke-dasharray: 3 7; }
.wheel .intents path { fill: none; stroke: var(--line); stroke-width: 1.1; }
.wheel .intents .heads { fill: var(--line); stroke: none; }
.wheel .intents .node { fill: var(--paper); stroke: var(--line); stroke-width: 1.1; }
.wheel .intent { transform-origin: 500px 500px; }
.wheel .mark path, .wheel .mark rect, .wheel .mark circle { fill: none; stroke: var(--line); stroke-width: 1.7; stroke-linejoin: round; stroke-linecap: round; }
.wheel .mark circle { fill: var(--paper); }
.wheel .mark .solid { fill: var(--line); stroke: none; }
.wheel .mark .caret { fill: var(--accent); stroke: none; }
.wheel .mark-text { font: 400 28px var(--serif); fill: var(--line); }
.wheel .cell { font-size: 18px; }
.wheel .small { font-size: 20px; }
.wheel .cells-disc { transform-origin: 500px 500px; }
.wheel .talk { stroke: var(--line); stroke-width: 1.1; }
.wheel .talk-dot { fill: var(--ink); stroke: none; transform: rotate(30deg); transform-origin: 500px 500px; }
.wheel .person { fill: var(--paper); }
.wheel .pointer { fill: var(--accent); }
.wheel .line-out, .wheel .ask path { fill: none; stroke: var(--accent); stroke-width: 1.8; stroke-linejoin: round; }
.wheel .ask circle, .wheel .intents .token, .wheel .intents .job-fill { fill: var(--accent); stroke: none; }
.wheel .token { opacity: 0; }
.wheel .intents .job-ring { fill: color-mix(in srgb, var(--accent) 16%, transparent); stroke: var(--accent); stroke-width: 1.6; opacity: 0; }
.wheel .job-fill { opacity: 0; }
.wheel .landed { fill: none; stroke: var(--accent); stroke-width: 3; opacity: 0; }
.wheel .ask { opacity: 0; }
.wheel .ask-0 { opacity: 1; }
@keyframes talk {
  0%, 11% { transform: rotate(0deg); }
  16.6%, 27.7% { transform: rotate(60deg); }
  33.3%, 44.4% { transform: rotate(120deg); }
  50%, 61% { transform: rotate(180deg); }
  66.6%, 77.7% { transform: rotate(240deg); }
  83.3%, 94.4% { transform: rotate(300deg); }
  100% { transform: rotate(360deg); }
}
@keyframes cells-turn { to { transform: rotate(-360deg); } }
@keyframes cells-upright { to { transform: rotate(360deg); } }
@keyframes caret-a { 0%, 12% { transform: translateX(0); } 80%, 100% { transform: translateX(50px); } }
@keyframes caret-b { 0%, 30% { transform: translateX(0); } 90%, 100% { transform: translateX(38px); } }
@keyframes switch-provider {
  0%, 30% { transform: rotate(0deg); }
  33%, 63% { transform: rotate(120deg); }
  66%, 96% { transform: rotate(240deg); }
  100% { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: no-preference) {
  .wheel .disc-outer { animation: switch-provider 30s ease-in-out infinite; }
  .wheel .talk-0 { animation: talk 30s ease-in-out infinite; }
  .wheel .talk-1 { animation: talk 30s ease-in-out -5s infinite reverse; }
  .wheel .cells-disc { animation: cells-turn 240s linear infinite; }
  .wheel .upright { animation: cells-upright 240s linear infinite; }
  .wheel .caret-a { animation: caret-a 7s steps(14) infinite; }
  .wheel .caret-b { animation: caret-b 9s steps(12) infinite; }
}
/* On a phone the wheel shrinks to a seal: rings and the blue line, without the lettering. */
@media (max-width: 52rem) {
  .plane { min-height: 0; }
  .plane-body { justify-content: flex-start; padding-top: 1rem; }
  .plane-detail { max-width: 36rem; }
  .wheel { top: 4.25rem; right: var(--gutter); width: clamp(4.5rem, 26vw, 6.75rem); transform: none; }
  .wheel text, .wheel .disc path, .wheel .spines, .wheel .person, .wheel .ask, .wheel .pointer, .wheel .line-out, .wheel .landed, .wheel .mark, .wheel .person-dot, .wheel .intents, .wheel .talk, .wheel .talk-dot { display: none; }
  .wheel circle { stroke-width: 7; }
  .wheel .ontology path { stroke-width: 6; }
  .wheel .wall { stroke-width: 11; }
  .wheel .merge { stroke-width: 11; }
  .wheel .merge-gate { stroke-width: 11; }
  .claim-line { max-width: none; font-size: clamp(1.9rem, 8.8vw, 3rem); }
  /* The statement wraps around the seal, which sits outside its flow. */
  .claim-line::before {
    content: "";
    float: right;
    width: calc(clamp(4.5rem, 26vw, 6.75rem) + 0.75rem);
    height: calc(clamp(4.5rem, 26vw, 6.75rem) + 0.25rem);
  }
}

.page { padding: clamp(2rem, 6vw, 4rem) var(--gutter) 3rem; }

.page h1, .list-title {
  margin: 0 0 1.5rem;
  font-size: clamp(2.5rem, 6vw, 4.5rem);
  font-weight: 400;
  line-height: 1.02;
  letter-spacing: -0.03em;
}
.list-title { font-size: clamp(1.9rem, 4vw, 2.75rem); }

.log {
  display: grid;
  grid-template-columns: 11rem minmax(0, 44rem);
  gap: 0.55rem 1.25rem;
  margin: 0;
}
.lab-lead { max-width: 44rem; margin: 0 0 2rem; }
.log dt { font: 300 0.8125rem/1.9 var(--label); }
.log dd { margin: 0; }
.log .sub { display: block; color: var(--quiet); font-size: 1.0625rem; line-height: 1.3; }
@media (max-width: 34rem) {
  .log { grid-template-columns: 1fr; gap: 0; }
  .log dd { margin-bottom: 1rem; }
}

.career .log, .lab .log { row-gap: 1.75rem; }
.career .log dd h2, .lab .log dd h2 { margin: 0; font-size: 1.3125rem; font-weight: 600; line-height: 1.3; }
.career .log dd p, .lab .log dd p { margin: 0.2rem 0 0; }
.career .resume { margin-top: 2.5rem; }

.prose { max-width: 44rem; }
.prose h2 { margin: 2.25rem 0 0.4rem; font-size: 1.75rem; font-weight: 400; letter-spacing: -0.02em; line-height: 1.15; }
.prose p, .prose li { margin: 0 0 0.75rem; }
.prose ul, .prose ol { padding-left: 1.25rem; margin: 0 0 0.75rem; }
.prose strong { font-weight: 600; }

/* The agent's hand. Anything set in this class was written by Claude, not by Lane. */
.agent, .agent a { color: var(--accent); }
.agent-note {
  margin: 0 0 2rem;
  padding: 0.5rem 0 0.5rem 0.8rem;
  border-left: 2px solid var(--accent);
  color: var(--accent);
  font: 300 1rem/1.4 var(--label);
  letter-spacing: 0.06em;
}
.now .agent, .phase-title .agent { font: 300 0.9375rem/1.35 var(--label); letter-spacing: 0.06em; }

.piece h1 { max-width: 15em; margin-bottom: 1rem; font-size: clamp(2rem, 4.5vw, 3.25rem); line-height: 1.08; }
.piece h1.display {
  max-width: none;
  margin-bottom: 0.2em;
  font-size: clamp(2.6rem, 11vw, 6.5rem);
  line-height: 1;
  letter-spacing: -0.035em;
}
.subtitle {
  max-width: 34rem;
  margin: 0 0 0.75rem;
  font: 300 0.8125rem/1.2 var(--label);
  letter-spacing: 0.06em;
}
.deck {
  max-width: 34rem;
  margin: 0 0 0.6rem;
  font: 300 1.1875rem/1.35 var(--label);
  letter-spacing: 0.06em;
}
.piece-body { line-height: 1.5; }
.piece-body h2 {
  max-width: 34rem;
  margin: 2.25rem 0 0.5rem;
  font-size: 1.75rem;
  font-weight: 400;
  line-height: 1.12;
  letter-spacing: -0.02em;
}
.piece-body p { max-width: 34rem; margin: 0 0 1rem; }
.piece-body .agent-note { margin-bottom: 1.5rem; }
.piece-body blockquote { max-width: 34rem; margin: 0 0 1rem; padding-left: 1rem; color: var(--ink); font-style: italic; }
.piece-body blockquote p { margin: 0; }
.piece-body blockquote a { color: var(--ink); }

/* Where the browser has no scroll-driven animation, each phase opens with its own dates. */
.timeline .now[aria-hidden], .rail { display: none; }
.phase-title { margin: 2.25rem 0 1rem; }
.phase-title h2 { margin: 0; }
.phase-title p { margin: 0; }

/* The timeline runs down the text. Each section is a stretch of the rail, and one sticky header
   opens on the piece's description, in its place under the title, then names the section being read. */
@supports (animation-timeline: view()) {
  .piece { --head: 5.75rem; }
  .timeline {
    display: grid;
    position: sticky;
    top: 0;
    z-index: 1;
    margin-bottom: 1.25rem;
  }
  .timeline .now[aria-hidden] { display: block; }
  .piece-body .now {
    grid-area: 1 / 1;
    align-self: start;
    max-width: none;
    margin: 0 calc(-1 * var(--gutter));
    padding: 0.5rem var(--gutter);
    background: var(--paper);
    box-shadow: 0 1px var(--quiet);
    font-size: 1.0625rem;
    line-height: 1.3;
    visibility: hidden;
    animation: show linear;
    animation-range: exit-crossing 0% exit-crossing 100%;
  }
  .now b { display: block; font: 300 0.75rem/1.4 var(--label); letter-spacing: 0.06em; }
  /* It stands until the first section reaches the header. */
  .piece-body .now-intro {
    visibility: visible;
    animation: gone linear forwards;
    animation-range: exit-crossing 0% exit-crossing 0.1%;
  }
  .piece-body .now-intro p { max-width: none; margin: 0; }
  .piece-body .now-intro .deck { font: 300 0.9375rem/1.35 var(--label); letter-spacing: 0.06em; }
  .piece-body .now-intro .subtitle { font: 300 0.75rem/1.4 var(--label); letter-spacing: 0.06em; }
  /* The page ends before the last section can leave the top, so that section ends at the bottom. */
  .piece-body .now:last-child {
    animation-fill-mode: forwards;
    animation-range: exit-crossing 0% exit 0%;
  }

  .phase { position: relative; display: flow-root; padding-top: 1.25rem; view-timeline-inset: var(--head) 0; scroll-margin-top: calc(var(--head) - 2px); }
  .rail {
    display: block;
    position: absolute;
    top: 0;
    bottom: 0;
    left: -0.7rem;
    width: 0.3rem;
    border-top: 1px solid var(--ink);
    border-left: 1px solid var(--quiet);
    background: linear-gradient(to bottom, var(--quiet) 1px, transparent 1px) 0 0 / 100% calc(100% / var(--months)) repeat-y;
    font: 300 0.6875rem/1.15 var(--label);
    text-align: right;
  }
  .rail span { display: none; position: absolute; top: 0.15rem; right: calc(100% + 0.3rem); }
  .rail .rail-end { top: auto; bottom: 0; }
  .phase:last-of-type .rail { border-bottom: 1px solid var(--ink); }

  .phase-title {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}
@keyframes show { from, to { visibility: visible; } }
@keyframes gone { from, to { visibility: hidden; } }
@media (min-width: 42rem) {
  .piece { --head: 4.25rem; }
}
/* Only a wide gutter has room for the labels; the header carries the dates below that. */
@media (min-width: 70rem) {
  .rail span { display: block; }
}

/* A term opens its definition on hover, or on focus by keyboard or tap. */
.term { position: relative; border-bottom: 1px dotted var(--accent); cursor: help; }
.term:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.def {
  display: none;
  position: absolute;
  z-index: 3;
  bottom: calc(100% + 0.35rem);
  left: 0;
  width: 17rem;
  padding: 0.5rem 0.65rem;
  border: 1px solid var(--accent);
  background: var(--paper);
  color: var(--accent);
  font: 300 0.9375rem/1.35 var(--label);
  font-style: normal;
  letter-spacing: 0.02em;
  text-align: left;
}
.term:hover .def, .term:focus .def { display: block; }
@media (max-width: 34rem) {
  .term { position: static; }
  .def { position: fixed; right: var(--gutter); bottom: 1rem; left: var(--gutter); width: auto; }
}

/* An aside is Claude's explanation of a term, closed until a reader wants it. */
.aside { margin: 0 0 1rem; color: var(--accent); font: 300 1rem/1.4 var(--label); letter-spacing: 0.02em; }
.aside summary { cursor: pointer; list-style: none; }
.aside summary::-webkit-details-marker { display: none; }
.aside summary::before { content: "+ "; }
.aside[open] summary::before { content: "\2212  "; }
.aside summary:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }
.piece-body .aside p { max-width: 34rem; margin: 0.3rem 0 0; }

/* Figures are the agent's too, so they are all in its colour. */
.fig { display: block; width: 100%; height: auto; margin: 0.5rem 0 0; }
.fig text { fill: var(--accent); font: 300 13px var(--label); letter-spacing: 0.02em; }
.fig .fig-label { font-size: 11px; }
.fig .fig-row { font-size: 10.5px; }
.fig .fig-chip { font-size: 10px; paint-order: stroke; stroke: var(--paper); stroke-width: 3px; }
.fig-line, .fig-gate { fill: none; stroke: var(--accent); stroke-width: 1.2; }
.fig-gate { stroke-width: 2.5; stroke-dasharray: 2 5; }
.fig-node, .fig-gauge { fill: var(--paper); stroke: var(--accent); stroke-width: 1.2; }
.fig-done, .fig-token { fill: var(--accent); }
.fig-ring { fill: color-mix(in srgb, var(--accent) 16%, transparent); stroke: var(--accent); stroke-width: 1; }

.mark {
  margin: 0 0 1rem;
  font: italic 400 1rem/1.3 var(--serif);
  font-variant-numeric: lining-nums;
}
.mark b { font-weight: 300; font-style: normal; font-family: var(--label); font-size: 0.75rem; display: block; }

@media (min-width: 66rem) {
  .claim {
    display: grid;
    grid-template-columns: minmax(0, 34rem) minmax(15rem, 24rem);
    column-gap: 3rem;
    align-items: start;
  }
  .claim > p, .claim > blockquote { grid-row: 1 / span 4; }
  .claim > .mark, .claim > .aside { grid-column: 2; margin-top: 0.3rem; }
  /* A lone aside spans its paragraph's height, so it stays in view and stops where the paragraph ends. */
  .claim > p:nth-last-child(2) + .aside {
    grid-row: 1 / span 4;
    position: sticky;
    top: calc(var(--head, 0px) + 1rem);
  }
}

.foot {
  padding: 1.5rem var(--gutter) 2rem;
  font: 300 0.8125rem/1.6 var(--label);
}
.foot p { margin: 0; }
