/* Convenium Landing Template — kit.css. Shared by every category: never fork it per category.
   Reads only the semantic theme tokens (inlined per page) and the fixed brand constants below.
   Responsive since 2026-09-23 (V3). Breakpoints, used everywhere below and nowhere else:
     phone  < 640 · tablet 640–1023 · laptop 1024–1439 · desktop 1440–1919 · wide ≥ 1920
   Pins, the loader and the 3D floaters run from laptop up (min-width: 1024px) with motion allowed.
   Text columns keep their own ch caps at every width; only media and the footer wordmark grow. */
:root {
  /* Brand constants: the fixed frame (loader, outro, footer, lockup type). Never themed. */
  --brand-noir: #1B1717;
  --brand-cotton: #EDEBDD;
  --brand-chili: #D73B3E;
  --brand-gray-on-noir: #A8A29A;
  --font-brand: Archivo, "Arial Black", Arial, sans-serif;
  --font-brand-serif: Newsreader, Georgia, "Times New Roman", serif;
  --font-brand-sans: Inter, "Helvetica Neue", Arial, sans-serif;

  /* Theme tokens: defaults are Convenium's own; the inlined theme overrides them per category. */
  --ground: #EDEBDD;
  --surface: #F5F3E8;
  --ink: #241F1F;
  --muted: #6E6963;
  --rule: #D6D2C2;
  --accent: #810100;
  --accent-deep: #630000;
  --on-accent: #EDEBDD;
  --ring: #D73B3E;
  --ring-on-accent: #EDEBDD;
  --font-sans: var(--font-brand-sans);
  --font-serif: var(--font-brand-serif);

  /* Rhythm: fixed for every category (repetition). */
  --max: 1360px;
  --gutter: 48px;
  --section: 112px;
  --gap: 24px;
  --header-h: 96px;
}
@media (min-width: 1600px) { :root { --max: 1600px; --gutter: 64px; --section: 136px; } }
@media (min-width: 1920px) { :root { --max: 1760px; --gutter: 72px; --section: 152px; } }
@media (max-width: 1023px) { :root { --gutter: 32px; --section: 88px; --header-h: 88px; } }
@media (max-width: 639px)  { :root { --gutter: 20px; --section: 64px; --header-h: 72px; } }

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
/* Deliberately no `scroll-behavior: smooth`. GSAP's own ScrollTrigger docs warn against combining it
   with scroll-driven pins: the browser's native smooth-scroll interpolates scrollY on its own timer,
   racing ScrollTrigger's rAF-driven updates to the pinned, position:fixed hero/cut stages — on a long
   jump (e.g. the "back to top" link from deep in the page) this can paint a stale, overlapping frame
   of the fixed stage on top of whatever section the native animation is mid-scrolling through. The
   That rule still stands, and Lenis below does not reintroduce it: every programmatic jump in kit.js
   goes through `lenis.scrollTo(..., { immediate: true })`, so anchor navigation stays instant.

   DECISION REVERSED 2026-09-21 (user). This block previously read "the project's own decision was
   already 'one scroll engine, no Lenis'". The hero scrubs 180 canvas frames across 300vh — ~15px of
   scroll per frame — and on native wheel input (~100px per detent) that advances ~7 frames a tick,
   which reads as the scrub stepping or sticking rather than moving. Lenis interpolates the wheel
   input into continuous sub-pixel scroll and hands ScrollTrigger the update from its own rAF: one
   engine driving one timeline, not two engines racing (which is what `scroll-behavior: smooth` was).
   It is initialised only under `prefers-reduced-motion: no-preference` and torn down with its
   matchMedia context. */

/* Lenis's own required rules (v1.1.18, vendored in kit/vendor/). Kept inline rather than vendoring a
   second stylesheet for three declarations. `.lenis-stopped` is unused today but is part of the
   contract if the mobile menu ever needs to lock scroll. */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-stopped { overflow: hidden; }
body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font: 400 17px/1.55 var(--font-sans);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img { display: block; max-width: 100%; }
a { color: inherit; }
h1, h2, h3, p, ol, ul, figure { margin: 0; }
h1, h2, h3 { font-weight: 400; }
em { font-family: var(--font-serif); font-style: italic; font-weight: 400; }
button { font: inherit; color: inherit; }

/* Focus ring: a spacer that matches the ground behind the control, then the ring.
   The transparent outline keeps forced-colours mode visible. */
body { --ring-ground: var(--ground); --ring-color: var(--ring); }
.process, .composer, .site-header, .mobile-menu, .demo-note, .chapter { --ring-ground: var(--surface); }
.collection { --ring-ground: var(--accent); --ring-color: var(--ring-on-accent); }
.outro, .site-footer { --ring-ground: var(--brand-noir); --ring-color: var(--brand-chili); }
:focus-visible { outline: 2px solid transparent; outline-offset: 2px; box-shadow: 0 0 0 2px var(--ring-ground), 0 0 0 4px var(--ring-color); }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.js .nojs-only { display: none !important; }
.no-js .js-only { display: none !important; }
[data-motion="reduced"] .motion-toggle, [data-motion="unavailable"] .motion-toggle { display: none; }

.skip {
  position: absolute; left: var(--gutter); top: -120px; z-index: 300;
  background: var(--brand-noir); color: var(--brand-cotton); padding: 14px 20px;
  border-radius: 999px; text-decoration: none; font-weight: 500;
}
.skip:focus { top: 12px; }

section[id], [id="anfrage-title"] { scroll-margin-top: calc(var(--header-h) + 8px); }
.wrap { width: min(var(--max), calc(100% - 2 * var(--gutter))); margin-inline: auto; }

