/* Instrument direction: the research and Education Sanctum pages.
   Loaded after base.css on those pages only.

   The page is set like a paper: a head, sections on hairline rules, one
   sheet of ice paper, and one figure that stays on screen
   while the text is read. The figure is SVG over a brand plate
   (internal/figures). Each of its transitions has a progress,
   --instrument-tK, which a scroll timeline sets from a marker in the text
   (internal/pages/instrument_plan.go). Without scroll timelines or the CSS
   d property, or with reduced motion, instrument.js sets it. With neither
   scroll timelines nor the script, the figure shows its first scene, the
   plate. The page adds no words and no numbers: the head, the section
   headings and the leads share base.css's roles and Horizon's spacing. */

/* ---------- Transitions ---------- */

@property --instrument-t1 { syntax: "<number>"; inherits: true; initial-value: 0; }
@property --instrument-t2 { syntax: "<number>"; inherits: true; initial-value: 0; }
@property --instrument-t3 { syntax: "<number>"; inherits: true; initial-value: 0; }
@property --instrument-t4 { syntax: "<number>"; inherits: true; initial-value: 0; }
@property --instrument-t5 { syntax: "<number>"; inherits: true; initial-value: 0; }
@property --instrument-t6 { syntax: "<number>"; inherits: true; initial-value: 0; }
/* A path's morph progress, from its inline style (figures.Node.Style). */
@property --instrument-m { syntax: "<number>"; inherits: false; initial-value: 0; }

@keyframes instrument-t1 { from { --instrument-t1: 0; } to { --instrument-t1: 1; } }
@keyframes instrument-t2 { from { --instrument-t2: 0; } to { --instrument-t2: 1; } }
@keyframes instrument-t3 { from { --instrument-t3: 0; } to { --instrument-t3: 1; } }
@keyframes instrument-t4 { from { --instrument-t4: 0; } to { --instrument-t4: 1; } }
@keyframes instrument-t5 { from { --instrument-t5: 0; } to { --instrument-t5: 1; } }
@keyframes instrument-t6 { from { --instrument-t6: 0; } to { --instrument-t6: 1; } }

.instrument-track {
  /* The header's height; instrument.js measures it. */
  --instrument-top: 72px;
  --instrument-gap: clamp(32px, 4vw, 80px);
  /* The reading band, in percent of the viewport from its top: a
     transition runs while its marker rises from the bottom of the band to
     its top. instrument.js reads the same two numbers. */
  --instrument-band-top: 64;
  --instrument-band-bottom: 80;
  /* Strokes are drawn in stage units, 1000 to the plate: thicker on a
     small plate. */
  --instrument-sw: 1.6;
  --instrument-foot: 13rem;
  --instrument-plate: min(100%, 44svh);
  position: relative;
  padding-inline: var(--gutter);
  timeline-scope: --instrument-m1, --instrument-m2, --instrument-m3,
    --instrument-m4, --instrument-m5, --instrument-m6;
}

.instrument-mark {
  position: absolute;
  left: 0;
  width: 1px;
  height: 1px;
  pointer-events: none;
  view-timeline-axis: block;
  view-timeline-inset: calc(var(--instrument-band-top) * 1%) calc((100 - var(--instrument-band-bottom)) * 1%);
}
.instrument-mark-1 { view-timeline-name: --instrument-m1; }
.instrument-mark-2 { view-timeline-name: --instrument-m2; }
.instrument-mark-3 { view-timeline-name: --instrument-m3; }
.instrument-mark-4 { view-timeline-name: --instrument-m4; }
.instrument-mark-5 { view-timeline-name: --instrument-m5; }
.instrument-mark-6 { view-timeline-name: --instrument-m6; }

.instrument-stage {
  animation: instrument-t1 1s linear both, instrument-t2 1s linear both,
    instrument-t3 1s linear both, instrument-t4 1s linear both,
    instrument-t5 1s linear both, instrument-t6 1s linear both;
  animation-timeline: --instrument-m1, --instrument-m2, --instrument-m3,
    --instrument-m4, --instrument-m5, --instrument-m6;
}

/* A morphing path: a paused animation whose delay is its progress. */
.instrument-morph {
  animation: instrument-morph 1s linear paused both;
  animation-delay: calc(var(--instrument-m) * -1s);
}
@keyframes instrument-morph { to { d: var(--instrument-d); } }

/* Without scroll timelines or the CSS d property the stage holds its first
   scene, unless instrument.js drives it (.instrument-js). */
