/* =========================================================================
   Peter Wels — "Kabinett" redesign
   A hushed, spot-lit online gallery for hyperrealist pencil drawings.

   Design language
   ---------------
   • The drawings are monochrome and unframed on a white wall; the documentary
     photographs of exhibitions keep their colour, so only the art is graded.
   • A dark rail carries the navigation on every page but the home slideshow,
     which is a full-bleed black stage.
   • Two type voices: Futura for everything that labels the work (wordmark,
     navigation, section labels, wall-label captions) and an old-style serif
     for everything that is the writing (essay, CV, contact, legal).
   • One webfont request (Futura PT via Adobe Fonts, disclosed on the
     Datenschutz page); the serif is a system stack.

   All class hooks (ce_gallery, vollbild, breit, teaser-start, image_container,
   caption, mod_article, vita, galerie-vita, nav-*, wp-block-*) match the markup
   the PHP templates emit, so the CMS data flow is unchanged.
   ========================================================================= */

/* -------------------------------------------------------------------------
   1. Reset
   ---------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body, h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd, ul, ol {
  margin: 0;
}
ul[class], ol[class] { list-style: none; padding: 0; }
img, picture, video { max-width: 100%; height: auto; display: block; }
button, input, select, textarea { font: inherit; color: inherit; }
a { color: inherit; text-decoration: none; }
table { border-collapse: collapse; }

/* -------------------------------------------------------------------------
   2. Design tokens
   ---------------------------------------------------------------------- */
:root {
  /* Type — Futura PT (Adobe Fonts / Typekit). Light (300) is the workhorse;
     bold (700) for the rare emphasis. */
  --font:      "futura-pt", "Century Gothic", "Avenir Next", -apple-system,
               BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
  --font-bold: "futura-pt-bold", "futura-pt", "Century Gothic", "Avenir Next",
               Arial, sans-serif;
  /* The mockups run two voices: Futura for everything that labels the work —
     wordmark, navigation, section labels, wall-label captions — and an
     old-style serif for everything that *is* the writing: the essay, the CV,
     the contact and legal pages. Only the sans is licensed (Adobe Fonts), so
     the serif is a system stack chosen to sit closest to the drawn one. */
  --serif:     "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua",
               "Hoefler Text", Georgia, "Times New Roman", serif;
  --sans:      var(--font);   /* alias kept — every label voice is the sans */

  --step-0: clamp(1rem, 0.96rem + 0.2vw, 1.125rem);        /* body      */
  --step-1: clamp(1.2rem, 1.1rem + 0.5vw, 1.5rem);         /* h2 / h3   */

  --gap:        clamp(1.5rem, 1rem + 2vw, 3.3rem);   /* page side margin */
  /* The mockups hold everything — clips, photo grid, essay, CV — inside one
     narrow column beside the rail, roughly the width of the widest drawing.
     That column, not the viewport, is what sets the page's rhythm. */
  --measure:    34rem;    /* reading width for running prose             */
  --content:    42.6rem;  /* 681.5px — the clip/grid column, measured off
                             the Videos and Impressionen mockups           */
  --plate:      57.4rem;  /* 918px — the widest plate in the mockups     */
  --vita-col:   6.5rem;   /* 104px — the vita's narrow left column
                             (portrait, plate thumbnails)               */
  --label:      0.72rem;  /* wall-label / nav caption size               */
  --track:      0.18em;   /* tracking for labels                         */
  --header-h:   4.125rem;  /* 66px — puts the wordmark baseline at 45px */
  /* The white every page opens and closes with. The fixed header is
     transparent, so its 66px of clearance reads as part of that white — which
     is why the top gap has to carry it and the bottom does not have to
     subtract it: both ends show the same empty column. Client note ("Abstand
     oben und unten gleich"), and it is the one number that decides where
     content starts on every page. */
  --page-pad:   calc(var(--header-h) + clamp(1.5rem, 3.5vw, 3.5rem));
  /* 137px at 1728. The white under a wall label before the next thing starts,
     on the drawings' hang and — client note, "Gestaltung wie Seite 2
     (Zeichnungen). Gleiche Abstände, gleiche Schriftgröße" — on the clips, the
     photo grid and the essay too. One number, so the two pages read alike. */
  --hang-gap:   clamp(5rem, 9vw, 8.6rem);

  --nav-w: 243px;   /* rail width + the content inset it mirrors; measured
                       off every mockup, which all render the rail at 243px */
  --nav-gap: 1.65rem;  /* rail: 26.4px between nav items, so consecutive
                          baselines land 53.5px apart as in the mockups   */
  --logo:        #bfe5ce; /* wordmark mint (sampled from the mockups) */
  --logo-bright: #e2f4ea; /* the same mint, lifted, for hover over dark */

  /* ---- Content palette : a clean white gallery wall (per the mockups). ---- */
  --bg:          #ffffff;   /* white wall                          */
  --bg-raised:   #f4f4f4;   /* recessed panels                     */
  /* Black, not a soft near-black. Sampled off the mockups: the drawings'
     wall label, the essay body and the Kontakt/Impressum copy all have glyph
     cores at 0,0,0, and the same files render the rail at exactly 29 (#1d1d1d),
     so the JPEG is reproducing darks faithfully rather than crushing them. */
  --ink:         #000000;   /* primary text                        */
  --ink-dim:     #565656;   /* captions, secondary prose           */
  --ink-faint:   #7d7d7d;   /* wall-label metadata, fine print     */
  /* Now the same value as --ink. Kept as its own token because it is the
     *hover* role: it lifts --ink-dim links (the page footer) and swaps a link's
     hairline from --rule-strong to solid, which still reads on a black body. */
  --ink-bright:  #000000;   /* hover / emphasis                    */
  --rule:        rgba(0, 0, 0, 0.14);   /* hairlines               */
  --rule-strong: rgba(0, 0, 0, 0.26);
  --shadow:      0 10px 34px rgba(0, 0, 0, 0.12); /* frames the work */

  /* ---- Chrome palette : the dark navigation + the home cinema stage. ----
     Fixed — no light/dark toggle; dark chrome always sits over light content. */
  --chrome-bg:          #1d1d1d;   /* neutral near-black nav panel   */
  --chrome-ink:         #ffffff;   /* wordmark + active nav          */
  --chrome-ink-dim:     #8e8e8e;   /* inactive nav labels           */
  --chrome-ink-faint:   #6f6f6f;   /* legal links, copyright        */

  color-scheme: light;
}

/* -------------------------------------------------------------------------
   3. Base
   ---------------------------------------------------------------------- */
html { font-size: 100%; }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-weight: 300;                 /* Futura PT Light */
  font-size: var(--step-0);
  line-height: 1.65;
  font-feature-settings: "kern" 1, "liga" 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

::selection { background: var(--ink); color: var(--bg); }

/* Focus — visible for keyboard users, quiet for the mouse. */
:focus-visible {
  outline: 1px solid var(--rule-strong);
  outline-offset: 3px;
}

h1, h2, h3, h4 { font-weight: 300; line-height: 1.2; }

p { margin: 0 0 1.1em; }
p:last-child { margin-bottom: 0; }

strong, b { font-family: var(--font-bold); font-weight: 700; }
em, i { font-style: italic; }