.label {
  display: block; margin-bottom: 24px;
  font: 500 12px/1.3 var(--font-sans); letter-spacing: .08em; text-transform: uppercase; color: var(--accent);
}
.caption { font: 500 12px/1.3 var(--font-sans); letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
h2 { font-size: clamp(36px, 3.6vw, 72px); line-height: 1.06; letter-spacing: -.035em; }
h2 em { letter-spacing: -.015em; }
h3 { font-size: clamp(22px, 1.5vw, 30px); line-height: 1.2; letter-spacing: -.02em; }

/* ---------- Buttons & links ---------- */
.pill {
  display: inline-flex; align-items: center; justify-content: center; gap: 12px;
  min-height: 48px; padding: 0 24px; border-radius: 999px; border: 1px solid transparent;
  font: 500 15px/1.1 var(--font-sans); text-decoration: none; cursor: pointer; white-space: nowrap;
}
.pill--accent { background: var(--accent); color: var(--on-accent); }
.pill--accent:hover { background: var(--accent-deep); }
.pill--light { background: var(--surface); color: var(--ink); border-color: var(--rule); }
.text-link {
  display: inline-flex; align-items: center; gap: 10px; min-height: 44px;
  font: 500 15px/1.2 var(--font-sans); color: var(--ink);
  text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 6px;
}
.text-link:hover { color: var(--accent); }
.arrow { display: inline-block; }

/* ---------- Loader: the preload is part of the show (brand constant) ----------
   Only shown where the pinned sequence runs; kit.js wipes it away at 100% (or after 6s at most). */
.loader { display: none; }
@media (min-width: 1024px) and (prefers-reduced-motion: no-preference) {
  .pin-ready .loader {
    position: fixed; inset: 0; z-index: 250; display: flex; align-items: flex-end; justify-content: space-between;
    padding: 40px var(--gutter); background: var(--brand-noir); color: var(--brand-cotton);
  }
  .pin-ready .loader[hidden] { display: none; }
}
.loader-brand { font: 900 22px/1 var(--font-brand); letter-spacing: -.045em; }
.loader-brand span { color: var(--brand-chili); }
.loader-pct {
  font: 900 clamp(120px, 16vw, 300px)/.78 var(--font-brand); letter-spacing: -.05em; font-variant-numeric: tabular-nums;
  display: inline-block; min-width: 3.4ch; text-align: right; /* reserves width for "100%" so the digit growing 0->100 never shifts the box */
}
.loader-pct small { font-size: .3em; letter-spacing: 0; margin-left: .08em; color: var(--brand-gray-on-noir); }

/* ---------- Floating header (identical on every page) ---------- */
.site-header {
  position: fixed; z-index: 50; top: 24px; left: 32px; right: 32px;
  display: flex; align-items: center; gap: 10px; pointer-events: none;
  transition: transform .45s cubic-bezier(.2, .7, .2, 1);
}
/* Scrolling down tucks the header away so it never sits on top of section copy; scrolling up brings it
   back (kit.js). Transform only; it never hides while the menu is open or focus is inside it. */
.site-header.is-hidden { transform: translateY(calc(-100% - 32px)); }
@media (prefers-reduced-motion: reduce) { .site-header { transition: none; } }
@media (max-width: 639px) { .site-header { top: 12px; left: 12px; right: 12px; } }
.site-header > * { pointer-events: auto; }
.brand {
  display: inline-flex; align-items: center; min-height: 48px; padding: 0 22px; margin-right: auto;
  background: var(--surface); border: 1px solid var(--rule); border-radius: 999px;
  font: 900 22px/1 var(--font-brand); letter-spacing: -.045em; color: var(--ink); text-decoration: none;
}
.brand span { color: var(--accent); }
.nav-capsule {
  display: flex; align-items: center; gap: 2px; min-height: 48px; padding: 0 6px;
  background: var(--surface); border: 1px solid var(--rule); border-radius: 999px;
}
.nav-capsule a {
  display: inline-flex; align-items: center; min-height: 40px; padding: 0 14px; border-radius: 999px;
  font: 500 14px/1 var(--font-sans); text-decoration: none;
}
.nav-capsule a:hover { background: var(--ground); }
/* Surface edge keeps the accent pill legible when it floats over the accent collection. */
.header-cta { border-color: var(--surface); }
.locale { display: inline-flex; align-items: center; margin-left: 4px; padding-left: 4px; border-left: 1px solid var(--rule); }
.locale a { padding: 0 10px; }
.locale a[aria-current] { color: var(--accent); }
.menu-toggle { display: none; }
.mobile-menu {
  position: absolute; top: calc(100% + 8px); left: 0; right: 0;
  background: var(--surface); border: 1px solid var(--rule); border-radius: 20px; padding: 8px 16px 16px;
}
.mobile-menu a:not(.pill) {
  display: flex; align-items: center; justify-content: space-between; min-height: 56px;
  border-bottom: 1px solid var(--rule); font: 400 22px/1.2 var(--font-sans); letter-spacing: -.02em; text-decoration: none;
}
.mobile-menu .menu-locale { display: flex; gap: 8px; padding: 12px 0; font-size: 15px; }
.mobile-menu .menu-locale a:not(.pill) { min-height: 44px; font-size: 15px; border: 0; padding: 0 6px; }
.mobile-menu .menu-locale a[aria-current] { color: var(--accent); }
.mobile-menu .pill { width: 100%; font-size: 16px; }
@media (max-width: 1023px) {
  .nav-capsule, .header-cta { display: none; }
  .menu-toggle { display: inline-flex; }
  .no-js .nav-capsule { display: flex; }
}

/* ---------- Scroll hero: image-sequence scrub with three chapters ----------
   Static state (no-JS, reduced motion, before sign-off of other widths): the first frame full-bleed with
   the intro panel over its quiet lower-left, and the two statements as a block beneath.
   Pinned state (.pin-ready, desktop, motion allowed): the stage holds for 300% of the viewport while
   kit.js scrubs the frames and crossfades the chapters; the distance is reserved here, before paint. */
.hero { position: relative; background: var(--ground); }
.hero-stage { position: relative; }
/* One wrapper for everything the stage shows (same containing box as the stage itself). */
.hero-slide { position: relative; }
.hero-visual { position: relative; aspect-ratio: 16 / 9; max-height: 100svh; width: 100%; overflow: hidden; background: var(--surface); transform-origin: 60% 55%; }
.hero-poster, .hero-canvas { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.hero-canvas { opacity: 0; }   /* kept in layout (not display:none) so it measures a real size before the first paint */
.seq-live .hero-canvas { opacity: 1; }
.seq-live .hero-poster { opacity: 0; }   /* stays in the accessibility tree; the canvas is aria-hidden */

.chapter { background: var(--ground); border-radius: 4px; }
.chapter--intro {
  position: absolute; z-index: 2; left: var(--gutter); bottom: clamp(48px, 7vh, 96px);
  width: min(700px, calc(100% - 2 * var(--gutter))); padding: 40px 44px 44px;
}
.hero h1 { font-size: clamp(56px, 4.4vw, 92px); line-height: 1.02; letter-spacing: -.045em; margin: 4px 0 24px; }
.hero h1 em { color: var(--accent); letter-spacing: -.025em; }
.line { display: block; overflow: hidden; white-space: nowrap; padding: 0 .14em .1em 0; margin-bottom: -.1em; }
.line-inner { display: inline-block; }
.hero-body { max-width: 46ch; font-size: 18px; margin-bottom: 32px; }
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 28px; }

.hero-statements { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap); width: min(var(--max), calc(100% - 2 * var(--gutter))); margin: 0 auto; padding: var(--section) 0; }
.chapter--statement { padding: 0; background: none; }
.chapter-text { font: 400 clamp(32px, 2.5vw, 52px)/1.14 var(--font-serif); letter-spacing: -.012em; max-width: 22ch; text-wrap: balance; }

@media (min-width: 1024px) and (prefers-reduced-motion: no-preference) {
  /* Reserve must equal the pin range (+=300%) exactly. This is not additive with the stage's own
     100vh: with pinSpacing:false, GSAP still tracks the pinned element's reverted (unpinned) position
     internally as if a real spacer of height (end-start) existed. Reserving anything less than that
     (e.g. subtracting the stage's own height, on the theory that the fixed stage "already covers" that
     span) breaks GSAP's own bookkeeping for the moment the pin releases: the stage renders relative to
     the WRONG offset once back in normal flow, landing on top of the next section instead of scrolling
     out of view above it. Confirmed by reproduction: a continuous scroll (real wheel or synthetic,
     unlike a discrete scrollTo jump) shows the hero canvas/rail/counter still on screen, overlapping
     the pair portraits, once padding-bottom was reduced below the full pin range. Always match this to
     hero-pin's `end` value in kit.js. */
  .pin-ready .hero { padding-bottom: 300vh; }

  /* The stage's own 100vh is still in normal flow after the pin releases, and by then it holds
     nothing the user can see (hero-pin's onLeave fades it to opacity 0). Left alone that is one dead
     viewport of bare --ground between the hero and the pair portraits — measured 2026-09-21 at
     1440x900: blank from scrollY 2700 to 3600. Pull the next section up by exactly that height so the
     fading stage reveals `.worlds` instead of nothing. The padding-bottom reserve above is NOT
     touched — GSAP's reverted-position bookkeeping depends on it and only on it; this is a margin on
     the section, which the pin does not read. See the matching block on `.cut` below. */
  .pin-ready .hero { margin-bottom: -100vh; }
  .pin-ready .worlds { position: relative; z-index: 1; }
  .pin-ready .hero-stage { z-index: 2; }
  /* Let clicks through only once the pin has actually released — while the stage is up, `.worlds`
     sits behind it and a click would otherwise reach an invisible portrait link. Driven by the
     is-cleared class in kit.js (onRefresh + onLeave + onEnterBack). */
  .pin-ready .hero-stage.is-cleared { pointer-events: none; }

  .pin-ready .hero-stage { height: 100vh; overflow: hidden; }
  .pin-ready .hero-slide { position: absolute; inset: 0; }
  .pin-ready .hero-visual { position: absolute; inset: 0; aspect-ratio: auto; max-height: none; }
  .pin-ready .hero-statements { position: absolute; inset: 0; display: block; width: auto; padding: 0; margin: 0; pointer-events: none; }
  .pin-ready .chapter--statement {
    position: absolute; left: var(--gutter); bottom: clamp(48px, 7vh, 96px); width: min(700px, calc(100% - 2 * var(--gutter)));
    padding: 36px 44px 40px; background: var(--ground);
  }
}