@supports not ((animation-timeline: --instrument-a) and (timeline-scope: --instrument-a) and (d: path("M0 0"))) {
  .instrument-stage { animation: none; }
}
.instrument-js .instrument-stage,
.instrument-js .instrument-morph { animation: none; }

/* ---------- Head ---------- */

.instrument-head {
  position: relative;
  z-index: 1;
  padding-block: clamp(2.75rem, 8vh, 6.5rem) clamp(2.5rem, 6vh, 4.5rem);
}
/* The head's type and spacing are the Horizon pages' (horizon.css .hz-copy),
   so the first screen reads the same on every page. */
.instrument-eyebrow { margin-bottom: 1.6rem; }
.instrument-h1 { font-size: var(--fs-display); max-width: 12.5em; }
.instrument-lead {
  margin-top: 2rem;
  max-width: 30rem;
  font-size: var(--fs-lead);
  line-height: 1.55;
  color: var(--text-soft);
  text-wrap: pretty;
}
.instrument-lead p + p { margin-top: 0.55em; }
.instrument-actions { display: flex; flex-wrap: wrap; gap: 1rem 1.2rem; margin-top: 2.4rem; }

/* ---------- Sections ---------- */

.instrument-section {
  --instrument-ink: var(--text);
  --instrument-ink-soft: var(--text-soft);
  --instrument-rule: var(--hairline);
  --instrument-rule-strong: rgba(141, 180, 212, 0.45);
  position: relative;
  z-index: 1;
  padding-block: clamp(3.25rem, 9vh, 6.5rem);
  border-top: 1px solid var(--instrument-rule);
  /* Room for its markers, a reading band apart (instrumentRoom). */
  min-height: calc(var(--instrument-room, 0) * (var(--instrument-band-bottom) - var(--instrument-band-top)) * 1svh);
  /* A link to the section lands below the sticky figure. */
  scroll-margin-top: calc(var(--instrument-top) + min(100vw - 2 * var(--gutter), 44svh) + 24px);
  color: var(--instrument-ink);
}
/* The heading's size and ring are base.css's .heading. */
.instrument-h2 { max-width: 14em; }
.instrument-body { max-width: var(--measure); }
.instrument-prose { color: var(--instrument-ink-soft); text-wrap: pretty; }
/* A level-1 line is set apart as on the Horizon pages: in italic. */
.instrument-prose .line[data-level="1"] { font-style: italic; color: var(--instrument-ink); }
.instrument-prose + .instrument-prose { margin-top: 1.1em; }
.instrument-links { display: flex; flex-wrap: wrap; gap: 0.5rem 2rem; margin-top: 2rem; }
/* Room after the last section when it holds markers, so that the last can
   rise through the band before the page ends. A section is at least a
   band taller below its last marker (instrumentRoom), and the footer is at
   least --instrument-foot tall. */
.instrument-track:has(> .instrument-section:last-child > .instrument-mark) {
  padding-bottom: max(0px, calc((100 - var(--instrument-band-bottom)) * 1svh - var(--instrument-foot)));
}
/* On a phone the figure covers the top of the screen to the end, so the
   last section scrolls on until it is clear under the figure: the page
   never rests with a line cut by the figure's edge. The stage is the plate
   and 23px of padding and rule below the header. */
@media (max-width: 959.98px) {
  .instrument-track,
  .instrument-track:has(> .instrument-section:last-child > .instrument-mark) {
    padding-bottom: max(0px, calc(100svh - var(--instrument-top) - min(100vw - 2 * var(--gutter), 44svh) - 23px - var(--instrument-foot)));
  }
  /* Paper after the figure's last transition (no marker in it or after
     it) slides over the figure, so it has the screen below the header; a
     page that ends on it needs no room after it. Paper before a marker
     stays under the figure, which would otherwise move unseen. */
  .instrument-paper:not(:has(> .instrument-mark, ~ .instrument-section > .instrument-mark)) { z-index: 3; }
  .instrument-track:has(> .instrument-paper:last-child):not(:has(> .instrument-section:last-child > .instrument-mark)) { padding-bottom: 0; }
}

/* The ice paper: the first run of sections with items (instrumentPlan),
   edge to edge, with a printed ruler along its top. On a wide screen the
   figure stays over it. */