hr {
  border: 0;
  height: 1px;
  background: var(--rule);
  margin: clamp(2.5rem, 5vw, 5rem) auto;
  width: 100%;
}

/* Prose links: a restrained hairline that thickens on hover — no colour. */
.prose a,
[id=main] .ce_text a {
  text-decoration: none;
  background-image: linear-gradient(var(--rule-strong), var(--rule-strong));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 100% 1px;
  transition: color .3s, background-size .3s;
}
.prose a:hover,
[id=main] .ce_text a:hover {
  color: var(--ink-bright);
  background-image: linear-gradient(var(--ink-bright), var(--ink-bright));
}

/* -------------------------------------------------------------------------
   4. Layout scaffolding
   ---------------------------------------------------------------------- */
#wrapper {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

#container { flex: 1 0 auto; width: 100%; }

/* Desktop: the content column is inset beside the rail, so the two never
   overlap — the airy, asymmetric layout the mockups draw.

   The inset is a property of the *page*, not of whether the rail happens to be
   open: toggling must not move the content. Tying it to .nav-open meant the
   burger relaid out the whole page — 400ms of animated padding, one full
   layout per frame — and on the home page it shoved the full-bleed slideshow
   224px sideways, which is the flicker you saw. Now the rail simply slides
   over the page and away again, and nothing reflows. */
@media (min-width: 900px) {
  body:not(.home) #container { padding-left: var(--nav-w); }
}

/* #main carries only the vertical rhythm (clearing the fixed header at the
   top). Side gutters live on the content blocks themselves, so a full-bleed
   gallery can simply not have them — no negative-margin break-out tricks. */
#main .inside {
  /* One number, top and bottom, on every page — so the first element always
     lands on the same line and the page closes on the mirror of it. Anything
     that used to add its own opening gap on top of this (the drawings' first
     plate) now cancels it, rather than starting a page 48px lower than the
     rest. */
  padding-block: var(--page-pad);
}
.mod_article { width: 100%; }

/* Boxed content: centred to a cap, with responsive side gutters. Galleries
   set their own width below, so they are intentionally excluded here. */
.ce_text,
.ce_image,
.ce_player,
.ce_downloads,
.ce_hyperlink,
.mod_article > .wp-block-group {
  max-width: calc(var(--content) + var(--gap) * 2);
  margin-inline: auto;
  padding-inline: var(--gap);
}

/* Running text is the serif voice, held to a reading measure. `fit-content`
   makes the column shrink to short copy — so a contact block of four-word
   lines centres as a compact column instead of hanging off the left edge of a
   measure-wide box — while long prose simply fills the measure and centres. */
.ce_text,
.prose {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 1.02rem;
  line-height: 1.62;
  font-variant-numeric: oldstyle-nums;
}
.ce_text { max-width: calc(var(--measure) + var(--gap) * 2); }
hr { max-width: var(--content); padding-inline: var(--gap); }

/* -------------------------------------------------------------------------
   5. Section labels (the recurring wall-label idiom)
   ---------------------------------------------------------------------- */
/* The tracked-caps label is the chrome's voice. It belongs above a gallery
   room, not inside running text — headings in prose are part of the document
   and stay in the serif (see §10). */
.eyebrow {
  font-family: var(--sans);
  font-size: var(--label);
  font-weight: 500;
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--ink-faint);
  margin: 0 0 1.4rem;
  text-align: center;
}

/* The mockups carry no visible page titles — the work/content leads. Keep the
   heading in the DOM for accessibility + SEO, but hide it visually. */
.pw-pagehead {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Inside the vita the headings belong to the document, not to the chrome:
   they stay in the serif voice, bold and left-aligned, with no rule. */
.galerie-vita {
  /* 25.6px, the white the mockup leaves over a section heading. It was 52 —
     the heading floated in the middle of a gap instead of sitting on top of
     the thumbnails it introduces. Collapses with the h2's own margin. */
  margin-top: 1.6rem;
  max-width: calc(var(--content) + var(--gap) * 2);
  margin-inline: auto;
  padding-inline: var(--gap);
}
#main .ce_gallery > h2 {
  font-family: var(--serif);
  font-size: 1.02rem;
  font-weight: 700;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
  text-align: left;
  margin-bottom: 1rem;
}

/* -------------------------------------------------------------------------
   6. Header
   ---------------------------------------------------------------------- */
#header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 130;              /* above the sidebar, so the panel slides BEHIND
                               the wordmark + burger — no duplicate, no jump */
  background: transparent;   /* floats over the gallery — no bar, no blur */
  transition: background-color .25s ease;
}
#header .inside {
  display: flex;
  align-items: center;
  justify-content: flex-start;   /* wordmark + burger grouped, top-left */
  /* 0.5rem here + the burger's own 0.5rem padding = the 16px the mockups
     leave between the wordmark and the icon. */
  gap: 0.5rem;
  min-height: var(--header-h);
  /* Not var(--gap): the mockups indent the wordmark 34px, independently of
     the page gutter, which is far wider at desktop widths. */
  padding: 0 2rem;
  max-width: 100%;
}

/* Wordmark — lowercase Futura PT Light. It stays fixed while the dark panel
   slides in behind it: dark ink over white content when closed; mint over the
   home stage and over the open panel. The colour eases in sync with the slide. */
a#logo {
  font-family: var(--font);
  /* 38px with tight tracking: the mockups set the wordmark 130px wide over a
     16.5px x-height, which no positive tracking at this size can produce. */
  font-size: 2.375rem;
  font-weight: 300;
  letter-spacing: -0.035em;
  line-height: 1;
  text-transform: lowercase;
  color: var(--ink);
  white-space: nowrap;
  transition: color .4s ease, opacity .3s;
}
a#logo:hover { color: var(--ink-bright); }

/* The wordmark and the burger are one lockup and always share a colour: dark
   ink while they sit on the white wall, mint once the ground behind them goes
   dark — the home stage, or the open navigation rail. Hover lifts the same hue
   rather than switching to it, so the burger can never land black-on-black. */
.home a#logo,
.home .nav-toggle,
.nav-open a#logo,
.nav-open .nav-toggle { color: var(--logo); }
.home a#logo:hover,
.home .nav-toggle:hover,
.nav-open a#logo:hover,
.nav-open .nav-toggle:hover { color: var(--logo-bright); }

/* Over the black gallery stage the lockup gets a soft shadow so it stays
   legible wherever a drawing reaches the edge. */
.home a#logo { text-shadow: 0 1px 8px rgba(0, 0, 0, 0.55); }
.home .nav-toggle .nav-toggle-bars span { box-shadow: 0 1px 6px rgba(0, 0, 0, 0.55); }

/* Header controls — the burger, sitting just after the wordmark. */
.header-controls {
  display: flex;
  align-items: center;
  gap: clamp(0.5rem, 1.5vw, 1rem);
}

