/* ═══ FUNNEL ════════════════════════════════════════════════════════════════════════
   The tree is the page. On the stem: three short ARGUMENT slots (WHY · FARMERS ·
   PHOTOGRAPHERS) that open inline, then the sections (ORDER · SYSTEM · ABOUT · PSYCH),
   then one arrow on the line that leads straight to the offer. Plus the fixed buy pill.
   Loaded last; it only adds and re-tunes, base.css stays untouched.                  */

:root{
  --f-ink:#e8fff6;
  --f-text:rgba(205,236,228,.82);
  --f-mute:rgba(205,236,228,.5);
  --f-hi:#89f3dd;
}

/* the stem column: wide enough for an open sentence on any screen (base.css pins the
   old menu width with !important, so this has to as well); items keep their own caps */
.tree{ width:min(820px,92vw)!important; }

/* ── STEM · a real trunk: hairline under the crown, 5 px where it meets the roots.
      base.css draws it as a 1 px bar and animates transform scaleY from the top; the
      taper is a clip-path on a wider bar, so that animation is untouched. ─────────── */
.tree-stem{
  width:4px!important; top:-13vw;                  /* overridden per screen by funnel.js seatTruth() */
  /* 1 px at the top (under the crown), 4 px at the roots: a quiet trunk — present, never loud */
  -webkit-clip-path:polygon(38% 0, 62% 0, 100% 100%, 0 100%);
  clip-path:polygon(38% 0, 62% 0, 100% 100%, 0 100%);
  background:linear-gradient(to bottom, rgba(0,199,163,.17), rgba(0,199,163,.22) 30%, rgba(0,199,163,.26) 70%, rgba(0,199,163,.31))!important;   /* +15 % */
}

/* ── HERO LINE · the headline in front of the crown, and TRUTH as its second state ───────────── */
.hero-line{
  position:absolute; left:50%; top:46%; width:min(820px,92vw); z-index:4;
  transform:translate(-50%,-50%); transform-origin:50% 50%;
  text-align:center; cursor:pointer;
  text-shadow:0 1px 22px rgba(0,0,0,.6), 0 0 2px rgba(0,0,0,.4);
  transition:transform 1.6s cubic-bezier(.22,.61,.36,1), opacity 1.1s ease .3s;   /* a calm travel into TRUTH (1.6 s) */
}
.hero-line{ opacity:0; }                       /* landing: the headline comes after the light */
.hero-line.in{ opacity:1; transition:transform 1.6s cubic-bezier(.22,.61,.36,1), opacity .4s ease; }
/* calm arrival: each line surfaces slowly out of a soft blur, one after the other (3 s, staggered .8 s) —
   nothing pops; the parent only gates the whole block (fast) so the travel into TRUTH keeps its own timing */
.hero-line span{ opacity:0; text-shadow:0 1px 22px rgba(0,0,0,0), 0 0 2px rgba(0,0,0,0);
  transition:opacity 2s cubic-bezier(.25,.46,.45,.94), filter 0s, text-shadow 1.2s ease 1s; }   /* no blur: it read as softness in the crown */