.instrument-paper {
  --instrument-ink: var(--dn-void);
  --instrument-ink-soft: var(--dn-navy);
  --instrument-rule: rgba(12, 23, 50, 0.16);
  --instrument-rule-strong: rgba(12, 23, 50, 0.45);
  --focus: var(--dn-brick);
  margin-inline: calc(-1 * var(--gutter));
  padding-inline: var(--gutter);
  padding-top: 0;
  border-top: 0;
  background-color: var(--dn-plasma);
  background-image:
    linear-gradient(rgba(78, 127, 170, 0.09) 1px, transparent 1px),
    linear-gradient(90deg, rgba(78, 127, 170, 0.09) 1px, transparent 1px);
  background-size: 24px 24px;
  background-position: -1px -1px;
  color-scheme: light;
}
.instrument-paper::before {
  content: "";
  display: block;
  height: 18px;
  margin-bottom: clamp(2.75rem, 7vh, 4.5rem);
  border-bottom: 1px solid var(--instrument-rule-strong);
  background:
    repeating-linear-gradient(90deg, var(--instrument-rule-strong) 0 1px, transparent 1px 100px) left bottom / 100% 16px no-repeat,
    repeating-linear-gradient(90deg, var(--instrument-rule-strong) 0 1px, transparent 1px 20px) left bottom / 100% 7px no-repeat;
}
/* A run of paper sections is one sheet: the ruler tops the first. */
.instrument-paper + .instrument-paper::before { display: none; }
.instrument-paper ::selection { background: var(--dn-ice); color: var(--dn-void); }
.instrument-paper .more { color: var(--dn-brick); border-bottom-color: rgba(138, 62, 42, 0.5); }
.instrument-paper .more:hover { border-bottom-color: var(--dn-brick); }
/* On paper the ring is brick, without the glow, like the focus ring. */
.instrument-paper .heading::before { border-color: var(--dn-brick); box-shadow: none; }

/* References: a bibliography, the title linked, on hairlines. The titles
   are a step above the text, not display type. */
.instrument-refs,
.instrument-defs { margin: 0; padding: 0; list-style: none; }
.instrument-refs { margin-top: 2rem; border-top: 1px solid var(--instrument-rule-strong); }
.instrument-refs li {
  padding-block: 0.95rem;
  border-bottom: 1px solid var(--instrument-rule);
}
.instrument-refs a { display: block; text-decoration: none; }
.instrument-refs__title {
  display: block;
  font-family: var(--font-display);
  font-variation-settings: "opsz" 24;
  font-size: clamp(1.0625rem, 1rem + 0.2vw, 1.1875rem);
  font-weight: 400;
  line-height: 1.35;
  text-decoration: underline 1px var(--instrument-rule-strong);
  text-underline-offset: 0.2em;
  text-wrap: pretty;
}
.instrument-refs a:hover .instrument-refs__title { text-decoration-color: var(--dn-brick); }
.instrument-refs__detail {
  display: block;
  margin-top: 0.3rem;
  font: 400 0.8125rem / 1.5 var(--font-label);
  letter-spacing: 0.04em;
  color: var(--instrument-ink-soft);
}

/* Definitions: side by side where there is room, on hairlines. */
.instrument-defs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  gap: 0 clamp(1.5rem, 3vw, 3rem);
}
.instrument-defs li {
  padding-block: 1.25rem 1.75rem;
  border-top: 1px solid var(--instrument-rule-strong);
}
.instrument-defs__title {
  font-family: var(--font-display);
  font-variation-settings: "opsz" 72;
  font-size: clamp(1.35rem, 1.1rem + 0.7vw, 1.75rem);
  font-weight: 360;
  letter-spacing: 0.012em;
  line-height: 1.18;
  color: var(--instrument-ink);
}
.instrument-defs__detail { margin-top: 0.7rem; color: var(--instrument-ink-soft); text-wrap: pretty; }

/* ---------- The figure ----------
   On a phone it sticks under the header and the text runs beneath it; on a
   wide screen it sticks in the right half, centred in the viewport. */

.instrument-rail { display: contents; }
.instrument-stage {
  position: sticky;
  top: var(--instrument-top);
  z-index: 2;
  margin-inline: calc(-1 * var(--gutter));
  padding: 10px var(--gutter) 12px;
  background: var(--dn-void);
  border-bottom: 1px solid var(--hairline);
}
.instrument-plate-box {
  position: relative;
  width: var(--instrument-plate);
  aspect-ratio: 1;
  margin-inline: auto;
  overflow: clip;
  background: var(--dn-void);
}
.instrument-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: hidden; }
.instrument-stage figcaption {
  width: var(--instrument-plate);
  margin: 0 auto;
  padding: 0.6rem 0.9rem 0.7rem;
  background: var(--dn-void);
  font: 400 var(--fs-label) / 1.55 var(--font-label);
  letter-spacing: 0.06em;
  color: var(--dn-steel-on-dark);
}

