/* ============================================================
   cupola — plaster, cotto, marble.
   Three colours off the building itself: the lime plaster of the
   walls, the terracotta of the courses, and the grey-green of
   pietra serena for anything structural. Nothing else is coloured,
   because the dome already is.
   ============================================================ */

:root {
  --step--2: clamp(0.69rem, 0.67rem + 0.09vw, 0.75rem);
  --step--1: clamp(0.81rem, 0.78rem + 0.14vw, 0.91rem);
  --step-0:  clamp(0.98rem, 0.95rem + 0.19vw, 1.10rem);
  --step-1:  clamp(1.18rem, 1.10rem + 0.34vw, 1.42rem);
  --step-2:  clamp(1.46rem, 1.31rem + 0.62vw, 1.90rem);
  --step-3:  clamp(1.84rem, 1.55rem + 1.22vw, 2.76rem);
  --display: clamp(2.6rem, 1.0rem + 6.6vw, 6.1rem);

  --space-3xs: .25rem; --space-2xs: .5rem; --space-xs: .75rem;
  --space-s: 1rem;  --space-m: 1.5rem; --space-l: 2.5rem;
  --space-xl: 4rem; --space-2xl: 6rem;
  --space-3xl: clamp(5rem, 12vh, 9rem);

  --gutter: clamp(1.15rem, .6rem + 2.1vw, 3rem);
  --page: min(100% - var(--gutter) * 2, 1180px);

  --plaster:   oklch(94.5% 0.017 88);
  --plaster-2: oklch(91% 0.022 84);
  --ink:       oklch(24% 0.020 60);
  --ink-2:     oklch(44% 0.020 62);
  --ink-3:     oklch(47% 0.024 66);   /* 4.5:1 on plaster — labels are small */
  --rule:      oklch(83% 0.020 75);
  --cotto:     oklch(52% 0.125 42);
  --serena:    oklch(52% 0.023 235);
  --focus:     oklch(45% 0.14 250);

  --dur-fast: .18s; --dur-base: .4s;
  --ease-out: cubic-bezier(.22, 1, .36, 1);

  --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", "Cascadia Mono", "Roboto Mono", Menlo, Consolas, monospace;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
body, h1, h2, p, dl, dd { margin: 0; padding: 0; }
a { color: inherit; }

body {
  background: var(--plaster);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--step-0);
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
::selection { background: var(--cotto); color: var(--plaster); }

.skip {
  position: absolute; left: var(--space-s); top: -4rem; z-index: 60;
  background: var(--ink); color: var(--plaster);
  padding: .7rem 1.1rem; font-family: var(--mono); font-size: var(--step--1);
  text-decoration: none; transition: top var(--dur-fast) var(--ease-out);
}
.skip:focus-visible { top: var(--space-s); }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }

#stage {
  position: fixed; inset: 0; z-index: 0;
  display: block; width: 100%; height: 100%;
  background: var(--plaster);
}
header, main, footer, .hud { position: relative; z-index: 2; }

.head {
  width: var(--page); margin-inline: auto;
  padding-block: var(--space-m);
  display: flex; flex-wrap: wrap; gap: var(--space-s);
  align-items: baseline; justify-content: space-between;
  font-family: var(--mono); font-size: var(--step--1);
}
.head__back { text-decoration: none; }
.head__back:hover { color: var(--cotto); }
.dim { color: var(--ink-3); }
.head__meta {
  font-size: var(--step--2); color: var(--ink-3);
  letter-spacing: .10em; text-transform: uppercase;
}

