:root{
  --color-prussian:#1A253D;--color-prussian-900:#0E1626;--color-prussian-700:#1A253D;--color-prussian-500:#2F3F5E;--color-prussian-300:#6C7B95;--color-prussian-100:#C6CEDC;
  --color-rust:#9D4D27;--color-rust-700:#9D4D27;--color-rust-500:#B86A45;--color-rust-300:#D69A7E;
  --color-chestnut:#C58848;--color-chestnut-700:#C58848;--color-chestnut-500:#DAA470;--color-chestnut-300:#EBC9A4;--color-chestnut-100:#F7E8D5;
  --color-ebony:#494C3B;--color-vellum:#F6F2E9;--color-parchment:#CBCBBF;--color-greige:#9F9B8A;--color-india-ink:#111213;
  --bg:var(--color-vellum);--bg-ink:var(--color-prussian-900);--fg:var(--color-india-ink);--fg-2:var(--color-prussian-700);--fg-3:#6D7058;--fg-inv:var(--color-vellum);
  --accent:var(--color-rust-700);--gold:var(--color-chestnut-700);
  --line-1:rgba(30,29,30,.14);--line-2:rgba(30,29,30,.28);
  --bg-field:#DDDED2; /* the bibliography search field */
  --font-insc:"Cinzel","Trajan Pro","Times New Roman",serif;--font-disp:"Cormorant Garamond","Garamond","Hoefler Text",serif;--font-serif:"EB Garamond","Garamond",Georgia,serif;--font-sans:"Archivo Narrow","Helvetica Neue",Arial,sans-serif;
  /* type scale: one rule, 17px (the running text) × 6:5ⁿ, the minor third. Every font
     size is one of these steps; a fluid size runs between two neighbouring steps.
     −3 9.8 · −2 11.8 · −1 14.2 · 0 17 · 1 20.4 · 2 24.5 · 3 29.4 · 4 35.3 · 5 42.3 · 6 50.8 */
  --fs-0:17px;
  --fs-1:calc(var(--fs-0) * 6 / 5);--fs-2:calc(var(--fs-1) * 6 / 5);--fs-3:calc(var(--fs-2) * 6 / 5);
  --fs-4:calc(var(--fs-3) * 6 / 5);--fs-5:calc(var(--fs-4) * 6 / 5);--fs-6:calc(var(--fs-5) * 6 / 5);
  --fs--1:calc(var(--fs-0) * 5 / 6);--fs--2:calc(var(--fs--1) * 5 / 6);--fs--3:calc(var(--fs--2) * 5 / 6);
  --tr-cap:.12em;--tr-caps:.08em;--ease:cubic-bezier(.2,0,0,1);--ink-dur:3.0s;--ink-text:0s;--dur:.55s;--bar-h:52px;
  /* side gutters, +15% over the original 22 / 18 / 14. the full-bleed strips and
     docked cards read --pad-x back as a negative margin, so they stay flush */
  --pad-x:25.3px;--bar-x:20.7px;
  --shadow-card:0 1px 0 rgba(30,29,30,.06),0 4px 14px -8px rgba(30,29,30,.20);
  --shadow-plate:0 1px 0 rgba(30,29,30,.06),0 16px 36px -18px rgba(30,29,30,.34);
  --cursor-auge:url("../assets/op-auge-cursor.svg") 16 6,pointer;
}
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%;scrollbar-width:none}
/* one owner for the reading place: every fold, the auto-close, the reload and the
   language switch set the scroll position in step with what they move. The browser's
   own scroll anchoring (Chrome for years, Safari since 27) corrected the same shifts a
   second time, and in Safari the two disagreed by a pixel on every frame — the page
   shook while a panel rolled and the pinned titles trembled while scrolling */
html{overflow-anchor:none}
/* the gold hairline at the top of the page carries the reading position, so the
   grey native gutter is hidden on desktop too (mobile already hides all of them
   at ≤719px). wheel, trackpad, keys, touch and the anchor jumps are untouched —
   only the painted bar goes */
html::-webkit-scrollbar,body::-webkit-scrollbar{width:0;height:0;display:none}
body{background:var(--bg);color:var(--fg);font-family:var(--font-serif);font-size:17px;line-height:1.55;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;overflow-x:hidden}
img{display:block;max-width:100%}
button{font:inherit;color:inherit;background:none;border:none;cursor:pointer}
::selection{background:var(--color-chestnut-300);color:var(--color-india-ink)}
a:focus-visible,button:focus-visible,input:focus-visible,[tabindex]:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
body.is-ink a:focus-visible,body.is-ink button:focus-visible{outline-color:var(--color-chestnut-500)}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}*{transition-duration:.001ms!important;animation-duration:.001ms!important}}

/* the paper grain blends normally. Multiply looked the same (no pixel differs by more
   than 2 of 255 levels at 5 %), but a blended full-screen layer has to be recomposed
   with everything under it on every frame: it halved the frame rate of every fold */
.grain{position:fixed;inset:0;z-index:1;pointer-events:none;opacity:.05;
  background-image:radial-gradient(circle at 20% 30%,currentColor .6px,transparent .8px),radial-gradient(circle at 70% 40%,currentColor .5px,transparent .7px),radial-gradient(circle at 40% 80%,currentColor .4px,transparent .7px);background-size:17px 19px,23px 29px,31px 37px}

/* progress + topbar */
/* matte hairline, full width. The fill is a hard-stop gradient driven by --p:
   no width transition to lag behind the scroll, no transform (a scaled layer
   inside the zoomed body tears in WebKit), no glow */
.progress{--p:0%;position:fixed;top:0;left:0;right:0;height:3px;z-index:60;pointer-events:none;
  background:linear-gradient(to right,var(--gold) var(--p),transparent var(--p))}
/* where the browser has scroll timelines it fills the bar with the scroll itself, and no
   script writes --p: a full-width fill slides in from the left, so its edge sits where the
   gradient's stop did. A slide, not a scale (see above) */
@supports (animation-timeline:scroll()){
  .progress{background:none;overflow:clip}
  .progress::before{content:"";position:absolute;inset:0;background:var(--gold);transform:translateX(-100%);animation:progress-fill linear both;animation-timeline:scroll(root block)}
}
@keyframes progress-fill{to{transform:none}}
.topbar{position:fixed;top:0;left:0;right:0;height:var(--bar-h);z-index:55;display:flex;align-items:center;gap:calc(14px * var(--bar-k));padding:0 var(--bar-x);padding-top:env(safe-area-inset-top);
  background:color-mix(in oklab,var(--bg) 75%,transparent);backdrop-filter:blur(18px) saturate(1.1);border-bottom:1px solid var(--line-1);
  transform:translateY(-110%);opacity:0;transition:transform .4s var(--ease),opacity .4s var(--ease),background .5s var(--ease),border-color .5s var(--ease)}
.topbar.show{transform:none;opacity:1}
body.is-ink-bar .topbar{background:color-mix(in oklab,var(--bg-ink) 75%,transparent);border-color:rgba(255,255,255,.12);color:var(--fg-inv)}
body.is-ink-bar .topbar__cur{color:var(--fg-inv)}
/* the signature alone carries the brand — no wordmark to stack above it, so the
   column layout goes with it. The link's name lives on aria-label now that its only
   content is a decorative image. */
.topbar__brand{display:flex;align-items:center;text-decoration:none;color:inherit}
/* sized up from the 14px it held under the wordmark: on its own the autograph has to
   read as the mark, not as a fleck beside the controls */
/* the signature is PAINTED, not drawn: the artwork is a mask and its ink is a plain
   background-color, so the light↔dark change is one interpolated colour — the same
   thing text does. The old filter chain could not: it walked six functions at once
   (156° of hue-rotate among them), so its mid-transition frames belonged to neither
   state, and mix-blend-mode is not animatable at all, so it snapped mid-fade. A fast
   scroll flips the bar again inside the .5s window and parked the mark in that middle.
   aspect-ratio replaces the intrinsic size the <img> used to supply. */
