:root {
    /* Markentypografie — drei Register: Display-Serif (Fraunces, mit optischer
       Grösse via font-optical-sizing:auto) für Headlines · Body-Sans (Poppins) ·
       Mono (JetBrains Mono) für Eyebrows/Labels/Einheiten — die „Maschinen"-
       Stimme neben dem „Handwerks"-Serif. Lora bleibt Fallback hinter Fraunces.
       Familienwechsel künftig nur hier. (Skala: --text-* bleibt.) */
    --font-display: 'Fraunces', 'Lora', Georgia, 'Times New Roman', serif;
    --font-body: 'Poppins', system-ui, -apple-system, sans-serif;
    --font-mono: 'JetBrains Mono', ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace;

    --bg: #0a1622;
    --bg-elevated: #0f1e2e;
    --bg-card: #14283b;
    --surface: #1b3349;
    --border: #25415a;
    /* Interactive form-field boundary — ≥3:1 against both --bg and
       --bg-elevated (WCAG 1.4.11 non-text contrast). The field fill equals the
       page bg, so the border alone must carry perceivability; --border is a
       decorative divider tone (1.7:1) and stays as-is for non-interactive edges. */
    --border-field: #4a7196;
    --text: #eef4f8;
    --text-dim: #9fb6c6;
    /* Lightened from #6f8a9d so small print on cards/modals/tiles clears AA 4.5:1
       (was 4.15:1 on --bg-card, 3.59:1 on --surface); stays a clear tier below
       --text-dim. */
    --text-muted: #879fb0;
    /* Ocean Depths v2 („Reclaimed Light") — die helleren, leuchtenden Stops
       der Instagram-Slides (Drive → Slide Design System): Ozean-Blau → Teal →
       Aqua. Werte-Update, gleiche Rollen. */
    --accent: #2fae9e;
    --accent-2: #2f86b3;
    --accent-3: #7ee0cf;
    /* Dark ink for text/icons sitting ON the accent gradient (CTAs/buttons). */
    --on-accent: #06121c;
    /* Single danger/error tone (unified from three near-duplicate reds). Light
       enough to read on the dark theme as both border and text (6.6:1 on --bg). */
    --danger: #f87171;
    --gradient: linear-gradient(135deg, #2f86b3 0%, #2fae9e 50%, #7ee0cf 100%);
    --gradient-dim: linear-gradient(135deg, rgba(47, 174, 158, 0.15), rgba(47, 134, 179, 0.15));
    /* CTA fill: the teal→aqua slice of Ocean Depths (drops the dark blue stop)
       so DARK navy label text clears WCAG AA (6.9–11.7:1) across the whole
       button — white text failed on the bright end. */
    --gradient-cta: linear-gradient(135deg, #2fae9e 0%, #7ee0cf 100%);
    /* Die warme Kupfer-Familie (Slides, Akt I): das Chaos des Abfalls trägt
       Kupfer/Rosé — Aqua wird erst nach der Wende ausgegeben. --accent-warm
       bleibt zusätzlich der EINE warme Akzent in Akt II (#your-style):
       dieselbe Familie, Text-tauglich (7.7:1 auf --bg). */
    --accent-warm: #d99b78;
    --warm-thread: #c9906f;      /* der Akt-I-Faden (Canvas-Basis 201,144,111) */
    --warm-deep: #8a5f4c;        /* Schatten-Strang (≥3:1 auf --bg, nur gross/grafisch) */
    --warm-bright: #ecc39f;      /* Peach-Highlight der Slide-Ribbons */
    --gradient-warm: linear-gradient(135deg, #8a5f4c 0%, #c9906f 45%, #ecc39f 100%);
    --success: #10b981;
    --shadow-soft: 0 10px 40px rgba(0, 0, 0, 0.4);
    --shadow-glow: 0 0 60px rgba(47, 174, 158, 0.25);
    --radius: 14px;
    --radius-sm: 8px;

    /* 4px-base spacing scale — use these instead of ad-hoc px values
       so vertical rhythm stays consistent as the design evolves. */
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 20px;
    --space-6: 24px;
    --space-7: 32px;
    --space-8: 40px;
    --space-9: 56px;
    --space-10: 72px;
    --space-11: 96px;
    --space-12: 128px;

    /* Type scale — major-third (1.25) modular scale, fluid via clamp.
       Pair each size with a deliberate line-height + tracking. */
    --text-xs: 11px;
    --text-sm: 13px;
    --text-base: 15px;
    --text-md: 17px;
    --text-lg: 19px;
    --text-xl: clamp(22px, 2.2vw, 26px);
    --text-2xl: clamp(28px, 3vw, 36px);
    --text-3xl: clamp(36px, 4.5vw, 56px);
    --text-display: clamp(56px, 9vw, 128px);

    /* Editorial defaults */
    --tracking-tight: -0.02em;
    --tracking-tighter: -0.04em;
    --tracking-wide: 0.08em;
    --tracking-wider: 0.14em;
    --leading-tight: 1.05;
    --leading-snug: 1.25;
    --leading-normal: 1.55;
    --leading-loose: 1.75;

    /* Motion tokens — keep transitions consistent across components */
    --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
    --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
    --duration-fast: 150ms;
    --duration-base: 240ms;
    --duration-slow: 420ms;

    /* Akt I — „Die Linie": die gemeinsame Gossen-x, an der der eine KUPFERNE
       Maschinen-Faden durch Preloader → Hero → Manifest → #facts läuft.
       Jedes Segment richtet sich hieran aus, damit das Auge EINE Linie liest.
       Kupfer wie #pivot-line + fil-seam[1] (Slide-Dramaturgie: das Chaos des
       Abfalls ist warm) — Teal/Aqua wird erst nach der Wende ausgegeben
       (facts Beat 3 / #pivot). Safe-Area-bewusst. */
    /* Min-Gutter 28px: die zentrierte Preloader-Nadel-Marke (74px, Kreis ~25px
       links der Nadel-Achse) darf am schmalen Phone-Rand nicht anschneiden.
       Loader- UND Hero-Faden reiten auf dieser Variable → bleiben pixelgenau. */
    --act1-thread-x: calc(env(safe-area-inset-left, 0px) + clamp(28px, 4vw, 60px));
    /* Act-I-Inhalt (Hero/Manifest) rückt garantiert rechts an der Linie vorbei —
       links verankert, eine gemeinsame Spalte, nie auf der Linie. */
    --act1-pad-l: calc(var(--act1-thread-x) + clamp(20px, 3vw, 46px));
    --act1-thread: rgba(201, 144, 111, 0.42);
    --act1-thread-dim: rgba(201, 144, 111, 0.22);
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* Global focus-visible ring — consistent across all interactive
   elements. Hidden for pointer-driven focus (mouse clicks),
   visible for keyboard navigation. */
:where(button, a, input, select, textarea, [tabindex]):focus-visible {
    outline: 2px solid var(--accent-3);
    outline-offset: 3px;
    border-radius: var(--radius-sm);
}

/* Programmatic focus route-targets: when a keyboard user opens the studio /
   make-real panel we move focus INTO the revealed section (tabindex=-1) so Tab
   continues there and SR users hear the region. These are NOT Tab stops, so a
   container-sized ring around a viewport-tall section is inappropriate — the
   scroll + heading announcement is the cue. Real controls keep their ring. */
#design:focus-visible, #ownership:focus-visible, #measure:focus-visible,
#production:focus-visible, #faq:focus-visible,
#design:focus, #ownership:focus, #measure:focus,
#production:focus, #faq:focus { outline: none; }

/* Sharper text rendering across the app */
html {
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
}

body {
    font-feature-settings: "kern", "liga", "calt", "ss01";
    text-underline-offset: 0.15em;
}

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

html { scroll-behavior: smooth; }

/* Anchor jumps (#how, #design …) and scrollIntoView must clear the fixed
   navbar — without this the section eyebrow/heading lands hidden behind the
   ~60px bar. Matches nav-container height + a little breathing room; the
   safe-area term covers the notch where the bar grows. */
:is(main[id], section[id]) {
    scroll-margin-top: calc(72px + env(safe-area-inset-top));
}

body {
    font-family: var(--font-body);
    background: var(--bg);
    color: var(--text);
    line-height: 1.6;
    overflow-x: hidden;
    min-height: 100svh; /* small-viewport unit → stabil, kein iOS-Toolbar-Sprung */
    min-height: calc(var(--svh, 1svh) * 100); /* JS-gepinnt (in-app-Browser) */
}

.container {
    max-width: 1280px;
    margin: 0 auto;
    padding: 0 24px;
}

/* ============ NAVBAR ============ */
/* STICKY statt fixed — bewusst: iOS-26-Safari rendert position:fixed beim
   Scrollen/Toolbar-Animieren versetzt (Systembug, WebKit #297779: Inspector
   zeigt korrekt, Rendering hängt ~10–60px nach; real-iPhone-Befund hier).
   Sticky wird vom Scroller selbst positioniert: verschiebt iOS den Viewport,
   wandert der Header MIT dem Inhalt — Inhalt „oberhalb der Kopfzeile" kann
   konstruktiv nicht mehr auftreten. height:0 hält die Bar layout-neutral
   (wie fixed, alle padding-Klarhöhen der Seiten bleiben gültig); die sicht-
   bare Leiste ist die überlaufende .nav-shell. */
.navbar {
    position: sticky;
    top: 0;
    height: 0;
    overflow: visible;
    z-index: 100;
}
.nav-shell {
    background: rgba(10, 22, 34, 0.7);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    border-bottom: 1px solid var(--border);
}

/* Touch devices (iOS Safari, Android): a fixed bar with a LIVE backdrop blur
   re-rasterizes its 20px blur every frame over the scrolling content beneath
   it — including the WebGL canvases — which is a well-known source of scroll
   stutter. Drop the live blur on any touch-capable device and use a
   near-opaque bar instead; legibility is preserved and scrolling stays
   smooth. (any-pointer: coarse — NOT pointer:coarse — so it still applies on
   an iPad with a trackpad/Magic Keyboard attached, which reports the PRIMARY
   pointer as fine.) Pure-mouse desktops keep the brand glass. */
@media (any-pointer: coarse) {
    .nav-shell {
        background: rgba(10, 22, 34, 0.94);
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
    }
    /* iOS 26 rendert VIEWPORT-verankerte Layer (fixed UND sticky) beim
       Scrollen versetzt (WebKit #297779; translateZ/sticky-Umbau änderten
       nichts — real-iPhone-Befund dreifach). Auf Touch fährt die Kopfzeile
       deshalb gar nicht mit: position:relative hält sie im Fluss (0 Höhe,
       Shell überlagert wie gehabt den Hero-Anfang) und sie scrollt normal
       weg — ein inhaltsverankerter Layer kann nicht versetzt rendern, „Text
       oberhalb der Kopfzeile" ist konstruktiv ausgeschlossen. Die persistente
       Aktion trägt mobil der .sticky-create-Pill; Desktop bleibt sticky. */
    .navbar { position: relative; }
}
/* In-app browsers (Instagram/Facebook WKWebView) evaluate pointer media
   queries unreliably — many report no coarse pointer even on iPad — so the
   query above silently fails there. .is-touch is set from JS via
   navigator.maxTouchPoints (reliable in WKWebViews) as the load-bearing path. */
html.is-touch .nav-shell {
    background: rgba(10, 22, 34, 0.94);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}
html.is-touch .navbar { position: relative; }

.nav-container {
    max-width: 1280px;
    margin: 0 auto;
    padding: 18px 24px;
    /* Randlose iPhones: Inhalt unter die Notch schieben (0 auf allen anderen Geräten). */
    padding-top: max(18px, env(safe-area-inset-top));
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.logo {
    display: flex;
    align-items: center;
    gap: 12px;
}

.logo-mark {
    width: 36px;
    height: 36px;
    border-radius: 9px;
    background: var(--gradient);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 800;
    font-size: 14px;
    letter-spacing: -0.5px;
    color: white;
}

.logo-text {
    font-weight: 700;
    font-size: 15px;
    letter-spacing: -0.2px;
}

.nav-links {
    display: flex;
    list-style: none;
    gap: var(--space-7);
}

.nav-links a {
    color: var(--text-dim);
    text-decoration: none;
    font-size: var(--text-sm);
    font-weight: 500;
    letter-spacing: -0.005em;
    transition: color var(--duration-fast) var(--ease-out);
    position: relative;
}

.nav-links a::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: -6px;
    height: 1px;
    background: var(--gradient);
    transform: scaleX(0);
    transform-origin: center;
    transition: transform var(--duration-base) var(--ease-out);
}

.nav-links a:hover {
    color: var(--text);
}

.nav-links a:hover::after { transform: scaleX(0.6); }

/* Hamburger toggle — hidden on desktop, shown on mobile */
.nav-toggle {
    display: none;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    width: 44px;
    height: 44px;
    padding: 0;
    background: transparent;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    cursor: pointer;
}

.nav-toggle-bar {
    display: block;
    width: 20px;
    height: 2px;
    margin: 0 auto;
    background: var(--text);
    border-radius: 2px;
    transition: transform var(--duration-base) var(--ease-out),
                opacity var(--duration-fast) var(--ease-out);
}

.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(1) {
    transform: translateY(7px) rotate(45deg);
}
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(2) {
    opacity: 0;
}
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(3) {
    transform: translateY(-7px) rotate(-45deg);
}

/* Language toggle — segmented DE / EN control in the nav */

.lang-toggle {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 5px 10px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 100px;
    cursor: pointer;
    font-family: inherit;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.04em;
    line-height: 1;
    color: var(--text-dim);
    transition: border-color var(--duration-fast) var(--ease-out);
}

.lang-toggle:hover { border-color: var(--accent); }

.lang-opt {
    padding: 2px 4px;
    border-radius: 100px;
    color: var(--text-dim);
    transition: color var(--duration-fast) var(--ease-out);
}

.lang-opt.is-active {
    color: var(--text);
    background: var(--gradient);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}

.lang-sep { color: var(--border); }

/* ============ HERO ============ */
.hero {
    /* Full-bleed stage: the gradient visual + glow span the whole viewport.
       The content is constrained by .hero-inner so it never touches edges. */
    position: relative;
    overflow: hidden;
}

.hero-eyebrow {
    font-size: var(--text-xs);
    font-weight: 600;
    letter-spacing: var(--tracking-wider);
    color: var(--text-dim);
    margin-bottom: var(--space-6);
    text-transform: uppercase;
}

.orb {
    position: absolute;
    border-radius: 50%;
    filter: blur(80px);
    opacity: 0.5;
    animation: float 20s ease-in-out infinite;
}

@keyframes float {
    0%, 100% { transform: translate(0, 0); }
    33% { transform: translate(30px, -50px); }
    66% { transform: translate(-30px, 30px); }
}

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

/* ============ WORKFLOW STEP TRACKER ============ */

.step {
    display: flex;
    align-items: center;
    gap: 12px;
    color: var(--text-muted);
    font-weight: 500;
    font-size: 14px;
    flex: 1;
}

.step span {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    font-weight: 600;
    transition: all 0.3s;
}

.step.active {
    color: var(--text);
}

.step.active span {
    background: var(--gradient);
    border-color: transparent;
    color: white;
}

/* ============ SECTIONS ============ */
.section {
    padding: var(--space-12) 0;
    position: relative;
}

.section-header {
    margin-bottom: var(--space-10);
    max-width: 680px;
}

.section-number {
    display: inline-block;
    font-size: var(--text-sm);
    font-weight: 700;
    letter-spacing: var(--tracking-wider);
    color: var(--accent);
    margin-bottom: var(--space-4);
    text-transform: uppercase;
}

.section-header h2 {
    font-family: var(--font-display);
    font-size: var(--text-3xl);
    font-weight: 700;
    letter-spacing: var(--tracking-tight);
    line-height: var(--leading-tight);
    margin-bottom: var(--space-5);
    text-wrap: balance;
}

.section-header p {
    font-size: var(--text-md);
    color: var(--text-dim);
    line-height: var(--leading-normal);
    max-width: 560px;
    text-wrap: pretty;
}

/* ============ DESIGN SECTION ============ */
.design-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 32px;
}

.prompt-panel,
.result-panel {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 32px;
}

label {
    display: block;
    font-size: 13px;
    font-weight: 600;
    color: var(--text);
    margin-bottom: 12px;
    letter-spacing: 0.3px;
}

textarea,
input[type="text"],
input[type="number"],
select {
    width: 100%;
    background: var(--bg);
    border: 1px solid var(--border-field);
    border-radius: var(--radius-sm);
    padding: 14px 16px;
    color: var(--text);
    font-family: inherit;
    font-size: 15px;
    transition: border-color 0.2s, box-shadow 0.2s;
    resize: vertical;
}

textarea:focus,
input:focus,
select:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(47, 174, 158, 0.15);
}

/* Keyboard focus gets a real, high-contrast ring; mouse focus keeps just
   the subtle border/shadow above (the outline:none on :focus suppresses it
   for pointer focus, :focus-visible re-adds it for keyboard). */
textarea:focus-visible,
input:focus-visible,
select:focus-visible {
    outline: 2px solid var(--accent-3);
    outline-offset: 2px;
}

/* Out-of-range / invalid measurement inputs surface visibly + to AT. */
input[aria-invalid="true"] {
    border-color: var(--danger);
    box-shadow: 0 0 0 3px rgba(248, 113, 113, 0.25);
}

.prompt-suggestions {
    margin-top: 20px;
}

.suggestions-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 12px;
}

.suggestions-label {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 1.5px;
    color: var(--accent);
    text-transform: uppercase;
    margin: 0;
}

.suggestions-stats {
    font-size: 11px;
    color: var(--text-muted);
    letter-spacing: 0.4px;
}

.suggestions-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.suggestion {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: var(--surface);
    border: 1px solid var(--border);
    color: var(--text-dim);
    padding: 8px 16px 8px 10px;
    border-radius: 100px;
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    transition: border-color 0.2s, color 0.2s, background 0.2s, transform 0.15s;
    margin: 0;
    font-family: inherit;
}

.suggestion:hover {
    border-color: var(--accent);
    color: var(--text);
    background: var(--gradient-dim);
    transform: translateY(-1px);
}

.suggestion-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--bg);
    color: var(--text);
    flex-shrink: 0;
}

.suggestion-icon svg { display: block; }

.suggestion.personalized {
    border-color: rgba(47, 174, 158, 0.4);
    background: linear-gradient(135deg, rgba(47, 174, 158, 0.08), rgba(47, 134, 179, 0.08));
    color: var(--text);
}

.suggestion.personalized .suggestion-icon {
    background: var(--gradient);
    color: white;
}

.suggestion.personalized:hover {
    border-color: var(--accent);
    background: linear-gradient(135deg, rgba(47, 174, 158, 0.18), rgba(47, 134, 179, 0.18));
}

.suggestion.discovery {
    border-color: rgba(126, 224, 207, 0.4);
    background: linear-gradient(135deg, rgba(126, 224, 207, 0.08), rgba(47, 134, 179, 0.08));
    color: var(--text);
}

.suggestion.discovery .suggestion-icon {
    background: linear-gradient(135deg, var(--accent-3), var(--accent-2));
    color: white;
}

.suggestion.discovery:hover {
    border-color: var(--accent-3);
    background: linear-gradient(135deg, rgba(126, 224, 207, 0.18), rgba(47, 134, 179, 0.18));
}

.garment-type-selector {
    margin-top: 28px;
}

.type-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 10px;
}

.type-btn {
    background: var(--surface);
    border: 1px solid var(--border);
    color: var(--text-dim);
    padding: 16px 8px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    font-size: 12px;
    font-weight: 500;
    transition: all 0.2s;
}

.type-btn:hover {
    border-color: var(--accent);
    color: var(--text);
}

.type-btn.active {
    background: var(--gradient-dim);
    border-color: var(--accent);
    color: var(--text);
}

.primary-btn {
    width: 100%;
    background: var(--gradient-cta);
    border: none;
    color: var(--bg);
    text-shadow: none;
    padding: var(--space-5);
    border-radius: var(--radius);
    font-weight: 600;
    font-size: var(--text-base);
    letter-spacing: 0.01em;
    cursor: pointer;
    margin-top: var(--space-7);
    transition: transform var(--duration-base) var(--ease-out),
                box-shadow var(--duration-base) var(--ease-out),
                filter var(--duration-fast) var(--ease-out);
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-3);
    position: relative;
    box-shadow: 0 4px 24px rgba(47, 174, 158, 0.32);
    font-family: inherit;
}

.primary-btn:hover:not(:disabled) {
    transform: translateY(-1px);
    box-shadow: 0 8px 36px rgba(47, 174, 158, 0.55);
    filter: brightness(1.05);
}

.primary-btn:active:not(:disabled) {
    transform: translateY(0);
    filter: brightness(0.95);
}

.primary-btn:disabled {
    opacity: 0.55;
    cursor: wait;
    filter: saturate(0.7);
}

.btn-spinner {
    display: none;
    width: 16px;
    height: 16px;
    border: 2px solid rgba(255, 255, 255, 0.3);
    border-top-color: white;
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
}

.primary-btn.loading .btn-spinner {
    display: inline-block;
}

@keyframes spin {
    to { transform: rotate(360deg); }
}

/* ============ AI OUTPUT ============ */

.design-result h4 {
    font-size: 12px;
    color: var(--accent);
    letter-spacing: 2px;
    margin-bottom: 8px;
    font-weight: 700;
}

.design-result h3 {
    font-family: var(--font-display);
    font-size: 26px;
    margin-bottom: 16px;
    line-height: 1.2;
}

.design-result p {
    color: var(--text-dim);
    margin-bottom: 16px;
    line-height: 1.6;
}

/* ===== Enhanced design-result card ===== */

.color-swatch {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    border: 2px solid var(--border);
    cursor: pointer;
    transition: transform 0.15s, border-color 0.2s;
}

.color-swatch:hover {
    transform: scale(1.1);
}

.color-swatch.active {
    border-color: var(--accent);
    transform: scale(1.15);
    box-shadow: 0 0 0 3px rgba(47, 174, 158, 0.25);
}

/* Custom-color picker — a <label> wrapping a native <input type="color">.
   Shows a "+" on a brand-gradient disc until an off-palette color is active,
   then reflects that color via an inline background. */

/* ============ MEASURE SECTION ============ */
.measure-section {
    background: var(--bg-elevated);
}

.measure-grid {
    display: grid;
    grid-template-columns: 1.5fr 1fr;
    gap: 48px;
    align-items: flex-start;
}

.measure-form {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 32px;
}

.photo-upload-card {
    background: linear-gradient(135deg,
        rgba(47, 174, 158, 0.06),
        rgba(47, 134, 179, 0.06),
        rgba(126, 224, 207, 0.06));
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 22px;
    margin-bottom: 24px;
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 16px;
    align-items: center;
}

.photo-upload-text h3 {
    font-size: 15px;
    font-weight: 700;
    margin-bottom: 6px;
    background: var(--gradient);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}

.photo-upload-text p {
    font-size: 12px;
    color: var(--text-dim);
    line-height: 1.5;
    margin-bottom: 4px;
}

.photo-privacy {
    color: var(--text-muted) !important;
    font-size: 11px !important;
    font-style: italic;
}

/* Quiet Erwartungs-Notiz am Masse-Schritt (gilt für ALLE Methoden — Foto,
   manuell, Preset): Browser-only + Schätzung/jederzeit anpassbar. Ergänzt die
   foto-spezifische .photo-privacy, statt sie zu duplizieren. Kein erfundener
   Genauigkeitswert (kein „±X cm"). Selektor-Spezifität schlägt bewusst
   `.section-header p`, damit die Notiz kleiner/leiser bleibt als das Intro. */
.measure-section .section-header .measure-note {
    margin: var(--space-4) auto 0;
    max-width: 54ch;
    color: var(--text-muted);
    font-size: var(--text-sm);
    line-height: var(--leading-normal);
}

.photo-upload-action {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
    min-width: 160px;
}

.upload-btn {
    background: var(--gradient-cta);
    border: none;
    color: var(--bg);
    padding: 12px 18px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-weight: 600;
    font-size: 13px;
    transition: transform 0.2s, box-shadow 0.2s;
    box-shadow: 0 2px 12px rgba(47, 174, 158, 0.25);
    white-space: nowrap;
}

.upload-btn:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 18px rgba(47, 174, 158, 0.45);
}

.upload-btn:disabled {
    opacity: 0.6;
    cursor: wait;
}

.pose-status {
    font-size: 11px;
    color: var(--text-dim);
    text-align: center;
    min-height: 14px;
}

.pose-preview {
    grid-column: 1 / -1;
    display: flex;
    justify-content: center;
    padding-top: 12px;
    border-top: 1px solid var(--border);
}

.pose-preview canvas {
    border-radius: var(--radius-sm);
    max-width: 100%;
    height: auto;
}

@media (max-width: 600px) {
    .photo-upload-card {
        grid-template-columns: 1fr;
    }
    .photo-upload-action {
        min-width: 0;
    }
}

.preset-buttons {
    display: flex;
    gap: 8px;
    margin-bottom: 28px;
    flex-wrap: wrap;
}

.preset-btn {
    background: var(--surface);
    border: 1px solid var(--border);
    color: var(--text-dim);
    padding: 8px 16px;
    border-radius: 100px;
    font-size: 13px;
    cursor: pointer;
    font-weight: 500;
    transition: all 0.2s;
}

.preset-btn:hover {
    border-color: var(--accent);
    color: var(--text);
    background: var(--gradient-dim);
}

.measure-inputs {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 16px;
}

.measure-field label {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    font-size: 12px;
    font-weight: 500;
    color: var(--text-dim);
    margin-bottom: 6px;
    text-transform: none;
    letter-spacing: 0;
}

.measure-field .unit {
    color: var(--text-muted);
    font-size: 11px;
}

.measure-field input {
    padding: 12px;
    font-size: 14px;
}

/* Respect the hidden attribute on the pose preview — the .pose-preview flex
   display would otherwise keep the empty canvas + its border-top visible before
   any upload, leaving a blank band in the photo card. */
.pose-preview[hidden] { display: none; }

/* Collapsible detail measurements — a dropdown on EVERY screen size. The nine
   fields live in a <details> whose toggle is always visible; the fields show
   only when open. Display is gated on [open] / :not([open]) rather than
   force-showing a closed <details> — that keeps it consistent across Chromium
   and WebKit/Safari (Safari ignores a display override on closed details). */