/* ---------- Pair ("two worlds"), with silent loop portraits ----------
   Both portraits fit one screen whole: the frame is the source's own 4:5 (no crop), its height is what
   the viewport leaves after the label, the stagger and the titles, and its width follows. On a fine
   pointer the hovered portrait comes alive (loop video + tilt) while the other steps back (kit.js). */
.worlds { position: relative; padding: var(--section) 0; }
.worlds .label { text-align: center; margin-bottom: 48px; }
.worlds-grid {
  --ph: clamp(320px, calc(100svh - 380px), 780px);
  --wgap: clamp(24px, 5vw, 112px);
  display: grid; justify-content: center; gap: var(--wgap);
  grid-template-columns: repeat(2, min(calc(var(--ph) * .8), calc((100% - var(--wgap)) / 2)));
}
.world:nth-child(2) { padding-top: 48px; }
.world-mask { position: relative; overflow: hidden; aspect-ratio: 4 / 5; background: var(--surface); border-radius: 2px; }
.world-mask img { width: 100%; height: 100%; object-fit: cover; transform-origin: 50% 40%; }
.world-video, .pano-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity .8s ease; pointer-events: none; }
.world-video.is-playing, .pano-video.is-playing { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .world-video, .pano-video { display: none; } }
/* Only the photo steps back — the sibling's title and text keep full contrast. */
.world-mask { transition: opacity .5s ease; }
.worlds-grid.is-hovering .world:not(.is-hover) .world-mask { opacity: .55; }
@media (prefers-reduced-motion: reduce) { .world-mask { transition: none; } }
.world h3 { margin: 24px 0 8px; }
.world p { color: var(--muted); max-width: 36ch; }
.worlds-foot { display: grid; justify-items: center; gap: 10px; margin-top: 64px; text-align: center; }
.worlds-foot p:first-child { font-size: 17px; }
@media (max-width: 639px) {
  .worlds-grid { grid-template-columns: minmax(0, 420px); }
  .world:nth-child(2) { padding-top: 0; }
}

/* ---------- The cut: object glides across, draws a cut, the page opens onto the collection ----------
   Static state: a titled band with the object and a rule. Pinned state: two halves over the accent
   ground; kit.js moves the object, draws the line and parts the halves. */
.cut { position: relative; background: var(--accent); }
.cut-stage { position: relative; overflow: hidden; background: var(--surface); }
.cut-half { position: relative; z-index: 1; background: var(--surface); }
.cut-half--top { padding: var(--section) 0 40px; }
.cut-half--bottom { padding: 40px 0 var(--section); }
.cut-copy h2 { max-width: 16ch; }
.cut-text { max-width: 48ch; font-size: 19px; color: var(--muted); }
.cut-line { position: relative; z-index: 2; display: block; height: 1px; margin: 0 var(--gutter); background: var(--ink); }
.cut-object { position: absolute; z-index: 3; right: var(--gutter); top: 50%; width: min(460px, 30vw); height: auto; transform: translateY(-50%) rotate(52deg); pointer-events: none; }

@media (min-width: 1024px) and (prefers-reduced-motion: no-preference) {
  /* No manual padding-bottom reserve here (unlike the hero): cut-pin uses pinSpacing:true, so GSAP
     inserts its own spacer sized to exactly the pin's range.

     What the previous version of this comment got wrong: it claimed `.collection` "sits immediately
     after with nothing extra to scroll past once the pin releases". It does not. GSAP's spacer covers
     the pin's RANGE; the stage's own 100vh is still in normal flow after the release, and the halves
     have finished parting by progress ~0.98 — so that 100vh is a dead viewport of flat --accent, the
     same colour as `.collection`, reading as one frozen frame. Measured 2026-09-21 at 1440x900:
     scrollY 5875 to 6775, solid red, nothing in it.

     Fix: pull `.collection` up by exactly the stage height so the parting halves reveal the collection
     itself — which is what the section's whole metaphor promises. The pull lives on `.cut` rather than
     on `.collection` so it cannot exist for a category that renders no cut section (render.mjs only
     emits `.cut` when the category has a cutObject). ScrollTrigger's pin-spacer copies the PINNED
     element's margins (`.cut-stage`, which has none), not the section's, so a margin here is invisible
     to the pin. */
  .pin-ready .cut { margin-bottom: -100vh; }

  /* Paint order, in the ROOT stacking context. All three lines are load-bearing:
       .cut        z-index:auto (unchanged)  — its accent background paints below .collection
       .collection z-index:1                 — covers .cut's background where they overlap
       .cut-stage  z-index:2                 — the cover paints above .collection, and becomes the
                                               stacking context holding .cut-half/.cut-line/.cut-object
                                               (z 1/2/3 above)
     Do NOT give `.cut` a z-index. That makes it a stacking context, traps `.cut-stage` inside it below
     `.collection`, and then forces `background: transparent` on `.cut` — which exposes a ~16px band of
     cotton --ground across the top of the viewport in the last frames of the part. `.cut` keeps its
     accent background so the field behind the halves is continuous above and below the overlap seam.
     Conversely, WITHOUT z-index:2 on `.cut-stage`, `.cut-half` (z-index 1) ties with `.collection`
     (z-index 1) and loses on DOM order — the cover stops covering. */
  .pin-ready .collection { position: relative; z-index: 1; }
  .pin-ready .cut-stage { z-index: 2; }

  /* See the hero's is-cleared note. Here it matters more: while the cover is up, `.collection` sits
     behind it and a click on an apparently blank half would reach an invisible concept link.
     The `.pin-spacer` selector is not belt-and-braces — with pinSpacing:true GSAP wraps the stage in
     its own spacer div, and that div is the box that overlaps `.collection`. A block element hit-tests
     across its whole box whether or not it paints anything, so without this the spacer swallowed every
     click on the first viewport of cards (qa-1920's concept-select check caught it). kit.js toggles
     is-cleared on the spacer alongside the stage. */
  .pin-ready .cut-stage.is-cleared,
  .pin-ready .pin-spacer.is-cleared { pointer-events: none; }

  /* section[id] carries scroll-margin-top: calc(var(--header-h) + 8px) = 104px. With `.collection` now
     starting at cut-pin's end, that offset would land every #kollektion jump 104px INSIDE the pin
     range — at progress 0.87, on a half-parted cover. #kollektion is the hero's primary CTA plus the
     header nav and the mobile menu. Land at the pin's end instead. */
  .pin-ready .cut + .collection { scroll-margin-top: 0; }

  .pin-ready .cut-stage { height: 100vh; background: transparent; }
  .pin-ready .cut-half { position: absolute; left: 0; right: 0; display: flex; padding: 0; }
  .pin-ready .cut-half--top { top: 0; height: 50%; align-items: flex-end; padding-bottom: 56px; }
  .pin-ready .cut-half--bottom { bottom: 0; height: 50%; align-items: flex-start; padding-top: 56px; }
  .pin-ready .cut-line { position: absolute; left: 0; right: 0; top: 50%; margin: 0; height: 2px; transform-origin: 100% 50%; }
  .pin-ready .cut-object { left: 50%; right: auto; top: 50%; margin: calc(min(460px, 30vw) / -2) 0 0 calc(min(460px, 30vw) / -2); transform: rotate(52deg); }
}