/* Burger — opens the off-canvas navigation sidebar. */
.nav-toggle {
  appearance: none;
  -webkit-appearance: none;
  background: none;
  border: 0;
  cursor: pointer;
  color: var(--ink);
  padding: 0.5rem;
  display: inline-flex;
  align-items: center;
  transition: color .3s;
}
.nav-toggle:hover { color: var(--ink-bright); }   /* over the white wall */
.nav-toggle-bars {
  display: block;
  /* 28 × 16: three 2px bars on a 7px pitch, spanning the wordmark's
     x-height exactly as the mockups draw it. */
  width: 1.75rem; height: 1rem;
  position: relative;
  top: 4px;   /* the mockups hang the bars off the wordmark's baseline */
}
.nav-toggle-bars span {
  position: absolute;
  left: 0; right: 0;
  height: 2px;
  background: currentColor;
  transition: transform .3s ease, opacity .2s ease;
}
.nav-toggle-bars span:nth-child(1) { top: 0; }
.nav-toggle-bars span:nth-child(2) { top: 50%; transform: translateY(-50%); }
.nav-toggle-bars span:nth-child(3) { bottom: 0; }

/* The mockups keep three bars even with the rail open — beside a rail that is
   simply *there*, the icon reads as "the menu", not "close this". The overlay
   drawer is different: it covers the page, so it earns an X to dismiss it. */
@media (max-width: 899px) {
  .nav-open .nav-toggle-bars span:nth-child(1) { top: 50%; transform: translateY(-50%) rotate(45deg); }
  .nav-open .nav-toggle-bars span:nth-child(2) { opacity: 0; }
  .nav-open .nav-toggle-bars span:nth-child(3) { bottom: auto; top: 50%; transform: translateY(-50%) rotate(-45deg); }
}

/* Below the rail breakpoint there is no column to keep the page clear of the
   wordmark: the content runs full width and passes straight under the header,
   so once the page has left the top, drawings and photographs slide behind the
   lockup and it has nothing to read against. From the first pixel of scroll the
   header takes the wall's own white as a ground.

   Not on the home page — its stage is black and the lockup carries a shadow
   there — and not while the drawer is out, where the header sits over the dark
   panel and a white bar would cut across its top. Desktop keeps the clean float:
   the rail holds the content beside the wordmark rather than under it. */
@media (max-width: 899px) {
  body.is-scrolled:not(.home):not(.nav-open) #header { background: var(--bg); }
}

/* -------------------------------------------------------------------------
   6b. Navigation rail / off-canvas sidebar

   One element, two behaviours. From 900px up it is the persistent dark rail the
   mockups draw: open on every page but the home slideshow, with the content
   column simply inset beside it. Below 900px there is no room for a rail, so
   the same panel becomes an overlay drawer — dimmed backdrop, page scroll
   locked, closed until the burger is pressed.
   ---------------------------------------------------------------------- */
.nav-backdrop {
  position: fixed;
  inset: 0;
  z-index: 118;
  background: rgba(0, 0, 0, 0.42);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .35s ease, visibility .35s ease;
}
.nav-open .nav-backdrop { opacity: 1; visibility: visible; pointer-events: auto; }

/* Dark "chrome" panel on the LEFT, carrying the wordmark lockup at its top. */
.nav-sidebar {
  position: fixed;
  top: 0; left: 0; bottom: 0;
  z-index: 120;
  width: min(86vw, var(--nav-w));
  background: var(--chrome-bg);
  color: var(--chrome-ink);
  transform: translateX(-100%);
  transition: transform .4s cubic-bezier(.2,.7,.2,1), box-shadow .4s ease;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  /* A flick that runs past the end of the panel stays in the panel instead of
     handing the rest of itself to the page underneath. */
  overscroll-behavior: contain;
}
/* Shadow only while the drawer is out — an off-screen panel would otherwise
   smear a grey band down the left edge of the page. */
.nav-open .nav-sidebar {
  transform: translateX(0);
  box-shadow: 20px 0 60px rgba(0, 0, 0, 0.32);
}

/* Without JS the burger cannot fire, so the rail simply stays out — otherwise
   the navigation would be unreachable. */
html:not(.js) .nav-sidebar { transform: translateX(0); }
html:not(.js) .nav-backdrop { display: none; }

/* Rail mode: it sits in the layout rather than over it, so no backdrop, no
   drop shadow reaching across the page, and no scroll lock. */
@media (min-width: 900px) {
  .nav-backdrop { display: none; }
  .nav-open .nav-sidebar { box-shadow: none; }
}

/* Everything in the rail is centred on its axis, as the mockups draw it. */
.nav-sidebar-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: clamp(2rem, 5vw, 3rem);
  min-height: 100%;
  /* Clear the fixed header, so the panel's nav starts below the wordmark +
     burger that float on top of it. */
  /* The 1.3rem foot is 20.8px: the mockups (5- Kontakt, a full 1536x1020
     viewport) put the copyright's last ink 25px off the bottom edge, and at
     the old 0.75rem it sat 16.2px off — reading tighter under the copyright
     than the 16.5px the same mockups leave over the wordmark. */
  padding: calc(var(--header-h) + clamp(1.25rem, 4vw, 3.22rem)) 1rem 1.3rem;
}
.nav-sidebar-inner > * { width: 100%; }

/* Primary nav — a stacked column of lowercase Futura labels. Active = bright;
   the grouped trio (videos/impressionen/text) all read active on that page. */
.nav-sidebar .nav-main ul {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--nav-gap);
  line-height: 1.2;   /* no strut: the gap alone sets the baseline rhythm */
}
/* videos / impressionen / text point at one page, so they close ranks into a
   single cluster: pull each one back up until their pitch is roughly half the
   gap that separates the real menu entries. */
.nav-sidebar .nav-main li.trio + li.trio {
  /* The trio is one destination, so the mockups set it solid: its lines sit
     a single line-height apart, half the step between the other items. */
  margin-top: calc(var(--nav-gap) * -1);
}
.nav-sidebar .nav-main a,
.nav-sidebar .nav-main strong {
  font-family: var(--font);
  font-size: 1.4rem;           /* 22.4px — measured across six nav labels */
  font-weight: 300;
  letter-spacing: 0;
  line-height: 1.2;
  text-transform: lowercase;   /* labels come from page titles ("Zeichnungen") */
  color: var(--chrome-ink-dim);
  display: inline-block;
  transition: color .3s;
}
.nav-sidebar .nav-main a:hover { color: var(--chrome-ink); }
/* The trio is one destination, so it lights as one: hovering any of the three
   highlights all three, the same way all three read active on that page.
   Browsers without :has() simply fall back to the single-item hover above. */
.nav-sidebar .nav-main ul:has(li.trio:hover) li.trio a { color: var(--chrome-ink); }
.nav-sidebar .nav-main .active,
.nav-sidebar .nav-main .current-menu-item > a,
.nav-sidebar .nav-main strong { color: var(--chrome-ink); }

/* Secondary (legal) links — impressum / datenschutz, quieter than the primary. */
.nav-sidebar .nav-footer ul {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.55rem;
  font-size: 1rem;   /* not the page's 18px body size — the strut sets the gap */
  line-height: 1.2;
}
/* The current legal page renders as <strong> rather than a link — it must
   still read as the same quiet line, not as bold white shouting. */
.nav-sidebar .nav-footer a,
.nav-sidebar .nav-footer strong {
  font-family: var(--font);
  font-size: 1rem;             /* 16px, per the mockups' rail foot */
  font-weight: 300;
  letter-spacing: 0;
  line-height: 1.2;
  text-transform: lowercase;
  color: var(--chrome-ink-faint);
  transition: color .3s;
}
.nav-sidebar .nav-footer strong { color: var(--chrome-ink-dim); }
.nav-sidebar .nav-footer a:hover { color: var(--chrome-ink); }