.topbar__auge--sig{--sig:url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDg4IiBoZWlnaHQ9IjEzNyIgdmlld0JveD0iMCAwIDQ4OCAxMzciIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGQ9Ik0xMzcuNzcyIDUzLjg0NDFDMTUyLjM3NyAyMS4zMTExIDE4NC40OTMgOS42NzEwNyAyMTcuMjI0IDIuNjk1MDdDMjQwLjg0MSAtMi4zMzc5MyAyNzMuNjUxIC0wLjkwNTkxNyAyOTQuMjg2IDExLjk5OTFDMzAzLjYwNiAxNy44MjgxIDMxMC43NTEgMzEuNTE3MSAzMDUuMTMxIDQxLjYyNzFDMzAxLjQwNiA0OS41NjkxIDI3MC45NTEgNTguNjExMSAyNzAuMTE2IDQ4Ljk2MjFDMjc1LjE2MSA0NC44NTAxIDI5NC45MzEgNDUuNjY2MSAyOTYuMDcxIDM1LjgwOTFDMjk4LjQ2NiAxNC45OTgxIDI2NS45MDEgNi4xODkwNiAyNTAuMjA2IDYuNTg3MDZDMjE2LjAxMSA3LjUwMDA2IDE1OS4wNjIgMTYuOTMxMSAxNTAuNjMgNTcuNjA4MUMxNDYuNTQzIDc3LjMyMzEgMTU1LjU2OCA4MC40OTExIDE3Mi4xNTcgODIuOTQxMUMxNzcuNDggNzcuNjcyMSAxODQuMTczIDY2LjEwNjEgMTg4LjkyMSA1OS41MjUxQzE5Ni44OSA0OC40NzkxIDIwNy45NDEgMzguMDc2MSAyMjEuODk4IDM1LjgwODFDMjI3LjE4NyAzOC4xODYxIDIzNS4wODYgMzguMzk3MSAyNDEuMjQxIDQwLjIwMjFDMjQ5LjgwNiA0Mi43MTUxIDI1OC41MDYgNDguODg1MSAyNjIuNzk2IDU2Ljc1OTFDMjYxLjc5MSA1OC44MzcxIDI2MS42ODYgNTkuMzEzMSAyNjAuMDk2IDYwLjkwMDFDMjUyLjUxNiA2NC4xNDAxIDI0NC41NzYgNDMuNDEwMSAyMjcuNjUyIDQzLjY1OTFDMjEwLjM1OSA0My45MTQxIDIwMi41MjIgNTUuMzMzMSAxOTIuNjQ4IDY4LjI4MjFDMTg5LjE1MSA3Mi44NjgxIDE4OC4wNzcgNzYuMzMwMSAxODMuNjY2IDgwLjMyMDFMMTgzLjA2NCA4MC44NTYxQzE5NS43MTQgNzMuNzIyMSAyMTMuNzcxIDYzLjU1NDEgMjI3Ljk3MyA2MC4xOTcxQzIyNS4yMDYgNjIuMTY4MSAyMjAuMTgyIDY0Ljc1MjEgMjE3LjA0IDY2LjUxMTFDMjEwLjI4OCA3MC4zMjcxIDIwMy41MDQgNzQuMDg3MSAxOTYuNjg4IDc3Ljc5MDFDMTg2LjQ2OSA4My4yOTMxIDE4Mi4wOTEgODQuODM5MSAxNzYuMTY1IDk1LjMwNjFDMTcyLjUzOSAxMDEuNzExIDE2OC4xNDUgMTA3LjkxNyAxNjQuNjM4IDExNC41NkMxNTkuODY1IDEyMy42MDIgMTU3LjE4NyAxMzEuODAxIDE0Ny4yOTggMTM2LjA5MUMxNDQuNzg4IDEzNS4yOTEgMTM5Ljk4NyAxMzMuOTMxIDE0MC4wMDkgMTMwLjg0MUMxNTMuMTg3IDEyMi4xMDEgMTUyLjgzIDEwNC4yNjYgMTY3LjEyOCA5Mi4xMDcxQzE1Mi44IDkwLjQ0MDEgMTQwIDg2Ljg0MzEgMTM3LjEwOCA2OS42MjYxQzEzNi42MDQgNjYuNjI1MSAxMzcuNzAxIDYxLjk1NTEgMTM2LjA2OCA1OS41NTYxQzEzMi4xNTQgNTkuODk1MSAxMjkuNDg1IDU2LjU0MjEgMTIxLjI5NyA1OC4xNzQxQzEwNS4yODggNjEuMzY2MSA5Ny42NzQgNjguMzEyMSA4OC43NiA4MS42NjAxQzg2Ljg5MiA4NC4zMTYxIDg1LjQ2OSA4Ni42MTIxIDgzLjc4NSA4OS4zOTAxQzc4LjgwNyA5Ni44NjAxIDcwLjAxIDEwNS42NDMgNjcuMTM1IDExMy44NTJMNjcuMzA3IDExNC41NzFDNjkuNjkzIDExMy4wMyA4NC41NjQgOTQuMDI2MSA4Ny4xNjQgOTAuNTIyMUM4OS4zODkgODguNjg4MSA5MS4xODUgODUuNjM1MSA5My43OTcgODMuNTM5MUw5Ni4xOSA4MS42MzQxQzk5LjY5MSA3OS44NDUxIDEwMi4xNTcgNzcuOTQ1MSAxMDUuODM3IDc4LjkzNjFDMTEwLjczNiA4My4xNjYxIDkzLjMwMSAxMDMuMzM1IDg5Ljk0NCAxMDcuNTg4QzkyLjY0NCAxMDUuNjE3IDEwNC41NjUgOTQuNTQ0MSAxMDcuMzY2IDk0Ljk3ODFDMTE2LjA0NSA5Ni4zMjExIDExMi4wOTggMTA0LjE5MSAxMDkuNjkyIDEwOS4yMzJDMTA1Ljg0MSAxMTcuMzA0IDEwMy41MDQgMTIxLjUzMyA5Ni42NTQgMTI3LjQ4OUM5NC4xMzUgMTI1LjM3NiA5Mi4wOTggMTI0LjIzNiA4OS4yODQgMTIyLjU1MUM4My4yNyAxMjYuMTc3IDc1Ljg4NyAxMzIuNzkxIDY5Ljk3NSAxMjUuMDg3QzcwLjM3MiAxMjMuNjE4IDcwLjM4IDEyNC4wNTcgNzAuMzI4IDEyMi42MDJDNjcuMjIyIDEyMi42MTkgNjEuMTM0IDEyOC42NDYgNTcuODcxIDEyOS45OTFDNTYuMDMxIDEzMC43NTEgNDguMDczIDEzMi4yODYgNDguMDgyIDEyOC44NDZDNDguMTIyIDExMy42NjQgNjEuNjAyIDEwMi43NTEgNjcuNTE2IDg4Ljg5MzFDNDguOTk4IDEwNy43MDIgMzcuNzc0IDExOS43MTggMTQuMDkyIDEzMi4xNzFDOS44ODUwMSAxMzEuODc2IDUuNTMyMDEgMTMxLjA1NiAyLjQ5NzAxIDEyNy44NDhDMC43MDAwMDcgMTI1Ljk0OCAtMC4xODA5OTcgMTIzLjIyOSAwLjAzMTAwMzIgMTIwLjYyOUMwLjcyNzAwMyAxMTIuMDc4IDI3LjM4NCA4MS40NDkxIDM0Ljk0OSA3NC45NDgxQzM5LjIxNiA3MS4yODExIDQ1LjM0NCA2Ni4wODgxIDUxLjQwOSA2Ni45ODMxQzUyLjY4OSA2Ny4xNzExIDUzLjE2NiA2Ny42MDUxIDUzLjk3MiA2OC41NTcxQzU0LjExNSA3MC4zMDAxIDUzLjk4OSA3MC43NTMxIDUzLjcxNiA3Mi40MjkxTDU0LjA4NSA3Mi43NzQxTDU0Ljg0NyA3MS4xNTkxTDU1LjI0MiA3MS4wMzMxQzU4Ljc5MiA2OS44NDkxIDYyLjE2NiA2Ni45NjAxIDY1LjQxOCA2NC44NDUxQzc1LjAzNyA2Ni44ODMxIDcxLjggNjguOTQ0MSA3Mi43NDcgNzYuODcwMUw3My41NDcgNzcuMjg5MUM3Ny42MjEgNzMuOTkwMSA4NS4wNTcgNjIuMzg1MSA5MC40ODkgNTkuMTgzMUM5My4yMTggNTcuNTc1MSA5OS4xNzUgNTYuMzcxMSAxMDIuNTE3IDU1LjU2NTFDMTE2LjczNyA1Mi4xMzYxIDEyMy41MjIgNDkuNjU1MSAxMzcuNzcyIDUzLjg0NDFaTTE1Ljg1MSAxMTkuMTA3QzIxLjUwOSAxMTQuNDExIDI2LjY1MyAxMDYuODQ0IDMxLjQzNyAxMDAuOTk4QzM3LjAyMiA5NC4xNzUxIDQ1LjYwOCA4NC42NjYxIDUwLjM5NyA3Ny40MTQxQzUwLjAzNyA3Ni4xMTMxIDUwLjMzMiA3Ni43MzgxIDQ4Ljc3IDc1Ljc0MDFDMzguNjA2IDg1LjA1ODEgMjguNTUxIDk0LjA5ODEgMjEuMzQxIDEwNS45NTJDMTkuODIxIDEwOC40NSAxNC4zMzQgMTE2LjM2MiAxNC45MjYgMTE5LjE1N0wxNS44NTEgMTE5LjEwN1pNNTAuOTQ5IDkwLjg2MDFDNDUuNjc4IDk2Ljg2NDEgMzkuNTM3IDEwMy4wOTkgMzUuMzUzIDEwOS44MzRDNDAuNTYgMTA1Ljc4NSA0Ni43MDYgOTguNzE1MSA1Mi4wNjUgOTMuODA3MUM1NS44NDEgODkuODE1MSA2MS42MTUgODIuOTg3MSA2My42NzkgNzcuOTExMUw2My40NCA3Ny4zNjYxQzYwLjc0MiA3OC43NjQxIDUzLjE5MiA4OC4wODAxIDUwLjk0OSA5MC44NjAxWiIgZmlsbD0iIzIwMUYyMCIvPgo8cGF0aCBkPSJNMzUuNjk3IDEwOC40NTNDMzkuODgxIDEwMS43MTggNDYuMDIyIDk1LjQ4MjUgNTEuMjkzIDg5LjQ3ODVDNTEuOTIyIDkwLjgzMzUgNTIuMDU4IDkwLjk1MDUgNTIuNDA5IDkyLjQyNTVDNDcuMDUgOTcuMzMzNSA0MC45MDQgMTA0LjQwNSAzNS42OTcgMTA4LjQ1M1oiIGZpbGw9IiMwMjAyMDIiIGZpbGwtb3BhY2l0eT0iMC4wMTk2MDc4Ii8+CjxwYXRoIGQ9Ik0zMTguMjggOTEuNTc4NEMzMTkuNzYgOTIuMzg2NCAzMjEuOTggOTMuMjgwNCAzMjIuNTk1IDk1LjAwMDRDMzI0LjAxNSA5OC45NzE0IDMyMi4yMjUgMTAxLjY5NiAzMTguMTU1IDEwMi42MTJDMzE3LjgwNSAxMDEuMzU5IDMxNy45MDUgMTAxLjM0MiAzMTYuOTggMTAwLjQ2M0MzMDUuMTc1IDk5LjE4ODQgMzAxLjExIDEwOS41NTEgMjk0LjI0NSAxMTUuMzE0QzI5My41NzUgMTE1Ljg3OCAyOTIuNTcgMTE1LjA2MyAyOTEuOTU1IDExNy4wNzFMMjkyLjU4NSAxMTcuNTE2TDI5NC4wNTUgMTE2LjIzNUMzMTYuMSAxMTQuMDc2IDM1MS4zMzUgODYuMTIyNCAzNzEuMTM1IDc1LjI1MjRDMzc2LjY0NSA3Mi4yMjU0IDM3OS45MjUgNjguMDkwNCAzODcuNDQ1IDY3LjY4MDRDMzkwLjQxNSA2Ny41MTg0IDM5My4zOTUgNzAuMzcwNCAzOTMuODc1IDczLjAxMTRDMzkyLjQ5IDc0LjkxMTQgMzg5LjI5NSA3NS44Mzg0IDM4Ny4xMiA3Ny43NzE0QzM3NS43MyA4Ny44ODk0IDM2OC44NzUgOTMuNzQ3NCAzNTkuNjY1IDEwNS45MDFMMzU0LjUxNSAxMTEuMjMzQzM1Ny4zNTUgMTA5LjYxNiAzNTguODI1IDEwOC44NjEgMzYxLjE3IDEwNi40MzlDMzY3LjQ0NSAxMDIuNzQ4IDM2OS40NiAxMDAuMjk5IDM3Ni42OSA5OC43NTA0QzM4Mi4wMSAxMDMuMTA2IDM4My4wNzUgMTA0LjI0NSAzODEuODggMTExLjQ5MkMzODEuNCAxMTQuMzggMzgxLjE4IDExNi40NTIgMzgwLjMwNSAxMTkuMzg0QzM4OS45MzUgMTE0LjQxMSA0MTAuOSA5MS4xNjA0IDQxOS4yNDUgODIuMjQ5NEM0MTUuNDY1IDgwLjk2NDQgNDE0LjEgODAuNTE2NCA0MTAuNjQgNzguNTgwNEw0MTEuMjYgNzMuNzA1NEM0MjEuOTcgNjcuODU5NCA0MzMuOTQgNzQuMTgwNCA0NDUuNjE1IDc0LjI4OTRDNDUyLjA0IDc0LjkzMDQgNDU4LjcwNSA3NC4zNTU0IDQ2NS4xMDUgNzQuODI5NEM0NzUuMzggNzUuNTkwNCA0ODMuMjk1IDcxLjc2NTQgNDg3LjE1IDgzLjM0NDRDNDg2LjM4NSA4NS41OTM0IDQ4NS44NTUgODcuNzQzNCA0ODMuOTk1IDg5LjA1MzRDNDc4LjUyIDg5Ljk4NDQgNDc4LjIyIDg1LjQzMDQgNDc1LjA5NSA4NC44MDE0QzQ2Ny45NSA4My4zNjM0IDQ0NC45NCA4Ni4yNDg0IDQzOC43MSA4OC41NTU0QzQzNC41MzUgOTcuNzY0NCA0MjYuMzY1IDEyMi4yMjYgNDE4Ljk1NSAxMjguMTZDMzk2LjQ4IDEzMi45NCA0MjAuNDUgMTAwLjcwOCA0MjMuODUgOTQuMjc1NEw0MjQuMTQ1IDkzLjcwNDRDNDEzLjA2NSA5OS4yNDY0IDQwNi40NyAxMDYuNzggMzk3LjM4NSAxMTQuNjgyQzM5MS45OSAxMTkuMzggMzg0Ljg3NSAxMjQuODE4IDM3OS4xMzUgMTI5LjE4QzM1NS45MiAxMzEuNTM1IDM2OS42NiAxMTMuNzY0IDM2Ni4xNTUgMTA4LjIxMUMzNjIuMTIgMTA5LjAxNCAzNDkuMTYgMTE5LjUxNyAzNDUuNDA1IDEyMi40ODdDMzQzLjA1NSAxMjIuNjk5IDMzNi43OCAxMjAuMjQgMzM3LjM1NSAxMTcuNjU5QzMzOS43NTUgMTA2Ljg2MiAzNTYuNjA1IDk1LjcwNTQgMzYzLjQ4IDg3LjU0OTRMMzYzLjk1IDg2Ljk4NTRDMzU4LjY2NSA4OC44MDA0IDM1NS4wMTUgOTEuNjAzNCAzNTAuMTg1IDk0LjUzOTRDMzMzLjc2NSAxMDQuNTY3IDMxOC40NTUgMTE2LjQwNCAzMDAuMzM1IDEyMy4zNTJDMjk1LjE0IDEyNS4zNDQgMjgxLjMxIDEyNi4wMiAyNzkuMTA1IDExOC43NTJDMjc3LjEzNSAxMTIuMjUgMjg0LjMzNSAxMDcuMzIxIDI4OC45NTUgMTAzLjkxM0MyOTguMzk1IDk2Ljk0NjQgMzA2LjYgOTMuMjk0NCAzMTguMjggOTEuNTc4NFoiIGZpbGw9IiMyMDFGMjAiLz4KPHBhdGggZD0iTTI1MS41NTUgODEuODgyOEwyNTEuOTkgODIuMjA2OEMyNTMuNjEgODIuMTkxOCAyNTQuOTcgODIuNTM0OCAyNTUuOTMgODMuODE1OEMyNTQuMDU1IDg4LjMwMzggMjIxLjE4MiA4Ni4zMDU4IDIxNi45MTcgODguMjcyOEMyMTguNjI0IDkwLjUxNTggMjIzLjI4OCA4OC42ODM4IDIyNi45MzEgOTAuMDY1OEMyMzAuNTYzIDkxLjQ0MjggMjMxLjQ4NSA5MS44MzE4IDIzNC43NjUgOTMuOTM0OEMyMzkuMTg1IDk2Ljc4OTggMjQzLjMzNSAxMDAuMDQ1IDI0Ny4xNiAxMDMuNjYxQzI1Mi4wOTUgMTA4LjMzNSAyNjguNTk1IDEyOC4xOSAyNzMuNTY1IDEyOC4wMUwyNzMuNTQgMTI4LjU4NUMyNzAuNzA1IDEzMC4xIDI2NS4wMSAxMzEuNjc1IDI2MS40NCAxMzMuMDg1QzI1OS4yOTUgMTMzLjAwNSAyNTguMjIgMTMyLjY5NSAyNTYuMSAxMzIuMjE1QzI0Ny45NCAxMjUuMjc3IDI0My4yOSAxMTQuMjgxIDIzNC4zOCAxMDYuNzFDMjI2Ljk0OCA5OS45Mzk4IDIxNy44NzQgOTQuOTg1OCAyMDguMzI4IDkxLjkwNjhDMjAxLjg3MyA4OS44MjU4IDE5Ni40NDIgODguMjM3OCAxOTAuNTY1IDg0Ljc3NThDMTk5Ljk1MSA4Mi44NTA4IDIwNi41OSA4My4wMjY4IDIxNS45MTYgODIuNzE2OEwyNTEuNTU1IDgxLjg4MjhaIiBmaWxsPSIjMjAxRjIwIi8+CjxwYXRoIGQ9Ik0zNTkuNjY1IDEwNS45MDFMMzYxLjE3IDEwNi40NEMzNTguODI1IDEwOC44NjIgMzU3LjM1NSAxMDkuNjE2IDM1NC41MTUgMTExLjIzM0wzNTkuNjY1IDEwNS45MDFaIiBmaWxsPSIjMzMzMzMxIiBmaWxsLW9wYWNpdHk9IjAuMDc0NTA5OCIvPgo8L3N2Zz4K");
  display:block;height:19px;aspect-ratio:488/137;background-color:var(--fg);
  -webkit-mask:var(--sig) center/contain no-repeat;mask:var(--sig) center/contain no-repeat;
  transition:background-color .5s var(--ease)}