/* ---------- Collection (accent field) ---------- */
.collection { background: var(--accent); color: var(--on-accent); padding: var(--section) 0; }
.collection .label { color: var(--on-accent); }
.collection-head { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: var(--gap); align-items: end; margin-bottom: 72px; }
.collection-head p { max-width: 44ch; font-size: 18px; }
/* At most two per row: the track floor is half the row less half the largest gap, so a third never fits
   and four examples read as a 2x2, not three plus an orphan. */
.concepts { display: grid; grid-template-columns: repeat(auto-fit, minmax(max(min(100%, 420px), calc(50% - 28px)), 1fr)); gap: clamp(24px, 3vw, 56px); }
.concept-frame { overflow: hidden; border-radius: 4px; background: var(--brand-noir); aspect-ratio: 1440 / 1000; }
.concept-img { width: 100%; height: auto; transform-origin: 50% 30%; }
.concept-meta { padding-top: 24px; }
.concept-title { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 8px 16px; }
.concept h3 { font-size: clamp(26px, 2vw, 38px); letter-spacing: -.03em; }
.concept .status { font: 500 12px/1.3 var(--font-sans); letter-spacing: .08em; text-transform: uppercase; }
.concept-desc { margin: 14px 0 24px; max-width: 46ch; }
.concept-actions { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 4px 24px; border-top: 1px solid var(--on-accent); padding-top: 8px; }
.concept-actions a { display: inline-flex; align-items: center; gap: 10px; min-height: 48px; font: 500 15px/1.2 var(--font-sans); color: var(--on-accent); text-decoration: none; }
.concept-actions a:hover span:first-child,
.concept.is-selected .choose span:first-child { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 6px; }

/* ---------- Craft: split one-screen chapter (copy left, tall media right) ----------
   Rejected for this section: the full-bleed panorama with an overlay card — it repeats the hero. */
.craft { position: relative; padding: var(--section) 0; }
.craft-grid { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: clamp(48px, 6vw, 128px); align-items: center; }
.craft-copy { max-width: 620px; }
.craft-intro { max-width: 44ch; margin-top: 24px; font-size: 18px; color: var(--muted); }
.craft-media { margin: 0; }
.pano { position: relative; overflow: hidden; height: min(84svh, 900px); min-height: 440px; background: var(--surface); border-radius: 2px; }
.pano-depth { position: absolute; left: 0; right: 0; top: -6%; height: 112%; }
.pano-depth img { width: 100%; height: 100%; object-fit: cover; object-position: var(--pano-pos, 38% 55%); }
.pano-video { object-position: 38% 55%; }
.pano-caption { margin-top: 16px; }
.rows { list-style: none; padding: 0; display: grid; margin-top: 48px; }
.rows li { display: grid; grid-template-columns: 56px minmax(0, 1fr); column-gap: 8px; border-top: 1px solid var(--rule); padding: 22px 0; }
.rows li:last-child { border-bottom: 1px solid var(--rule); }
.rows .num { grid-row: span 2; margin: 6px 0 0; }
.rows h3 { font-size: clamp(20px, 1.3vw, 26px); }
.rows p { color: var(--muted); margin-top: 6px; max-width: 40ch; }
.num { display: block; font: 500 12px/1.3 var(--font-sans); letter-spacing: .08em; color: var(--accent); margin-bottom: 28px; }
.steps li { padding-top: 24px; }
.steps p { color: var(--muted); margin-top: 12px; max-width: 36ch; }
@media (max-width: 1023px) {
  .craft-grid { grid-template-columns: minmax(0, 1fr); gap: 40px; }
  .craft-media { order: -1; }
  .craft-copy { max-width: none; }
  .pano { height: auto; min-height: 0; aspect-ratio: 16 / 10; }
}
@media (max-width: 639px) { .pano { aspect-ratio: 4 / 5; } }

/* ---------- Why: found first, then booked ----------
   One sourced figure on the accent ground, then five services as open columns under a rule. The
   figure is the only number on the section, and it carries its source and what it is not. */
.why { position: relative; padding: var(--section) 0; }
.why-head { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: var(--gap); align-items: end; margin-bottom: 72px; }
.why-head p { max-width: 44ch; font-size: 18px; color: var(--muted); }
.why-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(32px, 3vw, 56px) clamp(24px, 2.4vw, 48px); }
.why-stat { --ring-ground: var(--accent); --ring-color: var(--ring-on-accent); display: flex; flex-direction: column; gap: 20px; margin: 0; padding: clamp(24px, 2.4vw, 40px); background: var(--accent); color: var(--on-accent); border-radius: 4px; }
.why-stat-value { font-size: clamp(64px, 6vw, 112px); line-height: .9; letter-spacing: -.05em; font-variant-numeric: tabular-nums; }
.why-stat-text { max-width: 30ch; font-size: 18px; }
.why-stat figcaption { margin-top: auto; font-size: 13px; }
.why-stat a { color: inherit; text-underline-offset: 4px; }
.why-item { padding-top: 24px; border-top: 1px solid var(--rule); }
.why-name { display: flex; align-items: baseline; gap: 12px; font: 500 12px/1.3 var(--font-sans); letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.why-name .num { margin: 0; }
.why-item h3 { margin-top: 20px; font-size: clamp(24px, 1.7vw, 32px); line-height: 1.1; letter-spacing: -.03em; }
.why-item > p:last-child { max-width: 40ch; margin-top: 12px; color: var(--muted); }
.why-foot { max-width: 64ch; margin-top: 56px; font-size: 18px; }
@media (max-width: 1023px) { .why-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 639px) {
  .why-grid { grid-template-columns: minmax(0, 1fr); gap: 32px; }
  .why-stat-value { font-size: 64px; }
  .why-foot { margin-top: 32px; font-size: 16px; }
}

/* ---------- Process ---------- */
.process { position: relative; background: var(--surface); padding: var(--section) 0; }
.process-head { margin-bottom: 72px; }
.process-head p { max-width: 48ch; font-size: 18px; color: var(--muted); margin-top: 20px; }
/* A single connected track replaces each step's own border-top rule: one line the reveal fills
   left to right (a "from conversation to appearance" progress read), with a dot per step marking
   where the accent has reached. */
.process-track { position: relative; height: 2px; background: var(--rule); margin-bottom: 32px; }
.process-track-fill { position: absolute; inset: 0; background: var(--accent); transform: scaleX(0); transform-origin: 0 50%; }
.steps { list-style: none; padding: 0; display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--gap); }
.steps li { border-top: none; padding-top: 24px; position: relative; }
.step-media { overflow: hidden; aspect-ratio: 4 / 3; margin-bottom: 28px; background: var(--ground); border-radius: 2px; }
.step-media img { width: 100%; height: 100%; object-fit: cover; }
.steps-caption { margin-top: 40px; }
.inquiry-media figcaption { margin-top: 12px; }
.steps li::before {
  content: ""; position: absolute; top: -37px; left: 0; width: 10px; height: 10px; border-radius: 50%;
  background: var(--surface); border: 2px solid var(--accent);
}

