/* The story's blocks.
 *
 * How far the page goes is the length of the story. The name and the brief are
 * there at every length; a part says with data-from which length it arrives
 * with, and stays for every longer one. Everything a length takes away is below
 * everything it keeps. */
html[data-level="brief"] [data-from="detailed"],
html[data-level="brief"] [data-from="full"],
html[data-level="detailed"] [data-from="full"] { display: none; }

/* No room at the end of the page as a whole: every length ends on something
   that keeps its own clear of the bottom edge — a screen, or a block of reading
   that makes room for the bar. A page that ran on past its last screen would
   never be at its end while that screen is the one being read, and reading past
   the end is how the next length is asked for. */

/* ---------- the two sizes ---------- */

/* Large: one size for every line set as a statement, the same as the name. */
.statement {
  margin: 0;
  max-width: min(960px, 100%);
  font-size: var(--wordmark-size);
  line-height: var(--wordmark-leading);
  letter-spacing: var(--wordmark-track);
  text-align: center;
  text-wrap: balance;
}

/* Reading. */
.intro {
  margin: 0;
  max-width: var(--measure);
  font-size: var(--read-size);
  line-height: var(--read-leading);
  color: var(--muted);
  text-align: center;
  text-wrap: pretty;
}

.status {
  margin: 0;
  font-size: 14px;
  letter-spacing: 0.02em;
  text-align: center;
  /* Three short items: on a phone they go over two lines, and they should go
     over as two halves rather than leave one word behind. */
  text-wrap: balance;
}

.status-item { white-space: nowrap; }

/* ---------- the brief ---------- */

/* The second screen at every length, and the whole of the shortest: a screen
   like the others, with the lockup already made above it. */
.brief { gap: 2.8svh; }

.brief .figs {
  --figure-size: min(5vw, 72px);
  margin-top: 1.5svh;
}

.brief-foot {
  display: grid;
  justify-items: center;
  gap: 10px;
  margin-top: 1svh;
}

.brief-links {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px 26px;
  font-size: 14px;
}

/* Links say so with a hairline rather than a colour. */
.brief-links a {
  background: linear-gradient(currentColor, currentColor) 0 100% / 100% 1px no-repeat;
}

/* ---------- the long page ---------- */

/* The runway the name comes apart over: it holds only the line under it. */
.gallery-hero {
  position: relative;
  height: 100svh;
}

.hero-status {
  position: absolute;
  left: var(--inset);
  right: var(--inset);
  bottom: calc(var(--bar-h) + 7svh);
}

/* A screen: one thing, centred, clear of the bar at the top and the bottom. */
.screen {
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 28px;
  padding: var(--wm-bar) var(--inset) var(--bar-h);
}

/* ---------- the numbers ---------- */

.figs {
  width: min(1080px, 100%);
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 32px 40px;
}

.fig-n {
  margin: 0;
  font-size: var(--figure-size);
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.fig-n sup {
  position: relative;
  top: 0.2em;
  margin-left: 4px;
  font-size: 13px;
  letter-spacing: 0;
  vertical-align: top;
}

.fig-l {
  margin: 12px 0 0;
  font-size: 15px;
  line-height: 1.35;
  color: var(--muted);
}

/* Where every number comes from, the way a research note does it. Open on a
   wide screen, where it has room; one word to tap on a phone. */
.fig-sources { width: min(1080px, 100%); }

.fig-sources > summary {
  width: max-content;
  margin: 0 auto;
  font-size: var(--label-size);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--muted);
  cursor: pointer;
}

.fig-sources[open] > summary { margin-bottom: 10px; }

@media (min-width: 761px) {
  .fig-sources > summary { display: none; }
}

.fig-notes {
  width: min(1080px, 100%);
  margin: 0;
  padding: 0 0 0 1.3em;
  display: grid;
  gap: 6px;
  font-size: 13px;
  line-height: 1.45;
  color: var(--muted);
}

/* ---------- sections ---------- */

.case { scroll-margin-top: var(--wm-bar); }

/* The screen that names a section. Its name is the copy that travels to the bar
   — see engine/wordmark.js — so it is set exactly as the bar sets it. */
.case-open {
  height: 100svh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 var(--inset);
}

/* The rest of the CV opens with its name too, but not with a screen of it. */
.case-open.is-short {
  height: auto;
  padding-block: 24svh 6svh;
}

.case-open h2 {
  margin: 0;
  font: inherit;
  font-size: var(--wordmark-size);
  line-height: var(--wordmark-leading);
  letter-spacing: var(--wordmark-track);
  text-align: center;
}