/* The foot: legal links, then copyright, pinned to the bottom of the rail. */
.nav-sidebar-foot {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.55rem;   /* 28px between the foot's baselines, per the mockups */
  line-height: 1.2;
  padding-top: 2rem;
}
/* The language switch closes the primary group rather than joining the legal
   fine print — the mockups sit it a clear step below "kontakt". */
.nav-utility {
  display: flex;
  justify-content: center;
  margin-top: clamp(0.5rem, 2.5vh, 1.06rem);
}

/* Language switch. */
.nav-sidebar .nav-lang ul { display: flex; align-items: center; justify-content: center; }
.nav-sidebar .nav-lang a,
.nav-sidebar .nav-lang strong {
  font-family: var(--font);
  font-size: 1.4rem;   /* the mockups set "de / en" at the primary nav size */
  font-weight: 300;
  letter-spacing: 0;
  line-height: 1.2;
  text-transform: lowercase;
  color: var(--chrome-ink-faint);
  transition: color .3s;
}
.nav-sidebar .nav-lang a:hover { color: var(--chrome-ink); }
.nav-sidebar .nav-lang .active,
.nav-sidebar .nav-lang strong { color: var(--chrome-ink); }
.nav-sidebar .nav-lang li:not(:first-child)::before {
  content: "/";
  color: var(--chrome-ink-faint);
  margin: 0 0.55em;
}

.nav-copyright {
  font-family: var(--font);
  font-size: 1rem;
  font-weight: 300;
  letter-spacing: 0;
  line-height: 1.2;
  text-transform: lowercase;
  color: var(--chrome-ink-faint);
  margin: 0;
}

/* Lock the page behind the overlay drawer only — the desktop rail is part of
   the layout, and locking there would freeze the whole site.

   `overflow: hidden` on its own was not a lock: with the document no longer
   scrollable some engines clamp the offset, so the page jumped to the top as
   the drawer opened and stayed there once it closed. The body is pinned in
   place instead, at minus the offset it was read at — theme.js writes that
   `top` and puts the scroll back on close, so the view never moves.

   It is also why this is keyed to a class JS sets rather than to `.nav-open`:
   the server marks sub pages `nav-open` for the rail, and with JS off — where
   nothing pins or restores anything — the old rule left the whole page
   unscrollable on a phone. */
@media (max-width: 899px) {
  .nav-locked {
    position: fixed;
    left: 0;
    width: 100%;
    overflow: hidden;
  }
}

/* -------------------------------------------------------------------------
   7. Home — the full-page drawings slideshow
   ---------------------------------------------------------------------- */
/* The home page is edge-to-edge: drop #main's gutters and header clearance so
   the slideshow fills the viewport, and let the fixed header float over it. */
.home #main .inside { padding: 0; }

/* And it is exactly one viewport — one stage, never a scroll, on any device.
   Leaving #wrapper on its site-wide `min-height: 100dvh` let a sub-pixel spill
   (or a mobile toolbar settling between svh and lvh) hand the page a scrollbar
   under the full-bleed slide. Pin the page to the dynamic viewport and clip, so
   nothing below the fold can exist to scroll to. */
.home { height: 100vh; height: 100dvh; overflow: hidden; }
.home #wrapper { min-height: 0; height: 100%; }

.pw-hero {
  position: relative;
  width: 100%;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  background: #000;   /* cinema stage — letterbox bars are black on every device */
}
.pw-hero-track { position: absolute; inset: 0; margin: 0; padding: 0; list-style: none; }
.pw-hero-slide {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity 1s ease, visibility 1s ease;
}
.pw-hero-slide.is-active { opacity: 1; visibility: visible; }
.pw-hero-img {
  width: 100%;
  height: 100%;
  /* Bleed off all four edges, as mockup 1 does — the drawing fills the stage
     on every device, never letterboxed. `contain` plus an aspect-ratio switch
     was not enough: on any viewport narrower than the 16:9 slide it fell back
     to bars, which is exactly what we do not want. `cover` always fills, so a
     phone held upright shows a centred slice rather than black margins. The
     slides are all one aspect, so the frame never jumps between them. */
  object-fit: cover;
  /* …and which slice, when the stage is narrower than the slide. A phone shows
     about a quarter of the width, so `center` is a guess that happens to be
     right for a symmetrical nave and wrong for a cellist sitting hard right.
     --pw-focus-x is that image's answer, set per slide by the template from
     pewe_focus_x(); 50% when nobody has said otherwise.

     Not behind a media query on purpose. At 16:9 and wider `cover` is
     width-driven — there is no horizontal overflow, so the x has no effect at
     all and the desktop stage is untouched by construction. Between 16:10 and
     16:9 it moves the frame by under 4%, which is a drift as the window
     narrows rather than a jump at a breakpoint when a tablet is rotated. */
  object-position: var(--pw-focus-x, 50%) center;
  filter: grayscale(1);
  background: #000;
}
/* Controls — a vertical column of dots down the lower right edge (design 1).
   Each dot is an open ring; the current work is the one filled mint, matching
   the wordmark. Click to jump. */
.pw-hero-controls {
  position: absolute;
  right: clamp(1rem, 2vw, 1.75rem);
  bottom: clamp(1.4rem, 3.2vh, 2.6rem);
  z-index: 3;
  display: flex;
}
.pw-hero-dots {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;   /* 12px + the 9px dot = the mockup's 21px pitch */
}
.pw-hero-dot {
  appearance: none;
  -webkit-appearance: none;
  padding: 0;
  cursor: pointer;
  width: 9px; height: 9px;
  flex: none;
  border-radius: 50%;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.75);
  filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.55));
  transition: background .3s, border-color .3s;
}
.pw-hero-dot:hover { background: rgba(255, 255, 255, 0.45); }
.pw-hero-dot[aria-selected="true"] {
  background: var(--logo);
  border-color: var(--logo);
}

/* Reduced motion: no crossfade (slides still change, but instantly). */
@media (prefers-reduced-motion: reduce) {
  .pw-hero-slide { transition: none; }
}

/* -------------------------------------------------------------------------
   7b. Home — fallback two portals (shown only if no drawings exist yet)
   ---------------------------------------------------------------------- */
/* The two square portals to Drawings / Impressions. */
.ce_gallery.teaser-start {
  max-width: 82rem;
  margin-inline: auto;
  padding-inline: var(--gap);
}
.ce_gallery.teaser-start ul {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(2rem, 5vw, 4rem);
}
@media (min-width: 720px) {
  .ce_gallery.teaser-start ul { grid-template-columns: 1fr 1fr; }
}
.ce_gallery.teaser-start figure { position: relative; margin: 0; }
.ce_gallery.teaser-start a {
  display: block;
  overflow: hidden;
  border: 1px solid var(--rule);
  background: var(--bg-raised);
}
.ce_gallery.teaser-start img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  filter: grayscale(1);
  transition: transform 1.1s cubic-bezier(.2,.7,.2,1), filter .6s;
}
.ce_gallery.teaser-start a:hover img {
  transform: scale(1.04);
  filter: grayscale(1) brightness(1.04);
}
.ce_gallery.teaser-start figcaption {
  font-family: var(--sans);
  font-size: var(--label);
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--ink-dim);
  text-align: center;
  padding-top: 1.1rem;
  transition: color .3s;
}
.ce_gallery.teaser-start figure:hover figcaption { color: var(--ink-bright); }
/* a discreet "view" cue */
.ce_gallery.teaser-start figcaption::after {
  content: "";
  display: block;
  width: 1.6rem; height: 1px;
  background: var(--rule-strong);
  margin: 0.8rem auto 0;
}