.measure-collapse > summary {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-3);
    list-style: none;
    cursor: pointer;
    padding: 14px 16px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg-card);
    color: var(--text);
    font-size: 14px;
    font-weight: 600;
    -webkit-tap-highlight-color: transparent;
    transition: border-color var(--duration-base) var(--ease-out);
}
.measure-collapse > summary::-webkit-details-marker { display: none; }
.measure-collapse > summary::marker { content: ""; }
.measure-collapse > summary:hover,
.measure-collapse[open] > summary { border-color: var(--accent-2, #2f86b3); }
.measure-collapse-icon {
    color: var(--text-muted);
    transition: transform var(--duration-base) var(--ease-out);
}
.measure-collapse[open] .measure-collapse-icon { transform: rotate(180deg); }
/* Closed: hide the grid. Open: show it (columns come from .measure-inputs). */
.measure-collapse:not([open]) > .measure-inputs { display: none; }
.measure-collapse[open] > .measure-inputs {
    display: grid;
    margin-top: var(--space-4);
}

.body-diagram {
    background:
        radial-gradient(ellipse at top, rgba(47, 174, 158, 0.05), transparent 60%),
        radial-gradient(ellipse at bottom, rgba(126, 224, 207, 0.04), transparent 60%),
        var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 16px;
    color: var(--text-dim);
    /* Hug the photo (no forced 100% height) so the card fills with the figure
       instead of leaving big empty bands above/below it. Centre it beside the
       taller form column. */
    align-self: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-3);
}

.body-diagram svg {
    width: 100%;
    height: auto;
    display: block;
}

/* Hint that the figure markers are tappable — makes the two-way link
   (tap a marker → open the measurements + edit that value) discoverable. */
.measure-figure-hint {
    margin: 0;
    font-size: 12px;
    line-height: 1.4;
    text-align: center;
    color: var(--text-muted);
}
.measure-figure-hint::before {
    content: "\2726  ";
    color: var(--accent-2, #2f86b3);
}

/* Aktiver Preset-Zustand — zeigt, welche Größe gerade geladen ist */
.preset-btn.is-active {
    border-color: transparent;
    color: var(--text);
    background:
        linear-gradient(var(--bg-card), var(--bg-card)) padding-box,
        var(--gradient) border-box;
    border: 1px solid transparent;
    box-shadow: 0 2px 14px rgba(47, 174, 158, 0.22);
}

/* Live berechnete Konfektionsgröße */
.size-readout {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 12px 16px;
    margin-bottom: 24px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
}

.size-readout-label {
    font-size: 12px;
    font-weight: 500;
    color: var(--text-dim);
}

.size-readout-badge {
    font-size: 16px;
    font-weight: 700;
    letter-spacing: 0.5px;
    min-width: 44px;
    text-align: center;
    padding: 4px 12px;
    border-radius: 100px;
    color: white;
    background: var(--gradient);
    box-shadow: 0 2px 12px rgba(47, 174, 158, 0.3);
}

/* Diagramm-Annotation hebt sich hervor, wenn das passende Feld fokussiert wird */
.annotation {
    transition: opacity 0.2s ease;
}

.measure-annotations.has-active .annotation {
    opacity: 0.28;
}

.measure-annotations.has-active .annotation.is-active {
    opacity: 1;
}

.annotation.is-active line {
    stroke: var(--accent-3);
    stroke-width: 5;
    stroke-dasharray: none;
}

.annotation.is-active circle {
    fill: var(--accent-3);
    r: 11;
}

.annotation.is-active text {
    fill: var(--accent-3);
}

/* Tappable markers (wired in app.js) — the figure doubles as a legend that
   jumps to the matching input. */
.annotation.is-tappable { cursor: pointer; }
.annotation.is-tappable:focus-visible {
    outline: 2px solid var(--accent-3, #7ee0cf);
    outline-offset: 3px;
    border-radius: 4px;
}

/* Fokussiertes Maßfeld bekommt eine farbige Markierung */
.measure-field.is-linked input {
    border-color: var(--accent);
    box-shadow: 0 0 0 2px rgba(47, 174, 158, 0.18);
}

/* Drag & Drop für den Foto-Upload */
.photo-upload-card.is-dragover {
    border-color: var(--accent);
    background: linear-gradient(135deg,
        rgba(47, 174, 158, 0.16),
        rgba(47, 134, 179, 0.16),
        rgba(126, 224, 207, 0.12));
}

.toggle {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 13px;
    color: var(--text-dim);
    cursor: pointer;
    margin-bottom: 10px;
    text-transform: none;
    letter-spacing: 0;
    font-weight: 400;
}

.toggle input {
    display: none;
}

/* ============ PRODUCTION SECTION ============ */
.production-section {
    background: var(--bg-elevated);
}

.production-grid {
    display: grid;
    grid-template-columns: 2fr 1fr;
    gap: 32px;
}

.spec-sheet {
    background: white;
    color: #111;
    border-radius: var(--radius);
    padding: 48px;
    font-family: var(--font-body);
    box-shadow: var(--shadow-soft);
}

.spec-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    padding-bottom: 24px;
    border-bottom: 2px solid #111;
    margin-bottom: 32px;
}

.spec-header h3 {
    font-family: var(--font-display);
    font-size: 22px;
    font-weight: 700;
    margin-bottom: 4px;
    letter-spacing: -0.5px;
}

.spec-header p {
    font-size: 13px;
    color: #666;
    font-family: monospace;
}

.spec-date {
    font-size: 12px;
    color: #666;
    text-align: right;
    font-family: monospace;
}

.spec-section {
    margin-bottom: 28px;
}

.spec-section h4 {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 2px;
    color: #666;
    margin-bottom: 12px;
    font-weight: 700;
}

.spec-section p,
.spec-section li {
    color: #222;
    font-size: 14px;
    line-height: 1.6;
}

.spec-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 14px;
}

.spec-table th,
.spec-table td {
    padding: 8px 0;
    border-bottom: 1px solid #eee;
    color: #222;
}

/* Row-header label cell (was a plain td; now <th scope="row"> so AT associates
   each value with its label). Reset the th defaults to match the old look. */
.spec-table th {
    color: #666;
    width: 40%;
    text-align: left;
    font-weight: 400;
}

.spec-table td:last-child {
    text-align: right;
    font-weight: 600;
}

.spec-section ul {
    padding-left: 20px;
}

.spec-section li {
    margin-bottom: 6px;
}

.export-panel {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 32px;
    height: fit-content;
    position: sticky;
    top: 160px;
}

.export-panel h3 {
    font-size: 20px;
    margin-bottom: 8px;
}

.export-panel > p {
    color: var(--text-dim);
    font-size: 14px;
    margin-bottom: 28px;
}

.export-btn {
    width: 100%;
    background: var(--surface);
    border: 1px solid var(--border);
    color: var(--text);
    padding: 14px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-size: 14px;
    font-weight: 500;
    margin-bottom: 10px;
    transition: all 0.2s;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
}

.export-btn:hover {
    border-color: var(--accent);
    background: var(--gradient-dim);
}

.export-btn.primary {
    background: var(--gradient-cta);
    color: var(--bg);
    border-color: transparent;
    font-weight: 600;
    box-shadow: 0 4px 16px rgba(47, 174, 158, 0.25);
}

.export-btn.primary:hover {
    transform: translateY(-1px);
    box-shadow: 0 6px 24px rgba(47, 174, 158, 0.4);
}

.export-btn.dark {
    background: #111;
    border-color: #111;
    color: white;
}

.estimate {
    margin-top: 28px;
    padding-top: 24px;
    border-top: 1px solid var(--border);
}

.estimate-line {
    display: flex;
    justify-content: space-between;
    font-size: 13px;
    color: var(--text-dim);
    padding: 6px 0;
}

.estimate-line span:last-child {
    color: var(--text);
    font-weight: 600;
}

/* ============ FOOTER ============ */
.footer {
    padding: var(--space-10) 0 var(--space-7);
    border-top: 1px solid var(--border);
    background: var(--bg);
}

.footer-grid {
    display: grid;
    grid-template-columns: 2fr 1fr 1fr;
    gap: var(--space-9);
    padding-bottom: var(--space-7);
    border-bottom: 1px solid var(--border);
}

.footer-brand-col { max-width: 360px; }

.footer-logo {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: var(--space-4);
}

.footer-tagline {
    color: var(--text-dim);
    font-size: var(--text-sm);
    line-height: var(--leading-snug);
    text-wrap: pretty;
}

.footer-col h2 {
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: var(--tracking-wider);
    color: var(--text-muted);
    text-transform: uppercase;
    margin: 0 0 var(--space-4);
}

.footer-col ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.footer-col a {
    color: var(--text-dim);
    text-decoration: none;
    font-size: var(--text-sm);
    transition: color var(--duration-fast) var(--ease-out);
}

.footer-col a:hover { color: var(--text); }

.footer-meta {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding-top: var(--space-6);
    color: var(--text-muted);
    font-size: var(--text-xs);
    text-align: center;
}

/* No opacity: it would composite --text-muted below the 4.5:1 WCAG-AA
   contrast floor on --bg (axe-core gate in scripts/e2e.mjs). The token
   itself clears it (~5:1); fine print stays muted via the token, not alpha. */
.footer-meta-fine { color: var(--text-muted); }

/* Older `.footer-content` rule retained for legacy compatibility — the
   new layout uses `.footer-grid`. */

@media (max-width: 700px) {
    .footer-grid {
        grid-template-columns: 1fr;
        gap: var(--space-7);
    }
}

/* ============ TOAST ============ */
.toast {
    position: fixed;
    bottom: 32px;
    right: 32px;
    background: var(--bg-card);
    color: var(--text);
    padding: 14px 20px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
    box-shadow: var(--shadow-soft);
    font-size: 14px;
    transform: translateY(100px);
    opacity: 0;
    /* Explicit props (not `all`) at ≤250ms — honours the no-layout-jump /
       transition-budget rule; these are exactly what .show/.success/.error change. */
    transition: transform 0.25s, opacity 0.25s, border-color 0.25s;
    z-index: 1000;
    max-width: 380px;
}

.toast.show {
    transform: translateY(0);
    opacity: 1;
}

.toast.success {
    border-color: var(--success);
}

.toast.error {
    border-color: var(--danger);
}

/* ============ LEGAL PAGES (Impressum / Datenschutz) ============ */
.legal-page {
    max-width: 820px;
    margin: 0 auto;
    padding: 140px var(--space-6) var(--space-11);
}

.legal-page h1 {
    font-family: var(--font-display);
    font-size: var(--text-3xl);
    letter-spacing: var(--tracking-tight);
    margin-bottom: var(--space-3);
}

/* Lange deutsche Komposita („Datenschutzerklärung") dürfen auf Phone-Breite
   nicht überlaufen — trennen statt sprengen (greift nur bei Platznot). */
.legal-page h1,
.legal-page h2,
.legal-page h3 {
    overflow-wrap: anywhere;
    hyphens: auto;
    -webkit-hyphens: auto;
}

.legal-page .legal-lead {
    color: var(--text-dim);
    font-size: var(--text-md);
    margin-bottom: var(--space-9);
}

.legal-page h2 {
    font-size: var(--text-xl);
    margin: var(--space-9) 0 var(--space-3);
    padding-top: var(--space-6);
    border-top: 1px solid var(--border);
}

.legal-page h3 {
    font-size: var(--text-md);
    margin: var(--space-6) 0 var(--space-2);
    color: var(--text);
}

.legal-page p,
.legal-page li {
    color: var(--text-dim);
    line-height: var(--leading-normal);
    margin-bottom: var(--space-3);
}

.legal-page ul {
    padding-left: var(--space-6);
    margin-bottom: var(--space-4);
}

.legal-page a { color: var(--accent-3); }

.legal-page .legal-note {
    margin-top: var(--space-9);
    padding: var(--space-4) var(--space-5);
    background: var(--gradient-dim);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font-size: var(--text-sm);
    color: var(--text-dim);
}

.legal-back {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    margin-bottom: var(--space-7);
    color: var(--text-dim);
    text-decoration: none;
    font-size: var(--text-sm);
}
.legal-back:hover { color: var(--text); }

/* ============================================================
   404 — Seite nicht gefunden (404.html)
   Eigenständige, zweisprachige Fehlerseite. Nutzt die Landing-Chrome
   (lp-nav / lp-btn / lang-toggle / footer) + markenkonforme Tokens. Die
   data-l-Spans blenden je <html lang> die passende Sprache ein (rein CSS;
   ohne JS bleibt das markup-seitige DE sichtbar → Progressive Enhancement).
   ============================================================ */
html[lang="de"] [data-l="en"],
html[lang="en"] [data-l="de"] { display: none; }

.nf-page {
    position: relative;
    /* svh statt vh: stabile Höhe trotz iOS-Toolbar, kein Sprung. Die Nav ist
       fixed (0 Layout-Höhe) → padding-top hält den Text frei darunter. */
    min-height: 100vh;
    min-height: 100svh;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: calc(64px + var(--space-9)) clamp(20px, 5vw, 48px) var(--space-9);
    overflow: hidden;
}
.nf-aurora { opacity: 0.7; }
.nf-inner {
    position: relative;
    z-index: 1;
    max-width: 640px;
}
.nf-eyebrow {
    display: block;
    color: var(--accent-3);
    margin-bottom: var(--space-5);
}
.nf-title {
    font-family: var(--font-display);
    font-weight: 500;
    font-size: clamp(40px, 9vw, 92px);
    line-height: 1.05;
    letter-spacing: var(--tracking-tighter);
    margin: 0;
}
.nf-title em {
    font-style: italic;
    background: var(--gradient);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    padding-right: 0.06em;
}
.nf-sub {
    max-width: 30rem;
    margin: var(--space-6) auto 0;
    color: var(--text-dim);
    font-weight: 300;
    font-size: clamp(15px, 1.6vw, 17px);
    line-height: 1.65;
}
.nf-ctas {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    justify-content: center;
    margin-top: var(--space-8);
}
.nf-footer { background-color: rgba(10, 22, 34, 0.85); }

/* ============ PRINT ============ */
@media print {
    body * { visibility: hidden; }
    .spec-sheet, .spec-sheet * { visibility: visible; }
    .spec-sheet {
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        box-shadow: none;
    }
    /* Werkstatt-Tinte statt Bildschirm-Bühne: echte Drucker lassen
       Hintergründe weg — ohne Tinten-Palette stünde helle Bildschirm-Schrift
       auf weissem Papier (vorbestehender Fund dieser Runde). Das ganze Sheet
       druckt dunkel-auf-weiss, die helle Linienzeichnung invertiert. */
    .spec-sheet { background: #fff !important; color: #111 !important; border: none !important; }
    .spec-sheet h3, .spec-sheet h4, .spec-sheet p, .spec-sheet th, .spec-sheet td, .spec-sheet li, .spec-sheet span, .spec-sheet div { color: #111 !important; }
    .spec-sheet .spec-table th, .spec-sheet .spec-table td { border-color: #ddd !important; }
    .spec-sheet .spec-drawing-note { color: #555 !important; }
    .spec-drawing { background: #fff !important; border: none !important; padding: 0 !important; }
    .spec-drawing svg { filter: invert(1) hue-rotate(180deg); }
}

/* Die Vorlage wird echt: die technische Zeichnung des Stücks im Spec-Sheet —
   dieselbe Studio-Bühnensprache wie Vorschau/Atelier/Ownership, gerendert aus
   denselben Flat-Params (app.js currentFlatParams). */
.spec-drawing { border-radius: var(--radius); border: 1px solid var(--border); padding: 14px; background: radial-gradient(70% 44% at 50% 4%, rgba(150, 205, 228, 0.08), rgba(150, 205, 228, 0) 60%), radial-gradient(130% 100% at 50% 34%, #122638, var(--bg)72%); }
.spec-drawing svg { display: block; width: 100%; max-height: 340px; }
.spec-drawing:empty { display: none; }
.spec-drawing-note { margin: 8px 0 0; font-size: var(--text-xs); color: #666; }

/* ============ RESPONSIVE ============ */
@media (max-width: 900px) {
    .nav-toggle { display: flex; }

    /* Off-canvas dropdown menu — slides down from the navbar */
    .nav-links {
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        flex-direction: column;
        gap: 0;
        background: rgba(10, 22, 34, 0.96);
        backdrop-filter: blur(20px);
        -webkit-backdrop-filter: blur(20px);
        border-bottom: 1px solid var(--border);
        padding: var(--space-2) var(--space-6) var(--space-5);
        transform: translateY(-12px);
        opacity: 0;
        pointer-events: none;
        visibility: hidden;
        transition: transform var(--duration-base) var(--ease-out),
                    opacity var(--duration-base) var(--ease-out),
                    visibility 0s linear var(--duration-base);
    }
    .nav-links.open {
        transform: translateY(0);
        opacity: 1;
        pointer-events: auto;
        visibility: visible;
        transition: transform var(--duration-base) var(--ease-out),
                    opacity var(--duration-base) var(--ease-out);
    }
    .nav-links li {
        border-bottom: 1px solid var(--border);
    }
    .nav-links li:last-child { border-bottom: none; }
    .nav-links a {
        display: block;
        padding: var(--space-4) 0;
        font-size: var(--text-base);
    }
    .nav-links a::after { display: none; }

    .design-grid,
    .measure-grid,
    .production-grid,
    .preview-container {
        grid-template-columns: 1fr;
    }
    .vto-stage,
    .vto-stage .vto-result-img,
    #vto-example.has-image {
        min-height: 440px;
        max-height: none;
    }
    .measure-inputs {
        grid-template-columns: 1fr 1fr;
    }
    .type-grid {
        grid-template-columns: repeat(2, 1fr);
    }
    .section {
        padding: 80px 0;
    }
    .step span {
        width: 24px;
        height: 24px;
    }
    .spec-sheet {
        padding: 24px;
    }
    .export-panel {
        position: static;
    }
}

@media (max-width: 600px) {
    /* Collapsed measurements show two compact columns when opened (see the
       .measure-collapse[open] rule); the bare 1-col fallback stays for any
       inputs grid not inside the collapse. */
    .measure-inputs { grid-template-columns: 1fr 1fr; }

    /* Step-3 teaser on phones: the portrait teaser fills the stacked stage with
       `cover`; the generated result keeps its natural portrait size. */
    .vto-stage .vto-result-img { min-height: 0; max-height: 75svh; }

    .hero-eyebrow { letter-spacing: var(--tracking-wide); }

    .section { padding: var(--space-11) 0; }

    .section-header { margin-bottom: var(--space-8); }

    .section-header h2 { font-size: clamp(28px, 8vw, 40px); }

    .section-header p { font-size: var(--text-base); }

    /* Step tracker — scrollable horizontally so it doesn't crunch */

    /* Fit all four steps on one row — no horizontal scroll (the cut-off
       4th step + the masked connector line read as "unfinished" on phones). */
/* drop the fragile connector line on mobile */
    .step {
        flex: 0 1 auto;
        min-width: 0;
        gap: 6px;
        font-size: 10px;
        white-space: nowrap;
        background: transparent;
        padding-right: 0;
    }
    .step span { flex: 0 0 auto; }

    /* Panels: tighter padding */
    .prompt-panel,
    .result-panel { padding: var(--space-6); }

    /* Library modal on mobile */
    .library-modal { padding: var(--space-3); }
    .library-modal-content {
        padding: var(--space-6) var(--space-5);
        border-radius: var(--radius);
    }
    .library-modal-head h3 { font-size: 22px; }
    .library-grid {
        grid-template-columns: 1fr 1fr;
        gap: var(--space-3);
    }
    .library-tile-body { padding: var(--space-3); }
    .library-tile-body h4 { font-size: 14px; }
    .library-tile-meta,
    .library-tile-date { font-size: 10px; }
    .library-tile-load { padding: var(--space-2) var(--space-3); font-size: 12px; }

    /* Body diagram doesn't need to be huge on mobile */
    .body-diagram { padding: var(--space-4); }
    .body-diagram svg { max-height: 70svh; }

    /* Spec sheet readability */
    .spec-sheet { padding: var(--space-5) !important; }

    /* Footer */
    .footer { padding: var(--space-7) 0; }

    /* Toast: center bottom instead of corner so it doesn't get cut */
    .toast {
        left: var(--space-4);
        right: var(--space-4);
        bottom: var(--space-4);
        max-width: none;
    }
}

@media (max-width: 400px) {
    .nav-container { padding: var(--space-3) var(--space-4); }
    .logo-text { display: none; }
    /* Narrowest phones: tighten so all four steps still fit one row. */
    .step { gap: 4px; }
    .step span { width: 20px; height: 20px; }
    .type-grid { grid-template-columns: repeat(3, 1fr); }
    .type-btn { padding: var(--space-3); }
    .type-btn svg { width: 28px; height: 28px; }
}

/* ============================================================
   Virtual Try-On — photorealistic preview button + result modal
   ============================================================ */

.vto-btn {
    width: 100%;
    padding: 18px 24px;
    background: var(--gradient-cta);
    color: var(--bg);
    border: none;
    border-radius: var(--radius);
    font-size: 1rem;
    font-weight: 600;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    transition: transform 0.15s ease, opacity 0.15s ease;
}

.vto-btn:hover:not(:disabled) {
    transform: translateY(-1px);
}

.vto-btn:disabled {
    opacity: 0.45;
    cursor: not-allowed;
    background: var(--bg-elevated);
    color: var(--text-muted);
}

.vto-btn-text {
    font-size: 1rem;
}

.vto-btn-hint {
    font-size: 0.78rem;
    font-weight: 400;
    opacity: 0.85;
}

.vto-disclaimer {
    margin-top: 10px;
    font-size: 0.75rem;
    color: var(--text-muted);
    line-height: 1.45;
    text-align: center;
}

.vto-loading {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 18px;
    padding: 48px 24px;
}

/* Error state (set by setVtoError): the spinner is gone, so make the message
   read as a final, legible notice — full-contrast text in a subtly bordered
   panel — instead of a faint placeholder that looks like it is still loading.
   Brand-safe: no red and no --accent-warm (reserved for #your-style); only
   the existing neutral tokens. */
.vto-loading.has-error {
    gap: 8px;
    padding: 28px 24px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: rgba(255, 255, 255, 0.025);
}
.vto-loading.has-error #vto-status {
    color: var(--text);
    font-weight: 500;
}

.vto-spinner {
    width: 56px;
    height: 56px;
    border: 4px solid var(--border);
    border-top-color: transparent;
    border-radius: 50%;
    background: conic-gradient(from 0deg, transparent, transparent 75%, var(--accent) 88%, var(--accent-2) 100%);
    -webkit-mask: radial-gradient(circle at center, transparent 18px, black 22px);
            mask: radial-gradient(circle at center, transparent 18px, black 22px);
    animation: vto-spin 1.1s linear infinite;
}

@keyframes vto-spin {
    to { transform: rotate(360deg); }
}

.vto-result-img {
    width: 100%;
    max-height: 70svh;
    object-fit: contain;
    border-radius: var(--radius);
    display: block;
}

/* ── Inline photorealistic preview stage (step 3) ── */
.vto-stage {
    position: relative;
    width: 100%;
    min-height: 600px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: radial-gradient(circle at center, #1a1a1f 0%, var(--bg)100%);
    overflow: hidden;
}
.vto-stage .vto-result-img {
    width: auto;
    max-width: 100%;
    max-height: 600px;
}
/* Respect the hidden attribute even though .vto-loading sets display:flex and
   .vto-result-img sets display:block (explicit display otherwise beats [hidden]). */
.vto-stage .vto-loading[hidden],
.vto-stage .vto-result-img[hidden] { display: none; }

.vto-example {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
    text-align: center;
    padding: 40px;
    max-width: 460px;
}
.vto-example[hidden] { display: none; }
.vto-example-tag {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 2px;
    font-weight: 700;
    color: #fff;
    background: var(--gradient);
    padding: 5px 12px;
    border-radius: 999px;
}
.vto-example-label {
    color: var(--text-muted);
    line-height: 1.65;
    max-width: 360px;
}
/* Static teaser image for the no-photo state; .has-image hides the placeholder
   text and pins the BEISPIEL badge over the photo. Portrait crop (vto-teaser)
   so it fills the portrait stage with `cover` on every device — the old wide
   16:9 source got cover-cropped to an empty sliver in the tall two-column
   stage on iPad/Safari. */
#vto-example.has-image {
    width: 100%;
    height: 100%;
    /* Override the .vto-example 460px cap so the photo fills the whole stage
       instead of being boxed into a narrow centred column. */
    max-width: none;
    padding: 0;
    background-image: url("../assets/vto-teaser.jpg");
    background-size: cover;
    background-repeat: no-repeat;
    background-position: center;
    justify-content: flex-end;
    align-items: flex-start;
}
#vto-example.has-image .vto-example-label { display: none; }

/* "Dein Stück" auf der Anprobe-Bühne: statt des Beispielfotos liegt die echte
   Flat des Entwurfs im Studio-Licht (dieselbe Bühnensprache wie Vorschau und
   Atelier); das Badge nennt es, die Unterzeile lädt zur Anprobe ein. */
#vto-example.has-flat {
    width: 100%;
    height: 100%;
    max-width: none;
    padding: 24px 16px 16px;
    justify-content: center;
    background: radial-gradient(70% 44% at 50% 4%, rgba(150, 205, 228, 0.1), rgba(150, 205, 228, 0) 60%), radial-gradient(120% 70% at 50% 118%, rgba(2, 7, 12, 0.6), rgba(2, 7, 12, 0) 55%), radial-gradient(130% 100% at 50% 34%, #122638, var(--bg)72%);
}
#vto-example.has-flat .own-flat { flex: 1; min-height: 0; width: min(300px, 82%); display: flex; align-items: center; }
#vto-example.has-flat .own-flat svg { width: 100%; height: 100%; max-height: 520px; display: block; }
#vto-example.has-flat .vto-example-tag { position: absolute; top: 14px; left: 14px; }
#vto-example.has-flat .vto-example-label { font-size: var(--text-sm); max-width: 320px; }

.vto-result-actions[hidden] { display: none; }

.vto-result-actions {
    display: flex;
    justify-content: center;
    margin-top: 16px;
}

.vto-download-btn {
    background: var(--gradient-cta);
    color: var(--bg);
    border: none;
    border-radius: var(--radius);
    padding: 12px 28px;
    font-size: 0.95rem;
    font-weight: 600;
    cursor: pointer;
    transition: transform 0.15s ease, box-shadow 0.2s ease;
    font-family: inherit;
    box-shadow: 0 0 30px rgba(47, 174, 158, 0.25);
}

.vto-download-btn:hover {
    transform: translateY(-1px);
    box-shadow: 0 0 40px rgba(47, 174, 158, 0.4);
}

.vto-download-btn:focus-visible {
    outline: 2px solid var(--accent-3);
    outline-offset: 3px;
}

#vto-status {
    color: var(--text-muted);
    font-size: 0.9rem;
    text-align: center;
}

/* ============================================================
   WOW LAYER — Visual upgrades stacked on top of the base system
   Goal: high-fashion digital studio feel (Off-White / Acne / SSENSE)
   ============================================================ */

/* ---------- Film grain — adds tactile, analog feel to the dark canvas ---------- */
body::before {
    content: '';
    position: fixed;
    inset: 0;
    z-index: 1000;
    pointer-events: none;
    opacity: 0.035;
    mix-blend-mode: overlay;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
    background-size: 200px 200px;
}

/* ---------- Hero: animated conic gradient mesh (slowly rotating) ---------- */
.hero::after {
    content: '';
    position: absolute;
    inset: -50%;
    z-index: 0;
    pointer-events: none;
    background: conic-gradient(
        from 0deg at 50% 50%,
        rgba(47, 174, 158, 0.08),
        rgba(47, 134, 179, 0.08),
        rgba(126, 224, 207, 0.06),
        rgba(47, 174, 158, 0.08)
    );
    filter: blur(60px);
    animation: spinSlow 60s linear infinite;
}
@keyframes spinSlow {
    to { transform: rotate(360deg); }
}

/* Crisper orb animations — subtle scale breathing */
.orb { animation: floatBreathe 22s ease-in-out infinite; }
@keyframes floatBreathe {
    0%, 100% { transform: translate(0, 0) scale(1); opacity: 0.5; }
    33%      { transform: translate(30px, -50px) scale(1.08); opacity: 0.6; }
    66%      { transform: translate(-30px, 30px) scale(0.95); opacity: 0.45; }
}

/* ---------- Glassmorphism cards ---------- */
.prompt-panel,
.result-panel,
.measure-form,
.body-diagram,
.preview-controls,
.export-panel {
    background: linear-gradient(
        135deg,
        rgba(24, 24, 27, 0.65) 0%,
        rgba(31, 31, 35, 0.55) 100%
    ) !important;
    backdrop-filter: blur(24px) saturate(140%);
    -webkit-backdrop-filter: blur(24px) saturate(140%);
    border: 1px solid rgba(255, 255, 255, 0.06) !important;
    box-shadow:
        0 1px 0 rgba(255, 255, 255, 0.04) inset,
        0 20px 60px -20px rgba(0, 0, 0, 0.6),
        0 0 0 1px rgba(255, 255, 255, 0.02);
    position: relative;
}

/* Gradient hairline on top edge of cards — fashion-mag chrome detail */
.prompt-panel::before,
.result-panel::before,
.measure-form::before,
.export-panel::before {
    content: '';
    position: absolute;
    top: 0; left: 12%; right: 12%;
    height: 1px;
    background: linear-gradient(90deg,
        transparent 0%,
        rgba(47, 174, 158, 0.4) 50%,
        transparent 100%);
    pointer-events: none;
}

/* ---------- Step tracker: animated progress line + glow on active ---------- */
.step { position: relative; z-index: 1; background: var(--bg); padding-right: 8px; }
.step.active span {
    box-shadow:
        0 0 0 4px rgba(47, 174, 158, 0.15),
        0 0 20px rgba(47, 174, 158, 0.55);
    animation: pulseRing 2.4s ease-in-out infinite;
}
@keyframes pulseRing {
    0%, 100% { box-shadow: 0 0 0 4px rgba(47, 174, 158, 0.15), 0 0 20px rgba(47, 174, 158, 0.55); }
    50%      { box-shadow: 0 0 0 6px rgba(47, 174, 158, 0.25), 0 0 28px rgba(47, 174, 158, 0.75); }
}

/* ---------- Section entrance reveal ----------
   One-shot fade on load — deliberately NOT scroll-driven. A scroll-driven
   animation-timeline: view() remaps its progress on EVERY viewport resize; in
   in-app browsers (Instagram) the bottom toolbar appears on scroll-up and
   resizes the viewport, which remapped the section transform and flung the
   page ("catapult", per the user's own diagnosis). An on-load animation has
   zero scroll coupling, so toggling the toolbar can't move anything — works on
   every browser with no touch detection needed. Touch devices skip the
   animation entirely via the .is-touch / any-pointer rules further below. */
.section {
    animation: revealUp 0.9s ease-out both;
}
@keyframes revealUp {
    from { opacity: 0; transform: translateY(40px); }
    to   { opacity: 1; transform: translateY(0); }
}
/* iOS Safari runs per-frame layout work for any registered scroll-driven
   timeline — even when its animation-name is none — which fights momentum
   scrolling and the dynamic toolbar, flinging the page up then back down
   while scrolling the wizard. #103 only reset the animation (transform), NOT
   the timeline, so the expensive view() registration stayed live on every
   section. Fully detach the timeline on touch devices; desktop keeps the
   reveal. (animation:none alone does not reset animation-timeline in Safari.)
   any-pointer: coarse — NOT pointer:coarse — so this still applies on an iPad
   with a trackpad attached (primary pointer reports as fine, but the device
   has a touchscreen), which is exactly where the section-boundary catapult
   was reported. */
@media (any-pointer: coarse) {
    .section {
        animation: none;
        animation-timeline: auto;
        animation-range: normal;
        opacity: 1;
        transform: none;
    }
    /* Smooth scroll on <html> lets iOS animate every scroll correction, which
       reads as the page being "flung". Touch gets native instant scrolling. */
    html { scroll-behavior: auto; }
}
/* Load-bearing duplicate gated on the JS .is-touch class — the media query
   above does not fire in Instagram/Facebook in-app browsers, which is exactly
   where the catapult kept happening after the any-pointer fix worked in
   Safari. Keep both: media query for correct browsers, class for the rest. */
html.is-touch .section {
    animation: none;
    animation-timeline: auto;
    animation-range: normal;
    opacity: 1;
    transform: none;
}
html.is-touch { scroll-behavior: auto; }

/* ---------- Buttons: subtle hover lift + accent glow ---------- */
.primary-btn,
.cta-button,
.upload-btn,
.export-btn.primary {
    transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1),
                box-shadow 0.25s ease;
}
.primary-btn:hover,
.export-btn.primary:hover {
    transform: translateY(-2px) scale(1.01);
}

/* ---------- AI output: typing cursor + pulse on generation ---------- */
.design-result h3 {
    background: linear-gradient(120deg, #fff 0%, #e879f9 50%, #fff 100%);
    background-size: 200% auto;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    animation: shineText 6s linear infinite;
}
@keyframes shineText {
    to { background-position: -200% center; }
}

/* ---------- Section number: magazine-style accent ---------- */
.section-number {
    position: relative;
    display: inline-block;
    padding-left: 28px;
}
.section-number::before {
    content: '';
    position: absolute;
    left: 0; top: 50%;
    transform: translateY(-50%);
    width: 20px; height: 1px;
    background: var(--accent);
}

/* ---------- Logo mark: animated gradient ---------- */
.logo-mark {
    background-size: 200% 200%;
    animation: shiftGradient 8s ease infinite;
}
@keyframes shiftGradient {
    0%, 100% { background-position: 0% 50%; }
    50%      { background-position: 100% 50%; }
}

/* ---------- Reduced-motion respect ---------- */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

/* ============================================================
   Saved Designs Library — trigger pill, modal, tile grid
   ============================================================ */

.library-trigger[hidden] { display: none !important; }

.library-trigger {
    margin-top: 14px;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 8px 16px 8px 12px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 100px;
    color: var(--text-dim);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    font-family: inherit;
    transition: border-color 0.2s, color 0.2s, transform 0.15s;
}

.library-trigger:hover {
    border-color: var(--accent);
    color: var(--text);
    transform: translateY(-1px);
}

.library-trigger-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: var(--gradient);
    color: white;
}

.library-trigger-count {
    min-width: 22px;
    height: 22px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 8px;
    border-radius: 100px;
    background: var(--surface);
    border: 1px solid var(--border);
    font-size: 11px;
    font-weight: 700;
    color: var(--text);
}

.library-modal[hidden] { display: none; }

.library-modal {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
}

.library-modal-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.78);
    backdrop-filter: blur(8px);
}

.library-modal-content {
    position: relative;
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 28px 28px 32px;
    max-width: 960px;
    width: 100%;
    max-height: 88svh;
    overflow-y: auto;
    box-shadow: var(--shadow-soft);
}

.library-modal-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 6px;
}

.library-modal-head h3 {
    font-family: var(--font-display);
    font-size: 28px;
    margin: 0;
}

.library-modal-close {
    width: 36px;
    height: 36px;
    border: none;
    background: transparent;
    color: var(--text-muted);
    font-size: 1.8rem;
    cursor: pointer;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: inherit;
}

.library-modal-close:hover {
    background: var(--bg);
    color: var(--text);
}

.library-modal-hint {
    color: var(--text-muted);
    font-size: 13px;
    margin: 0 0 22px;
}

.library-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 18px;
}

.library-tile {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    transition: border-color 0.2s, transform 0.15s;
}

.library-tile:hover {
    border-color: var(--accent);
    transform: translateY(-2px);
}

.library-tile-visual {
    position: relative;
    aspect-ratio: 1;
    background: var(--gradient-dim);
    display: flex;
    align-items: center;
    justify-content: center;
}

.library-tile-photo {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.library-tile-icon {
    width: 80px;
    height: 80px;
    display: flex;
    align-items: center;
    justify-content: center;
    filter: drop-shadow(0 0 16px rgba(47, 174, 158, 0.3));
}

.library-tile-swatch {
    position: absolute;
    bottom: 10px;
    right: 10px;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    border: 2px solid var(--bg-card);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4);
}

.library-tile-body {
    padding: 14px;
    display: flex;
    flex-direction: column;
    gap: 4px;
    flex: 1;
}

.library-tile-body h4 {
    font-family: var(--font-display);
    font-size: 17px;
    line-height: 1.2;
    margin: 0;
}

.library-tile-meta {
    font-size: 11px;
    color: var(--text-dim);
    letter-spacing: 0.8px;
    text-transform: uppercase;
    margin: 0;
}

.library-tile-date {
    font-size: 11px;
    color: var(--text-muted);
    margin: 0 0 8px;
}

.library-tile-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: auto;
    padding-top: 8px;
}