/* one token, exactly — no filter chain to solve and nothing to drift */
body.is-ink-bar .topbar__auge--sig{background-color:var(--color-chestnut-500)}
/* the station indicator IS the stations selector: it reads "Stationen" until a
   station is active, then carries that station's № + title as its own label */
.topbar__cur{margin-inline-start:auto;position:relative;display:flex;align-items:center;min-width:0;max-width:52vw;cursor:pointer;
  font-family:var(--font-sans);font-size:calc(12px * var(--bar-k));line-height:1;letter-spacing:var(--tr-caps);text-transform:uppercase;
  color:color-mix(in oklab,var(--color-greige) 70%,var(--color-india-ink));
  border:0;border-radius:0;padding:0;background:none;transition:color .15s}
.topbar__cur:hover{color:var(--accent);text-decoration:underline;text-underline-offset:calc(5px * var(--bar-k));text-decoration-thickness:1px}
.topbar__cur:focus-visible{outline:2px solid var(--accent);outline-offset:4px}
/* bare text carries no box to shift, so the dark bar hovers on the underline
   alone — recolouring the ink-mode label would trade a 13:1 pairing for a 5:1 one */
body.is-ink-bar .topbar__cur:hover{color:var(--fg-inv)}
/* the visible mark is text only; the tap area is restored invisibly so the
   44px target survives the box removal */
.topbar__cur::before,.topbar__lang::before{content:"";position:absolute;inset:-14px -6px}
.topbar__curval{display:flex;align-items:center;min-width:0}
.topbar__curval:empty{display:none}
.topbar__curval:not(:empty)+.topbar__curlabel{display:none} /* the live station replaces the generic word */
/* the station appears in place — the fade only takes the edge off the swap so it
   reads as arriving rather than blinking */
@keyframes topbarCurIn{from{opacity:0}to{opacity:1}}
.topbar__cur.is-fresh :is(.topbar__curval,.topbar__curlabel){animation:topbarCurIn .34s var(--ease) both}
/* the divider that used to separate the numeral from the station title goes with the
   title — a rule with nothing on its far side reads as a stray mark */
/* control scale: every control icon is 1em of the 13px control/label size (--ctl) —
   the globe, the "Näher sehen" + / ×, the docked-bar ×; the caret is half (6.5px
   wide); one 1.5px stroke (--ctl-stroke). The bar's station numeral is a type-scale
   value, not derived: Cinzel 600 at 17px, the running-text step. The top bar shows
   this cluster enlarged, see .topbar below. */
:root{--ctl:13px;--ctl-stroke:1.5px}
/* the top bar's two controls, the station selector and the globe, sit one step up:
   their control size is 17px, the running-text step, instead of the 13px label top.
   The whole cluster is enlarged by that one factor, 17/13, so its proportions stay
   as they were: label 12px, numeral 17px, caret gap 9px, the gap to the globe 14px
   (12px on phones) and the 1.5px stroke, each × 17/13. Tap areas stay fixed (≥44px).
   The "Näher sehen" sign and the docked-bar × keep the 13px control size. */
.topbar{--bar-k:calc(17 / 13);--ctl:calc(13px * var(--bar-k));--ctl-stroke:calc(1.5px * var(--bar-k))}
.topbar__num{font-family:var(--font-insc);font-weight:600;font-size:calc(17px * var(--bar-k));letter-spacing:.06em;color:var(--gold);flex:none;line-height:1}
/* the control is a station readout AND the station selector; text alone reads as the
   readout only, and the hover underline cannot say so on touch. One disclosure caret
   carries it — not a hamburger, which would announce a generic nav drawer and be the
   only borrowed UI mark on a page whose icon language is the serif +/× and the globe.
   currentColor, so it follows the label into the dark band with no second rule.
   flex:none keeps it out of the title's ellipsis budget. */
.topbar__caret{flex:none;width:calc(var(--ctl) / 2);height:calc(var(--ctl) / 4);overflow:visible;margin-inline-start:calc(9px * var(--bar-k));fill:none;stroke:currentColor;stroke-width:var(--ctl-stroke);stroke-linecap:round;stroke-linejoin:round;opacity:.75;transition:transform .3s var(--ease),opacity .15s}
.topbar__cur:hover .topbar__caret{opacity:1}
/* the same rotate-to-close move the panel and drawer marks already use */
.topbar__cur[aria-expanded="true"] .topbar__caret{transform:rotate(180deg)}
/* language selector — the bare globe mark, no chip */
/* stretched to the bar's own height so the dropdown still hangs off the bar's
   bottom edge — without the chip's padding the wrapper alone is too short */
.topbar__langwrap{position:relative;display:flex;align-items:center;align-self:stretch}
.topbar__lang{position:relative;display:flex;align-items:center;justify-content:center;border:0;border-radius:0;padding:0;background:none;color:color-mix(in oklab,var(--color-greige) 70%,var(--color-india-ink));transition:color .15s}
.topbar__lang:hover{color:var(--accent)}
.topbar__lang:focus-visible{outline:2px solid var(--accent);outline-offset:4px}
.topbar__globe{display:block;width:calc((var(--ctl) - var(--ctl-stroke)) * 24 / 18);height:calc((var(--ctl) - var(--ctl-stroke)) * 24 / 18);fill:none;stroke:currentColor;stroke-width:var(--ctl-stroke);stroke-linecap:round}
/* strokes keep their CSS width whatever the drawing's scale */
:is(.topbar__caret,.topbar__globe) *{vector-effect:non-scaling-stroke}
/* the globe's hit zone reaches past 44px: 10px towards the station control (that
   control reaches 4px, the bar gap is 14px × 17/13), the rest into the bar's edge padding */
.topbar__cur::before{inset:-14px -4px -14px -6px}
.topbar__lang::before{inset:-15px -19px -15px -10px}
body.is-ink-bar .topbar__lang{color:var(--fg-inv)}
/* the icon has no text to underline, so ink-mode hover warms it to the lightest
   chestnut — equal contrast to the resting vellum, never below it */
body.is-ink-bar .topbar__lang:hover{color:var(--color-chestnut-100)}
.langmenu{position:absolute;inset-inline-end:0;top:calc(100% + 8px);margin:0;padding:4px;list-style:none;width:max-content;
  background:color-mix(in oklab,var(--bg) 92%,transparent);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);
  border:1px solid var(--line-1);border-radius:7px;box-shadow:0 12px 32px rgba(30,29,30,.14)}
.langmenu button{display:block;width:100%;text-align:start;padding:7px 12px;border-radius:5px;font-family:var(--font-sans);font-size:13px;color:var(--fg-2);transition:.15s}
.langmenu button:hover{background:color-mix(in oklab,var(--bg) 80%,var(--color-vellum));color:var(--fg)}
.langmenu button.active{color:var(--accent)}
/* desktop: menu-bar text aligns with the station column's text edge (--pad-x
   inset of the centered 1180px content column), matching the mobile alignment */
/* desktop topbar keeps the base --bar-x edge inset — components pin to the
   browser edges, not the content column (approved reference layout) */
/* mobile: the bar becomes the station wayfinder (replaces the hidden desktop rail) —
   wordmark shrinks, the station numeral and the two controls lead the bar */
@media(max-width:560px){
  .topbar{--bar-x:16.1px;gap:calc(12px * var(--bar-k));padding:0 var(--bar-x)} /* 14px + 15% */
  .topbar__brand{margin-inline-start:calc(var(--pad-x) - var(--bar-x))} /* lands the signature on the station bar's text inset */
  .topbar__auge--sig{height:18px}
  .topbar__cur{max-width:46vw}
  /* Stationen + globe stay bare text/icon here too — only the tap area tightens
     to the narrower bar gap (12px × 17/13) so the two hit zones never overlap */
  .topbar__cur::before{inset:-14px 0 -14px -5px}
  .topbar__lang::before{inset:-15px -17px -15px -12px} /* 44px and more, clear of the station control */
}

/* left timeline rail (desktop) */
.rail{position:fixed;inset-inline-start:16px;top:50%;transform:translateY(-50%);z-index:40;display:none;flex-direction:column;gap:0}
/* rail visibility is decided by fitZoom(): it needs real clearance left of the
   content column (effective width ÷ zoom ≥ ~1310px), not just raw window width */
body.rail-ok .rail{display:flex}
.rail__line{position:absolute;inset-inline-start:5px;top:6px;bottom:6px;width:1px;background:var(--line-2)}
.rail__fill{position:absolute;inset-inline-start:5px;top:6px;width:1px;height:0;background:var(--gold);transition:height .2s linear}
.rail__dot{position:relative;display:flex;align-items:center;gap:12px;padding:9px 0;text-decoration:none;color:var(--fg-3)}
.rail__dot::before{content:"";width:11px;height:11px;border-radius:999px;border:1px solid var(--line-2);background:var(--bg);z-index:1;transition:.2s}
.rail__dot .rl{position:absolute;inset-inline-start:24px;top:50%;pointer-events:none;font-family:var(--font-sans);font-size:11px;letter-spacing:var(--tr-caps);text-transform:uppercase;opacity:0;transform:translateY(-50%) translateX(-6px);transition:.2s;white-space:nowrap;
  background:color-mix(in oklab,var(--bg) 85%,transparent);backdrop-filter:blur(6px);padding:3px 8px;border-radius:2px}
body.is-ink .rail__dot .rl{background:color-mix(in oklab,var(--bg-ink) 85%,transparent)}
body.is-ink .rail__dot.active .rl{color:var(--fg-inv)}
.rail__dot:hover .rl{opacity:1;transform:translateY(-50%)}
.rail__dot.passed::before{background:var(--color-chestnut-500);border-color:var(--color-chestnut-500)}
.rail__dot.active::before{background:var(--accent);border-color:var(--accent);transform:scale(1.25)}
.rail__dot.active:hover .rl{color:var(--fg)}
body.is-ink .rail__dot::before{background:var(--bg-ink)}
body.is-ink .rail__line{background:rgba(255,255,255,.18)}
/* rail: the "minimal" hairline markers */
.rail[data-rail="minimal"] .rail__dot::before{width:14px;height:1px;border-radius:0;border:none;background:var(--line-2);transition:.2s}
.rail[data-rail="minimal"] .rail__dot.passed::before{background:var(--color-chestnut-500)}
.rail[data-rail="minimal"] .rail__dot.active::before{background:var(--accent);width:24px;transform:none}
.rail[data-rail="minimal"] .rail__dot{padding:7px 0}
.rail[data-rail="minimal"] .rail__line,.rail[data-rail="minimal"] .rail__fill{display:none}
body.is-ink .rail[data-rail="minimal"] .rail__dot::before{background:rgba(255,255,255,.25)}
body.is-ink .rail[data-rail="minimal"] .rail__dot.passed::before{background:var(--color-chestnut-500)}
body.is-ink .rail[data-rail="minimal"] .rail__dot.active::before{background:var(--color-chestnut-300)}

/* ===== HERO ===== */
main{container-type:inline-size;overflow-x:clip} /* the dark band is 100vw wide, and Chrome and the newest Safari scale vw by the page zoom (screens 1230px+), so it reached past the window and the page could be pushed sideways; clip keeps it inside and keeps sticky working */
/* ONE proportional system for the hero: every size is a multiple of --hu,
   calibrated so a 390px phone renders exactly the approved phone composition
   (1hu = 3.9px there). Wider/taller screens scale the SAME relations up,
   limited by whichever dimension runs out first — so desktop and tablet are
   the phone design magnified, filling the screen, never re-proportioned.
   The composition centres in the clear screen (100svh: above a phone's
   toolbar); the margin carries the hero on to the bottom of the largest
   screen (100lvh), so Station I never shows under a see-through toolbar
   (iOS 26 Safari and in-app browsers draw the page behind it). */
.hero{--hu:min(1cqw,calc(0.66svh / var(--pz,1)));position:relative;z-index:2;min-height:calc(100svh / var(--pz,1));margin-bottom:calc((100lvh - 100svh) / var(--pz,1));display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:calc(8*var(--hu)) var(--pad-x) calc(13*var(--hu));overflow:hidden}
/* desktop: same relations, sized so the WHOLE stack lands at ~90% of the
   window height — fills comfortably, never spills past the fold */