/* -------------------------------------------------------------------------
   8. Galleries
   ---------------------------------------------------------------------- */
.ce_gallery ul { padding: 0; margin: 0; }
.ce_gallery li { list-style: none; }
.ce_gallery figure { margin: 0; }

/* 8a. Drawings — one plate at a time, floating in the room (vollbild). */
.ce_gallery.vollbild ul {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.ce_gallery.vollbild li {
  width: 100%;
  display: flex;
  justify-content: center;
  /* Deliberately NOT content-visibility: auto. It is tempting on a page this
     long, but it skips layout for the off-screen plates, and the scroll-reveal
     observer watches the figures *inside* them — so nothing ever intersected
     and every drawing stayed at opacity 0. Lazy loading already keeps the
     images off the wire, which is the cost that actually matters here. */
  padding-inline: var(--gap);
}
/* The mockups pace the plates about two captions' worth of white apart — close
   enough that scrolling reads as one hang, not a slideshow. It is a gap
   *between* plates, so it lives on `li + li` rather than as symmetric padding
   on every li: padding on the first and last would also open and close the
   page, and the drawings would start 48px below every other page's first line
   while `#main .inside` was already setting that white. */
/* 137px, which puts 166px between one plate's bottom edge and the next one's
   top once the wall label and its margin sit in between — the pitch the mockup
   holds between all three of its plates. It was 125. */
.ce_gallery.vollbild li + li { padding-top: var(--hang-gap); }
/* The Zeichnungen mockup sizes a plate by its *width*, and uses two widths:
   the landscape drawing runs the full 917px plate, while the portrait and the
   square one are both held to 679px — the content column. Height never enters
   into it: the portrait plate is 893px tall, taller than either square plate.
   Sizing by 82vh instead made every plate a function of the window's height —
   a square drawing came out 886px on a 1080px screen where the mockup draws it
   at 679 — so the cap moved back onto the figure and 82vh stays only as a
   guard, to keep one plate from outgrowing a short laptop screen. */
.ce_gallery.vollbild figure {
  max-width: var(--content);
  text-align: center;
  /* The plate is an inline-block, so the figure's strut would otherwise leave
     a descender's worth of air under it and push the wall label too low. */
  line-height: 0;
}
/* No frame and no shadow: the mockups drop the work straight onto the white
   wall, so a black-ground drawing keeps its own hard edge. */
.ce_gallery.vollbild a[data-lightbox] {
  display: inline-block;
  line-height: 0;
  cursor: zoom-in;
}
/* Landscape work earns the wide plate; `pewe_render_gallery` measures the
   attachment and tags the item. */
.ce_gallery.vollbild li.plate-wide figure { max-width: var(--plate); }
.ce_gallery.vollbild img {
  max-height: 82vh;
  width: auto;
  margin-inline: auto;
  filter: grayscale(1);   /* guarantee monochrome even if a scan is warm */
}

/* Wall label beneath each drawing. */
.ce_gallery.vollbild figcaption,
.ce_gallery figcaption.caption {
  /* The Zeichnungen mockup annotates this label "Schrift: futura light" and
     sets it at 16px, untracked, in the same black as the drawing's own ink. */
  font-family: var(--sans);
  font-size: 1rem;
  letter-spacing: 0;
  line-height: 1.2;
  color: var(--ink);
  max-width: 40rem;
  margin: 0.6rem auto 0;
}
.ce_gallery.vollbild figcaption br { display: block; }

/* 8b. Impressions — an even, quiet grid. */
.ce_gallery:not(.vollbild):not(.teaser-start):not(.galerie-vita) {
  max-width: calc(var(--content) + var(--gap) * 2);
  margin-inline: auto;
  padding-inline: var(--gap);
}
/* Two columns at every size, with a hairline of white between them — the
   mockup's tight, contact-sheet block. The old 4-up grid shrank the photos to
   thumbnails once the content column narrowed to the drawings' width. */
.ce_gallery:not(.vollbild):not(.teaser-start):not(.galerie-vita) ul {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(0.5rem, 1.2vw, 0.9rem);
}
.ce_gallery:not(.vollbild):not(.teaser-start):not(.galerie-vita) a[data-lightbox] {
  display: block;
  overflow: hidden;
  cursor: zoom-in;
  background: var(--bg-raised);
}
/* These are documentary photographs of the work in rooms, not the work itself:
   the mockups leave them in colour, so the monochrome rule stops at the art. */
.ce_gallery:not(.vollbild):not(.teaser-start):not(.galerie-vita) img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  transition: transform 1s cubic-bezier(.2,.7,.2,1), filter .5s;
}
.ce_gallery:not(.vollbild):not(.teaser-start):not(.galerie-vita) a:hover img {
  transform: scale(1.05);
  filter: brightness(1.03);
}

/* -------------------------------------------------------------------------
   9. Vita

   One left-aligned serif document in the content column. A narrow left column
   recurs down it — the portrait, the plate thumbnails and the short section
   dividers all begin on the same line — which is what holds the page together
   in the mockup, in place of any rules or boxes.
   ---------------------------------------------------------------------- */
.mod_article.vita .inside,
.mod_article.vita { width: 100%; }

/* Portrait — the one photograph of the artist, at the width of the left
   column and left-aligned on it. Kept in colour: the monochrome rule is about
   the drawings, and the mockup shows the garden portrait as shot. */
.mod_article.vita .ce_image {
  /* 8.5px. The mockup sets the first CV entry 29.5px under the photo credit's
     ink; at the old clamp (40px here) it was 61px, so the page opened with a
     hole between the portrait and the CV that the mockup does not draw. */
  margin: 0 auto 0.53rem;
  text-align: left;
}
.mod_article.vita .ce_image img {
  width: var(--vita-col);
  margin-inline: 0;
}
.mod_article.vita .ce_image figcaption {
  letter-spacing: 0;
  text-transform: none;
  /* 5.8px, which lands the credit's ink 8.5px under the portrait — the mockup's
     gap. 0.85rem put it at 16.3, nearly double. */
  padding-top: 0.36rem;
}

/* The CV's voice. The "Text Futura 100" revision of this page drops the serif
   and the hierarchy alike: year, entry, photo credit and catalogue caption are
   all Futura Light at 14/16.8 in one colour, so the page reads as a single
   typed document. Blocks are separated by one blank line (33.6px baseline to
   baseline), which is the only structure the design gives it. */
