/* ────────────────────────────────────────────────────────────────────────────
   LoC-Intelligence
   ───────────────────────────────────────────────────────────────────────────
   The field carries the colour. This layer only has to stay legible on top of
   it and get out of the way — so it is nearly monochrome, with one warm accent
   that shifts per section to stay in step with the disc.
   ──────────────────────────────────────────────────────────────────────────── */

@font-face{
  font-family:'Lexend';
  src:url('assets/lexend-latin.woff2') format('woff2');
  font-weight:100 900; font-style:normal; font-display:swap;
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
                U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,
                U+2212,U+2215,U+FEFF,U+FFFD;
}

:root{
  /* These carry real content over a picture, so they are set by contrast
     rather than by taste: measured against the darkest ground each section
     puts under the text column, every one of them clears WCAG AA. */
  --ink:        #f0f3f7;
  --ink-soft:   rgba(240,243,247,.76);
  --ink-faint:  rgba(240,243,247,.66);
  /* --ink-ghost dresses no text anywhere: measured against this field it
     lands at 4.28:1 wherever it falls, which misses AA for small type. It is
     kept for the one thing that is not text — the fade of the onward mark. */
  --ink-ghost:  rgba(240,243,247,.46);
  --rule:       rgba(240,243,247,.12);
  --rule-soft:  rgba(240,243,247,.07);

  /* the one warm accent — retuned per section to match the disc */
  --accent:     #f6ae5e;
  /* The wordmark does not retune. In the logo the "o" is the sun and it is
     always the same orange; an identity that changes colour per section is not
     an identity. The glyph beside it takes the same value, because the two sit
     ten pixels apart and would otherwise disagree. */
  --mark:       #f6ae5e;

  --ease:       cubic-bezier(.22,.61,.36,1);
  --ease-out:   cubic-bezier(.16,1,.3,1);
  --slow:       1.5s;

  --gut:        clamp(20px, 5vw, 76px);
  --dock-h:     72px;
}