@media(min-width:720px){.hero{--hu:min(1cqw,calc(0.5svh / var(--pz,1)))}}
.hero__auge{width:calc(21*var(--hu));height:auto;margin:calc(3*var(--hu)) 0 calc(4*var(--hu));animation:blink 7s ease-in-out infinite,fu 1s var(--ease) both}
@keyframes blink{0%,92%,100%{opacity:1;transform:scaleY(1)}95%{opacity:.65;transform:scaleY(.08)}97%{opacity:1;transform:scaleY(1)}}
.hero__name{font-family:var(--font-insc);font-weight:600;font-size:calc(11.4*var(--hu));line-height:1;letter-spacing:.06em;text-transform:uppercase;animation:fu 1s var(--ease) .1s both}
.hero__dates{font-family:var(--font-sans);letter-spacing:.18em;font-size:calc(4.4*var(--hu));color:var(--fg-3);margin:5px 0 0;animation:fu 1s var(--ease) .26s both}
.hero__cred{font-family:var(--font-sans);letter-spacing:.14em;font-size:calc(3.7*var(--hu));text-transform:uppercase;color:var(--fg-3);margin:10px 0 0;animation:fu 1s var(--ease) .2s both}
.hero__credo{font-family:var(--font-disp);font-style:italic;font-size:calc(6.2*var(--hu));line-height:1.22;color:var(--fg-2);max-width:20ch;margin:calc(4.6*var(--hu)) auto calc(2*var(--hu));animation:fu 1.1s var(--ease) .4s both}
.hero__portrait{display:flex;align-items:flex-end;justify-content:center;gap:calc(3*var(--hu));margin:calc(3.6*var(--hu)) 0 0;animation:fu 1.2s var(--ease) .6s both}
.hero__portrait figure{width:auto}
.hero__portrait .plate img{height:100%;width:auto;max-width:none}
.hero__portrait figcaption{font-family:var(--font-sans);font-size:calc(3.7*var(--hu));letter-spacing:var(--tr-caps,.08em);text-transform:uppercase;color:var(--fg-3);margin-top:calc(1.8*var(--hu))}
.hero__sig{width:calc(18.7*var(--hu));height:auto;mix-blend-mode:multiply;opacity:.9}
.hero__sigrow{max-width:20ch;margin:6px auto 4px;display:flex;justify-content:center;animation:fu 1s var(--ease) .46s both}
/* phone: hero elements share one proportional fluid scale (ratio × name curve),
   so image / SVG / text keep the same size relations as desktop.
   container-query on <main> so it also fires inside a fixed-width preview frame. */