/* Only one copy of a section's name may be painted: once the bar carries it,
   the screen's own is not drawn. visibility, not display — the travelling copy
   is measured off this one. */
html[data-case-label="lockup"] .case.is-named.is-parked .case-open h2 { visibility: hidden; }

/* ---------- pictures, until they are in ---------- */

.picture {
  position: relative;
  margin: 0;
  aspect-ratio: 16 / 9;
  display: grid;
  place-items: center;
  overflow: hidden;
  background: var(--slot);
}

.picture::before,
.portrait.is-empty::before {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(135deg, var(--slot-line) 0 1px, transparent 1px 12px);
}

/* At the top, under the bar: a field taller than the window would otherwise
   carry its caption down into the glass, where it is bent out of reading. */
.picture figcaption {
  position: absolute;
  left: var(--inset);
  right: var(--inset);
  top: calc(var(--wm-bar) + 8px);
  font-size: 13px;
  line-height: 1.4;
  color: var(--muted);
}

.mats {
  position: relative;
  display: flex;
  align-items: center;
  gap: 4vw;
}

.mat {
  width: calc(var(--s, 1) * clamp(56px, 9vw, 140px));
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--page);
  box-shadow: inset 0 0 0 1px var(--slot-edge);
  font-size: 14px;
}

.doc {
  position: relative;
  width: clamp(150px, 20vw, 290px);
  aspect-ratio: 1 / 1.414;
  background: var(--page);
  box-shadow: inset 0 0 0 1px var(--slot-edge);
}

/* ---------- charts ---------- */

/* A chart is a screen: centred, clear of the bar at the top and the bottom. The
   plot inside is drawn by engine/chart.js; this is the frame around it. */
.chart { margin: 0; }

.chart-in {
  width: min(1120px, 100%);
  display: grid;
  gap: 18px;
}

.chart-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 14px 24px;
}

.chart-title {
  margin: 0;
  font-size: var(--read-size);
  line-height: 1.3;
}

.chart-sub {
  margin: 4px 0 0;
  font-size: 14px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* The season switch: the bottom slider's language, in ink on the page. */
.chart-seasons {
  display: inline-flex;
  padding: 3px;
  border-radius: 999px;
  box-shadow: inset 0 0 0 1px var(--ink);
}

.chart-seasons button {
  padding: 8px 16px;
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: var(--label-size);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color 250ms var(--ease-out), color 250ms var(--ease-out);
}

.chart-seasons button[aria-checked="true"] {
  background: var(--ink);
  color: var(--page);
}

/* The legend doubles as the choice of which line is in ink. */
.chart-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 20px;
}

.chart-key {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 0;
  border: 0;
  background: none;
  color: var(--muted);
  font: inherit;
  font-size: 14px;
  cursor: pointer;
}

.chart-key i {
  width: 16px;
  height: 2px;
  background: var(--chart-context);
}

.chart-key[aria-pressed="true"] { color: var(--ink); }
.chart-key[aria-pressed="true"] i { background: var(--ink); }

/* The plot claims sideways movement only: a finger sliding across it reads the
   hours, a finger sliding up or down still scrolls the page. */
.chart-plot {
  position: relative;
  height: var(--chart-height);
  touch-action: pan-y;
  cursor: crosshair;
  outline: none;
}

.chart-plot:focus-visible { box-shadow: 0 0 0 1px var(--ink); }
.chart-plot.is-failed {
  display: grid;
  place-items: center;
  font-size: 14px;
  color: var(--muted);
}

.chart-svg { display: block; overflow: visible; }

.chart-svg text {
  font-family: var(--font);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  fill: var(--muted);
}

.chart-grid line { stroke: var(--chart-grid); stroke-width: 1; }
.chart-grid line.is-zero { stroke: var(--chart-axis); }