body[data-section="substrate"]{ --accent:#e08c50; }
body[data-section="state"]    { --accent:#e4813e; }
body[data-section="field"]    { --accent:#cdd6e2; }

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

html{ background:#070C18; -webkit-text-size-adjust:100%; }

body{
  font-family:'Lexend',-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif;
  font-weight:300;
  font-size:clamp(15px,.55vw + 13px,17px);
  line-height:1.62;
  color:var(--ink);
  background:#070C18;
  min-height:100svh;
  overflow-x:hidden;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  transition:background .9s var(--ease);
}

/* ── the field ─────────────────────────────────────────────────────────── */
#field-canvas,
.field-fallback{
  position:fixed; inset:0; z-index:0;
  width:100%; height:100%;
  display:block;
  pointer-events:none;
}
/* stands in if WebGL is unavailable — the page must never be a black slab */
.field-fallback{
  z-index:-1;
  background:
    radial-gradient(46% 36% at 62% 44%, rgba(246,174,94,.30) 0%, rgba(246,174,94,0) 62%),
    radial-gradient(80% 60% at 50% 100%, rgba(159,182,210,.10) 0%, rgba(159,182,210,0) 70%),
    linear-gradient(180deg,#070C18 0%,#111C31 58%,#2A2231 100%);
}
#field-canvas.dead{ display:none; }

/* The field is a picture, and type on a picture needs quiet ground under it.
   This scrim sits between the two: heavy where the column is, gone where the
   disc is, so the composition still reads as one image. */
.scrim{
  position:fixed; inset:0; z-index:1;
  pointer-events:none;
  background:linear-gradient(96deg,
    rgba(5,8,16,.80) 0%,
    rgba(5,8,16,.68) 28%,
    rgba(5,8,16,.34) 48%,
    rgba(5,8,16,0)   68%);
  transition:opacity .9s var(--ease);
}

/* The field is a picture for the hero. Once someone has scrolled past it they
   are reading, and reading text travels over the brightest part of the frame
   — so the picture gives way. Narrow screens only: on a wide one the type has
   its own column beside the disc and never crosses it. */
.scrim::after{
  content:'';
  position:absolute; inset:0;
  background:rgba(5,8,16,.86);
  opacity:0;
}

/* Loci's horizon haze is the brightest ground any type on this site sits on,
   and it crosses the column exactly where the standfirst ends. This band is
   held down harder than the other sections need; the sun and the sky to the
   right of it are untouched.

   The stops carry the strong part past the right edge of the type column,
   which sits at about 43% of the width. With the shoulder at 52% the last
   line of the hero reached only 4.37:1 — the column ends inside the falloff,
   and the glitter on the water reaches that far across. */
body[data-section="loci"] .scrim{
  background:linear-gradient(96deg,
    rgba(5,8,16,.88) 0%,
    rgba(5,8,16,.82) 34%,
    rgba(5,8,16,.62) 56%,
    rgba(5,8,16,0)   76%);
}

/* everything above the field */
.dock,main,.foot,.locus{ position:relative; z-index:2; }

.skip{
  position:absolute; left:-9999px; top:0; z-index:20;
  background:#0b1120; color:var(--ink);
  padding:12px 18px; border-radius:0 0 10px 0;
}
.skip:focus{ left:0; }

/* ── dock ──────────────────────────────────────────────────────────────── */
.dock{
  position:fixed; top:0; left:0; right:0; z-index:6;
  height:var(--dock-h);
  display:flex; align-items:center; justify-content:space-between;
  gap:24px;
  padding:0 var(--gut);
  /* a whisper of shading so the words never fight the sky behind them */
  background:linear-gradient(180deg,rgba(6,10,20,.52) 0%,rgba(6,10,20,.16) 62%,rgba(6,10,20,0) 100%);
  backdrop-filter:blur(1.5px);
  -webkit-backdrop-filter:blur(1.5px);
}
/* The veil under the dock. On a wide screen the hero sits clear of it and
   the sky shows through; once the reading starts, body text travels up under
   the wordmark, and the veil comes with `--read` so the two never collide.
   Twice the dock's height, so the fade is never seen as an edge. */
.dock::before{
  content:'';
  position:absolute; left:0; right:0; top:0;
  height:200%;
  z-index:-1;
  pointer-events:none;
  background:linear-gradient(180deg,
    rgba(5,8,16,.94) 0%,
    rgba(5,8,16,.88) 32%,
    rgba(5,8,16,.52) 64%,
    rgba(5,8,16,0) 100%);
  opacity:var(--read, 0);
}

.mark{
  display:inline-flex; align-items:center; gap:10px;
  text-decoration:none; color:var(--ink);
  letter-spacing:.005em;
  transition:opacity .35s var(--ease);
}
.mark:hover{ opacity:.82; }
.mark-glyph{
  width:19px; height:19px; flex:none;
  color:var(--mark);
  transition:transform .6s var(--ease-out);
}
.mark:hover .mark-glyph{ transform:rotate(-8deg); }
.mark-text{ font-size:15px; font-weight:300; white-space:nowrap; }
.mark-text b{ font-weight:600; letter-spacing:-.01em; }

/* The wordmark's own "o" is the disc. It takes the section's accent, so the
   name in the corner is lit by the same light as the picture behind it. */
.wo{
  font-style:normal;
  color:var(--mark);
}

/* Four words and a line. No container: the sections are not settings, and a
   segmented control is a piece of somebody else's interface. What marks the
   current one is the site's own figure — the horizon, a 1px cut, the width of
   the word — sliding under whichever is open. */
.tabs{
  position:relative;
  display:flex; align-items:center; gap:6px;
}
.tabs a{
  position:relative; z-index:1;
  display:block;
  padding:9px 12px 11px;
  font-size:13.5px; font-weight:300; letter-spacing:.02em;
  color:var(--ink-faint);
  text-decoration:none;
  white-space:nowrap;
  transition:color .4s var(--ease);
}
.tabs a:hover{ color:var(--ink-soft); }
.tabs a[aria-current="page"]{ color:var(--ink); }

/* the line that slides between words, measured to the word rather than to
   the link, so it reads as a waterline under the type and not as a tab */
.tab-ink{
  position:absolute; z-index:0; left:0; bottom:5px;
  height:1px; width:0;
  background:linear-gradient(90deg,
    rgba(240,243,247,0) 0%, rgba(240,243,247,.85) 22%,
    rgba(240,243,247,.85) 78%, rgba(240,243,247,0) 100%);
  box-shadow:0 0 8px rgba(240,243,247,.22);
  transition:transform .55s var(--ease-out), width .55s var(--ease-out);
  will-change:transform,width;
}
.tabs.no-anim .tab-ink{ transition:none; }

/* ── panels ────────────────────────────────────────────────────────────── */
main{ display:block; }

/* Each section opens on one screen and continues below it. The hero is what
   the visitor is given; the rest is what they go and get. */
.panel{ padding:0 var(--gut); }
.panel[hidden]{ display:none; }

.wrap{
  width:100%;
  max-width:min(52ch, 46vw);
}

/* The hero is set against a line in the picture. The field tells the page
   where that line is — the waterline where there is one, the centre of the
   disc where there is not — as `--anchor-y`, in viewport pixels, updated as
   the disc morphs. Everything above the line (eyebrow, title) sits in the sky
   and closes on it from above; everything below (standfirst, the ways out)
   stands in the water. So the type and the picture are one composition rather
   than two columns that happen to share a screen. */
.hero{
  position:relative;
  min-height:100svh;
  display:grid;
  grid-template-rows:minmax(min-content, calc(var(--anchor-y, 58svh) + var(--anchor-lift, 0px))) 1fr;
  align-content:start;
}
.hero-sky{
  align-self:end;
  padding:calc(var(--dock-h) + 32px) 0 var(--sky-gap, 22px);
}
.hero-water{
  padding:var(--water-gap, 24px) 0 108px;
}
/* The strand titles are single words at 92px. Their optical middle — the
   x-height of the lowercase — is about .44 of the type size above the bottom
   of the line box, and that is what has to meet the disc's equator: the o in
   "LoCI State" on the same line as the core. Measured, not guessed. */
#sec-substrate .hero,
#sec-state .hero{
  --anchor-lift:calc(clamp(46px, 5.4vw + 14px, 92px) * .44);
  --sky-gap:0px;
  --water-gap:34px;
}
/* Feld: the word rests on the cut. The line box has a little air under the
   baseline, so the gap is taken back by that much. */
#sec-field .hero{
  --anchor-lift:calc(clamp(46px, 5.4vw + 14px, 92px) * .12);
  --sky-gap:0px;
  --water-gap:34px;
}
.more{ padding:0 0 132px; }

/* the entrance: each element arrives a beat after the one above it */
.panel .hero-sky > *,
.panel .hero-water > *,
.panel .onward{
  opacity:0;
  transform:translateY(14px);
}
.panel.in .hero-sky > *,
.panel.in .hero-water > *,
.panel.in .onward{
  opacity:1;
  transform:none;
  transition:opacity .85s var(--ease-out), transform .85s var(--ease-out);
}
.panel.in .hero-sky   > :nth-child(1){ transition-delay:.05s; }
.panel.in .hero-sky   > :nth-child(2){ transition-delay:.14s; }
.panel.in .hero-water > :nth-child(1){ transition-delay:.23s; }
.panel.in .hero-water > :nth-child(2){ transition-delay:.32s; }
.panel.in .onward{ transition-delay:.44s; }

/* the exit: quick and all at once, with no stagger, before the panel is
   hidden and the next one arrives into the changing picture */
.panel.in.out .hero-sky > *,
.panel.in.out .hero-water > *,
.panel.in.out .onward,
.panel.in.out .more{
  opacity:0;
  transform:none;
  transition:opacity .24s var(--ease);
  transition-delay:0s;
}

/* the cue that there is more below — a line that breathes downward */
.onward{
  position:absolute; left:0; bottom:56px;
  width:1px; height:44px;
  background:linear-gradient(180deg,rgba(240,243,247,0) 0%,var(--ink-ghost) 45%,rgba(240,243,247,0) 100%);
  overflow:visible;
}
.onward::after{
  content:'';
  position:absolute; left:0; top:0;
  width:1px; height:14px;
  background:var(--accent);
  animation:onward 3.4s var(--ease) infinite;
}
@keyframes onward{
  0%,12%  { transform:translateY(0);    opacity:0; }
  30%     { opacity:.85; }
  70%     { opacity:.85; }
  88%,100%{ transform:translateY(30px); opacity:0; }
}

/* ── type ──────────────────────────────────────────────────────────────── */
.eyebrow{
  font-size:11.5px; font-weight:400;
  letter-spacing:.17em; text-transform:uppercase;
  color:var(--ink-faint);
  margin-bottom:26px;
}

h1{
  font-size:clamp(29px,2.3vw + 12px,46px);
  line-height:1.13;
  font-weight:250;
  letter-spacing:-.022em;
  text-wrap:balance;
  max-width:22ch;
}
/* the strand titles are single words — let them sit large and quiet */
#h-substrate,#h-state,#h-field{
  font-size:clamp(46px,5.4vw + 14px,92px);
  font-weight:200;
  letter-spacing:-.038em;
}

.standfirst{
  font-size:clamp(17px,.8vw + 14px,21px);
  line-height:1.5;
  font-weight:300;
  color:var(--ink);
  max-width:42ch;
  margin-bottom:30px;
  text-wrap:pretty;
}

.cols{
  display:flex; flex-direction:column; gap:19px;
  color:var(--ink-soft);
  max-width:50ch;
  padding-top:8px;
  margin-bottom:38px;
}
.cols p{ text-wrap:pretty; }
.cols em{ font-style:normal; color:var(--ink); }

/* German sets long compounds into a narrow column; without hyphenation the
   rag gets violent and single words overhang. Headings are left alone —
   a hyphenated headline reads worse than a slightly uneven one. */
.cols p, .q-t, .locus-body p, .nots li, .meta dd{
  hyphens:auto;
  -webkit-hyphens:auto;
}
h1, .standfirst{ overflow-wrap:break-word; }

/* the invariant, and anything else that has to be read as a sentence twice */
.pull{
  margin:4px 0 2px;
  padding-left:18px;
  border-left:1px solid var(--accent);
  font-size:clamp(16px,.5vw + 14px,18.5px);
  line-height:1.42;
  color:var(--ink);
  hyphens:none;
}

/* the paragraph that names what is missing. It is set apart because it is the
   one thing on the page a visitor would not expect to find, and burying it in
   the run of text would look like burying it. */
.gap{
  padding:16px 0 0;
  border-top:1px solid var(--rule);
  color:var(--ink-soft);
}
.gap em{ color:var(--ink); }

/* ── the "not" list ────────────────────────────────────────────────────── */
.nots{
  list-style:none;
  border-top:1px solid var(--rule);
  margin-bottom:36px;
}
.nots li{
  position:relative;
  padding:11px 0 11px 22px;
  border-bottom:1px solid var(--rule-soft);
  font-size:14.5px;
  color:var(--ink-faint);
}
.nots li::before{
  content:'';
  position:absolute; left:2px; top:calc(50% - .5px);
  width:9px; height:1px;
  background:currentColor;
  opacity:.7;
}

/* ── meta table ────────────────────────────────────────────────────────── */
.meta{
  border-top:1px solid var(--rule);
  font-size:14px;
}
.meta > div{
  display:flex; gap:18px; align-items:baseline;
  padding:11px 0;
  border-bottom:1px solid var(--rule-soft);
}
.meta dt{
  flex:none; width:8.5em;
  color:var(--ink-faint);
  font-size:11.5px; letter-spacing:.14em; text-transform:uppercase;
}
.meta dd{ color:var(--ink-soft); }

/* ── a numbered run of findings ─────────────────────────────────────────
   Like the question list, but meant to be read through rather than scanned,
   so it does not dim its own siblings on hover. */
.ladder{
  list-style:none;
  border-top:1px solid var(--rule);
  margin-bottom:34px;
}
.ladder li{
  display:flex; gap:20px; align-items:baseline;
  padding:14px 0;
  border-bottom:1px solid var(--rule-soft);
}
.ladder .q-t{ color:var(--ink-soft); }
.ladder .q-n{ color:var(--accent); opacity:.75; }

/* ── questions ─────────────────────────────────────────────────────────── */
.questions{
  list-style:none;
  border-top:1px solid var(--rule);
  margin-bottom:34px;
}
.questions li{
  display:flex; gap:20px; align-items:baseline;
  padding:16px 0;
  border-bottom:1px solid var(--rule-soft);
  transition:opacity .5s var(--ease);
}
.questions:hover li{ opacity:.42; }
.questions li:hover{ opacity:1; }
.q-n{
  flex:none;
  font-size:11.5px; letter-spacing:.1em;
  /* Not --ink-ghost: at 11.5px over this field, 0.46 alpha measures 4.28:1 and
     misses AA. The ladder overrides this with the accent anyway; the open
     questions fell through to it and were the one place it showed. */
  color:var(--ink-faint);
  font-variant-numeric:tabular-nums;
  padding-top:.35em;
}
.q-t{
  color:var(--ink-soft);
  text-wrap:pretty;
}
.questions li:hover .q-t{ color:var(--ink); }

/* ── the "o" that holds the structure ──────────────────────────────────────
   The wordmark's disc, made into a control. It has to read as pressable while
   nobody is pointing at it — the thing it opens is the whole character of the
   section, and a visitor who never touches it sees a room with the lights
   half off. So: a ring at rest that breathes, and a real one on hover. */
.glyph-o{
  position:relative;
  display:inline-block;
  font:inherit; color:inherit;
  background:none; border:0; padding:0;
  cursor:pointer;
  line-height:1;
  vertical-align:baseline;
  -webkit-tap-highlight-color:transparent;
}
.glyph-o-in{
  position:relative; z-index:1;
  display:inline-block;
  transition:color .5s var(--ease);
}
/* The ring, sized and placed off the glyph rather than off the em box. A
   lowercase o sits well below the middle of its line box: measured against the
   loaded font, its ink centre is at 61% of the button's height, not 50%.
   The button is exactly 1em tall, so this holds at every heading size. */
.glyph-o::before{
  content:'';
  position:absolute; z-index:0;
  left:50%; top:61%;
  /* sized against the letter it rings, not against the heading's font size —
     at 92px type, 1.62em put a 149px halo around a 55px glyph */
  width:.95em; height:.95em;
  margin:-0.475em 0 0 -0.475em;
  border-radius:50%;
  border:1px solid var(--accent);
  opacity:.30;
  transform:scale(.94);
  transition:opacity .45s var(--ease), transform .45s var(--ease-out),
             box-shadow .45s var(--ease);
  animation:oBreathe 4.6s var(--ease) infinite;
}
/* a seed of what is inside, so the invitation says what it is offering */
.glyph-o::after{
  content:'';
  position:absolute; z-index:0;
  left:50%; top:61%;
  width:.48em; height:.48em;
  margin:-0.24em 0 0 -0.24em;
  border-radius:50%;
  border:1px solid var(--accent);
  opacity:.16;
  transform:rotate(0deg) scale(.9);
  transition:opacity .45s var(--ease), transform 1.1s var(--ease-out);
}
@keyframes oBreathe{
  0%,100%{ opacity:.24; }
  50%    { opacity:.44; }
}

.glyph-o:hover::before,
.glyph-o:focus-visible::before{
  opacity:1;
  transform:scale(1.06);
  box-shadow:0 0 22px -4px var(--accent), inset 0 0 14px -6px var(--accent);
  animation:none;
}
.glyph-o:hover::after,
.glyph-o:focus-visible::after{ opacity:.42; transform:rotate(120deg) scale(1); }
.glyph-o:hover .glyph-o-in{ color:var(--accent); }
.glyph-o:active::before{ transform:scale(.98); }

/* switched on: the ring stops asking and simply burns */
.glyph-o[aria-pressed="true"]::before{
  opacity:.92;
  border-color:var(--accent);
  box-shadow:0 0 26px -6px var(--accent), inset 0 0 16px -7px var(--accent);
  animation:none;
}
.glyph-o[aria-pressed="true"]::after{ opacity:.55; transform:rotate(180deg) scale(1.02); }
.glyph-o[aria-pressed="true"] .glyph-o-in{ color:var(--accent); }

/* the boat is drawn in the field, so the cursor has to be told about it */
body.over-boat{ cursor:pointer; }

.sr{
  position:absolute; width:1px; height:1px;
  padding:0; margin:-1px; overflow:hidden;
  clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

/* ── outbound line ─────────────────────────────────────────────────────── */
.lede-out{
  font-size:14.5px;
  color:var(--ink-faint);
  display:flex; flex-wrap:wrap; align-items:center; gap:12px;
}
.lede-out.subtle{ max-width:46ch; display:block; padding-top:6px; }
/* after a table of facts the link needs air, or it hangs off the last rule */
.meta + .lede-out{ margin-top:30px; }
.aside{ color:var(--ink-faint); font-size:13px; }

.go{
  display:inline-flex; align-items:center; gap:7px;
  padding:7px 15px 7px 16px;
  border:1px solid var(--rule);
  border-radius:999px;
  color:var(--ink);
  font-size:13.5px;
  text-decoration:none;
  transition:border-color .4s var(--ease), background .4s var(--ease), transform .4s var(--ease-out);
}
.go::after{
  content:'→';
  color:var(--accent);
  transition:transform .4s var(--ease-out), color var(--slow) var(--ease);
}
.go:hover{
  border-color:rgba(240,243,247,.26);
  background:rgba(240,243,247,.045);
}
.go:hover::after{ transform:translateX(3px); }

/* A link that leaves the place for a document. The arrow turns, because this
   one does not morph a section — it opens a text. */
.go-doc::after{ content:'↗'; }
.go-doc:hover::after{ transform:translate(2px,-2px); }

/* ── footer ────────────────────────────────────────────────────────────── */
.foot{
  position:fixed; left:0; right:0; bottom:0; z-index:5;
  padding:0 var(--gut) 20px;
  pointer-events:none;
  background:linear-gradient(0deg,
    rgba(5,8,16,.94) 0%,
    rgba(5,8,16,.80) 38%,
    rgba(5,8,16,.34) 72%,
    rgba(5,8,16,0) 100%);
}
.foot-in{
  display:flex; align-items:center; justify-content:space-between;
  gap:20px; flex-wrap:wrap;
  padding-top:52px;
  font-size:12.5px;
  color:var(--ink-faint);
}
.foot-line{ display:flex; align-items:center; gap:10px; pointer-events:auto; }
.foot-name b{ font-weight:600; color:var(--ink); }
.sep{ opacity:.5; }
.imprint{ white-space:nowrap; }
/* The other language. It names itself in itself — someone who cannot read the
   page they are on can still read the way out of it. */
.lang{ white-space:nowrap; }
.foot .lang{ border-bottom:1px solid var(--rule-soft); }
.foot a{
  color:var(--ink-faint); text-decoration:none;
  border-bottom:1px solid transparent;
  transition:color .35s var(--ease), border-color .35s var(--ease);
}
.foot a:hover{ color:var(--ink); border-bottom-color:var(--rule); }

/* The index of places. A found one can be opened again — otherwise the first
   reading is the only one, and the footer is a score rather than a shelf. */
.index{ display:inline-flex; align-items:center; gap:3px; pointer-events:auto; }
.index button{
  display:grid; place-items:center;
  width:15px; height:15px; padding:0;
  background:none; border:0;
  border-radius:50%;
  cursor:default;
}
.index button::before{
  content:'';
  width:5px; height:5px; border-radius:50%;
  background:transparent;
  box-shadow:inset 0 0 0 1px rgba(240,243,247,.26);
  transition:background .8s var(--ease), box-shadow .8s var(--ease),
             transform .5s var(--ease-out);
}
.index button.on{ cursor:pointer; }
.index button.on::before{
  background:var(--accent);
  box-shadow:0 0 9px -1px var(--accent);
  transform:scale(1.18);
}
.index button.on:hover::before{ transform:scale(1.7); }

/* back to nothing found, for anyone who wants to go looking again */
.reset{
  margin-left:4px;
  padding:2px 8px;
  font:inherit; font-size:11px; letter-spacing:.09em; text-transform:lowercase;
  color:var(--ink-faint);
  background:none;
  border:1px solid transparent;
  border-radius:999px;
  cursor:pointer;
  pointer-events:auto;
  transition:color .35s var(--ease), border-color .35s var(--ease);
}
.reset:hover{ color:var(--ink-faint); border-color:var(--rule); }
.reset[hidden]{ display:none; }
.reset.asking{ color:var(--accent); border-color:var(--rule); }

/* The register: specials that have been on at least once. The scene is where
   they are found; this is so nobody has to find them twice. */
.register{ display:inline-flex; align-items:center; gap:6px; pointer-events:auto; }
.register:empty{ display:none; }
.register::before{ content:'·'; opacity:.5; margin-right:2px; }
.register button{
  padding:2px 9px;
  font:inherit; font-size:11px; letter-spacing:.06em;
  color:var(--ink-faint);
  background:none;
  border:1px solid var(--rule-soft);
  border-radius:999px;
  cursor:pointer;
  transition:color .35s var(--ease), border-color .35s var(--ease),
             background .35s var(--ease);
}
.register button:hover{ color:var(--ink-faint); border-color:var(--rule); }
.register button[aria-pressed="true"]{
  color:var(--accent);
  border-color:color-mix(in srgb, var(--accent) 42%, transparent);
  background:color-mix(in srgb, var(--accent) 9%, transparent);
}

/* ── a found locus ─────────────────────────────────────────────────────── */
.locus{
  position:fixed; inset:0; z-index:9;
  display:flex; align-items:center; justify-content:center;
  padding:var(--gut);
  background:rgba(4,7,14,.62);
  backdrop-filter:blur(9px) saturate(.9);
  -webkit-backdrop-filter:blur(9px) saturate(.9);
  opacity:0;
  transition:opacity .8s var(--ease);
}
.locus[hidden]{ display:none; }
.locus.in{ opacity:1; }

.locus-in{
  width:100%; max-width:46ch;
  padding:38px clamp(24px,3vw,42px) 30px;
  border:1px solid var(--rule);
  border-radius:3px;
  background:linear-gradient(180deg,rgba(13,19,32,.90) 0%,rgba(9,13,23,.94) 100%);
  box-shadow:0 40px 90px -30px rgba(0,0,0,.8);
  transform:translateY(16px) scale(.985);
  transition:transform .9s var(--ease-out);
}
.locus.in .locus-in{ transform:none; }

.locus-eyebrow{
  font-size:11px; letter-spacing:.19em; text-transform:uppercase;
  color:var(--accent);
  margin-bottom:14px;
}
.locus-h{
  font-size:clamp(24px,2vw + 14px,32px);
  font-weight:250; letter-spacing:-.025em; line-height:1.15;
  margin-bottom:22px;
}
.locus-body{
  display:flex; flex-direction:column; gap:16px;
  font-size:15.5px;
  color:var(--ink-soft);
}
.locus-body em{ font-style:normal; color:var(--ink); }
.locus-quote{
  font-size:17px; line-height:1.45;
  color:var(--ink);
  padding-left:18px;
  border-left:1px solid var(--accent);
}
.locus-close{
  margin-top:28px;
  padding:8px 18px;
  font:inherit; font-size:13px;
  color:var(--ink-faint);
  background:transparent;
  border:1px solid var(--rule);
  border-radius:999px;
  cursor:pointer;
  transition:color .35s var(--ease), border-color .35s var(--ease);
}
.locus-close:hover{ color:var(--ink); border-color:rgba(240,243,247,.26); }

/* ── noscript ──────────────────────────────────────────────────────────── */
.noscript{
  position:relative; z-index:8;
  max-width:60ch;
  margin:calc(var(--dock-h) + 40px) auto 40px;
  padding:0 var(--gut);
  display:flex; flex-direction:column; gap:14px;
  color:var(--ink-soft);
}
/* without JS every panel is shown, stacked, and reads as one document */
html:not(.js) .panel[hidden]{ display:flex; }
/* The entrance is driven by a class the script adds. Without the script it is
   never added, so every hero — eyebrow, heading, standfirst, links — would sit
   at opacity 0 and the page would read as four bodies with no titles. */
html:not(.js) .panel .hero-sky > *,
html:not(.js) .panel .hero-water > *,
html:not(.js) .panel .onward{ opacity:1; transform:none; }

/* ── selection ─────────────────────────────────────────────────────────── */
/* selected text takes the light of the section, not the browser's blue */
::selection{
  background:color-mix(in srgb, var(--accent) 34%, transparent);
  color:var(--ink);
}

/* ── focus ─────────────────────────────────────────────────────────────── */
:focus-visible{
  outline:1px solid var(--accent);
  outline-offset:3px;
  border-radius:2px;
}

/* ── narrow ────────────────────────────────────────────────────────────── */
@media (max-width:1080px) and (min-width:761px){
  .wrap{ max-width:52ch; }
  .standfirst{ max-width:36ch; }
  /* the column runs further across a mid-sized screen, into the arena's
     outer cells; the scrim's shoulder moves out with it */
  .scrim{
    background:linear-gradient(96deg,
      rgba(5,8,16,.82) 0%,
      rgba(5,8,16,.72) 36%,
      rgba(5,8,16,.40) 56%,
      rgba(5,8,16,0)   76%);
  }
}

@media (max-width:1080px){
  .onward{ display:none; }
}

@media (max-width:760px){
  :root{ --dock-h:64px; }

  .dock{ gap:14px; padding:0 var(--gut); }
  .mark-text{ display:none; }
  .mark-glyph{ width:22px; height:22px; }
  .tabs{ flex:1; justify-content:space-between; gap:0; }
  .tabs a{ padding:9px 9px 11px; font-size:12.5px; }

  /* The disc takes the upper third; the type sits under it. There is no line
     the type could share with the picture here, so the anchor grid gives way
     to a plain stack pushed to the foot of the screen. */
  .hero{
    display:flex; flex-direction:column; justify-content:flex-end;
    padding:calc(var(--dock-h) + 30vh) 0 92px;
  }
  /* align-self:end was the grid's "sit on the line"; in a column it would
     mean "sit on the right" */
  .hero-sky{ align-self:auto; padding:0 0 24px; }
  .hero-water{ padding:0; }
  .wrap{ max-width:none; }

  /* On narrow screens the disc is above the type, so the scrim turns vertical.
     The Loci variant has to be named again here: a media query adds no
     specificity, and `body[data-section] .scrim` would otherwise keep winning
     and leave the phone with a sideways gradient. */
  .scrim{
    background:linear-gradient(180deg,
      rgba(6,10,20,0) 17%,
      rgba(6,10,20,.56) 38%,
      rgba(6,10,20,.86) 62%,
      rgba(6,10,20,.93) 100%);
  }
  /* Loci puts the sun's path on the water straight through the type. The sky,
     the sun and the band along the horizon stay untouched; the near water,
     which is where the reading happens, goes dark. */
  body[data-section="loci"] .scrim{
    background:linear-gradient(180deg,
      rgba(6,10,20,0) 14%,
      rgba(6,10,20,.48) 28%,
      rgba(6,10,20,.87) 44%,
      rgba(6,10,20,.94) 100%);
  }
  .scrim::after{ opacity:var(--read,0); }

  .meta dt{ width:7em; }
  /* The phone puts the disc in the upper third, so the dock sits on the
     brightest part of the picture — the arena ring reaches (224,153,94) up
     there, and the tabs read 1.78:1 against it. The veil is on from the
     start here, not only once the reading begins. */
  .dock::before{ opacity:1; }

  /* On a phone a fixed footer is a tenth of the screen that never reads. It
     goes to the end of the page instead, where the index of places is what
     a visitor arrives at rather than what sits over what they are reading. */
  .foot{ position:relative; padding-top:0; }
  .foot-in{ justify-content:center; text-align:center; padding-top:40px; }
  .more{ padding-bottom:24px; }
  .foot-right{ width:100%; justify-content:center; }
  /* the phone footer keeps the controls and drops the label */
  .where{ display:none; }
  .register::before{ display:none; }
}

@media (max-width:420px){
  .tabs a{ padding:9px 6px 11px; font-size:12px; }
}

/* ── paper ─────────────────────────────────────────────────────────────── */
/* The place is not made for paper, but it must not print as a black slab
   with white gaps. Everything that is picture goes; the four sections come
   out stacked, one to a page, as the readable text they also are. */
@media print{
  @page{ margin:22mm 20mm 24mm; }
  :root{
    --ink:       #14171c;
    --ink-soft:  #2c3138;
    --ink-faint: #5b616a;
    --rule:      rgba(0,0,0,.30);
    --rule-soft: rgba(0,0,0,.14);
    --accent:    #8F4718;
    --mark:      #8F4718;
  }
  html, body{ background:#fff; color:var(--ink); }
  body{ font-weight:400; }
  #field-canvas, .field-fallback, .scrim, .dock, .foot, .locus, .onward,
  .noscript, .skip, .glyph-o::before, .glyph-o::after{ display:none !important; }

  .panel[hidden]{ display:block; }
  .panel{ padding:0; break-before:page; }
  .panel:first-of-type{ break-before:auto; }
  .wrap{ max-width:none; }
  .hero{ min-height:0; display:block; }
  .hero-sky{ padding:0 0 14pt; }
  .hero-water{ padding:0 0 18pt; }
  .more{ padding:0; }
  .panel .hero-sky > *, .panel .hero-water > *{ opacity:1; transform:none; }
  .cols, .standfirst, h1{ max-width:none; }
  .questions:hover li{ opacity:1; }
  .ladder li, .questions li, .nots li, .meta > div, .pull, .gap{ break-inside:avoid; }
  h1{ font-size:24pt; }
  #h-substrate, #h-state, #h-field{ font-size:34pt; }
  .go{ border:0; padding:0; color:var(--ink); }
  .go::after{ content:none; }
  .lede-out a, .cols a{ color:inherit; text-decoration:none; }
}

/* ── reduced motion ────────────────────────────────────────────────────── */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    scroll-behavior:auto !important;
  }
  .panel .hero-sky > *,
  .panel .hero-water > *,
  .panel .onward{ opacity:1; transform:none; }
}
