:root{--nuvolead-whatsapp:#25D366;}

  /* Arrow in flight (nuvolead.ch only, #45, ADR 0034). The flat arrow is the
     page without script, reduced motion or WebGL, and its box is where the
     3D arrow rests: right of the title on wide screens, above it on narrow
     ones. The canvas covers the whole hero, so the hero's own edge is the
     only place the flight is ever cut. */
  .hero-pfeil {
    position: absolute; z-index: 1; right: var(--gutter); top: calc(var(--nav-h) + clamp(32px, 6vh, 72px));
    width: clamp(160px, min(40vw, calc(100svh - var(--nav-h) - 360px)), 600px); height: auto; aspect-ratio: 1;
    color: var(--nl-violet); transition: opacity .8s var(--ease-out);
  }
  @media (max-width: 900px) {
    .hero-pfeil { top: calc(var(--nav-h) + 24px); width: clamp(88px, min(46vw, calc(100svh - 520px)), 320px); }
  }
  .hero-flug { position: absolute; inset: 0; z-index: 1; pointer-events: none; opacity: 0; transition: opacity .8s var(--ease-out); }
  .hero-flug canvas { display: block; width: 100%; height: 100%; }
  .hero-hitze { position: absolute; width: 0; height: 0; overflow: hidden; }
  .hero--flug .content { z-index: 2; }
  .hero[data-flug="an"] .hero-flug { opacity: 1; }
  .hero[data-flug="an"] .hero-pfeil { opacity: 0; }

  /* --- the bar with the mega menu (draft Web-Nav, nuvolead.ch) ------------
     Only when the navigation carries points under its pages (.nav--mega).
     Height and negative margin move together, so the bar grows smaller
     without moving the page underneath it. SiteNav sets .klein once the
     page has moved; without a script the bar simply keeps its full size. */
  header.nav--mega {
    --nav-h: 80px;
    transition: transform .5s cubic-bezier(.2,.7,.2,1), color .3s ease, background-color .3s ease, box-shadow .3s ease,
      height .5s var(--ease-out), margin-bottom .5s var(--ease-out);
  }
  header.nav--mega.klein { --nav-h: 60px; }
  /* ADR 0095, #219 (owner, 11.11.2026: «schaut euch auch noch die
     Navigationsbar an», after the bar of cmdweb.ch): once the page has
     moved the bar is a white surface with its line, not a veil the page
     shines through; over a dark section it is black. The tabs stand in the
     middle between mark and login; the mark keeps its width from 1181 px,
     so the tabs do not slide when the name leaves. The arrow of the mark
     lifts off under the pointer, like the one in the footer. */
  header.nav--mega.scrolled { background: var(--nl-card); -webkit-backdrop-filter: none; backdrop-filter: none; }
  header.nav--mega.scrolled.over-dark { background: var(--nl-ink); }
  /* With the tabs in the middle the text of a tall opening runs under them
     while the visitor scrolls through it: on the start page the bar stayed
     transparent for a whole screen (SiteNav sets scrolled only once the
     opening has passed) and «Leistungen» and «Plattform» stood in the
     running text. So the bar takes its surface with the first movement
     (class klein, above 8 px). At rest over the opening it stays
     transparent, as DESIGN.md chapter 6 has it. */
  header.nav--mega.klein { background: var(--nl-card); box-shadow: inset 0 -1px 0 var(--nl-line); }
  header.nav--mega.klein.over-dark { background: var(--nl-ink); box-shadow: inset 0 -1px 0 var(--nl-dark-line); }
  @media (min-width: 901px) {
    header.nav--mega nav.links { flex: 1 1 auto; }
    header.nav--mega .mega-reiter { margin-inline: auto; }
  }
  @media (min-width: 1181px) { header.nav--mega .brand { min-width: 168px; } }
  @media (hover: hover) and (prefers-reduced-motion: no-preference) {
    header.nav--mega .brand:hover .brand-pfeil { transform: translate(3px, -3px); }
  }
  /* The first block keeps its air below the taller bar (site.css, --kopf-h). */
  :root:has(header.nav--mega) { --kopf-h: 80px; }
  header.nav--mega .wrap { gap: 24px; }
  header.nav--mega .brand { gap: 10px; font-size: 24px; letter-spacing: -0.03em; }
  .brand-pfeil { width: 32px; height: 32px; color: var(--nl-violet); flex: none; transition: width .4s var(--ease-out), height .4s var(--ease-out), transform .6s var(--ease-expo); }
  .brand-wort { display: inline-block; overflow: hidden; max-width: 12em; transition: max-width .4s var(--ease-out), opacity .25s ease; }
  header.nav--mega.klein .brand-pfeil { width: 26px; height: 26px; }
  /* The name stays in the link for assistive technology, only the eye
     loses it while the bar is small. */
  header.nav--mega.klein .brand-wort { max-width: 0; opacity: 0; }
  header.nav--mega nav.links {
    align-self: stretch; gap: 28px;
    font-size: var(--fs-label); font-weight: 400; letter-spacing: .08em; text-transform: uppercase;
  }
  /* The tabs stand side by side without a gap of their own: the air between
     them is padding of each tab, so the pointer crossing from one tab to the
     next is on a tab the whole way and the panel it leaves does not start to
     close before the next one opens (ADR 0066). The tabs reach the full
     height of the bar, so there is no gap between a tab and its panel. */
  .mega-reiter { display: flex; align-items: stretch; height: 100%; }
  .mega-reiter > li { display: flex; align-items: center; padding: 0 14px; }
  .mega-reiter > li:first-child { padding-left: 0; }
  .mega-reiter > li:last-child { padding-right: 0; }
  .mega-reiter .navlink { gap: 7px; }
  /* «Ihr Zugang» (ADR 0081): third level, set off from the tabs by a line,
     the drawn key before the word, in the full colour of the bar: the
     line and the key set it apart, so it is no longer muted (site.css). */
  header.nav--mega .navlink-login { display: inline-flex; align-items: center; gap: 8px; margin-left: 6px; padding-left: 22px; box-shadow: inset 1px 0 0 var(--nl-line); color: inherit; }
  header.nav--mega .navlink-login .schluessel { flex: none; }
  .mega-pfeil { width: 10px; height: 10px; transition: transform .25s ease; }
  .mega-pfeil path { stroke: currentColor; stroke-width: 1.4; fill: none; }
  .mega-reiter li:hover .mega-pfeil, .mega-reiter li:focus-within .mega-pfeil { transform: rotate(180deg); }
  /* The button of the bar keeps its white surface and is the second level
     (ADR 0067): pointing closes its corners into a 1px frame and turns the
     text violet, there is no fill; on the page it leads to (/kontakt) the
     frame stands closed. Straight under header.nav--mega, not under :has(),
     so colour and fill always change together, in every browser. */
  header.nav--mega .nav-knopf { min-height: 52px; background: var(--nl-card); color: var(--nl-ink); transition: color .25s ease, min-height .5s var(--ease-out); }
  header.nav--mega .nav-knopf:hover { color: var(--nl-violet-fill); }
  header.nav--mega .nav-knopf:hover .fill { opacity: 0; }
  header.nav--mega .nav-knopf .deco { transition: width .35s var(--ease-out), height .35s var(--ease-out); }
  header.nav--mega .nav-knopf:hover .deco, header.nav--mega .nav-knopf[aria-current="page"] .deco { width: 50%; height: 50%; }
  header.nav--mega.klein .nav-knopf { min-height: 44px; }
  /* The same button in the full screen menu, which lies right after the
     bar (SiteNav): white surface, 52px, aligned left. 0,3,1 beats the
     underline of the current page in the menu (site.css, 0,2,2). */
  header.nav--mega + .mobile-menu .nav-knopf { justify-self: start; margin-top: var(--s-2); min-height: 52px; background: var(--nl-card); color: var(--nl-ink); text-decoration: none; }
  header.nav--mega + .mobile-menu .nav-knopf:hover { color: var(--nl-violet-fill); }
  header.nav--mega + .mobile-menu .nav-knopf:hover .fill { opacity: 0; }
  header.nav--mega + .mobile-menu .nav-knopf .deco { transition: width .35s var(--ease-out), height .35s var(--ease-out); }
  header.nav--mega + .mobile-menu .nav-knopf:hover .deco, header.nav--mega + .mobile-menu .nav-knopf[aria-current="page"] .deco { width: 50%; height: 50%; }
  /* The full screen menu on the phone is the mega menu at full size
     (owner's wish of 20.10.2026): the light surface of the panels, each
     page in capitals with its points beneath as cards, title and text,
     a line above each; the same arrow and name as in the bar. The list
     draws the cards for this package only (NavTeile, karten). */
  header.nav--mega + .mobile-menu { background: var(--nl-paper); color: var(--nl-ink); gap: var(--s-6); }
  header.nav--mega + .mobile-menu .mm-head .brand { gap: 8px; font-size: 20px; letter-spacing: -0.03em; }
  header.nav--mega + .mobile-menu .mm-head .brand-pfeil { width: 26px; height: 26px; }
  header.nav--mega + .mobile-menu nav { gap: var(--s-6); font-size: 16px; letter-spacing: 0; }
  header.nav--mega + .mobile-menu .mm-gruppe { gap: 8px; }
  header.nav--mega + .mobile-menu .mm-seite { justify-self: start; display: inline-flex; align-items: center; min-height: var(--tap, 44px); font-size: var(--fs-label); letter-spacing: .08em; text-transform: uppercase; text-decoration: none; }
  header.nav--mega + .mobile-menu .mm-seite:hover .u::after, header.nav--mega + .mobile-menu .mm-seite[aria-current="page"] .u::after { transform: scaleX(1); transform-origin: left; }
  header.nav--mega + .mobile-menu .mm-punkte { gap: 4px; }
  header.nav--mega + .mobile-menu .mm-punkt { display: flex; flex-direction: column; align-items: stretch; gap: 4px; min-height: var(--tap, 44px); padding: 14px 0 12px; box-shadow: inset 0 1px 0 var(--nl-line); color: var(--nl-ink); font-size: 15px; letter-spacing: 0; }
  header.nav--mega + .mobile-menu .mm-punkt b { font-weight: 700; }
  header.nav--mega + .mobile-menu .mm-punkt > span { font-size: 14px; color: var(--nl-muted); }
  header.nav--mega + .mobile-menu .mm-punkt:hover .u::after { transform: scaleX(1); transform-origin: left; }
  /* #179: every page a group that opens on a tap (details in NavTeile.tsx).
     Closed, the menu is five lines, Anmelden and the button; the group of the
     page you are on is open. A line between the groups, a chevron that
     turns. */
  header.nav--mega + .mobile-menu nav { gap: var(--s-3); }
  header.nav--mega + .mobile-menu details.mm-gruppe { display: block; box-shadow: inset 0 -1px 0 var(--nl-line); }
  header.nav--mega + .mobile-menu summary.mm-seite {
    display: flex; justify-content: space-between; align-items: center; gap: 16px; min-height: 56px; cursor: pointer; list-style: none;
  }
  header.nav--mega + .mobile-menu summary.mm-seite::-webkit-details-marker { display: none; }
  header.nav--mega + .mobile-menu summary.mm-seite::after {
    content: ""; flex: none; width: 9px; height: 9px; margin-right: 6px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
    transform: translateY(-3px) rotate(45deg); transition: transform .25s var(--ease-out);
  }
  header.nav--mega + .mobile-menu details[open] > summary.mm-seite::after { transform: translateY(2px) rotate(-135deg); }
  header.nav--mega + .mobile-menu summary.mm-seite:focus-visible { outline: 2px solid var(--nl-violet-fill); outline-offset: 2px; }
  header.nav--mega + .mobile-menu details.mm-gruppe .mm-punkte { padding-bottom: 12px; }
  header.nav--mega + .mobile-menu details.mm-gruppe:has(+ .mm-login) { box-shadow: none; }
  @media (prefers-reduced-motion: reduce) { header.nav--mega + .mobile-menu summary.mm-seite::after { transition: none; } }
  /* The corner for customers at the end of the menu (ADR 0081): below a
     line, a card like the points of a page, with the key, the word and
     whom it is for. */
  header.nav--mega + .mobile-menu .mm-login { flex-direction: column; align-items: stretch; gap: 6px; margin-top: var(--s-6); padding: var(--s-5) 0 var(--s-2); border-top: 1px solid var(--nl-line); color: var(--nl-ink); font-size: 15px; letter-spacing: normal; text-transform: none; }
  header.nav--mega + .mobile-menu .mm-login b { display: inline-flex; align-items: center; gap: 10px; font-size: var(--fs-label); font-weight: 400; letter-spacing: .08em; text-transform: uppercase; }
  header.nav--mega + .mobile-menu .mm-login .mm-login-satz { font-size: 14px; line-height: 1.45; color: var(--nl-muted); max-width: 44ch; }
  /* In bar and menu the four corners sit 4px inside the white surface, at
     rest, pointed and as the standing frame on /kontakt: on its very edge
     they were ink on the dark ground of the menu and of dark sections under
     the bar, which is the same token, 1.0:1 (#159, #163). Inside they are
     ink on white, 19.75:1 (DESIGN.md A1: 3:1), and the button shows the
     same picture over light ground, over dark ground and in the menu. Only
     the offsets of base.css move (0,4,1 and 0,5,1 beat 0,3,0); size and
     motion stay those above. */
  header.nav--mega .nav-knopf .deco.tl, header.nav--mega + .mobile-menu .nav-knopf .deco.tl { top: 4px; left: 4px; }
  header.nav--mega .nav-knopf .deco.tr, header.nav--mega + .mobile-menu .nav-knopf .deco.tr { top: 4px; right: 4px; }
  header.nav--mega .nav-knopf .deco.bl, header.nav--mega + .mobile-menu .nav-knopf .deco.bl { bottom: 4px; left: 4px; }
  header.nav--mega .nav-knopf .deco.br, header.nav--mega + .mobile-menu .nav-knopf .deco.br { bottom: 4px; right: 4px; }

  /* One panel per tab, inside its <li> (ADR 0066). CSS opens it while the
     pointer or the focus is on its tab or in the panel itself, which is the
     tab's child, no script involved; no other panel opens with it.
     visibility takes it out of the tab order while it is shut; the delay
     lets the pointer cross from a tab into it. Placed against the bar
     (header.nav is the positioned ancestor), so it spans the whole width.
     Its height ends at the window: under the alert bar the bar stands lower,
     by --kopf-oben, which SiteNav measures while the page moves (#101).
     Left alone (the pointer went off the bar, the focus went on) a panel
     fades out at once, in .28s (DESIGN.md chapter 7). */
  .mega {
    position: absolute; top: 100%; left: 0; right: 0; z-index: 3;
    max-height: calc(100vh - var(--nav-h) - var(--kopf-oben, 0px)); overflow-y: auto; overscroll-behavior: contain;
    /* The window as it is now: on a phone held sideways (956px, mega menu)
       Safari's 100vh counts the toolbar too, and the last pages of the
       panel lay under it, out of reach (#127). */
    max-height: calc(100dvh - var(--nav-h) - var(--kopf-oben, 0px));
    color: var(--nl-ink);
    font-size: 16px; line-height: 1.45; letter-spacing: 0; text-transform: none; white-space: normal;
    /* No surface of its own (#220): the box stays the area the pointer
       rests in from the first frame, the surface is .mega-innen, which
       the light reveals. Line and shadow are a filter, so they follow
       the part of the surface already there and never hang under an
       empty panel. It does not drop in any more: the light comes from
       the lower edge of the bar, and that edge stays where it is. */
    filter: drop-shadow(0 1px 0 var(--nl-line)) drop-shadow(0 14px 14px var(--nl-ink-a35));
    visibility: hidden; opacity: 0; transform: none;
    transition: opacity .28s var(--ease-out), transform .28s var(--ease-out), visibility 0s linear .28s;
  }
  /* With motion a panel left alone takes itself down the way it built up
     (owner, 11.11.2026, #224, ADR 0098; «the light», below): it stays in
     the page for the .58s that takes, and its fade is the opening's fade
     backwards, at the end. Meanwhile the box is out of the hit test and
     the surface is in: what can still be seen can be touched (and opens
     the panel again), the page that shows again underneath is free. Not
     the surface of a panel that a pointed one has made inert (below). */
  @media (prefers-reduced-motion: no-preference) {
    .mega { pointer-events: none; transition: opacity .28s cubic-bezier(.8, 0, .8, .3) .3s, visibility 0s linear .58s; }
    .mega-reiter > li:not(:hover, :focus-within) > .mega > .mega-innen { pointer-events: auto; }
  }
  /* The pointer on a tab opens its panel once it has rested there .12s
     (owner's decision of 19.10.2026): a tab only crossed on the way to
     another one, or on the way down into the open panel, opens nothing. For
     those .12s the panel is out of the hit test too, so the pointer lands
     in the panel still open underneath and keeps it. The pointed panel lies
     over a focused one (5 over 4). */
  .mega-reiter > li:hover > .mega {
    visibility: visible; opacity: 1; transform: none; z-index: 5; pointer-events: auto;
    transition: opacity .28s var(--ease-out) .12s, transform .28s var(--ease-out) .12s, visibility 0s linear .12s;
  }
  /* The focus on a tab or in its panel opens it at once. */
  .mega-reiter > li:focus-within > .mega {
    visibility: visible; opacity: 1; transform: none; z-index: 4; pointer-events: auto;
    transition: opacity .28s var(--ease-out), transform .28s var(--ease-out), visibility 0s;
  }
  /* Changing tabs. While the pointer or the focus is still on the tabs, the
     panel just left keeps its look for .5s: long enough for the next one to
     fade in over it (.12s + .28s, a sweep across several tabs included),
     only then does it fade, covered. Two panels fading at the same time let
     the page shine through between them. Only times: the panel is shut
     either way. Its surface stands whole meanwhile («the light», below),
     and it stays in the hit test as long, so the pointer that crosses a
     tab on its way down lands in it. :where keeps these modifiers below
     the opening rules in specificity, so the order of the rules decides. */
  .mega-reiter:where(:hover, :has(> li:focus-within)) > li:where(:not(:hover, :focus-within)) > .mega {
    pointer-events: auto;
    transition: opacity .28s var(--ease-out) .5s, transform .28s var(--ease-out) .5s, visibility 0s linear .78s;
  }
  /* The pointer wins over a focus that only rests on a tab: that tab's panel
     goes see-through and inert under the pointed one, in the same time, but
     stays in the tab order, so Tab still leads from the tab into its panel
     (which brings it back, next rule). */
  .mega-reiter:where(:hover) > li:where(:not(:hover)):focus-within > .mega:where(:not(:focus-within)) {
    opacity: 0; pointer-events: none;
    transition: opacity .28s var(--ease-out) .5s;
  }
  /* The focus inside a panel wins over everything: that panel lies on top
     (6) and every other one, the pointed one included, is away, so the
     focused link is never covered (DESIGN.md A5). */
  .mega-reiter > li > .mega:focus-within { z-index: 6; }
  .mega-reiter:where(:has(> li > .mega:focus-within)) > li:not(:focus-within) > .mega { visibility: hidden; opacity: 0; }
  /* Escape (script, Nav.tsx) shuts at once: every panel but a pointed one
     while the focus walks the tabs (data-mega on the bar, pointing at a tab
     opens its panel again), and the pointed one until the pointer comes
     onto a tab anew (data-zu on that tab). Last, so it wins. */
  header.nav[data-mega="zu"] .mega-reiter > li:not(:hover) > .mega,
  .mega-reiter > li[data-zu] > .mega { visibility: hidden; opacity: 0; transition: none; }
  /* Without a script nothing measures: the alert bar is one line high then
     (its closing button only exists with a script), --alert-h (tokens.css). */
  @media (scripting: none) {
    body:has(.alert) .mega { max-height: calc(100vh - var(--nav-h) - var(--alert-h)); }
    body:has(.alert) .mega { max-height: calc(100dvh - var(--nav-h) - var(--alert-h)); }
  }
  /* Own measure instead of .wrap: inside header.nav every .wrap is the
     flex row of the bar. */
  /* The full width of the bar with the measure of the content as padding,
     so the surface, its reveal and the light span the whole window.
     Three surfaces (ADR 0075, owner's choice of 11.11.2026, #220): the
     panel is the grey page, the points are white tiles, what one
     touches, and the overview of the page is the black result on the
     left, with the square dot grid of head and foot (ADR 0094). */
  .mega-innen {
    position: relative; display: grid; grid-template-columns: minmax(200px, 1fr) 3fr; align-items: stretch; gap: 12px;
    padding: 20px max(var(--gutter), calc((100% - var(--max)) / 2 + var(--gutter))) 24px;
    background: var(--nl-paper); box-shadow: inset 0 1px 0 var(--nl-line);
  }
  .mega-seite {
    position: relative; isolation: isolate; display: flex; align-items: flex-end; min-height: 120px; padding: 20px;
    background: var(--nl-ink); color: var(--nl-on-dark);
    font-size: var(--fs-label); letter-spacing: .08em; text-transform: uppercase;
  }
  .mega-seite::before {
    content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
    background-image: linear-gradient(90deg, var(--nl-dark-line) 2px, transparent 2px); background-size: 32px 32px; background-position: 15px 15px;
    -webkit-mask-image: linear-gradient(var(--nl-ink) 2px, transparent 2px); mask-image: linear-gradient(var(--nl-ink) 2px, transparent 2px);
    -webkit-mask-size: 32px 32px; mask-size: 32px 32px; -webkit-mask-position: 15px 15px; mask-position: 15px 15px;
  }
  .mega-seite:focus-visible { outline-offset: -4px; }
  .mega-seite:hover .u::after, .mega-seite[aria-current="page"] .u::after { transform: scaleX(1); transform-origin: left; }
  /* The points of the page as cards, at most three side by side; a fourth
     starts a new row. Equal height in a row: the card fills its cell. */
  .mega-punkte { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
  .mega-punkte > li { display: flex; }
  .mega-punkt { flex: 1 1 auto; display: flex; flex-direction: column; gap: 4px; min-height: var(--tap, 44px); padding: 18px 20px; background: var(--nl-card); }
  .mega-punkt b { font-size: 15px; font-weight: 700; }
  .mega-punkt > span { font-size: 14px; color: var(--nl-muted); }
  /* No hover effect on the card (DESIGN.md chapter 7): the title takes the
     underline of a link, as the tabs do. */
  .mega-punkt:hover .u::after { transform: scaleX(1); transform-origin: left; }
  .mega-punkt:focus-visible { outline-offset: -2px; }
  /* Between phone and desktop the bar has to hold five tabs, the login
     and the button on one line: the name leaves the eye first (not the
     link), then the gaps and the tracking shrink, then the chevrons go. */
  @media (min-width: 901px) and (max-width: 1180px) {
    header.nav--mega .brand-wort { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
    header.nav--mega nav.links { gap: 16px; }
    .mega-reiter > li { padding: 0 8px; }
    .mega-innen { grid-template-columns: minmax(160px, 1fr) 4fr; }
    .mega-punkte { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    header.nav--mega .nav-knopf { padding: 0 16px; }
  }
  @media (min-width: 901px) and (max-width: 1020px) {
    header.nav--mega nav.links { letter-spacing: .04em; }
    header.nav--mega nav.links { gap: 12px; }
    .mega-reiter > li { padding: 0 6px; }
    .mega-pfeil { display: none; }
  }
  /* The phone has the full screen menu with the points (MenueListe). The
     bar keeps the word mark, the button and the burger, and must fit 320px. */
  @media (max-width: 900px) {
    .mega-reiter, .mega { display: none; }
    header.nav--mega nav.links { gap: var(--s-2); }
    header.nav--mega .brand { font-size: 20px; gap: 8px; }
    header.nav--mega .brand-pfeil { width: 26px; height: 26px; }
    header.nav--mega .nav-knopf, header.nav--mega.klein .nav-knopf { min-height: var(--tap, 44px); padding: 0 14px; letter-spacing: .06em; }
  }
  /* Narrowest phones: the name leaves the eye, not the link (its only text). */
  @media (max-width: 380px) { header.nav--mega .brand-wort { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; } }

  /* Reading progress: a violet line on the lower edge of the bar, driven by
     the scroll position itself where the browser can (scroll-driven
     animation). Elsewhere, and with reduced motion, there is none. */
  .nav-linie { display: none; position: absolute; left: 0; right: 0; bottom: 0; height: 2px; background: var(--nl-violet); transform-origin: left center; transform: scaleX(0); pointer-events: none; }
  @keyframes nl-fortschritt { from { transform: scaleX(0); } to { transform: scaleX(1); } }
  @supports (animation-timeline: scroll()) {
    @media (prefers-reduced-motion: no-preference) {
      .nav-linie { display: block; animation: nl-fortschritt auto linear both; animation-timeline: scroll(root block); }
    }
  }

  /* --- the light that opens and shuts a panel (owner, 11.11.2026, #220, #224) ---
     «beim hologramm effekt soll die violette linie in der navbar die den
     seiten scroll fortschritt angibt den start des effekts sein.» And later
     that day: the reading progress is not shown while a panel is open, and
     «wenn man wieder weggeht, sollte sich die Seite wieder so abbauen, wie
     sie sich aufgebaut hat, mit diesem violetten Effekt. Und zurück zum
     Scroll-Fortschritt-Balken werden.» (ADR 0097, ADR 0098)

     The bar carries a second line beside the reading progress,
     .nav-linie-licht: same place, same 2 px, same violet, at rest drawn to
     nothing. When a panel opens it runs to the end of the bar from the left;
     over the progress already drawn nothing changes, beyond it the line
     grows, so it reads as the progress line running to the end. While it
     covers the whole bar, the reading progress underneath goes out. Nearly
     there, the panel's own line leaves that edge downwards
     (.mega-innen::before, the same 2 px violet, its glow above it) and
     reveals the panel behind it with a short flicker; the bar's line
     fades, and the bar carries no line while a panel is open. Shutting is
     the same film backwards: the light comes up and the panel goes behind
     it, the line stands across the bar, the reading progress comes back
     under it, and the line draws back to where the progress stands. On the
     bar, not on the panel: changing tabs keeps a panel open, so the bar
     does nothing then, the new panel's light runs down anew.

     Two means. Opening is keyframes, as the owner chose them in #220: they
     begin at «shut» whatever stood before, so every panel opens with its
     light, also one whose surface was whole while another was open.
     Shutting is transitions: each part has a value shut and a value open,
     and from open and at rest it goes back with the opening's curve
     mirrored, its wait counted from the other end of the .58s. Both
     engines start no transition for a part that keyframes are still
     moving, and all the keyframes end together, so leaving before the
     opening is over stops everything at once: nothing lingers, nothing
     shows that had not shown, the reading progress is back. (Not one
     progress in a custom property that everything follows: Safari does not
     paint a transition of a custom property, it jumps to the end. Measured
     on 11.11.2026, #224.)

     Seconds from the start, opening: the bar's line runs from 0 to .16
     and fades from .22 to .40, the reading progress goes out at .19,
     covered; the curtain from .12 to .49 with the flicker until .30, the
     panel's light travels with the curtain and fades from .488 to .58.
     The pointer waits .12s before all of it (as the panel does, above),
     the focus does not; shutting starts at once. Without a script it is
     the same, all CSS. With reduced motion none of it runs, the panel is
     simply there and the bar shows no light. */
  .nav-linie-licht {
    position: absolute; left: 0; right: 0; bottom: 0; height: 2px; background: var(--nl-violet);
    transform-origin: left center; transform: scaleX(0); pointer-events: none;
  }
  .mega-innen::before {
    content: ""; position: absolute; left: 0; right: 0; top: 0; height: 100%; z-index: 1; pointer-events: none; opacity: 0;
    background:
      linear-gradient(var(--nl-violet-a0) calc(100% - 96px), var(--nl-violet-a16) calc(100% - 2px), var(--nl-violet) calc(100% - 2px)),
      repeating-linear-gradient(var(--nl-violet-a0) 0 3px, var(--nl-violet-light-a18) 3px 4px);
    -webkit-mask-image: linear-gradient(transparent calc(100% - 96px), var(--nl-ink)); mask-image: linear-gradient(transparent calc(100% - 96px), var(--nl-ink));
  }
  /* All five end at the same moment, .58s after the first begins (those
     of the panel begin .12s later and take .46s): as long as one of them
     runs, leaving stops them all. Their keyframes stand at the seconds
     above: .16, .22 and .40 of .58 for the bar's line, .19 for the reading
     progress; .37 of .46 for the curtain, .054, .108 and .18 for the
     flicker, .368 for the panel's light. */
  @keyframes nl-mega-lauf {
    from { transform: scaleX(0); opacity: 1; animation-timing-function: cubic-bezier(.16, 1, .3, 1); }
    27.586% { transform: scaleX(1); opacity: 1; }
    37.931% { transform: scaleX(1); opacity: 1; animation-timing-function: ease-out; }
    68.966% { transform: scaleX(1); opacity: 0; }
    to { transform: scaleX(1); opacity: 0; }
  }
  @keyframes nl-mega-ohne { from { opacity: 1; animation-timing-function: step-end; } 32.759% { opacity: 0; } to { opacity: 0; } }
  @keyframes nl-mega-vorhang {
    from { clip-path: inset(0 0 100% 0); animation-timing-function: cubic-bezier(.3, .7, .2, 1); }
    80.435% { clip-path: inset(0 0 0 0); }
    to { clip-path: inset(0 0 0 0); }
  }
  @keyframes nl-mega-flackern { from { opacity: .5; } 11.739% { opacity: .12; } 23.478% { opacity: .85; } 39.13% { opacity: 1; } to { opacity: 1; } }
  @keyframes nl-mega-strahl {
    from { opacity: 1; transform: translateY(-100%); animation-timing-function: cubic-bezier(.3, .7, .2, 1); }
    80% { opacity: 1; transform: translateY(0); }
    to { opacity: 0; transform: translateY(0); }
  }
  /* The pointer waits .12s before a panel opens (above), the focus does not. */
  .mega-reiter > li:focus-within > .mega { --mega-warten: 0s; }
  .mega-reiter > li:hover > .mega { --mega-warten: .12s; }
  @media (prefers-reduced-motion: no-preference) {
    /* Shut, and the way there from open and at rest: the opening backwards.
       The flicker backwards begins at 0: while a transition waits it shows
       the first value of its curve, and the panel would dim the moment the
       pointer leaves. The second transition of the surface is for browsers
       that know linear(); the others keep the first and take the panel to
       half strength in one step. */
    .nav-linie-licht { opacity: 1; transition: transform .16s cubic-bezier(.7, 0, .84, 0) .42s, opacity .18s ease-in .18s; }
    .nav-linie { opacity: 1; transition: opacity 0s linear .39s; }
    .mega > .mega-innen {
      clip-path: inset(0 0 100% 0); opacity: .5;
      transition: clip-path .37s cubic-bezier(.8, 0, .7, .3) .09s, opacity 0s linear .28s;
      transition: clip-path .37s cubic-bezier(.8, 0, .7, .3) .09s, opacity .18s linear(0, .3 1%, .3 40%, 1.76 40%, 1.76 70%, 1 70%, 1) .28s;
    }
    .mega > .mega-innen::before { transform: translateY(-100%); opacity: 1; transition: transform .368s cubic-bezier(.8, 0, .7, .3) .092s, opacity .092s linear; }
    /* Open: the values at rest, and the keyframes that lead there. On the
       bar once while a panel is open, with the focus at once and with the
       pointer after its .12s. Not while Escape keeps the panels shut
       (data-mega="zu" for the focus on the tabs, data-zu for the pointed
       tab); a tab pointed at opens its panel in either case, so the
       pointer's rule asks only that this tab is not the one Escape shut.
       The reading progress keeps its own keyframes, which follow the
       scroll position, beside the ones that take it out: named again here,
       or the line would fall to nothing the moment a panel opens. */
    header.nav--mega:not([data-mega="zu"]):has(.mega-reiter > li:focus-within > .mega) .nav-linie-licht { transform: scaleX(1); opacity: 0; transition: none; animation: nl-mega-lauf .58s linear backwards; }
    header.nav--mega:not([data-mega="zu"]):has(.mega-reiter > li:focus-within > .mega) .nav-linie { opacity: 0; transition: none; animation: nl-fortschritt auto linear both, nl-mega-ohne .58s linear backwards; animation-timeline: scroll(root block), auto; }
    header.nav--mega:has(.mega-reiter > li:hover:not([data-zu]) > .mega) .nav-linie-licht { transform: scaleX(1); opacity: 0; transition: none; animation: nl-mega-lauf .58s linear .12s backwards; }
    header.nav--mega:has(.mega-reiter > li:hover:not([data-zu]) > .mega) .nav-linie { opacity: 0; transition: none; animation: nl-fortschritt auto linear both, nl-mega-ohne .58s linear .12s backwards; animation-timeline: scroll(root block), auto; }
    /* The panel behind the light: it hides only in the «from» of its
       keyframes and on its way back. .mega itself keeps its box. */
    .mega-reiter > li:is(:hover, :focus-within) > .mega > .mega-innen {
      clip-path: inset(0 0 0 0); opacity: 1; transition: none;
      animation:
        nl-mega-vorhang .46s linear calc(var(--mega-warten) + .12s) backwards,
        nl-mega-flackern .46s step-end calc(var(--mega-warten) + .12s) backwards;
    }
    .mega-reiter > li:is(:hover, :focus-within) > .mega > .mega-innen::before {
      transform: translateY(0); opacity: 0; transition: none;
      animation: nl-mega-strahl .46s linear calc(var(--mega-warten) + .12s) backwards;
    }
    /* Changing tabs: every other panel's surface is whole while the pointer
       or the focus is on the tabs. The one just left covers that way until
       the next one stands over it (above), also if it was left half open;
       the others are hidden and open with their keyframes all the same. */
    .mega-reiter:where(:hover, :has(> li:focus-within)) > li:where(:not(:hover, :focus-within)) > .mega > .mega-innen { clip-path: inset(0 0 0 0); opacity: 1; transition: none; }
    .mega-reiter:where(:hover, :has(> li:focus-within)) > li:where(:not(:hover, :focus-within)) > .mega > .mega-innen::before { transform: translateY(0); opacity: 0; transition: none; }
    /* Escape shuts at once (above), the light and the curtain with it. Last, so it wins. */
    header.nav--mega[data-mega="zu"]:not(:has(.mega-reiter > li:hover:not([data-zu]))) :is(.nav-linie, .nav-linie-licht),
    header.nav--mega:has(.mega-reiter > li[data-zu]) :is(.nav-linie, .nav-linie-licht) { transition: none; }
    header.nav[data-mega="zu"] .mega-reiter > li:not(:hover) > .mega > .mega-innen,
    .mega-reiter > li[data-zu] > .mega > .mega-innen { clip-path: inset(0 0 100% 0); opacity: .5; transition: none; animation: none; }
    header.nav[data-mega="zu"] .mega-reiter > li:not(:hover) > .mega > .mega-innen::before,
    .mega-reiter > li[data-zu] > .mega > .mega-innen::before { transform: translateY(-100%); opacity: 1; transition: none; animation: none; }
  }

  @media (prefers-reduced-motion: reduce) {
    .mega { transform: none; }
    header.nav--mega, .brand-pfeil, .brand-wort, .mega-pfeil { transition: none; }
  }

  /* --- the three levels of the button in the content (ADR 0067) ----------
     Every button moves the same way again, the bracket button of DESIGN.md
     chapter 6 (owner's decision of 20.10.2026): the corners close into a
     1px frame in 0.35s while a surface slides in from the left in 0.45s.
     The levels differ by that surface (owner's wish of 19.10.2026: the
     pointed look of one level is never the resting look of the next higher
     one). The button itself stays the shared one of base.css in the dress
     of site.css; this is a dress, not a second button. The only hold this
     package takes on buttons of shared blocks, and only for their motion:
     everything under :root:has(header.nav--mega), the bar of this package,
     as --kopf-h above. 0,5,1 and up beats site.css (.bbtn:hover .fill
     0,3,0) and base.css (.bbtn:hover 0,2,0). A browser without :has()
     shows the dress of 15.10.2026, usable all the same. */
  :root:has(header.nav--mega) .bbtn .fill { opacity: 1; transform: scaleX(0); transform-origin: left; transition: transform .45s var(--ease-out); }
  :root:has(header.nav--mega) .bbtn:hover .fill { transform: scaleX(1); }
  :root:has(header.nav--mega) .bbtn .deco { transition: width .35s var(--ease-out), height .35s var(--ease-out); }
  :root:has(header.nav--mega) .bbtn:hover .deco, :root:has(header.nav--mega) .bbtn[aria-pressed="true"] .deco { width: 50%; height: 50%; }
  /* First level: ink slides in over the violet; on dark ground on-dark
     with ink on it, not ink on ink. */
  :root:has(header.nav--mega) .dark .bbtn.solid .fill { background: var(--nl-on-dark); }
  :root:has(header.nav--mega) .dark .bbtn.solid:hover, :root:has(header.nav--mega) .dark .bbtn.solid:hover .deco { color: var(--nl-ink); }
  /* Second level: only the light violet tint slides in (violet-light-a18
     on dark ground) and the text turns violet-fill (violet-light on dark):
     5.0:1 and 5.2:1. A pressed switch keeps the closed frame. */
  :root:has(header.nav--mega) .bbtn:not(.solid) .fill { background: var(--nl-violet-tint); }
  :root:has(header.nav--mega) .dark .bbtn:not(.solid) .fill { background: var(--nl-violet-light-a18); }
  :root:has(header.nav--mega) .bbtn:not(.solid):hover { color: var(--nl-violet-fill); }
  :root:has(header.nav--mega) .dark .bbtn:not(.solid):hover { color: var(--nl-violet-light); }
  /* «Erstgespräch» in bar and menu stands on its white surface already:
     there only the frame closes and the text turns violet, no surface
     slides in (owner, 20.10.2026), so it stands apart from the page. */
  :root:has(header.nav--mega) .nav-knopf .fill { display: none; }
  /* The box on /leistungen is a second level pointed through its summary. */
  :root:has(header.nav--mega) .schachtel-auf > summary:hover .schachtel-knopf .fill { transform: scaleX(1); }
  /* Third level: the text link .lbtn (site.css) draws its line in 0.45s. */

  /* --- measure of rich text (audit 24.10.2026) ---------------------------
     A paragraph of running text on nuvolead.ch runs no wider than about 70
     characters: on /ueber a line held 105. Only this package, under the mark
     of its bar; the customer sites keep their text as it is. */
  :root:has(header.nav--mega) .rt > p { max-width: 70ch; }

  /* --- head of a subpage without a photo (#217, ADR 0094) ----------------
     Owner, 10.11.2026: the fade over the photo «sieht kacke aus», after
     cmdweb.ch. No head of nuvolead.ch carries a photo any more (ADR 0092),
     and without one the shared head left most of a screen empty with the
     title at its foot. Here the title stands right under the bar, the page
     begins after it, and the ground is the footer's grid of square dots,
     fading in from the left so the text keeps a calm ground. */
  :root:has(header.nav--mega) .blk-hero:has(.media > .nl-bildflaeche) { min-height: 0; align-items: start; border-bottom: 1px solid var(--nl-line); }
  :root:has(header.nav--mega) .blk-hero:has(.media > .nl-bildflaeche) .media { background: none; }
  :root:has(header.nav--mega) .blk-hero .media > .nl-bildflaeche { display: none; }
  :root:has(header.nav--mega) .blk-hero:has(.media > .nl-bildflaeche) .media::after {
    background: linear-gradient(90deg, var(--nl-line-2) 2px, transparent 2px) 0 0 / 32px 32px;
    -webkit-mask-image: linear-gradient(var(--nl-ink) 2px, transparent 2px), linear-gradient(100deg, transparent 35%, var(--nl-ink) 100%);
    mask-image: linear-gradient(var(--nl-ink) 2px, transparent 2px), linear-gradient(100deg, transparent 35%, var(--nl-ink) 100%);
    -webkit-mask-size: 32px 32px, 100% 100%; mask-size: 32px 32px, 100% 100%;
    -webkit-mask-composite: source-in; mask-composite: intersect;
  }
  /* A long title (an article's question) stood five lines high at the
     shared size and measure; here it runs wider and a little smaller. */
  :root:has(header.nav--mega) .blk-hero:has(.media > .nl-bildflaeche) h1 { max-width: 19ch; font-size: clamp(40px, 5.2vw, 80px); }
  :root:has(header.nav--mega) .blk-hero:has(.media > .nl-bildflaeche) .content { padding-block: calc(var(--kopf-h, 68px) + clamp(48px, 7vw, 112px)) clamp(40px, 5vw, 72px); }

  /* --- the way back above the title (ADR 0095, #219) -----------------------
     «Startseite / Wissenswertes» on a page of the second level: small, muted,
     each a link with the line of a text link and the 44 px of every
     action. The page itself is not named, its title stands right below. */
  .nl-krumen { display: flex; flex-wrap: wrap; align-items: center; gap: 0 10px; font-size: var(--fs-label); color: var(--nl-muted); }
  .nl-krumen a { display: inline-flex; align-items: center; min-height: var(--tap, 44px); min-width: var(--tap, 44px); color: var(--nl-ink); }
  .nl-krumen a:hover .u::after, .nl-krumen a:focus-visible .u::after { transform: scaleX(1); transform-origin: left; }

  /* --- link cards as white tiles (ADR 0095, #219) -------------------------
     Cards that lead somewhere (Einzugsgebiet, Wissenswertes, further
     places, further offers) were text on the grey page. White is what one
     touches (ADR 0075): each is a white tile and the whole tile is the
     link (Sektionen.tsx, cards). The line under the last word draws itself
     as on every text link; there is no hover effect on the tile itself
     (DESIGN.md chapter 7). Cards without a link stay the shared cards. */
  .nl-kachel { display: grid; grid-template-rows: auto 1fr auto; gap: var(--s-3); min-height: var(--tap, 44px); padding: 22px 24px 20px; background: var(--nl-card); border: 1px solid var(--nl-line); color: var(--nl-ink); }
  .nl-kachel-titel { margin: 0; font-size: var(--fs-card); font-weight: 600; letter-spacing: -0.02em; line-height: 1.3; }
  .nl-kachel-text { margin: 0; font-size: var(--fs-text); color: var(--nl-ink-2); }
  .nl-kachel-weiter { justify-self: start; align-self: end; display: inline-flex; align-items: center; gap: 8px; padding-top: 6px; font-size: 15px; color: var(--nl-ink); }
  .nl-kachel-weiter svg { flex: none; width: 12px; height: 12px; transition: transform .45s var(--ease-out); }
  .nl-kachel-weiter svg path { stroke: currentColor; stroke-width: 1.6; fill: none; }
  .nl-kachel:hover .u::after, .nl-kachel:focus-visible .u::after { transform: scaleX(1); transform-origin: left; }
  @media (hover: hover) and (prefers-reduced-motion: no-preference) { .nl-kachel:hover .nl-kachel-weiter svg { transform: translate(3px, -3px); } }
  .nl-kachel:focus-visible { outline: 2px solid var(--nl-violet-fill); outline-offset: 2px; }
  @media (prefers-reduced-motion: reduce) { .nl-kachel-weiter svg { transition: none; } }

  /* --- project cards with floating screens (ADR 0095, #219) ---------------
     After the reference cards of vierless.de and the framed films of
     filmcrew.one, in the owner's terms of 10.11.2026: angular, no laptop
     and no phone but two floating rectangles in the format of a screen and
     of a phone, violet the only colour. A card is white (what one touches)
     or, with tone dark, black (the result), like the price cards
     (ADR 0075): own classes, never .dark, the bar measures .dark surfaces.
     The stage clips: a tilted screen never reaches past the card. The
     screens stand tilted without a script; floating is the animation below
     and rests with reduced motion; --pk-x and --pk-y come from Neigung.tsx
     and turn them towards the pointer. */
  .pkarten { display: grid; gap: clamp(16px, 2vw, 28px); margin-top: var(--s-10); }
  .pkarte { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); background: var(--nl-card); border: 1px solid var(--nl-line); color: var(--nl-ink); }
  .pkarte-text { display: flex; flex-direction: column; align-items: flex-start; gap: 16px; padding: clamp(24px, 3.2vw, 52px); }
  .pkarte-name { margin: 0; font-size: 17px; font-weight: 600; letter-spacing: -0.01em; line-height: 1.3; }
  .pkarte-satz { margin: 0; max-width: 24ch; font-size: clamp(22px, 2.25vw, 32px); font-weight: 500; letter-spacing: -0.025em; line-height: 1.16; text-wrap: balance; }
  /* Trade, place and date as the tag line of the former tiles (.card .meta
     and .card .tag in site.css): a tag with the violet square, then plain
     words. Not boxes of their own, which looked like buttons that do
     nothing (owner, 11.11.2026). */
  .pkarte-angaben { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin: 0; font-size: 14px; line-height: 1.4; color: var(--nl-muted); }
  .pkarte-etikett { position: relative; padding: 3px 9px 3px 16px; border: 1px solid var(--nl-line); color: var(--nl-ink); }
  .pkarte-etikett::before { content: ""; position: absolute; left: 7px; top: 50%; width: 4px; height: 4px; background: var(--nl-violet); transform: translateY(-50%); }
  .pkarte-text > a { margin-top: auto; }
  /* The stage: a violet light behind the screens, where the pointer is or,
     without one, behind the screens (owner, 11.11.2026: «ein violetter
     Glow» or «die Punkte im Hintergrund leuchten lassen»; both). */
  .pkarte-buehne {
    position: relative; display: grid; grid-template-columns: minmax(0, 1fr); align-content: center; overflow: hidden; background-color: var(--nl-paper-2);
    background-image: radial-gradient(circle 420px at calc(58% + var(--pk-x, 0) * 34%) calc(52% + var(--pk-y, 0) * 34%), var(--nl-violet-a16), var(--nl-violet-a0));
  }
  /* The picture: the box of fixed format the screens stand in. The stage
     itself has no format of its own, so it is as tall as its card: where
     the text of a card is taller than the picture (a long sentence on a
     window of 901 to about 1100 px) the ground, the dots and the light
     reach the card's lower edge and the picture stands in the middle
     (owner, 11.11.2026: the stage «geht nicht auf die ganze card höhe»).
     Above the lit dots, which are the stage's ::after. */
  .pkarte-bild { position: relative; z-index: 1; display: block; width: 100%; aspect-ratio: 16 / 9.6; perspective: 1500px; }
  /* The ground of the stage: the grid of square dots of head and footer. */
  .pkarte-buehne::before {
    content: ""; position: absolute; inset: 0;
    background: linear-gradient(90deg, var(--nl-line-2) 2px, transparent 2px) 0 0 / 32px 32px;
    -webkit-mask-image: linear-gradient(var(--nl-ink) 2px, transparent 2px); mask-image: linear-gradient(var(--nl-ink) 2px, transparent 2px);
    -webkit-mask-size: 32px 32px; mask-size: 32px 32px;
  }
  /* The same grid in violet, only where the light falls: the dots light up. */
  .pkarte-buehne::after {
    content: ""; position: absolute; inset: 0; pointer-events: none;
    background: linear-gradient(90deg, var(--nl-violet) 2px, transparent 2px) 0 0 / 32px 32px;
    -webkit-mask-image: linear-gradient(var(--nl-ink) 2px, transparent 2px), radial-gradient(circle 300px at calc(58% + var(--pk-x, 0) * 34%) calc(52% + var(--pk-y, 0) * 34%), var(--nl-ink), transparent);
    mask-image: linear-gradient(var(--nl-ink) 2px, transparent 2px), radial-gradient(circle 300px at calc(58% + var(--pk-x, 0) * 34%) calc(52% + var(--pk-y, 0) * 34%), var(--nl-ink), transparent);
    -webkit-mask-size: 32px 32px, 100% 100%; mask-size: 32px 32px, 100% 100%;
    -webkit-mask-composite: source-in; mask-composite: intersect;
  }
  .pkarte-schirm { position: absolute; z-index: 1; display: block; transition: transform .45s var(--ease-out); }
  .pkarte-schirm--breit { left: 12%; top: 10%; width: 62%; aspect-ratio: 16 / 10; transform: rotateY(calc(-11deg + var(--pk-x, 0) * 8deg)) rotateX(calc(4deg + var(--pk-y, 0) * -6deg)); }
  .pkarte-schirm--foto { left: 4%; bottom: 8%; width: 22%; aspect-ratio: 4 / 3; z-index: 2; transform: translate3d(calc(var(--pk-x, 0) * 8px), calc(var(--pk-y, 0) * -6px), 50px) rotateY(calc(-11deg + var(--pk-x, 0) * 9deg)) rotateX(calc(4deg + var(--pk-y, 0) * -6deg)); }
  .pkarte-schirm--hoch { right: 6%; bottom: 8%; width: 16.5%; aspect-ratio: 390 / 844; z-index: 2; transform: translate3d(calc(var(--pk-x, 0) * -10px), calc(var(--pk-y, 0) * -8px), 70px) rotateY(calc(-11deg + var(--pk-x, 0) * 10deg)) rotateX(calc(4deg + var(--pk-y, 0) * -7deg)); }
  .pkarte-flaeche { display: block; width: 100%; height: 100%; overflow: hidden; background: var(--nl-card); border: 1px solid var(--nl-line-2); box-shadow: 0 30px 54px -24px var(--nl-ink-a60); transition: box-shadow .45s var(--ease-out); }
  .pkarte-flaeche img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: top center; }
  @media (prefers-reduced-motion: no-preference) {
    .pkarte-flaeche { animation: pkarte-schweben 7s ease-in-out infinite alternate; }
    .pkarte-schirm--hoch .pkarte-flaeche { animation-duration: 5.2s; animation-delay: -2.1s; }
    .pkarte-schirm--foto .pkarte-flaeche { animation-duration: 6.1s; animation-delay: -4s; }
  }
  @keyframes pkarte-schweben { from { transform: translate3d(0, -6px, 0); } to { transform: translate3d(0, 6px, 0); } }
  @media (hover: hover) { .pkarte:hover .pkarte-flaeche { box-shadow: 0 44px 70px -26px var(--nl-ink-a72); } }
  .pkarte--dunkel { background: var(--nl-ink); border-color: var(--nl-ink); color: var(--nl-on-dark); }
  .pkarte--dunkel .pkarte-angaben { color: var(--nl-on-dark-muted); }
  .pkarte--dunkel .pkarte-etikett { border-color: var(--nl-dark-line); color: var(--nl-on-dark); }
  .pkarte--dunkel .pkarte-etikett::before { background: var(--nl-violet-light); }
  .pkarte--dunkel .pkarte-buehne { background-color: var(--nl-dark-2); background-image: radial-gradient(circle 460px at calc(58% + var(--pk-x, 0) * 34%) calc(52% + var(--pk-y, 0) * 34%), var(--nl-violet-a38), var(--nl-violet-a0)); }
  .pkarte--dunkel .pkarte-buehne::before { background-image: linear-gradient(90deg, var(--nl-dark-line) 2px, transparent 2px); }
  .pkarte--dunkel .pkarte-buehne::after { background-image: linear-gradient(90deg, var(--nl-violet-light) 2px, transparent 2px); }
  .pkarte--dunkel .pkarte-flaeche { border-color: var(--nl-dark-line); box-shadow: 0 30px 54px -20px var(--nl-shadow-a45); }
  /* The button on a black card is the bracket button of a dark section
     (the rules for .dark above), not one of its own: light text, the
     violet veil, light violet while pointed. The card cannot wear .dark,
     the bar measures that. */
  :root:has(header.nav--mega) .pkarte--dunkel .bbtn:not(.solid) { color: var(--nl-on-dark); }
  :root:has(header.nav--mega) .pkarte--dunkel .bbtn:not(.solid) .fill { background: var(--nl-violet-light-a18); }
  :root:has(header.nav--mega) .pkarte--dunkel .bbtn:not(.solid):hover { color: var(--nl-violet-light); }
  @media (max-width: 900px) {
    .pkarte { grid-template-columns: minmax(0, 1fr); }
    .pkarte-buehne { order: -1; }
    .pkarte-bild { aspect-ratio: 16 / 10.4; }
    .pkarte-schirm--breit { left: 11%; width: 63%; }
    .pkarte-schirm--foto { left: 3%; width: 24%; }
    .pkarte-schirm--hoch { right: 5%; width: 18%; }
  }
  @media (prefers-reduced-motion: reduce) { .pkarte-schirm, .pkarte-flaeche { transition: none; } }
  /* The opening of a project page: the website it is about beside the
     title, on the same floating surfaces, without a stage of its own: the
     head's grid of dots is the ground, only the violet light stays. Without
     a ground there is no edge to clip at either: clipped, the phone's
     shadow ended in a straight line beside it on a window of about 940 px
     (the head itself clips what leaves the section). */
  .pkarte-kopf .pkarte-buehne { overflow: visible; background-color: transparent; background-image: radial-gradient(closest-side circle at calc(52% + var(--pk-x, 0) * 12%) calc(50% + var(--pk-y, 0) * 12%), var(--nl-violet-a16), var(--nl-violet-a0)); }
  .pkarte-kopf .pkarte-buehne::before, .pkarte-kopf .pkarte-buehne::after { display: none; }
  @media (min-width: 901px) {
    :root:has(header.nav--mega) .blk-hero .content:has(> .pkarte-kopf) { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); column-gap: clamp(24px, 4vw, 64px); align-items: start; }
    :root:has(header.nav--mega) .blk-hero .content:has(> .pkarte-kopf) > * { grid-column: 1; }
    :root:has(header.nav--mega) .blk-hero .content:has(> .pkarte-kopf) > .pkarte-kopf { grid-column: 2; grid-row: 1 / span 8; align-self: center; }
  }

  /* --- contact block with the arrow (draft Web-Fuss) -------------------- */
  section.blk:has(> .wrap > .contact--pfeil) { overflow: hidden; }
  .contact--pfeil {
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    grid-template-areas: "titel flug" "seite flug";
    align-items: center; row-gap: 28px;
  }
  .contact--pfeil :is(h2, h3) { grid-area: titel; max-width: 14ch; line-height: .95; }
  .contact--pfeil .side { grid-area: seite; }
  .flug { grid-area: flug; position: relative; justify-self: end; width: min(100%, 300px); aspect-ratio: 1; color: var(--nl-violet); }
  /* ADR 0095, #219: the person in the block. The stage of the project cards
     again: a violet light and the lit grid of dots behind a floating
     surface, here Ron's portrait, his name on a tag in front, the arrow
     small and flying out of the picture. --pk-x and --pk-y come from
     Neigung.tsx (the pointer anywhere in the block); without a script and
     with reduced motion everything stands still. */
  .nl-portraet {
    grid-area: flug; position: relative; justify-self: end; width: min(100%, 440px); aspect-ratio: 1 / 1.06; perspective: 1500px;
    background-image: radial-gradient(closest-side circle at calc(50% + var(--pk-x, 0) * 14%) calc(46% + var(--pk-y, 0) * 14%), var(--nl-violet-a38), var(--nl-violet-a0));
  }
  .nl-portraet::before {
    content: ""; position: absolute; inset: 0; pointer-events: none;
    background: linear-gradient(90deg, var(--nl-violet-light) 2px, transparent 2px) 0 0 / 32px 32px;
    -webkit-mask-image: linear-gradient(var(--nl-ink) 2px, transparent 2px), radial-gradient(closest-side circle at calc(50% + var(--pk-x, 0) * 14%) calc(46% + var(--pk-y, 0) * 14%), var(--nl-ink), transparent);
    mask-image: linear-gradient(var(--nl-ink) 2px, transparent 2px), radial-gradient(closest-side circle at calc(50% + var(--pk-x, 0) * 14%) calc(46% + var(--pk-y, 0) * 14%), var(--nl-ink), transparent);
    -webkit-mask-size: 32px 32px, 100% 100%; mask-size: 32px 32px, 100% 100%;
    -webkit-mask-composite: source-in; mask-composite: intersect;
  }
  .nl-portraet-flaeche {
    position: absolute; left: 16%; top: 5%; width: 60%; aspect-ratio: 4 / 5; overflow: hidden;
    border: 1px solid var(--nl-dark-line); box-shadow: 0 34px 60px -22px var(--nl-shadow-a45);
    transform: rotateY(calc(-12deg + var(--pk-x, 0) * 9deg)) rotateX(calc(4deg + var(--pk-y, 0) * -6deg)); transition: transform .45s var(--ease-out);
  }
  .nl-portraet-flaeche img { display: block; width: 100%; height: 100%; object-fit: cover; }
  .nl-portraet-schild {
    position: absolute; left: 4%; bottom: 9%; display: grid; gap: 2px; margin: 0; padding: 12px 16px; background: var(--nl-card); color: var(--nl-ink); font-size: 15px; line-height: 1.3;
    box-shadow: 0 22px 40px -18px var(--nl-shadow-a45);
    transform: translate3d(calc(var(--pk-x, 0) * 10px), calc(var(--pk-y, 0) * -8px), 60px) rotateY(calc(-12deg + var(--pk-x, 0) * 9deg)) rotateX(calc(4deg + var(--pk-y, 0) * -6deg)); transition: transform .45s var(--ease-out);
  }
  .nl-portraet-schild b { font-size: 17px; font-weight: 700; letter-spacing: -0.01em; }
  .nl-portraet-schild span { color: var(--nl-muted); }
  .nl-portraet .flug { position: absolute; right: 2%; top: 3%; width: 24%; }
  @media (prefers-reduced-motion: no-preference) {
    .nl-portraet-flaeche img { animation: nl-portraet-schweben 7s ease-in-out infinite alternate; }
  }
  @keyframes nl-portraet-schweben { from { transform: scale(1.04) translate3d(0, -4px, 0); } to { transform: scale(1.04) translate3d(0, 4px, 0); } }
  @media (prefers-reduced-motion: reduce) { .nl-portraet-flaeche, .nl-portraet-schild { transition: none; } }
  .flug svg { position: absolute; inset: 0; width: 100%; height: 100%; }
  .flug .schatten { opacity: .12; transition: opacity .6s ease; }
  .flug .pfeil { transition: transform .9s var(--ease-expo); }
  .blk:hover .flug .pfeil, .blk:focus-within .flug .pfeil { transform: translate(28px, -28px); }
  .blk:hover .flug .schatten, .blk:focus-within .flug .schatten { opacity: .22; }
  @media (max-width: 900px) {
    .contact--pfeil { grid-template-columns: 1fr; grid-template-areas: "titel" "seite" "flug"; }
    .flug { justify-self: start; width: min(40%, 160px); }
    .nl-portraet { justify-self: start; width: min(86%, 340px); }
  }
  @media (prefers-reduced-motion: reduce) {
    .blk:hover .flug .pfeil, .blk:focus-within .flug .pfeil { transform: none; }
  }

  /* --- footer of nuvolead.ch (draft Web-Fuss) --------------------------- */
  .site-footer.fuss-nuvolead { border-top: 0; padding: 72px 0 28px; position: relative; isolation: isolate; }
  /* The ground of the footer (#217, ADR 0094): a grid of square dots, two
     pixels every 32, and the same grid in light violet where the light
     falls. Vertical lines as the picture, horizontal lines as the mask:
     what is left of both are squares. Without a script a band of light
     drifts through; with a fine pointer it follows the pointer
     (FussLicht.tsx); with reduced motion it rests at the bottom. */
  .fuss-nuvolead::before, .fuss-nuvolead::after {
    content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
    background-image: linear-gradient(90deg, var(--fuss-punkt) 2px, transparent 2px); background-size: 32px 32px;
  }
  .fuss-nuvolead::before {
    --fuss-punkt: var(--nl-dark-line);
    -webkit-mask-image: linear-gradient(var(--nl-ink) 2px, transparent 2px); mask-image: linear-gradient(var(--nl-ink) 2px, transparent 2px);
    -webkit-mask-size: 32px 32px; mask-size: 32px 32px;
  }
  .fuss-nuvolead::after {
    --fuss-punkt: var(--nl-violet-light);
    -webkit-mask-image: linear-gradient(var(--nl-ink) 2px, transparent 2px), radial-gradient(circle closest-side, var(--nl-ink), transparent);
    mask-image: linear-gradient(var(--nl-ink) 2px, transparent 2px), radial-gradient(circle closest-side, var(--nl-ink), transparent);
    -webkit-mask-size: 32px 32px, 520px 520px; mask-size: 32px 32px, 520px 520px;
    -webkit-mask-repeat: repeat, no-repeat; mask-repeat: repeat, no-repeat;
    -webkit-mask-composite: source-in; mask-composite: intersect;
    -webkit-mask-position: 0 0, 50% 100%; mask-position: 0 0, 50% 100%;
    animation: fuss-licht 18s ease-in-out infinite alternate;
  }
  @keyframes fuss-licht {
    from { -webkit-mask-position: 0 0, -260px 30%; mask-position: 0 0, -260px 30%; }
    to { -webkit-mask-position: 0 0, calc(100% + 260px) 70%; mask-position: 0 0, calc(100% + 260px) 70%; }
  }
  .fuss-nuvolead[data-licht="an"]::after {
    animation: none;
    -webkit-mask-position: 0 0, calc(var(--fuss-licht-x, 50%) - 260px) calc(var(--fuss-licht-y, 100%) - 260px);
    mask-position: 0 0, calc(var(--fuss-licht-x, 50%) - 260px) calc(var(--fuss-licht-y, 100%) - 260px);
  }
  @media (prefers-reduced-motion: reduce) { .fuss-nuvolead::after { animation: none; } }
  .fuss-innen { display: flex; flex-direction: column; gap: 56px; }
  .fuss-spalten { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 32px 48px; }
  /* The mark opens the footer: a row of its own, a column from 1100 px. */
  .fuss-marke { grid-column: 1 / -1; gap: 12px; }
  .fuss-logo { display: inline-flex; align-items: center; gap: 10px; align-self: flex-start; min-height: var(--tap, 44px); font-size: 22px; font-weight: 700; letter-spacing: -0.02em; color: var(--nl-on-dark); }
  .fuss-pfeil { width: 32px; height: 32px; color: var(--nl-violet-light); transition: transform .6s var(--ease-expo); }
  .fuss-logo:hover .fuss-pfeil, .fuss-logo:focus-visible .fuss-pfeil { transform: translate(4px, -4px); }
  .fuss-satz { margin: 0; max-width: 16ch; font-size: clamp(22px, 2.2vw, 30px); line-height: 1.1; font-weight: 600; letter-spacing: -0.02em; color: var(--nl-on-dark); }
  @media (min-width: 1100px) {
    .fuss-spalten { grid-template-columns: minmax(0, 1.5fr) minmax(0, 1.7fr) minmax(0, 1fr) minmax(0, 1.2fr) minmax(0, 1fr); }
    .fuss-spalten .fuss-marke { grid-column: auto; }
    .fuss-spalten .fuss-gruppe--breit { grid-column: auto; }
  }
  @media (prefers-reduced-motion: reduce) { .fuss-pfeil { transition: none; } .fuss-logo:hover .fuss-pfeil, .fuss-logo:focus-visible .fuss-pfeil { transform: none; } }
  .fuss-gruppe { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
  @media (min-width: 720px) { .fuss-gruppe--breit { grid-column: span 2; } }
  .fuss-titel { font-size: var(--fs-label); letter-spacing: .08em; text-transform: uppercase; white-space: nowrap; color: var(--nl-on-dark-muted); border-bottom: 1px solid var(--nl-dark-line); padding-bottom: 10px; margin-bottom: 8px; }
  .fuss-seiten { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 24px; }
  /* The local pages under «In Ihrer Nähe» (#214), one under the other. */
  .fuss-orte { display: grid; }
  .fuss-link, .fuss-zeile { display: inline-flex; align-items: center; min-height: var(--tap, 44px); }
  /* A short page name («Fotos», 39px) is a tap area all the same (A2). */
  .fuss-link { justify-self: start; align-self: flex-start; min-width: var(--tap, 44px); }
  .fuss-link:hover .u::after { transform: scaleX(1); transform-origin: left; }
  .fuss-mail .u { overflow-wrap: anywhere; }
  .fuss-klein { font-size: 15px; color: var(--nl-on-dark-muted); }
  /* The floor was 80px: at 320px "nuvolead." needed 336px of a 280px
     column and the whole page scrolled sideways. 17vw alone fits. */
  .fuss-wort { font-size: clamp(48px, 17vw, 250px); line-height: .8; font-weight: 700; letter-spacing: -0.05em; color: var(--nl-on-dark); }
  .fuss-wort .fuss-punkt { color: var(--nl-violet-light); }
  /* Each letter lifts under the pointer. The outer span keeps its place,
     so the pointer does not lose the letter it lifted. */
  .fuss-b { display: inline-block; }
  /* The letters are boxes now and would break onto a second line where the
     word does not fit; it stays one word, sized to fit by 17vw above, and
     the layout check reports it past the edge (Gegenprobe in layout.spec). */
  .fuss-wort { white-space: nowrap; }
  .fuss-b > span { display: inline-block; transition: transform .5s var(--ease-expo); }
  @media (hover: hover) and (prefers-reduced-motion: no-preference) { .fuss-b:hover > span { transform: translateY(-7%); } }
  .fuss-unten { display: flex; flex-wrap: wrap; gap: 12px 32px; justify-content: space-between; align-items: center; border-top: 1px solid var(--nl-dark-line); padding-top: 8px; font-size: 14px; color: var(--nl-on-dark-muted); }
  .fuss-recht { display: flex; flex-wrap: wrap; align-items: center; gap: 0 24px; }

  /* --- WhatsApp on the phone (owner's decision of 28.10.2026, #174, ADR 0069)
     The round green button of the former nuvolead.ch, bottom right, 48px
     (A2), over the safe area. Only on the phone, where the link opens the
     app: on a desktop it stays away (display: none), as the owner wished.
     Green is WhatsApp's own mark, kept as the package's token
     --nuvolead-whatsapp (index.ts), the one place a third colour stands
     beside violet and orange; the ring of ink-a35 sets the button off from
     light ground. Below the full screen menu (z 60) and away while it is
     open. A plain link: nothing here needs a script (ADR 0012). */
  .wa-knopf { display: none; }
  @media (max-width: 900px) {
    .wa-knopf {
      position: fixed; z-index: 50; right: 16px; bottom: calc(16px + var(--sicher-b, 0px));
      display: flex; align-items: center; justify-content: center; width: 48px; height: 48px; border-radius: 50%;
      background: var(--nuvolead-whatsapp); color: var(--nl-card);
      box-shadow: 0 0 0 1px var(--nl-ink-a35), 0 10px 18px -6px var(--nl-ink-a35);
      transition: transform .25s var(--ease-out);
    }
    .wa-knopf:hover, .wa-knopf:focus-visible { transform: scale(1.08); }
    .wa-knopf:focus-visible { outline: 2px solid var(--nl-ink); outline-offset: 3px; }
    body:has(.mobile-menu:target) .wa-knopf { display: none; }
  }
  @media (prefers-reduced-motion: reduce) { .wa-knopf, .wa-knopf:hover { transition: none; transform: none; } }

  /* --- Contact corner on the computer (owner's decision of 09.11.2026, #203,
     ADR 0082), after the contact card of cmdweb.ch: Ron's face and three
     ways, bottom right from 901 px, where the WhatsApp button ends. White
     like everything one touches, square, the link of the first talk on the
     second level (one full button per screen, ADR 0067), the two other ways
     as square signs of 52 px. Without a script it is the closed tab, opened
     by hand; the script only adds when it shows (Kontaktecke.tsx). While
     the script is allowed but has not run, it waits hidden, and after four
     seconds the tab comes anyway (ADR 0012). Below the menu (z 60). */
  .kontaktecke { display: none; }
  @media (min-width: 901px) {
    .kontaktecke {
      position: fixed; z-index: 50; right: 24px; bottom: 24px; display: block;
      width: min(432px, calc(100vw - 48px));
      background: var(--nl-card); color: var(--nl-ink);
      box-shadow: 0 0 0 1px var(--nl-line), 0 18px 40px -16px var(--nl-ink-a35);
      transition: opacity .3s var(--ease-out), transform .3s var(--ease-out), visibility 0s;
    }
    .kontaktecke[data-zustand="weg"] {
      opacity: 0; visibility: hidden; transform: translateY(12px); pointer-events: none;
      transition: opacity .3s var(--ease-out), transform .3s var(--ease-out), visibility 0s .3s;
    }
    .kontaktecke-kopf { display: flex; align-items: center; gap: 14px; min-height: 72px; padding: 12px 8px 12px 12px; cursor: pointer; list-style: none; }
    .kontaktecke-kopf::-webkit-details-marker { display: none; }
    .kontaktecke-kopf:focus-visible { outline: 2px solid var(--nl-violet); outline-offset: -2px; }
    .kontaktecke-bild { flex: none; width: 48px; height: 48px; object-fit: cover; object-position: 50% 20%; background: var(--nl-paper); }
    .kontaktecke-wer { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
    .kontaktecke-wer b { font-size: 16px; font-weight: 600; line-height: 1.3; }
    .kontaktecke-wer span { font-size: 14px; line-height: 1.4; color: var(--nl-muted); }
    .kontaktecke-zeichen { flex: none; position: relative; width: 44px; height: 44px; }
    .kontaktecke-zeichen::before {
      content: ""; position: absolute; inset: 0; margin: auto; width: 14px; height: 14px;
      background: linear-gradient(currentColor, currentColor) center / 100% 1.5px no-repeat, linear-gradient(currentColor, currentColor) center / 1.5px 100% no-repeat;
      transition: transform .25s var(--ease-out);
    }
    .kontaktecke[open] .kontaktecke-zeichen::before { transform: rotate(45deg); }
    .kontaktecke-kopf:hover .kontaktecke-zeichen { color: var(--nl-violet-fill); }
    .kontaktecke-inhalt { padding: 20px 24px 24px; border-top: 1px solid var(--nl-line); }
    .kontaktecke-frage { margin: 0; font-size: 20px; font-weight: 600; line-height: 1.3; }
    .kontaktecke-text { margin: 6px 0 20px; font-size: 16px; line-height: 1.5; color: var(--nl-muted); }
    .kontaktecke-wege { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
    :root:has(header.nav--mega) .kontaktecke-wege .bbtn { flex: 1 1 auto; padding: 0 20px; }
    .kontaktecke-weg {
      flex: none; display: flex; align-items: center; justify-content: center; width: 52px; height: 52px;
      color: var(--nl-ink); box-shadow: inset 0 0 0 1px var(--nl-ink-a35); transition: color .25s ease, box-shadow .25s ease;
    }
    .kontaktecke-weg:hover, .kontaktecke-weg:focus-visible { color: var(--nl-violet-fill); box-shadow: inset 0 0 0 1px var(--nl-violet); }
    .kontaktecke-weg:focus-visible { outline: 2px solid var(--nl-ink); outline-offset: 3px; }
    body:has(.mobile-menu:target) .kontaktecke { display: none; }
  }
  @media (min-width: 901px) and (scripting: enabled) {
    .kontaktecke:not([data-zustand]) { visibility: hidden; animation: kontaktecke-notfall 0s 4s forwards; }
  }
  @keyframes kontaktecke-notfall { to { visibility: visible; } }
  /* Without a script the tab stays over the page to its end: the legal
     links of the footer keep their place above it. */
  @media (min-width: 901px) and (scripting: none) {
    .fuss-nuvolead .fuss-unten { padding-bottom: 96px; }
  }
  @media (prefers-reduced-motion: reduce) {
    .kontaktecke, .kontaktecke[data-zustand="weg"], .kontaktecke-zeichen::before { transition: none; }
  }

  /* #189: nichts rund auf nuvolead.ch (Wunsch des Inhabers, 30.10.2026).
     Kacheln, Bilder, Schlagwörter, Punkte, Mockups: alle Ecken eckig. Der
     WhatsApp-Knopf bleibt rund wie das Zeichen von WhatsApp (ADR 0069).
     Hier und nicht in den Tokens, weil site.css auch feste Werte (50 %,
     2px, 26px) hat und die Kunden-Websites ihre Rundungen behalten. */
  :root:has(header.nav--mega) body *:not(.wa-knopf),
  :root:has(header.nav--mega) body *::before,
  :root:has(header.nav--mega) body *::after { border-radius: 0 !important; }

  /* #190: Überschriften stehen sofort, ohne Einblendung Buchstabe für
     Buchstabe (Wunsch des Inhabers, 30.10.2026). Die Bewegung im Titelbild
     (Pfeil, Hitze) bleibt. */
  :root:has(header.nav--mega) [data-anim="split"] .ch { transform: none !important; transition: none !important; animation: none !important; }

  /* #191: Plus und Minus gezeichnet statt geschrieben. Das Zeichen «+» sitzt
     in der Schrift über der Mitte; zwei Linien sitzen genau in der Mitte,
     auch um 45 Grad gedreht als ×. */
  :root:has(header.nav--mega) .node button::before {
    content: ""; width: 12px; height: 12px;
    background: linear-gradient(currentColor, currentColor) center / 100% 1.5px no-repeat, linear-gradient(currentColor, currentColor) center / 1.5px 100% no-repeat;
  }
  :root:has(header.nav--mega) .werkbank-punkt::before {
    content: ""; width: 16px; height: 16px;
    background: linear-gradient(currentColor, currentColor) center / 100% 2px no-repeat, linear-gradient(currentColor, currentColor) center / 2px 100% no-repeat;
  }
  :root:has(header.nav--mega) .werkbank-punkt[aria-pressed="true"]::before {
    content: ""; background: linear-gradient(currentColor, currentColor) center / 100% 2px no-repeat;
  }

  /* #193 (ADR 0075): an abgehaktes Kärtchen der Einführung wird schwarz,
     das Ergebnis eines Tippens, nicht nur sein Kästchen violett. Nur auf
     nuvolead.ch; der Baustein steht auf keiner anderen Website. */
  :root:has(header.nav--mega) .einf-kachel[aria-pressed="true"] { background: var(--nl-ink); border-color: var(--nl-ink); color: var(--nl-on-dark); }
  :root:has(header.nav--mega) .einf-kachel[aria-pressed="true"] .tipp { color: var(--nl-on-dark-muted); }
  :root:has(header.nav--mega) .einf-kachel[aria-pressed="true"] .box { background: var(--nl-on-dark); border-color: var(--nl-on-dark); color: var(--nl-ink); }
  /* --- an article of «Wissenswertes» (#214, ADR 0091) ---------------------
     One column at reading width: about 68 characters a line, body text 17px
     on the computer and never under 16px, headings that wrap instead of
     being cut. The page is grey; nothing here is a card, the summary and
     the next step are set apart by a line, not a surface (ADR 0075). */
  .artikel-text {
    display: grid; gap: clamp(36px, 4.5vw, 56px); max-width: 68ch;
    font-size: clamp(16px, 1.15vw, 17px); line-height: 1.6; color: var(--nl-ink-2);
  }
  .artikel-text :is(.artikel-abschnitt, .artikel-kurz) { display: grid; gap: var(--s-4); }
  .artikel-text :is(.artikel-abschnitt, .artikel-kurz) h2 {
    font-size: clamp(22px, 2vw, 30px); font-weight: 600; letter-spacing: -0.02em; line-height: 1.2;
    color: var(--nl-ink); text-wrap: balance; overflow-wrap: break-word; hyphens: auto;
  }
  .artikel-text .artikel-meta {
    display: flex; flex-wrap: wrap; gap: 4px 24px; font-size: 15px; line-height: 1.5; color: var(--nl-muted);
    padding-bottom: var(--s-4); border-bottom: 1px solid var(--nl-line);
  }
  .artikel-text .artikel-meta a { color: var(--nl-ink); }
  .artikel-text .artikel-kurz { border-left: 2px solid var(--nl-ink); padding-left: clamp(16px, 2vw, 24px); }
  .artikel-text .artikel-kurz h2 { font-size: var(--fs-h4); }
  .artikel-text .artikel-liste { display: grid; gap: var(--s-3); }
  .artikel-text .artikel-liste li { position: relative; padding-left: 22px; }
  .artikel-text .artikel-liste li::before {
    content: ""; position: absolute; left: 2px; top: 0.7em; width: 6px; height: 6px; background: var(--nl-violet);
  }
  .artikel-text .artikel-liste--zahlen { counter-reset: artikel-punkt; }
  .artikel-text .artikel-liste--zahlen li { counter-increment: artikel-punkt; padding-left: 30px; }
  .artikel-text .artikel-liste--zahlen li::before {
    content: counter(artikel-punkt) "."; top: 0; left: 0; width: auto; height: auto; background: none;
    color: var(--nl-ink); font-weight: 700;
  }
  .artikel-text .artikel-weiter {
    display: flex; flex-wrap: wrap; align-items: center; gap: 0 12px; padding-top: var(--s-6); border-top: 1px solid var(--nl-line);
    color: var(--nl-ink);
  }