/* ---- the site readout: the year, the height, the hole ---- */
.hud {
  position: fixed; right: var(--gutter); bottom: var(--space-l); z-index: 3;
  width: min(46vw, 15rem);
  font-family: var(--mono); text-align: right;
  opacity: 0; transition: opacity var(--dur-base) var(--ease-out);
}
.hud.is-live { opacity: 1; }
.hud__grid > div { display: grid; gap: 0; margin-bottom: var(--space-2xs); }
.hud__grid dt {
  font-size: var(--step--2); letter-spacing: .16em; text-transform: uppercase;
  color: var(--ink-3);
}
.hud__grid dd {
  font-size: var(--step-1); line-height: 1.15; color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.hud__rule { margin-top: var(--space-2xs); height: 2px; background: var(--rule); }
.hud__rule i { display: block; height: 100%; width: 0; background: var(--cotto); }
/* On a phone the readout goes to the top, in one row, clear of both
   the header and the copy card at the bottom. */
@media (max-width: 56rem) {
  .hud {
    bottom: auto; top: 3.1rem; left: 0; right: 0;
    width: auto; text-align: left;
    padding: .4rem var(--gutter) .5rem;
    /* its own plaster, so a panel leaving the top of the screen cannot
       collide with the instrument */
    background: linear-gradient(to bottom,
      oklch(94.5% 0.017 88 / .97) 62%, oklch(94.5% 0.017 88 / 0) 100%);
  }
  .hud__grid { display: flex; gap: var(--space-m); }
  .hud__grid > div { margin-bottom: 0; }
  .hud__grid dd { font-size: var(--step-0); }
  .hud__rule { margin-top: var(--space-3xs); }
}

/* ---- the panels laid down the build ---- */
.scene { position: relative; }
/* Thirteen screens of document is a lot of layout to do before the first
   word appears; on a throttled machine it was most of first paint. The
   reading below the fold is skipped until it is needed, at its own height,
   so nothing moves when it arrives. The panels are deliberately left out
   of this: skipping them costs more per scrolled frame than it saves at
   load, which was measured both ways. */
.section, .foot {
  content-visibility: auto;
  contain-intrinsic-size: auto 100svh;
}
.panel {
  min-height: 100svh;
  width: 100%;
  padding-block: var(--space-2xl);
  padding-inline: max(var(--gutter), calc(50% - var(--page) / 2));
  display: flex; flex-direction: column; justify-content: center;
  position: relative;
}
/* the dome holds the middle of the frame, so the copy takes the left
   and carries its own plaster rather than trusting what is behind it */
.panel::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: linear-gradient(to right,
    oklch(94.5% 0.017 88 / .94) 0%,
    oklch(94.5% 0.017 88 / .82) 32%,
    transparent 58%);
}
.panel > * { position: relative; z-index: 1; max-width: 34rem; }

/* On a phone the dome cannot share the frame side by side with the
   writing, so it does not: the copy drops to the bottom third under
   a soft plaster gradient and the scene keeps the rest of the
   screen. Same content, different composition. */
@media (max-width: 56rem) {
  .panel {
    justify-content: flex-end;
    padding-block: var(--space-l) calc(var(--space-xl) + env(safe-area-inset-bottom));
  }
  .panel::before {
    background: linear-gradient(to bottom,
      transparent 0%,
      oklch(94.5% 0.017 88 / .55) 26%,
      oklch(94.5% 0.017 88 / .93) 44%,
      oklch(94.5% 0.017 88 / .97) 100%);
  }
  .panel--open { justify-content: flex-end; }
  .body, .lede { max-width: none; }
  .beat { max-width: 16ch; }
}

.eyebrow, .mark {
  font-family: var(--mono); font-size: var(--step--2);
  letter-spacing: .16em; text-transform: uppercase; color: var(--ink-3);
}
.mark { color: var(--cotto); letter-spacing: .12em; }
.title {
  font-size: var(--display); line-height: 0.98;
  letter-spacing: -.04em; font-weight: 300;
  margin-block: var(--space-s) var(--space-m);
  text-wrap: balance;
}
.beat {
  font-size: var(--step-3); line-height: 1.13; letter-spacing: -.022em;
  font-weight: 400; margin-block: var(--space-2xs) var(--space-s);
  max-width: 19ch; text-wrap: balance;
}
.lede { font-size: var(--step-1); max-width: 41ch; color: var(--ink-2); line-height: 1.55; }
.body { max-width: 43ch; color: var(--ink-2); }
.body b, .facts b { color: var(--cotto); font-variant-numeric: tabular-nums; font-weight: 600; }
.cue {
  margin-top: var(--space-xl);
  font-family: var(--mono); font-size: var(--step--2);
  letter-spacing: .18em; text-transform: uppercase; color: var(--ink-3);
  transition: opacity var(--dur-base) var(--ease-out);
}
.cue.is-done { opacity: 0; }

/* ---- reading ---- */
/* The reading sits on its own full-bleed sheet: the scene is still
   behind it, but a column of body copy floating over a city is a
   legibility problem, not a device. */
