/* Story pages: the homepage's night, kept on for reading.
   Each project story is one long evening. The drawing from its card is drawn
   again at the top, the words follow in chapters, and the bar's clock runs on
   as you read; story.js drives the clock, the drawing and the reveals. */

:root {
  --night: #161513;
  --moon: #e7e9ee;
  --moon-soft: #9a978f;
  --moon-body: color-mix(in oklab, var(--moon) 84%, var(--night));
  --surface: color-mix(in oklab, var(--night), var(--moon) 5%);
  --hair: color-mix(in oklab, var(--moon) 16%, transparent);
  /* The drawings' two accents. Amber marks what to look at; red, what went wrong. */
  --amber: #b98c4a;
  --amber-text: #c8924c;
  --red: #b5544c;
  --red-text: #d0655b;
  --sodium: #f5a524;
  /* Chart pair, validated against the night: amber for the result, a neutral
     grey for what it is measured against. Every bar is also labelled. */
  --s1: var(--amber);
  --s2: #6f6c66;
  --track: color-mix(in oklab, var(--moon) 7%, transparent);

  --gutter: clamp(16px, 4vw, 56px);
  --col-gap: clamp(16px, 2vw, 32px);
  /* No system-ui: on Android that resolves to Roboto. */
  --font: "Mona Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --ease: cubic-bezier(.2, .7, .2, 1);
}

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

html {
  background: var(--night);
  color: var(--moon);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

body {
  margin: 0;
  background: var(--night);
  font-family: var(--font);
  font-size: clamp(1.0625rem, 1rem + .25vw, 1.1875rem);
  line-height: 1.5;
  font-kerning: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: clip;
}

img, svg { display: block; max-width: 100%; }

p, h1, h2, h3 { text-wrap: pretty; }

a { color: inherit; text-decoration: none; }

:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 4px;
  border-radius: 2px;
}

code {
  font-family: var(--mono);
  font-size: .84em;
  color: var(--moon);
}

/* ---------- bar ---------- */

.bar {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  align-items: baseline;
  gap: 2rem;
  padding: 18px var(--gutter);
  background: var(--night);
  font-size: .9375rem;
  line-height: 1.2;
}

.bar-name {
  font-weight: 600;
  font-stretch: 112%;
}

.bar-nav {
  display: flex;
  gap: 1.5rem;
  margin-left: auto;
}

.bar-clock {
  min-width: 5ch;
  text-align: right;
  font-weight: 500;
}

.bar-nav a,
.prose a,
.story-back {
  text-decoration: underline;
  text-decoration-color: transparent;
  text-decoration-thickness: 1px;
  text-underline-offset: .25em;
  transition: text-decoration-color .2s, color .2s;
}

.bar-nav a:hover,
.story-back:hover { text-decoration-color: currentColor; }

/* ---------- opening: the card's drawing, then the name ---------- */

.story-hero {
  position: relative;
  min-height: calc(100svh - 56px);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 0 var(--gutter) clamp(40px, 8vh, 88px);
}

.story-art {
  position: absolute;
  top: clamp(24px, 6vh, 72px);
  right: var(--gutter);
  width: min(58vw, 880px, 110svh);
  height: auto;
  overflow: visible;
}

.story-name {
  position: relative;
  margin: 0;
  font-size: clamp(4rem, 13vw, 12rem);
  font-stretch: 75%;
  font-weight: 500;
  line-height: .85;
  letter-spacing: -.035em;
}

.story-line {
  position: relative;
  max-width: 26ch;
  margin: clamp(18px, 3vh, 28px) 0 0;
  font-size: clamp(1.25rem, 1rem + 1vw, 1.75rem);
  line-height: 1.25;
  text-wrap: balance;
  color: var(--moon-body);
}

/* The same pills the project cards carry. */
.story-links {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: clamp(24px, 4vh, 36px) 0 0;
  padding: 0;
  list-style: none;
  font-size: .875rem;
}

.pill {
  display: inline-block;
  padding: 5px 14px;
  border: 1px solid color-mix(in oklab, currentColor 35%, transparent);
  border-radius: 999px;
  transition: background-color .2s, color .2s, border-color .2s;
}

.pill:hover {
  background: var(--moon);
  border-color: var(--moon);
  color: var(--night);
}

/* Drawn on arrival: every stroke carries pathLength="1". */
@media (prefers-reduced-motion: no-preference) {
  .js .draw [pathLength] {
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
  }

  .js .draw.is-drawn [pathLength] {
    animation: draw 1.4s var(--ease) calc(var(--i, 0) * 70ms) forwards;
  }

  .js .draw text {
    opacity: 0;
    transition: opacity .8s var(--ease) .6s;
  }

  .js .draw.is-drawn text { opacity: 1; }

  .js .story-name,
  .js .story-line,
  .js .story-links {
    animation: rise 1.1s var(--ease) backwards;
  }
  .js .story-line { animation-delay: .1s; }
  .js .story-links { animation-delay: .18s; }
}

@keyframes draw { to { stroke-dashoffset: 0; } }

@keyframes rise {
  from { opacity: 0; transform: translateY(.35em); }
}