/* the dark text-shadow arrives AFTER the letters (else a dark smudge crosses the watermark before any text shows) */
.hero-line.in span{ opacity:1; text-shadow:0 1px 22px rgba(0,0,0,.6), 0 0 2px rgba(0,0,0,.4); }
.hero-line.in .h2{ transition-delay:.5s,.5s,1.5s; }
.hero-line.away span{ transition-duration:1s,0s,.6s; transition-delay:.2s,0s,0s; }
.hero-line.away{ opacity:0; pointer-events:none; }
.hero-line span{ display:block; white-space:nowrap; }
.hero-line .h1{ font-family:'DM Sans',sans-serif; font-weight:700; font-size:clamp(22px,2.5vw,38px); line-height:1.08; letter-spacing:.01em; text-transform:uppercase; color:#fff; margin:0 0 clamp(10px,1.6vh,18px); }
.hero-line .h2{ font-family:'DM Sans',sans-serif; font-weight:500; font-size:clamp(15px,1.7vw,26px); line-height:1.15; color:var(--f-hi); margin:0; letter-spacing:.02em; }
/* TRUTH is not there until the headline has travelled into it */
.tree details.act[data-act="truth"]{ opacity:0!important; pointer-events:none; transition:opacity .5s ease!important; }   /* !important: base's reveal rule sets opacity 1 */
.tree details.act[data-act="truth"].shown{ opacity:1!important; pointer-events:auto; }
@media(max-width:640px){ .hero-line span{ white-space:normal; } .hero-line{ top:50%; } }

/* ── GENESIS · the stem waits until the crown has bundled to 80 %, then glides in softly ──────── */
.tree-wrap{ transition:opacity .9s ease; }
body.genesis .tree-wrap{ opacity:0; transition:none; }   /* the class is set in the HTML itself, so the menu is never painted early and never fades 1 → 0 at load */

/* ── MENU HOVER · the word opens up: a space's worth of air between every letter ──────────── */
.tree details.act summary{ transition:letter-spacing .28s cubic-bezier(.16,1,.3,1), font-weight .22s ease, color .22s ease, text-shadow .22s ease!important; }
.tree details.act:hover summary,
.tree details.act:focus-within summary{ letter-spacing:.34em!important; }

/* ── ARROW · frameless, on the stem axis below the last item. Appears once the tree stands
      and blinks ONCE — "here I am" — then rests. The stem stops above it. ────────────── */
.tree{ padding-bottom:3.4vw!important; }     /* 3.4vw foot below the GROUND LINE; the roots block starts on that line */
.tree-wrap{ padding-bottom:0!important; }
.tree-stem{ bottom:3.4vw!important; }   /* the trunk ends exactly on the GROUND LINE (= roots top): there it becomes root */
.stem-arrow{
  position:absolute; left:50%; bottom:calc(3.4vw - 20px); transform:translateX(-50%);   /* centred ON the ground line */
  width:40px; height:40px; display:flex; align-items:center; justify-content:center;
  color:rgba(137,243,221,.75);
  background:transparent; border:0; border-radius:0;
  text-decoration:none; z-index:3;
  animation:stemArrowIn .9s ease 3.6s both, stemArrowBlink .9s ease-in-out 5s 1;
  transition:color .25s;
}
.stem-arrow:hover{ color:#fff; }
body.about-open .stem-arrow{ opacity:.45; }
body:not(.hero-open) .stem-arrow{ opacity:0!important; pointer-events:none; }   /* the arrow belongs to the landing state */
body.arrow-gone .stem-arrow{ animation:none; opacity:0!important; pointer-events:none; transition:opacity .5s ease; }
@keyframes stemArrowIn{ from{ opacity:0; } to{ opacity:1; } }
@keyframes stemArrowBlink{ 0%,100%{ opacity:1; color:rgba(137,243,221,.75); } 35%{ opacity:1; color:#fff; text-shadow:0 0 18px rgba(0,199,163,.9); } 70%{ opacity:.25; } }
@media (prefers-reduced-motion:reduce){ .stem-arrow{ animation:none; } }

/* overlays.css puts a 3 s !important opacity transition on the crown canvas (for the PSYCH
   focus fade). mesh-morph drives that opacity per frame, so the 3 s smear made the crown
   linger behind the node for seconds. Short transition by default, the long one only for PSYCH. */
#terra_canvas{ transition:opacity .25s linear!important; }
body.psych-focus #terra_canvas{ transition:opacity 3s ease!important; }

/* ── TERRASCOPE watermark: lives directly in .main-content (index.html), NOT in the stage, so neither
      the camera dolly (#treeGroup) nor the PARTS crown move (.canvas-stage) can ever shift it. It covers
      exactly the stage's box and stays behind everything. ───────────────────────────────────── */
.main-content > .gothic-title{ position:absolute; top:0; left:0; width:100%; height:56.67vw;
  display:flex; align-items:center; justify-content:center; transform:none; z-index:0; }
@media(max-width:640px){ .main-content > .gothic-title{ height:74.17vw; } }
.gothic-title.wm-shop{ font-size:clamp(22px,4.4vw,66px); line-height:1.1; padding:0 8vw; letter-spacing:.02em; }

/* ── ORDER · the crown becomes the node, the stem slides down, the offer takes its place.
      The overlay is transparent over the (still visible) crown stage; only the stem and
      the roots leave. order.js' own node canvas is not needed any more. ────────────── */
body.shop-open #mainContent{ opacity:1!important; pointer-events:none; }
.tree-section{ transition:opacity .7s ease .9s, transform 1.1s cubic-bezier(.16,1,.3,1) .9s; }   /* return: after the crown has re-formed, from below, as clean as it left */
body.shop-open .tree-section{ opacity:0!important; transform:translateY(38vh); pointer-events:none; transition-delay:0s,0s; }  /* leaving: at once; !important: tree.js writes an inline opacity per frame */
.roots-section{ transition:opacity 1.2s ease; }
body.genesis-roots .roots-section{ opacity:0!important; }   /* landing: the roots and the ground line arrive last (3.6 s), then grow */
body.shop-open .roots-section{ opacity:0; pointer-events:none; }
body.parts-zoom .tree-section{ opacity:0!important; transform:translateY(38vh)!important; pointer-events:none; transition-delay:0s,0s!important; }   /* PARTS: menu leaves like under ORDER */
body.shop-open .logo-top{ opacity:0!important; }

.ts-ov#ovOrder{ background:transparent!important; }
.ts-ov#ovOrder .ts-ov-scroll{ display:block; overflow:hidden!important; }
/* the shop is a box UNDER the camera (which sits where the crown is: stage = 56.67vw tall, camera ends
   ~84 % down) and scrolls inside itself; the camera area above never moves or gets covered */
.ts-ov#ovOrder .shop2{ position:absolute; left:0; right:0; top:50vh; bottom:0;   /* die Node darüber, das Angebot darunter; unten bleibt Platz für das × in der Mitte */
  display:flex; align-items:center; max-width:none; margin:0; padding:8px 4vw 62px; overflow:hidden; }
.ts-ov#ovOrder .shop2-visual{ display:none; }
/* ORDER reads like every other page now: one centred column, kicker → title → choice → price →
   action → details → chips → closing line. The old three-column row put two very different weights
   left and right of the price and never balanced. */
.ts-ov#ovOrder .shop2-info{ flex:none; max-width:900px; width:100%; margin:0 auto; text-align:center;
  display:grid; grid-template-columns:minmax(0,1fr);
  grid-template-areas:"r" "rl" "c" "sp" "l" "ch";
  row-gap:clamp(3px,0.6vh,9px); justify-items:center; }
.ts-ov#ovOrder .shop2-side{ grid-area:r; justify-self:center; text-align:center; display:block; margin:0; }
.ts-ov#ovOrder .shop2-sub{ font-family:ui-monospace,Menlo,monospace; font-size:10.5px; letter-spacing:2.6px;
  text-transform:uppercase; color:rgba(137,243,221,.9); margin:0; }
/* Der Modellname bleibt im Dokument — das Wasserzeichen hinter der Seite liest ihn —, aber er
   steht nicht mehr als Ueberschrift da. Die Ueberschrift ist jetzt die Schlusszeile. */
.ts-ov#ovOrder .shop2-title{ display:none; }
.ts-ov#ovOrder .shop2-title-sub{ display:block; font-size:.58em; font-weight:400; color:rgba(205,236,228,.6); margin-top:5px; letter-spacing:.04em; }
.ts-ov#ovOrder .shop2-buy{ grid-area:c; display:flex; flex-direction:column; align-items:center; gap:5px; }
/* a price this size does not need to shout: one centred line, the running cost quietly under it */
.ts-ov#ovOrder .shop2-price{ margin:0; flex-direction:column; align-items:center; gap:2px; }
.ts-ov#ovOrder .shop2-price .now{ font-weight:500; color:rgba(238,252,247,.94); text-shadow:none; letter-spacing:.02em; }
.ts-ov#ovOrder .shop2-price .shop2-monthly{ font-size:11px; letter-spacing:.05em; color:rgba(205,236,228,.58); margin-top:1px; }
.ts-ov#ovOrder .shop2-price .now{ font-size:clamp(19px,1.8vw,25px); }
.ts-ov#ovOrder .shop2-meta{ margin:0; max-width:min(1000px,94vw); white-space:nowrap; }
.ts-ov#ovOrder .shop-cta{ margin:2px 0 0; padding:9px 30px; white-space:nowrap; }
.ts-ov#ovOrder .details-drop{ grid-area:l; justify-self:center; text-align:center; margin:0; max-width:min(760px,92vw); }
.ts-ov#ovOrder .details-drop .shop2-args{ text-align:left; font-size:12px; max-height:26vh; overflow:auto; }
.ts-ov#ovOrder .rl-line{ grid-area:rl; margin:0; justify-self:center; text-align:center;
  font-size:clamp(19px,2.05vw,29px); line-height:1.15; white-space:nowrap; max-width:96vw; }