#main .mod_article.vita .ce_text,
#main .mod_article.vita .ce_text p,
#main .mod_article.vita .ce_image figcaption,
#main .mod_article.vita .ce_gallery > h2,
#main .galerie-vita figcaption,
#main .galerie-vita figcaption.caption {
  font-family: var(--font);
  font-weight: 300;
  font-size: 0.875rem;      /* 14px  */
  line-height: 1.2;         /* 16.8px */
  letter-spacing: 0;
  color: var(--ink);
  font-variant-numeric: normal;
  text-transform: none;
}
/* The CV runs in a column of its own: the mockup's block — thumbnail, gutter
   and entry — measures 451px across, well inside the media column. */
.mod_article.vita { --content: 28.1875rem; --measure: 28.1875rem; }

/* One blank line before each new section, nothing anywhere else. */
#main .mod_article.vita .ce_text p { margin: 0; }
/* "Beispiele Architekturzeichnungen" and "Bücher" head their sections, so the
   mockup sets them heavier than the entries and gives them room on both sides:
   its ink sits ~25px under the block above and ~16px over the first thumbnail.
   They had 16.8px above, nothing at all below — the first thumbnail started on
   the line under them — and the same weight as everything else. */
#main .mod_article.vita .ce_gallery > h2 {
  font-family: var(--font-bold);
  font-weight: 700;
  margin: 0 0 0.8rem;
}

/* "Freie Zeichnungen" under 2005 does the same job inside the CV: it names the
   work the rest of the page belongs to rather than reporting an exhibition, so
   it carries the same weight as the two gallery headings. Only the weight — the
   line stays tied to its year, so it keeps the entries' spacing. The paragraph
   is marked by pewe_vita_section_labels(); the CV's own rule sets every entry
   to 300, hence the class here. */
#main .mod_article.vita .ce_text p.vita-label {
  font-family: var(--font-bold);
  font-weight: 700;
}

/* Year / description entries. The year is a quiet line of its own directly
   above its entry rather than a hanging column — the mockup's CV reads as one
   continuous document, and multi-line entries stay tied to their year. */
.ce_text.vita,
.mod_article.vita .wp-block-group.ce_text.vita > .wp-block-group__inner-container {
  max-width: calc(var(--content) + var(--gap) * 2);
  margin: 0 auto;
}
.mod_article.vita .wp-block-group.ce_text.vita { margin-inline: auto; }

/* Entries that follow a thumbnail run: the mockup leaves 27px between the last
   plate's bottom edge and the next entry's first line. With nothing here the
   1999 Overbeck entry started flush against the 2001 book cover. */
.mod_article.vita .ce_gallery + .ce_text.vita { margin-top: 1.5rem; }

/* A short hairline, the width of the left column, is the only divider the
   mockup draws — used between consecutive CV blocks. */
.mod_article.vita .ce_text.vita + .ce_text.vita { margin-top: clamp(2rem, 4vw, 3rem); }
.mod_article.vita .ce_text.vita + .ce_text.vita::before {
  content: "";
  display: block;
  width: var(--vita-col);
  height: 1px;
  background: var(--rule-strong);
  margin-bottom: clamp(2rem, 4vw, 3rem);
}

#main .ce_text.vita h2, #main .ce_text.vita h3, #main .ce_text.vita h4,
#main .ce_text.vita p,
#main .ce_text.vita .wp-block-group__inner-container h3,
#main .ce_text.vita .wp-block-group__inner-container p { margin: 0; }

#main .ce_text.vita h2, #main .ce_text.vita h3, #main .ce_text.vita h4,
#main .ce_text.vita .wp-block-group__inner-container h3 {
  font-family: var(--font);
  font-size: 0.875rem;              /* 14px — no bigger than the entry */
  font-weight: 300;
  letter-spacing: 0;
  line-height: 1.2;
  color: var(--ink);                /* the year is not quieter than its entry */
  margin-top: 1.2em;                /* one blank line between entries */
}
#main .ce_text.vita > :first-child,
#main .ce_text.vita .wp-block-group__inner-container > :first-child { margin-top: 0; }
#main .ce_text.vita p,
#main .ce_text.vita .wp-block-group__inner-container p {
  color: var(--ink);
}

/* Architecture / books galleries in the vita: a plate on the left column, its
   catalogue entry beside it. */
.galerie-vita ul {
  display: grid;
  gap: clamp(1rem, 2vw, 1.5rem) 2rem;
}
.galerie-vita figure {
  display: grid;
  grid-template-columns: var(--vita-col) 1fr;
  /* Centred on the plate, not hung from its top. Measured across all nine
     thumbnail rows in "4- über mich.jpg": the space over the entry equals the
     space under it in every one of them (13/13, 24/21, 21.5/21, 21.5/23.5,
     24/24, 23.5/21, 24/21, 16/15.5, 15.5/13). The old `start` was read off the
     first row, where a five-line entry nearly fills the plate and the two look
     the same. */
  align-items: center;
  gap: 0.8rem;          /* 13px between the plate and its entry */
}
.galerie-vita a[data-lightbox] {
  display: block; line-height: 0; cursor: zoom-in;
}
/* Documentation of built work and book covers — colour, like the mockup. */
.galerie-vita img { width: 100%; }
.galerie-vita figcaption,
.galerie-vita figcaption.caption {
  letter-spacing: 0;
  text-align: left;
  max-width: none;
  margin: 0;   /* the caption is the grid's second column, not a label below */
}

/* -------------------------------------------------------------------------
   10. Text pages (Kontakt, Datenschutz) + editorial bits
   ---------------------------------------------------------------------- */
#main .ce_text h2,
#main .ce_text h3 {
  font-family: var(--serif);
  font-size: var(--step-1);
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
  margin: 1.8em 0 0.6em;
}
#main .ce_text h2:first-child,
#main .ce_text h3:first-child { margin-top: 0; }
/* The white a page closes with is --page-pad and nothing else. `p:last-child`
   (§3) already drops a trailing paragraph's margin; these are the block-level
   voices that would otherwise slip past it. */
#main .ce_text > :last-child,
#main .prose > :last-child { margin-bottom: 0; }
.ce_text ul:not([class]), .ce_text ol:not([class]) {
  padding-left: 1.2em;
  margin: 0 0 1.1em;
}
.ce_text li { margin-bottom: 0.35em; }

/* Kontakt + Impressum — a single quiet left-aligned column (mockups 5 & 6).
   The content inset (§4) already floats it in the region right of the nav. */
/* The copy here is a handful of short lines, so the column is sized to the
   copy and then centred: the block lands in the middle of the room the way the
   mockups place it, instead of hugging the left edge of a measure-wide box. */
.ce_text.pw-legal {
  /* A fixed column, not `fit-content`. Both mockups start their copy on the
     same line (786.5px at a 1536 viewport) even though Impressum's longest line
     runs 30px past Kontakt's — so the column is a constant, centred, and the
     shorter page's lines simply sit left-aligned inside it. Centring each page
     on its own width instead left the two 15px apart, which shows when you page
     between them from the rail. 14rem = 224px clears the longest rendered line
     on all four pages (Impressum DE, at 218.5); the mockup's column is 210, but
     its face sets narrower than the system serif and "Realisierung: Andreas
     Neeven" wraps below 219. */
  width: min(100%, calc(14rem + var(--gap) * 2));
  margin-inline: auto;
}
.pw-legal > :first-child { margin-top: 0; }
/* Roomy gaps between the address / representation / credit groups. */
/* Futura, not the serif. The Impressum comp the client sent with the videos
   feedback sets this page in the same voice as the essay and the CV — the
   "Text Futura 100" direction — where mockups 5 and 6 still drew it in a serif.
   Scaled off the rail in that comp (its foot pitch is 28px, its nav pitch 53.5,
   both known): 12.26px cap height, so 18px Futura, on a 26.7px line with 51px
   between paragraphs. */