/* ---------- chapters: the heading keeps the left while its words go by ---------- */

.story { padding: 0 var(--gutter); }

.chapter {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--col-gap);
  padding: clamp(40px, 7vh, 72px) 0 clamp(56px, 10vh, 112px);
  /* A background rather than a border, so the rule can grow from the left. */
  background: linear-gradient(var(--hair) 0 0) 0 0 / 100% 1px no-repeat;
}

.chapter-title {
  grid-column: 1 / span 4;
  align-self: start;
  position: sticky;
  top: calc(56px + clamp(20px, 4vh, 40px));
  margin: 0 0 24px;
  padding-right: 1em;
  font-size: clamp(2rem, 1.2rem + 2.6vw, 3.75rem);
  font-stretch: 75%;
  font-weight: 500;
  line-height: .95;
  letter-spacing: -.03em;
}

.prose {
  grid-column: 5 / span 7;
  min-width: 0;
  max-width: 40em;
  color: var(--moon-body);
  line-height: 1.62;
}

.prose > * { margin: 0; }
.prose > * + * { margin-top: 1.1em; }

.prose strong { color: var(--moon); font-weight: 560; }
.prose em { font-style: italic; }

.prose a {
  color: var(--moon);
  text-decoration-color: color-mix(in oklab, currentColor 40%, transparent);
}

.prose a:hover { text-decoration-color: currentColor; }

.lede {
  color: var(--moon);
  font-size: clamp(1.25rem, 1.05rem + .7vw, 1.625rem);
  line-height: 1.4;
  letter-spacing: -.01em;
}

/* the one line a story lands on, set large */
.thesis {
  color: var(--moon);
  font-size: clamp(2rem, 1.2rem + 2.8vw, 3.75rem);
  font-stretch: 75%;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -.03em;
  text-wrap: balance;
}

.prose > .thesis { margin-bottom: .6em; }

.aside {
  padding-left: 18px;
  border-left: 1px solid var(--amber);
}

.aside > * { margin: 0; }
.aside > * + * { margin-top: .8em; }

.small {
  font-size: .9375rem;
  color: var(--moon-soft);
}

/* ---------- figures: big thin numbers, as on the homepage ---------- */

.figures {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9.5em, 1fr));
  gap: 28px var(--col-gap);
  padding: 0;
  list-style: none;
}

.prose > .figures { margin-block: 2.2em; }

.figures li { min-width: 0; }

.figure {
  display: block;
  font-size: clamp(2.5rem, 1.6rem + 2.4vw, 3.75rem);
  font-weight: 280;
  line-height: .95;
  letter-spacing: -.035em;
  color: var(--moon);
}

.figure-label {
  display: block;
  max-width: 20ch;
  margin-top: 10px;
  font-size: .875rem;
  line-height: 1.4;
  color: var(--moon-soft);
  text-wrap: balance;
}

.figure-label em { font-style: normal; color: var(--amber-text); }

/* ---------- charts: plain HTML bars ---------- */

.prose > .chart { margin-block: 2.4em; }

.chart { margin: 0; }

.chart-title {
  margin: 0 0 20px;
  font-size: 1rem;
  font-weight: 560;
  color: var(--moon);
}

.legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  margin: -8px 0 20px;
  padding: 0;
  list-style: none;
  font-size: .875rem;
  color: var(--moon-soft);
}

.legend li { display: inline-flex; align-items: center; gap: 8px; }
.legend i { width: 10px; height: 10px; border-radius: 2px; background: var(--s1); }
.legend .k2 i { background: var(--s2); }
.legend .ref i { width: 16px; height: 0; border-radius: 0; background: none; border-top: 2px dashed var(--moon-soft); }

.bars { display: grid; gap: 18px; }

.bar-row {
  display: grid;
  grid-template-columns: minmax(0, 9.5em) 1fr;
  gap: 6px 16px;
  align-items: center;
}

.bar-label {
  font-size: .9375rem;
  line-height: 1.3;
  color: var(--moon);
}

.bar-label small {
  display: block;
  font-size: .8125rem;
  color: var(--moon-soft);
}

.bar-group { display: grid; gap: 4px; }

/* The 62px gutter holds the value label. It shrinks the track box itself, so
   fill widths and reference lines stay on one percentage base. */
.track {
  position: relative;
  height: 12px;
  margin-right: 62px;
  background: var(--track);
  border-radius: 0 4px 4px 0;
}

.fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: var(--v);
  min-width: 2px;
  background: var(--s1);
  border-radius: 0 4px 4px 0;
  transform-origin: 0 50%;
}

.fill.k2 { background: var(--s2); }
.fill.moon { background: var(--moon); }

.value {
  position: absolute;
  left: calc(var(--v) + 10px);
  top: 50%;
  translate: 0 -50%;
  font-size: .875rem;
  font-weight: 500;
  color: var(--moon);
  white-space: nowrap;
}

.refline {
  position: absolute;
  top: -6px;
  bottom: -6px;
  left: var(--v);
  border-left: 2px dashed var(--moon-soft);
}

.panels {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 32px var(--col-gap);
}