/* ---------- Packages ----------
   Three priced tiers, optional per category. The featured tier takes the accent ground (on-accent
   text, the collection's pairing); the others sit on the surface like the composer. They are
   "from" prices: the copy carries that, and nothing here may read as a discount or a struck price.
   Every card is a column whose list grows, so price rules and the choose link align across a row. */
.packages { position: relative; padding: var(--section) 0; }
.packages-head { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: var(--gap); align-items: end; margin-bottom: 72px; }
.packages-head p { max-width: 44ch; font-size: 18px; color: var(--muted); }
.plans { list-style: none; padding: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(16px, 1.6vw, 28px); }
.plan { --ring-ground: var(--surface); display: flex; flex-direction: column; padding: clamp(24px, 2.4vw, 40px); background: var(--surface); border: 1px solid var(--rule); border-radius: 4px; }
.plan--featured { --ring-ground: var(--accent); --ring-color: var(--ring-on-accent); background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.plan.is-selected { outline: 2px solid var(--ink); outline-offset: 3px; }
.plan-head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-start; gap: 12px 16px; }
.plan h3 { display: grid; gap: 14px; }
.plan-name { font: 500 12px/1.3 var(--font-sans); letter-spacing: .08em; text-transform: uppercase; color: var(--accent); }
.plan-title { font-size: clamp(26px, 2vw, 38px); line-height: 1.1; letter-spacing: -.03em; }
.plan-badge { padding: 8px 12px; border: 1px solid currentColor; border-radius: 999px; font: 500 12px/1 var(--font-sans); letter-spacing: .08em; text-transform: uppercase; white-space: nowrap; }
.plan-for { max-width: 34ch; margin-top: 14px; color: var(--muted); }
.plan-price { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; margin-top: 32px; padding-top: 24px; border-top: 1px solid var(--rule); }
.plan-from { font: 500 15px/1 var(--font-sans); }
.plan-amount { font-size: clamp(40px, 3.4vw, 60px); line-height: 1; letter-spacing: -.04em; font-variant-numeric: tabular-nums; }
.plan-unit { flex-basis: 100%; font-size: 14px; color: var(--muted); }
.plan-monthly { margin-top: 10px; font: 500 15px/1.4 var(--font-sans); }
.plan-includes { flex: 1 1 auto; list-style: none; padding: 0; margin: 28px 0 0; }
.plan-includes li { position: relative; padding: 12px 0 12px 28px; border-top: 1px solid var(--rule); font-size: 15px; line-height: 1.45; }
.plan-includes li::before {
  content: ""; position: absolute; left: 2px; top: 18px; width: 11px; height: 6px;
  border-left: 1.5px solid var(--accent); border-bottom: 1.5px solid var(--accent); transform: rotate(-45deg);
}
.plan-choose { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 48px; margin-top: 24px; padding-top: 8px; border-top: 1px solid currentColor; font: 500 15px/1.2 var(--font-sans); color: inherit; text-decoration: none; }
.plan-choose:hover span:first-child,
.plan.is-selected .plan-choose span:first-child { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 6px; }
.plan--featured .plan-name, .plan--featured .plan-for, .plan--featured .plan-unit { color: var(--on-accent); }
.plan--featured .plan-price, .plan--featured .plan-includes li { border-color: var(--on-accent); }
.plan--featured .plan-includes li::before { border-color: var(--on-accent); }
.plan--featured.is-selected { outline-color: var(--accent); }
.plans-note { max-width: 96ch; margin-top: 32px; font-size: 14px; color: var(--muted); }
@media (max-width: 1023px) {
  .plans { grid-template-columns: minmax(0, 1fr); max-width: 640px; }
}

/* ---------- Builder: pick services, see the "from" total ----------
   The list is a form of native checkboxes (keyboard, screen readers and forced colours for free);
   the summary sticks beside it on desktop and follows it below. Nothing is sent: the selection
   lives in the URL and flows into the inquiry draft. */
.builder { --ring-ground: var(--surface); position: relative; padding: var(--section) 0; background: var(--surface); }
.builder-head { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: var(--gap); align-items: end; margin-bottom: 72px; }
.builder-head p { max-width: 44ch; font-size: 18px; color: var(--muted); }
.builder h2[tabindex]:focus:not(:focus-visible) { outline: none; }
.builder-nojs { max-width: 72ch; margin-bottom: 32px; padding: 16px 18px; border-left: 2px solid var(--accent); background: var(--ground); font-size: 15px; }
.builder-grid { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: clamp(32px, 4vw, 80px); align-items: start; }
.svc-group { min-width: 0; margin: 0; padding: 0; border: 0; }
.svc-group + .svc-group { margin-top: 48px; }
.svc-group legend { margin-bottom: 12px; padding: 0; font: 500 12px/1.3 var(--font-sans); letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.svc { border-top: 1px solid var(--rule); }
.svc:last-child { border-bottom: 1px solid var(--rule); }
.svc-main { display: grid; grid-template-columns: 24px minmax(0, 1fr) auto; gap: 4px 18px; align-items: start; padding: 20px 0 4px; cursor: pointer; }
.svc-main input { width: 22px; height: 22px; margin: 3px 0 0; accent-color: var(--accent); cursor: pointer; }
.svc-name { display: block; font: 500 19px/1.3 var(--font-sans); }
.svc.is-on .svc-name { color: var(--accent); }
.svc-why { display: block; max-width: 52ch; margin-top: 6px; font-size: 16px; color: var(--muted); }
.svc-price { font-size: 22px; letter-spacing: -.02em; text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.svc-price small { display: block; font-size: 13px; letter-spacing: 0; color: var(--muted); }
.svc-details { margin: 0 0 12px 42px; }
.svc-details summary { display: inline-flex; align-items: center; min-height: 44px; cursor: pointer; font: 500 14px/1.2 var(--font-sans); text-decoration: underline; text-underline-offset: 5px; }
.svc-details p { max-width: 60ch; margin-top: 4px; font-size: 15px; }
.svc-details .svc-excludes { margin-top: 10px; color: var(--muted); }
.builder-dep { max-width: 64ch; margin-top: 20px; font-size: 14px; color: var(--muted); }
.builder-summary { --ring-ground: var(--ground); position: sticky; top: calc(var(--header-h) + 24px); display: grid; gap: 16px; padding: clamp(24px, 2.4vw, 40px); background: var(--ground); border: 1px solid var(--rule); border-radius: 4px; }
.builder-summary .field-label { margin-bottom: 0; }
.sum-name { font: italic 400 28px/1.2 var(--font-serif); color: var(--accent); }
.sum-list { margin: 0; padding: 0; list-style: none; }
.sum-list:empty { display: none; }
.sum-list li { display: flex; justify-content: space-between; gap: 16px; padding: 8px 0; border-top: 1px solid var(--rule); font-size: 15px; }
.sum-list li span:last-child { white-space: nowrap; font-variant-numeric: tabular-nums; }
.sum-total { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; padding-top: 16px; border-top: 1px solid var(--ink); }
.sum-amount { font-size: clamp(40px, 3.4vw, 56px); line-height: 1; letter-spacing: -.04em; font-variant-numeric: tabular-nums; }
.sum-monthly { font: 500 15px/1.4 var(--font-sans); }
.sum-budget { padding-top: 16px; border-top: 1px solid var(--rule); }
.sum-budget-intro { margin: 8px 0 14px; font-size: 14px; color: var(--muted); }
.builder-summary input { background: var(--surface); }
.money-field { position: relative; display: block; }
.money-field > span { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: var(--muted); pointer-events: none; }
.money-field input { padding-left: 32px; }
.sum-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 20px; }
.builder-summary .status:empty { display: none; }
.sum-note { font-size: 13px; color: var(--muted); }
@media (max-width: 1023px) {
  .builder-grid { grid-template-columns: minmax(0, 1fr); }
  .builder-summary { position: static; max-width: 640px; }
}
@media (max-width: 639px) {
  .svc-main { grid-template-columns: 24px minmax(0, 1fr); padding-top: 16px; }
  .svc-price { grid-column: 2; font-size: 18px; text-align: left; }
  .svc-price small { display: inline; margin-left: 6px; }
  .svc-name { font-size: 17px; }
  .svc-why { font-size: 15px; }
}
/* Print / save as PDF: the chosen services and the summary, nothing else. */
@media print {
  .loader, .skip, .site-header, .site-footer, .atmo, .floater-slot, main > section:not(.builder),
  .builder-head > p, .builder-nojs, .builder-dep, .svc:not(.is-on), .svc-main input, .svc-details,
  .sum-actions, .sum-budget-intro, .builder-summary .status, .svc-group:not(:has(.is-on)) { display: none !important; }
  html, body { background: none !important; }
  .builder { padding: 0; background: none; }
  .builder-head { display: block; margin-bottom: 24px; }
  .builder-grid { display: block; }
  .svc-main { grid-template-columns: minmax(0, 1fr) auto; }
  .builder-summary { position: static; margin-top: 24px; }
}

/* ---------- Inquiry + FAQ ---------- */
.inquiry { position: relative; padding: var(--section) 0; }
.inquiry-grid, .faq { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); gap: clamp(40px, 6vw, 128px); align-items: start; }
/* The desk still fills what the intro leaves beside the composer and ends on the composer's bottom
   edge, instead of hanging below it at a fixed 4:5 (2026-09-24, user). */