@media(max-width:520px){ .ts-ov#ovOrder .rl-line{ font-size:clamp(16px,5.2vw,21px); } }
.ts-ov#ovOrder .chips{ grid-area:ch; justify-content:center; margin:0; }
.ground-fill{ display:none; }   /* nur auf dem Telefon gebraucht */
@media(max-width:640px){
  .ts-ov#ovOrder .shop2-meta{ white-space:normal; }
  /* Auf dem Telefon steht die Node oben und das Angebot scrollt darunter. Vorher begann es erst bei
     56 vh — darüber lag eine große leere Fläche — und die vier Blöcke standen gar nicht im Raster,
     landeten also ganz am Ende unterhalb der Schlusszeile. */
  .ts-ov#ovOrder .shop2{ top:40vh; padding:6px 14px 74px; overflow-y:auto; align-items:flex-start; }
  .ts-ov#ovOrder .shop2-info{ grid-template-columns:1fr;
    grid-template-areas:"r" "rl" "c" "sp" "l" "ch"; row-gap:9px; }
  .ts-ov#ovOrder .spec-row{ grid-template-columns:minmax(0,1fr); gap:11px; width:100%; }
  .ts-ov#ovOrder .details-drop,.ts-ov#ovOrder .shop2-side{ justify-self:center; text-align:center; align-items:center; max-width:none; margin:0; }
  /* Unter den Wurzeln blieb auf dem Telefon eine leere Fläche stehen: der Inhalt endete bei 593 px,
     das Dokument war 844 px hoch. Der Wurzelstreifen selbst liegt tief im Baum-Container und lässt
     sich nicht dehnen, ohne die Zeichnung zu verzerren — deshalb eine Fläche darunter, die den Rest
     im Ton des Erdreichs auffüllt. */
  .main-content{ display:flex; flex-direction:column; min-height:100dvh; }
    /* der Wurzelstreifen läuft in beiden Schemata auf Schwarz aus (siehe .roots-section::after),
     also füllt die Fläche darunter in Schwarz weiter — gemessen: Sprung 0,0 */
  .ground-fill{ display:block; flex:1 1 auto; min-height:0; background:#000; }
}

/* ── ABOUT · the two bubbles sit in .tree, pinned to the ABOUT item's centre (overlays.js) ─── */
body.about-open .canvas-stage{ opacity:1!important; }        /* the crown stays exactly as it is while ABOUT is open */
body.about-open .roots-section{ opacity:1!important; }
@media(min-width:761px){
  .about-inline{ position:absolute!important; left:50%!important; right:auto!important;
    transform:translate(-50%,-50%)!important; width:max-content; z-index:40; }
  .about-inline .ai-col{ width:clamp(210px,21vw,280px); }
  /* the connector line and its dot leave the card at its vertical MIDDLE — i.e. exactly at ABOUT —
     not 22 px under the card's top edge as in base.css */
  .ai-col.left .ai-card::after,.ai-col.right .ai-card::before{ top:50%!important; }
  .ai-col.left .ai-card::after{ transform:translate(100%,-50%)!important; }
  .ai-col.right .ai-card::before{ transform:translate(-100%,-50%)!important; }
  .ai-col.left .ai-card .ai-dot,.ai-col.right .ai-card .ai-dot{ top:50%!important; }
  .ai-col.left .ai-card .ai-dot{ transform:translate(100%,-50%)!important; }
  .ai-col.right .ai-card .ai-dot{ transform:translate(-100%,-50%)!important; }
}

/* roots: a homogeneous foundation — the strands and the PARTNERS watermark fade to 0 % toward the bottom;
   partner names and legal links stay readable */
#rootCanvas{ opacity:.55; }                     /* the crown is the brightest thing on the page, never the roots */
/* the fade is a STATIC overlay (composited once), not a mask on the canvas — a mask on a canvas that
   redraws every frame forced a re-mask per frame and made scrolling stutter. Colours follow the
   underground gradient below, so the overlay is invisible as a shape. Partner names / legal links
   sit at z-index 10 and stay above it. */
.roots-section::after{ content:""; position:absolute; inset:0; z-index:2; pointer-events:none;
  background:linear-gradient(to bottom, rgba(1,8,6,0) 0%, rgba(1,8,6,0) 15%, rgba(1,8,6,.72) 64%, #000 100%); }   /* fully dark exactly at the page's end */
.roots-section{ padding-bottom:0!important; margin-bottom:0!important; }   /* no empty run-out below the roots */
.roots-title{ -webkit-mask-image:linear-gradient(to bottom,#000 0%,#000 15%,rgba(0,0,0,.30) 64%,rgba(0,0,0,0) 100%);
  mask-image:linear-gradient(to bottom,#000 0%,#000 15%,rgba(0,0,0,.30) 64%,rgba(0,0,0,0) 100%); }

/* the stem/arrow column must paint above the roots block, whatever its own stacking */
.tree-section{ position:relative; z-index:10; background:none!important; }        /* no glow band above the roots */
/* GROUND LINE: the roots block starts 3.4vw up, exactly where the stem's foot and the roots' origin meet.
   Its top edge is the (invisible) horizon — everything below is underground: the same greens as the
   sky above (#052016 / #03160f), only much darker, with no glow and no gradient seam at the edge. */
.roots-section{ transform:none!important; margin-top:-3.4vw!important;   /* a LAYOUT shift (not a transform), so the document ends where the roots end */
  background:linear-gradient(to bottom, #020e0a 0%, #010806 30%, #000 55%, #000 100%)!important; }   /* underground is black from half height on */
.roots-fade-top{ display:none!important; }                                         /* was the visible horizontal edge */

.shop-pop .sp-box{ max-width:480px; }

/* ── responsive ───────────────────────────────────────────────────────────────── */
@media(max-width:760px){
  .tree details.arg[open]{ width:100%!important; max-width:92vw!important; padding:10px 16px 14px!important; }
  .tree details.arg p{ white-space:normal; }
  .tree details.arg p{ font-size:13px; }
}

/* ── LANDING: the background light is switched on softly AFTER the name (tree.js adds body.light-on at 1.2 s) ── */
#bangVoid{ opacity:0; transition:opacity var(--light-dur,2400ms) cubic-bezier(.55,0,.45,1); }
body.light-on #bangVoid{ opacity:1; }
@media (prefers-reduced-motion:reduce){ #bangVoid{ transition:opacity .35s linear; } }

/* ── ABOUT in front of the crown — same idiom as the headline (no box, text-shadow, soft blur-in) ── */
.about-line{ position:absolute; left:50%; top:auto; bottom:40%; width:min(760px,90vw); z-index:4; transform:translate(-50%,0);   /* bottom-anchored: the block always ends above the menu, however long the text */
  text-align:center; opacity:0; pointer-events:none; transition:opacity .45s ease;
  text-shadow:0 1px 22px rgba(0,0,0,.7), 0 0 2px rgba(0,0,0,.5); }
body.about-open #aboutLine{ opacity:1; pointer-events:auto; }
/* ABOUT is a reading view: the menu steps aside so the block gets the whole screen and the
   headings can carry their real size; the × brings the tree back (same idiom as MODELS) */
#aboutLine{ top:50%; bottom:auto; transform:translate(-50%,-50%); width:min(860px,92vw); }
body.about-open .tree-wrap{ opacity:.60!important; pointer-events:none; transition:opacity 1.2s ease; }
/* Bei ABOUT steht das Menue sichtbar da — dann muss es auch antworten. Ein sichtbares Menue, das
   Klicks schluckt, fuehlt sich an wie eine haengende Seite. Der Stamm faengt weiterhin nichts,
   klickbar sind allein die Woerter. */
body.about-open .tree details.act summary{ pointer-events:auto; cursor:pointer; }
.about-line .l-en,.about-line .l-de{ display:none; }
.about-line[data-lang="en"] .l-en,.about-line[data-lang="de"] .l-de{ display:block; }
.about-line .al-lang{ font-family:ui-monospace,Menlo,monospace; font-size:11px; letter-spacing:2.2px; color:rgba(137,243,221,.55); margin:0 0 clamp(10px,1.6vh,18px); }
.about-line .al-lang button{ background:none; border:0; padding:0 6px; font:inherit; letter-spacing:inherit; color:rgba(137,243,221,.55); cursor:pointer; }
.about-line .al-lang button.on{ color:#fff; }
.about-line .al-title{ font-family:'DM Sans',sans-serif; font-weight:700; font-size:clamp(20px,2.2vw,34px); line-height:1.1; letter-spacing:.06em; text-transform:uppercase; color:#fff; margin:0 0 clamp(6px,1.1vh,14px); }
/* ABOUT has three levels now: the title, a real section heading, and the compliance status under it.
   A hairline gives every section its own field instead of one running wall of centred lines. */
.about-line .al-sec{ margin:0; padding:clamp(6px,1.1vh,14px) 0 clamp(2px,0.4vh,6px); }
/* ABOUT is read one thought at a time now: scrolling changes the section's state, it does not run the
   whole page past the reader at once */
#aboutLine .al-sec{ display:none; }
#aboutLine[data-step="0"] .al-sec[data-i="0"],#aboutLine[data-step="1"] .al-sec[data-i="1"],
#aboutLine[data-step="2"] .al-sec[data-i="2"],#aboutLine[data-step="3"] .al-sec[data-i="3"],
#aboutLine[data-step="4"] .al-sec[data-i="4"]{ display:flex; }
/* every step keeps the same box, so the title and the chevron hold still while the thought changes */
#aboutLine .al-sec{ min-height:clamp(130px,19vh,190px); flex-direction:column; justify-content:center; }
#aboutLine .al-nav{ font-family:ui-monospace,Menlo,monospace; font-size:10.5px; letter-spacing:2.2px;
  text-transform:uppercase; color:rgba(137,243,221,.5); display:flex; gap:16px; justify-content:center;
  margin:0 0 clamp(6px,1vh,12px); }
#aboutLine .al-nav b{ color:rgba(232,255,248,.9); font-weight:500; }
#aboutLine .al-hint{ display:none; }
#aboutLine[data-lang="en"] .al-hint.l-en,#aboutLine[data-lang="de"] .al-hint.l-de{ display:inline; }
#aboutLine .al-next{ display:block; margin:clamp(12px,2.2vh,26px) auto 0; width:42px; height:42px;
  border:0; background:none; color:rgba(137,243,221,.55); font-size:26px; line-height:1; cursor:pointer;
  transition:color .3s ease,transform .3s ease; }
#aboutLine .al-next:hover{ color:#fff; transform:translateY(3px); }
#aboutLine[data-step="4"] .al-next{ opacity:.35; }
.about-line .al-h{ font-family:'DM Sans',sans-serif; font-weight:700; text-transform:uppercase;
  letter-spacing:.17em; color:#eafff9; line-height:1.15; margin:0 0 3px; }
.about-line .al-t{ font-family:ui-monospace,Menlo,monospace; letter-spacing:.14em; text-transform:uppercase;
  color:rgba(0,199,163,.95); line-height:1.3; margin:0 0 clamp(5px,.9vh,10px); }
.about-line[data-lang="en"] .al-h .l-en,.about-line[data-lang="de"] .al-h .l-de,
.about-line[data-lang="en"] .al-t .l-en,.about-line[data-lang="de"] .al-t .l-de{ display:inline; }
.about-line .al-sec p{ margin:0; }
.about-line .al-k{ font-family:ui-monospace,Menlo,monospace; font-size:clamp(12.5px,1.08vw,15px); letter-spacing:3.2px; text-transform:uppercase; color:rgba(137,243,221,.92); margin:0 0 5px; }
.about-line p{ margin:0; font-family:'DM Sans',sans-serif; font-weight:400; font-size:clamp(13px,1.15vw,17px); line-height:1.5; color:rgba(225,246,240,.9); }
.about-line p .ln{ display:block; white-space:nowrap; line-height:1.32; }   /* one balanced, edge-to-edge line each, own size (fitAbout) */
/* blur-in like the headline, staggered by block */
.about-line > *{ opacity:0; transition:opacity 1.1s cubic-bezier(.25,.46,.45,.94); }   /* no blur, like the headline */
body.about-open #aboutLine > *{ opacity:1; }
body.about-open #aboutLine .al-title{ transition-delay:.1s; }
@media(max-width:640px){ .about-line{ bottom:36%; } .about-line p{ font-size:13px; } }

/* ── root labels: brighter lettering (the root lines themselves keep their light) ── */
#rootLegal .rleg{ color:rgba(150,246,226,.95); font-size:11px; letter-spacing:2.2px; text-shadow:0 0 10px rgba(0,199,163,.55), 0 0 2px rgba(0,0,0,.6); }
#rootLegal .rleg:hover{ color:#fff; }

/* the watermark's colour is driven per frame (updTitle): bright mint during the landing, the dark embossed watermark at rest */
.gothic-title{ color:var(--wm-color, transparent)!important; -webkit-text-fill-color:var(--wm-color, transparent)!important; }   /* base.css paints the glyphs with a transparent fill + gradient clip — the variable must drive the fill too */

/* ── PARTS · four states of the crown, explained in front of it (same idiom as ABOUT) ── */
.parts-line{ position:absolute; left:0; right:0; margin:0 auto; top:auto; bottom:9%; width:min(760px,90vw); z-index:5; transform:none;   /* no transform: the fixed children (nav, ×) must anchor to the viewport */
  text-align:center; opacity:0; pointer-events:none; transition:opacity .5s ease; text-shadow:0 1px 22px rgba(0,0,0,.7), 0 0 2px rgba(0,0,0,.5); }
body.parts-open[data-deck="parts"] #partsLine,body.parts-open[data-deck="datas"] #datasLine{ opacity:1; pointer-events:auto; }
.parts-line .l-en,.parts-line .l-de{ display:none; }
.parts-line[data-lang="en"] .l-en,.parts-line[data-lang="de"] .l-de{ display:block; }
.parts-line .pl-step{ display:none; }
.parts-line[data-step="0"] .pl-step[data-i="0"],.parts-line[data-step="1"] .pl-step[data-i="1"],.parts-line[data-step="2"] .pl-step[data-i="2"],.parts-line[data-step="3"] .pl-step[data-i="3"]{ display:block; }
.parts-line .pl-step > *{ opacity:0; transition:opacity 1s cubic-bezier(.25,.46,.45,.94); }
.parts-line .pl-step.on > *{ opacity:1; }
.parts-line .pl-step.on .al-title{ transition-delay:.15s; } .parts-line .pl-step.on .al-sec{ transition-delay:.35s; }
.parts-line .al-lang{ font-family:ui-monospace,Menlo,monospace; font-size:11px; letter-spacing:2.2px; color:rgba(137,243,221,.55); margin:0 0 clamp(8px,1.4vh,14px); }
.parts-line .al-lang button{ background:none; border:0; padding:0 6px; font:inherit; letter-spacing:inherit; color:rgba(137,243,221,.55); cursor:pointer; }
.parts-line .al-lang button.on{ color:#fff; }
.parts-line .al-k{ font-family:ui-monospace,Menlo,monospace; font-size:11px; letter-spacing:2.6px; text-transform:uppercase; color:var(--f-hi,#89f3dd); margin:0 0 6px; }
.parts-line .al-title{ font-family:'DM Sans',sans-serif; font-weight:700; font-size:clamp(20px,2.2vw,34px); line-height:1.1; letter-spacing:.06em; text-transform:uppercase; color:#fff; margin:0 0 clamp(10px,1.8vh,18px); }
.parts-line .al-sec{ margin:0; }
.parts-line p{ margin:0; font-family:'DM Sans',sans-serif; font-weight:400; font-size:clamp(13px,1.15vw,17px); line-height:1.5; color:rgba(225,246,240,.9); }
.parts-line p .ln{ display:block; white-space:nowrap; line-height:1.32; }
.parts-line .pl-nav{ position:fixed; left:50%; top:22px; transform:translateX(-50%); display:flex; gap:18px; align-items:center; font-family:ui-monospace,Menlo,monospace; font-size:11px; letter-spacing:2.2px; text-transform:uppercase; color:rgba(137,243,221,.55); }
.parts-line .pl-nav b{ color:#fff; font-weight:500; }
.parts-line .pl-close{ position:fixed; top:14px; right:18px; width:36px; height:36px; border:1px solid rgba(137,243,221,.35); border-radius:50%; background:rgba(2,26,19,.6); color:#cdece4; font-size:20px; line-height:34px; cursor:pointer; }
.parts-line .pl-close:hover{ color:#fff; border-color:rgba(137,243,221,.8); }
body.parts-open .roots-section{ opacity:0!important; pointer-events:none; }   /* focus: only the crown and its explanation */
body.parts-open .gothic-title{ opacity:0!important; }
@media(max-width:640px){ .parts-line{ bottom:6%; } .parts-line p{ font-size:13px; } }
.about-line .al-title,.parts-line .al-title{ white-space:nowrap; }
/* PARTS: the stage grows to the full viewport height — driven by JS (px → px), so it animates instead of jumping */

/* ── menu brackets: 15 % narrower than before (128 → 109 px at ORDER) and widening by 0.75 % per row down to TRUTH (+3 %) ── */
.tree details.act[data-act="order"],.tree details.act[data-act="order"][open]{ width:109px!important; max-width:109px!important; }
.tree details.act[data-act="parts"],.tree details.act[data-act="parts"][open]{ width:109.8px!important; max-width:109.8px!important; }
.tree details.act[data-act="about"],.tree details.act[data-act="about"][open]{ width:110.6px!important; max-width:110.6px!important; }
.tree details.act[data-act="cortex"],.tree details.act[data-act="cortex"][open]{ width:111.5px!important; max-width:111.5px!important; }
.tree details.act[data-act="truth"],.tree details.act[data-act="truth"][open]{ width:112.3px!important; max-width:112.3px!important; }

/* ── 2026-09-07: TRUTH and PSYCH are footer links only — their menu hooks stay in the DOM, hidden ── */
.tree details.act.nav-hidden{ display:none!important; }
.tree details.act[data-act="parts"],.tree details.act[data-act="parts"][open]{ width:110.6px!important; max-width:110.6px!important; }
.tree details.act[data-act="about"],.tree details.act[data-act="about"][open]{ width:112.3px!important; max-width:112.3px!important; }
.shop2-args li.blk{ margin-bottom:8px; }
.shop2-args li.blk b{ display:block; color:#cdece4; letter-spacing:.04em; font-size:11px; text-transform:uppercase; margin-bottom:2px; }
.shop2-price .shop2-monthly{ display:block; font-size:12px; letter-spacing:.06em; color:rgba(205,236,228,.72); margin-top:2px; }   /* the running cost, spoken next to the price */

/* ── 2026-09-07: five menu items again (ORDER · PARTS · ABOUT · MODELS · DATAS); the brackets widen like a trunk —
   the lowest is 1.618× the top one (geometric steps of 1.128) ── */
.tree details.act[data-act="order"],.tree details.act[data-act="order"][open]{ width:109px!important; max-width:109px!important; }
.tree details.act[data-act="parts"],.tree details.act[data-act="parts"][open]{ width:123px!important; max-width:123px!important; }
.tree details.act[data-act="about"],.tree details.act[data-act="about"][open]{ width:139px!important; max-width:139px!important; }
.tree details.act[data-act="nodes"],.tree details.act[data-act="nodes"][open]{ width:156px!important; max-width:156px!important; }
.tree details.act[data-act="datas"],.tree details.act[data-act="datas"][open]{ width:176px!important; max-width:176px!important; }
/* ── MODELS · 2026-09-08: the Apple-style comparison. Three columns, one architecture; every column
   carries the SAME blank as ORDER, drawn live (models-3d.js). Night: the crown steps back, the three
   nodes are the only lit things. Touching a column lights it and gives the header its name. ── */
.nodes-line{ width:min(1180px,95vw); top:50%; bottom:auto; transform:translate(-50%,-50%); }
body.nodes-open .nodes-line{ opacity:1; pointer-events:auto; }
body.nodes-open #bangVoid{ opacity:.40!important; }
/* the overlays live INSIDE #canvasStage, so night has to dim the crown's canvases, never the stage */
body.nodes-open #canvasStage > canvas{ opacity:1!important; transition:opacity 1.1s cubic-bezier(.25,.46,.45,.94); }
body.nodes-open .roots-section{ opacity:.06!important; transition:opacity 1.1s cubic-bezier(.25,.46,.45,.94); }
body.nodes-open .gothic-title{ opacity:0!important; }
body.nodes-open #rootLegal,body.about-open #rootLegal{ opacity:0!important; pointer-events:none; transition:opacity .5s ease; }
/* ABOUT is a reading view too: the crown steps back so the lines stay quiet behind the text */
/* Bei ABOUT tritt der Baum zurueck und wird klein — bei 20 % Deckkraft bliebe davon nichts uebrig,
   und genau ihn soll man hier ja als Ganzes sehen. Er darf darum kraeftiger stehen als frueher,
   wo er in voller Groesse hinter dem Text lag. */
body.about-open #canvasStage > canvas{ opacity:.62!important; transition:opacity 1.1s cubic-bezier(.25,.46,.45,.94); }
/* Der Boden bringt im zurueckgetretenen Zustand seinen eigenen Kasten mit — als kleines Rechteck
   mitten im Bild waere das ein Fremdkoerper. Sichtbar bleiben die Wurzeln, nicht ihr Untergrund. */
/* Der Boden bleibt, wie er ist: seine Oberkante ist der Horizont und laeuft ueber die ganze Seite.
   Er traegt waehrend ABOUT den Text — deshalb wird hier nichts abgeschaltet, nur verschoben (siehe
   stepBack in overlays.js). */   /* der Auslauf nach Schwarz gehoert an den Seitenfuss, nicht als Kasten mitten ins Bild */
body.about-open .roots-fade-top{ opacity:0!important; }
body.about-open .ground-fill{ opacity:0; transition:opacity 1.2s ease; }   /* der schwarze Fuss der Seite gehoert zum vollen Baum, nicht zum zurueckgetretenen */
body.about-open .roots-title{ opacity:0!important; }
body.about-open .roots-fade-top{ opacity:1!important; }          /* die weiche Kante des Horizonts gehoert dazu */
/* PARTS und DATAS: die Erklärung hat Vorrang. Die Krone tritt hinter ihr zurück, damit die Schrift
   unverändert stehen kann — ohne Hof, ohne Kasten, einfach lesbar. Sie bleibt dabei deutlich
   sichtbar, sie nimmt nur nicht mehr die Sicht. */
body.parts-open #canvasStage > canvas{ opacity:.34!important; transition:opacity 1.1s cubic-bezier(.25,.46,.45,.94); }
body.about-open .roots-section{ opacity:1!important; }
body.about-open #rootCanvas{ opacity:.62; transition:opacity 1.1s cubic-bezier(.25,.46,.45,.94); }   /* die Wurzeln bleiben sichtbar, treten aber hinter den Text zurueck */
body.nodes-open .tree-wrap{ opacity:0!important; pointer-events:none; transition:opacity .6s ease; }
.nodes-line .l-en,.nodes-line .l-de{ display:none; }
.nodes-line[data-lang="en"] .l-en,.nodes-line[data-lang="de"] .l-de{ display:block; }
.nodes-line[data-lang="en"] .md-r .l-en,.nodes-line[data-lang="de"] .md-r .l-de,
.nodes-line[data-lang="en"] .md-form .l-en,.nodes-line[data-lang="de"] .md-form .l-de,
.nodes-line[data-lang="en"] .md-price .l-en,.nodes-line[data-lang="de"] .md-price .l-de,
.nodes-line[data-lang="en"] .md-cta .l-en,.nodes-line[data-lang="de"] .md-cta .l-de,
.nodes-line[data-lang="en"] .al-k .l-en,.nodes-line[data-lang="de"] .al-k .l-de{ display:inline; }
/* the header: the wordmark's face, reading SOMERA until a column is touched */
/* the header carries the section, it must not shout: light weight, wide tracking, the site's own face */
.nodes-line .md-word{ font-family:'DM Sans',sans-serif; font-weight:300; font-size:clamp(19px,2vw,28px);
  line-height:1.2; letter-spacing:.42em; text-indent:.42em; text-transform:uppercase;
  color:rgba(180,246,229,.72); margin:0 0 clamp(8px,1.3vh,16px);
  transition:color .5s ease; }
/* one face for both states, so the scramble reads as one word changing rather than a swap */
.nodes-line .md-word.on{ color:#e8fff8; text-shadow:0 0 22px rgba(0,199,163,.28); }
.nodes-line .al-k{ margin-bottom:clamp(8px,1.4vh,16px); color:rgba(137,243,221,.9); }
.nodes-line .al-lang{ color:rgba(137,243,221,.8); }
.nodes-line .al-lang button{ color:rgba(137,243,221,.8); }
.nodes-line .md-grid{ display:grid; grid-template-columns:repeat(3,1fr); grid-template-rows:repeat(10,auto);
  gap:0 clamp(12px,2vw,34px); align-items:stretch; text-align:center; }
.nodes-line .md-col{ display:grid; grid-row:span 10; grid-template-rows:subgrid; align-content:start;
  padding:clamp(6px,1vh,12px) clamp(6px,.8vw,14px) clamp(8px,1.2vh,14px);
  border:1px solid transparent; border-radius:14px; cursor:pointer; outline:none;
  transition:border-color .45s ease,background .45s ease; }
.nodes-line .md-col.on,.nodes-line .md-col:hover{ border-color:rgba(0,199,163,.30); background:rgba(0,199,163,.045); }
/* the tile: the node is the subject here, so it gets the room a product shot needs */
.nodes-line .md-shot{ position:relative; height:clamp(186px,29vh,286px); border-radius:12px;
  background:linear-gradient(180deg,rgba(0,199,163,.055) 0%,rgba(0,199,163,.018) 58%,rgba(0,0,0,0) 100%);
  box-shadow:inset 0 0 0 1px rgba(0,199,163,.10); transition:background .5s ease,box-shadow .5s ease; }
.nodes-line .md-col.on .md-shot,.nodes-line .md-col:hover .md-shot{
  background:linear-gradient(180deg,rgba(0,199,163,.11) 0%,rgba(0,199,163,.04) 58%,rgba(0,0,0,0) 100%);
  box-shadow:inset 0 0 0 1px rgba(0,199,163,.26); }
.nodes-line .md-cv{ position:absolute; inset:0; width:100%; height:100%; display:block; }
.nodes-line .md-name{ font-family:'DM Sans',sans-serif; font-weight:700; font-size:clamp(17px,1.7vw,26px);
  letter-spacing:.14em; color:rgba(240,255,251,.95); transition:color .4s ease,text-shadow .4s ease; }
.nodes-line .md-col.on .md-name,.nodes-line .md-col:hover .md-name{ color:#fff; text-shadow:0 0 18px rgba(0,199,163,.5); }
.nodes-line .md-form{ font-family:ui-monospace,Menlo,monospace; font-size:10px; letter-spacing:2px;
  text-transform:uppercase; color:rgba(137,243,221,.85); margin:3px 0 clamp(5px,.8vh,10px); }
.nodes-line .md-r{ font-family:'DM Sans',sans-serif; font-size:clamp(12.5px,1.05vw,15.5px); line-height:1.45;
  color:rgba(240,255,251,.98); padding:7px 2px; border-top:1px solid rgba(0,199,163,.13);
  display:flex; flex-direction:column; justify-content:flex-start; gap:2px; transition:color .4s ease; }
.nodes-line .md-col.on .md-r,.nodes-line .md-col:hover .md-r{ color:rgba(232,250,245,.94); }
.nodes-line .md-r b{ display:block; font-family:ui-monospace,Menlo,monospace; font-weight:400; font-size:9.5px;
  letter-spacing:1.7px; text-transform:uppercase; color:rgba(137,243,221,.62); margin-bottom:1px; }
.nodes-line .md-price{ padding-top:10px; font-family:'DM Sans',sans-serif; font-weight:700;
  font-size:clamp(17px,1.5vw,23px); letter-spacing:.02em; color:#eafff9; line-height:1.2; }
.nodes-line .md-cta{ align-self:center; justify-self:center; margin-top:8px; padding:6px 20px;
  border:1px solid rgba(137,243,221,.4); border-radius:999px; font-family:ui-monospace,Menlo,monospace;
  font-size:10.5px; letter-spacing:2.2px; text-transform:uppercase; color:rgba(255,255,255,.9);
  text-decoration:none; transition:border-color .35s ease,color .35s ease; }
.nodes-line .md-col.on .md-cta,.nodes-line .md-cta:hover{ border-color:rgba(137,243,221,.95); color:#fff; }
body.nodes-open #nodesLine > *{ opacity:1; }
/* narrow screens: both reading views become full-screen scrollers instead of one centred block
   that would run off the top and bottom of the phone */
/* the three columns rise in from below, one per camera, while the crown is still travelling */
.nodes-line .md-col{ transform:translateY(52px); opacity:0;
  transition:transform 1.15s cubic-bezier(.16,1,.3,1),opacity 1.15s ease,border-color .45s ease,background .45s ease; }
body.nodes-open .nodes-line .md-col{ transform:none; opacity:1; transition-delay:1.15s; }
body.nodes-open .nodes-line .md-col:nth-of-type(2){ transition-delay:1.30s; }
body.nodes-open .nodes-line .md-col:nth-of-type(3){ transition-delay:1.45s; }
body.nodes-open .nodes-line .md-col.dim{ opacity:.82; transition-delay:0s; }
body.nodes-open .nodes-line .md-col.on,body.nodes-open .nodes-line .md-col:hover,
body.nodes-open .nodes-line .md-col:focus-within{ transition-delay:0s!important; }
/* Zurückgenommen wird das Bild der Node, nicht der Vergleichswert: eine Vergleichsseite, auf der man
   den Vergleichswert nicht lesen kann, ist keine. Gemessen war die ganze Spalte bei 1,17–1,56 : 1. */
body.nodes-open .nodes-line .md-col.dim .md-shot{ opacity:.34; }
/* the crisp wireframe comes up under the crown's points as they land */
/* on the way in the wireframe waits for the crown's points; on the way OUT it clears fast, so what
   you watch is the crown re-forming and not two pictures cross-fading */
.nodes-line .md-cv{ opacity:0; transition:opacity .38s ease; }
body.nodes-open .nodes-line .md-cv{ opacity:1; transition:opacity 1s ease; transition-delay:1.9s; }
/* Die Pflichtzeile ist eine Fusszeile: eine Zeile ueber die ganze Breite, ganz unten am Fenster.
   Das Schliesszeichen rueckt darueber, damit es nicht mehr hinter dem Text verschwindet. */
#nodesNote{ position:fixed; left:0; right:0; bottom:13px; z-index:9; text-align:center; pointer-events:none;
  opacity:0; visibility:hidden; transition:opacity .5s ease, visibility 0s linear .5s; }
body.nodes-open #nodesNote{ opacity:1; visibility:visible; transition:opacity .8s ease .9s, visibility 0s linear 0s; }
#nodesNote .l-en,#nodesNote .l-de{ display:none; }
#nodesNote[data-lang="en"] .l-en,#nodesNote[data-lang="de"] .l-de{ display:block; }
#nodesNote p{ margin:0; font-family:ui-monospace,Menlo,monospace; font-size:clamp(9px,.68vw,10.5px);
  letter-spacing:.08em; text-transform:uppercase; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  padding:0 14px; line-height:1.4; color:rgba(190,224,216,.5); }
body.nodes-open .ov-close{ bottom:44px!important; }
.ov-close,.ts-ov-close,.parts-line .pl-close{ z-index:40!important; }
body.nodes-open .nodes-line{ padding-bottom:78px; }        /* die Spalten enden ueber dem Zeichen, nicht darunter */
/* Auf kleinen Schirmen scrollen die drei Systeme — dann zieht immer irgendein Inhalt hinter dem
   Schliesszeichen vorbei. Ein ruhiger Grund unter dem unteren Rand haelt Zeichen und Pflichtzeile
   in jeder Scrollstellung klar lesbar. */
/* Nur wo die drei Systeme wirklich scrollen — auf dem Schreibtisch stehen sie, dort braucht es
   keinen Grund, und im hellen Schema zeichnete er selbst eine Kante (Naht 1,0 → 3,5). */
@media(max-width:860px){
  body.nodes-open #nodesNote::before{ content:""; position:fixed; left:0; right:0; bottom:0; height:84px; z-index:-1;
    pointer-events:none; background:linear-gradient(to top,rgba(1,11,8,.94),rgba(1,11,8,.78) 46%,rgba(1,11,8,0)); }
  body[data-theme="light"].nodes-open #nodesNote::before{
    background:linear-gradient(to top,rgba(228,235,232,.88),rgba(228,235,232,.5) 52%,rgba(228,235,232,0)); } }
@media(max-width:860px){ body.nodes-open .nodes-line{ padding-bottom:92px; } }
/* Auf dem Telefon passt die Pflichtangabe nicht in eine Zeile — und abschneiden darf man sie nicht.
   Sie bricht dort um; das Schliesszeichen rueckt entsprechend hoeher. */
@media(max-width:640px){ #nodesNote p{ font-size:8.5px; letter-spacing:.03em; white-space:normal;
    line-height:1.4; padding:0 16px; text-overflow:clip; }
  body.nodes-open .ov-close{ bottom:54px!important; }
  body.nodes-open #nodesNote::before{ height:104px; } }
@media(max-width:860px){
  .nodes-line .md-grid{ grid-template-columns:1fr; grid-template-rows:none; gap:18px 0; }
  .nodes-line .md-col{ grid-row:auto; grid-template-rows:none; display:block; }
  .nodes-line .md-shot{ height:180px; }
  /* #scene carries a perspective, so a fixed child is trapped in its box — the height is set
     explicitly instead of using bottom:0, otherwise the sheet stops short of the phone's edge */
  .nodes-line,#aboutLine{ position:fixed; left:0; right:0; top:0; bottom:auto; width:auto; max-width:none;
    height:100vh; height:100dvh; transform:none; overflow-y:auto; overflow-x:hidden; -webkit-overflow-scrolling:touch;
    padding:58px 16px 48px; }
  body.nodes-open .nodes-line,body.about-open #aboutLine{ overscroll-behavior:contain; }
}

/* ── 2026-09-07: brackets half as wide (54.5 → 88 px), same 1.128 steps, 1.618 bottom/top; the lettering keeps its size
   and stays centred on the stem even where it is wider than its bracket ── */
/* the brackets widen by position, not by name: ORDER · NODES · ABOUT · PARTS · DATAS */
.tree details.act[data-act="order"],.tree details.act[data-act="order"][open]{ width:54.5px!important; max-width:54.5px!important; }
.tree details.act[data-act="nodes"],.tree details.act[data-act="nodes"][open]{ width:61.5px!important; max-width:61.5px!important; }
.tree details.act[data-act="about"],.tree details.act[data-act="about"][open]{ width:69.5px!important; max-width:69.5px!important; }
.tree details.act[data-act="parts"],.tree details.act[data-act="parts"][open]{ width:78px!important; max-width:78px!important; }
.tree details.act[data-act="datas"],.tree details.act[data-act="datas"][open]{ width:88px!important; max-width:88px!important; }
.tree details.act{ display:flex!important; justify-content:center; overflow:visible!important; }
.tree details.act summary{ flex:0 0 auto; width:max-content; }
.tree details.act:hover summary,.tree details.act:focus-within summary{ letter-spacing:.1em!important; }   /* hover spread scaled to the half-width brackets */

/* one × for ABOUT and MODELS — it lives outside both blocks, so it really sits in the screen corner */
.ov-close{ position:fixed; top:14px; right:18px; width:36px; height:36px; z-index:12;
  border:1px solid rgba(137,243,221,.35); border-radius:50%; background:rgba(2,26,19,.6);
  color:#cdece4; font-size:20px; line-height:34px; cursor:pointer;
  opacity:0; pointer-events:none; transition:opacity .45s ease,color .3s ease,border-color .3s ease; }
body.about-open .ov-close,body.nodes-open .ov-close{ opacity:1; pointer-events:auto; }
.ov-close:hover{ color:#fff; border-color:rgba(137,243,221,.8); }

/* ── ORDER · the three systems, chosen right where the price stands ── */
.shop2-models{ display:flex; justify-content:center; gap:8px; margin:0 0 6px; flex-wrap:wrap; }
.shop2-models .sm-opt{ padding:6px 16px; border:1px solid rgba(0,199,163,.32); border-radius:999px;
  background:transparent; font-family:ui-monospace,Menlo,monospace; font-size:11px; letter-spacing:2px;
  color:rgba(205,236,228,.72); cursor:pointer; transition:border-color .3s ease,color .3s ease,background .3s ease; }
.shop2-models .sm-opt:hover{ color:#fff; border-color:rgba(0,199,163,.6); }
.shop2-models .sm-opt.on{ color:#062018; background:#4fe3c1; border-color:#4fe3c1; }
@media(max-width:640px){ .shop2-models .sm-opt{ padding:5px 12px; font-size:10px; letter-spacing:1.4px; } }

/* ── 2026-09-11 · EIN Zeichen, zwei Aufgaben. Auf der Startseite steht der Helligkeitsschalter oben in
   der Mitte. Wird eine Sektion geöffnet, wandert er auf der Mittelachse nach unten an den unteren
   Rand und wird dort vom × abgelöst — die Seite bleibt symmetrisch, und das Schließen liegt nicht
   mehr in einer Ecke. Der Weg ist eine Verschiebung, kein Sprung: top/bottom lassen sich nicht
   überblenden, transform schon. ── */
.theme-switch{ transition:opacity .3s ease .40s,
  transform .62s cubic-bezier(.5,0,.15,1),
  width .35s cubic-bezier(.16,1,.3,1), height .35s cubic-bezier(.16,1,.3,1)!important; }
body.about-open .theme-switch,body.nodes-open .theme-switch,
body.parts-open .theme-switch,body.shop-open .theme-switch{
  transform:translate(-50%,calc(100dvh - 58px))!important; }
/* das × übernimmt den Platz, sobald der Schalter dort angekommen ist */
/* Das Zeichen zum Schließen soll da sein, wenn man es sucht — nicht dazu einladen, die Seite zu
   verlassen. Deshalb kleiner, dünner und zurückhaltend; erst bei Berührung tritt es hervor. */
.ov-close,.ts-ov-close,.parts-line .pl-close{
  top:auto!important; bottom:16px!important; left:50%!important; right:auto!important;
  transform:translateX(-50%); border-radius:50%!important;
  width:24px!important; height:24px!important; font-size:13px!important; line-height:22px!important;
  border-width:1px!important; }
.ov-close,.parts-line .pl-close{ border-color:rgba(137,243,221,.22)!important; color:rgba(205,236,228,.5)!important;
  background:rgba(2,26,19,.35)!important; }
.ts-ov-close{ border-color:rgba(0,199,163,.22)!important; color:rgba(137,243,221,.5)!important;
  background:rgba(2,26,19,.35)!important; }
.ov-close:hover,.ts-ov-close:hover,.parts-line .pl-close:hover{
  border-color:rgba(137,243,221,.6)!important; color:#fff!important; background:rgba(2,26,19,.7)!important; }
.ov-close{ transition:opacity .4s ease .46s,color .3s ease,border-color .3s ease,background-color .3s ease!important; }
@media(max-width:640px){
  body.about-open .theme-switch,body.nodes-open .theme-switch,
  body.parts-open .theme-switch,body.shop-open .theme-switch{ transform:translate(-50%,calc(100dvh - 46px))!important; }
  .ov-close,.parts-line .pl-close{ bottom:12px!important; } .ts-ov-close{ bottom:12px!important; } }

/* ── 2026-09-11 · ORDER liest sich als ein Satz: Name → Zusage → Wahl → Preis → Handlung → die vier
   Blöcke, die die Node ausmachen. Die Blöcke stehen offen da, nicht hinter Knöpfen: maximaler
   Überblick, ohne dass jemand etwas aufklappen muss. ── */
.ts-ov#ovOrder .spec-row{ grid-area:sp; width:min(1000px,94vw); display:grid; gap:clamp(14px,2.2vw,34px);
  grid-template-columns:repeat(4,minmax(0,1fr)); text-align:left; margin:clamp(2px,0.8vh,10px) 0 0; }
.ts-ov#ovOrder .spec b{ display:block; font-family:ui-monospace,Menlo,monospace; font-size:10.5px;
  letter-spacing:2.0px; text-transform:uppercase; color:rgba(137,243,221,.92); font-weight:400;
  padding-bottom:5px; margin-bottom:6px; border-bottom:1px solid rgba(0,199,163,.22); }
.ts-ov#ovOrder .spec p{ margin:0; font-size:11.5px; line-height:1.45; color:rgba(205,236,228,.78); }
/* eine Zeile Kleingedrucktes unter dem Preis, nicht zwei fast gleiche */
/* Diese Zeile trägt die Pflichtangaben (Core-Cloud, Anzahlung). Gemessen stand sie bei 2,31 : 1. */
.ts-ov#ovOrder .shop2-meta{ font-size:10.5px; letter-spacing:.06em; color:rgba(205,236,228,.82); margin:1px 0 0; }
/* das × steht jetzt unten mittig — die Schlusszeile darf nicht darunter geraten */

body[data-theme="light"] .ts-ov#ovOrder .spec b{ color:#001a13; border-bottom-color:rgba(0,84,69,.34); }
body[data-theme="light"] .ts-ov#ovOrder .spec p{ color:#0a1a16; }
body[data-theme="light"] .ts-ov#ovOrder .shop2-meta{ color:rgba(16,41,35,.92); }
@media(max-width:900px){ .ts-ov#ovOrder .spec-row{ grid-template-columns:repeat(2,minmax(0,1fr)); row-gap:12px; } }
@media(max-width:640px){ .ts-ov#ovOrder .spec-row{ grid-template-columns:minmax(0,1fr); } }

/* ── Zugänglichkeit ─────────────────────────────────────────────────────────────────────────────
   Ein Bereich, der auf opacity:0 steht, ist für Auge und Maus weg — für Tastatur und Screenreader
   aber nicht. Gemessen lagen dadurch 19 unsichtbare Tabstationen vor dem ersten Menüpunkt, und ein
   Screenreader las am Ruhezustand über 2.000 Zeichen aus vier geschlossenen Bereichen vor.
   visibility schaltet verzögert, damit die Blende unverändert bleibt. */
.about-line,.parts-line,.nodes-line{ visibility:hidden; transition:opacity .45s ease, visibility 0s linear .45s; }
body.about-open #aboutLine,body.parts-open #partsLine,body.parts-open #datasLine,
body.nodes-open #nodesLine{ visibility:visible; transition-delay:0s,0s; }
.ov-close{ visibility:hidden; }
body.arrow-gone .stem-arrow{ visibility:hidden; }
body.about-open .ov-close,body.nodes-open .ov-close{ visibility:visible; }

/* nur für Hilfsmittel */
.sr-only{ position:absolute!important; width:1px; height:1px; margin:-1px; padding:0;
  overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap; border:0; }

/* Der Fokusring war der blaue Standardring des Browsers — eine Fremdfarbe in einer sehr
   reduzierten Seite, und an drei Stellen ganz abgeschaltet. Jetzt im Ton des Schemas, und nur
   bei Tastaturbedienung sichtbar. */
:root{ --ts-focus:#78ffdc; }
body[data-theme="light"]{ --ts-focus:#00251e; }
:focus-visible{ outline:2px solid var(--ts-focus); outline-offset:3px; border-radius:2px; }
.nodes-line .md-col:focus-visible,.order-field input:focus-visible,
.tree details.act summary:focus-visible{ outline:2px solid var(--ts-focus)!important; outline-offset:0; }

/* Ab Seite 2 steht die Ueberschrift oben im Titel — im Block waere sie nur noch eine Wiederholung. */
.about-line:not([data-step="0"]) .al-sec .al-h{ display:none; }

/* Der Schritt zurück bei ABOUT: zwei Sekunden, weich beginnend und weich endend. Die Werte setzt
   overlays.js (stepBack) — hier steht nur, wie lange die Bewegung dauert. */
#canvasStage > canvas,#treeSection,#rootsSection{ transition:transform 2s cubic-bezier(.33,.02,.2,1)!important; }

/* ═══ Rechtstexte: der Spalt im Horizont ═══════════════════════════════════════════════════════
   Kein Kasten ueber der Seite und kein Vorhang davor — der Baum bleibt sichtbar, er macht Platz.
   Der Text liegt in dem Spalt, den Stamm und Wurzeln freigeben: zwei Spalten, das Schliesszeichen
   unten in der Mitte auf der Linie des Stammes. */
.legal-modal{ background:transparent!important; backdrop-filter:none!important; align-items:flex-start!important; }
/* Erst der Platz, dann der Text. Der Spalt oeffnet sich ueber zwei Sekunden — der Text kommt in
   der zweiten Haelfte dazu, wenn der Raum schon da ist, und nicht davor. Beim Schliessen geht er
   zuerst, damit der Baum in einen leeren Spalt zusammenwaechst. */
/* Der Text macht sich seinen Platz SELBST: das Feld rollt aus der Mitte auf — die Oberkante
   wandert nach oben, die Unterkante nach unten —, und der Baum weicht im selben Takt und mit
   derselben Kurve. Es gibt also nicht erst einen Spalt und dann Text, sondern das Ausrollen des
   Textes IST das Entstehen des Spalts.
   Geschaltet wird ueber `visibility`, nie ueber `display`: aus `display:none` heraus laeuft kein
   Uebergang (der Browser setzt den Endwert sofort), und ein unsichtbarer Kasten ohne
   `pointer-events:none` hat hier schon einmal das ganze Menue lahmgelegt. */
#legalBox{ opacity:0; visibility:hidden; pointer-events:none; overflow:hidden!important;
  transition:height 2s cubic-bezier(.33,.02,.2,1), top 2s cubic-bezier(.33,.02,.2,1),
             padding 2s cubic-bezier(.33,.02,.2,1), opacity .3s ease, visibility 0s linear .3s; }
#legalBox.zeigt{ opacity:1; visibility:visible; pointer-events:auto;
  transition:height 2s cubic-bezier(.33,.02,.2,1), top 2s cubic-bezier(.33,.02,.2,1),
             padding 2s cubic-bezier(.33,.02,.2,1), opacity .3s ease .1s, visibility 0s linear .1s; }
/* Sichtbarkeit haengt jetzt an .zeigt (siehe legal.js) — sie muss das Aufrollen ueberdauern,
   auch beim Schliessen, damit der Text mit dem Spalt zusammenrollt statt vorher zu verschwinden. */
.legal-box{ position:absolute; left:50%; transform:translateX(-50%); z-index:10001; display:none;
  width:min(1040px,90vw); max-height:none!important; height:auto;
  background:linear-gradient(180deg,rgba(2,20,15,.62),rgba(2,20,15,.30));
  border:1px solid rgba(0,199,163,.16); border-radius:3px;
  padding:clamp(14px,2.2vh,22px) clamp(16px,2.4vw,30px) clamp(30px,4.2vh,40px);
  box-shadow:0 18px 60px rgba(0,0,0,.45); display:flex; flex-direction:column; }
.legal-box .lg-h{ position:static; width:auto; height:auto; clip:auto; margin:0 0 clamp(8px,1.4vh,14px);
  font-family:ui-monospace,Menlo,monospace; font-size:clamp(9.5px,.78vw,11px); letter-spacing:.24em;
  text-transform:uppercase; font-weight:500; color:rgba(137,243,221,.92); text-align:left; }
.legal-box .lg-cols{ flex:1 1 auto; min-height:0; overflow:hidden;
  column-count:2; column-gap:clamp(22px,3vw,44px); column-rule:1px solid rgba(0,199,163,.10);
  line-height:1.62; color:rgba(205,236,228,.82); text-align:left; }
.legal-box .lg-cols p{ margin:0 0 .82em; break-inside:avoid; }
.legal-box .legal-close{ position:absolute; top:auto; left:50%; bottom:9px; transform:translateX(-50%);
  float:none; width:24px; height:24px; line-height:22px; font-size:13px; border-radius:50%;
  border:1px solid rgba(137,243,221,.22); background:rgba(2,26,19,.35); color:rgba(205,236,228,.5); }
.legal-box .legal-close:hover{ border-color:rgba(137,243,221,.6); color:#fff; background:rgba(2,26,19,.7); }
body.legal-open .ov-close{ opacity:0!important; pointer-events:none; }
body.legal-open #nodesNote{ opacity:0!important; }
@media(max-width:720px){ .legal-box .lg-cols{ column-count:1; } .legal-box{ width:94vw; } }
body[data-theme="light"] .legal-box{ background:linear-gradient(180deg,rgba(236,241,239,.78),rgba(236,241,239,.46));
  border-color:rgba(0,84,69,.18); box-shadow:0 18px 60px rgba(20,40,34,.18); }
body[data-theme="light"] .legal-box .lg-cols{ color:rgba(12,34,28,.88); }
body[data-theme="light"] .legal-box .lg-h{ color:rgba(0,66,54,.95); }
body[data-theme="light"] .legal-box .legal-close{ border-color:rgba(0,84,69,.3); color:rgba(0,66,54,.6); background:rgba(255,255,255,.4); }