.library-tile-load {
    flex: 1;
    padding: 8px 14px;
    background: var(--gradient);
    color: white;
    border: none;
    border-radius: var(--radius-sm);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    font-family: inherit;
    transition: transform 0.15s;
}

.library-tile-load:hover { transform: translateY(-1px); }

.library-tile-delete {
    width: 32px;
    height: 32px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 50%;
    color: var(--text-dim);
    font-size: 1.3rem;
    cursor: pointer;
    font-family: inherit;
    display: flex;
    align-items: center;
    justify-content: center;
}

.library-tile-delete:hover {
    border-color: var(--danger);
    color: var(--danger);
}

/* ============================================================
   Scroll-driven reveals + micro-interactions
   ============================================================ */

[data-reveal] {
    opacity: 0;
    transform: translateY(24px);
    transition:
        opacity var(--duration-slow, 420ms) var(--ease-out, cubic-bezier(0.16,1,0.3,1)),
        transform var(--duration-slow, 420ms) var(--ease-out, cubic-bezier(0.16,1,0.3,1));
    transition-delay: var(--reveal-delay, 0ms);
    will-change: opacity, transform;
}

[data-reveal].is-revealed {
    opacity: 1;
    transform: none;
}

/* When reduced motion is requested, render the final state immediately
   without any transition or delay so users never see the pre-state. */
@media (prefers-reduced-motion: reduce) {
    [data-reveal] {
        opacity: 1 !important;
        transform: none !important;
        transition: none !important;
    }
}

/* ── Modul C · Reveal-Upgrade (Blur + Rise) ────────────────────────────────
   Variante des bestehenden Reveal-Systems (animations.js unverändert): nur die
   Elemente mit data-reveal="blur" bekommen zusätzlich einen Blur-Rise. Selektor
   matcht exakt den Wert "blur" → attributlose data-reveal bleiben unangetastet. */
[data-reveal="blur"] {
    transform: translateY(22px);
    filter: blur(10px);
    transition:
        opacity 1s var(--ease-out, cubic-bezier(0.16,1,0.3,1)),
        transform 1s var(--ease-out, cubic-bezier(0.16,1,0.3,1)),
        filter 1s var(--ease-out, cubic-bezier(0.16,1,0.3,1));
    transition-delay: var(--reveal-delay, 0ms);
    will-change: opacity, transform, filter;
}
[data-reveal="blur"].is-revealed { filter: blur(0); }

/* f02 · „Liquid"-Variante für den Schlussakkord: Text materialisiert sich —
   Blur + sanftes Verdichten (letter-spacing 0.06em → 0). Bewusst KEIN
   feDisplacementMap auf i18n-HTML-Text (auf iOS Safari notorisch kaputt). */
[data-reveal="liquid"] {
    transform: translateY(18px);
    filter: blur(14px);
    letter-spacing: 0.06em;
    transition:
        opacity 1.1s var(--ease-out, cubic-bezier(0.16,1,0.3,1)),
        transform 1.1s var(--ease-out, cubic-bezier(0.16,1,0.3,1)),
        filter 1.1s var(--ease-out, cubic-bezier(0.16,1,0.3,1)),
        letter-spacing 1.1s var(--ease-out, cubic-bezier(0.16,1,0.3,1));
    transition-delay: var(--reveal-delay, 0ms);
    will-change: opacity, transform, filter;
}
[data-reveal="liquid"].is-revealed { filter: blur(0); letter-spacing: 0em; }
/* Reduced-motion: der Basis-Guard neutralisiert opacity/transform/transition,
   NICHT aber filter/letter-spacing → hier explizit, sonst bliebe die Headline
   verschwommen bzw. gesperrt. */
@media (prefers-reduced-motion: reduce) {
    [data-reveal="blur"], [data-reveal="liquid"] { filter: none !important; }
    [data-reveal="liquid"] { letter-spacing: 0em !important; }
}

/* Navbar gets a stronger background after the user has scrolled past
   the hero — JS toggles `.scrolled` on the .navbar element. */
.nav-shell {
    transition:
        background var(--duration-base) var(--ease-out),
        border-color var(--duration-base) var(--ease-out),
        backdrop-filter var(--duration-base) var(--ease-out);
}

.navbar.scrolled .nav-shell {
    background: rgba(10, 22, 34, 0.88);
    border-bottom-color: rgba(255, 255, 255, 0.06);
}

/* Cards lift slightly on hover — same easing/duration tokens
   throughout for a consistent motion language. */
.prompt-panel,
.result-panel {
    transition:
        border-color var(--duration-base) var(--ease-out),
        transform var(--duration-base) var(--ease-out),
        box-shadow var(--duration-base) var(--ease-out);
}

.prompt-panel:hover,
.result-panel:hover {
    border-color: rgba(255, 255, 255, 0.08);
    box-shadow: 0 12px 48px rgba(0, 0, 0, 0.35);
}

/* Type buttons (T-Shirt / Hoodie / ...) — refined hover + selected state */
.type-btn {
    transition:
        transform var(--duration-fast) var(--ease-out),
        border-color var(--duration-base) var(--ease-out),
        background var(--duration-base) var(--ease-out),
        color var(--duration-base) var(--ease-out);
}

.type-btn:hover:not(.active) {
    transform: translateY(-2px);
    border-color: rgba(255, 255, 255, 0.18);
}

/* Color swatches — clearer press/select feedback */
.color-swatch {
    transition:
        transform var(--duration-fast) var(--ease-out),
        box-shadow var(--duration-base) var(--ease-out),
        border-color var(--duration-base) var(--ease-out);
    cursor: pointer;
}

.color-swatch:hover { transform: scale(1.12); }
.color-swatch:active { transform: scale(0.96); }

/* Step tracker — animated active step indicator */
.step span {
    transition:
        background var(--duration-base) var(--ease-out),
        color var(--duration-base) var(--ease-out),
        transform var(--duration-base) var(--ease-out),
        box-shadow var(--duration-base) var(--ease-out);
}

.step.active span {
    box-shadow: 0 0 24px rgba(47, 174, 158, 0.4);
}

/* Body-diagram + library tiles — subtle hover lift */
.body-diagram {
    transition: border-color var(--duration-base) var(--ease-out);
}

.body-diagram:hover {
    border-color: rgba(255, 255, 255, 0.08);
}

/* CTA gradient sheen on hover */

/* ============================================================
   A11y — skip link + landmark refinement
   ============================================================ */

.skip-link {
    position: absolute;
    top: -100px;
    left: 0;
    background: var(--gradient);
    color: white;
    padding: var(--space-3) var(--space-5);
    font-size: var(--text-sm);
    font-weight: 600;
    border-bottom-right-radius: var(--radius-sm);
    z-index: 1001;
    text-decoration: none;
    transition: top var(--duration-base) var(--ease-out);
}

.skip-link:focus {
    top: 0;
    outline: 3px solid var(--accent-3);
    outline-offset: 2px;
}

main { display: block; }

/* ============================================================
   Trust Strip — brand values band between hero and workflow
   ============================================================ */

/* ── Manifesto — compact thesis band right after the hero ── */
.manifesto {
    position: relative;
    padding: var(--space-12) 0;
    background:
        radial-gradient(ellipse 70% 60% at 50% 0%, rgba(47, 134, 179, 0.10), transparent 70%),
        var(--bg);
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
}
.manifesto-eyebrow {
    font-family: var(--font-body);
    font-weight: 600;
    font-size: var(--text-sm);
    letter-spacing: var(--tracking-wider, 0.18em);
    text-transform: uppercase;
    background: var(--gradient);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    margin: 0 0 var(--space-5);
}
.manifesto-cta {
    display: inline-flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-4) var(--space-8);
    border-radius: 100px;
    background: var(--gradient-cta);
    color: var(--bg);
    font-weight: 600;
    font-size: var(--text-base);
    text-decoration: none;
    box-shadow: var(--shadow-glow);
    transition: transform 0.2s var(--ease-out, ease);
}
.manifesto-cta:hover { transform: translateY(-2px); }
.manifesto-link {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    color: var(--text-dim);
    font-size: var(--text-base);
    text-decoration: none;
    transition: color 0.2s ease;
}
.manifesto-link:hover { color: var(--text); }

/* ── How it works — compact 3-step "our model" bridge into the tool ── */
/* KI als Pluspunkt, nicht Hauptpunkt: ruhige, abgesetzte Fußnote unter den
   Payoff-Chips — gedämpft, nur "Und die KI?" trägt den Akzent. */

/* ── The true cost — fast-fashion evidence band (after the scroll story) ── */
.cost {
    position: relative;
    padding: var(--space-12) 0 var(--space-11);
    background:
        radial-gradient(ellipse 80% 50% at 50% 0%, rgba(47, 174, 158, 0.07), transparent 70%),
        var(--bg);
    border-top: 1px solid var(--border);
}

/* ============================================================
   FAQ Section — native <details>/<summary> accordion
   ============================================================ */

.faq-section { padding-top: var(--space-11); padding-bottom: var(--space-12); }

.faq-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    max-width: 800px;
}

.faq-item {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
    transition:
        border-color var(--duration-base) var(--ease-out),
        background var(--duration-base) var(--ease-out);
}

.faq-item:hover { border-color: rgba(255, 255, 255, 0.10); }

.faq-item[open] {
    border-color: rgba(47, 174, 158, 0.35);
    background: linear-gradient(180deg, var(--bg-card) 0%, rgba(47, 174, 158, 0.03) 100%);
}

.faq-item summary {
    list-style: none;
    cursor: pointer;
    padding: var(--space-6) var(--space-7);
    font-size: var(--text-md);
    font-weight: 600;
    color: var(--text);
    letter-spacing: -0.005em;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-5);
    transition: color var(--duration-fast) var(--ease-out);
}

.faq-item summary::-webkit-details-marker { display: none; }

.faq-item summary::after {
    content: "";
    width: 14px;
    height: 14px;
    flex-shrink: 0;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14'%3E%3Cpath d='M3 5 L7 9 L11 5' fill='none' stroke='%232fae9e' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-size: contain;
    background-repeat: no-repeat;
    transition: transform var(--duration-base) var(--ease-out);
}

.faq-item[open] summary::after { transform: rotate(180deg); }

.faq-item summary:hover { color: var(--accent); }

.faq-item p {
    padding: 0 var(--space-7) var(--space-6);
    color: var(--text-dim);
    font-size: var(--text-base);
    line-height: var(--leading-normal);
    text-wrap: pretty;
    margin: 0;
}

/* Make sure the FAQ shows up in the nav at the same level as other sections */
@media (max-width: 600px) {
    .faq-section { padding-top: var(--space-9); padding-bottom: var(--space-10); }
    .faq-item summary { padding: var(--space-5) var(--space-5); font-size: var(--text-base); }
    .faq-item p { padding: 0 var(--space-5) var(--space-5); }
}

/* ============================================================
   Hero — Brand Asset Slot
   ============================================================ */

/* ===================================================================
   Hero — „Lebender Prompt" (Konzept A)
   ------------------------------------------------------------------
   Selbst-tippende Prompt-Konsole als Haupt-Hook; die SVG-Figur rechts
   morpht farblich passend zum gerade getippten Beispiel-Prompt.
   Logik in js/hero.js (progressive enhancement: ohne JS bleibt ein
   normales Eingabefeld + Button). Bewusst additiv ans Dateiende
   gehängt, um Merge-Konflikte mit parallel laufenden Branches
   (Story-Sektion) klein zu halten.
   =================================================================== */

/* Gradient-Ring, der bei Fokus aufleuchtet (mask-trick: nur Rand) */

@keyframes heroSparkle {
    0%, 100% { opacity: 0.7; transform: scale(1) rotate(0deg); }
    50%      { opacity: 1;   transform: scale(1.18) rotate(18deg); }
}

/* Higher specificity than the global `input[type="text"]` form style above, so
   the hero prompt stays a clean line of text on the pill — no dark input box. */

/* Ghost-Layer = die selbst tippende Zeile, liegt über dem leeren Input.
   Wird ausgeblendet, sobald der Nutzer fokussiert oder selbst tippt. */

@keyframes heroCaret {
    0%, 50%      { opacity: 1; }
    50.01%, 100% { opacity: 0; }
}

/* Vision-first path into the story (A2). Quiet but clear; the bouncing
   arrow pulls the eye downward so the "why" isn't skipped. */
@keyframes heroNudge {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(3px); }
}

/* ============================================================
   Flair — pointer/scroll micro-interactions + easter egg
   (wired in js/flair.js; pure progressive enhancement)
   ============================================================ */

/* Easter egg — neon fabric-particle burst + a fading message. */
@keyframes eggFly {
    0%   { opacity: 1; transform: translate(-50%, -50%) scale(1) rotate(0); }
    100% { opacity: 0; transform: translate(calc(-50% + var(--tx)), calc(-50% + var(--ty))) scale(0.3) rotate(160deg); }
}
@keyframes eggMsg {
    0%        { opacity: 0; transform: translateX(-50%) translateY(8px); }
    15%, 72%  { opacity: 1; transform: translateX(-50%) translateY(0); }
    100%      { opacity: 0; transform: translateX(-50%) translateY(-8px); }
}

/* QA: touch tap-target sizing — lift the two shortest interactive controls to a
   comfortable height on touch (measured at 390px: preset 33px, lang 28px). */
html.is-touch .preset-btn { min-height: 44px; }
/* Touch-Komfort: ≥44px für alle interaktiven Kleinelemente (UX-Scan #4). */
html.is-touch .lang-toggle { min-height: 44px; }
html.is-touch .de-nav { min-height: 44px; padding-left: 10px; padding-right: 10px; display: inline-flex; align-items: center; }
html.is-touch .nav-links a { min-height: 44px; display: inline-flex; align-items: center; }
html.is-touch .manifesto-link { min-height: 44px; display: inline-flex; align-items: center; gap: 6px; }
html.is-touch .de-concept-evolve,
html.is-touch .de-concept-back,
html.is-touch .gallery-tile-actions a,
html.is-touch .gallery-tile-actions button { min-height: 44px; }

/* ── Card spotlight: a faint sheen follows the cursor across dark cards
      (wired in js/flair.js; desktop fine-pointer only). ── */
.spotlight { position: relative; }
.spotlight > .card-glow {
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    z-index: 2;
    opacity: 0;
    transition: opacity 0.4s var(--ease-out);
    background: radial-gradient(240px circle at var(--mx, 50%) var(--my, 0%),
        rgba(255, 255, 255, 0.08), rgba(47, 134, 179, 0.05) 35%, transparent 60%);
}
.spotlight:hover > .card-glow { opacity: 1; }

/* ── Section "seam": a short gradient thread under each section header that
      sews itself in when the header reveals (tailoring motif). ── */
.section-header::after {
    content: "";
    display: block;
    width: 56px;
    height: 2px;
    margin-top: var(--space-5);
    border-radius: 2px;
    background: linear-gradient(90deg, var(--accent), var(--accent-2), var(--accent-3));
}
@media (prefers-reduced-motion: no-preference) {
    [data-reveal].section-header::after {
        width: 0;
        transition: width 0.9s var(--ease-out) 0.15s;
    }
    [data-reveal].section-header.is-revealed::after { width: 56px; }
}

/* ============================================================
   Post-story life — round 2 (F3/F4/F5)
   3 tasteful, professional micro-interactions for the sections
   after the scroll story. All reduced-motion safe.
   ============================================================ */

/* ── F3. CTA sheen — a single soft glint sweeps across the brand-gradient
      buttons on hover, like light catching satin. Compositor-only. ── */
.upload-btn,
.export-btn.primary,
.vto-download-btn,
.hero-prompt-go {
    position: relative;
    overflow: hidden;
    isolation: isolate;
}
.upload-btn::after,
.export-btn.primary::after,
.vto-download-btn::after,
.hero-prompt-go::after {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 60%;
    height: 100%;
    pointer-events: none;
    z-index: 1;
    background: linear-gradient(
        100deg,
        transparent 0%,
        rgba(255, 255, 255, 0.05) 35%,
        rgba(255, 255, 255, 0.55) 50%,
        rgba(255, 255, 255, 0.05) 65%,
        transparent 100%);
    transform: translateX(-180%) skewX(-18deg);
    opacity: 0;
}
@media (prefers-reduced-motion: no-preference) {
    .upload-btn:hover::after,
    .export-btn.primary:hover::after,
    .vto-download-btn:hover::after,
    .hero-prompt-go:hover::after {
        opacity: 1;
        animation: ctaSheen 0.85s var(--ease-out);
    }
}
@keyframes ctaSheen {
    from { transform: translateX(-180%) skewX(-18deg); }
    to   { transform: translateX(320%)  skewX(-18deg); }
}

/* ============================================================
   Design preview — AI studio render inline in the design card
   (the cheap "do I like it?" gate before the photo-based try-on)
   ============================================================ */

/* Call-to-action that triggers the render (no image yet). */
.design-preview-btn:hover:not(:disabled) {
    border-color: rgba(47, 174, 158, 0.85);
    background: linear-gradient(135deg, rgba(47, 174, 158, 0.22), rgba(47, 134, 179, 0.22));
    transform: translateY(-1px);
}

/* Free $0 fallback render (client-side SVG studio illustration). */
.pf-svg {
    display: block;
    width: 100%;
    aspect-ratio: 4 / 5;
    max-height: 420px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
}

@media (prefers-reduced-motion: reduce) {
    .design-preview-btn:hover:not(:disabled) { transform: none; }
}

/* ============================================================
   NEW IA — mono section-label system + consolidated facts block
   (brand dark theme + pink→purple→cyan gradient; appended last)
   ============================================================ */
.mono-label {
    font-family: var(--font-mono);
    font-size: 12px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-muted);
    font-weight: 500;
    margin: 0;
}
.section-label { color: var(--accent); }
/* Unify section kickers: neutralise old .section-number gimmick + gradient eyebrows */
.section-number.section-label,
.howto-eyebrow.section-label,
.manifesto-eyebrow.section-label {
    font-family: var(--font-mono) !important;
    background: none !important;
    -webkit-text-fill-color: currentColor !important;
    color: var(--accent) !important;
    font-weight: 500 !important;
    letter-spacing: 0.1em !important;
    font-size: 12px !important;
    padding-left: 0 !important;
    display: block;
}
.section-number.section-label::before { content: none !important; }

/* ---- [ 01 / Das Problem ] facts block ---- */
.facts { padding: var(--space-12) 0; }
.facts-top {
    display: flex; justify-content: space-between; align-items: baseline;
    gap: var(--space-4); flex-wrap: wrap;
    border-bottom: 1px solid var(--border);
    padding-bottom: var(--space-4); margin-bottom: var(--space-8);
}
/* Key figure pulled out big — the number is the anchor of each row. Kept in
   clean white (the brand gradient stays reserved for the live odometer above,
   so the two don't compete) with tabular figures so they align. */

/* ============================================================
   BEGIN EXPERIENCE — cursor-first opening ("doesn't sell, lets you begin")
   No headline-wall, no photo gallery: a quiet invitation + the live prompt
   console as the focal point; the belief is whispered, the cost is ambient.
   ============================================================ */
/* the cost simply exists, like a clock in the corner — not a pitch */
.ambient-ticker {
    position: absolute; bottom: var(--space-7); left: var(--space-7);
    color: var(--text-muted); opacity: 0.65; pointer-events: none;
    font-variant-numeric: tabular-nums; letter-spacing: 0.08em; margin: 0;
}
@media (max-width: 720px) {
    .ambient-ticker { position: static; display: block; text-align: center; margin: 0 0 var(--space-6); opacity: 0.6; }
}

/* ============================================================
   GUIDED FUNNEL — "Hilf mir entscheiden" (für Besucher ohne klare Idee)
   ============================================================ */

@keyframes funnelFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes funnelRise { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: translateY(0); } }

/* ============================================================
   DESIGN ENGINE — die adaptive "Design-Reise" (js/design-engine/)
   Ruhig, cineastisch: eine Frage groß, viel Negativraum. Nur :root-Tokens.
   ============================================================ */
.de-stage { max-width: 1120px; margin: 0 auto; padding: var(--space-8) var(--space-5); display: flex; flex-direction: column; gap: var(--space-7); }
.de-live { margin: 0; color: var(--text-dim); font-size: var(--text-sm); line-height: var(--leading-snug); }
.de-question { font-family: var(--font-display); font-size: var(--text-2xl); letter-spacing: var(--tracking-tight); line-height: var(--leading-tight); margin: 0 0 var(--space-6); color: var(--text); }

.de-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: var(--space-4); }
.de-card { display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-3); background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); color: var(--text); cursor: pointer; transition: transform .2s var(--ease-out), border-color .2s var(--ease-out), box-shadow .2s var(--ease-out); }
.de-card:hover, .de-card:focus-visible { transform: translateY(-3px); border-color: var(--accent); box-shadow: var(--shadow-soft); outline: none; }
.de-card-label { font-size: var(--text-md); font-weight: 600; }

.de-visual { position: relative; width: 100%; aspect-ratio: 4 / 3; border-radius: var(--radius-sm); overflow: hidden; background: var(--surface); display: flex; align-items: center; justify-content: center; color: var(--text-dim); }
.de-visual-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity .4s var(--ease-out); }
.de-visual-img.is-loaded { opacity: 1; }
.de-glyph { width: 64%; height: 64%; }
.de-swatch { width: 100%; height: 100%; }
.de-swatch-soft { opacity: 0.5; }
.de-swatch-fill { position: absolute; inset: 0; }

.de-tot { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); }
.de-tot-panel { position: relative; min-height: 280px; background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; color: var(--text); cursor: pointer; display: flex; align-items: flex-end; padding: var(--space-5); transition: transform .2s var(--ease-out), box-shadow .2s var(--ease-out); }
.de-tot-panel .de-visual { position: absolute; inset: 0; aspect-ratio: auto; border-radius: 0; }
.de-tot-panel:hover, .de-tot-panel:focus-visible { transform: translateY(-3px); box-shadow: var(--shadow-glow); outline: none; }
.de-tot-label { position: relative; font-family: var(--font-display); font-size: var(--text-xl); font-weight: 600; text-shadow: 0 2px 12px rgba(0,0,0,0.6); }

/* Slider → Couture (roadmap §6): Haarlinien-Spur mit Live-Füllung (--val vom
   Input), Ring-Daumen, und der Pol, dem sich der Regler nähert, hellt auf —
   die Achse liest sich als Spannung zwischen zwei Worten, nicht als
   Browser-Widget. Natives <input type=range> darunter (A11y unverändert). */
.de-slider { padding: var(--space-5) 0; }
.de-slider-poles { display: flex; justify-content: space-between; color: var(--text-dim); font-size: var(--text-sm); margin-bottom: var(--space-3); }
.de-slider-poles .de-pole { transition: color .2s var(--ease-out), opacity .2s var(--ease-out); opacity: .75; }
.de-slider[data-side="lo"] .de-pole-lo,
.de-slider[data-side="hi"] .de-pole-hi { color: var(--accent-3); opacity: 1; }
.de-range { -webkit-appearance: none; appearance: none; width: 100%; height: 32px; background: transparent; cursor: pointer; --val: 50%; }
.de-range::-webkit-slider-runnable-track { height: 2px; border-radius: 2px;
    background: linear-gradient(90deg, var(--accent-2), var(--accent-3) var(--val), var(--border) var(--val)); }
.de-range::-webkit-slider-thumb { -webkit-appearance: none; width: 22px; height: 22px; border-radius: 50%; margin-top: -10px;
    background: var(--bg-elevated); border: 2px solid var(--accent-3);
    box-shadow: 0 0 0 4px rgba(126, 224, 207, 0.14), 0 2px 10px rgba(0, 0, 0, 0.5); }
.de-range::-moz-range-track { height: 2px; border-radius: 2px; background: var(--border); }
.de-range::-moz-range-progress { height: 2px; border-radius: 2px; background: linear-gradient(90deg, var(--accent-2), var(--accent-3)); }
.de-range::-moz-range-thumb { width: 22px; height: 22px; border-radius: 50%; background: var(--bg-elevated); border: 2px solid var(--accent-3);
    box-shadow: 0 0 0 4px rgba(126, 224, 207, 0.14), 0 2px 10px rgba(0, 0, 0, 0.5); }