@media (min-width: 960px) {
  .instrument-track {
    --instrument-top: 73px;
    --instrument-band-top: 30;
    --instrument-band-bottom: 58;
    --instrument-sw: 1;
    --instrument-foot: 7rem;
    --instrument-plate: min(100%, calc(100svh - var(--instrument-top) - 8rem));
  }
  .instrument-head,
  .instrument-section { width: calc((100% - var(--instrument-gap)) / 2); }
  .instrument-paper { width: auto; }
  /* A section taller than its text, for its markers, holds the text still
     while the figure moves. */
  .instrument-copy { position: sticky; top: calc(var(--instrument-top) + 2.5rem); }
  .instrument-section { scroll-margin-top: var(--instrument-top); }
  .instrument-rail {
    display: block;
    position: absolute;
    top: 0;
    bottom: 0;
    right: var(--gutter);
    width: calc((100% - 2 * var(--gutter) - var(--instrument-gap)) / 2);
  }
  .instrument-stage {
    display: flex;
    flex-direction: column;
    justify-content: center;
    height: calc(100svh - var(--instrument-top));
    margin: 0;
    padding: 0;
    background: none;
    border: 0;
  }
  .instrument-plate-box,
  .instrument-stage figcaption { margin-inline: auto 0; }
  /* The paper runs edge to edge; its text keeps to the left column. */
  .instrument-paper { padding-right: calc(var(--gutter) + (100% + var(--instrument-gap)) / 2); }
  .instrument-paper::before { margin-right: calc(-100% - var(--instrument-gap)); }
  /* The first screen is the head beside the figure. */
  .instrument-head {
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-height: calc(100svh - var(--instrument-top));
  }
}

/* ---------- Drawing ---------- */

.instrument-svg path,
.instrument-ring,
.instrument-probe-ring { fill: none; }
.instrument-grat { stroke: var(--dn-steel-on-dark); stroke-opacity: 0.3; stroke-width: calc(1.2px * var(--instrument-sw)); }
.instrument-drawn { stroke-dasharray: 1 2; }
/* Strokes keep their width when a group scales (--instrument-k). */
.instrument-lattice,
.instrument-link,
.instrument-build {
  stroke-width: calc(2.6px * var(--instrument-sw) / max(var(--instrument-k, 1), 0.25));
  stroke-linejoin: round;
  stroke-linecap: round;
}
/* Segments stretch along their length: flat ends, or the caps would
   stretch with them. */
.instrument-link,
.instrument-join { stroke-linecap: butt; }
.instrument-frame {
  stroke: var(--dn-steel-on-dark);
  stroke-opacity: 0.6;
  stroke-width: calc(1.4px * var(--instrument-sw) / max(var(--instrument-k, 1), 0.25));
}
.instrument-svg .instrument-disc { fill: #000; }
.instrument-ring {
  stroke: var(--dn-ring);
  stroke-width: calc(3px * var(--instrument-sw) / max(var(--instrument-k, 1), 0.25));
  stroke-linecap: round;
}
.instrument-inner {
  stroke-width: calc(1.4px * var(--instrument-sw) / max(var(--instrument-k, 1), 0.25));
  stroke-linejoin: round;
  stroke-linecap: round;
}
.instrument-trail { stroke: var(--dn-ring); stroke-width: calc(3.4px * var(--instrument-sw)); stroke-linecap: round; }
.instrument-probe-ring {
  stroke: var(--dn-ice);
  stroke-width: calc(1.8px * var(--instrument-sw) / max(var(--instrument-k, 1), 0.25));
  stroke-dasharray: 6 8;
}
.instrument-probe-ticks { stroke: var(--dn-ice); stroke-width: calc(1.8px * var(--instrument-sw) / max(var(--instrument-k, 1), 0.25)); }
.instrument-scale-base { stroke: var(--dn-ice); stroke-width: calc(2px * var(--instrument-sw)); stroke-linecap: butt; }
.instrument-scale-ticks { stroke: var(--dn-steel-on-dark); stroke-width: calc(1.6px * var(--instrument-sw)); }
.instrument-svg .instrument-scale-mark { fill: var(--dn-gold); }
.instrument-reading { stroke: var(--dn-gold); stroke-width: calc(2.2px * var(--instrument-sw)); stroke-linecap: round; }

/* ?p=: the document scrolls inside body, because headless captures ignore
   the window's scroll position. Body is a flex column; its children keep
   their height, so the sticky header is the one visitors see. */
.instrument-p { height: 100%; overflow: hidden; }
.instrument-p body { height: 100%; min-height: 0; overflow-y: auto; }
.instrument-p body > * { flex-shrink: 0; }