@container (max-width:560px){
  .hero__portrait{flex-direction:column;align-items:center}
  .hero__portrait figcaption{text-align:center}
}
.hero__cue{position:absolute;bottom:24px;left:50%;transform:translateX(-50%);font-family:var(--font-sans);font-size:11px;letter-spacing:var(--tr-caps);text-transform:uppercase;color:var(--fg-3);display:flex;flex-direction:column;align-items:center;gap:8px;animation:fu 1s var(--ease) .9s both}
.hero__cue span{width:1px;height:32px;background:var(--gold);animation:cue 1.8s var(--ease) infinite}
@keyframes cue{0%{transform:scaleY(0);transform-origin:top}50%{transform:scaleY(1);transform-origin:top}51%{transform-origin:bottom}100%{transform:scaleY(0);transform-origin:bottom}}
@keyframes fu{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
/* hero intro variant — the eye opens huge, settles into place, then the hero rises.
   A moving layer is drawn once at its laid-out size and then only resized as a picture,
   so an eye laid out small and scaled up 5.25× opened soft and pixelated. While it zooms
   it is laid out at the opened size (--k), negative margins keep its place in the stack,
   and it is scaled down to its size instead; once it has landed main.js adds .is-landed
   and it is the plain small eye again, which looks the same */
main[data-hero-intro="auge-zoom"] .hero__auge{animation:augezoom 2.6s var(--ease) backwards,blink 7s ease-in-out 3.2s infinite;transform-origin:center}
@media (prefers-reduced-motion: no-preference){main[data-hero-intro="auge-zoom"] .hero__auge:not(.is-landed){--k:5.25;--dh:calc(21*(var(--k) - 1)*var(--hu)*66/380);width:calc(21*var(--k)*var(--hu));max-width:none;margin:calc(3*var(--hu) - var(--dh)) calc(-21*(var(--k) - 1)*var(--hu)/2) calc(4*var(--hu) - var(--dh));scale:calc(1/var(--k))}}
@keyframes augezoom{0%,18%{translate:0 34vh;scale:1}100%{translate:none;scale:calc(1/5.25)}}
main[data-hero-intro="auge-zoom"] .hero__name{animation:fuSlow 2.4s var(--ease) 2.2s both}
main[data-hero-intro="auge-zoom"] .hero__dates{animation:fuSlow 2.4s var(--ease) 2.65s both}
main[data-hero-intro="auge-zoom"] .hero__cred{animation:fuSlow 2.4s var(--ease) 2.45s both}
main[data-hero-intro="auge-zoom"] .hero__credo{animation:fuSlow 2.6s var(--ease) 2.9s both}
main[data-hero-intro="auge-zoom"] .hero__sigrow{animation:fuSlow 2.5s var(--ease) 3.05s both}
main[data-hero-intro="auge-zoom"] .hero__portrait{animation:fuSlow 2.8s var(--ease) 3.4s both}
main[data-hero-intro="auge-zoom"] .hero__cue{animation:fuSlow 2.4s var(--ease) 4.4s both}
@keyframes fuSlow{from{opacity:0;transform:translateY(46px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion: reduce){main[data-hero-intro="auge-zoom"] .hero__auge,main[data-hero-intro="auge-zoom"] .hero__name,main[data-hero-intro="auge-zoom"] .hero__dates,main[data-hero-intro="auge-zoom"] .hero__cred,main[data-hero-intro="auge-zoom"] .hero__credo,main[data-hero-intro="auge-zoom"] .hero__sigrow,main[data-hero-intro="auge-zoom"] .hero__portrait,main[data-hero-intro="auge-zoom"] .hero__cue{animation:none}}

/* ===== STATION ===== */
/* big screens: scale the whole composition instead of stretching it —
   zoom ratio follows window width, so type, galleries and spacing keep their proportions */
/* desktop scaling is continuous now — body zoom + --pz are set by fitZoom()
   in the script (anchors: 1280px window → 1.28, 2560px → 1.7, linear between);
   the old fixed 1400/1560/1720/1900/2200 steps left every window under 1400px
   at base size, which is why half-screen windows rendered tiny */
.st{position:relative;max-width:1180px;margin:0 auto;padding:clamp(27px,4.13vw,48px) var(--pad-x) clamp(16px,2.5vw,32px);border-top:1px solid var(--line-1)}
/* the marked station is a STATIC dark band — is-ink-section is written into the
   markup and never toggled, so there is nothing to fade: the ink starts and stops at
   the section's own borders */
.st[data-ink]{isolation:isolate}
/* the band is exactly as wide as <main> (cqw): 100vw scaled with the page zoom reached
   past the window, and Safari left light rows at both edges where the clip cut it */
.st[data-ink]::before{content:"";position:absolute;top:0;bottom:calc(-1 * var(--fold-ext,0px));left:calc(50% - 50cqw);width:100cqw;z-index:-1;background:var(--bg)}
/* while a panel of the dark station slides, the band keeps the station's old length
   (--fold-ext) or its new one ahead of the page, and the station below lays its own
   paper over the part of the band it has not yet reached or already left */
.st.fold-cover{isolation:isolate}
.st.fold-cover::before{content:"";position:absolute;top:-1px;bottom:0;left:calc(50% - 50cqw);width:100cqw;z-index:-1;
  background:linear-gradient(var(--line-1),var(--line-1)) center top/min(1180px,100cqw) 1px no-repeat,var(--bg)} /* from its top rule, redrawn: the band must not show through it */
.st[data-ink].is-ink-section{color:var(--fg-inv);border-color:rgba(255,255,255,.12)}
.st[data-ink].is-ink-section::before{background:var(--bg-ink)}
.st__num{position:absolute;top:clamp(10px,4vw,40px);inset-inline-end:clamp(16px,3vw,48px);max-width:calc(100% - 32px);text-align:end;white-space:nowrap;z-index:0;pointer-events:none;
  font-family:var(--font-insc);font-weight:700;font-size:clamp(150px,40vw,420px);line-height:.8;color:var(--fg);opacity:.026;letter-spacing:.04em}
.st.is-ink-section .st__num{color:var(--color-chestnut-300);opacity:.032}
.st__grid{position:relative;z-index:1}
@media(min-width:720px){.st__grid{display:grid;grid-template-columns:minmax(220px,300px) 1fr;gap:clamp(40px,5vw,80px);align-items:start}}
.st__aside{position:sticky;top:calc(var(--bar-h) + 18px);z-index:6;align-self:start;
  background:color-mix(in oklab,var(--bg) 70%,transparent);backdrop-filter:blur(6px);padding:10px 0;margin-bottom:14px;
  transition:background var(--ink-dur) var(--ease),color var(--ink-text) var(--ease),border-color var(--ink-dur) var(--ease)}
/* the phone bar's offset (js/main.js barSettle) is written on the elements that read it,
   not on the root, and registered as not inherited: a root variable restyled the whole
   page on every frame of the bar's spring */
@property --bar-off{syntax:"<length>";inherits:false;initial-value:0px}
@media(max-width:719px){
  /* touch surfaces: no visible scrollbars anywhere (panning unaffected) */
  *{scrollbar-width:none}
  *::-webkit-scrollbar{display:none}
  /* desktop treatment ported to mobile: the station bar paints NOTHING —
     no background, no blur, no hairline (matches the min-width:720px rules).
     the section canvas shows through it, so the ink transition can never
     render the bar as a separate box */
  .topbar{border-bottom:0}
  /* open reading mode: the close ✕ lives INSIDE the docked station bar (right
     edge, "Stationen"-chip style); the in-flow button row stops floating */
  .st .detail:is(.open,.is-closing) .detail__btn{position:static;top:auto;background:none;-webkit-backdrop-filter:none;backdrop-filter:none}
  .st__aside.x-live{padding-inline-end:56px}
  .st__aside.x-live .aside__x{display:flex}
  /* bare gold ✕ — no chip, 44px tap area (WCAG 2.5.5 / Apple HIG). Aligned to the
     title, not the bar box: its centre sits on the middle of the title's line box
     (bar padding 8px + half of the title's line, = the caps' middle in Cormorant),
     its right edge on the content edge (--pad-x), like the "Näher sehen" sign. */
  .aside__x{position:absolute;inset-inline-end:calc(var(--pad-x) - (44px - var(--sign)) / 2);bottom:calc(8px + var(--st-title) * 1.12 / 2 - 22px);height:44px;width:44px;margin:0;padding:0;
    align-items:center;justify-content:center}
  .aside__x span{transform:rotate(45deg)} /* drawn sign, see .detail__sign */
  /* the rupture station is a static dark band, so the bar is simply light or dark
     depending on what passes under it. Both directions swap on the same quick .5s —
     the old 3s return belonged to the section's slow ink fade, and against a hard
     band edge it left the bar dark long after the band had gone. */
  /* the bar's glass swaps instantly: it hands over to (and takes back from) the docked
     card's glass in one frame, so there is never a moment with no glass under the
     controls. Against the hard band edge an instant light/dark swap is also the honest one. */
  .topbar{transition:transform .4s var(--ease),opacity .4s var(--ease),color .5s var(--ease),border-color .5s var(--ease)}
  .topbar__cur,.topbar__lang{transition:color .5s var(--ease)}
  /* the signature rides the same .5s as the rest of the bar, on background-color now
     — it is declared once in the base rule and needs no per-state restatement */
  /* in flow the title floats bare (no card, no border — ink sweep passes through
     it untouched); .docked is set by the scroll-spy the moment it pins under the
     topbar, and only then the glass card fades in */
  /* the docked card tucks up under the (transparent) bar by --dock-tuck, so the
     signature row sits as close to the station line as the station line sits to
     the title — the three lines read as one block */
  :root{--dock-tuck:10px;--dock-head:8px}
  /* when the menu row retreats, the card stops --dock-head short of the screen top
     (its glass runs on above it), so the station line always keeps its head margin */
  .st__aside{top:max(var(--dock-head),calc(var(--bar-h) - var(--dock-tuck) - var(--bar-off,0px)));margin-inline:calc(-1 * var(--pad-x));padding:2px var(--pad-x) 8px;margin-bottom:18px;
    background:none;backdrop-filter:none;border-bottom:1px solid transparent;
    transition:background .5s var(--ease),border-color .5s var(--ease),color var(--ink-text) var(--ease)}
  /* in contact with the bar: one offset moves both, driven per frame by the
     spring, so neither carries a transition of its own here */
  .topbar.show{translate:0 calc(-1 * var(--bar-off,0px))}
  .st.is-ink-section .st__aside{background:none}
  /* ONE floating bar: while a title is docked, the topbar paints nothing and the
     docked card's glass runs up behind it (::before reaches bar-h above the card).
     The pair already moves as one via --bar-off, so the hidden part of the glass
     simply rides off-screen with the bar — same reveal, no seam between two panes. */
  .st__aside::before{content:"";position:absolute;left:0;right:0;bottom:0;top:calc(var(--dock-tuck) - var(--bar-h));z-index:-1;pointer-events:none;
    background:transparent}
  body.has-dock .topbar{background:transparent;-webkit-backdrop-filter:none;backdrop-filter:none}
  .st__aside.docked{background:none;backdrop-filter:none;border-color:var(--line-1)}
  .st__aside.docked::before{background:color-mix(in oklab,var(--bg) 75%,transparent);-webkit-backdrop-filter:blur(18px) saturate(1.1);backdrop-filter:blur(18px) saturate(1.1)}
  /* rupture station: docked title gets the dark glass while pinned (keeps text
     legible scrolling under it); the .docked class is stripped the moment the
     bar starts leaving, so the card vanishes before the exit light fade runs */
  .st[data-ink] .st__aside.docked{background:none;backdrop-filter:none;border-color:rgba(255,255,255,.12)}
  .st[data-ink] .st__aside.docked::before{background:color-mix(in oklab,var(--bg-ink) 75%,transparent)}
  /* mobile reads the same as desktop: the selector carries the live station numeral,
     falling back to the plain word only on the hero. No auto margin here any more —
     the signature holds the far edge at every width, and re-asserting it on the
     control would push the control back across the bar and undo the order. */
  .st__aside{--st-title:clamp(23px,6.2vw,29px)}
  .st__aside .st__title{font-size:var(--st-title);margin-top:2px;line-height:1.12}}
@media(min-width:720px){.st__aside{background:none;backdrop-filter:none;padding:0}.st.is-ink-section .st__aside{background:none}}
.eyebrow{font-family:var(--font-insc);font-weight:500;font-size:12px;letter-spacing:var(--tr-cap);text-transform:uppercase;color:var(--accent);display:flex;align-items:center;gap:10px}
.eyebrow .yr{color:var(--fg-3);font-family:var(--font-sans);letter-spacing:var(--tr-caps)}
.st__title{font-family:var(--font-disp);font-weight:500;line-height:1.05;letter-spacing:-.01em;font-size:clamp(30px,7vw,54px);margin-top:10px;text-wrap:balance;color:var(--color-ebony)}
.st__main{position:relative;z-index:1;min-width:0}
.prose p{margin:0 0 .525em;text-wrap:pretty;text-align:justify}
.prose p:last-child{margin-bottom:0}
.prose p,.detail__pad p{-webkit-hyphens:auto;hyphens:auto}
.prose i,.prose cite{font-style:italic}
.lead{font-size:clamp(18px,2.4vw,21px)}
/* classical two-line versal, solved rather than eyeballed. Two constraints: the cap's
   top meets the CAP-HEIGHT of line 1, and its baseline sits ON the baseline of line 2.
   With the paragraph at line-height 1.55, that is one line plus EB Garamond's cap
   height (.65em): 2.2em, Cinzel's cap height (.70em) at font-size 3.16em.
   The float below is the fallback for browsers without initial-letter, today only
   Firefox. Gecko sizes a floated letter by its ink: the float's top is the top of the
   glyph and its height the glyph's height. So the top margin is the distance from the
   paragraph's top to line 1's cap height, half the leading plus EB Garamond's ascent
   less its cap height: (1.55 - 1.305) / 2 + 1.007 - .65 = .48em of the text, .152em of
   the 3.16em letter. The float then ends 2.69em down (.48 + 2.21): past line 1 (1.55em)
   and short of line 3 (3.1em), so exactly two lines wrap beside it. The side margin
   .045em is the .14em of the text that initial-letter uses.
   No breakpoint override: every value is em-relative, so it already tracks .lead's
   clamp(18px,2.4vw,21px). The old @media rule shrank the cap a further 22% against a
   paragraph that only drops 14%, which is what made mobile look the more shifted. */
.dropcap::first-letter{font-family:var(--font-insc);font-weight:700;font-size:3.16em;line-height:1;float:left;margin:.152em .045em 0 0;color:var(--accent)}
/* WebKit (every iPad and iPhone browser) does not size a floated ::first-letter by its
   line-height: it takes the glyph's own ascent and descent, so the cap stood half a
   line above the second baseline with a gap under it, and line 3 crept in beneath.
   Where the browser can sink the letter itself (Safari, Chrome, Edge), initial-letter
   does exactly the two-line versal above: cap top on line 1's cap-height, baseline on
   line 2's baseline, line 3 back at full width (measured within 1px in Chrome, Safari 26
   and WebKit 27). The float stays as the fallback. */
@supports (initial-letter:2) or (-webkit-initial-letter:2){
  .dropcap::first-letter{float:none;font-size:inherit;line-height:inherit;-webkit-initial-letter:2;initial-letter:2;margin:0;margin-inline-end:.14em}
}

/* media */
figure{margin:0}
.media{margin:22.5px 0}
.plate{display:block;width:100%;background:transparent;border-radius:3px;position:relative;overflow:visible;isolation:isolate;transition:transform .35s var(--ease),filter .35s var(--ease)}
/* the soft shadow under every image is a box-shadow, not a blurred box. A filter:blur
   layer behind each of the ~80 images had to be re-rendered by WebKit on every frame
   the page moved by layout, which is what the "Näher sehen" roll does: on iPad that
   dropped about half of the frames of every open and close. It is the same blur
   (36px = blur(18px)) of the same box (inset 8% 7% -5%, 8px down), but a box-shadow is
   never painted under its own box, so where the box showed below the image it left a
   pale ledge. The box is lifted behind the image and casts its shadow back down by
   the same --lift; that holds for plates up to 1080px high. */
.plate::before{content:"";position:absolute;inset:8% 7% -5%;z-index:-1;border-radius:6px;--sh:rgba(30,29,30,.18);--lift:64px;box-shadow:0 var(--lift) 36px var(--sh);opacity:.62;transform:translateY(calc(8px - var(--lift)));transition:opacity .35s var(--ease),transform .35s var(--ease),box-shadow 3.0s var(--ease)}
.plate:hover{transform:translateY(-2px);filter:brightness(1.04) saturate(1.03)}
.plate:hover::before{opacity:.76;transform:translateY(calc(10px - var(--lift)))}
.plate img{width:100%;height:auto;display:block;border-radius:3px}
.hero__portrait .plate img{outline:var(--frame-w,0px) solid var(--frame-c,transparent);outline-offset:calc(0px - var(--frame-w,0px))}
.shelf .plate img{outline:none}
.grid2 .plate,.grid3 .plate,.strip .plate{height:clamp(200px,60vw,325px)}
.grid2 .plate img,.grid3 .plate img,.strip .plate img{height:100%;width:auto;max-width:none}
/* Vermächtnis is the one deliberate exception to the gallery height: the station
   carries Pächt's death, it holds a single late portrait, and at gallery scale that
   portrait reads as one more thumbnail. Every term of the clamp is multiplied by 1.5,
   so the exception scales at every width instead of only on desktop. */
#vermaechtnis .grid3 .plate{height:clamp(300px,90vw,488px)}
.media:has(> figure),figure.media{max-width:480px}
.detail__pad .strip.media{max-width:none}
.hero__portrait .plate{aspect-ratio:auto;padding:0;display:block;height:auto}
.hero__portrait figure{display:flex;flex-direction:column;align-items:center}
.hero__portrait .plate img{width:calc(65.3*var(--hu));height:auto;max-height:calc(70svh / var(--pz,1));margin:0 auto}
.lensable{cursor:var(--cursor-auge)}
.lens-hint{display:none}
.caption{font-family:var(--font-sans);font-size:11px;letter-spacing:var(--tr-caps);text-transform:uppercase;color:var(--fg-3);display:flex;align-items:center;gap:8px;margin-top:4px;line-height:1.4}
.caption::after{content:"→";color:var(--gold)}
.grid2,.grid3{display:flex;gap:14px;overflow-x:auto;overflow-y:hidden;overscroll-behavior-x:contain;-webkit-overflow-scrolling:touch;padding-bottom:12px;scrollbar-width:thin;scrollbar-color:var(--color-chestnut-500) transparent}
.grid2::-webkit-scrollbar,.grid3::-webkit-scrollbar{height:6px}
.grid2::-webkit-scrollbar-track,.grid3::-webkit-scrollbar-track{background:transparent}
.grid2::-webkit-scrollbar-thumb,.grid3::-webkit-scrollbar-thumb{background:var(--color-chestnut-500);border-radius:999px}
/* gallery alignment — "safe center" falls back to start when content overflows */
main[data-gallery-align="centered"] :is(.strip,.grid2,.grid3){justify-content:safe center}
.grid2,.grid3,.strip{align-items:center;padding-top:12px}
/* gallery scrollbar variants */
main[data-gallery-scroll="hidden"] :is(.grid2,.grid3,.strip){scrollbar-width:none}
main[data-gallery-scroll="hidden"] :is(.grid2,.grid3,.strip)::-webkit-scrollbar{height:0;display:none}
/* horizontal scroll strip */
.strip{display:grid;grid-auto-flow:column;grid-auto-columns:max-content;gap:14px;overflow-x:auto;overflow-y:hidden;overscroll-behavior-x:contain;scroll-snap-type:x proximity;padding-bottom:12px;-webkit-overflow-scrolling:touch;scrollbar-width:thin;scrollbar-color:var(--color-chestnut-500) transparent}
.strip::-webkit-scrollbar{height:6px}
.strip::-webkit-scrollbar-track{background:transparent}
.strip::-webkit-scrollbar-thumb{background:var(--color-chestnut-500);border-radius:999px}
/* the strip bleeds full-width and restores the gutter as padding, but
   scroll-snap-align:start would park the first plate against the scrollport
   edge and eat that gutter — scroll-padding holds the snap inside it */
@media(max-width:719px){.strip{margin-inline:calc(-1 * var(--pad-x));padding-inline:var(--pad-x);scroll-padding-inline:var(--pad-x)}}
.strip>figure{scroll-snap-align:start}
.strip__cue{font-family:var(--font-sans);font-size:11px;letter-spacing:var(--tr-caps);text-transform:uppercase;color:var(--fg-3);display:flex;align-items:center;gap:8px;margin-top:4px}
.strip__cue::after{content:"→";color:var(--gold)}

/* reveal + parallax */
.reveal{opacity:0;transform:translateY(26px);transition:opacity var(--rv-dur,1.6s) var(--ease) var(--rv-delay,0s),transform var(--rv-dur,1.6s) var(--ease) var(--rv-delay,0s)}
.reveal.in{opacity:1;transform:none}
.reveal[data-d="1"]{--rv-delay:.15s}.reveal[data-d="2"]{--rv-delay:.3s}.reveal[data-d="3"]{--rv-delay:.45s}
/* station choreography: text and gallery enter as one movement, once the station top reaches
   65 % of the viewport. Text rises, each gallery image slides in from the right; all
   start and land together on one soft curve (gentle start, long settle). Images are
   told apart by distance, not by delay: each next image travels 22px further
   (main.js writes --fg-x), so they fan in one by one without lagging behind the text. */
.st{--st-ease:cubic-bezier(.45,0,.15,1)}
.st .reveal{--rv-delay:0s;transform:translateY(44px);transition:opacity var(--rv-dur,2s) var(--st-ease),transform var(--rv-dur,2s) var(--st-ease)}
.st .reveal.in{transform:none}
/* the exile map keeps its own fades (sticky open state) next to the entrance */
.st .exilmap.reveal{transition:opacity var(--rv-dur,2s) var(--st-ease),transform var(--rv-dur,2s) var(--st-ease),background .9s var(--ease),border-color .9s var(--ease),padding .9s var(--ease)}
/* the station title (sticky aside) has no entrance: it is there from the start, so a
   station is never empty while its text and gallery come in */
.st .st__aside.reveal{opacity:1;transform:none}
.st .media.reveal{opacity:1;transform:none}
.st .media.reveal :is(figure,.caption,.strip__cue){opacity:0;transition:opacity var(--rv-dur,2s) var(--st-ease),transform var(--rv-dur,2s) var(--st-ease)}
.st .media.reveal figure{transform:translateX(var(--fg-x,56px))}
.st .media.reveal.in :is(figure,.caption,.strip__cue){opacity:1;transform:none}
/* scroll snap stays off until the images have landed: a snapping strip otherwise
   re-snaps to the moving images and drags the strip back at the end of the entrance */
.st .media.reveal:not(.settled) .strip{scroll-snap-type:none}

/* detail expand */
.detail{margin-top:30px;border-top:1px solid var(--gold)}
.aside__x{display:none} /* mobile-only close chip in the docked bar; shown via .has-open-detail */
.detail__btn{display:flex;align-items:center;justify-content:space-between;width:100%;gap:14px;padding:12px 0;margin:12px 0;font-family:var(--font-sans);font-size:13px;letter-spacing:var(--tr-caps);text-transform:uppercase;color:var(--fg-2);border:none;transition:color .15s}
.detail__btn:hover{color:var(--accent)}
/* no gray touch highlight over the full-width row on iPhone and iPad: the row answers
   the tap itself (the sign turns, the panel opens) */
:is(.detail__btn,.aside__x){-webkit-tap-highlight-color:transparent}
/* the + / × sign is drawn, not typeset: 1em of the control size (--ctl, 13px, the
   label's size), centred on the label; the label's 1.5px stem weight. The same icon
   closes the panel from the docked station bar on phones (.aside__x). Rotates to ×. */
:is(.detail__btn,.aside__x){--sign:var(--ctl);--sign-w:var(--ctl-stroke)}
.detail__sign{transition:transform .4s var(--ease)}
:is(.detail__sign,.aside__x span){position:relative;display:block;flex:none;width:var(--sign);height:var(--sign);font-size:0;color:var(--gold)}
:is(.detail__sign,.aside__x span)::before,:is(.detail__sign,.aside__x span)::after{content:"";position:absolute;left:0;top:50%;width:100%;height:var(--sign-w);margin-top:calc(var(--sign-w) / -2);background:currentColor}
:is(.detail__sign,.aside__x span)::after{transform:rotate(90deg)}
.detail.open .detail__sign{transform:rotate(45deg)}
.detail__wrap{display:grid;grid-template-rows:0fr;grid-template-columns:minmax(0,100%);transition:grid-template-rows .6s var(--ease)}
.detail__in{min-width:0;max-width:100%}
.detail.open .detail__wrap{grid-template-rows:1fr}
.detail--static .detail__wrap{display:block}
.detail__in{overflow:hidden}
.detail.open .detail__in{overflow:visible} /* lets the Schließen bar stick to the viewport; open/close animation clips via the wrap */
.detail--long.open .detail__in{overflow:hidden} /* capped panel keeps its own frame; its pad is the scrollport */
.detail__pad{padding:6px 0 18px}
/* EB Garamond, the same face as the h4 subheads directly beneath it. On the display
   face the panel's larger heading was the only Cormorant in a column of Garamond —
   one serif reading against another at the size that carries the most weight. */
.detail__pad h3,.st__text h3{font-family:var(--font-serif);font-weight:600;font-size:20px;line-height:1.25;margin:8px 0 5px}
.detail__pad h4,.st__text h4{font-family:var(--font-serif);font-weight:600;font-size:18px;margin:12px 0 4px;color:var(--fg-2)}
/* A work title in a panel heading uses the text italic. Italic is loaded only at
   400 and 500, so an inherited 600 is a false bold built from the 500 italic. */
.detail__pad :is(h3,h4) i,.st__text :is(h3,h4) i{font-weight:inherit;font-style:italic;font-synthesis:none}
/* long expanders: capped panel, scrolls internally instead of stretching the page.
   The cap lives on the inner pad — .detail__in must stay a plain overflow:hidden box
   for the 0fr→1fr grid animation to measure content. */
.detail--long .detail__pad{max-height:clamp(420px,64vh,680px);overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:var(--color-chestnut-500) transparent;padding:14px clamp(16px,3vw,28px) 24px}
.detail--long.open .detail__wrap{grid-template-rows:none;display:block}
.detail--long.open .detail__in{border:1px solid var(--line-1);background:color-mix(in oklab,var(--bg) 96%,var(--color-vellum))}
/* in the expanded state the whole button row (label + ×) floats below the topbar,
   so the reader can exit at any point */
.detail:is(.open,.is-closing) .detail__btn{position:sticky;top:var(--bar-h);z-index:7;background:color-mix(in oklab,var(--color-vellum) 90%,transparent);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}
.detail.is-closing{overflow-anchor:none}
.detail--long blockquote{font-size:17px;line-height:1.42;margin:16px 0;padding-left:1em}
/* a letter quoted whole (Station IV): set as a document, not as a pull-quote */
.detail__pad blockquote.letter{font-family:var(--font-serif);font-style:normal;font-weight:400;font-size:16.5px;line-height:1.62;color:var(--fg-2);border-left:1px solid var(--gold);padding:2px 0 2px 1.1em;margin:14px 0 24px}
.detail__pad blockquote.letter p{margin:0 0 .425em}
.detail__pad blockquote.letter p:last-child{margin-bottom:0}
.detail__pad blockquote.letter .letter__open{font-style:italic;text-align:start}
.st.is-ink-section .detail__pad blockquote.letter{color:var(--color-chestnut-100)}
/* the letter is long: it reads in its own scroll window, like the Nachhall panel and
   the bibliography. Framed by a hairline, the gold rule stays on its opening edge.
   Native scrolling, chained to the page at both ends: the reader is never captured. */
.detail__pad blockquote.letter{max-height:clamp(320px,calc(52vh / var(--pz,1)),560px);overflow-y:auto;overscroll-behavior:auto;
  scrollbar-width:thin;scrollbar-color:var(--color-chestnut-500) transparent;
  border:1px solid var(--line-1);border-inline-start:1px solid var(--gold);
  padding:14px clamp(16px,3vw,24px) 18px 1.1em;background:color-mix(in oklab,var(--bg) 96%,var(--color-vellum))}
.detail__pad blockquote.letter:focus-visible{outline:1px solid var(--gold);outline-offset:2px}
.st.is-ink-section .detail__pad blockquote.letter{border-color:rgba(255,255,255,.12);border-inline-start-color:var(--gold);background:rgba(255,255,255,.02)}
/* a gallery at the end of an open panel (Station V: the Wormald letter) */
.detail__media{margin:2px 0 24px}
/* an image between the panel's paragraphs (Station I: the Pächt brothers). The plate
   takes the gallery height from .grid2; the caption keeps its own rhythm, not the
   paragraph margins of .prose */
:is(.detail__pad,.st__text) .detail__media{margin:4px 0 12px}
:is(.detail__pad,.st__text) .detail__media .caption{margin:4px 0 0;text-align:start}
.st.is-ink-section .detail{border-color:var(--color-chestnut-500)}
/* the label carries the same gold as the "+" at the other end of the row, so the
   control reads as one object rather than two colours. 6.1:1 on the ink band — past
   AA for the 13px label, and the hover lifts to the lighter chestnut at 8.2:1, so the
   state change brightens rather than weakens it. */
.st.is-ink-section .detail__btn{color:var(--gold);border-color:rgba(255,255,255,.28)}
.st.is-ink-section .detail__btn:hover{color:var(--color-chestnut-500)}
.st.is-ink-section .detail:is(.open,.is-closing) .detail__btn{background:color-mix(in oklab,var(--bg-ink) 88%,transparent)}

/* lists */
.namegrid{list-style:none;display:grid;gap:12px;margin:8px 0;grid-template-columns:1fr}
@media(min-width:620px){.namegrid{grid-template-columns:1fr 1fr;gap:14px 30px}}
.namegrid li{font-family:var(--font-disp);font-size:21px;line-height:1.15;border-bottom:1px solid var(--line-1);padding-bottom:10px}
.namegrid span{display:block;font-family:var(--font-sans);font-size:12px;color:var(--fg-3);margin-top:3px}
.honors{list-style:none;display:grid;gap:11px;margin:8px 0}
.honors li{display:grid;grid-template-columns:66px 1fr;gap:14px;align-items:baseline;border-bottom:1px solid var(--line-1);padding-bottom:10px;font-size:16px}
.honors b{font-family:var(--font-sans);font-weight:600;font-size:13px;color:var(--accent)}
blockquote{font-family:var(--font-disp);font-style:italic;font-weight:400;font-size:clamp(20px,3vw,26px);line-height:1.22;color:var(--fg-2);border-left:2px solid var(--gold);padding-left:1.1em;margin:20px 0}
blockquote cite{display:block;font-style:normal;font-family:var(--font-sans);font-size:12px;letter-spacing:var(--tr-caps);text-transform:uppercase;color:var(--fg-3);margin-top:12px}
.pullquote{font-size:clamp(18px,2.4vw,21px);line-height:1.5;border-left:none;border-top:1px solid var(--gold);border-bottom:1px solid var(--gold);padding:22px 0;margin:6px 0 20px}
.st.is-ink-section blockquote{color:var(--color-chestnut-100)}

.shelf{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin:8px 0 30px}
/* every cover fills the same tile. The tile takes the format most of the scans share
   (1076×1462), so those show whole; the few that differ lose a sliver at the edges.
   A later object-fit:contain used to override the fill, so a scan with another format
   floated smaller in its tile. 16 covers keep four full rows of four. */
.shelf .plate{aspect-ratio:1076/1462;display:block;padding:0}
.shelf .plate img{width:100%;height:100%;object-fit:cover;object-position:center}
/* the Japanese edition's title runs up to its top edge, so it gives up its sliver at the
   bottom (the floor of the picture) instead */
.shelf .plate img[src*="werk-19"]{object-position:top}
@media(max-width:560px){.shelf{grid-template-columns:repeat(2,1fr)}}

/* dark station inner accents */
.st.is-ink-section .caption,.st.is-ink-section .st__aside .eyebrow .yr,.st.is-ink-section .strip__cue{color:var(--color-prussian-300)}
.st.is-ink-section .plate{background:transparent}
.st.is-ink-section .plate::before{--sh:rgba(0,0,0,.46);opacity:.72}
#der-bruch :is(.st__num,.st__aside,.eyebrow,.eyebrow .yr,.st__title,.lead,.caption,.detail,.detail__btn,.detail__pad h3,.detail__pad h4,blockquote,blockquote cite){
  transition:color var(--ink-text) var(--ease),border-color var(--ink-dur) var(--ease),background var(--ink-dur) var(--ease),opacity var(--rv-dur,2s) var(--st-ease) var(--rv-delay,0s),transform var(--rv-dur,2s) var(--st-ease) var(--rv-delay,0s)}
#der-bruch .dropcap::first-letter{transition:color var(--ink-text) var(--ease)}
/* mobile: the rupture title's glass must snap in/out quickly (dock/undock),
   independent of the section's slow 3s ink fade */
@media(max-width:719px){
  #der-bruch .st__aside{transition:background .35s var(--ease),border-color .35s var(--ease),opacity .35s var(--ease),color var(--ink-text) var(--ease),transform var(--rv-dur,2s) var(--st-ease) var(--rv-delay,0s)}
  /* final position reached: the whole title (text included) fades out before
     the exit light transition — nothing left to overlap the section content */
  #der-bruch .st__aside.leaving{opacity:0}
  /* the year lives inside the heading, so only the compact offset is kept */
  #der-bruch .bruch-title-row{margin-top:2px}
}
.bruch-title-row{display:flex;flex-direction:column;align-items:flex-start;gap:4px;margin-top:10px}
/* the row is align-items:flex-start, which cross-shrinks a lone child — stretch
   keeps the title on the aside's full measure, like every other station */
.bruch-title-row .st__title{margin-top:0;text-align:start;align-self:stretch}
#der-bruch.is-ink-section .st__title{color:var(--color-chestnut-500)}
/* subheads on the ink ground take the title colour (light bronze) */
#der-bruch.is-ink-section :is(.detail__pad,.st__text) :is(h3,h4){color:var(--color-chestnut-500)}

/* exile map */
.st.ac-silent .detail__wrap,.st.ac-silent .detail__in,.st.ac-silent .exilmap,.st.ac-silent .st__aside{transition:none}
.exilmap{margin:4px 0 4px;border-top:1px solid transparent;background:transparent;transition:background .9s var(--ease),border-color .9s var(--ease),padding .9s var(--ease)}
#exil .detail__wrap{transition:none}
#exil{overflow-anchor:none}
/* with "Näher sehen" open, the map (in flow after the panel) rides the viewport bottom
   until its natural position at the station's end arrives — column-width, not full screen */
#exil .detail__btn{padding-bottom:8px}
#exil:has(.detail.open) .exilmap{position:sticky;bottom:0;z-index:3;margin-bottom:0;padding:6px 0 10px;border-top-color:var(--line-1)}
/* the floating card has no hard edge: its paper and blur sit on a layer that reaches
   past the card and fades out at the top and both sides, so it melts into the page */
#exil .exilmap{position:relative;isolation:isolate}
/* Station V does not clip its own sides: main already clips the page at the window's edge,
   which is all the feather needs. A side clip here made Safari on Retina screens draw the
   whole station 1–2px off and back in every frame in which the station changed height,
   i.e. through every opening of its panel (reproduced in Safari's engine at 2x, 25 Oct) */
#exil .exilmap::before{content:"";position:absolute;inset:0 -72px 0;z-index:-1;pointer-events:none;opacity:0;transition:opacity .9s var(--ease);
  background:var(--bg);
  /* eased fades only at the sides, outside the column. The paper is opaque over the
     whole column, so no text shows through it. The hairline on top belongs to the
     card itself (below), so it spans exactly the text column */
  -webkit-mask-image:linear-gradient(to right,rgba(0,0,0,0) 0,rgba(0,0,0,.05) 9px,rgba(0,0,0,.16) 18px,rgba(0,0,0,.34) 27px,rgba(0,0,0,.56) 37px,rgba(0,0,0,.76) 48px,rgba(0,0,0,.91) 58px,#000 72px,#000 calc(100% - 72px),rgba(0,0,0,.91) calc(100% - 58px),rgba(0,0,0,.76) calc(100% - 48px),rgba(0,0,0,.56) calc(100% - 37px),rgba(0,0,0,.34) calc(100% - 27px),rgba(0,0,0,.16) calc(100% - 18px),rgba(0,0,0,.05) calc(100% - 9px),rgba(0,0,0,0) 100%);mask-image:linear-gradient(to right,rgba(0,0,0,0) 0,rgba(0,0,0,.05) 9px,rgba(0,0,0,.16) 18px,rgba(0,0,0,.34) 27px,rgba(0,0,0,.56) 37px,rgba(0,0,0,.76) 48px,rgba(0,0,0,.91) 58px,#000 72px,#000 calc(100% - 72px),rgba(0,0,0,.91) calc(100% - 58px),rgba(0,0,0,.76) calc(100% - 48px),rgba(0,0,0,.56) calc(100% - 37px),rgba(0,0,0,.34) calc(100% - 27px),rgba(0,0,0,.16) calc(100% - 18px),rgba(0,0,0,.05) calc(100% - 9px),rgba(0,0,0,0) 100%)}
#exil:has(.detail.open) .exilmap::before{opacity:1}
.exilmap svg{width:106.25%;height:auto;overflow:visible;display:block;margin:0 -3.125%}
@media(max-width:719px){
  /* mobile: same desktop map, scaled to fit — full-bleed across the viewport
     (gutters reclaimed ≈ +15% scale); type and dots enlarged inside the SVG */
  .exilmap{margin-inline:calc(-1 * var(--pad-x))}
  .exilmap svg{width:100%;max-width:none;margin:0;padding:6px 0}
  .mlabel{font-size:22px}
  .myear{font-size:16px}
  .city{r:7}.city.lit{r:8.5}
  .route--fg{stroke-width:5}
}
.route{fill:none;stroke-linecap:round}
.route--bg{stroke:var(--line-2);stroke-width:1.5;stroke-dasharray:3 6}
.route--fg{stroke:var(--color-rust);stroke-width:3.2}
.city{fill:var(--bg);stroke:var(--fg-2);stroke-width:1.8;transition:fill .3s,stroke .3s,r .3s}
.city.lit{fill:var(--accent);stroke:var(--accent);r:5.5}
.mlabel{font-family:var(--font-insc);font-size:clamp(16px,calc(33.275px - 1.4056vw),19.5px);letter-spacing:.1em;text-transform:uppercase;fill:var(--fg-2);transition:fill .3s}
.mlabel.lit{fill:var(--fg)}
.myear{font-family:var(--font-sans);font-size:clamp(13.5px,calc(26.04px - 1.004vw),16px);letter-spacing:.04em;fill:var(--fg-2)}
.st.is-ink-section .city{fill:var(--bg-ink);stroke:var(--color-prussian-300)}
.st.is-ink-section .city.lit{fill:var(--color-chestnut-500);stroke:var(--color-chestnut-500)}
.st.is-ink-section .mlabel{fill:var(--color-prussian-300)}
.st.is-ink-section .mlabel.lit{fill:var(--color-chestnut-300)}
.st.is-ink-section .myear{fill:var(--color-prussian-300)}
.st.is-ink-section .route--bg{stroke:rgba(255,255,255,.20)}
.st.is-ink-section .route--fg{stroke:var(--color-chestnut-500)}

/* station head, desktop: title 20% down (54 → 43), eyebrow up (12 → 14), so the
   title reads at ~3× the eyebrow instead of 4.5×. The phone keeps its own head sizes. */
@media(min-width:720px){
  .st__title{font-size:43px}
  .st__aside .eyebrow{font-size:14px}
}
/* compact desktop, 720–979: the two-column desktop composition, fluid. Each size
   runs on a straight line from its compact value at 720 to its exact desktop value
   at 980, so the design meets itself at 980 with no step. The steps of the type
   scale keep their order and near their ratios: running text keeps a reading floor
   (16px), the title and its column carry most of the reduction, the uppercase
   labels (eyebrow, captions, buttons) hold their desktop size. */
@media(min-width:720px) and (max-width:979px){
  .st__grid{grid-template-columns:clamp(220px,calc(-1.538px + 30.7692vw),300px) minmax(0,1fr)}
  .st__main{font-size:clamp(16px,calc(13.231px + 0.3846vw),17px)}
  .st__title{font-size:clamp(34px,calc(9.077px + 3.4615vw),43px)}
  .lead,.pullquote,.namegrid li{font-size:clamp(19.75px,calc(16.288px + 0.4808vw),21px)}
  blockquote{font-size:clamp(24.5px,calc(20.346px + 0.5769vw),26px)}
  .detail__pad h3,.st__text h3{font-size:clamp(18.8px,calc(15.477px + 0.4615vw),20px)}
  .detail__pad h4,.st__text h4{font-size:clamp(17px,calc(14.231px + 0.3846vw),18px)}
  .detail--long blockquote{font-size:clamp(16px,calc(13.231px + 0.3846vw),17px)}
  .detail__pad blockquote.letter{font-size:clamp(15.5px,calc(12.731px + 0.3846vw),16.5px)}
  .honors li{font-size:clamp(15px,calc(12.231px + 0.3846vw),16px)}
  .grid2 .plate,.grid3 .plate,.strip .plate{height:clamp(229px,calc(-36.846px + 36.9231vw),325px)}
  #vermaechtnis .grid3 .plate{height:clamp(344px,calc(-54.769px + 55.3846vw),488px)}
  /* the Exil map sits in the narrower column: its type grows as the column shrinks,
     so the labels keep the size they read at on the desktop */
  .mlabel{font-size:clamp(19.5px,calc(28.923px - 0.9615vw),22px)}
  .myear{font-size:16px}
}
/* a station whose full text is always open: the panel's typography, no panel.
   It sits where the "Näher sehen" row sat, at the same distance from the gallery */
.st__text{margin-top:30px}
/* vermächtnis — contact at the station end */
.nachlass-contact{font-family:var(--font-sans);font-size:12px;letter-spacing:var(--tr-caps);text-transform:uppercase;color:var(--fg-3);margin-top:22px}
.nachlass-contact a{color:var(--accent);text-decoration:none;border-bottom:1px solid var(--gold)}
.nachlass-contact a:hover{color:var(--color-chestnut-500)}
/* bibliography */
/* the box is a plain native scroller, scoped by the cursor: a wheel or drag that
   STARTS over the entries scrolls the entries; anywhere else — the margins, the head,
   the station around it — the page scrolls and can carry the reader past the panel.
   At the list's ends the browser chains the gesture to the page. No script drives or
   blocks this scroller: the reader is never captured. */
.detail--biblio .detail__in{max-height:clamp(360px,calc(58vh / var(--pz,1)),640px);overflow-y:auto;overscroll-behavior:auto;scrollbar-width:none;border:1px solid var(--line-1);border-top:0;background:color-mix(in oklab,var(--bg) 94%,var(--color-vellum))}
.detail--biblio .detail__in::-webkit-scrollbar{display:none}
/* minimalist read indicator: a hairline of gold on the tools block's lower edge */
.biblio__progress{position:absolute;inset-inline-start:0;bottom:-1px;height:2px;width:0;background:var(--gold);transition:width .1s linear;z-index:1}
.detail--biblio .detail__pad{padding:16px clamp(16px,3vw,28px) 24px}
/* the title rides with the search and the chips, outside the scrollport; margins
   compacted since the block carries its own padding. The face and weight are restated
   because the heading does not sit inside .detail__pad. */
.detail--biblio .biblio__tools h3{font-family:var(--font-serif);font-weight:600;font-size:22px;line-height:1.2;margin:0 0 11px;padding-block:3px}
main[data-biblio-scroll="full-height"] .detail--biblio .detail__in{max-height:none;overflow-y:visible}
/* click-to-expand affordance: same auge cursor folded or expanded;
   controls inside keep their own cursors */
.detail--biblio .detail__in{cursor:var(--cursor-auge)}
.detail--biblio .detail__in :is(a,button){cursor:pointer}
.detail--biblio .detail__in input{cursor:text}
/* head of the card, not a passenger in the scrollport: it carries the box's top and
   side borders so the two blocks read as one framed panel.
   It is sticky to the PAGE, not to the list — pinned under the chrome for as long as
   any entry is still on screen, and released by its own container the moment the list's
   foot passes under it, so it leaves with the panel and the next station follows. */
.biblio__tools{position:sticky;top:var(--bar-h);z-index:3;margin:0;padding:12px clamp(16px,3vw,28px) 14px;background:color-mix(in oklab,var(--bg) 96%,var(--color-vellum));border:1px solid var(--line-1);box-shadow:inset 0 1px 0 rgba(255,255,255,.55)}
@media (max-width:719px){
  /* the docked station title sits between the topbar and the panel here, and its height
     follows the language, so the clearance is measured rather than guessed */
  .biblio__tools{top:calc(max(var(--dock-head,0px),calc(var(--bar-h) - var(--dock-tuck,0px) - var(--bar-off,0px))) + var(--biblio-dock,44px))}
}
/* count on the left, exit mark on the right — the same split the drawer header
   uses, kept inside the sticky bar so the way out follows the reader down */
.biblio__foot{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:-7px}
.biblio__foot .biblio__count{margin-bottom:0}
/* the same rotated serif "+" as the section and drawer exits, darkened out of
   the gold: the mark's own --gold reads 2.7:1 on this vellum panel */
.biblio__skip{position:relative;flex:none;display:flex;align-items:center;justify-content:center;width:32px;height:32px;margin-inline-end:-6px;text-decoration:none}
.biblio__skip::before{content:"";position:absolute;inset:-6px} /* 44px tap area, no visible box */
.biblio__skip span{font-family:var(--font-disp);font-size:26px;line-height:1;color:color-mix(in oklab,var(--gold) 70%,var(--color-india-ink));transform:rotate(45deg);transition:color .15s}
.biblio__skip:hover span{color:color-mix(in oklab,var(--gold) 55%,var(--color-india-ink))}
.biblio__skip:focus-visible{outline:2px solid var(--gold);outline-offset:2px;border-radius:4px}
.biblio__search{width:100%;font-family:var(--font-serif);font-size:16px;padding:12px 14px;border:1px solid var(--line-2);border-radius:2px;background:var(--bg-field);color:var(--fg);margin-bottom:12px}
.biblio__search:focus{outline:2px solid var(--gold);outline-offset:2px;border-color:var(--gold)}
.chips{display:flex;flex-wrap:nowrap;gap:7px;margin-bottom:12px;overflow-x:auto;overscroll-behavior-x:contain;-webkit-overflow-scrolling:touch;scrollbar-width:none;padding-bottom:4px}
.chips::-webkit-scrollbar{display:none}
/* 2px, the same corner as .biblio__search directly above — the filter row and the
   field it filters read as one control surface */
.chip{flex:none;white-space:nowrap;font-family:var(--font-sans);font-size:12px;letter-spacing:var(--tr-caps);text-transform:uppercase;border:1px solid var(--line-2);border-radius:2px;padding:6px 13px;color:var(--fg-2);transition:.15s}
.chip:hover{border-color:var(--accent);color:var(--accent)}
.chip.active{background:var(--color-ebony);border-color:var(--color-ebony);color:var(--color-vellum)}
/* the filled chip hovers on its own ground — inheriting the outline chip's
   rust text would put 1.5:1 ink on the ebony fill */
.chip.active:hover{background:color-mix(in oklab,var(--color-ebony) 86%,var(--color-vellum));border-color:color-mix(in oklab,var(--color-ebony) 86%,var(--color-vellum));color:var(--color-vellum)}
.biblio__count{font-family:var(--font-sans);font-size:12px;letter-spacing:.04em;color:var(--fg-3);margin-bottom:14px}
.biblio__list{list-style:none;display:grid;gap:12px;margin-top:-24px}
/* the decade HEADING carries the brand's ebony green: as rust it read 5.2:1 on the
   vellum panel, too weak for a 12px inscriptional cap. Ebony reads 7.9:1. The
   individual entry years below keep the gold — they are data in a column, not the
   title of the group. */
/* EB Garamond, not the inscriptional face: Cinzel and Trajan carry no lowercase at
   all, so the ordinal suffix came out as a small capital there. No text-transform
   either — the caps are applied in decadeCaps() so "er" can stay down while the word
   beside it goes up. 13px because Garamond's caps sit shorter than Cinzel's. */
.biblio__decade{font-family:var(--font-sans);font-size:13px;font-weight:400;letter-spacing:var(--tr-cap);color:var(--color-ebony);border-bottom:1px solid var(--gold);padding:14px 0 7px;margin-top:8px}
.biblio__entry{display:grid;grid-template-columns:50px 1fr;gap:12px;align-items:baseline;font-size:15px;line-height:1.45;border-bottom:1px solid var(--line-1);padding-bottom:11px}
.biblio__entry b{font-family:var(--font-sans);font-weight:600;font-size:13px;color:var(--gold)}
.biblio__entry i{font-style:italic}
.biblio__entry small{display:block;font-size:12.5px;color:var(--fg-3);margin-top:5px;font-style:italic}
.biblio__empty{color:var(--fg-3);font-style:italic;padding:14px 0}

/* closing */
/* the credo group is scaled as one unit (×0.75: sizes and the gaps between them), then
   joined to the footer by an even gap around the gold rule (19px above, 19px below) */
.closing{text-align:center;max-width:760px;margin:0 auto;padding:clamp(60px,10vw,120px) 22px 19px}
.closing__auge{width:clamp(76.5px,16.6vw,102px);height:auto;margin:26px auto 14px;animation:blink 8s ease-in-out infinite}
.closing__credo{font-family:var(--font-disp);font-style:italic;font-size:clamp(18px,4.5vw,25.5px);color:var(--fg-2);margin-bottom:10.5px}
.closing__fw{font-family:var(--font-insc);font-size:10.5px;letter-spacing:var(--tr-cap);text-transform:uppercase;color:var(--fg-3)}
/* phones: name and dates on one line, the subtitle below — never a break inside the dates */
@media(max-width:719px){.closing__fw .fw-dot{display:none}.closing__fw .fw-sub{display:block;margin-top:2px;text-wrap:balance}}
.sitefoot__legal{letter-spacing:var(--tr-caps);text-transform:uppercase;margin-bottom:4px;text-wrap:balance}
.sitefoot__legal a{color:var(--fg-2);text-decoration:none}
.sitefoot__legal a:hover{color:var(--accent);text-decoration:underline;text-underline-offset:4px}
.sitefoot{padding:0 var(--pad-x) 34px;display:flex;flex-direction:column;gap:5px;align-items:center;text-align:center;font-family:var(--font-sans);font-size:12px;letter-spacing:.02em;color:var(--fg-3)}
/* one short gold rule ties the footer to the closing credo above it */
.sitefoot::before{content:"";width:44px;height:1px;background:var(--gold);margin-bottom:14px}
.sitefoot__official{color:var(--fg-2);margin-bottom:2px}
.sitefoot__meta{font-size:11px;max-width:760px;text-wrap:balance}
.sitefoot__meta--short{display:none}
/* designer credit: the year, then the label set like the rights line above (quiet, not
   caps) and the AGWA logo in its own colours, the two as one link, so the page ends on it.
   The wordmark's letters are as tall as the label's caps (Archivo Narrow cap height .686em),
   so the logo, 120 units tall around a 94-unit wordmark, is .686em × 120/94 */
.sitefoot__credit{display:flex;align-items:baseline;font-size:11px;line-height:1.55}
.sitefoot__by{position:relative;display:inline-flex;align-items:center;gap:.5em;color:var(--fg-3);text-decoration:none}
/* the tap area grows to 44px into the gap and the footer padding below, so the line keeps
   the footer's row spacing and never covers the rights line */
.sitefoot__by::after{content:"";position:absolute;inset:-4px -8px -23px}
.sitefoot__agwa{display:block;height:calc(.686em * 120 / 94);width:auto;aspect-ratio:543/120;overflow:visible} /* visible: at 9.6px the box edge lands mid-pixel and clipped the loop's lowest row */
.sitefoot__by:hover{color:var(--accent)}
/* two wrappers that only lay out where they are needed; elsewhere their rows are footer
   rows like the others */
.sitefoot__links,.sitefoot__hinge{display:contents}
/* desktop: the rights line and the credit hinge on their "|". Each line's first part ends
   at one column edge ("… |" and a no-break space), the rest starts there; the rights line
   is the wider in both parts, so it stays centred and the credit's "|" stands under its "|" */
@media(min-width:720px){
  .sitefoot__hinge{display:grid;grid-template-columns:auto auto;justify-content:center;align-items:baseline;row-gap:5px}
  .sitefoot__hinge>*{display:contents}
  .sitefoot__hinge>*>:first-child{justify-self:end}
  .sitefoot__hinge>*>:last-child{justify-self:start}
}
/* phones: each footer row holds one line. The rights line, in its short form, keeps the
   credit's 11px (it fits from 320px). The links line, its tracking tighter and its size
   scaling with the width, reaches at least one em past the rights line on each side, never
   past the margins: its "|" spread apart (space-between), with one word space of Archivo
   Narrow (.228em) plus the line's tracking as the least gap, the spacing they have inline */
@media(max-width:719px){
  .sitefoot__links{display:grid;grid-template-columns:minmax(0,max-content);row-gap:5px}
  .sitefoot__legal{display:flex;justify-content:space-between;column-gap:.258em;white-space:nowrap;font-size:min(12px,2.9vw);letter-spacing:.03em}
  .sitefoot__meta--long{display:none}
  .sitefoot__meta--short{display:flex;justify-content:center;white-space:nowrap;padding-inline:1em}
}


/* menu */
.menu{--mk:1;--mvh:min(1vh,calc(8.44px * var(--mk)));position:fixed;inset:0;z-index:80;display:flex;justify-content:flex-end;background:color-mix(in oklab,var(--color-india-ink) 44%,transparent);-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);opacity:0;visibility:hidden;transition:opacity .32s var(--ease),visibility .32s}
.menu.open{opacity:1;visibility:visible}
.menu__in{width:min(78vw,calc(360px * var(--mk)));margin:16px 16px 16px auto;height:min(calc(100dvh / var(--pz,1) - 32px),calc(820px * var(--mk)));display:flex;flex-direction:column;overflow-y:auto;-webkit-overflow-scrolling:touch;background:var(--color-ebony);color:var(--fg-inv);border:1px solid rgba(255,255,255,.1);border-radius:8px;box-shadow:0 32px 84px -26px rgba(30,29,30,.62);padding:calc(env(safe-area-inset-top) + clamp(calc(12px * var(--mk)),calc(1.8 * var(--mvh)),calc(18px * var(--mk)))) calc(clamp(20.7px,2.76vw,29.9px) * var(--mk)) clamp(calc(14px * var(--mk)),calc(2 * var(--mvh)),calc(24px * var(--mk)));transform:translateX(20px);transition:transform .32s var(--ease)}
.menu.open .menu__in{transform:none}
/* the card keeps the phone's proportions on every screen: the phone's width (at most
   360px; it was up to 600px on larger screens) and at most the height it has on the
   reference phone (390×844: 844px − 24px = 820px). On tall screens (an upright iPad,
   a big monitor) it used to run the full screen height and spread its rows far apart.
   Its spacing, written in vh, stops at the reference phone's vh (--mvh ≤ 8.44px) for
   the same reason, so a tall screen shows the phone's spacing exactly; a shorter
   screen still fits the card to its height, as before. Phones keep the plain screen
   height.
   Desktop (a mouse or trackpad, wider than a phone) shows the same card one step up the
   type scale: --mk = 6/5 multiplies every length in it (type, width, height, spacing,
   the ×'s stroke), so its proportions stay the phone's. A laptop is read from about
   twice a phone's distance; at the phone's sizes its text looked a third smaller.
   Phones and iPads (touch) keep the phone sizes, --mk = 1 */
@media(min-width:641px) and (hover:hover) and (pointer:fine){.menu{--mk:calc(6 / 5)}}
@media(max-width:640px){.menu{--mvh:1vh}.menu__in{margin:12px 12px 12px auto;height:calc(100dvh - 24px)}}
.menu__hd{--t:calc(var(--fs--1) * var(--mk));display:flex;align-items:center;justify-content:space-between;margin-bottom:clamp(calc(8px * var(--mk)),calc(1.5 * var(--mvh)),calc(14px * var(--mk)))}
.menu__t{font-family:var(--font-insc);font-size:var(--t);letter-spacing:var(--tr-cap);text-transform:uppercase;color:var(--color-chestnut-300)}
/* bare ✕ in the card's white (vellum, --fg-inv, the colour of the station names): on
   the ebony card it reads clearly (8:1), the gold it had before was too faint. Hover
   takes the title's gold. As tall as the title's capitals: Cinzel's cap height is .70em, 9.9px at the title's 14.2px (--t). It is
   drawn like the "Näher sehen" sign: two bars at the 1.5px control stroke crossed
   at 45°. A bar of length L and width w spans (L + w)/√2, so L = cap × √2 − w.
   The title's caps sit .045em above the middle of its line box (Cinzel: ascent .98,
   descent .37, caps .70), and the × moves up by the same amount to share their middle */
.menu__x{--ctl-stroke:calc(1.5px * var(--mk));position:relative;display:flex;align-items:center;justify-content:center;height:calc(32px * var(--mk));width:calc(32px * var(--mk));margin-inline-end:calc(-6px * var(--mk));padding:0;border:0;background:none}
.menu__x::before{content:"";position:absolute;inset:-6px} /* 44px tap area, no visible box */
.menu__x span{--bar:calc(var(--t) * .7 * 1.4142 - var(--ctl-stroke));position:relative;display:block;width:var(--bar);height:var(--bar);font-size:0;color:var(--fg-inv);transform:translateY(calc(var(--t) * -.045)) rotate(45deg);transition:color .15s}
.menu__x span::before,.menu__x span::after{content:"";position:absolute;left:0;top:50%;width:100%;height:var(--ctl-stroke);margin-top:calc(var(--ctl-stroke) / -2);background:currentColor}
.menu__x span::after{transform:rotate(90deg)}
.menu__x:hover span{color:var(--color-chestnut-300)}
.menu__x:focus-visible{outline:2px solid var(--color-chestnut-300);outline-offset:2px;border-radius:4px}
#menu-list{display:flex;flex-direction:column;flex:1;min-height:0}
.menu__act{font-family:var(--font-sans);font-size:calc(var(--fs--3) * var(--mk));letter-spacing:var(--tr-caps);text-transform:uppercase;color:var(--color-chestnut-300);border-bottom:1px solid rgba(255,255,255,.14);padding-bottom:calc(3px * var(--mk));margin:clamp(calc(7px * var(--mk)),calc(1.3 * var(--mvh)),calc(15px * var(--mk))) 0 calc(2px * var(--mk));flex:none}
.menu__act:first-of-type{margin-top:0}
.menu a{display:grid;grid-template-columns:calc(34px * var(--mk)) 1fr auto;gap:calc(11px * var(--mk));align-items:baseline;align-content:center;flex:1 0 auto;text-decoration:none;color:var(--fg-inv);padding:clamp(calc(3px * var(--mk)),calc(.7 * var(--mvh)),calc(8px * var(--mk))) calc(3px * var(--mk));border-bottom:1px solid rgba(255,255,255,.08);transition:.15s}
.menu a:hover{color:var(--color-chestnut-300);padding-inline-start:calc(8px * var(--mk))}
#menu-list a:last-of-type{border-bottom:none}
.menu__n{font-family:var(--font-insc);font-size:calc(var(--fs--2) * var(--mk));color:var(--color-chestnut-500)}
.menu__nm{font-family:var(--font-disp);font-size:calc(var(--fs--1) * var(--mk));line-height:1.05}
.menu__y{font-family:var(--font-sans);font-size:calc(var(--fs--2) * var(--mk));color:var(--color-chestnut-300);text-align:end}

/* language switch: the two addresses cross through a short blur. The old page blurs
   (14px, the language menu's glass), then the two cross-fade on the same curve and the
   same window, so their sum stays whole; the new page comes in .25s late, which gives
   main.js the time to land it on the reading place, and clears. Cross-document view
   transition; main.js skips it for every navigation that is not a switch. Browsers
   without it get .langveil, the same blur as a veil over the page */
@view-transition{navigation:auto}
::view-transition-old(root){animation:langOut .55s var(--ease) both}
::view-transition-new(root){animation:langIn .55s var(--ease) .25s both}
@keyframes langOut{0%{filter:blur(0)}45%{filter:blur(14px);opacity:1}100%{filter:blur(14px);opacity:0}}
@keyframes langIn{0%{filter:blur(14px);opacity:0}55%{opacity:1}100%{filter:blur(0);opacity:1}}
.langveil{position:fixed;inset:0;z-index:200;pointer-events:none;background:color-mix(in oklab,var(--bg) 30%,transparent);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);opacity:0;transition:opacity .55s var(--ease)}
.langveil.on{opacity:1;transition-duration:.25s}
.langveil.is-instant{transition:none}
@media (prefers-reduced-motion:reduce){::view-transition-old(root),::view-transition-new(root){animation:none}.langveil{display:none}}

/* lightbox */
.lightbox{position:fixed;inset:0;z-index:90;background:rgba(10,12,18,.62);-webkit-backdrop-filter:blur(14px) saturate(1.05);backdrop-filter:blur(14px) saturate(1.05);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;padding:40px 20px;opacity:0;visibility:hidden;transition:opacity .3s var(--ease),visibility .3s;overscroll-behavior:contain;touch-action:none}
.lightbox.open{opacity:1;visibility:visible}
/* every picture fills the same frame, 78vh tall and at most 94vw wide, scaled up or down:
   --ar is the picture's width/height, set by the lightbox from the plate's image. With
   only the max- limits, a scan smaller than the frame showed at its own, smaller size.
   Zoom happens INSIDE this frame: its size, shadow and place never change, only the
   picture in it is scaled (up to 4x) and moved, always covering the frame (main.js) */
.lightbox__frame{position:relative;flex-shrink:0;overflow:hidden;max-width:94vw;max-height:78vh;width:min(94vw,calc(78vh * var(--ar)));aspect-ratio:var(--ar);border-radius:3px;box-shadow:0 22px 70px -24px rgba(0,0,0,.72);transform:scale(.97);transition:transform .3s var(--ease),opacity .14s linear;touch-action:none}
.lightbox.open .lightbox__frame{transform:none}
.lightbox img{display:block;width:100%;height:100%;border:none;transform-origin:0 0;transition:transform .32s var(--ease);touch-action:none;user-select:none;-webkit-user-select:none;-webkit-user-drag:none}
/* while a finger, the mouse or the trackpad moves the picture it follows directly; the
   layer hint is dropped again afterwards so the zoomed picture is redrawn sharp */
.lightbox__frame.is-moving img{transition:none;will-change:transform}
@media (hover:hover){.lightbox__frame{cursor:zoom-in}.lightbox__frame.is-zoomed{cursor:grab}.lightbox__frame.is-zoomed.is-moving{cursor:grabbing}}
.lightbox figcaption{font-family:var(--font-sans);font-size:13px;letter-spacing:.03em;color:var(--color-chestnut-100);text-align:center;max-width:60ch;text-shadow:0 1px 8px rgba(0,0,0,.45)}
.lightbox__x{position:absolute;top:calc(env(safe-area-inset-top) + 16px);inset-inline-end:18px;font-family:var(--font-sans);font-size:12px;letter-spacing:var(--tr-caps);text-transform:uppercase;color:var(--fg-inv);border:1px solid rgba(246,242,233,.38);border-radius:999px;padding:8px 16px;background:rgba(10,12,18,.38);backdrop-filter:blur(10px)}
.lightbox__nav[hidden]{display:none}
.lightbox__nav{position:absolute;top:50%;transform:translateY(-50%);width:52px;height:52px;display:grid;place-items:center;border-radius:999px;border:1px solid rgba(246,242,233,.44);background:rgba(10,12,18,.48);color:var(--fg-inv);font-family:var(--font-disp);font-size:31px;line-height:0;padding-bottom:4px;box-shadow:0 10px 28px -18px rgba(0,0,0,.75);backdrop-filter:blur(10px);transition:border-color .15s,background .15s,transform .15s}
.lightbox__nav:hover{border-color:var(--color-chestnut-300);background:rgba(10,12,18,.72);transform:translateY(-50%) scale(1.04)}
.lightbox__nav--prev{inset-inline-start:clamp(24px,calc(50% - min(36vw,460px)),42vw)}
.lightbox__nav--next{inset-inline-end:clamp(24px,calc(50% - min(36vw,460px)),42vw)}
.lightbox__count{font-family:var(--font-sans);font-size:12px;letter-spacing:var(--tr-caps);color:var(--color-chestnut-100);text-shadow:0 1px 8px rgba(0,0,0,.45)}
@media(max-width:600px){.lightbox__nav{display:none}}