/* Datenschutz. It is the third legal page and sat in the serif on its own after
   Kontakt and Impressum moved to Futura — and it sits directly under Impressum
   in the rail's foot, so the mismatch showed. Same voice and the same 18/26.6
   rhythm as those two; it keeps the reading measure rather than their narrow
   column, because it is running prose and 224px would be 25 characters a line.

   `.prose` is also the exhibition essay, which overrides family, size, leading
   and figures of its own under `#main #text.ce_text` — two IDs deep, so it is
   untouched by this. */
.ce_text.prose {
  font-family: var(--font);
  font-weight: 300;
  font-size: var(--step-0);
  line-height: 1.48;
  font-variant-numeric: normal;
}
.ce_text.prose p { margin: 0 0 1.35em; }   /* 24.3px -> 51px paragraph pitch */
/* Headings take the weight, not a size step — the same way the CV heads its
   sections. `#main #text h2` keeps the essay's tracked byline. */
#main .ce_text.prose h2,
#main .ce_text.prose h3,
#main .ce_text.prose h4 {
  font-family: var(--font-bold);
  font-weight: 700;
  font-size: 1em;
  letter-spacing: 0;
  text-transform: none;
  margin: 2.4em 0 0.8em;
}
/* Datenschutz is the one page that prints its own title in the content, so it
   keeps a step over its sections — 24.3px — rather than being indistinguishable
   from them. It was 36px Futura Light, the last thing on the page still sized
   off the old serif scale. */
#main .ce_text.prose h1 {
  font-family: var(--font-bold);
  font-weight: 700;
  font-size: 1.35em;
  line-height: 1.2;
  letter-spacing: 0;
  margin: 0 0 1.4em;
}

.ce_text.pw-legal {
  font-family: var(--font);
  font-weight: 300;
  font-size: var(--step-0);        /* 18px from 1728 down */
  line-height: 1.48;               /* 26.6px */
  font-variant-numeric: normal;    /* Futura sets lining figures, not old-style */
}
.pw-legal p { margin: 0 0 1.35em; }  /* 24.3px -> 51px paragraph pitch */
/* Both mockups open a wider break where the copy changes subject, and draw it
   at two sizes: one extra line before Kontakt's "Vertreten durch:" (66.5px
   pitch), and a much wider one on Impressum between the address and the
   credits (104.5px). The importer puts the class on the paragraph. */
/* Collapses against the previous paragraph's bottom margin rather than adding
   to it, so the value here is the whole gap, not the extra: one line wider than
   an ordinary paragraph, which is how mockup 5 opens Kontakt's representation
   block. The Impressum had a second, wider step of its own; the Futura comp
   draws no break there at all, so it is gone. */
.pw-legal p.pw-break { margin-top: 2.85em; }   /* 51px -> 78px pitch */
/* The two rules that divide the Impressum's own details from the production
   credits below them. Short, left-aligned on the copy, and nothing like the
   full-width `hr` the prose pages use. */
.pw-legal hr {
  width: 11rem;
  max-width: 100%;
  margin: 2.6em 0;
  padding: 0;
  background: var(--rule-strong);
}
/* The credits run longer than the address above them — "Realisierung: Marcel
   Martens, Hamburg" is 290px against the column's 224. The comp keeps the whole
   page on one left line and simply lets them extend to the right, rather than
   widening the column, which would drag Kontakt's copy left with it and off the
   line both mockups draw it on. Desktop only: in the phone column there is no
   room to the right, and wrapping is the better answer there. */
@media (min-width: 900px) {
  .pw-legal hr ~ p {
    width: max-content;
    max-width: 30rem;
  }
}
.pw-legal p:last-child { margin-bottom: 0; }

/* Video (impressions) */
.ce_player { max-width: calc(var(--content) + var(--gap) * 2); margin-inline: auto; }
.ce_player figure { margin: 0; }
.ce_player video {
  width: 100%;
  background: #000;
}

/* Videos section — a stack of clips, each a poster with a ▶ overlay + credit. */
/* Same gap the drawings hang on. The credit is one line now, so the fixed slot
   that used to hold a constant rhythm against a six-line credit is gone with
   it — every clip closes the same way and this is simply the white after it. */
.pw-videos .ce_player + .ce_player { margin-top: var(--hang-gap); }
.pw-video-shell { position: relative; }
/* Hold a stable 16:9 box so the poster never collapses the layout. */
.pw-videos .ce_player video {
  aspect-ratio: 16 / 9;
  object-fit: cover;
  display: block;
}
/* Centred play triangle over the poster; fades out once the clip is playing. */
.pw-video-play {
  position: absolute;
  inset: 0;
  margin: auto;
  width: clamp(3.25rem, 6vw, 4.5rem);
  height: clamp(3.25rem, 6vw, 4.5rem);
  display: flex;
  align-items: center;
  justify-content: center;
  appearance: none;
  -webkit-appearance: none;
  /* The mockups show a bare frame, so the affordance stays as light as it can
     while still reading as "this plays": a hairline ring, no fill. */
  border: 1px solid rgba(255, 255, 255, 0.85);
  border-radius: 50%;
  background: rgba(20, 20, 20, 0.18);
  color: #fff;
  cursor: pointer;
  /* No scale on hover. The button is centred with auto margins inside a box
     whose width is a vw clamp, so it routinely lands on a half pixel; scaling
     from there dragged the 1px ring back and forth across the pixel grid and
     it shimmered. Colour carries the hover, as it does everywhere else. */
  transition: opacity .3s, background .3s, border-color .3s;
}
.pw-video-play:hover {
  background: rgba(20, 20, 20, 0.45);
  border-color: #fff;
}
.pw-video-play svg { width: 42%; height: 42%; fill: currentColor; margin-left: 6%; }
.pw-video-shell.is-playing .pw-video-play { opacity: 0; pointer-events: none; }
/* Wall-label under each clip. The client asked for the videos to be laid out
   "wie Seite 2 (Zeichnungen). Gleiche Abstände, gleiche Schriftgröße", so this
   is the drawings' wall label exactly: 16px Futura Light, black, centred, the
   same 9.6px under the frame. It was 11.2px with its own spacing, and it
   carried the whole credit block — that now lives on the Impressum. */
.pw-video-credit {
  font-family: var(--font);
  font-size: 1rem;
  font-weight: 300;
  letter-spacing: 0;
  line-height: 1.2;
  color: var(--ink);
  text-align: center;
  margin-top: 0.6rem;
}

/* The exhibition essay. The mockup marks it up twice: "Text FUTURA", and
   "gedachte Linie aufnehmen" with a rule drawn down each side of the block —
   the essay sits ~10px inside the clips and the photo grid above it, and the
   client wants all three flush on the same pair of lines. Holding it to
   --content instead of the narrower reading measure does that exactly. */