.chart-line {
  fill: none;
  stroke: var(--chart-context);
  stroke-width: 1.5;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.chart-line.is-focus { stroke: var(--ink); stroke-width: 2.25; }
.chart-svg .chart-end.is-focus { fill: var(--ink); }

.chart-hair { stroke: var(--ink); stroke-width: 1; }
.chart-dot { fill: var(--chart-context); stroke: var(--page); stroke-width: 2; }
.chart-dot.is-focus { fill: var(--ink); }

.chart-tip {
  position: absolute;
  left: 0;
  top: 0;
  min-width: 156px;
  padding: 10px 12px;
  background: var(--page);
  box-shadow: 0 0 0 1px var(--chart-grid), 0 10px 28px rgba(22, 22, 22, 0.08);
  font-size: 13px;
  pointer-events: none;
}

.chart-tip-h {
  margin: 0 0 6px;
  font-size: 12px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.chart-tip ol {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 3px;
}

.chart-tip li {
  display: grid;
  grid-template-columns: 14px 2.6em minmax(0, 1fr);
  align-items: center;
  gap: 8px;
  color: var(--muted);
}

.chart-tip li i { height: 2px; background: var(--chart-context); }
.chart-tip li b {
  font-weight: inherit;
  color: var(--ink);
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.chart-tip li.is-focus i { background: var(--ink); }
.chart-tip li.is-focus span { color: var(--ink); }

.chart-source {
  font-size: 12px;
  line-height: 1.45;
  color: var(--muted);
}

.chart-table summary {
  width: max-content;
  font-size: var(--label-size);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  cursor: pointer;
}

.chart-table-in {
  margin-top: 12px;
  overflow-x: auto;
}

.chart-table table {
  border-collapse: collapse;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}

.chart-table caption {
  padding-bottom: 8px;
  text-align: left;
  color: var(--muted);
}

.chart-table th,
.chart-table td {
  padding: 4px 16px 4px 0;
  text-align: right;
  font-weight: inherit;
  border-bottom: 1px solid var(--chart-grid);
}

.chart-table th:first-child { text-align: left; }

/* ---------- reading ---------- */

.read { padding: 14svh var(--inset) calc(var(--bar-h) + 10svh); }
.read:empty { display: none; }

.works {
  max-width: var(--measure);
  margin: 0 auto;
  display: grid;
  gap: 40px;
}

.work h3 {
  margin: 0;
  font: inherit;
  font-size: var(--read-size);
  line-height: var(--read-leading);
}

.work p {
  margin: 2px 0 0;
  font-size: var(--read-size);
  line-height: var(--read-leading);
  color: var(--muted);
}

.timeline {
  max-width: calc(var(--measure) + 10em);
  margin: 0 auto;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 36px;
}

.timeline li {
  display: grid;
  grid-template-columns: 8.5em minmax(0, 1fr);
  gap: 0 32px;
}

.tl-when {
  margin: 0;
  font-size: var(--read-size);
  line-height: var(--read-leading);
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.facts {
  max-width: var(--measure);
  margin: 64px auto 0;
  display: grid;
  gap: 22px;
}

.facts div { display: grid; gap: 4px; }

.facts dt {
  font-size: var(--label-size);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--muted);
}

.facts dd {
  margin: 0;
  font-size: var(--read-size);
  line-height: var(--read-leading);
}

/* ---------- the way to write ---------- */

.contact-in {
  width: min(1000px, 100%);
  display: flex;
  align-items: center;
  gap: 56px;
}

.portrait {
  position: relative;
  flex: none;
  width: clamp(140px, 16vw, 220px);
  aspect-ratio: 3 / 4;
  overflow: hidden;
  background: var(--slot);
}
.portrait img { width: 100%; height: 100%; object-fit: cover; }

.contact-text { display: grid; gap: 18px; }
.contact .statement,
.contact .intro { text-align: left; }
.contact .statement { overflow-wrap: anywhere; }

/* The address is a link, and says so with a hairline rather than a colour. */
.contact .statement a {
  background: linear-gradient(currentColor, currentColor) 0 100% / 100% 1px no-repeat;
}

.contact-links {
  margin: 0;
  display: flex;
  gap: 28px;
  font-size: var(--label-size);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

/* ---------- a phone ---------- */

@media (max-width: 760px) {
  .figs {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 28px 20px;
  }
  /* On a phone the brief keeps its numbers and their sources, and leaves the
     paragraph to the sections under it. */
  .brief .figs { --figure-size: 44px; }
  .brief .intro { display: none; }

  /* A narrow screen gets an upright field, as kirrr's blocks do: the wide one
     would leave the picture a strip. */
  .picture { aspect-ratio: 4 / 5; }

  .chart-plot { height: 44svh; }
  .chart-legend { gap: 0 16px; }
  .mats {
    flex-wrap: wrap;
    justify-content: center;
    gap: 14px;
    padding: 0 var(--inset);
  }

  .timeline li {
    grid-template-columns: minmax(0, 1fr);
    gap: 2px;
  }

  .contact-in {
    flex-direction: column;
    gap: 32px;
  }
  .contact .statement,
  .contact .intro { text-align: center; }
  .contact-links { justify-content: center; }
}