.panel-title {
  margin: 0 0 14px;
  font-size: .9375rem;
  font-weight: 500;
  color: var(--moon);
}

.panels .bar-row { grid-template-columns: 3.6em 1fr; }

.scale {
  margin: 12px 0 0;
  font-size: .8125rem;
  color: var(--moon-soft);
}

.chart figcaption {
  margin-top: 20px;
  font-size: .9375rem;
  line-height: 1.55;
  color: var(--moon-soft);
}

/* ---------- lists of rules and numbers ---------- */

.rows {
  padding: 0;
  list-style: none;
}

.prose > .rows { margin-block: 2em; }

.rows li {
  display: grid;
  grid-template-columns: minmax(0, 7em) 1fr auto;
  gap: 4px 20px;
  align-items: baseline;
  padding: 16px 0;
  border-top: 1px solid var(--hair);
}

.rows li:last-child { border-bottom: 1px solid var(--hair); }

.rows b {
  font-weight: 560;
  color: var(--moon);
}

.rows span { font-size: .9375rem; }

.rows .num {
  color: var(--moon);
  text-align: right;
  white-space: nowrap;
}

.rows .num small {
  display: block;
  font-size: .8125rem;
  color: var(--moon-soft);
}

.rows.pairs li { grid-template-columns: 1fr auto; }

/* ---------- the demo ---------- */

.demo {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 20px;
}

.prose > .demo { margin-top: 1.8em; }

.prose .demo-go {
  text-decoration: none;
  padding: 10px 20px;
  border-radius: 999px;
  background: var(--moon);
  color: var(--night);
  font-size: .9375rem;
  font-weight: 500;
  transition: background-color .2s;
}

.prose .demo-go:hover { background: var(--sodium); text-decoration-color: transparent; }

.demo-status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: .875rem;
  color: var(--moon-soft);
}

.demo-status i {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--s2);
  transition: background-color .3s, box-shadow .3s;
}

.demo[data-state="ready"] .demo-status i {
  background: var(--sodium);
  box-shadow: 0 0 10px var(--sodium);
}

/* ---------- close: the next story, large ---------- */

.story-next {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-height: 80svh;
  justify-content: flex-end;
  padding: clamp(56px, 10vh, 112px) var(--gutter) clamp(28px, 5vh, 48px);
  background: linear-gradient(var(--hair) 0 0) var(--gutter) 0 / calc(100% - 2 * var(--gutter)) 1px no-repeat;
}

.story-next-label {
  margin: 0 0 12px;
  color: var(--moon-soft);
}

.story-next-name {
  font-size: clamp(4rem, 15vw, 13rem);
  font-stretch: 75%;
  font-weight: 500;
  line-height: .85;
  letter-spacing: -.035em;
  background: linear-gradient(var(--sodium), var(--sodium)) 0 100% / 0 3px no-repeat;
  transition: background-size .5s var(--ease), color .3s;
}

.story-next-name:hover,
.story-next-name:focus-visible {
  color: var(--sodium);
  background-size: 100% 3px;
}

.story-back {
  margin-top: clamp(40px, 12vh, 120px);
  font-size: .875rem;
  color: var(--moon-soft);
}

/* ---------- reveals: the rule draws in, then the words rise ---------- */

@media (prefers-reduced-motion: no-preference) {
  .can-reveal .chapter {
    transition: background-size .9s var(--ease);
  }

  .can-reveal .chapter > * {
    transition: opacity .8s var(--ease) .15s, translate .8s var(--ease) .15s;
  }

  .can-reveal .chapter > .prose { transition-delay: .22s; }

  .can-reveal .chapter:not(.is-shown) { background-size: 0 1px; }

  .can-reveal .chapter:not(.is-shown) > * {
    opacity: 0;
    translate: 0 14px;
  }

  /* Bars grow from the baseline as their chart arrives; values follow. */
  .can-reveal .chart .fill { transition: scale 1.1s var(--ease) .1s; }
  .can-reveal .chart .value { transition: opacity .6s var(--ease) .7s; }
  .can-reveal .chart:not(.is-shown) .fill { scale: 0 1; }
  .can-reveal .chart:not(.is-shown) .value { opacity: 0; }
}

/* ---------- narrow screens: one column ---------- */

@media (max-width: 899px) {
  .chapter { display: block; }

  .chapter-title {
    position: static;
    margin-bottom: 28px;
  }

  .prose { max-width: none; }
}

@media (max-width: 719px), (max-width: 1100px) and (orientation: portrait) {
  .story-hero {
    min-height: 0;
    padding-top: 8px;
  }

  .story-art {
    position: static;
    width: 100%;
    margin: 0 0 clamp(40px, 8vh, 72px);
  }
}

@media (max-width: 559px) {
  .bar-nav { display: none; }
  .bar-clock { margin-left: auto; }

  .bar-row,
  .panels .bar-row { grid-template-columns: 1fr; gap: 8px; }

  .panels { grid-template-columns: 1fr; }

  .rows li { grid-template-columns: 1fr auto; }
  .rows li > b + span:not(.num) { grid-column: 1 / -1; grid-row: 2; }
}