#main #text.ce_text {
  max-width: calc(var(--content) + var(--gap) * 2);
  font-family: var(--font);
  font-weight: 300;
  font-size: 1rem;
  line-height: 1.7;          /* 27.2px — the mockup sets the essay on 27.5 */
  font-variant-numeric: normal;
}
/* :not(:last-child) so the essay's closing paragraph does not add its 46px to
   the page's own closing white — the rule is two IDs deep and outranks the
   trailing-margin reset in §10. */
#main #text.ce_text p:not(:last-child) { margin-bottom: 1.2em; }   /* 46px between baselines */

/* The byline is already Futura in the mockup — a widely tracked label, a shade
   quieter than the essay — and it and the standfirst under it centre over the
   column while the essay itself stays flush left. */
#main #text h2 {
  font-family: var(--font);
  font-size: 0.9375rem;        /* 15px, on a 10.5px cap height */
  font-weight: 300;
  letter-spacing: 0.45em;
  text-transform: uppercase;
  line-height: 1.2;
  color: var(--ink-dim);
  text-align: center;
  /* The tracking trails the last letter too, which would sit the line half a
     space left of true centre; the negative margin takes that back. */
  /* 48.5px byline-to-standfirst in the mockup; it was 44. */
  margin: 0 -0.45em 2.05em 0;
}
/* Matched to `#main #text.ce_text p:not(:last-child)` above, which is two IDs
   and two classes deep and would otherwise keep its 1.2em here. */
#main #text.ce_text h2 + p:not(:last-child) {
  font-style: italic;
  font-size: 1.05rem;
  text-align: center;
  margin-bottom: 1.01em;   /* 46px standfirst-to-body in the mockup; it was 48 */
}

/* In-page section anchors clear the fixed header when jumped to. */
#main section[id] { scroll-margin-top: calc(var(--header-h) + 1.5rem); }
/* The client bracketed all four gaps down this page — under each of the three
   clips and under the photo grid — and marked them "Abstand", against a note
   asking for the drawings page's spacing. So they are one number, the same one
   the drawings hang on, and the page reads in a single rhythm rather than
   clips at one pitch and section breaks at another. */
#videos + #impressionen,
#impressionen + #text,
.pw-videos + #impressionen { margin-top: var(--hang-gap); }

/* Buttons / links / downloads — quiet, outlined. */
.btn, .ce_hyperlink.button a, a.toplink {
  display: inline-block;
  font-family: var(--sans);
  font-size: var(--label);
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--ink);
  padding: 0.85em 1.6em;
  border: 1px solid var(--rule-strong);
  transition: background .3s, color .3s, border-color .3s;
}
.btn:hover, .ce_hyperlink.button a:hover, a.toplink:hover {
  background: var(--ink);
  color: var(--bg);
  border-color: var(--ink);
}

.ce_downloads ul { list-style: none; padding: 0; margin: 0; }
.download-element {
  border-top: 1px solid var(--rule);
  padding: 0.9em 0;
}
.download-element a { display: flex; justify-content: space-between; gap: 1em; }
.download-element .size { color: var(--ink-faint); font-size: 0.85em; }

/* Tables */
td, th {
  text-align: left; vertical-align: top;
  padding: 0.6em 1.2em 0.6em 0;
  border-top: 1px solid var(--rule);
}
th { font-weight: 500; }

/* -------------------------------------------------------------------------
   11. Footer
   ---------------------------------------------------------------------- */
#footer {
  flex-shrink: 0;
  background: var(--bg-raised);
  border-top: 1px solid var(--rule);
}
#footer .inside {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.25rem 2rem;
  max-width: var(--content);
  margin-inline: auto;
  padding: clamp(2rem, 4vw, 3rem) var(--gap);
}
.nav-footer ul { display: flex; flex-wrap: wrap; gap: clamp(1.25rem, 3vw, 2.5rem); }
.nav-footer a,
.nav-footer strong {
  font-family: var(--sans);
  font-size: var(--label);
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--ink-dim);
  transition: color .3s;
}
.nav-footer a:hover { color: var(--ink-bright); }
.nav-footer .active,
.nav-footer strong { color: var(--ink); }
#footer .copyright {
  font-family: var(--sans);
  font-size: var(--label);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
  white-space: nowrap;
}

/* -------------------------------------------------------------------------
   12. Lightbox tuning (GLightbox) — a dark, chromeless viewing room.
   ---------------------------------------------------------------------- */
.glightbox-clean .gslide-description { background: var(--bg-raised); }
.glightbox-clean .gslide-title {
  font-family: var(--serif);
  color: var(--ink);
}
.glightbox-clean .gslide-desc {
  font-family: var(--sans);
  color: var(--ink-dim);
}
.gbtn { color: var(--ink-dim) !important; }
.goverlay { background: rgba(10, 9, 7, 0.96) !important; }
.gslide-image img { box-shadow: var(--shadow); }

/* -------------------------------------------------------------------------
   13. Curated reveal — works fade up as they enter the room.
   No-JS and reduced-motion users simply see everything.
   ---------------------------------------------------------------------- */
/* No `will-change` here: the drawings page carries 38 of these, and a standing
   hint would promote every one of them to its own compositor layer for a
   one-shot fade. The browser promotes what it needs for the duration of the
   transition on its own. */
.js .pw-reveal {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 1s ease, transform 1s cubic-bezier(.2,.7,.2,1);
}
.js .pw-reveal.is-visible { opacity: 1; transform: none; }

/* The CV's pictures are part of the document, not an entrance: the portrait
   heads the page and the plate thumbnails sit in the left column beside the
   entries they belong to, so fading them in would read as a slideshow of the
   man's own CV. The typed entries beside them still arrive like every other
   page's prose — this exempts the images, not the vita. */
.js .mod_article.vita .ce_image.pw-reveal,
.js .mod_article.vita .ce_gallery .pw-reveal {
  opacity: 1;
  transform: none;
  transition: none;
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .001ms !important; transition-duration: .001ms !important; }
  .js .pw-reveal { opacity: 1; transform: none; }
  html { scroll-behavior: auto; }
}

/* -------------------------------------------------------------------------
   14. Responsive — small screens
   The header stays fixed on top at every width; the burger opens the same
   off-canvas sidebar. Only the wordmark eases down a touch to fit the bar.
   ---------------------------------------------------------------------- */
@media (max-width: 820px) {
  a#logo { font-size: 2rem; }
}

@media (max-width: 540px) {
  .galerie-vita figure { grid-template-columns: 6rem 1fr; gap: 1.1rem; }
  .ce_gallery.vollbild li + li { padding-top: clamp(7rem, 33vw, 11rem); }
}

/* -------------------------------------------------------------------------
   15. Utilities, accessibility, print
   ---------------------------------------------------------------------- */
.invisible, .fe-unsichtbar, .screen-reader-text {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--ink); color: var(--bg);
  padding: 0.6em 1em; font-family: var(--sans); font-size: var(--label);
  letter-spacing: var(--track); text-transform: uppercase;
}
.skip-link:focus { left: 1rem; top: 1rem; }
.clear { clear: both; }

@media print {
  #header, #footer, .nav-sidebar, .nav-backdrop { display: none !important; }
  body { background: #fff; color: #000; }
  .ce_gallery img, .mod_article.vita img { filter: none; }
}