.section {
  width: 100%;
  padding-block: var(--space-3xl);
  padding-inline: max(var(--gutter), calc(50% - var(--page) / 2));
  border-top: 1px solid var(--rule);
  background: var(--plaster);
}
.section__head { margin-bottom: var(--space-l); }
.section__title {
  font-size: var(--step-3); line-height: 1.12; letter-spacing: -.025em;
  font-weight: 400; margin-block: var(--space-2xs) var(--space-s);
  max-width: 22ch; text-wrap: balance;
}
.section__sub { max-width: 52ch; color: var(--ink-2); }
.cols { display: grid; gap: var(--space-l); }
.col p { max-width: 46ch; color: var(--ink-2); }
.col p + p { margin-top: var(--space-s); }
@media (min-width: 54rem) { .cols { grid-template-columns: 1fr 1fr; column-gap: var(--space-2xl); } }

.counts {
  display: grid; gap: 1px; background: var(--rule);
  border: 1px solid var(--rule);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (min-width: 46rem) { .counts { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.counts > div { background: var(--plaster); padding: var(--space-m); display: grid; gap: var(--space-3xs); }
.counts dt {
  font-family: var(--mono); font-size: var(--step--2);
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3);
}
.counts dd {
  font-family: var(--mono); font-size: var(--step-2);
  font-variant-numeric: tabular-nums; color: var(--cotto);
}

/* ---- the two tables of numbers ---- */
.facts > div {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--space-s); align-items: baseline;
  padding-block: var(--space-2xs);
  border-bottom: 1px solid var(--rule);
}
.facts dt { font-size: var(--step--1); color: var(--ink-2); }
.facts dd {
  font-family: var(--mono); font-size: var(--step--1);
  font-variant-numeric: tabular-nums; text-align: right; color: var(--ink);
}
.facts--ours {
  margin-top: var(--space-l);
  padding-left: var(--space-m);
  border-left: 2px solid var(--serena);
}
.facts--ours dd { color: var(--serena); }
@media (min-width: 54rem) {
  .facts { columns: 2; column-gap: var(--space-2xl); }
  .facts > div { break-inside: avoid; }
  .facts--ours { columns: 1; }
}

.note {
  margin-top: var(--space-m); max-width: 62ch;
  font-size: var(--step--1); color: var(--ink-2); line-height: 1.65;
  padding-left: var(--space-s); border-left: 2px solid var(--rule);
}
.note a { text-decoration-color: var(--cotto); text-underline-offset: 3px; }
.note a:hover { color: var(--cotto); }
code {
  font-family: var(--mono); font-size: .92em;
  background: var(--plaster-2); padding: .1em .35em; border-radius: 2px;
}

.colophon__grid { display: grid; gap: var(--space-l); }
.creds > div {
  display: grid; grid-template-columns: 6.5rem minmax(0, 1fr);
  gap: var(--space-s); padding-block: var(--space-2xs);
  border-bottom: 1px solid var(--rule);
}
.creds dt {
  font-family: var(--mono); font-size: var(--step--2);
  letter-spacing: .1em; text-transform: uppercase; color: var(--ink-3);
}
.creds dd { font-size: var(--step--1); color: var(--ink-2); }
.creds b { color: var(--ink); }
.colophon__note p { max-width: 46ch; color: var(--ink-2); font-size: var(--step--1); line-height: 1.65; }
.cta {
  display: inline-block; margin-top: var(--space-m);
  font-family: var(--mono); font-size: var(--step--1);
  text-decoration: none; border-bottom: 2px solid var(--cotto); padding-bottom: 2px;
}
.cta:hover { color: var(--cotto); }
@media (min-width: 56rem) {
  .colophon__grid { grid-template-columns: 1fr 1fr; column-gap: var(--space-2xl); }
}

.foot {
  width: 100%;
  padding-inline: max(var(--gutter), calc(50% - var(--page) / 2));
  padding-block: var(--space-l) var(--space-2xl);
  border-top: 1px solid var(--rule);
  background: var(--plaster);
  display: flex; flex-wrap: wrap; gap: var(--space-s); justify-content: space-between;
  font-family: var(--mono); font-size: var(--step--2); color: var(--ink-3);
}

@media (prefers-reduced-motion: reduce) {
  .cue { display: none; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}