.de-range:focus-visible { outline: 2px solid var(--accent-3, #7ee0cf); outline-offset: 4px; border-radius: 4px; }

/* Farb-Atelier (roadmap §6): das Kleidungsstück auf der Bühne IST die
   Vorschau (das tote Farb-Rechteck ist weg) — benannte Stoff-Chips statt
   roher Punkte. Chip = Stoff-Feld (mit feiner Web-Struktur) + Farbname in
   Mono-Micro; Auswahl trägt die Karten-Selektionssprache (Accent-Ring). */
.de-scheme-tabs { display: inline-flex; gap: var(--space-1); background: var(--surface); border-radius: 999px; padding: 4px; margin-bottom: var(--space-2); }
.de-scheme-tab { border: 0; background: none; color: var(--text-dim); padding: var(--space-2) var(--space-5); border-radius: 999px; cursor: pointer; font-size: var(--text-sm); transition: all .2s var(--ease-out); }
.de-scheme-tab.is-active { background: var(--gradient); color: #fff; }
/* Fest reservierte Hinweiszeile (kein Layout-Sprung beim Moduswechsel). */
.de-scheme-hint { min-height: 18px; margin: 0 0 var(--space-3); font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.04em; color: var(--text-dim); }
.de-palette { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: var(--space-3); }
.de-palette-swatch { display: flex; flex-direction: column; gap: 8px; padding: 8px 8px 10px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); cursor: pointer; transition: transform .15s var(--ease-out), border-color .15s var(--ease-out); }
.de-fabric-field { position: relative; display: block; height: 60px; border-radius: calc(var(--radius) - 4px); overflow: hidden; }
/* Feine Web-Struktur + Lichtkante: die Fläche liest sich als Stoff. */
.de-fabric-field::after { content: ""; position: absolute; inset: 0;
    background:
        repeating-linear-gradient(0deg, rgba(255, 255, 255, 0.05) 0 1px, transparent 1px 3px),
        repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.07) 0 1px, transparent 1px 3px),
        linear-gradient(160deg, rgba(255, 255, 255, 0.10), transparent 45%);
}
.de-fabric-name { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-dim); text-align: center; }
.de-palette-swatch:hover { transform: translateY(-2px); border-color: var(--text-muted); }
.de-palette-swatch:focus-visible { outline: 2px solid var(--accent-3, #7ee0cf); outline-offset: 2px; }
/* Selected stop(s): accent ring + brightened name; the order badge shows the
   gradient direction (1 → 2) in duo mode. */
.de-palette-swatch.is-selected { border-color: transparent; box-shadow: 0 0 0 2px var(--accent), 0 8px 24px rgba(47, 174, 158, 0.25); }
.de-palette-swatch.is-selected .de-fabric-name { color: var(--text); }
.de-palette-order {
    position: absolute; top: 6px; right: 6px; min-width: 16px; height: 16px;
    padding: 0 4px; display: none; place-items: center; box-sizing: border-box;
    border-radius: 999px; background: var(--gradient); color: #fff;
    font-size: 10px; font-weight: 700; line-height: 1;
}
.de-palette-swatch.is-selected .de-palette-order:not(:empty) { display: grid; }

.de-confirm { margin-top: var(--space-6); padding: var(--space-4) var(--space-8); border: 0; border-radius: 999px; background: var(--gradient); color: #fff; font-size: var(--text-md); font-weight: 600; cursor: pointer; box-shadow: var(--shadow-glow); transition: transform .2s var(--ease-out); }
.de-confirm:hover { transform: translateY(-2px); }
.de-summary { font-family: var(--font-display); font-size: var(--text-lg); line-height: var(--leading-snug); color: var(--text); margin: 0 0 var(--space-2); }

.de-controls { display: flex; align-items: center; gap: var(--space-4); }
/* --text-dim, not --text-muted: these skip/restart controls sit on the
   elevated engine panel (#14283b) where --text-muted only reaches 4.15:1 —
   below the 4.5:1 WCAG-AA floor (axe gate). --text-dim clears it with margin
   and makes the interactive controls more discoverable. */
.de-nav { background: none; border: 0; color: var(--text-dim); cursor: pointer; font-size: var(--text-sm); transition: color .2s var(--ease-out); }
.de-nav:hover:not(:disabled) { color: var(--accent); }
.de-nav:disabled { opacity: 0.4; cursor: default; }
/* "Fertig" ist DIE Zusage "du kannst jederzeit abschliessen" — sobald sie
   erscheint, verdient sie Confirm-Gewicht statt eines leisen Textlinks. */
.de-finish { margin-left: auto; background: var(--gradient); color: var(--on-accent); font-weight: 700; border-radius: 999px; padding: 8px 18px; }
.de-finish:hover:not(:disabled) { color: var(--on-accent); filter: brightness(1.1); }

@media (max-width: 560px) {
    .de-question { font-size: var(--text-xl); }
    .de-tot { grid-template-columns: 1fr; }
    .de-tot-panel { min-height: 180px; }
}
@media (prefers-reduced-motion: reduce) {
    .de-card, .de-tot-panel, .de-confirm, .de-palette-swatch, .de-visual-img { transition: none !important; }
}

/* Design Engine integration — Reise als Hauptfokus, Prompt als optionales <details> */
.design-grid > .design-journey,
.design-grid > .prompt-fallback,
.design-grid > .result-panel { grid-column: 1 / -1; }
.design-journey { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow-soft); }
.prompt-fallback { border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-elevated); overflow: hidden; }
.prompt-fallback-summary { cursor: pointer; padding: var(--space-4) var(--space-5); color: var(--text-dim); font-size: var(--text-sm); list-style: none; user-select: none; transition: color .2s var(--ease-out); }
.prompt-fallback-summary:hover { color: var(--text); }
.prompt-fallback-summary::-webkit-details-marker { display: none; }
.prompt-fallback-summary::before { content: "+ "; color: var(--accent); font-weight: 600; }
.prompt-fallback[open] .prompt-fallback-summary::before { content: "\2013 "; }
.prompt-fallback .prompt-panel { padding: 0 var(--space-5) var(--space-5); }

/* Design Engine — Mikro-Feedback (Flash) am Rand der Vorschau, Phase F */
.de-flash { position: absolute; top: var(--space-4); right: var(--space-4); z-index: 2; font-size: var(--text-sm); color: var(--accent-3); background: var(--bg-elevated); border: 1px solid var(--border); border-radius: 999px; padding: 4px var(--space-3); opacity: 0; transform: translateY(-4px); transition: opacity .25s var(--ease-out), transform .25s var(--ease-out); pointer-events: none; }
.de-flash.is-on { opacity: 1; transform: translateY(0); }

.de-inferred { margin: var(--space-5) 0; }
.de-inferred-h { font-size: var(--text-xs); letter-spacing: var(--tracking-wider); text-transform: uppercase; color: var(--text-muted); margin: 0 0 var(--space-3); }
.de-chips { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.de-chip { font-size: var(--text-sm); color: var(--text-dim); background: var(--bg-elevated); border: 1px solid var(--border); border-radius: 999px; padding: var(--space-2) var(--space-4); }
.de-chip b { color: var(--text); font-weight: 600; }

.de-refine-axes { margin: var(--space-6) 0; display: flex; flex-direction: column; gap: var(--space-3); }
.de-axis { display: flex; align-items: center; gap: var(--space-3); }
.de-axis-label { flex: 1; color: var(--text); font-size: var(--text-sm); }
/* §8.3: Akzent-Stepper statt grauer Form-Pillen — die Vorschau antwortet auf
   jeden Klick sofort (updatePreview), der Knopf soll danach aussehen. */
.de-nudge { border: 1px solid rgba(126, 224, 207, 0.38); background: rgba(47, 174, 158, 0.09); color: var(--text); border-radius: 999px; padding: var(--space-2) var(--space-4); font-size: var(--text-sm); cursor: pointer; transition: border-color .2s var(--ease-out), background .2s var(--ease-out), transform .15s var(--ease-out); }
.de-nudge:hover { border-color: var(--accent-3); background: rgba(47, 174, 158, 0.22); }
.de-nudge:active { transform: scale(0.96); }
.de-refine-actions { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); margin-top: var(--space-6); flex-wrap: wrap; }
.de-refine-actions .de-confirm { margin-top: 0; }

@media (prefers-reduced-motion: reduce) {
    .de-flash, .de-nudge { transition: none !important; }
}

/* Design Engine — optionale Modalitäten: Ranking, Tap-auf-Vorschau, Mehrfachauswahl */
.de-card.is-selected { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent), var(--shadow-soft); }
.de-card.is-selected::after { content: "✓"; position: absolute; top: var(--space-3); right: var(--space-3); width: 22px; height: 22px; display: grid; place-items: center; border-radius: 50%; background: var(--gradient); color: #fff; font-size: 13px; }
.de-card { position: relative; }

.de-rank { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-3); }
.de-rank-item { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) var(--space-4); background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); }
.de-rank-num { flex: none; width: 26px; height: 26px; display: grid; place-items: center; border-radius: 50%; background: var(--gradient); color: #fff; font-weight: 700; font-size: var(--text-sm); }
.de-rank-label { flex: 1; color: var(--text); font-size: var(--text-md); }
.de-rank-btn { flex: none; width: 36px; height: 36px; border: 1px solid var(--border); background: var(--surface); color: var(--text); border-radius: var(--radius-sm); cursor: pointer; font-size: 16px; transition: border-color .2s var(--ease-out); }
.de-rank-btn:hover:not(:disabled) { border-color: var(--accent); }
.de-rank-btn:disabled { opacity: 0.3; cursor: default; }

@media (prefers-reduced-motion: reduce) {
    .de-rank-btn { transition: none !important; }
}

/* Design Engine — Detail-Atelier (Modalität "regions", Roadmap §7): das Stück
   gross in der Mitte, ein tippbarer Hotspot pro Bauteil, der Micro-Picker
   öffnet AM Teil. Ein Screen statt sechs Kartenraster — Direktmanipulation am
   Kleidungsstück. Hotspots sind normale Buttons (Tastaturpfad in DOM-Folge);
   der Puls ist rein dekorativ und nur unter html.fx aktiv. */
.de-regions-hint { margin: calc(var(--space-2) * -1) 0 0; color: var(--text-dim); font-size: var(--text-sm); }
.de-regions { position: relative; width: min(340px, 100%); margin: var(--space-4) auto 0; }
/* Werkbank-Bühne: dasselbe Studio-Licht wie die Hauptvorschau (sanftes
   Key-Light von oben, abgedunkelter Boden, Tiefen-Verlauf) — das Atelier ist
   ein beleuchteter Arbeitsplatz, kein schwebendes Icon. */
.de-regions-stage { aspect-ratio: 240 / 340; border-radius: var(--radius); border: 1px solid var(--border); overflow: hidden; background: radial-gradient(70% 44% at 50% 4%, rgba(150, 205, 228, 0.11), rgba(150, 205, 228, 0) 60%), radial-gradient(120% 70% at 50% 118%, rgba(2, 7, 12, 0.6), rgba(2, 7, 12, 0) 55%), radial-gradient(130% 100% at 50% 34%, #122638, var(--bg)72%); }
.de-regions-stage svg { width: 100%; height: 100%; display: block; }
/* Hotspots treten gestaffelt auf wie gesetzte Stecknadeln (Delay inline aus
   JS, Reihenfolge = JSON-Reihenfolge). */
html.fx .de-hotspot { animation: deSpotIn 0.32s var(--ease-out) backwards; }
@keyframes deSpotIn { from { opacity: 0; transform: scale(0.4); } }
/* Pick-Bestätigung: die Nadel „setzt sich" mit einem kurzen Pop … */
html.fx .de-hotspot.is-just-set .de-hotspot-dot { animation: deSpotPop 0.28s var(--ease-out); }
@keyframes deSpotPop { 40% { transform: scale(1.45); } }
/* … und das geänderte Teil blüht kurz auf (§6 Preview-Reaktion). */
.de-region-glow { position: absolute; width: 84px; height: 84px; margin: -42px 0 0 -42px; border-radius: 50%; pointer-events: none; z-index: 1; background: radial-gradient(circle, rgba(126, 224, 207, 0.34), rgba(126, 224, 207, 0.1) 45%, rgba(126, 224, 207, 0) 70%); animation: deRegionGlow 0.55s var(--ease-out) forwards; }
@keyframes deRegionGlow { from { opacity: 0; transform: scale(0.5); } 35% { opacity: 1; } to { opacity: 0; transform: scale(1.25); } }
html.fx .de-region-picker.is-open { animation: dePickerIn 0.18s var(--ease-out); }
@keyframes dePickerIn { from { opacity: 0; transform: translateY(6px) scale(0.97); } }
/* Kamerafahrt: Picker öffnen = die Kamera fährt aufs Teil (translate+scale
   aus JS, der getippte Anker bleibt Fixpunkt); die übrigen Nadeln treten
   zurück, die Beschriftung der aktiven Nadel weicht dem Panel. Der Zoom-
   ZUSTAND gilt auch unter reduced-motion (Zustand, nicht Bewegung) — nur die
   Fahrt entfällt (globaler Transition-Reset). */
.de-regions-zoom { position: relative; transition: transform 0.24s var(--ease-out); }
.de-regions.is-zoomed .de-hotspot:not([aria-expanded="true"]) { opacity: 0.28; transition: opacity 0.2s var(--ease-out); }
.de-regions.is-zoomed .de-hotspot[aria-expanded="true"] .de-hotspot-tag,
.de-regions.is-zoomed .de-hotspot[aria-expanded="true"] .de-hotspot-val { opacity: 0; transition: opacity 0.15s var(--ease-out); }
.de-hotspot { position: absolute; width: 44px; height: 44px; margin: -22px 0 0 -22px; display: grid; place-items: center; padding: 0; background: none; border: 0; cursor: pointer; z-index: 2; }
.de-hotspot-dot { width: 14px; height: 14px; border-radius: 50%; border: 2px solid var(--accent-3); background: rgba(10, 22, 34, 0.72); box-shadow: 0 0 0 3px rgba(126, 224, 207, 0.14); transition: background .2s var(--ease-out), box-shadow .2s var(--ease-out); }
html.fx .de-hotspot:not(.is-set) .de-hotspot-dot { animation: deSpotBreath 2.6s ease-in-out infinite; }
@keyframes deSpotBreath { 0%, 100% { box-shadow: 0 0 0 3px rgba(126, 224, 207, 0.14); } 50% { box-shadow: 0 0 0 7px rgba(126, 224, 207, 0.05); } }
.de-hotspot:hover .de-hotspot-dot, .de-hotspot:focus-visible .de-hotspot-dot, .de-hotspot[aria-expanded="true"] .de-hotspot-dot { background: rgba(47, 174, 158, 0.55); box-shadow: 0 0 0 6px rgba(126, 224, 207, 0.12); }
.de-hotspot.is-set .de-hotspot-dot { background: var(--accent); }
.de-hotspot-tag { position: absolute; top: calc(50% + 12px); left: 50%; transform: translateX(-50%); font-family: var(--font-mono); font-size: 9.5px; letter-spacing: var(--tracking-wider); text-transform: uppercase; color: var(--text-dim); white-space: nowrap; pointer-events: none; }
.de-hotspot-val { position: absolute; top: calc(50% + 24px); left: 50%; transform: translateX(-50%); font-size: 10.5px; color: var(--accent-3); white-space: nowrap; pointer-events: none; }
/* Seitenbewusste Labels (data-side, gesetzt aus der Anker-Geometrie): links
   liegende Hotspots beschriften nach links, rechte nach rechts — Labels
   benachbarter Regionen stapeln sich nie mehr in der Körpermitte. */
.de-hotspot[data-side="l"] .de-hotspot-tag { top: auto; bottom: calc(50% - 4px); left: auto; right: calc(50% + 13px); transform: none; }
.de-hotspot[data-side="l"] .de-hotspot-val { top: calc(50% + 6px); left: auto; right: calc(50% + 13px); transform: none; }
.de-hotspot[data-side="r"] .de-hotspot-tag { top: auto; bottom: calc(50% - 4px); left: calc(50% + 13px); right: auto; transform: none; }
.de-hotspot[data-side="r"] .de-hotspot-val { top: calc(50% + 6px); left: calc(50% + 13px); right: auto; transform: none; }
.de-region-picker { position: absolute; z-index: 4; min-width: 208px; max-width: min(262px, 96%); padding: var(--space-3); background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow-soft); display: flex; flex-direction: column; gap: var(--space-2); }
/* display:flex würde sonst das UA-[hidden]{display:none} überstimmen — der
   „geschlossene" Picker bliebe sichtbar und finge Taps ab. */
.de-region-picker[hidden] { display: none; }
.de-region-picker-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.de-region-picker-h { margin: 0; font-family: var(--font-mono); font-size: 10px; letter-spacing: var(--tracking-wider); text-transform: uppercase; color: var(--text-dim); }
.de-region-close { flex: none; width: 28px; height: 28px; display: grid; place-items: center; background: none; border: 1px solid var(--border); border-radius: 50%; color: var(--text-dim); font-size: 12px; cursor: pointer; transition: border-color .2s var(--ease-out); }
.de-region-close:hover { border-color: var(--accent); color: var(--text); }
.de-region-opt { display: flex; align-items: center; gap: 10px; width: 100%; min-height: 46px; text-align: left; padding: var(--space-1) var(--space-2) var(--space-1) var(--space-1); background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm); color: var(--text); font-size: var(--text-sm); cursor: pointer; transition: border-color .2s var(--ease-out); }
.de-region-opt:hover { border-color: var(--accent); }
.de-region-opt[aria-pressed="true"] { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
/* Atelier-Lupe: jede Option ist eine echte Nahaufnahme GENAU dieses Details
   (zugeschnittene viewBox am Anker) — Touch sieht, was es wählt, ohne Hover. */
.de-region-opt-thumb { flex: none; width: 54px; height: 40px; border-radius: 6px; overflow: hidden; border: 1px solid rgba(37, 65, 90, 0.8); background: radial-gradient(120% 100% at 50% 20%, #16293b, #0c1a2b 85%); }
.de-region-opt-thumb svg { width: 100%; height: 100%; display: block; }
.de-region-opt-label { flex: 1; min-width: 0; }
.de-region-opt-cur { flex: none; margin-left: auto; font-family: var(--font-mono); font-size: 8.5px; letter-spacing: var(--tracking-wider); text-transform: uppercase; color: var(--accent-3); border: 1px solid rgba(126, 224, 207, 0.35); border-radius: 999px; padding: 2px 7px; }
html.is-touch .de-region-opt { min-height: 48px; }
/* No-Board-Fallback (kein SVG/keine Kategorie): Regions als schlichte Gruppen */
.de-regions-list { display: flex; flex-direction: column; gap: var(--space-4); }
.de-region-group .de-region-opt { display: inline-block; width: auto; margin: var(--space-1) var(--space-1) 0 0; }
@media (max-width: 480px) {
    .de-regions { width: min(276px, 94%); }
    .de-hotspot-tag { font-size: 9px; }
}
@media (prefers-reduced-motion: reduce) {
    .de-hotspot-dot, .de-region-opt, .de-region-close { transition: none !important; }
    html.fx .de-hotspot:not(.is-set) .de-hotspot-dot { animation: none !important; }
    html.fx .de-hotspot, html.fx .de-hotspot.is-just-set .de-hotspot-dot,
    .de-region-glow, html.fx .de-region-picker.is-open { animation: none !important; }
    .de-region-glow { display: none; }
}

/* §3.2 — Fallback „nie flach": Duotone-Sheen + feines Filmkorn auf allen Tile-Platzhaltern */
.de-swatch { position: relative; overflow: hidden; }
.de-swatch::before { content: ""; position: absolute; inset: 0; background: radial-gradient(130% 90% at 28% 18%, rgba(255,255,255,0.22), rgba(255,255,255,0) 55%); pointer-events: none; }
.de-swatch::after { content: ""; position: absolute; inset: 0; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); background-size: 140px 140px; mix-blend-mode: overlay; opacity: 0.16; pointer-events: none; }
.de-preview::after { content: ""; position: absolute; inset: 0; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n2'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n2)'/%3E%3C/svg%3E"); background-size: 140px 140px; mix-blend-mode: overlay; opacity: 0.1; pointer-events: none; border-radius: inherit; }

/* ============================================================
   §1 — Live-Vorschau wird das Hauptstück (Layout-Umbau).
   Überschreibt die frühere 96px-Thumbnail-Box. 2-spaltig auf Desktop,
   große sticky Vorschau; mobil Vorschau oben sticky, Frage darunter.
   ============================================================ */
.de-stage-grid { display: grid; grid-template-columns: 1fr; gap: var(--space-7); align-items: start; }
.de-preview-col { position: relative; }
.de-ask-col { display: flex; flex-direction: column; gap: var(--space-5); }

/* Honest orientation stepper — named journey phases, the current one lit and
   earlier ones marked done. NO 0–100% gauge / closing ring: the journey is
   adaptive and always-viable, so it only shows WHERE you are; readiness lives
   on the "Fertig" button. Mono = the "machine voice" register. */
.de-stepper { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; margin: 0; }
.de-step { display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: var(--tracking-wider); text-transform: uppercase; color: var(--text-dim); white-space: nowrap; opacity: 0.5; transition: opacity .3s var(--ease-out), color .3s var(--ease-out); }
.de-step-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; transition: box-shadow .3s var(--ease-out); }
.de-step.is-done { opacity: 0.85; color: var(--accent-3); }
.de-step.is-cur { opacity: 1; color: var(--text); }
.de-step.is-cur .de-step-dot { background: var(--accent-3); box-shadow: 0 0 0 4px rgba(126, 224, 207, 0.18); }
.de-step.is-todo { opacity: 0.38; }
.de-step-bar { flex: 1; min-width: 10px; max-width: 34px; height: 2px; border-radius: 2px; background: var(--border); }
.de-step-bar.is-done { background: var(--gradient); }
@media (prefers-reduced-motion: reduce) { .de-step, .de-step-dot { transition: none; } }
@media (max-width: 560px) {
    .de-stepper { gap: 4px; }
    .de-step { font-size: 9px; gap: 4px; }
    .de-step-bar { min-width: 6px; max-width: 16px; }
}

/* Vorschau dominant. Höhen in svh + JS-gepinntem --svh (wie Hero/Story), damit
   nichts springt, wenn die iOS-Adressleiste ein-/ausfährt. */
/* Cinematic studio stage: a soft key light from the top, a darkened floor that
   seats the garment's contact shadow, and a depth gradient — the flat reads as
   a garment lit in a studio, not an icon on a panel. */
.de-preview { position: relative; width: 100%; height: 56svh; height: calc(var(--svh, 1svh) * 56); min-height: 300px; max-height: 70svh; max-height: calc(var(--svh, 1svh) * 70); border-radius: var(--radius); border: 1px solid var(--border); overflow: hidden; background: radial-gradient(68% 48% at 50% 6%, rgba(150,205,228,0.13), rgba(150,205,228,0) 62%), radial-gradient(120% 78% at 50% 122%, rgba(2,7,12,0.62), rgba(2,7,12,0) 56%), radial-gradient(132% 104% at 50% 36%, #122638, var(--bg)70%); display: flex; align-items: center; justify-content: center; }
.de-preview svg { width: 100%; height: 100%; object-fit: contain; }
.de-preview.is-fade { animation: deCross .24s var(--ease-out); }
@keyframes deCross { from { opacity: .4; } to { opacity: 1; } }

/* Reife-Ring + Mikro-Feedback an den RAND der VORSCHAU (Banner), nicht an der
   Spalte: .de-preview-stage umschließt nur den Banner und ist der Bezugsrahmen
   für Ring/Flash. Sonst verankern sie am Spalten-Boden — dort sitzen aber die
   Chips, die der Ring dann überlagert (Desktop wie Mobile). */
.de-preview-stage { position: relative; }

/* Frage groß, ruhig */
.de-ask-col .de-question { margin-top: 0; }

@media (min-width: 900px) {
    .de-stage-grid { grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr); gap: var(--space-9); }
    .de-preview-col { position: sticky; top: calc(84px + env(safe-area-inset-top)); }
    .de-preview { height: 64svh; height: calc(var(--svh, 1svh) * 64); }
    .de-ask-col { min-height: 60svh; min-height: calc(var(--svh, 1svh) * 60); justify-content: center; }
}
/* iPad-Hochformat (481–899): große sticky Vorschau bleibt — sieht dort gut aus */
@media (max-width: 899px) and (min-width: 481px) {
    .de-preview-col { position: sticky; top: calc(64px + env(safe-area-inset-top)); z-index: 2; }
    .de-preview { height: 46svh; height: calc(var(--svh, 1svh) * 46); min-height: 260px; }
}
@media (prefers-reduced-motion: reduce) {
    .de-preview.is-fade { animation: none; }
}

/* ============================================================
   iPhone-Layout-Pass (≤480px) — iPad/Desktop bleiben unangetastet.
   Kein sticky (eine halbe Bildschirmhöhe konkurriert sonst mit der Frage):
   kompaktes Vorschau-Banner oben, Frage fließt normal darunter. svh-Höhen,
   Safe-Area, kein backdrop-filter (iOS-Scroll-Ruckeln).
   ============================================================ */
@media (max-width: 480px) {
    /* 1 — Sticky entschärfen: Vorschau als kompaktes Banner mit moderater Höhe.
       (Ring/Flash hängen am .de-preview-stage, nicht an der Spalte, daher reicht
       hier `static`, um das sticky zu killen.) */
    .de-preview-col { position: static; }
    .de-preview {
        height: 34svh;
        height: calc(var(--svh, 1svh) * 34);
        min-height: 200px;
        max-height: 300px;
    }

    /* 5 — Vertikale Enge lösen: Stage/Grid enger; Safe-Area unten (Home-Indicator) */
    .de-stage {
        gap: var(--space-4);
        padding: var(--space-6) var(--space-4);
        padding-bottom: max(var(--space-6), env(safe-area-inset-bottom));
    }
    .de-stage-grid { gap: var(--space-4); }
    .de-ask-col { gap: var(--space-4); }
    .de-preview-chips { margin-top: var(--space-2); }

    .de-preview-badge {
        background: rgba(10, 22, 34,0.82);
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
    }

    /* 5 — This-or-That + Cards kompakter, damit beides ohne Riesen-Scroll passt */
    .de-tot { gap: var(--space-3); }
    .de-tot-panel { min-height: 150px; }
    .de-cards { grid-template-columns: 1fr 1fr; gap: var(--space-3); }
    .de-card { padding: var(--space-2); }

    /* Intro enger */
    .de-intro { min-height: calc(var(--svh, 1svh) * 60); padding: var(--space-6) var(--space-4); }
}

/* §2 — Intro-Screen + optionaler Freitext am Schluss */
.de-intro { min-height: 68svh; min-height: calc(var(--svh, 1svh) * 68); display: flex; align-items: center; justify-content: center; text-align: center; padding: var(--space-8) var(--space-5); }
.de-intro-inner { max-width: 620px; display: flex; flex-direction: column; gap: var(--space-6); align-items: center; }
.de-intro-title { font-family: var(--font-display); font-size: var(--text-3xl); line-height: var(--leading-tight); letter-spacing: var(--tracking-tight); margin: 0; color: var(--text); }
.de-intro-sub { color: var(--text-dim); font-size: var(--text-md); line-height: var(--leading-normal); margin: 0; max-width: 52ch; }
.de-intro-start { margin-top: var(--space-2); }

.de-freetext { margin: var(--space-6) 0 0; display: flex; flex-direction: column; gap: var(--space-2); }
.de-freetext-label { font-size: var(--text-sm); color: var(--text-dim); }
.de-freetext-input { width: 100%; box-sizing: border-box; background: var(--bg-elevated); border: 1px solid var(--border-field); border-radius: var(--radius-sm); color: var(--text); padding: var(--space-3) var(--space-4); font-family: inherit; font-size: var(--text-base); resize: vertical; transition: border-color .2s var(--ease-out); }
.de-freetext-input:focus { outline: none; border-color: var(--accent); }
.de-freetext-input::placeholder { color: var(--text-muted); }

@media (prefers-reduced-motion: reduce) { .de-freetext-input { transition: none; } }

/* §3.1 — Hero-Foto + Live-Recolor (Duotone) in der Vorschau + Material/Muster-Chips */
.de-preview-proxy, .de-preview-photo { position: absolute; inset: 0; }
.de-preview-photo { isolation: isolate; }
.de-preview-photo img { width: 100%; height: 100%; object-fit: cover; display: block; filter: grayscale(1) contrast(1.08) brightness(0.96); }
.de-preview-duo { position: absolute; inset: 0; mix-blend-mode: color; opacity: 0.9; transition: background .24s var(--ease-out); }
.de-preview-badge { position: absolute; top: var(--space-4); left: var(--space-4); z-index: 2; font-size: var(--text-xs); letter-spacing: var(--tracking-wider); text-transform: uppercase; color: var(--text-dim); background: rgba(10, 22, 34,0.55); backdrop-filter: blur(8px); padding: 4px var(--space-3); border-radius: 999px; }
.de-preview-chips { display: flex; flex-wrap: wrap; gap: var(--space-2); justify-content: center; margin-top: var(--space-3); }
.de-preview-chip { font-size: var(--text-xs); color: var(--text-dim); background: var(--bg-elevated); border: 1px solid var(--border); border-radius: 999px; padding: 3px var(--space-3); }
/* Dimensions-Mikrolabel im Chip (Maschinen-Stimme): unterscheidet gleichlautende
   Werte ("FIT Regular · LÄNGE Regular") statt zwei identischer Pillen. */
.de-chip-dim { font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.08em; text-transform: uppercase; opacity: 0.8; margin-right: 6px; } /* 0.8: bleibt über 4.5:1 AA-Kontrast auf --bg-elevated */

/* Fragen-Choreografie (Roadmap §6): die alte Frage sinkt weg (150ms, JS-getaktet),
   die neue staffelt ihre Kinder herein (≤250ms). Nur html.fx; reduced-motion und
   no-JS behalten den Sofort-Tausch. pointer-events aus während des Abgangs —
   der zweite Tipp eines Doppeltipps darf nichts Abgehendes treffen. */
html.fx .de-body.is-leaving { animation: deStepOut 0.15s var(--ease-out) both; pointer-events: none; }
@keyframes deStepOut { to { opacity: 0; transform: translateY(8px); } }
html.fx .de-body.is-entering > * { animation: deStepIn 0.24s var(--ease-out) both; }
html.fx .de-body.is-entering > *:nth-child(2) { animation-delay: 45ms; }
html.fx .de-body.is-entering > *:nth-child(3) { animation-delay: 90ms; }
html.fx .de-body.is-entering > *:nth-child(4) { animation-delay: 135ms; }
html.fx .de-body.is-entering > *:nth-child(n+5) { animation-delay: 180ms; }
@keyframes deStepIn { from { opacity: 0; transform: translateY(10px); } }

/* §8 Refine-Crescendo · Ankunfts-Beat: der Satz tippt sich in Mono auf
   (Maschinenstimme, JS-rAF), die Options-Sektionen treten EINEN Atemzug
   später ein (spezifischere Regeln als .is-entering > * — sie gewinnen die
   Kaskade und verschieben nur den Eintritt dieser Abschnitte nach hinten).
   Ohne fx / mit reduced-motion: alles sofort, voller Text. */
.de-summary-type { font-family: var(--font-mono); font-size: var(--text-sm); letter-spacing: 0.02em; line-height: 1.55; color: var(--accent-3); min-height: 3.1em; }
.de-summary-type.is-typing::after { content: "▎"; color: var(--accent-3); animation: deCaret 0.7s steps(1) infinite; }
@keyframes deCaret { 50% { opacity: 0; } }
html.fx .de-body.is-refine .de-concepts { animation: deRefineIn 0.45s var(--ease-out) 380ms backwards; }
html.fx .de-body.is-refine .de-inferred { animation: deRefineIn 0.45s var(--ease-out) 460ms backwards; }
html.fx .de-body.is-refine .de-refine-axes { animation: deRefineIn 0.45s var(--ease-out) 530ms backwards; }
html.fx .de-body.is-refine .de-freetext { animation: deRefineIn 0.45s var(--ease-out) 590ms backwards; }
html.fx .de-body.is-refine .de-refine-actions { animation: deRefineIn 0.45s var(--ease-out) 650ms backwards; }
@keyframes deRefineIn { from { opacity: 0; transform: translateY(10px); } }
@media (prefers-reduced-motion: reduce) {
    .de-summary-type.is-typing::after { animation: none !important; content: none; }
    html.fx .de-body.is-refine .de-concepts, html.fx .de-body.is-refine .de-inferred,
    html.fx .de-body.is-refine .de-refine-axes, html.fx .de-body.is-refine .de-freetext,
    html.fx .de-body.is-refine .de-refine-actions { animation: none !important; }
}

/* §5.4 Die Maschine näht: während AI.generateDesign läuft, kehrt das
   Genesis-Fadenfeld ÜBER dem Flat zurück — die Fäden laufen als Stiche über
   ihre eigenen Bahnen (pathLength=1 → wandernde dash-Stiche), das Stück liegt
   leicht abgedunkelt darunter. Von flow.js nur unter html.fx + ohne
   reduced-motion erzeugt; der globale Reduced-Reset friert zusätzlich ein. */
.de-sew { position: absolute; inset: 0; pointer-events: none; z-index: 3; opacity: 0; animation: deSewIn 0.4s var(--ease-out) forwards; }
.de-sew svg { width: 100%; height: 100%; }
.de-sew path { stroke-dasharray: 0.16 0.84; animation: deSewRun 1.15s linear infinite; }
.de-sew path:nth-child(3n) { animation-duration: 1.5s; animation-delay: 0.2s; }
.de-sew path:nth-child(3n+1) { animation-duration: 0.9s; animation-delay: 0.45s; }
@keyframes deSewRun { to { stroke-dashoffset: -1; } }
@keyframes deSewIn { to { opacity: 0.85; } }
.de-sew.is-done { animation: deSewOut 0.4s var(--ease-out) forwards; }
@keyframes deSewOut { from { opacity: 0.85; } to { opacity: 0; } }
.de-preview.is-sewing .de-garment-wrap { filter: brightness(0.8); transition: filter 0.4s var(--ease-out); }

/* Namensschild (§5.4): das fertige Stück bekommt seinen Namen in der
   Maschinenstimme — tippt sich auf (typeOn) und bleibt auf der Bühne stehen. */
.de-nameplate { position: absolute; left: 50%; bottom: 14px; transform: translateX(-50%); z-index: 4; font-family: var(--font-mono); font-size: var(--text-sm); letter-spacing: 0.12em; text-transform: uppercase; color: var(--accent-3); background: rgba(10, 22, 34, 0.78); border: 1px solid rgba(126, 224, 207, 0.32); border-radius: 999px; padding: 6px 16px; max-width: 92%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.de-nameplate.is-typing::after { content: "▎"; color: var(--accent-3); animation: deCaret 0.7s steps(1) infinite; }
@media (prefers-reduced-motion: reduce) {
    .de-sew, .de-sew path, .de-sew.is-done { animation: none !important; opacity: 0.5; }
    .de-preview.is-sewing .de-garment-wrap { transition: none; }
    .de-nameplate.is-typing::after { animation: none !important; content: none; }
}

/* §9 Ownership-Nahtstelle: die Karte gleitet herein (ur-create setzt
   .own-arrive nur unter html.fx beim ersten Enthüllen). */
html.fx #ownership.own-arrive { animation: ownArrive 0.55s var(--ease-out) backwards; }
@keyframes ownArrive { from { opacity: 0; transform: translateY(18px); } }

/* Phasen-Interstitial: fest reservierte Mono-Zeile zwischen Stepper und Frage
   (KEIN Layout-Sprung) — beim Kapitelwechsel blendet der neue Phasen-Titel
   kurz ein und wieder aus; der aktuelle Stepper-Punkt pulst einmal mit. */
.de-phase-flash { display: block; min-height: 1.3em; font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: 0.22em; text-transform: uppercase; color: var(--accent-3); opacity: 0; }
html.fx .de-phase-flash.is-on { animation: dePhaseFlash 0.95s var(--ease-out) both; }
@keyframes dePhaseFlash {
  0% { opacity: 0; letter-spacing: 0.14em; }
  25% { opacity: 1; }
  70% { opacity: 1; letter-spacing: 0.24em; }
  100% { opacity: 0; letter-spacing: 0.3em; }
}
html.fx .de-stepper.is-crossed .de-step.is-cur .de-step-dot { animation: deDotPulse 0.6s var(--ease-out); }
@keyframes deDotPulse {
  0% { box-shadow: 0 0 0 4px rgba(126, 224, 207, 0.18); }
  45% { box-shadow: 0 0 0 9px rgba(126, 224, 207, 0.28); }
  100% { box-shadow: 0 0 0 4px rgba(126, 224, 207, 0.18); }
}
@media (prefers-reduced-motion: reduce) {
  html.fx .de-body.is-leaving { animation: none; }
  html.fx .de-body.is-entering > * { animation: none; }
  html.fx .de-phase-flash.is-on { animation: none; opacity: 0; }
  html.fx .de-stepper.is-crossed .de-step.is-cur .de-step-dot { animation: none; }
}

/* Gedockte Mini-Vorschau (Mobile): hält den "wählen → sehen"-Loop am Leben,
   wenn die grosse Vorschau aus dem Bild scrollt (≤480px ist sie static).
   Spiegelt jeden Morph-Frame; Tipp springt zurück zur Vorschau. Nur per JS
   (IntersectionObserver) sichtbar geschaltet — Desktop blendet sie hart aus. */
.de-preview-dock {
  position: fixed;
  right: var(--space-3);
  bottom: calc(var(--space-4) + env(safe-area-inset-bottom, 0px));
  z-index: 40;
  width: 76px;
  height: 76px;
  padding: 8px;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background:
    radial-gradient(90% 90% at 50% 20%, rgba(47, 134, 179, 0.18), transparent 70%),
    var(--bg-elevated);
  box-shadow: 0 8px 28px rgba(4, 10, 16, 0.55);
  cursor: pointer;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.22s var(--ease-out), transform 0.22s var(--ease-out);
  display: none;
}
.de-preview-dock.is-on { opacity: 1; transform: none; }
.de-preview-dock:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.de-dock-flat { display: block; width: 100%; height: 100%; pointer-events: none; }
.de-dock-flat svg { width: 100%; height: 100%; display: block; }
@media (max-width: 480px) {
  .de-preview-dock { display: block; }
  .de-preview-dock[hidden] { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .de-preview-dock { transition: none; transform: none; }
}
@media (prefers-reduced-motion: reduce) { .de-preview-duo { transition: none; } }

/* ============================================================
   Startseiten-Umbau: Manifest = Hero-Landing, durchgehender Marken-Verlauf
   (oben kräftig, unten ruhiger), Textsektionen als halbtransparente Panels.
   ============================================================ */

/* Durchgehender, fester Marken-Schimmer hinter ALLEM (dezent → unten ruhiger) */
body { background: var(--bg); }
/* Durchgehender Marken-Verlauf als Basis hinter ALLEM, auf JEDER Seite.
   Auf body::after, weil body::before bereits das Filmkorn trägt (sonst mergen
   die Pseudo-Elemente und der Verlauf erbt opacity:0.035 → unsichtbar). */
body::after {
    content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
    background:
        radial-gradient(72vw 64vh at 84% -8%, rgba(47, 174, 158, 0.32), transparent 58%),
        radial-gradient(62vw 58vh at 110% 38%, rgba(47, 134, 179, 0.26), transparent 62%),
        radial-gradient(66vw 60vh at 4% 110%, rgba(126, 224, 207, 0.22), transparent 60%);
}

/* Manifest als Hero-Landing — oben kräftiger Verlauf (wie Bild 1) */

/* Textsektionen als halbtransparente dunkle Panels über dem Verlauf
   → der Schimmer peekt an den Rändern, Text bleibt voll lesbar */
.facts,
.howto,
.workflow,
.design-section,
.measure-section,
.preview-section,
.production-section,
.trust-strip,
.faq-section,
.site-footer,
footer.footer {
    background-color: rgba(10, 22, 34, 0.85);
}

/* ============================================================
   Live-Abfall-Zähler (Ticker) — Kombi C (Fakten-Odometer) + A (Badges)
   Tickt die belegte Abfallmasse hoch (≈ 2'918 kg/s). Zahl im Marken-Verlauf,
   warm-roter Live-Puls als Echtzeit-Signal. Gebaut von js/ambient-ticker.js.
   ============================================================ */
.section-meta {
    display: flex; justify-content: space-between; align-items: baseline;
    gap: var(--space-4); flex-wrap: wrap;
    border-bottom: 1px solid var(--border);
    padding-bottom: var(--space-4);
    margin-bottom: var(--space-6);
}

/* Shared: tabular mono digits + brand-gradient number + pulsing live dot */
.tnum {
    font-variant-numeric: tabular-nums;
    font-family: ui-monospace, 'SFMono-Regular', 'SF Mono', Menlo, Consolas, monospace;
    font-weight: 700; letter-spacing: -0.01em;
}
.cost-ticker-kg,
.ticker-kg .tnum {
    background: var(--gradient);
    -webkit-background-clip: text; background-clip: text;
    -webkit-text-fill-color: transparent; color: transparent;
}
.ticker-pulse {
    display: inline-block; width: 8px; height: 8px; border-radius: 50%;
    background: #ff5a5f; flex: none;
    box-shadow: 0 0 0 0 rgba(255, 90, 95, 0.55);
    animation: ticker-pulse 1.8s var(--ease-out) infinite;
}
@keyframes ticker-pulse {
    0%   { box-shadow: 0 0 0 0 rgba(255, 90, 95, 0.5); }
    70%  { box-shadow: 0 0 0 9px rgba(255, 90, 95, 0); }
    100% { box-shadow: 0 0 0 0 rgba(255, 90, 95, 0); }
}

/* ---- C: dramatic odometer in the facts section ---- */
.cost-ticker {
    display: flex; align-items: center; gap: var(--space-6); flex-wrap: wrap;
    margin: var(--space-6) 0 var(--space-8);
    padding: var(--space-5) 0;
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
}

/* ---- A: compact omnipresent badge (beside every other section number) ---- */
.section-live { color: var(--text-muted); font-variant-numeric: tabular-nums; }
.section-live.ticker-badge {
    display: inline-flex; align-items: center; gap: var(--space-2); flex-wrap: wrap;
    font-family: ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace;
    font-size: 12px; letter-spacing: 0.04em; color: var(--text-muted);
}
.ticker-live-label {
    color: #ff5a5f; font-weight: 700; letter-spacing: 0.16em;
    font-size: 10px; text-transform: uppercase;
}
.ticker-kg { font-size: 14px; }
.ticker-cap { color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.06em; font-size: 11px; }
.manifesto-live.ticker-badge { justify-content: center; margin: var(--space-2) 0 var(--space-6); }

@media (max-width: 520px) {
    .ticker-cap { width: 100%; }          /* caption wraps under the number on phones */
    .cost-ticker { gap: var(--space-4); }
}

/* Legal-Seiten (Impressum/Datenschutz): lesbares Panel über dem durchgehenden Verlauf */
.legal-page {
    background: rgba(10, 22, 34, 0.82);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    -webkit-backdrop-filter: blur(3px);
    backdrop-filter: blur(3px);
}

/* Timer auf der Landing ("Warum es uns gibt") — mittig unter dem Eyebrow */
.manifesto-live { margin: 0 0 var(--space-6); }

/* §7/§1 — Technischer Flat = primäres, morphendes Vorschau-Element, steht
   allein auf der Bühne. Das Hero-Foto = Realismus-Ebene DARÜBER, blendet erst
   bei Konvergenz/„Generieren" ein (nicht abgedunkelt dahinter). */
.de-garment-wrap { position: absolute; inset: 0; z-index: 1; display: flex; align-items: center; justify-content: center; padding: var(--space-6); transition: opacity .5s var(--ease-out); }
/* The garment's grounded contact shadow is drawn IN the SVG (garment-svg.js) so
   it aligns to each piece's hem and morphs with it. Here we only add a soft
   directional cast shadow consistent with the upper-left key light (falls down
   + slightly right): a tight ambient plus a longer soft throw. */
.de-garment { position: relative; z-index: 1; width: 78%; height: 92%; max-width: 320px; filter: drop-shadow(2px 5px 8px rgba(0,0,0,0.36)) drop-shadow(4px 13px 22px rgba(0,0,0,0.4)); }
.de-preview-photo { position: absolute; inset: 0; z-index: 2; opacity: 0; transition: opacity .5s var(--ease-out); pointer-events: none; }
.de-preview-photo.is-shown { opacity: 1; }
.de-preview.is-realism .de-garment-wrap { opacity: 0.1; }
.de-preview-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.de-preview-photo.is-duo { isolation: isolate; }
.de-preview-photo.is-duo img { filter: grayscale(1) contrast(1.06) brightness(0.9); }
.de-preview-photo .de-preview-duo { position: absolute; inset: 0; mix-blend-mode: color; opacity: 0.9; }
.de-preview-photo:not(.is-duo) .de-preview-duo { display: none; }
@media (prefers-reduced-motion: reduce) { .de-garment-wrap, .de-preview-photo { transition: none; } }

/* Genesis-Reise: Vor der Kategorie-Wahl steht KEIN Kleidungsstück auf der
   Bühne — ein abstrakter Faden-Fluss (Nebula) atmet ruhig und gewinnt mit
   jeder Antwort Material. Die Kategorie-Entscheidung „webt" ihn dann in die
   Silhouette: alle Pfade zeichnen sich per Stroke-Draw selbst (is-weave),
   die Füllung blendet nach. Reduced-Motion: Zustände erscheinen sofort. */
@media (prefers-reduced-motion: no-preference) {
  /* Cinematic genesis curve used across the moment for one coherent feel.
     Tempo follows the mood (§5.2): calm = long slow breaths, bold = quick
     tight pulses — render-preview sets --neb-breath/--neb-pulse from energy. */
  .de-garment-wrap.is-genesis .de-nebula { animation: deBreath var(--neb-breath, 7s) ease-in-out infinite alternate; will-change: opacity, transform; }
  /* One-time draw-in on the FIRST genesis paint only: during a re-tension
     tween (.is-retension, per-frame repaints) a restarting draw-in would pin
     every fresh path at dashoffset 1 (invisible). */
  .de-garment-wrap.is-genesis:not(.is-retension) .de-nebula path { stroke-dasharray: 1; stroke-dashoffset: 1; animation: deWeaveDraw 1.3s cubic-bezier(0.22, 1, 0.36, 1) forwards; }
  /* Bright fibre nodes pulse (staggered) so the spun threads feel alive. */
  .de-garment-wrap.is-genesis .de-neb-node { animation: deNodePulse var(--neb-pulse, 3.4s) ease-in-out infinite alternate; transform-box: fill-box; transform-origin: center; }
  .de-garment-wrap.is-genesis .de-neb-node:nth-of-type(2n) { animation-delay: .8s; animation-duration: calc(var(--neb-pulse, 3.4s) * 1.2); }
  .de-garment-wrap.is-genesis .de-neb-node:nth-of-type(3n) { animation-delay: 1.5s; animation-duration: calc(var(--neb-pulse, 3.4s) * 1.08); }
  /* While the re-tension tween repaints per frame (.is-tweening), the infinite
     breath/pulse animations pause: each repaint would restart them at t=0 and
     pin the nodes at their dimmest keyframe for the whole tween. The tween's
     own lerped opacities carry the life; idle animation resumes at tween end. */
  .de-garment-wrap.is-genesis.is-tweening .de-nebula,
  .de-garment-wrap.is-genesis.is-tweening .de-neb-node { animation: none; }
  /* Weave-in — the journey's sanctioned hero beat (§5.3, ~1.6 s):
       1) the genesis threads converge into the piece (.de-weave-ghost),
       2) the OUTLINE draws itself along its paths out of them,
       3) the construction seams stitch on,
       4) the panels (fill/shading/ground shadow) materialise LAST,
       5) a soft light sweep passes over the finished cloth.
     The gs-* layer classes come from garment-svg renderFlat; reduced-motion
     never sets .is-weave (everything appears complete, instantly). */
  .de-weave-ghost { position: absolute; inset: 0; z-index: 0; display: flex; align-items: center; justify-content: center; padding: var(--space-6); pointer-events: none; animation: deGhostConverge .6s cubic-bezier(0.22, 1, 0.36, 1) forwards; }
  .de-garment-wrap.is-weave .gs-outline { stroke-dasharray: 1; stroke-dashoffset: 1; animation: deWeaveDraw 1.1s cubic-bezier(0.22, 1, 0.36, 1) .12s both; will-change: stroke-dashoffset; }
  .de-garment-wrap.is-weave .gs-seams { opacity: 0; animation: deFillIn .45s var(--ease-out) .9s both; }
  .de-garment-wrap.is-weave .gs-seams path { stroke-dasharray: 1; stroke-dashoffset: 1; animation: deWeaveDraw .6s cubic-bezier(0.22, 1, 0.36, 1) .95s both; }
  .de-garment-wrap.is-weave .gs-int,
  .de-garment-wrap.is-weave .gs-ground { opacity: 0; animation: deFillIn .6s var(--ease-out) 1s both; }
  .de-garment-wrap.is-weave::after { content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 2;
    background: linear-gradient(115deg, transparent 40%, rgba(126,224,207,0.18) 50%, transparent 60%);
    background-size: 260% 100%; animation: deSweep 1.15s cubic-bezier(0.22, 1, 0.36, 1) 1s both; }
  .de-garment-wrap:not(.is-genesis) .de-garment { animation: deFloat 8s ease-in-out infinite alternate; }
}
@keyframes deWeaveDraw { to { stroke-dashoffset: 0; } }
@keyframes deFillIn { to { opacity: 1; } }
@keyframes deGhostConverge { from { opacity: 1; transform: scale(1); } to { opacity: 0; transform: scale(0.85); } }
@keyframes deBreath { from { opacity: 0.84; transform: scale(0.99); } to { opacity: 1; transform: scale(1.012); } }
@keyframes deFloat { from { transform: translateY(-2.5px); } to { transform: translateY(2.5px); } }
@keyframes deNodePulse { from { opacity: 0.25; transform: scale(0.7); } to { opacity: 0.9; transform: scale(1.25); } }
@keyframes deSweep { from { background-position: 140% 0; opacity: 1; } to { background-position: -140% 0; opacity: 0; } }

/* Karten-Kacheln zeigen statt rosa-lila Farbfläche eine parametrische
   GarmentSVG-Illustration der jeweiligen Option (Kragen/Länge/Verschluss …);
   ein echtes Foto blendet darüber, sobald das JSON `image` lädt. */
.de-visual-garment { background: radial-gradient(120% 90% at 50% 22%, #16293b, var(--bg)82%); }
.de-visual-garment .de-garment { width: 100%; height: 100%; max-width: none; filter: drop-shadow(0 6px 16px rgba(0,0,0,0.4)); }

/* ── Hybrid card cohesion (Schritt 3) ───────────────────────────────────
   One shared "campaign" treatment over EVERY tile — photo (mood/material/
   context) and technical flat (collar/sleeve/pockets) alike — so the two
   visual languages read as one system: a cohesive cool grade + bottom
   vignette seats heterogeneous photos on the dark theme and unifies them
   with the line-art tiles. The photo itself sits below this overlay. */
.de-visual-img { z-index: 1; }
.de-visual::after {
    content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none;
    border-radius: inherit;
    background:
        linear-gradient(180deg, rgba(10, 22, 34, 0) 45%, rgba(10, 22, 34, 0.55) 100%),
        radial-gradient(120% 100% at 50% 0%, rgba(126, 224, 207, 0.06), rgba(0, 0, 0, 0) 60%);
}
/* Crisper, more intentional technical flats: brighten the line a touch and
   lift it off the tile so it reads as a deliberate spec drawing, not a stub. */
.de-visual-garment { color: #d7dade; }
.de-visual-garment .de-garment { filter: drop-shadow(0 4px 14px rgba(0, 0, 0, 0.5)) drop-shadow(0 0 1px rgba(255, 255, 255, 0.15)); }

/* One strong, consistent selection state for photo + diagram tiles alike:
   gradient-accent ring + glow + the existing ✓, and the chosen tile brightens. */
.de-card.is-selected {
    border-color: transparent;
    box-shadow: 0 0 0 2px var(--accent), 0 10px 34px rgba(47, 174, 158, 0.28), var(--shadow-soft);
}
.de-card.is-selected .de-visual::after {
    background:
        linear-gradient(180deg, rgba(10, 22, 34, 0) 45%, rgba(10, 22, 34, 0.5) 100%),
        radial-gradient(120% 100% at 50% 0%, rgba(47, 174, 158, 0.14), rgba(0, 0, 0, 0) 65%);
}
@media (prefers-reduced-motion: no-preference) {
    .de-card.is-selected .de-visual-img { transform: scale(1.03); transition: transform .35s var(--ease-out); }
}

/* ═══ UR-CREATE-DIREKTIVE — Hero · Ownership · Galerie · Problem · Vision ·
   Join · Final · Sticky-CTA. Nur :root-Tokens, mobile-first. ═══ */

/* 1 · Hero */
.ur-hero { padding: calc(96px + env(safe-area-inset-top)) 0 56px; min-height: calc(86 * var(--svh, 1svh)); display: flex; align-items: center; position: relative; overflow: hidden; }

/* ── Modul A · Schnittmuster-Hero (SVG-Bezier-Layer) ───────────────────────── */
/* Selbstzeichnen beim Laden (pathLength=1 normiert die Strichlänge), danach
   sehr langsames Opacity-Atmen. Pro Kurve leicht gestaffelt. */
/* Lichtfunken: kurzes helles Dash-Segment, das den Stroke entlangläuft —
   weil es Teil des Strokes ist, klebt es exakt an der morphenden Geometrie
   (Reel-Referenz: Licht wandert an der Linie entlang). Erscheint nach dem
   Draw-In, pro Kurve eigenes Tempo. */
@keyframes urcDraw { to { stroke-dashoffset: 0; } }
@keyframes urcBreathe { 0%, 100% { opacity: 1; } 50% { opacity: .85; } }
@keyframes urcPulse { from { transform: scale(.78); opacity: .7; } to { transform: scale(1.15); opacity: 1; } }
@keyframes urcSpark { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes urcSparkFade { to { opacity: .9; } }

/* ── Modul B · Aurora-Layer ────────────────────────────────────────────────
   Weiche radial-gradient-Falloffs statt filter:blur (kein iOS-Safari-Jank);
   Drift ausschließlich per transform (compositor-only). */
.aurora { position: absolute; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
.aurora::before, .aurora::after {
  content: ""; position: absolute; width: min(55vw, 640px); height: min(55vw, 640px);
  border-radius: 50%; will-change: transform;
}
.aurora::before { top: -12%; left: -8%; background: radial-gradient(closest-side, rgba(47,174,158,.42), transparent 70%); /* --accent */ animation: auroraDriftA 26s ease-in-out infinite alternate; }
.aurora::after { bottom: -14%; right: -6%; background: radial-gradient(closest-side, rgba(47,134,179,.33), transparent 70%); /* --accent-2 */ animation: auroraDriftB 34s ease-in-out infinite alternate; }
@keyframes auroraDriftA { from { transform: translate(0, 0) scale(1); } to { transform: translate(10%, 8%) scale(1.15); } }
@keyframes auroraDriftB { from { transform: translate(0, 0) scale(1.05); } to { transform: translate(-12%, -8%) scale(1.1); } }
/* Dritter Orb im Community-Hub: ein einzelner Orb, eigene Position. */
.community-hub { position: relative; overflow: hidden; }
.community-hub > .container { position: relative; z-index: 1; }
.aurora--community::after { display: none; }
.aurora--community::before { top: auto; bottom: -18%; left: auto; right: -10%; background: radial-gradient(closest-side, rgba(126,224,207,.24), transparent 70%); /* --accent-3 */ animation: auroraDriftB 30s ease-in-out infinite alternate; }
@media (prefers-reduced-motion: reduce) {
  .aurora::before, .aurora::after { animation: none !important; }
}

/* ── f13 · Border-Beam: Lichtbogen läuft um die Kante (Reel-Motiv „Connected",
   hier = LIVE-Zustand des Showcase-Rahmens). Wrapper-Variante: statische Ring-
   Maske auf .ur-beam, darin rotiert NUR der Conic-Gradient per transform
   (compositor-only — keine Repaints). ────────────────────────────────────── */
@keyframes urBeamSpin { to { transform: rotate(1turn); } }

/* Featured-Kachel im Community-Hub: gleiche Optik ohne Zusatz-Markup (Kachel
   kommt aus ur-create.js) → Conic-Winkel via @property animiert. Browser ohne
   @property zeigen einen statischen Bogen (würdevoller Fallback). */
@property --ur-beam-a { syntax: "<angle>"; inherits: false; initial-value: 0deg; }
@keyframes urBeamAngle { to { --ur-beam-a: 360deg; } }
/* position:relative + overflow:hidden → der absolut gesetzte .de-garment-wrap
   bleibt in SEINER Box; vorher füllte er die ganze Stage und überlappte die
   Caption (iPhone-Report). */
/* Portrait-Rahmen, der das (Hochformat-)Stück eng fasst, statt es in einer
   breiten Landschafts-Box schweben zu lassen → Flat und Foto füllen denselben
   Rahmen, die Webkante verwandelt EIN deckungsgleiches Stück. */
/* Flat (technischer Schnitt) und echtes Foto deckungsgleich gestapelt — beide
   zentriert auf dunklem Grund (Foto via contain, dessen Studio-Grund ~= --bg
   blendet), damit die Webkante das EINE Stück verwandelt statt zwei Bilder zu
   tauschen. Bewegung wird per Web Animations API (ur-create.js) gesteuert. */
.ur-hero-flat, .ur-hero-photo { position: absolute; inset: 0; width: 100%; height: 100%; }
.ur-hero-flat { display: flex; align-items: center; justify-content: center; }
.ur-hero-flat svg { height: 86%; width: auto; filter: drop-shadow(0 8px 22px rgba(0,0,0,0.4)); }
/* contain (nicht cover): das Foto ist jetzt freigestellt (transparent) → das
   Stück zentriert auf dem Stage-Grund, deckungsgleich zum Flat, statt den
   Rahmen zu füllen und oben/unten zu beschneiden. */
.ur-hero-photo { object-fit: contain; border-radius: inherit; will-change: clip-path, filter; clip-path: inset(0 0 100% 0); }
/* Leuchtende Webkante: dünner Gradient-Faden + Glow + weiche Schimmer-Bahn
   darunter; fährt (JS: top 0→100 %) mit der Enthüllungskante nach unten. */
.ur-hero-weave { position: absolute; left: 0; right: 0; top: 0; height: 0; opacity: 0; pointer-events: none; will-change: top, opacity; }
.ur-hero-weave::before { content: ""; position: absolute; left: 6%; right: 6%; top: -1px; height: 2px; border-radius: 2px; background: linear-gradient(90deg, transparent, var(--accent-2), var(--accent-3), var(--accent), transparent); box-shadow: 0 0 14px 2px rgba(126,224,207,0.55); }
.ur-hero-weave::after { content: ""; position: absolute; left: 0; right: 0; top: -2px; height: 30px; background: linear-gradient(180deg, rgba(126,224,207,0.20), transparent); }

.btn-ghost { padding: 0.8rem 1.4rem; border-radius: 999px; border: 1px solid var(--border, #25415a); background: transparent; color: var(--text); font: inherit; cursor: pointer; transition: border-color .2s var(--ease-out), background .2s var(--ease-out); }
.btn-ghost:hover, .btn-ghost:focus-visible { border-color: var(--accent); background: rgba(47,174,158,0.08); }
.manifesto-link.as-button { background: none; border: none; cursor: pointer; font: inherit; padding: 0; }

/* 3 · Ownership */
.ownership { padding: 86px 0; background: linear-gradient(180deg, transparent, rgba(47,134,179,0.06) 40%, transparent); }
.ownership-inner { text-align: center; max-width: 720px; }
.ownership-headline { font-family: var(--font-display, 'Lora', serif); font-size: clamp(1.9rem, 5.4vw, 3rem); line-height: 1.12; }
.ownership-headline em { font-style: italic; background: var(--gradient); -webkit-background-clip: text; background-clip: text; color: transparent; }
.ownership-name { margin: 14px 0 4px; color: var(--accent-3, #7ee0cf); letter-spacing: 0.1em; }
.ownership-text { color: var(--text-muted); max-width: 56ch; margin: 14px auto 26px; }
.ownership-actions { display: flex; flex-wrap: wrap; gap: 14px; justify-content: center; }
.ownership-next { display: flex; flex-wrap: wrap; gap: 22px; justify-content: center; margin-top: 26px; }

/* Ownership-Moment · die fotorealistische Anprobe + „Wer trägt es?"-Auswahl
   + Design-Infos in EINER ruhigen Sektion. Zwei Spalten (Stage links, Auswahl
   + Infos rechts), die auf Mobil sauber untereinander stapeln. */
.own-show {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(280px, 360px);
    gap: 22px;
    max-width: 1040px;
    margin: 34px auto 6px;
    text-align: left;
}
.own-stage-col { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.own-stage-col .vto-stage {
    flex: 1;
    min-height: 440px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
}
.own-stage-col .vto-stage .vto-result-img { max-height: 560px; }
.own-stage-col .vto-btn { width: 100%; }
.own-stage-col .vto-disclaimer { text-align: left; }

.own-side-col { display: flex; flex-direction: column; gap: 18px; min-width: 0; }
.own-chooser,
.own-info {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 20px;
}
.own-side-title {
    font-family: var(--font-display, 'Lora', serif);
    font-size: 1.15rem;
    margin: 0 0 12px;
}
.own-upload-btn {
    width: 100%;
    padding: 13px 16px;
    border-radius: var(--radius-sm, 10px);
    border: 1px solid transparent;
    background: var(--gradient);
    color: var(--on-accent);
    font-weight: 600;
    cursor: pointer;
    transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.own-upload-btn:hover { transform: translateY(-2px); }
.own-upload-hint { color: var(--text-muted); font-size: 0.82rem; margin: 10px 0 0; }
.own-or {
    color: var(--text-muted);
    font-size: 0.78rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    margin: 18px 0 12px;
    display: flex;
    align-items: center;
    gap: 10px;
}
.own-or::before,
.own-or::after { content: ""; flex: 1; height: 1px; background: var(--border); }
.own-presets {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 10px;
}
.own-preset {
    position: relative;
    padding: 0;
    border: 2px solid transparent;
    border-radius: var(--radius-sm, 10px);
    background: #0e1c2b;
    overflow: hidden;
    cursor: pointer;
    aspect-ratio: 2 / 3;
    transition: border-color 0.2s ease, transform 0.2s ease;
}
.own-preset img { width: 100%; height: 100%; object-fit: cover; display: block; }
.own-preset:hover { transform: translateY(-2px); }
.own-preset.is-selected {
    border-color: var(--accent-3, #7ee0cf);
    box-shadow: 0 0 0 2px rgba(126, 224, 207, 0.35);
}
.own-preset.is-loading, .own-upload-btn.is-loading { opacity: 0.6; cursor: progress; }
.own-preset:focus-visible { outline: 2px solid var(--accent-3, #7ee0cf); outline-offset: 2px; }

.own-info-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 18px; margin: 0; }
.own-info-grid > div { min-width: 0; }
.own-info-grid dt {
    color: var(--text-muted);
    font-size: 0.72rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    margin: 0 0 3px;
}
.own-info-grid dd {
    margin: 0;
    font-size: 0.95rem;
    color: var(--text);
    display: flex;
    align-items: center;
    gap: 7px;
}
.oi-swatch {
    width: 13px;
    height: 13px;
    border-radius: 3px;
    border: 1px solid rgba(255, 255, 255, 0.25);
    display: inline-block;
    flex: none;
}

/* „Weiter anpassen" — kompakter Inline-Editor (Fassade über #design/#measure) */
.own-edit { max-width: none; margin: 0; text-align: left; }
/* The calibrate editor now lives in the moment's (narrow) side column → single
   column, full width of the column. */
.own-side-col .own-edit-body { grid-template-columns: 1fr; }
.own-choose-lead { color: var(--text-muted); font-size: 0.9rem; line-height: 1.5; margin: 0 0 14px; }
.own-edit-summary {
    cursor: pointer;
    list-style: none;
    padding: 12px 16px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg-card);
    color: var(--text);
    font-weight: 600;
    display: flex;
    align-items: center;
    gap: 8px;
}
.own-edit-summary::-webkit-details-marker { display: none; }
.own-edit-summary::after {
    content: "▾";
    margin-left: auto;
    color: var(--text-muted);
    transition: transform 0.2s ease;
}
.own-edit[open] .own-edit-summary { border-radius: var(--radius) var(--radius) 0 0; }
.own-edit[open] .own-edit-summary::after { transform: rotate(180deg); }
.own-edit-body {
    border: 1px solid var(--border);
    border-top: none;
    border-radius: 0 0 var(--radius) var(--radius);
    background: var(--bg-card);
    padding: 18px;
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 16px 20px;
}
.own-edit-field { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.own-edit-label {
    color: var(--text-muted);
    font-size: 0.74rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}
.own-edit select,
.own-edit input[type="range"] { width: 100%; }
.own-edit-value {
    color: var(--text);
    font-size: 0.82rem;
    font-weight: 500;
    margin-top: -2px;
}
.own-edit select {
    padding: 9px 10px;
    border-radius: var(--radius-sm, 10px);
    border: 1px solid var(--border-field);
    background: var(--bg-elevated);
    color: var(--text);
}
.own-edit-colors { display: flex; flex-wrap: wrap; gap: 8px; }
.oe-color {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    padding: 0;
    cursor: pointer;
    border: 2px solid transparent;
    transition: transform 0.15s ease, border-color 0.15s ease;
}
.oe-color:hover { transform: scale(1.1); }
.oe-color[aria-pressed="true"] {
    border-color: var(--accent-3, #7ee0cf);
    box-shadow: 0 0 0 2px rgba(126, 224, 207, 0.3);
}
.oe-color:focus-visible { outline: 2px solid var(--accent-3, #7ee0cf); outline-offset: 2px; }
.own-edit-sizes { display: flex; gap: 8px; }
.oe-size {
    flex: 1;
    padding: 8px 0;
    border-radius: var(--radius-sm, 10px);
    border: 1px solid var(--border);
    background: var(--bg-elevated);
    color: var(--text);
    cursor: pointer;
    font-weight: 600;
    transition: border-color 0.15s ease, color 0.15s ease;
}
.oe-size:hover { border-color: var(--accent-3, #7ee0cf); }
.oe-size.is-active { border-color: var(--accent-3, #7ee0cf); color: var(--accent-3, #7ee0cf); }
.own-edit-hint { grid-column: 1 / -1; margin: 0; color: var(--text-muted); font-size: 0.8rem; }

@media (max-width: 860px) {
    .own-show { grid-template-columns: 1fr; }
    .own-stage-col .vto-stage { min-height: 360px; }
    .own-edit-body { grid-template-columns: 1fr; }
}

/* 4 · Galerie */
.gallery { padding: 72px 0; }

/* 5 · Problem-Karten */
.problem { padding: 72px 0 8px; }
@keyframes probIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* 7 · Community-Hub: Typ-Filter-Chips + hervorgehobene Kachel + Mitmachen-Block.
   (Galerie + Beitreten wurden zu einer Sektion zusammengeführt.) */

/* Mitmachen: der Übergang vom Entdecken zum Teil-Werden (zentriert, abgesetzt). */
.community-join { max-width: 680px; margin: 56px auto 0; padding-top: 44px; border-top: 1px solid var(--border, #25415a); text-align: center; }
.community-join-sub { color: var(--text-muted); max-width: 52ch; margin: 0 auto 26px; }
.join-headline { font-family: var(--font-display, 'Lora', serif); font-size: clamp(1.8rem, 5vw, 2.7rem); margin: 12px 0 14px; }
.join-choices { border: none; padding: 0; margin: 0 0 22px; display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 10px; }
.join-choice { display: flex; align-items: center; gap: 10px; padding: 0.85rem 1rem; border: 1px solid var(--border, #25415a); border-radius: 12px; cursor: pointer; font-size: 0.92rem; text-align: left; transition: border-color .2s; }
.join-choice:hover { border-color: var(--accent); }
.join-choice input { accent-color: var(--accent); }
.join-row { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; }
.join-row input[type="email"] { flex: 1 1 240px; padding: 0.85rem 1.1rem; border-radius: 999px; border: 1px solid var(--border-field, #4a7196); background: var(--bg-elevated, #0f1e2e); color: var(--text); font: inherit; }
.join-consent { margin-top: 14px; font-size: 0.8rem; color: var(--text-muted); }
.join-status { margin-top: 12px; color: var(--accent-3, #7ee0cf); min-height: 1.2em; }

/* ── Community-Sphäre — Kugel-Galerie ersetzt Filter+Grid ──────────────────
   Volle Sektionshöhe, Canvas füllt den Raum; Scroll läuft durch (kein
   Wheel-Hijack, touch-action: pan-y), nur Ziehen/Tippen interagiert.
   Overlays (Detail/Join) liegen fixed über der Seite, ≤ 250 ms Übergänge. */
/* Höhe = Viewport minus Anker-Versatz (scroll-margin-top 72px): so sitzt die
   Sektion nach einem Nav-Sprung exakt im Fold, CTA inklusive. */
.community-sphere { padding: 0; min-height: calc(100svh - 72px - env(safe-area-inset-top)); display: flex; flex-direction: column; }
.community-sphere .sphere-head { position: relative; z-index: 2; padding-top: 76px; pointer-events: none; }
.community-sphere .section-header { margin-bottom: 0; }
.community-sphere .section-header p { max-width: 56ch; }
/* Kompakter Glas-Header: die Sphäre ist der Star — der Titel wird zur
   schlanken, zentrierten Kapsel statt einer großen Karte. */
.community-sphere .sphere-head { text-align: center; }
.community-sphere .section-header {
    display: inline-block;
    padding: 0.8rem 1.8rem 0.95rem;
    text-align: center;
    max-width: min(92%, 620px);
}
.community-sphere .section-header::after { display: none; }
.community-sphere .section-header .section-label { font-size: 0.58rem; margin-bottom: 6px; }
.community-sphere .section-header h2 { font-size: clamp(1.25rem, 2.6vw, 1.65rem); margin-bottom: 4px; }
.community-sphere .section-header p { font-size: 0.78rem; max-width: 58ch; margin: 0 auto; }
.sphere-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; touch-action: pan-y; cursor: grab; z-index: 1; }
.sphere-canvas:focus-visible { outline: 2px solid var(--accent-3, #7ee0cf); outline-offset: -3px; }
.community-sphere.is-dragging .sphere-canvas { cursor: grabbing; }
.community-sphere.has-hover .sphere-canvas { cursor: pointer; }
/* Scrims oben/unten trennen Header + Hint/CTA von den vorbeiziehenden
   Karten (Lesbarkeit), die Mitte bleibt frei für die Sphäre. */
.sphere-vignette { position: absolute; inset: 0; pointer-events: none; z-index: 1;
    background:
        linear-gradient(180deg, rgba(4, 10, 17, 0.85), rgba(4, 10, 17, 0.35) 15%, transparent 30%),
        linear-gradient(0deg, rgba(4, 10, 17, 0.8), rgba(4, 10, 17, 0.3) 13%, transparent 26%),
        radial-gradient(115% 80% at 50% 46%, transparent 52%, rgba(4, 10, 17, 0.5) 100%); }
.sphere-foot { position: relative; z-index: 2; margin-top: auto; display: flex; flex-direction: column; align-items: center; gap: 16px; padding: 28px 20px calc(30px + env(safe-area-inset-bottom)); pointer-events: none; }
.sphere-hint { color: var(--text-muted); font-size: 0.7rem; letter-spacing: 0.22em; text-transform: uppercase; text-align: center; padding: 0.55rem 1.15rem; }
.sphere-cta { pointer-events: auto; font: inherit; font-size: 0.92rem; font-weight: 600; color: var(--text); padding: 0.8rem 1.6rem; cursor: pointer; transition: border-color 0.22s ease, transform 0.22s ease; }
.sphere-cta:hover { border-color: rgba(126, 224, 207, 0.6); transform: translateY(-2px); }
/* Liquid Glass (Apple-Look) — EIN Rezept, EINE Form (Kapsel) für alle
   Text-Halter der Sphäre: stark verdichtetes Milchglas (blur + saturate),
   weiße Hairline, Spekular-Kante oben. Basis-Deckung ~0.4 als Fallback
   ohne backdrop-filter-Support. */
.community-sphere .section-header,
.sphere-hint,
.sphere-cta {
    background: rgba(14, 30, 46, 0.4);
    -webkit-backdrop-filter: blur(28px) saturate(180%);
    backdrop-filter: blur(28px) saturate(180%);
    border: 1px solid rgba(255, 255, 255, 0.13);
    border-radius: 999px;
    box-shadow:
        inset 0 1px 1px rgba(255, 255, 255, 0.18),
        inset 0 -1px 1px rgba(255, 255, 255, 0.04),
        0 12px 32px rgba(4, 10, 17, 0.45);
}
.sphere-label { position: absolute; top: 0; left: 0; z-index: 3; pointer-events: none; display: flex; flex-direction: column; gap: 3px; opacity: 0; transition: opacity 0.2s ease; will-change: transform; }
.sphere-label.is-on { opacity: 1; }
.sphere-label-name { font-weight: 600; font-size: 0.9rem; text-shadow: 0 1px 8px rgba(0, 0, 0, 0.9); }
.sphere-label-meta { font-size: 0.68rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--text-muted); text-shadow: 0 1px 6px rgba(0, 0, 0, 0.9); }
@media (pointer: coarse) { .sphere-label { display: none; } }

/* Overlays: Detail + Join — gleiche Hülle, eigener Inhalt.
   Wichtig: [hidden] muss das display:flex schlagen, sonst liegt das
   unsichtbare Overlay über der ganzen Seite und frisst alle Klicks. */
.sphere-detail, .sphere-join { position: fixed; inset: 0; z-index: 140; display: flex; align-items: center; justify-content: center; padding: 18px; }
.sphere-detail[hidden], .sphere-join[hidden] { display: none; }
.sphere-backdrop { position: absolute; inset: 0; background: rgba(4, 10, 17, 0.72); backdrop-filter: blur(10px); opacity: 0; transition: opacity 0.22s ease; }
.sphere-detail-card, .sphere-join-card { position: relative; opacity: 0; transform: translateY(18px) scale(0.985); transition: opacity 0.22s ease, transform 0.24s ease; }
.sphere-detail.is-open .sphere-backdrop, .sphere-join.is-open .sphere-backdrop { opacity: 1; }
.sphere-detail.is-open .sphere-detail-card, .sphere-join.is-open .sphere-join-card { opacity: 1; transform: none; }
html.sphere-lock, html.sphere-lock body { overflow: hidden; }

.sphere-close { position: absolute; top: 12px; right: 12px; z-index: 2; width: 40px; height: 40px; border-radius: 50%; border: 1px solid var(--border, #25415a); background: rgba(10, 22, 34, 0.65); color: var(--text); font-size: 1.3rem; line-height: 1; cursor: pointer; transition: border-color 0.2s ease; }
.sphere-close:hover { border-color: var(--accent-3, #7ee0cf); }

.sphere-detail-card { margin: 0; display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); width: min(920px, 100%); max-height: min(86svh, 720px); background: var(--bg-card, #14283b); border: 1px solid var(--border, #25415a); border-radius: var(--radius-lg, 18px); overflow: hidden; box-shadow: var(--shadow-lg, 0 30px 80px rgba(0, 0, 0, 0.5)); }
.sphere-detail-media { min-height: 0; }
.sphere-detail-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sphere-detail-info { padding: clamp(22px, 4vw, 40px); display: flex; flex-direction: column; gap: 12px; justify-content: center; min-width: 0; }
.sphere-detail-kicker { color: var(--accent-3, #7ee0cf); }
.sphere-detail-name { font-family: var(--font-display, 'Lora', serif); font-size: clamp(1.7rem, 4vw, 2.5rem); margin: 0; line-height: 1.08; }
.sphere-detail-meta { color: var(--text-muted); font-size: 0.85rem; letter-spacing: 0.08em; text-transform: uppercase; margin: 0; }
.sphere-detail-line { color: var(--text-muted); margin: 4px 0 8px; }
.sphere-detail-actions { display: flex; flex-direction: column; gap: 10px; align-items: flex-start; }
.sphere-detail-join { background: none; border: none; padding: 0; font: inherit; font-size: 0.85rem; color: var(--text-muted); text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.sphere-detail-join:hover { color: var(--text); }

.sphere-join-card { width: min(720px, 100%); max-height: 86svh; overflow-y: auto; background: var(--bg-card, #14283b); border: 1px solid var(--border, #25415a); border-radius: var(--radius-lg, 18px); padding: clamp(22px, 4vw, 40px); box-shadow: var(--shadow-lg, 0 30px 80px rgba(0, 0, 0, 0.5)); }
.sphere-join-card .community-join { margin: 0; padding-top: 0; border-top: none; max-width: none; }

@media (max-width: 700px) {
    .sphere-detail-card { grid-template-columns: 1fr; overflow-y: auto; }
    .sphere-detail-media { max-height: 38svh; }
    .sphere-detail-media img { max-height: 38svh; }
    .community-sphere .sphere-head { padding-top: 64px; }
    /* Telefon: nur Label + Titel in der Kapsel — das Intro würde sie zum
       hohen Oval strecken; die Botschaft trägt das Detail-Overlay. */
    .community-sphere .section-header p { display: none; }
    .community-sphere .section-header h2 { margin-bottom: 0; }
}

/* Make-real (eingeklappter Fertigungs-Pfad) */
.make-real[hidden] { display: none; }

/* Sticky-CTA (mobil, immer erreichbar) */
.sticky-create { position: fixed; left: 50%; transform: translateX(-50%); bottom: calc(14px + env(safe-area-inset-bottom)); z-index: 60; padding: 0.9rem 1.6rem; border-radius: 999px; background: var(--gradient); color: var(--on-accent); font-weight: 700; letter-spacing: 0.04em; text-decoration: none; box-shadow: 0 10px 30px rgba(0,0,0,0.45); }
.sticky-create[hidden] { display: none; }
@media (min-width: 861px) { .sticky-create { display: none; } }

/* Concept-Studio (Direktive Schritte 3+4): Varianten-Grid + EVOLVE-Kette */
.de-concepts { margin: 18px 0 6px; }
/* §8 Refine-Crescendo: grössere Kacheln auf hellerer Bühne, jede Richtung mit
   Namen aus ihrem Delta — Mutationen (Hue ±34°, Fit ±0.15) lesen sich sonst
   auf 140px-Kacheln nicht. */
.de-concept-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(176px, 1fr)); gap: 14px; margin-top: 10px; }
.de-concept { margin: 0; display: flex; flex-direction: column; gap: 6px; position: relative; }
.de-concept-pick { position: relative; display: block; width: 100%; padding: 10px; border-radius: 14px; border: 1px solid var(--border, #25415a); background: radial-gradient(120% 90% at 50% 20%, #21384e, #101f31 84%); cursor: pointer; transition: border-color .2s var(--ease-out), transform .2s var(--ease-out), background .3s var(--ease-out), box-shadow .3s var(--ease-out); }
/* f05 · Karten gleiten gestaffelt herein (CSS-Animation greift automatisch,
   wenn flow.js das Varianten-Grid mountet — kein JS-Eingriff). */
.de-concept { animation: urConceptIn .5s var(--ease-out) backwards; }
.de-concept:nth-child(2) { animation-delay: 90ms; }
.de-concept:nth-child(3) { animation-delay: 180ms; }
.de-concept:nth-child(4) { animation-delay: 270ms; }
@keyframes urConceptIn { from { opacity: 0; transform: translateY(16px) scale(.97); } }
.de-concept-pick:hover { border-color: var(--accent); transform: translateY(-2px); }
/* f05 · Gewählte Karte = Teal-Glas (Reel-Motiv Glas-Gradient-Karte): satte
   Gradient-Fläche + Top-Highlight wie eine beleuchtete Glaskante. */
.de-concept.is-selected .de-concept-pick { border-color: var(--accent-3, #7ee0cf);
  background:
    linear-gradient(165deg, rgba(47,174,158,.30), rgba(47,134,179,.16) 52%, rgba(10,22,34,.55)),
    radial-gradient(120% 90% at 50% 22%, #16293b, var(--bg, #0a1622) 82%);
  box-shadow: inset 0 1px 0 rgba(238,244,248,.22), 0 0 0 1px var(--accent-3, #7ee0cf), 0 10px 28px rgba(0,0,0,.4); }
/* f05 · Chromatischer KI-Sparkle am Eck der gewählten Karte (vierzackiger Stern
   per clip-path). Bewusst NICHT im Evolve-Button: das DE-Label
   „Weiterentwickeln" lässt auf 120px-Karten keinen Platz für ein Icon. */
.de-concept.is-selected .de-concept-pick::after { content: ""; position: absolute; top: -6px; right: -6px; width: 14px; height: 14px;
  background: linear-gradient(135deg, var(--accent-3), var(--accent-2));
  clip-path: polygon(50% 0, 62% 38%, 100% 50%, 62% 62%, 50% 100%, 38% 62%, 0 50%, 38% 38%);
  animation: urSparkle 2.4s ease-in-out infinite; }
@keyframes urSparkle { 0%, 100% { transform: scale(.8) rotate(0deg); opacity: .75; } 50% { transform: scale(1.15) rotate(45deg); opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .de-concept { animation: none !important; }
  .de-concept.is-selected .de-concept-pick::after { animation: none !important; }
}
.de-concept-stage svg { width: 100%; height: 164px; display: block; }
.de-concept-name { display: block; margin-top: 8px; font-size: 0.84rem; line-height: 1.3; color: var(--text); text-align: left; min-height: 2.2em; }
.de-concept-meta { display: flex; align-items: center; justify-content: space-between; margin-top: 4px; }
.de-concept-v { color: var(--accent-3, #7ee0cf); font-size: 0.7rem; letter-spacing: 0.12em; }
.de-concept-actions { display: flex; gap: 6px; }
.de-concept-evolve { flex: 1; padding: 0.5rem 0.4rem; border-radius: 10px; border: 1px solid var(--accent); background: linear-gradient(180deg, rgba(47,174,158,0.16), transparent); color: var(--text); font: inherit; font-size: 0.78rem; letter-spacing: 0.04em; cursor: pointer; transition: background .2s; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: center; }
.de-concept-evolve:hover { background: rgba(47,174,158,0.28); }
/* ↩ "one version back" — a compact corner chip on the tile, NOT a row sibling,
   so the long "Weiterentwickeln" label keeps the full action-row width and the
   two never overlap on narrow tiles (iPad/phone). */
.de-concept-back { position: absolute; top: 9px; left: 9px; z-index: 3; width: 34px; height: 34px; padding: 0; display: inline-flex; align-items: center; justify-content: center; border-radius: 9px; border: 1px solid var(--border, #25415a); background: rgba(10,22,34,0.74); color: var(--text); cursor: pointer; font-size: 0.95rem; line-height: 1; }
.de-concept-back:hover { border-color: var(--accent-3, #7ee0cf); color: var(--accent-3, #7ee0cf); }
.de-concepts-hint { margin-top: 10px; font-size: 0.8rem; color: var(--text-muted); }
@media (prefers-reduced-motion: reduce) { .de-concept-pick, .de-concept-pick:hover { transition: none; transform: none; } }

/* Hero-Showcase: Journey-Badge dort ausblenden (reines Schaufenster) */

/* Bugfix: [hidden] muss IMMER gewinnen — Klassen mit eigenem display
   (.manifesto-cta, .de-nav …) überstimmten sonst die UA-Regel, wodurch z. B.
   „Zeig die Alternative" schon bei Karte 1/4 sichtbar war (iPhone-Report). */
.prob-controls [hidden], #ownership [hidden], .ownership-actions [hidden],
.sphere-detail-actions [hidden] { display: none !important; }

/* ─── UX-Scan-Feinschliff (präziser Audit) ─────────────────────────────────
   #4 Touch-Ziele werden über html.is-touch oben gelöst (Projekt-Muster). */
/* #5 Concept-Studio: Grid-/Flex-Kinder dürfen schrumpfen (min-width:0). Der
   ↩-Pfeil ist als absolute Eck-Chip aus der Aktionszeile genommen (siehe
   .de-concept-back oben), damit „Weiterentwickeln" die volle Breite behält. */
.de-concept { min-width: 0; }
.de-concept-evolve { min-width: 0; }
.de-concept-actions { align-items: stretch; }

/* ============================================================
   LANDING-EXPERIENCE (lp-*) — Hero, Marquee, Manifest, Kreislauf,
   Zahlen, Finale + Preloader. Von js/landing.js gesteuert.
   Verstärkungen sind unter html.fx gescopet (GSAP geladen + keine
   reduced motion) — ohne JS/GSAP ist alles sichtbar und benutzbar.
   ============================================================ */

:root {
    /* Stabile Viewport-Höhe: --svh wird im <head> in px gepinnt. */
    --vh100: calc(var(--svh, 1vh) * 100);
}
@supports (height: 1svh) {
    :root { --vh100: calc(var(--svh, 1svh) * 100); }
}

/* ── Preloader — die Nadel gebiert die Linie ──────────────────────────────
   Statt eines zentrierten Logos steht die Nadel-Marke oben an der Gossen-x
   und zieht EINEN geraden Faden nach unten — genau dort, wo gleich der Hero-
   Faden steht (pixelgenaue Übergabe an --act1-thread-x). */
.lp-loader {
    position: fixed;
    inset: 0;
    z-index: 150;
    background: var(--bg);
    transition: opacity 0.5s var(--ease-out), visibility 0.5s;
    --lp-mark-top: clamp(60px, 11vh, 124px);
}
.lp-loader.is-done { opacity: 0; visibility: hidden; pointer-events: none; }
html:not(.fx) .lp-loader { display: none; }
.lp-mark { color: var(--text); display: block; width: clamp(96px, 22vw, 140px); height: auto; }
/* die Marke sitzt oben, auf der Gossen-Linie zentriert (Nadel-Achse = Faden).
   Zentrierung via margin (nicht translateX), damit der GSAP-scale-Ausklang
   der Marke die Zentrierung nicht überschreibt. */
.lp-loader .lp-mark {
    position: absolute;
    top: var(--lp-mark-top);
    left: var(--act1-thread-x);
    width: clamp(74px, 11vw, 100px);
    margin-left: calc(-0.5 * clamp(74px, 11vw, 100px));
}
/* der gezogene Faden: von der Nadelspitze bis zum unteren Rand */
.lp-loader-thread {
    position: absolute;
    left: var(--act1-thread-x);
    top: calc(var(--lp-mark-top) + clamp(56px, 8vw, 82px));
    bottom: 0;
    width: 1px;
    background: linear-gradient(180deg,
        var(--act1-thread) 0%,
        var(--act1-thread) 86%,
        rgba(201, 144, 111, 0) 100%);
    transform-origin: top center;
    will-change: transform;
}
.lp-mark-eye, .lp-loop-eye { fill: var(--bg); }

/* ── Navbar im Landing-Stil (Nadel-Marke + Pill-Buttons) ── */
.lp-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    text-decoration: none;
}
.lp-mark--nav { width: 34px; height: 34px; flex: 0 0 auto; }
.lp-wordmark {
    font-size: 12px;
    font-weight: 600;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    color: var(--text);
    white-space: nowrap;
}
.lp-nav-actions { display: flex; align-items: center; gap: 10px; }
.lp-btn--nav { padding: 9px 18px; font-size: 12.5px; white-space: nowrap; }
/* Schmale Screens: erst weicht der Nav-CTA (Hero- und Sticky-CTA decken
   ihn ab), dann der Schriftzug — Nadel-Marke + Community bleiben. */
@media (max-width: 720px) {
    .lp-nav .lp-btn--primary.lp-btn--nav { display: none; }
}
@media (max-width: 480px) {
    .lp-wordmark { display: none; }
}

/* ── Buttons ── */
.lp-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 14px 26px;
    border-radius: 999px;
    font-family: var(--font-body);
    font-size: 14px;
    font-weight: 500;
    letter-spacing: 0.02em;
    text-decoration: none;
    transition: transform 0.25s var(--ease-out), box-shadow 0.25s, border-color 0.25s;
}
.lp-btn--primary {
    background: var(--gradient-cta);
    color: var(--on-accent);
    font-weight: 600;
    position: relative;
    overflow: hidden;   /* clippt den Sheen-Sweep auf die Pille (Box-Shadow bleibt sichtbar) */
}
/* Signatur-Sheen-Sweep — gleiche Geste wie .cta-button: ein heller Streifen
   wandert beim Hover über die dominante Hero-CTA. */
.lp-btn--primary::before {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(120deg, transparent 30%, rgba(255, 255, 255, 0.25) 50%, transparent 70%);
    transform: translateX(-100%);
    transition: transform 0.6s var(--ease-out);
    pointer-events: none;
}
.lp-btn--primary:hover::before { transform: translateX(100%); }
.lp-btn--primary:hover { transform: translateY(-2px); box-shadow: var(--shadow-glow); }
.lp-btn--ghost {
    border: 1px solid var(--border);
    color: var(--text-dim);
}
.lp-btn--ghost:hover { border-color: var(--accent); color: var(--text); }

/* ── Hero ── */
.lp-hero {
    position: relative;
    min-height: 100vh;
    min-height: var(--vh100);
    display: flex;
    flex-direction: column;
    justify-content: center;
}
.lp-hero-canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
}
.lp-hero-inner {
    position: relative;
    z-index: 1;
    width: 100%;
    /* Links verankert an der Linie (gemeinsame Akt-I-Spalte), nicht zentriert —
       so steht der Hero-Text konsequent RECHTS des Fadens, wie das Manifest. */
    max-width: 1220px;
    margin: 0;
    /* Unten bewusst viel Raum, damit der Scroll-Hinweis frei steht
       und nicht an den CTAs klebt. */
    padding: 96px clamp(20px, 5vw, 48px) clamp(120px, 18vh, 170px);
    padding-left: var(--act1-pad-l);
}
/* Kurze Viewports (z. B. Laptop 1280×~600 mit Browser-Chrome): Hero-Polster
   straffen + den dekorativen Tipp ausblenden, damit die primäre CTA über der
   Falte bleibt. Greift nur ≤ 660px Höhe — normale Viewports unberührt. */
@media (max-height: 660px) {
    .lp-hero-inner { padding-top: 56px; padding-bottom: clamp(56px, 9vh, 88px); }
    .lp-hero-hint { display: none; }
}
.lp-hero-eyebrow {
    font-size: 11.5px;
    font-weight: 500;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    color: var(--accent-3);
    margin-bottom: 22px;
}
.lp-hero-title {
    font-family: var(--font-display);
    font-weight: 500;
    font-size: clamp(46px, 11.5vw, 132px);
    line-height: 1.04;
    letter-spacing: var(--tracking-tighter);
}
.lp-hero-mask { display: block; overflow: hidden; padding-bottom: 0.08em; margin-bottom: -0.08em; }
.lp-hero-line { display: inline-block; }
.lp-hero-line--grad {
    font-style: italic;
    background: var(--gradient);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    /* Kursiver Überhang des „l" nicht abschneiden */
    padding-right: 0.06em;
}
.lp-hero-sub {
    max-width: 540px;
    margin-top: 26px;
    color: var(--text-dim);
    font-weight: 300;
    font-size: clamp(15px, 1.6vw, 17px);
}
.lp-hero-ctas {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    margin-top: 38px;
}
.lp-hero-hint {
    margin-top: 22px;
    font-size: 11.5px;
    letter-spacing: var(--tracking-wide);
    color: var(--text-muted);
}
/* Der Tap-Morph ist Bewegung — ohne Bewegung kein irreführender Hinweis */
@media (prefers-reduced-motion: reduce) {
    .lp-hero-hint { display: none; }
}
.lp-scroll-cue {
    position: absolute;
    left: 50%;
    bottom: calc(env(safe-area-inset-bottom, 0px) + 22px);
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    font-size: 10.5px;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    color: var(--text-muted);
}
.lp-scroll-cue-line {
    width: 1px;
    height: 44px;
    background: linear-gradient(to bottom, var(--accent-3), transparent);
    animation: lp-cue-drop 2.2s var(--ease-out) infinite;
    transform-origin: top;
}
@keyframes lp-cue-drop {
    0% { transform: scaleY(0); opacity: 0; }
    35% { transform: scaleY(1); opacity: 1; }
    100% { transform: scaleY(1) translateY(18px); opacity: 0; }
}
/* Sehr kurze Viewports (eingebettete Webviews, Telefon quer): kein Platz
   für einen frei stehenden Hinweis → ausblenden statt quetschen. */
@media (max-height: 560px) {
    .lp-scroll-cue { display: none; }
}

/* ── Sektionen, Labels ── */
.lp-block { padding: clamp(90px, 14vw, 160px) clamp(20px, 5vw, 48px); }
.lp-label {
    font-family: var(--font-mono);
    font-size: 11.5px;
    font-weight: 500;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    color: var(--accent-3);
    margin-bottom: 18px;
}
.lp-label::before { content: "[ "; color: var(--text-muted); }
.lp-label::after { content: " ]"; color: var(--text-muted); }

/* ── Manifest — sitzt rechts an der Linie (Gossen-Spine) ──
   Sektion VOLLE Breite, damit left:--act1-thread-x = Viewport-x ist und der
   Manifest-Faden exakt unter dem Hero-Faden steht (EINE Linie). Inhalt ist
   eine links verankerte redaktionelle Spalte rechts der Linie. */
.lp-manifesto { position: relative; }
.lp-manifesto-col { max-width: 920px; padding-left: var(--act1-pad-l); }
.lp-manifesto-text {
    font-family: var(--font-display);
    font-size: clamp(26px, 4.6vw, 52px);
    font-weight: 400;
    line-height: 1.3;
    letter-spacing: -0.01em;
}
.lp-manifesto-text .w { display: inline-block; }
/* Verben-Band — drei Stationen der Linie, aufgefädelt auf den Gossen-Faden.
   Die Knoten sitzen AUF der Linie (Gossen-x = Spalten-Anschlag), die Labels
   in Maschinen-Stimme daneben. Ohne JS bleibt der reine i18n-String stehen. */
.lp-verbs {
    list-style: none;
    margin: clamp(34px, 6vw, 60px) 0 0;
    padding: 0;
    font-family: var(--font-mono);
    font-size: clamp(11px, 1.4vw, 13px);
    font-weight: 500;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    color: var(--text-muted);
}
/* aufgefädelt: die Liste rückt links auf die Gossen-Linie (Knoten AUF dem Faden) */
.lp-verbs.is-stationed { margin-left: calc(var(--act1-thread-x) - var(--act1-pad-l)); }
/* No-JS-Rückfall: der ungespaltete String liegt als ruhige Mono-Zeile (im Text-Padding) */
.lp-verbs:not(.is-stationed) {
    padding-top: 16px;
    border-top: 1px solid var(--border);
}
.lp-verb {
    display: block;
    position: relative;
    padding: 15px 0 15px 28px;   /* Label 28px rechts der Linie */
    line-height: 1.2;
}
.lp-verb + .lp-verb { border-top: 1px solid var(--act1-thread-dim); }
/* der Stations-Knoten — exakt auf der Gossen-Linie (Listen-Anschlag = Faden),
   Loop-Dot-Vokabular (bg-Füllung, Muted-Rand). */
.lp-verb-knot {
    position: absolute;
    left: 0;
    top: 50%;
    width: 7px;
    height: 7px;
    margin: -3.5px 0 0 -3.5px;
    border-radius: 50%;
    background: var(--bg);
    border: 1px solid var(--text-muted);
    box-shadow: 0 0 0 3px var(--bg);
}
/* Index dimmer (muted), Label heller (dim) — Hierarchie, aber beide klar über
   AA-Kontrast (der frühere --act1-thread-dim-Index fiel bei axe durch). */
.lp-verb-index {
    color: var(--text-muted);
    margin-right: 10px;
}
.lp-verb-label { color: var(--text-dim); }
/* die letzte Station (Wegwerfen) ist das Ende der Linie — am hellsten markiert */
.lp-verb:last-child .lp-verb-label { color: var(--text); }

/* ── Akt I · „Die Linie" — der eine kupferne Maschinen-Faden ───────────────
   Ein durchgehender Faden (Kupfer/Rosé wie die Chaos-Stränge der Slides,
   bewusst OHNE Teal) läuft an --act1-thread-x senkrecht durch Preloader →
   Hero → Manifest → in #facts. Er ist TOT GERADE — genau das macht die Wende
   (#pivot) lesbar. Ruhezustand (kein JS / reduced-motion) = fertig gezeichnet;
   nur GSAP setzt Startzustände (scaleY 0) und zeichnet ihn ein. Farbe =
   fil-seam[1] / #pivot-line (die alte, lineare Industrie: warm, menschlich,
   weggeworfen). Teal/Aqua wird erst nach der Wende ausgegeben. */
.lp-linie {
    position: absolute;
    left: var(--act1-thread-x);
    top: 0;
    bottom: 0;
    width: 1px;
    z-index: 0;
    pointer-events: none;
}
.lp-linie-rail {
    position: absolute;
    inset: 0;
    width: 1px;
    background: linear-gradient(180deg,
        rgba(201, 144, 111, 0) 0%,
        var(--act1-thread) 6%,
        var(--act1-thread) 94%,
        rgba(201, 144, 111, 0) 100%);
    transform-origin: top center;
    will-change: transform;
}
/* Hero: von oben hart einsetzend (Übergabe aus dem Preloader-Faden),
   unten ausklingend Richtung Manifest. */
.lp-linie--hero .lp-linie-rail {
    background: linear-gradient(180deg,
        var(--act1-thread) 0%,
        var(--act1-thread) 80%,
        rgba(201, 144, 111, 0) 100%);
}
/* der Ruhe-Knoten: die Spitze des Fadens, kurz unter der Headline */
.lp-linie-tip {
    position: absolute;
    left: 0;
    top: clamp(320px, 62vh, 640px);
    width: 6px;
    height: 6px;
    margin: -3px 0 0 -3px;
    border-radius: 50%;
    background: var(--act1-thread);
    box-shadow: 0 0 0 3px var(--bg), 0 0 10px 1px rgba(201, 144, 111, 0.22);
}
/* Manifest-Faden klingt oben/unten weich aus (Segment einer Linie) */
.lp-linie--mani .lp-linie-rail {
    background: linear-gradient(180deg,
        rgba(201, 144, 111, 0) 0%,
        var(--act1-thread) 4%,
        var(--act1-thread) 100%);
}

/* Übergabe in #facts — die eine Stelle, an der die Akt-I-Gossen-Linie EINMAL
   sanft zur Mitte findet (dort liegt ab #facts/#pivot die zentrale Spine der
   Seite). Bewusst eine ruhige Naht-Kurve wie „Der Faden" — NICHT die dramatische
   Wende (#pivot bleibt die eigentliche Krümmung). Das SVG spannt exakt von der
   Gosse (left:--act1-thread-x) bis zur Mitte (right:50%), preserveAspectRatio
   none → x 0→100 bildet Gosse→Mitte über jede Breite ab (kein px-in-d nötig).
   Ruhezustand = gezeichnet; fx enthüllt per Clip-Reveal (wie fil-seam). Liegt
   zwischen den Sektionen, fasst #facts nicht an. */
.lp-linie-seam {
    position: relative;
    height: clamp(112px, 17svh, 210px);
    margin: clamp(-44px, -4vw, -24px) 0 0;
    pointer-events: none;
}
.lp-linie-seam-svg {
    position: absolute;
    left: var(--act1-thread-x);
    top: 0;
    height: 100%;
    /* exakt Gosse → Bildmitte (SVG ist ein ersetztes Element → Breite explizit) */
    width: calc(50% - var(--act1-thread-x));
    overflow: visible;
}
.lp-linie-seam-path {
    fill: none;
    stroke: var(--act1-thread);
    stroke-width: 1;
    stroke-linecap: round;
}
/* der Terminal-Knoten: mittig, genau über dem zentrierten Protokoll-Kopf */
.lp-linie-seam-knot {
    position: absolute;
    left: 50%;
    bottom: 2px;
    width: 9px;
    height: 9px;
    margin-left: -4.5px;
    border-radius: 50%;
    background: var(--bg);
    border: 1.5px solid var(--warm-thread);
    box-shadow: 0 0 0 4px var(--bg);
}

/* ── Der Kreislauf ── */
.lp-loop-pin {
    min-height: 100vh;
    min-height: var(--vh100);
    display: flex;
    flex-direction: column;
    justify-content: center;
    /* Kompakt: auf kurzen Viewports muss Kopf + Kreis + Stationstext
       gemeinsam in eine (gepinnte) Viewport-Höhe passen. */
    padding: clamp(56px, 9vw, 120px) clamp(20px, 5vw, 48px) clamp(24px, 4vw, 60px);
    /* Eigener Stacking-Context: Vignette + Asche-Canvas liegen auf z -1
       HINTER Kopf/Grid, aber über dem Seiten-Hintergrund (Muster wie
       .lp-identity / .lp-identity-ring). */
    position: relative;
    z-index: 0;
    overflow: hidden;
}
/* Bühnen-Vignette — dieselbe stille Tiefe wie #pivot und die fxb-Beats */
.lp-loop-pin::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background:
        radial-gradient(94% 52% at 50% -8%, rgba(2, 7, 12, 0.45), rgba(2, 7, 12, 0) 64%),
        radial-gradient(130% 44% at 50% 114%, rgba(2, 7, 12, 0.45), rgba(2, 7, 12, 0) 68%);
}
/* Asche-Schicht: ganze Bühne, hinter allem Inhalt; ohne JS/fx leer.
   max-width: none schlägt die 1160px-Klemme der .lp-loop-pin-Kinder —
   die Bühnen-Schicht ist full-bleed wie die Vignette. */
.lp-loop-canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    max-width: none;
    height: 100%;
    z-index: -1;
    pointer-events: none;
}
.lp-loop-head { margin-bottom: clamp(16px, 3.5vw, 56px); }
.lp-loop-title {
    font-family: var(--font-display);
    font-weight: 500;
    font-size: clamp(30px, 5vw, 56px);
    letter-spacing: -0.02em;
    line-height: 1.12;
}
/* STATUS-Vermerk (Mono) — Vorlaunch-Ehrlichkeit als Dokument-Metadatum */
.lp-loop-status {
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    color: var(--text-muted);
    margin-top: 14px;
}
.lp-loop-status::before { content: "[ "; }
.lp-loop-status::after { content: " ]"; }
.lp-loop-sub {
    margin-top: 10px;
    color: var(--text-dim);
    font-weight: 300;
    font-size: clamp(14.5px, 1.6vw, 17px);
    max-width: 52ch;
}
.lp-loop-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: clamp(18px, 4vw, 64px);
    align-items: center;
    max-width: 1160px;
}
.lp-loop-pin > * { width: 100%; max-width: 1160px; margin-left: auto; margin-right: auto; }
@media (min-width: 880px) {
    .lp-loop-grid { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); }
}
.lp-loop-visual { position: relative; display: grid; place-items: center; }
.lp-loop-svg {
    /* Auch an der Viewport-HÖHE gedeckelt — sonst drückt der Kreis auf
       kurzen Screens den Stationstext unter den gepinnten Fold. */
    width: min(56vw, 280px, 34vh);
    width: min(56vw, 280px, calc(var(--svh, 1vh) * 34));
    height: auto;
    color: var(--text);
}
@media (min-width: 880px) {
    .lp-loop-svg {
        width: min(36vw, 440px, 56vh);
        width: min(36vw, 440px, calc(var(--svh, 1vh) * 56));
    }
}
/* Kurze, breite Viewports (Telefon quer, eingebettete Webviews):
   Kreis und Text nebeneinander statt untereinander. */
@media (max-height: 540px) and (min-width: 500px) and (max-width: 879px) {
    .lp-loop-grid { grid-template-columns: minmax(0, 4fr) minmax(0, 6fr); }
    .lp-loop-svg {
        width: min(30vw, 38vh);
        width: min(30vw, calc(var(--svh, 1vh) * 38));
    }
}
.lp-loop-track { stroke: var(--border); }
.lp-loop-dots circle {
    fill: var(--bg);
    stroke: var(--border);
    stroke-width: 1.5;
    transition: fill 0.4s, stroke 0.4s;
}
.lp-loop-dots circle.is-active { fill: var(--accent-3); stroke: var(--accent-3); }
.lp-loop-count {
    position: absolute;
    bottom: -6px;
    right: 4%;
    font-family: var(--font-display);
    font-style: italic;
    font-size: 15px;
    color: var(--text-dim);
}
.lp-loop-count-total { color: var(--text-muted); }
/* Ohne fx sind alle Stationen gleichzeitig sichtbar — Zähler wäre irreführend */
html:not(.fx) .lp-loop-count { display: none; }

.lp-loop-steps { list-style: none; display: grid; gap: 36px; padding: 0; margin: 0; }
.lp-loop-step-index {
    display: block;
    font-family: var(--font-display);
    font-style: italic;
    font-size: 15px;
    background: var(--gradient);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    margin-bottom: 8px;
}
.lp-loop-step-title {
    font-family: var(--font-display);
    font-weight: 500;
    font-size: clamp(24px, 3.4vw, 40px);
    letter-spacing: -0.02em;
    margin-bottom: 10px;
}
/* Attributions-Tag je Station: wer wirkt hier — [ Alle ] / [ KI ] / [ Du ].
   Die Mensch/Maschine-Grenze als Informationsdesign im Kreis-Diagramm. */
.lp-loop-step-tag {
    font-family: var(--font-mono);
    font-size: 10.5px;
    font-weight: 500;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    color: var(--text-muted);
    margin: -2px 0 10px;
}
.lp-loop-step-tag::before { content: "[ "; }
.lp-loop-step-tag::after { content: " ]"; }
.lp-loop-step-tag--you { color: var(--accent-3); }
.lp-loop-step-text {
    color: var(--text-dim);
    max-width: 46ch;
    font-weight: 300;
    font-size: clamp(14.5px, 1.5vw, 16.5px);
}

/* fx: Stationen überlagern sich und blenden je Viertel um;
   ohne fx bleiben sie eine normale, vollständig sichtbare Liste. */
html.fx .lp-loop-steps { position: relative; min-height: 200px; }
@media (min-width: 880px) {
    html.fx .lp-loop-steps { min-height: 260px; }
}
html.fx .lp-loop-step {
    position: absolute;
    inset: 0;
    opacity: 0;
    transform: translateY(16px);
    transition: opacity 0.45s var(--ease-out), transform 0.45s var(--ease-out);
    pointer-events: none;
}
html.fx .lp-loop-step.is-active {
    opacity: 1;
    transform: none;
    pointer-events: auto;
}
/* Laptop-kurze Viewports (1366×768 & Co.): Kopf kompakt, damit Kopf + Kreis +
   Stationstext in EINE gepinnte Viewport-Höhe passen (Vertrag im
   .lp-loop-pin-Kommentar). Der STATUS-Vermerk trägt die Botschaft, der Sub
   weicht — mobil (<880px) passt alles und bleibt vollständig. */
@media (max-height: 820px) and (min-width: 880px) {
    .lp-loop-sub { display: none; }
    .lp-loop-status { margin-top: 8px; }
    .lp-loop-head { margin-bottom: clamp(12px, 2vw, 28px); }
}

/* Auf sehr kurzen Viewports zählt jede Zeile: kompaktere Stationen */
@media (max-height: 600px) {
    html.fx .lp-loop-steps { min-height: 150px; }
    .lp-loop-step-title { font-size: clamp(20px, 3vw, 28px); margin-bottom: 6px; }
    .lp-loop-step-text { font-size: 13.5px; }
    .lp-loop-title { font-size: clamp(24px, 4vw, 40px); }
    .lp-loop-count { display: none; }
    /* Kopf kompakt: der STATUS-Vermerk trägt die Botschaft, der Sub weicht */
    .lp-loop-sub { display: none; }
    .lp-loop-status { margin-top: 8px; }
    .lp-loop-step-tag { margin-bottom: 6px; }
}

/* ── Die Zahlen ── */
.lp-stats { max-width: 1160px; margin: 0 auto; }
.lp-stats-title {
    font-family: var(--font-display);
    font-weight: 500;
    font-size: clamp(30px, 5vw, 56px);
    letter-spacing: -0.02em;
    line-height: 1.12;
    margin-bottom: clamp(36px, 6vw, 72px);
    max-width: 16ch;
}
.lp-stat { border-top: 1px solid var(--border); padding-top: 22px; }
/* Mono-Kicker über jeder Zahl: die Station der Linie (Produzieren/Wegwerfen/Zurück) */
.lp-stat-kicker {
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    color: var(--text-muted);
    margin-bottom: 10px;
}
/* Protokoll-Zahlen: Kupfer-Verlauf (Slide-Dramaturgie — die Beweise der
   alten Linie sind warm; Aqua antwortet erst in Beat 3 / #pivot). */
.lp-stat-value {
    font-family: var(--font-display);
    font-size: clamp(60px, 9vw, 104px);
    line-height: 1;
    background: var(--gradient-warm);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}
.lp-stat-unit, .lp-stat-prefix { font-family: var(--font-mono); font-size: 0.5em; }
.lp-stat-label {
    margin-top: 12px;
    color: var(--text-dim);
    font-weight: 300;
    font-size: 14.5px;
    max-width: 30ch;
}
/* Coda — das Urteil unter dem Beweisband (Serif-Kursiv, leitet zu #pivot über) */
.lp-stats-coda {
    margin-top: clamp(40px, 6vw, 72px);
    font-family: var(--font-display);
    font-style: italic;
    font-size: clamp(19px, 2.6vw, 28px);
    line-height: 1.4;
    color: var(--text-dim);
    max-width: 34ch;
}
.lp-stats-sources {
    margin-top: clamp(20px, 3vw, 32px);
    font-size: 12.5px;
    color: var(--text-muted);
}
.lp-stats-sources a { color: var(--text-dim); }

/* ── Die Wende (#pivot) — die Linie biegt sich zum Kreis ──────────────
   Statischer Default (no-JS / ohne GSAP / reduced-motion): fertige
   Geometrie (Kreis) und Frage + Antwort untereinander sichtbar. Nur
   html.fx überlagert Frage/Antwort für den Scrub-Crossfade und startet
   mit der geraden Linie; js/landing.js (initPivot) treibt den Rest. */
.lp-pivot-pin {
    min-height: 100vh;
    min-height: var(--vh100);
    display: grid;
    place-items: center;
    padding: clamp(56px, 9vw, 120px) clamp(20px, 5vw, 48px);
    position: relative;
    overflow: hidden;
}
/* Bühnen-Vignette (gleiche Theater-Sprache wie die fxb-Beats in #facts):
   dunkle Pools oben/unten + ein kaum wahrnehmbarer Aqua-Atem hinter dem
   Kreis. Immer sichtbar — Tiefe, kein Zustand. */
.lp-pivot-pin::before {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background:
        radial-gradient(94% 52% at 50% -8%, rgba(2, 7, 12, 0.5), rgba(2, 7, 12, 0) 64%),
        radial-gradient(130% 44% at 50% 114%, rgba(2, 7, 12, 0.5), rgba(2, 7, 12, 0) 68%),
        radial-gradient(46% 40% at 50% 50%, rgba(126, 224, 207, 0.045), rgba(126, 224, 207, 0) 72%);
}
.lp-pivot-svg {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    height: min(78vh, 620px);
    height: min(calc(var(--svh, 1vh) * 78), 620px);
    width: auto;
    /* Schmale Screens: Box darf schrumpfen — preserveAspectRatio (meet)
       skaliert die Zeichnung passend, nichts clippt. */
    max-width: 96vw;
    /* currentColor der geraden Mono-Linie = der kupferne Akt-I-Faden:
       die Wende morpht sichtbar Kupfer → Ozean-Verlauf (Slide-Story
       „AI brings order to the chaos"). */
    color: var(--warm-thread);
    pointer-events: none;
}
/* Default (statisch): nur der fertige Verlaufs-Kreis, ruhig hinter dem Text */
.lp-pivot-line { opacity: 0; }
.lp-pivot-arc { opacity: 0.55; }
/* Die eine Faser: statisch ein stiller Glimmpunkt an der Naht des Kreises;
   unter fx übernimmt js/landing.js Position (Pfadspitze) und Opazität. */
.lp-pivot-comet-core { fill: var(--text); }
.lp-pivot-comet { opacity: 0.75; }
html.fx .lp-pivot-comet { opacity: 0; }
.lp-pivot-copy {
    position: relative;
    z-index: 1;
    text-align: center;
    max-width: 760px;
    display: grid;
    gap: clamp(30px, 5vw, 48px);
}
.lp-pivot-question {
    font-family: var(--font-display);
    font-weight: 500;
    font-size: clamp(30px, 5.6vw, 60px);
    letter-spacing: -0.02em;
    line-height: 1.12;
    margin: 0 auto;
    max-width: 16ch;
}
.lp-pivot-hinge {
    font-family: var(--font-display);
    font-weight: 500;
    font-size: clamp(27px, 4.8vw, 54px);
    letter-spacing: -0.02em;
    line-height: 1.14;
    margin: 0 auto;
    max-width: 17ch;
    background: var(--gradient);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}
.lp-pivot-mission {
    margin: clamp(16px, 2.5vw, 24px) auto 0;
    max-width: 46ch;
    color: var(--text-dim);
    font-weight: 300;
    font-size: clamp(15.5px, 1.9vw, 19px);
    line-height: 1.7;
}
/* fx: Frage und Antwort überlagern sich (Crossfade unter Scrub-Kontrolle);
   Startzustand = gerade Mono-Linie, Antwort verborgen. */
html.fx .lp-pivot-q,
html.fx .lp-pivot-answer { grid-area: 1 / 1; align-self: center; }
html.fx .lp-pivot-answer { opacity: 0; transform: translateY(28px); }
html.fx .lp-pivot-line { opacity: 1; }
html.fx .lp-pivot-arc { opacity: 0; }

/* ── #facts · „Die Masse" (fxb-) ───────────────────────────
   Drei bühnenhohe Beats zeigen die physische Masse hinter den Zahlen:
   1 · Produzieren (CO₂-Fahne) · 2 · Wegwerfen (wachsende Halde) ·
   3 · Zurück (100 Tracer, einer steigt). Partikel via <canvas>
   (js/facts-mass.js), Bühne via Vignetten.
   Progressive Enhancement (tragend): der CSS-Default ist der fertige
   Ruhezustand — Vignetten + statische Silhouetten (.fxb-static) + alle
   Texte sichtbar. NUR unter html.fxb-go (Controller, nicht bei
   reduced-motion) werden Startzustände versteckt; .is-live pro Beat
   blendet die Statik aus, sobald der Canvas wirklich zeichnet. */
.lp-stats-vb { max-width: none; padding-left: 0; padding-right: 0; }
.lp-stats-vb .fxb-head,
.lp-stats-vb .fxb-epilogue {
    max-width: 1160px;
    margin-left: auto;
    margin-right: auto;
    padding-left: clamp(20px, 5vw, 48px);
    padding-right: clamp(20px, 5vw, 48px);
    text-align: center;
}
.fxb-head { margin-bottom: clamp(28px, 5svh, 56px); }
.lp-stats-vb .lp-stats-title { margin-left: auto; margin-right: auto; }
.lp-stats-vb .lp-stats-coda { margin-left: auto; margin-right: auto; }
.fxb-epilogue { margin-top: clamp(48px, 9svh, 96px); }

/* Die Bühne: volle Höhe, Inhalt zentriert, Canvas + Statik dahinter. */
.fxb-beat {
    position: relative;
    min-height: clamp(560px, 88svh, 860px);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    padding: clamp(48px, 9svh, 96px) clamp(20px, 5vw, 48px);
}
.fxb-vignette,
.fxb-static,
.fxb-canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
}
/* Bühnen-Vignetten (immer sichtbar — Tiefe, kein Zustand). Beat 1 + 2
   glimmen warm (Kupfer-Chaos der Slides); erst Beat 3 kühlt nach Aqua. */
.fxb-beat--produce .fxb-vignette {
    background:
        radial-gradient(120% 66% at 50% 110%, rgba(201, 144, 111, 0.10), rgba(201, 144, 111, 0) 62%),
        radial-gradient(94% 52% at 50% -8%, rgba(2, 7, 12, 0.55), rgba(2, 7, 12, 0) 64%);
}
.fxb-beat--dump .fxb-vignette {
    background:
        radial-gradient(86% 48% at 50% -10%, rgba(201, 144, 111, 0.11), rgba(201, 144, 111, 0) 60%),
        radial-gradient(130% 44% at 50% 114%, rgba(2, 7, 12, 0.6), rgba(2, 7, 12, 0) 68%);
}
.fxb-beat--return .fxb-vignette {
    background:
        radial-gradient(60% 38% at 50% -14%, rgba(126, 224, 207, 0.05), rgba(126, 224, 207, 0) 62%),
        radial-gradient(130% 46% at 50% 114%, rgba(2, 7, 12, 0.55), rgba(2, 7, 12, 0) 68%);
}
/* Statische Instrument-Silhouetten = Ruheform der Animation (no-JS /
   reduced-motion / Canvas-Ausfall). .is-live blendet sie sanft aus. */
.fxb-static { transition: opacity 1.2s ease; }
.fxb-beat--produce .fxb-static {
    background:
        radial-gradient(44% 62% at 50% 102%, rgba(201, 144, 111, 0.10), rgba(201, 144, 111, 0) 70%),
        radial-gradient(28% 44% at 50% 102%, rgba(238, 244, 248, 0.07), rgba(238, 244, 248, 0) 74%),
        radial-gradient(15% 86% at 50% 92%, rgba(238, 244, 248, 0.05), rgba(238, 244, 248, 0) 78%);
}
.fxb-beat--produce .fxb-static::after {
    content: "";
    position: absolute;
    left: 37%;
    right: 37%;
    bottom: 0;
    height: 2px;
    background: linear-gradient(90deg, rgba(201, 144, 111, 0), rgba(201, 144, 111, 0.42), rgba(201, 144, 111, 0));
}
.fxb-beat.is-live .fxb-static { opacity: 0; }
.fxb-static-svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.fxb-beat--dump .fxb-static-svg { top: auto; bottom: 0; height: 32%; }
/* Halden-Silhouetten: warm-getönte Strata (der Berg besteht aus
   weggeworfener Kleidung — Kupfer-Welt, wie der Canvas-Berg). */
.fxb-svg-mound { fill: rgba(59, 42, 35, 0.92); }
.fxb-svg-mound--far { fill: rgba(44, 32, 28, 0.85); }
.fxb-svg-arc {
    fill: none;
    stroke: rgba(159, 182, 198, 0.18);                    /* --text-dim */
    stroke-width: 1.5;
    stroke-dasharray: 2 7;
}
.fxb-svg-one { stroke-width: 2; }
.fxb-svg-one-halo { fill: rgba(126, 224, 207, 0.18); }
/* Canvas: ohne Controller leer/transparent; unter fxb-go weich einblenden,
   sobald der Beat wirklich zeichnet (.is-live). */
html.fxb-go .fxb-canvas { opacity: 0; transition: opacity 1.6s ease; }
html.fxb-go .fxb-beat.is-live .fxb-canvas { opacity: 1; }

/* Inhalt auf der Bühne */
.fxb-copy {
    position: relative;
    z-index: 2;
    text-align: center;
    max-width: 680px;
}
.fxb-copy .lp-stat-label {
    margin-left: auto;
    margin-right: auto;
    font-size: clamp(14.5px, 1.6vw, 17px);
}
.fxb-value { font-size: clamp(64px, 12vw, 148px); }
.fxb-value--star { font-size: clamp(92px, 21vw, 220px); }
.fxb-value .lp-stat-unit,
.fxb-value .lp-stat-prefix { font-size: 0.42em; }

/* Beat 1 · Massen-Block (mono — die Maschinen-Stimme) */
.fxb-mass { margin-top: clamp(26px, 4.5svh, 48px); }
.fxb-mass-rate {
    font-family: var(--font-mono);
    font-size: clamp(15px, 1.9vw, 19px);
    font-weight: 500;
    color: var(--text-dim);
    letter-spacing: 0.02em;
}
.fxb-mass-live {
    display: none;
    margin-top: 10px;
    font-family: var(--font-mono);
    font-size: clamp(13px, 1.6vw, 16px);
    color: var(--text-muted);
}
html.fxb-tick .fxb-mass-live { display: block; }
.fxb-mass-live-num {
    color: var(--text);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.fxb-mass-note {
    margin-top: clamp(14px, 2.4svh, 22px);
    font-size: 12.5px;
    color: var(--text-muted);
    max-width: 46ch;
    margin-left: auto;
    margin-right: auto;
}

/* Beat 2 · Odometer (nur wenn der Ticker läuft — wie .lp-stat-live) */
.fxb-odo { display: none; }
html.ticker-on .fxb-odo { display: block; margin-top: clamp(26px, 4.5svh, 48px); }
.fxb-odo-rate {
    font-family: var(--font-mono);
    font-size: 11.5px;
    font-weight: 500;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    color: var(--text-muted);
    margin-bottom: 8px;
}
.fxb-odo-kg {
    font-family: var(--font-mono);
    font-weight: 600;
    font-size: clamp(34px, 6.4vw, 76px);
    line-height: 1.05;
    color: var(--text);
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.01em;
}
.fxb-odo-unit { font-size: 0.42em; font-weight: 500; color: var(--text-muted); }
.fxb-odo-cap {
    margin-top: 8px;
    font-family: var(--font-mono);
    font-size: 11.5px;
    color: var(--text-muted);
}

/* Beat 3 · stille Fussnote; der Kicker antwortet in Aqua */
.fxb-beat--return .lp-stat-kicker { color: var(--accent-3); }
.fxb-return-note {
    margin-top: clamp(18px, 3svh, 30px);
    font-family: var(--font-mono);
    font-size: 12.5px;
    color: var(--text-muted);
}

/* Entrance-Choreografie — NUR unter html.fxb-go (Opt-in durch den
   Controller; reduced-motion bekommt fxb-go nie). Gestaffelt: Kicker →
   Zahl → Label → Massen-/Odo-Block. */
html.fxb-go .fxb-copy > * {
    opacity: 0;
    transform: translate3d(0, 22px, 0);
    transition:
        opacity 1s cubic-bezier(0.16, 1, 0.3, 1),
        transform 1s cubic-bezier(0.16, 1, 0.3, 1);
}
html.fxb-go .fxb-copy > .fxb-value { transform: translate3d(0, 30px, 0) scale(0.96); }
html.fxb-go .fxb-copy > *:nth-child(2) { transition-delay: 140ms; }
html.fxb-go .fxb-copy > *:nth-child(3) { transition-delay: 320ms; }
html.fxb-go .fxb-copy > *:nth-child(4) { transition-delay: 480ms; }
html.fxb-go .fxb-beat.is-in .fxb-copy > * { opacity: 1; transform: none; }

/* Sicherheitsnetz: falls fxb-go trotz reduced-motion gesetzt sein sollte,
   gewinnt der Ruhezustand (höhere Spezifität durch html-Typselektor). */
@media (prefers-reduced-motion: reduce) {
    html.fxb-go .fxb-copy > * { opacity: 1; transform: none; transition: none; }
    html.fxb-go .fxb-canvas { opacity: 1; transition: none; }
    html.fxb-go .fxb-beat.is-live .fxb-static { opacity: 1; transition: none; }
}

/* Mobil ≤ 480 px: Bühnen bleiben hoch, Typo klemmt herunter */
@media (max-width: 480px) {
    .fxb-beat { min-height: clamp(560px, 88svh, 760px); }
    .fxb-copy { max-width: 100%; }
    .fxb-mass-note { max-width: 34ch; }
}

/* ── Der Faden — die durchgehende Naht der Erzählung ─────────────
   Sechs scroll-gezeichnete Nähte verbinden #facts → #pivot → #loop →
   Urteil → #your-style → #how → Orb zu EINER Linie. Farb-Dramaturgie
   (Slides): Naht 1 kupfern (die alte Linie, kein Glint), ab der Wende
   lebt der Faden (Teal/Aqua + wanderndes Glint-Signal), im Identitäts-
   Beat kehrt die Wärme zurück (lp-identity-fuse — Kupfer als Identität,
   nicht mehr als Abfall), am Orb wird er Kreis. Ruhezustand = fertig
   gezeichnet (no-JS/reduced-motion); erst html.fil-go (js/faden.js)
   setzt Startzustände und scrubbt. */
.fil-seam {
    position: relative;
    height: clamp(130px, 22svh, 260px);
    margin: clamp(-56px, -4vw, -28px) 0;
    pointer-events: none;
}
.fil-seam svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.fil-path { fill: none; stroke-width: 1.5; stroke-linecap: round; }
.fil-seam[data-fil="1"] .fil-path { stroke: rgba(201, 144, 111, 0.42); }
/* Ein-/Auslauffaden der Wende-Bühne: statische Verlängerungen der Linie
   über die viewBox hinaus (overflow visible) — die Naht davor/danach
   trifft die Bühne ohne totes Stück. Kein Eingriff in die gescrubbten
   Pfade (#pivot-line/-arc, unit-getestet). */
.lp-pivot-svg { overflow: visible; }
.lp-pivot-thread-in { stroke: rgba(201, 144, 111, 0.40); stroke-width: 2; }
.lp-pivot-thread-out { stroke: rgba(47, 174, 158, 0.5); stroke-width: 1.5; }
.fil-seam[data-fil="2"] .fil-path { stroke: rgba(47, 174, 158, 0.55); }
.fil-seam[data-fil="3"] .fil-path,
.fil-seam[data-fil="4"] .fil-path,
.fil-seam[data-fil="5"] .fil-path { stroke: rgba(126, 224, 207, 0.38); }
.fil-seam[data-fil="6"] .fil-path { stroke: rgba(126, 224, 207, 0.48); }
/* S6: eine Naht, zwei Wege — Desktop kommt von rechts (Faden-Ende),
   Mobil aus der linken Gosse (wie der vertikale How-Bogen). */
.fil-seam .fil-m { display: none; }
@media (max-width: 860px) {
    .fil-seam .fil-d { display: none; }
    .fil-seam .fil-m { display: block; }
}
/* Startzustand NUR wenn das Skript wirklich scrubbt (Opt-in, wie fxb-go).
   Clip-Reveal statt Dash-Draw: stroke-dasharray + pathLength bricht in
   Chromium bei extremer nicht-uniformer Streckung (100×240 → ~1440×198)
   mit Löchern mitten im Pfad; ein vertikaler inset-Clip zeichnet die Naht
   dagegen verlustfrei von oben nach unten (Glint-Punkt liegt ausserhalb
   des SVG und bleibt unbeschnitten). */
html.fil-go .fil-seam svg { clip-path: inset(0% -3% 102% -3%); }
/* Glint — das Signal, das den lebenden Faden entlangwandert (js-positioniert;
   HTML-Punkt statt SVG-Kreis: preserveAspectRatio=none würde Kreise verzerren) */
.fil-glint {
    position: absolute;
    top: 0;
    left: 0;
    width: 3px;
    height: 3px;
    border-radius: 50%;
    background: rgba(126, 224, 207, 0.95);
    box-shadow: 0 0 9px 2.5px rgba(126, 224, 207, 0.28);
    opacity: 0;
    will-change: transform, opacity;
}
/* Zünd-Naht im Identitäts-Beat: der ankommende Aqua-Faden wird warm —
   die einzige Stelle in AKT II, an der Kupfer existieren darf: dieselbe
   Wärme, die in Akt I Abfall war, kehrt hier als Identität zurück. */
.lp-identity { position: relative; }
.lp-identity-fuse {
    position: absolute;
    top: 0;
    left: 50%;
    width: 1px;
    height: clamp(44px, 9svh, 110px);
    transform: translateX(-0.5px);
    background: linear-gradient(180deg, rgba(126, 224, 207, 0.5), var(--accent-warm));
    opacity: 0.8;
}

/* ── KI, richtig eingesetzt — das Urteil als Protokoll ──────────────────────
   Offenes typografisches Verdikt-Ledger statt Karten (Gerichtsakte, in der
   Sprache von #facts): EINE Haarlinie, zwei Spalten reiner Text. Die Linie
   weicht zurück (gedämpft — der verworfene Weg), der Kreis trägt ruhiges
   Gewicht. Bewusst statisch — nur der bestehende Entrance-Reveal. */
.lp-aidr { max-width: 1100px; margin: 0 auto; }
.lp-aidr-title {
    font-family: var(--font-display);
    font-weight: 500;
    font-size: clamp(30px, 5vw, 56px);
    letter-spacing: -0.02em;
    line-height: 1.14;
    max-width: 22ch;
    margin-bottom: clamp(34px, 5vw, 60px);
}
.lp-aidr-title em { font-style: italic; color: var(--accent-3); }
.lp-aidr-grid {
    border-top: 1px solid var(--border);
    display: grid;
    grid-template-columns: 1fr;
    margin-bottom: clamp(36px, 6vw, 64px);
}
.lp-aidr-card { padding: clamp(24px, 3.5vw, 36px) 0 0; }
/* Mobil gestapelt: jede Aussage beginnt an ihrer eigenen Haarlinie */
.lp-aidr-card + .lp-aidr-card {
    border-top: 1px solid var(--border);
    margin-top: clamp(26px, 4vw, 40px);
}
@media (min-width: 760px) {
    .lp-aidr-grid { grid-template-columns: 1fr 1fr; column-gap: clamp(48px, 7vw, 110px); }
    .lp-aidr-card + .lp-aidr-card { border-top: 0; margin-top: 0; }
}
/* „Auf der Linie" — der verworfene Weg tritt zurück */
.lp-aidr-card.is-dim .lp-aidr-tag { color: var(--text-muted); }
.lp-aidr-card.is-dim h3 { color: var(--text-muted); }
.lp-aidr-card.is-dim p { color: var(--text-muted); }
/* „Im Kreis" — trägt ruhiges Gewicht */
.lp-aidr-card.is-lit .lp-aidr-tag { color: var(--accent-3); }
.lp-aidr-card.is-lit h3 { color: var(--text); }
.lp-aidr-card.is-lit p { color: var(--text-dim); }
.lp-aidr-tag {
    font-family: var(--font-mono);
    font-size: 11.5px;
    font-weight: 500;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    margin-bottom: clamp(14px, 2vw, 20px);
}
.lp-aidr-tag::before { content: "[ "; color: var(--text-muted); }
.lp-aidr-tag::after { content: " ]"; color: var(--text-muted); }
.lp-aidr-card h3 {
    font-family: var(--font-display);
    font-weight: 500;
    font-size: clamp(21px, 2.8vw, 30px);
    letter-spacing: -0.01em;
    line-height: 1.2;
    margin-bottom: 12px;
}
.lp-aidr-card p {
    font-weight: 300;
    font-size: clamp(14.5px, 1.5vw, 16px);
    line-height: 1.6;
    max-width: 42ch;
}
.lp-aidr-body {
    color: var(--text-dim);
    font-weight: 300;
    font-size: clamp(15.5px, 1.9vw, 19px);
    line-height: 1.7;
    max-width: 64ch;
}
.lp-aidr-body strong { color: var(--text); font-weight: 500; }

/* ── Der Mittelpunkt (Identitäts-Beat — der eine warme Akzent, nur hier) ── */
.lp-identity {
    max-width: 820px;
    margin: 0 auto;
    text-align: center;
    position: relative;
    z-index: 0; /* eigener Stacking-Context: der Ring (z -1) bleibt ÜBER dem bg */
    /* fauchter warmer Schimmer hinter dem Block — fällt zum Rand auf 0 ab */
    background: radial-gradient(58% 52% at 50% 42%, rgba(217, 155, 120, 0.10) /* --accent-warm */, transparent 70%);
}
/* Haarlinien-Kreis mit EINER warmen Glut hinter dem Text — dieselbe
   Ring-Sprache wie der Finale-Orb. Die Glut ist der einzige warme und der
   einzige bewegte Punkt der Sektion: unter html.fx treibt sie langsam am
   Ring entlang (Rotation der Gruppe im SVG-Raum) und atmet (Opacity).
   Ruhezustand (no-JS / reduced-motion): stiller warmer Punkt bei ~1 Uhr. */
.lp-identity-ring {
    position: absolute;
    inset: 0;
    margin: auto;
    z-index: -1;
    width: min(86vw, 480px);
    height: min(86vw, 480px);
    color: var(--border);
    opacity: 0.9;
    pointer-events: none;
}
.lp-identity-ember-halo { fill: rgba(217, 155, 120, 0.16); } /* --accent-warm */
.lp-identity-ember-dot { fill: var(--accent-warm); }
/* Drift auf der GRUPPE im SVG-Koordinatenraum (transform-origin = viewBox-
   Zentrum 200×200): bewegt den Punkt am Ring entlang, ohne die Layout-Box
   anzufassen — kein scrollWidth-Risiko wie bei rotierter Host-Box. */
html.fx .lp-identity-ember {
    transform-origin: 100px 100px;
    animation: lp-ember-drift 18s ease-in-out infinite alternate;
}
html.fx .lp-identity-ember-halo,
html.fx .lp-identity-ember-dot { animation: lp-ember-breathe 5.5s ease-in-out infinite; }
@keyframes lp-ember-drift {
    from { transform: rotate(-6deg); }
    to { transform: rotate(6deg); }
}
@keyframes lp-ember-breathe {
    0%, 100% { opacity: 0.55; }
    50% { opacity: 1; }
}
.lp-label--warm { color: var(--accent-warm); }
.lp-identity-title {
    font-family: var(--font-display);
    font-weight: 500;
    font-size: clamp(32px, 6vw, 64px);
    letter-spacing: -0.02em;
    line-height: 1.14;
    max-width: 16ch;
    margin: 0 auto;
}
.lp-identity-title em { font-style: italic; color: var(--accent-warm); }
.lp-identity-body {
    margin: clamp(22px, 3.5vw, 32px) auto 0;
    max-width: 54ch;
    color: var(--text-dim);
    font-weight: 300;
    font-size: clamp(15.5px, 1.9vw, 19px);
    line-height: 1.7;
}
.lp-identity-body strong { color: var(--text); font-weight: 500; }

/* ── So funktioniert's — vier Stationen auf offenem Faden ──────────────────
   Der Bogen (stroke-dashoffset, pathLength=1) bleibt der Erzähler: die Linie,
   die zu deinem Faden wird. Die Stationen sind offene Typo-Blöcke OHNE
   Karten-Boxen — Mono-Index, Fraunces-Titel, gedimmte Zeile — im Duktus von
   #facts (viel Negativraum, Typografie trägt). Desktop: ein Stations-Punkt
   sitzt AUF dem Faden (Hairline-Ring, füllt sich accent-3 beim Reveal), die
   mittleren Stationen reiten die Wölbung. Mobil: Faden vertikal in der Gosse,
   Stationen rechts davon wie ein Protokollrand. Alles über das bestehende
   [data-reveal]-System (animations.js), keine neue JS. */
.lp-how { max-width: 1180px; margin: 0 auto; scroll-margin-top: 84px; }
.lp-how-head { max-width: 760px; margin: 0 auto clamp(48px, 8vw, 96px); text-align: center; }
.lp-how-title {
    font-family: var(--font-display);
    font-weight: 500;
    font-size: clamp(30px, 5vw, 52px);
    letter-spacing: -0.02em;
    line-height: 1.16;
    margin: 0 auto;
    max-width: 18ch;
}
.lp-how-sub {
    margin: var(--space-4) auto 0;
    max-width: 52ch;
    color: var(--text-dim);
    font-weight: 300;
    font-size: clamp(15px, 1.8vw, 18px);
    line-height: 1.6;
}

.lp-how-track { position: relative; }

/* Die Naht — der BOGEN, auf beiden Breakpoints mit demselben Mechanismus
   gezeichnet (stroke-dashoffset, pathLength=1): Desktop horizontal durch die
   Icon-Reihe, Mobil vertikal in der linken Gosse (leichte Wölbung zu den
   Karten). Die frühere mobile clip-path-Leiste + Wander-Nadel sind entfernt. */
.lp-how-seam {
    position: absolute;
    left: 0; right: 0;
    top: 0;
    height: 88px;
    z-index: 0;            /* hinter den Stationen; die sind offener Text */
    pointer-events: none;
}
.lp-how-arc, .lp-how-arc-v { display: block; width: 100%; height: 100%; overflow: visible; }
.lp-how-arc-v { display: none; }  /* nur mobil (max-width: 860px) */
.lp-how-arc-path {
    stroke-dasharray: 1;
    stroke-dashoffset: 1;  /* ungezeichnet; .is-revealed zieht den Faden durch */
    transition: stroke-dashoffset 1.4s var(--ease-out);
    filter: drop-shadow(0 0 6px rgba(126, 224, 207, 0.4)); /* --accent-3 Glow wie die Naht */
}
.lp-how-seam.is-revealed .lp-how-arc-path { stroke-dashoffset: 0; }
/* Desktop: die MITTLEREN Stationen sitzen tiefer — Punkt + Text reiten die
   Wölbung des Fadens. Faden-y an den Spaltenmitten (Quadratik
   M10 25 Q 500 73 990 25, y-Skala 1:1 bei 88px Seam-Höhe): aussen ≈34px,
   innen ≈47px → 13px Versatz, Punkt-Offset bleibt für alle gleich.
   860.02px statt 861px: schliesst das 1px-Loch zum mobilen max-width:860px-
   Block (fraktionale Zoom-Breiten zeigten sonst BEIDE Naht-Systeme). */
@media (min-width: 860.02px) {
    .lp-how-grid { align-items: start; }
    .lp-how-station:nth-child(2),
    .lp-how-station:nth-child(3) { margin-top: 13px; }
}
/* Die Naht selbst nicht mit-faden/-translaten — sie wird gezeichnet. */
.lp-how-seam[data-reveal] { opacity: 1; transform: none; transition: none; }

.lp-how-grid {
    list-style: none;
    margin: 0; padding: 0;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: clamp(20px, 3vw, 36px);
    position: relative;
}
/* Offene Station: kein Rahmen, keine Fläche — der Text hängt am Faden. */
.lp-how-station {
    position: relative;
    z-index: 1;
    text-align: center;
    padding-top: 78px;     /* Luft für die Faden-Zone; der Punkt sitzt bei 34px */
    transition:
        opacity var(--duration-slow) var(--ease-out) var(--reveal-delay, 0ms),
        transform var(--duration-slow) var(--ease-out) var(--reveal-delay, 0ms);
}
/* Desktop-Kaskade: die vier Stationen stehen nebeneinander und triggern
   gleichzeitig — das Reveal kaskadiert dem Faden hinterher (3× das
   animations.js-Stagger-Delay: 0/180/360/540ms). Die Stationen erscheinen
   sichtbar ENTLANG des sich zeichnenden Bogens — das ist die ganze
   Choreografie der Sektion. Mobil (eigener Scroll-Trigger je Station)
   bleibt das schnelle Basis-Delay, sonst wirkt Station 04 verschleppt. */
@media (min-width: 860.02px) {
    .lp-how-station { transition-delay: calc(var(--reveal-delay, 0ms) * 3); }
}
/* Der Stations-Punkt AUF dem Faden: Hairline-Ring, der Grund stanzt den Faden
   aus; füllt sich accent-3, sobald die Station enthüllt ist — der Faden
   „knotet" die Station fest, kurz nachdem ihre Spitze vorbeigezogen ist. */
.lp-how-dot {
    position: absolute;
    top: 34px; left: 50%;
    width: 9px; height: 9px;
    transform: translate(-50%, -50%);
    border-radius: 50%;
    border: 1px solid var(--accent-3);
    background: var(--bg);
    transition:
        background-color var(--duration-slow) var(--ease-out) calc(var(--reveal-delay, 0ms) * 3 + 300ms),
        box-shadow var(--duration-slow) var(--ease-out) calc(var(--reveal-delay, 0ms) * 3 + 300ms);
}
.lp-how-station.is-revealed .lp-how-dot {
    background: var(--accent-3);
    box-shadow: 0 0 12px rgba(126, 224, 207, 0.45);
}
.lp-how-num {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-weight: 500;
    letter-spacing: var(--tracking-wider);
    color: var(--text-muted);
    display: block;
    margin-bottom: var(--space-3);
}
.lp-how-label {
    font-family: var(--font-display);
    font-size: clamp(22px, 2.4vw, 28px);
    font-weight: 400;
    color: var(--text);
    margin: 0 0 var(--space-3);
    line-height: 1.15;
}
.lp-how-line {
    font-family: var(--font-body);
    font-size: var(--text-sm);
    font-weight: 300;
    color: var(--text-dim);
    line-height: 1.65;
    margin: 0 auto;
    max-width: 24ch;
}

/* Mobil + Tablet (<860px): Faden vertikal in der linken Gosse (Wölbung zu den
   Stationen), Stationen rechts davon als Protokollrand — offener Text,
   linksbündig, grosszügig gestapelt. Punkte nur auf dem Desktop: das Wölbungs-x
   der Gosse variiert mit der Inhaltshöhe, ein fixer Punkt sässe daneben — der
   Mono-Index übernimmt die Marke. Spalte gedeckelt + zentriert, sonst wird der
   Text auf iPad-Breite absurd breit; auf Phones (<560px) volle Breite. */
@media (max-width: 860px) {
    .lp-how-track { max-width: 560px; margin-inline: auto; }
    .lp-how-grid { grid-template-columns: 1fr; gap: clamp(40px, 7svh, 64px); padding-left: var(--space-8); }
    .lp-how-arc { display: none; }
    .lp-how-arc-v { display: block; }  /* der Bogen läuft vertikal in der Gosse */
    .lp-how-seam { top: 0; bottom: 0; left: 2px; right: auto; width: 40px; height: auto; }
    .lp-how-dot { display: none; }
    .lp-how-station { padding: 0; text-align: left; }
    .lp-how-line { margin: 0; max-width: 36ch; }
}

/* Reduced-motion: Bogen vollständig gezeichnet, Punkte gefüllt, keine Bewegung.
   (Das globale [data-reveal]-Reset deckt die Stationen ab; Naht-Pfad und Punkt
   brauchen eigene Guards, da sie kein [data-reveal] tragen.) */
@media (prefers-reduced-motion: reduce) {
    .lp-how-arc-path { transition: none; stroke-dashoffset: 0 !important; }
    .lp-how-dot { transition: none; background: var(--accent-3); }
}

/* ── Finale ── */
.lp-finale {
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
}
/* Übergabe-Zeile — Protokoll-Klammer wie .lp-label: [ … ] statt Zier-Naht */
.lp-handoff {
    font-family: var(--font-mono);
    font-size: 11.5px;
    font-weight: 500;
    letter-spacing: var(--tracking-wider);
    text-transform: uppercase;
    color: var(--accent-3);
    margin-bottom: clamp(22px, 4vw, 36px);
    text-wrap: balance;
}
.lp-handoff::before { content: "[ "; color: var(--text-muted); }
.lp-handoff::after { content: " ]"; color: var(--text-muted); }
.lp-finale-title {
    font-family: var(--font-display);
    font-weight: 500;
    font-size: clamp(32px, 6.5vw, 72px);
    letter-spacing: -0.02em;
    line-height: 1.15;
    max-width: 18ch;
}
.lp-finale-title em { font-style: italic; color: var(--accent-3); }
.lp-finale-sub {
    margin-top: 18px;
    color: var(--text-dim);
    max-width: 50ch;
    font-weight: 300;
    font-size: clamp(14.5px, 1.6vw, 16.5px);
}
.lp-cta-orb {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    width: clamp(190px, 46vw, 250px);
    aspect-ratio: 1;
    margin-top: clamp(40px, 7vw, 72px);
    border-radius: 50%;
    text-decoration: none;
    color: var(--text);
    background: radial-gradient(circle at 38% 32%, rgba(47, 174, 158, 0.22), rgba(10, 22, 34, 0) 68%);
    border: 1px solid var(--border);
    transition: border-color 0.3s, box-shadow 0.3s;
}
.lp-cta-orb:hover { border-color: var(--accent); box-shadow: var(--shadow-glow); }
/* Haarlinien-Orbit: der Ring steht still; die eine Bewegung ist der Tracer —
   die entkommene Faser aus #facts umkreist ihr Ziel (nur html.fx, ~14 s).
   Ruhezustand (no-JS / reduced-motion): stiller Aqua-Punkt oben am Ring. */
.lp-cta-orb-ring {
    position: absolute;
    inset: -12px;
    width: calc(100% + 24px);
    height: calc(100% + 24px);
    color: var(--border);
}
.lp-cta-orb-tracer-halo { fill: rgba(126, 224, 207, 0.18); } /* --accent-3 */
.lp-cta-orb-tracer-dot { fill: var(--accent-3); }
html.fx .lp-cta-orb-tracer {
    transform-origin: 100px 100px;
    animation: lp-orb-spin 14s linear infinite;
}
@keyframes lp-orb-spin { to { transform: rotate(360deg); } }
.lp-cta-orb-label {
    font-family: var(--font-display);
    font-style: italic;
    font-size: clamp(17px, 2vw, 21px);
    max-width: 80%;
    line-height: 1.3;
}
.lp-cta-orb-arrow {
    margin-top: 6px;
    font-size: 20px;
    color: var(--accent-3);
    transition: transform 0.3s var(--ease-out);
}
.lp-cta-orb:hover .lp-cta-orb-arrow { transform: translateX(6px); }

/* §5.1 Threshold-Portal — der Kreis der Landing öffnet sich wörtlich ins
   Studio: eine REINE Scheibe (Midnight-Fläche + Ocean-Ring, bewusst ohne
   Inhalt — eingebettete Grafik würde beim Skalieren zum aufgeblasenen Bild)
   wächst lesbar vom angeklickten CTA über den Viewport, darunter wird das
   Studio instant enthüllt, dann öffnet sich die Scheibe auf die
   Studio-Oberfläche (landing.js portalReveal). Nur transform/opacity →
   Compositor, iOS-tauglich. JS gated auf html.fx + Live-Motion; hier
   zusätzlich abgesichert. Über allem (Loader 150, Navbar 100, Egg 1200).
   Kurve: ausgewogen (schneller Ansprung, lange lesbare Landung) — eine
   kopflastige Ease deckte in ~120 ms und las sich als Blitz statt Wachstum. */
.lp-portal { position: fixed; inset: 0; z-index: 1300; }
/* Ab dem Reveal (is-out) gehört der Input dem Studio — die auslaufende
   Scheibe darf den ersten Tap auf die enthüllte Bühne nicht mehr schlucken. */
.lp-portal.is-out { pointer-events: none; }
html:not(.fx) .lp-portal { display: none; }
@media (prefers-reduced-motion: reduce) { .lp-portal { display: none; } }
.lp-portal-disc {
    position: absolute;
    border-radius: 50%;
    background: radial-gradient(120% 90% at 50% 30%, #16293b, var(--bg)78%);
    box-shadow:
        inset 0 0 0 2px rgba(126, 224, 207, 0.32),
        inset 0 0 120px rgba(47, 134, 179, 0.24),
        0 0 90px rgba(6, 14, 22, 0.8);
    transition: transform .56s cubic-bezier(0.4, 0.08, 0.22, 1);
    will-change: transform, opacity;
}
.lp-portal.is-out .lp-portal-disc { transition: opacity .32s var(--ease-out), transform .32s var(--ease-out); }