.inquiry-grid { align-items: stretch; }
.inquiry-intro { display: flex; flex-direction: column; }
.inquiry-intro > p:not(.label) { max-width: 44ch; margin-top: 24px; }
.inquiry-media { display: flex; flex-direction: column; flex: 1 1 auto; width: min(520px, 100%); min-height: 280px; margin: 40px 0 0; }
.inquiry-media img { flex: 1 1 0; min-height: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 62%; border-radius: 2px; background: var(--surface); }
@media (max-width: 1023px) {
  .inquiry-media { flex: none; width: min(440px, 100%); min-height: 0; }
  .inquiry-media img { flex: none; height: auto; aspect-ratio: 4 / 5; }
}
.inquiry h2[tabindex]:focus:not(:focus-visible) { outline: none; }
.demo-note { margin-top: 32px !important; padding: 16px 18px; border-left: 2px solid var(--accent); background: var(--surface); font-size: 15px; }
.composer { display: grid; gap: 20px; padding: clamp(24px, 3vw, 44px); background: var(--surface); border: 1px solid var(--rule); border-radius: 4px; }
.selection { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 16px; padding-bottom: 20px; border-bottom: 1px solid var(--rule); }
.selection .field-label { flex-basis: 100%; }
.selection-value { font: italic 400 28px/1.2 var(--font-serif); color: var(--accent); margin-right: auto; }
.text-button { min-height: 44px; padding: 0 2px; background: none; border: 0; cursor: pointer; font: 500 14px/1.2 var(--font-sans); text-decoration: underline; text-underline-offset: 5px; }
.text-button[aria-disabled="true"] { color: var(--muted); text-decoration: none; cursor: default; }
.field-label { display: block; font: 500 12px/1.3 var(--font-sans); letter-spacing: .08em; text-transform: uppercase; color: var(--muted); margin-bottom: 8px; }
.fields-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
input, textarea { width: 100%; font: 400 16px/1.5 var(--font-sans); color: var(--ink); background: var(--ground); border: 1px solid var(--rule); border-radius: 4px; padding: 12px 14px; }
input:focus-visible, textarea:focus-visible { border-color: var(--ink); }
textarea { resize: vertical; }
.preview { min-height: 172px; font-size: 15px; }
.composer-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 20px; }
.status { min-height: 1.5em; font-size: 15px; }
.status[data-state="error"] { color: var(--accent); }
.fallback { font-size: 15px; color: var(--muted); }
.faq { position: relative; margin-top: var(--section); padding-top: 48px; border-top: 1px solid var(--rule); }
.faq-list details { border-top: 1px solid var(--rule); }
.faq-list details:last-child { border-bottom: 1px solid var(--rule); }
.faq-list summary { display: flex; align-items: center; justify-content: space-between; gap: 24px; min-height: 64px; padding: 16px 0; cursor: pointer; list-style: none; font: 400 20px/1.3 var(--font-sans); letter-spacing: -.01em; }
.faq-list summary::-webkit-details-marker { display: none; }
.faq-list summary::after { content: "+"; flex: none; font-size: 26px; line-height: 1; color: var(--accent); transition: transform .2s ease; }
.faq-list details[open] summary::after { transform: rotate(45deg); }
.faq-list details p { padding: 0 0 24px; color: var(--muted); max-width: 58ch; }
@media (prefers-reduced-motion: reduce) { .faq-list summary::after { transition: none; } }

/* ---------- Outro: the Convenium studio hero banner (brand constant, identical on every page) ----------
   Noir stage, ONE restrained chili atmospheric field (the studio hero's own stops, derived from chili),
   uppercase Archivo display, Newsreader italic line, gray-on-noir support. The field is the single
   gradient in the kit; it sits on an aria-hidden, z-index:-1 layer with nothing interactive on it. */
.outro {
  position: relative; isolation: isolate; overflow: hidden; display: flex; align-items: flex-end;
  min-height: min(100svh, 1080px); background: var(--brand-noir); color: var(--brand-cotton);
}
.outro-field { position: absolute; inset: -4%; z-index: -1; transform-origin: 72% 48%; }
.outro-glow {
  position: absolute; inset: 0; transform-origin: 72% 48%;
  background: radial-gradient(ellipse 58% 52% at 74% 84%,
    color-mix(in srgb, var(--brand-chili) 20%, transparent),
    color-mix(in srgb, var(--brand-chili) 0%, transparent) 70%);
}
.outro-copy { padding: clamp(144px, 20vh, 220px) 0 clamp(80px, 10vh, 120px); }
.outro .label { color: var(--brand-gray-on-noir); }
/* Studio: 44→112px. Tuned so German's longest word (DIGITALISIEREN) fits 360px uppercase. */
.outro-headline { margin: 0; max-width: min(100%, 1480px); font-size: clamp(2.1rem, .8rem + 5.2vw, 7rem); line-height: .84; letter-spacing: -.03em; }
.outro-display { display: block; font-family: var(--font-brand); font-weight: 900; text-transform: uppercase; color: var(--brand-cotton); }
.outro-serif { display: block; margin-top: .28em; max-width: 13ch; font-family: var(--font-brand-serif); font-style: italic; font-weight: 400; font-size: .54em; line-height: 1.02; letter-spacing: -.02em; color: var(--brand-cotton); }
.outro-support { margin-top: 40px; max-width: 46ch; font: 400 clamp(1rem, .9rem + .35vw, 1.25rem)/1.45 var(--font-brand-sans); color: var(--brand-gray-on-noir); }
.outro-link {
  display: inline-flex; align-items: center; gap: 10px; min-height: 44px; margin-top: 28px;
  font: 500 15px/1.2 var(--font-brand-sans); color: var(--brand-cotton);
  text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 6px;
}

/* ---------- Footer (brand constant) ----------
   Full width at every size: the inner block is not capped by --max, and the wordmark is sized from
   its own measured advance (CONVENIUM. in Archivo 900 at -.05em measures 6.78em, see --wordmark-em) against the
   container width, so it runs gutter to gutter on a 390px phone and on a 2560px display alike. */
.site-footer { --wordmark-em: 6.8; background: var(--brand-noir); color: var(--brand-cotton); }
.footer-inner {
  container-type: inline-size;
  display: flex; flex-direction: column; gap: 40px;
  margin-inline: var(--gutter); padding: 56px 0 28px;
}
.footer-top { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 16px 48px; }
.footer-line { color: var(--brand-gray-on-noir); font-size: 15px; }
.footer-brand { margin: 0; overflow: hidden; font: 900 calc(100cqw / var(--wordmark-em)) / .8 var(--font-brand); letter-spacing: -.05em; white-space: nowrap; } /* overflow only matters if Archivo fails to load */
.footer-brand span { color: var(--brand-chili); }
.footer-links { display: flex; flex-wrap: wrap; gap: 4px 28px; }
.footer-links a { display: inline-flex; align-items: center; min-height: 44px; text-decoration: none; font-weight: 500; }
.footer-links a:hover { text-decoration: underline; text-underline-offset: 5px; }
/* The studio's real contact lines (category.launch.email / phone), shown in demo and live mode. */
.footer-id { display: grid; gap: 4px; }
.footer-contact { display: flex; flex-wrap: wrap; gap: 0 24px; margin: 0; }
.footer-contact a { display: inline-flex; align-items: center; min-height: 44px; color: var(--brand-cotton); font-weight: 500; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 5px; }
.footer-bottom { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 12px 24px; padding-top: 24px; border-top: 1px solid #6E6963; color: var(--brand-gray-on-noir); font-size: 14px; }
.footer-legal { display: flex; flex-wrap: wrap; gap: 4px 24px; align-items: center; }
.footer-legal a { display: inline-flex; align-items: center; min-height: 44px; color: var(--brand-cotton); text-underline-offset: 5px; }
@media (max-width: 639px) { .footer-inner { gap: 28px; padding-top: 44px; } }

/* ---------- Compact mobile (2026-09-24, user: "sections cover too much height") ----------
   The cut band exists for the desktop scissor animation; static on a phone it was a 630px block that
   said one line. It is dropped below laptop width (content-only loss: its line repeats the collection's
   own promise). Everything else keeps its content and loses height. */
@media (max-width: 1023px) {
  .cut { display: none; }
  /* The two chapter statements belong to the pinned hero scrub (desktop). Static below laptop they were
     a second, text-only block between the hero and the pair; the hero card already says it. */
  .hero-statements { display: none; }
  .hero { padding-bottom: 8px; }
  .inquiry-media { flex: none; width: 100%; max-width: 640px; min-height: 0; margin-top: 28px; }
  .inquiry-media img { flex: none; height: auto; aspect-ratio: 3 / 2; object-position: 50% 62%; }
  .concepts { grid-template-columns: repeat(auto-fit, minmax(max(min(100%, 300px), calc(50% - 12px)), 1fr)); gap: 32px 24px; }
}
@media (max-width: 639px) {
  :root { --section: 56px; }
  .label { margin-bottom: 14px; }
  h2 { font-size: clamp(30px, 8.2vw, 40px); }
  /* Hero: shorter image, tighter statements. */
  .hero-visual { aspect-ratio: 1 / 1; }
  .hero-statements { gap: 24px; padding: 48px 0; }
  .chapter-text { font-size: 24px; }
  /* Pair side by side: two small portraits instead of two full-width ones. */
  .worlds .label { margin-bottom: 24px; }
  .worlds-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  .world:nth-child(2) { padding-top: 32px; }
  .world h3 { margin: 12px 0 4px; font-size: 17px; }
  .world p { font-size: 14px; line-height: 1.45; }
  .worlds-foot { margin-top: 32px; gap: 6px; }
  .worlds-foot p:first-child { font-size: 15px; }
  /* Collection. */
  .collection-head, .packages-head, .why-head, .builder-head { margin-bottom: 28px; gap: 16px; }
  .collection-head p, .packages-head p, .why-head p, .builder-head p { font-size: 16px; }
  .plan-amount { font-size: 44px; }
  .plans-note { margin-top: 24px; }
  .concept-desc { margin: 10px 0 14px; font-size: 15px; }
  /* Craft: shorter frame, smaller rows. */
  .craft-grid { gap: 28px; }
  .pano { aspect-ratio: 4 / 3; }
  .craft-intro { margin-top: 16px; font-size: 16px; }
  .rows { margin-top: 24px; }
  .rows li { grid-template-columns: 36px minmax(0, 1fr); padding: 14px 0; }
  .rows h3 { font-size: 18px; }
  .rows p { font-size: 15px; margin-top: 2px; }
  /* Process: a thumbnail beside each step instead of a full-width image above it. */
  .process-head { margin-bottom: 28px; }
  .process-head p { font-size: 16px; margin-top: 12px; }
  .steps { gap: 0; }
  .steps li { display: grid; grid-template-columns: 96px minmax(0, 1fr); column-gap: 16px; align-items: start; padding: 16px 0; }
  .steps li:last-child { border-bottom: 1px solid var(--rule); }
  .steps--media .step-media { grid-row: 1 / span 3; margin: 0; aspect-ratio: 1; }
  .steps .num { margin-bottom: 6px; }
  .steps h3 { font-size: 18px; }
  .steps p { font-size: 15px; margin-top: 4px; }
  /* Inquiry: a landscape crop of the desk, not a full 4:5 portrait. */
  .inquiry-media { width: 100%; margin-top: 24px; }
  .inquiry-media img { aspect-ratio: 3 / 2; object-position: 50% 62%; }
  .inquiry-intro > p:not(.label) { margin-top: 16px; }
  .demo-note { margin-top: 20px !important; }
  .composer { gap: 16px; padding: 20px; }
  .faq { padding-top: 32px; gap: 16px; }
  .faq-list summary { min-height: 56px; padding: 12px 0; font-size: 17px; }
}

/* ---------- Legal pages (Impressum / Datenschutz): one text column on the cotton ground ---------- */
.legal-page { background: var(--ground, #EDEBDD); color: var(--ink, #241F1F); }
.legal-header { display: flex; justify-content: space-between; align-items: center; padding: 24px var(--gutter); }
.legal-header a { display: inline-flex; align-items: center; min-height: 44px; }
.legal { max-width: 68ch; margin: 0 auto; padding: clamp(32px, 6vw, 96px) var(--gutter) 96px; }
.legal h1 { font-size: clamp(36px, 4vw, 64px); margin-bottom: 32px; }
.legal h2 { font-size: clamp(22px, 1.8vw, 28px); margin: 40px 0 12px; }
.legal p { margin-top: 16px; }
.legal a { color: var(--accent, #810100); text-underline-offset: 4px; }
.legal-lead, .legal-updated { color: var(--muted, #6E6963); }
.legal-list { display: grid; grid-template-columns: minmax(0, 14em) minmax(0, 1fr); gap: 12px 24px; margin: 32px 0; padding: 24px 0; border-block: 1px solid var(--rule, #D6D2C2); }
.legal-list dt { color: var(--muted, #6E6963); }
.legal-list dd { margin: 0; }
.legal-draft { display: inline-block; padding: 8px 12px; border-left: 2px solid var(--accent, #810100); background: var(--surface, #F5F3E8); }
.legal mark { background: none; color: var(--accent, #810100); font-weight: 600; }
@media (max-width: 639px) { .legal-list { grid-template-columns: minmax(0, 1fr); gap: 4px; } .legal-list dd { margin-bottom: 12px; } }

/* ---------- Atmosphere: dust in window light (kit.js, motion only) + 3D floater slots ----------
   Each light section carries one aria-hidden canvas behind its content; nothing draws on it without
   motion. Floater slots are empty, aria-hidden boxes that kit/floaters.mjs draws a GLB over from one
   fixed canvas; they exist only from laptop up. */
.atmo { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; pointer-events: none; }
.worlds > .wrap, .collection > .wrap, .craft > .wrap, .process > .wrap, .why > .wrap, .packages > .wrap, .builder > .wrap, .inquiry > .wrap { position: relative; z-index: 1; }
.floater-slot {
  position: absolute; z-index: 2; display: none; pointer-events: none; aspect-ratio: 1;
  top: var(--fx-top, auto); right: var(--fx-right, auto); bottom: var(--fx-bottom, auto); left: var(--fx-left, auto);
  width: var(--fx-width, 260px);
}
@media (min-width: 1024px) { .floater-slot { display: block; } }
.floater-canvas { position: fixed; inset: 0; z-index: 40; width: 100%; height: 100%; pointer-events: none; }

/* ---------- Responsive fallbacks (tablet and phone) ---------- */
@media (max-width: 1023px) {
  /* The entrance scales .hero-visual from 1.06; without the pinned stage's own overflow:hidden that
     overshoot is a 4–8px sideways scroll for the first second on phones and tablets. */
  .hero { overflow-x: clip; }
  /* Static hero: the intro card sits under the image, overlapping it slightly, never on top of it. */
  .chapter--intro { position: relative; left: auto; bottom: auto; width: auto; margin: -56px var(--gutter) 0; padding: 32px 32px 36px; }
  .hero-visual { aspect-ratio: 4 / 3; }
  .hero-poster { object-position: 70% 50%; }
  .collection-head, .packages-head, .why-head, .builder-head, .inquiry-grid, .faq { grid-template-columns: minmax(0, 1fr); gap: 32px; }
  .collection-head, .packages-head, .why-head, .builder-head { margin-bottom: 48px; }
  .cut-object { position: relative; right: auto; top: auto; display: block; width: min(300px, 56vw); margin: 0 auto var(--section); transform: rotate(52deg); }
  .cut-half--bottom { padding-bottom: 48px; }
}
@media (max-width: 639px) {
  .hero-visual { aspect-ratio: 4 / 5; }
  .chapter--intro { margin: -40px 12px 0; padding: 24px 20px 28px; }
  .hero h1 { font-size: clamp(38px, 10.5vw, 56px); }
  .hero-body { font-size: 17px; }
  .hero-statements { grid-template-columns: minmax(0, 1fr); gap: 40px; }
  h2 { font-size: clamp(32px, 8.6vw, 44px); }
  .steps, .fields-2 { grid-template-columns: minmax(0, 1fr); }
  .steps { gap: 40px; }
  .process-track { display: none; }
  .steps li { border-top: 1px solid var(--rule); }
  .steps li::before { display: none; }
  .faq-list summary { font-size: 18px; }
  .selection-value { font-size: 24px; }
}

/* ---- Launch campaign (campaign.js) -------------------------------------------------------------
   A cherry band above "07 / Pakete". No gradient, no shadow, nothing that blinks. The block is hidden
   without JavaScript and reserves its height before the state arrives, so nothing shifts. */
.no-js .campaign, .no-js .plan-then { display: none; }
.campaign { background: var(--accent); color: var(--on-accent); }
.campaign[hidden] { display: none; }
.campaign-inner { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); gap: 20px clamp(20px, 3vw, 56px); align-items: start; padding-block: clamp(28px, 4vw, 56px); min-height: 280px; }
@media (max-width: 640px) { .campaign-inner { min-height: 400px; } }
.campaign .label, .campaign-claim, .campaign-count, .campaign-slots, .campaign-regular, .campaign-risk { margin: 0; }
.campaign .label { color: var(--on-accent); opacity: .85; }
.campaign-claim { margin-top: 10px; font-family: var(--font-brand); font-weight: 900; text-transform: uppercase; letter-spacing: -.02em; line-height: 1; font-size: clamp(22px, 2.6vw, 38px); }
.campaign-source { display: block; margin-top: 8px; font: 400 14px/1.4 var(--font-sans); text-transform: none; letter-spacing: 0; text-decoration: underline; text-underline-offset: 3px; color: var(--on-accent); }
.campaign-count { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 14px; }
.campaign-ends { font: 500 13px/1 var(--font-sans); text-transform: uppercase; letter-spacing: .08em; opacity: .85; }
.campaign-units { display: inline-flex; gap: 14px; }
.campaign-unit { display: inline-flex; align-items: baseline; gap: 4px; }
.campaign-num { font-family: var(--font-brand); font-weight: 900; font-variant-numeric: tabular-nums; font-size: clamp(26px, 2.6vw, 38px); line-height: 1; }
.campaign-unitname { font: 400 13px/1 var(--font-sans); opacity: .85; }
.campaign-slots { margin-top: 10px; font: 500 16px/1.4 var(--font-sans); }
.campaign-regular { font: 400 16px/1.4 var(--font-sans); }
.campaign-cta { display: inline-flex; align-items: center; min-height: 48px; margin-top: 14px; padding: 0 22px; border-radius: 8px; background: var(--on-accent); color: var(--accent); font: 600 13px/1 var(--font-sans); text-transform: uppercase; letter-spacing: .08em; }
.campaign-cta { text-decoration: none; }
.campaign-cta:hover { background: var(--surface); }
.campaign-risk { margin-top: 12px !important; font: 400 14px/1.4 var(--font-sans); opacity: .9; }
.campaign :focus-visible { outline-color: var(--on-accent); box-shadow: none; }
.plan-then { margin: 8px 0 0; font: 400 14px/1.4 var(--font-sans); color: var(--muted); }
.plan--featured .plan-then { color: var(--on-accent); }
.pin-ready .plan-then { min-height: 20px; }
.pin-ready:not(.camp-ready) [data-camp-pkg], .pin-ready:not(.camp-ready) [data-camp-svc] { opacity: 0; animation: camp-reveal 0s 1.5s forwards; }
@keyframes camp-reveal { to { opacity: 1; } }
