/* Seitenleiste und Seitenrahmen – gilt für alle Seiten.
 *
 * Die Navigation ist Rahmen, nicht Inhalt: dunkler als die Panels, ohne
 * Verlauf, ohne Schatten. Sie soll die Galaxie einfassen, nicht mit ihr
 * konkurrieren. Farben ausschließlich aus tokens.css.
 */

:root {
  /* 72 statt 190. Die Leiste zeigt nur noch Zeichen, und ein Zeichen braucht
     keine Textspalte neben sich. Die 118 px gehen an die Arbeitsfläche; auf
     der Galaxie und in der Review ist das eine ganze Spalte mehr.

     Den Einklappknopf gibt es damit nicht mehr. Er machte aus 190 px 86, und
     die Leiste ist jetzt schmaler, als sie eingeklappt je war. Ein Schalter,
     der nichts mehr zu schalten hat, ist ein Fach für einen Zweifel. */
  --nav-w: 72px;
  /* Höhe der Fußleiste. Am Rechner gibt es sie nicht, und weil jede Rechnung
     mit ihr über `calc` läuft, muss sie dort 0 sein statt zu fehlen. */
  --nav-h: 0px;
}

/* Inline-SVG-Icons statt Emojis: erben Farbe und skalieren mit der Schrift.
   Steht hier und nicht in style.css, weil shell.js diese Klasse in jede
   Seite schreibt – auch in feedback.html, das style.css nie lädt. */
.ico { width: 1.05em; height: 1.05em; display: inline-block; vertical-align: -0.16em; flex: none; }
.ico--lead { margin-right: 0.42em; }

/* Die Untergrenze für Tippziele. Auf Zeigegeräten mit grobem Zeiger – Finger,
   nicht Maus – braucht jedes Ziel 44 x 44 px; gemessen lagen Navigation (39 x 40),
   Selects (33) und Eingabefelder (31) darunter. Auf der Maus bleibt es kompakt,
   dort genügen die 24 px der schwächeren Stufe. */
@media (pointer: coarse) {
  /* Der Boden steht am Maß, nicht an einer Aufzählung.
   *
   * Darunter stand von Anfang an eine Liste von Selektoren — und eine Liste
   * vergisst. Am 23. August 2026 nachgemessen lagen trotz dieses Blocks
   * weiterhin sieben Ziele auf /board, vier auf /plan und die vier
   * Umwandlungsknöpfe unter 44 px: Sie waren nach dem Block dazugekommen und
   * hat niemand nachgetragen. Genau so entsteht die Zahl, die den ganzen
   * Mobil-Befund rahmt — 8 % der Regeln gelten dem Finger, weil die
   * Mobilfassung ein Nachtrag ist und kein Entwurf.
   *
   * `--ctl-h` ist das Maß, aus dem alle fünfzehn Höhen und Breiten des
   * Projekts folgen. Hier angehoben wächst jedes Bedienelement mit, auch das,
   * welches es morgen gibt. Nachgesehen: Alle fünfzehn Stellen benutzen es
   * als `min-height` oder `min-width`, keine rechnet damit — es kann also
   * nichts verschieben, nur vergrößern.
   *
   * Die Liste darunter bleibt trotzdem stehen: Sie fängt, was seine Höhe
   * nicht aus dem Maß bezieht. Sie ist jetzt das Netz und nicht mehr der
   * Boden. */
  :root { --ctl-h: 44px; }

  .navItem, .navWho, .navBrand,
  #controls input, #controls select, #controls button, #controls a,
  .platBtn, .hubBtn, .heroBtn, .ghostBtn, .solidBtn,
  #closeInsights, #closeSidebar, .tourBtns button, .boardNav .ghostBtn,
  .entryCard input, .entryCard select, .entryCard button {
    min-height: 44px;
  }
  /* Symbolknöpfe tragen keinen Text, der sie breit zieht – sie brauchen die
     Breite ausdrücklich. */
  .navWho, .platBtn, #controls button, #closeInsights, #closeSidebar,
  .boardNav .ghostBtn { min-width: 44px; }
  /* Die Zugliste fehlte in dieser Aufzählung. Gemessen blieb jede Zelle bei
     118 x 25 px, auch mit grobem Zeiger – und sie ist die Liste, die man auf
     dem Handy am häufigsten antippt. 36 statt 44: Zwei Spalten à 44 px plus
     Zugnummer passen auf 360 px nicht nebeneinander, und die Zellen berühren
     sich nicht, was 2.5.8 als Ausgleich ausdrücklich zulässt. */
  .mvCell { min-height: 36px; }
  /* Dieselbe Lücke eine Ebene tiefer: die Sprungzahlen der Zähltabelle maßen
     19 x 19 px. Sie sind der kürzeste Weg von "du hattest einen Fehler" zu
     "hier war er" – also genau das, wofür man die Seite auf dem Handy öffnet.
     Auch hier 36 statt 44, aus demselben Grund wie bei .mvCell: Die Tabelle
     hat elf Zeilen, und 44 überall machte aus ihr einen ganzen Bildschirm.
     Höchstens sechs Zeilen tragen überhaupt einen Knopf (JUMPABLE), der
     Zuwachs bleibt damit im Bereich von 30 px. Der negative Rand fällt weg,
     sonst berührten sich benachbarte Ziele. */
  .jump {
    min-height: 36px;
    min-width: 36px;
    margin: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  /* Der unterstrichene Textknopf. Er sieht aus wie ein Verweis im Fließtext,
     steht aber überall allein auf seiner Zeile ("Copy FEN", "Cancel", "Back
     to the map", "… or explore the demo", "Change account or filters") —
     also gilt für ihn das volle Maß und nicht die Ausnahme für Verweise
     zwischen Wörtern. Gemessen lag er bei 15 px Höhe. */
  .linkBtn {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
}

/* ---------- Der Browser rollt selbst, und er kennt die Fußleiste nicht ----
 *
 * Wer ein Feld antippt, dessen Tastatur es verdeckt, wer mit der Tabtaste
 * weitergeht, wer einem Sprungziel folgt: In all diesen Fällen rollt nicht
 * der Besucher, sondern der Browser — und er rollt genau so weit, dass das
 * Ziel gerade eben im Fenster steht. Die Fußleiste liegt darüber, also landet
 * das Ziel darunter. Gemessen auf /board landete #whoUser nach dem Tippen
 * hinter der Leiste.
 *
 * `scroll-padding-bottom` sagt dem Browser, wo das Fenster für ihn endet.
 * Es steht hier für JEDE Fläche und nicht nur für die, auf denen es jemand
 * bemerkt hat — die Leiste gibt es überall. Die Galaxie sperrt das Rollen
 * ohnehin; dort ist die Zeile wirkungslos, nicht falsch.
 *
 * Die acht Pixel obendrauf sind der Unterschied zwischen "berührt die Kante"
 * und "steht darüber". */
:root {
  scroll-padding-bottom: calc(var(--nav-h) + env(safe-area-inset-bottom) + 8px);
}

/* Bewegung ist in der Galaxie zu Hause, nicht im Rahmen. Wer sie abbestellt,
   bekommt trotzdem jeden Zustandswechsel – nur ohne Weg dorthin. Kein
   pauschales 0.01ms auf alles: Das nimmt auch die Rückmeldung mit, die den
   Wechsel überhaupt erst lesbar macht. Deshalb bleiben Farbe und Deckkraft
   kurz animiert, während Größe, Position und Drehung sofort sitzen.
   galaxy.js liest dieselbe Einstellung für Aufbau, Sonnenpuls und UFO. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-property: color, background-color, border-color, opacity, fill, stroke !important;
    transition-duration: 80ms !important;
    scroll-behavior: auto !important;
  }
}

/* Die Flächen, die der Browser stellt und kein Designsystem beansprucht. */
::selection { background: var(--indigo-600); color: var(--text); }
:root { caret-color: var(--gold); }

/* ======================= DER SETZKASTEN =======================
   Die Leiste ist ein Setzkasten: Fächer mit einem Typen darin. Sie ist Rahmen,
   nicht Inhalt – dunkler als die Fächer der Arbeitsfläche, ohne Verlauf, ohne
   Schatten. Farben ausschließlich aus tokens.css.

   Vier Orte tragen keine Textspalte. Die Leiste ist deshalb auf ihre Zeichen
   zusammengezogen: 72 px, ein Zeichen je Fach, der Name im `title` und im
   vorgelesenen Namen. Das ist keine eingeklappte Fassung eines breiten
   Kastens, sondern die einzige – ein Zustand weniger, den man wählen, merken
   und wiederherstellen muss. */

#sideNav {
  position: fixed;
  top: 0; left: 0; bottom: 0;
  width: var(--nav-w);
  z-index: 30;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-4);
  /* 4 px seitlich, nicht 8: Der Fokusring zeichnet 2 px Strich mit 2 px
     Versatz um ein 46 px breites Fach, braucht also 54. Bei 8 px Polster
     blieb genau 1 px Luft zum `overflow` – ein Ring, der beim nächsten
     Pixel Änderung angeschnitten wird, ist ein Ring, der irgendwann fehlt. */
  padding: var(--sp-5) var(--sp-1);
  background: var(--indigo-950);
  border-right: 1px solid var(--panel-border);
  /* Senkrecht rollbar statt abgeschnitten. Vier Werkzeuge passen in jedes
     Fenster, sechs (zwei sind geplant) in einem 560 px hohen nicht mehr –
     und `hidden` hätte das letzte lautlos weggenommen. Waagerecht bleibt es
     bei clip: Dort steht nichts, was hinausragen dürfte. */
  overflow-y: auto;
  overflow-x: clip;
  /* Hier stand einmal ein Breitenübergang, und die Leiste blieb damit hängen,
     sobald das Fenster die 720px-Grenze kreuzte: 166 px tote Lücke zwischen
     Leiste und Inhalt, von keiner automatischen Prüfung zu sehen, weil
     scrollWidth dabei gleich bleibt. Die Charta sagt ohnehin, dass das Chrome
     statisch ist – also schnappt die Leiste, statt zu gleiten. */
}

/* Der Kopf trägt nur noch die Marke. Das Wortzeichen stand daneben und hätte
   in 72 px umbrechen müssen; ein zweizeiliges Wortzeichen ist keins mehr. Der
   Name der Seite steht ohnehin auf jeder Fläche im Inhalt. */
.navHead { display: grid; place-items: center; padding-bottom: var(--sp-3); }
.navBrand {
  display: grid; place-items: center;
  width: 46px; height: 44px;
  border-radius: var(--r-md);
  text-decoration: none; color: var(--text);
}
.navBrand img { width: 28px; height: 28px; }
.navBrand:hover { background: var(--indigo-900); }

/* Hier stand bis zum 16. August 2026 die Überschrift "CASE" über den vier
   Fächern. In der breiten Leiste war sie die Ansage des Setzkastens; in 72 px
   war sie das einzige Wort weit und breit und benannte etwas, das man ohnehin
   sieht. Vier Zeichen brauchen keine Zwischenüberschrift. */

.navList {
  list-style: none; width: 100%;
  display: flex; flex-direction: column; align-items: center;
  gap: var(--sp-2);
}
.navList li { display: flex; justify-content: center; width: 100%; }

/* Ein Fach: quadratisch, mit dem Zeichen darin. Im Ruhezustand trägt es
   nichts als das Zeichen. Vier gerahmte Kästen untereinander sind vier
   Rahmen, die alle gleich laut um Aufmerksamkeit bitten, und keiner davon
   sagt, wo man steht – erst der aktive bekommt Fläche und Kante.

   Die Kante ist --accent, nicht Gold. Gold heißt "dein Zug" und trägt in
   einer Navigation keine Bedeutung. */
.navItem, .drawer {
  position: relative;
  display: grid; place-items: center;
  width: 46px; height: 44px;
  border: 1px solid transparent;
  border-radius: var(--r-md);
  color: var(--text-dim);
  text-decoration: none;
}
.navItem:hover { background: var(--indigo-900); color: var(--text); }
.navItem.active, .drawer.is-here {
  background: var(--indigo-800);
  border-color: var(--accent);
  color: var(--text);
}
/* Der globale Fokusring setzt `border-radius: --r-xs` auf das Element selbst,
   nicht auf den Ring. Am Fach hieß das: Wer durchtabbt, sieht die Ecken
   springen. Die Fächer behalten ihre Rundung, der Ring folgt ihr. */
.navItem:focus-visible, .navBrand:focus-visible, .navWho:focus-visible {
  border-radius: var(--r-md);
}

/* Ein Zeichen je Fach, gezeichnet in js/icons.js.
   
   Es erbt die Farbe seines Eintrags und nimmt damit von selbst am Zustand
   teil: --text-dim im Ruhezustand, --text auf der Seite, auf der man steht.
   Vorher hing das an einer Deckkraft von .62 auf .95 — und ein halb
   durchsichtiges Bild ist kein Zustand, sondern ein blasses Bild.
   
   Bis zum 13. August 2026 stand hier eine Reihe aus sechs Figuren je Fach und
   für die Galaxie ein Ausschnitt ihrer Karte. Der Ausschnitt trug Coral und
   Mint, also Bedeutungsfarben an einer Stelle ohne Daten; er war damit die
   einzige Marke der Leiste, die sich rechtfertigen musste. Ein gezeichnetes
   Zeichen in currentColor muss das nicht. */
.mark { display: block; }
.mark svg { display: block; width: 22px; height: 22px; }

/* Am Rechner stumm: Das Zeichen steht allein im Fach, der Name liegt im
   `title` und im vorgelesenen Namen. Auf dem Telefon wird die Leiste zur
   Fußzeile und bekommt das Wort zurück – dort stehen die vier nebeneinander
   und ein Zeichen ohne Wort wäre dort ein Ratespiel. */
.navLabel {
  display: none;
  font-size: var(--fs-micro); letter-spacing: 1.4px;
  text-transform: uppercase; font-weight: 700;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Kontur, nicht Füllung – so steht das Abzeichen als Komponente in DESIGN.md.
   Gefüllt wäre es eine zweite --btn-bg-Fläche neben dem einen Knopf, den die
   Charta je Ansicht erlaubt. In der Leiste gibt es das Abzeichen nicht mehr
   (dort steht der Punkt darunter); auf den Seiten selbst steht es weiter. */
.beta {
  font-size: var(--fs-micro); font-weight: 700; letter-spacing: .8px;
  text-transform: uppercase; color: var(--text-dim);
  border: 1px solid var(--panel-border);
  border-radius: var(--r-xs); padding: 1px 5px;
  margin-left: var(--sp-2); vertical-align: 2px;
}

/* Neben ein Zeichen passt in 46 px kein Wort. Der Punkt sagt dasselbe, was
   das Abzeichen sagte: hier ist etwas anders. Er trägt keine Bedeutungsfarbe,
   weil er keine Bedeutung hat außer "sieh noch einmal hin".

   4 statt 7/8: Das Zeichen misst 22 px in einem 46 x 44 px großen Fach, seine
   obere rechte Ecke liegt also bei 34/11. Bei 7/8 saß der Punkt auf der
   Schulter des Schildes und las sich als Teil der Zeichnung – als Niete, als
   Stern, jedenfalls nicht als Hinweis. In der Ecke berührt er nichts. */
.navDot {
  position: absolute; top: 4px; right: 4px;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--text-dim);
}
.navItem:hover .navDot, .navItem.active .navDot { background: var(--text); }

/* Wer geladen ist, steht im Fuß der Leiste. Der Name entscheidet über jedes
   Ergebnis auf jeder Fläche; steht er nirgends, rechnet man irgendwann über
   ein fremdes Konto und merkt es nicht.

   Aus Zeile plus Knopf ist ein Knopf geworden. Sichtbar bleiben das Zeichen
   und ein Punkt, sobald jemand gesetzt ist; der Name selbst liegt im `title`
   und im vorgelesenen Namen. Das ist der einzige Ort, an dem die schmale
   Leiste etwas verliert – der Name war vorher lesbar, ohne zu zeigen. Dafür
   ist er nie wieder umgebrochen, abgeschnitten oder eingeklappt weg. */
.navFoot {
  margin-top: auto;
  width: 100%;
  display: grid; place-items: center;
  border-top: 1px solid var(--panel-border);
  padding-top: var(--sp-4);
}
.navWho {
  position: relative;
  display: grid; place-items: center;
  width: 46px; height: 44px;
  background: none;
  border: 1px solid transparent;
  border-radius: var(--r-md);
  color: var(--text-dim);
  cursor: pointer;
}
.navWho:hover:not(:disabled) { background: var(--indigo-900); color: var(--text); }
.navWho:disabled { cursor: default; }
.navWho[data-set="yes"] { color: var(--text); }
.navWho[data-set="yes"]::after {
  content: "";
  position: absolute; top: 4px; right: 4px;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--accent);
}
/* Der Name ist der zugängliche Name des Knopfes. Er darf deshalb nicht
   verschwinden, nur unsichtbar werden – display:none nähme ihn auch der
   Vorlesesoftware. */
#navWho {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* ======================= DAS FACH =======================
   Das Grundelement jeder Arbeitsfläche. Ein Raster aus gleich großen Karten
   sieht bei vier Werkzeugen falsch aus; Fächer sind verschieden groß, jedes
   tut etwas anderes, und ein leeres Fach ist ein gültiger Zustand statt eines
   Lochs. */
.slot {
  background: var(--indigo-950);
  border: 1px solid var(--panel-border);
  border-radius: var(--r-xs);
  padding: var(--sp-8);
}
.slotLabel {
  font-size: var(--fs-micro); letter-spacing: 1.6px;
  text-transform: uppercase; color: var(--text-dim);
}

/* ---------- Der Weltraum für Seiten ohne Leinwand ----------
   Dieselbe Farbe, die die Galaxie ins Canvas malt: --space in der Mitte,
   --space-deep zum Rand. Vorher stand hier die Indigo-Leiter der Panels,
   und die Seiten liefen sichtbar ins Violette. */
/* Die Startseite fehlt hier mit Absicht: Sie heißt `hubPage`, nicht
   `homePage`, und sie richtet sich in hub.css selbst ein (`.work` trägt dort
   Rand und Fußabstand). Bis zum 24. August 2026 stand hier und weiter unten
   `.homePage` — ein Selektor, den keine Seite trägt. Er sah aus wie die
   Regel, die den Hub einrückt, und war es nicht; wer ihn änderte, änderte
   nichts. */
.reviewPage body,
body.feedbackPage {
  /* Ohne die volle Höhe endet der Körper unter kurzem Inhalt, und darunter
     scheint das violette html-Element durch – auf der Review-Seite stand so
     ein Farbblock unter der Karte. */
  min-height: 100vh;
}

/* Der Himmel aller Seiten ohne Galaxie kommt aus js/sky.js auf eine Leinwand –
   dieselbe Dichte und dieselben Alphawerte wie in der Galaxie. Vorher standen
   hier neun CSS-Punkte; nebeneinander gestellt sah die Review-Seite dadurch
   leer aus, obwohl beide dieselben Farben benutzten.

   Die Leinwand liegt exakt dort, wo auf der Galaxie-Seite #galaxy liegt: rechts
   neben der Leiste. Nur so fällt die Mitte des Radialverlaufs auf beiden Seiten
   auf denselben Punkt – über die volle Fensterbreite säße sie um die halbe
   Leistenbreite daneben, und genau das sah man beim Seitenwechsel. */
#sky {
  position: fixed;
  top: 0;
  left: var(--nav-w);
  /* Maße ausschreiben, nicht über top/right/bottom/left aufspannen: Eine
     Leinwand ist ein ersetztes Element und fällt bei `width: auto` auf ihre
     eigene Größe von 300 x 150 zurück, egal welche Kanten festgenagelt sind.
     Gemessen sah man genau das – ein Briefmarkenhimmel oben links.
     Dieselben Werte wie #galaxy, damit beide Seiten dieselbe Fläche füllen. */
  width: calc(100vw - var(--nav-w));
  height: 100vh;
  z-index: -1;
  display: block;
  pointer-events: none;
}

/* Die Identität steht in der Leiste; ein zweites "Chess Galaxy" in der Topbar
   wäre Verdopplung – der Platz gehört den Bedienelementen. Aber display:none
   hätte die einzige h1 der Seite mitgenommen: Für einen Screenreader begann
   die Galaxie dann bei h3, ohne Überschrift. Sichtbar weg, hörbar da. */
#topbar #brand {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ---------- Platz für die Leiste schaffen ---------- */
/* Die Galaxie ist eine Leinwand über dem ganzen Fenster – sie bekommt den
   Rand als Versatz, nicht als Innenabstand. */
#galaxy,
#topbar,
#setup { left: var(--nav-w); }
#galaxy,
#setup { width: calc(100vw - var(--nav-w)); }
#topbar { right: 0; }
#legend { left: calc(var(--nav-w) + 16px); }
#insights { left: calc(var(--nav-w) + 16px); }
#breadcrumb { left: calc(var(--nav-w) + 16px); }

/* Seiten mit normalem Fluss bekommen den Rand als Innenabstand – so bleibt
   der Inhalt im Rest der Fläche mittig statt nach rechts geschoben. Unten
   kommt auf dem Handy die Fußleiste dazu; am Rechner ist --nav-h null. */
.reviewPage body,
.planPage body,
body.feedbackPage {
  padding-left: var(--nav-w);
  padding-bottom: calc(var(--nav-h) + env(safe-area-inset-bottom));
}

/* ---------- Auf dem Handy wandert die Leiste nach unten ----------
 *
 * Bis zum 11. August 2026 stand sie auch dort seitlich und war zur
 * Symbolspalte eingeschrumpft: 58 von 375 px – 15,5 % der Bildschirmbreite,
 * dauerhaft, für fünf **unbeschriftete** Ziele. Die Inhaltsspalte blieb bei
 * 289 px, das Brett der Review bei 231 × 231, und aus zwei 24-px-Symbolen war
 * "Opening galaxy" gegen "Play patterns" nicht zu erraten.
 *
 * Der alte Kommentar lehnte hier eine ausklappbare Schublade ab – zu Recht,
 * sie wäre ein zweites Bedienkonzept gewesen. Nur ist die Fußleiste keins:
 * Sie ist das, was auf diesem Gerät jede Anwendung tut, sie liegt in
 * Daumenreichweite statt oben links, und sie hat endlich Platz für Wörter.
 */
/* Die zweite Bedingung kam am 24. August 2026 dazu. Bis dahin hing die Leiste
 * allein an der Breite — und ein quer gehaltenes Telefon ist 812 px breit.
 * Die Regel griff dort nicht, die Leiste stand wieder senkrecht, und zwar auf
 * einem Gerät, das 375 px **hoch** ist. Gemessen: `scrollHeight` 445 gegen
 * `clientHeight` 375, der Konto-Knopf fiel unten heraus, auf allen sechs
 * Flächen — und alle sechs Ziele verloren ihre Beschriftung.
 *
 * Gemessen wird deshalb, was tatsächlich fehlt: die Höhe. Ein Fenster unter
 * 560 px trägt keine senkrechte Leiste mit sechs beschrifteten Zielen, gleich
 * wie breit es ist. Am Rechner ist ein so flaches Fenster selten; die
 * Fußleiste ist dort ungewohnt, aber vollständig — die senkrechte war
 * abgeschnitten. */
@media (max-width: 720px), (max-height: 560px) {
  :root {
    /* Seitlich nichts mehr – die volle Breite gehört dem Inhalt. */
    --nav-w: 0px;
    --nav-h: 58px;
  }

  #sideNav {
    top: auto;
    right: 0;
    bottom: 0;
    width: auto;
    flex-direction: row;
    align-items: stretch;
    gap: 0;
    /* Die Höhe steht fest, statt sich aus dem Inhalt zu ergeben.
     *
     * Vorher wuchs sie aus Zeichen, Wort und Innenabstand — und --nav-h war
     * eine Behauptung daneben, mit der jede andere Fläche rechnete. Gemessen
     * am 24. August 2026 stimmten die beiden nie überein: 52 px Leiste gegen
     * 58 px Token im Hochformat (sechs Pixel verschenkt), 45 gegen 44 im
     * Querformat — dort lag die Leiste einen Pixel über dem, was der Inhalt
     * für sie freigehalten hatte.
     *
     * Sechs Pixel sind kein Schaden. Ein Maß, das nur ungefähr gilt, ist
     * einer: Wer damit rechnet, rechnet falsch, und niemand sieht es, bis
     * etwas knapp wird. Jetzt ist --nav-h die Höhe der Leiste, nicht ihre
     * Schätzung. */
    height: calc(var(--nav-h) + env(safe-area-inset-bottom));
    padding: 0 var(--sp-1) env(safe-area-inset-bottom);
    border-right: none;
    border-top: 1px solid var(--panel-border);
    /* Der Fokusring braucht Luft nach außen. `overflow: hidden` hat ihn auf
       der Startseite schon einmal auf einen Splitter gekappt; hier trägt die
       waagerechte Reihe ohnehin nichts, was überstehen könnte. */
    overflow: visible;
  }

  /* Die Marke fällt weg: Sie steht auf jeder Seite im Inhalt, und der
     Setzkasten wird hier zur Reihe – ein Kopf gehört an einen Kasten. */
  .navHead { display: none; }

  .navList {
    flex-direction: row;
    flex: 1;
    gap: 0;
    min-width: 0;
  }
  .navList li { flex: 1; min-width: 0; display: flex; }

  /* Die Typen bleiben auch hier stehen. Sie sind die erste Zusage dieses
     Entwurfs – sie auf dem Telefon wegzuschalten hätte die Seite genau dort
     wieder in Textkarten verwandelt, wo die meisten sie zuerst sehen. */
  .navItem, .drawer {
    flex: 1;
    min-width: 0;
    width: auto;
    height: auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    padding: var(--sp-2) 2px;
    background: none;
    border: none;
    border-top: 2px solid transparent;
    border-radius: 0;
  }
  .navItem.active { border-top-color: var(--accent); background: none; }
  .mark svg { width: 20px; height: 20px; }

  /* Die Sperrung ist das Erste, was der sechste Eintrag kostet.
   *
   * Gemessen am 22. August 2026, als der Trainingsplan dazukam: Bei 375 px
   * teilen sich sechs Ziele 367 px, jedes Wortfeld ist 57,2 px breit — und
   * "PATTERNS" braucht bei 1,4 px Sperrung 60. Es stand also als "PATTERN…"
   * da. Von den 60 px sind 11,2 reine Sperrung; die Buchstaben selbst
   * brauchen 48,8.
   *
   * Sperrung macht 10-px-Versalien lesbar und wird deshalb gekürzt, nicht
   * gestrichen: 0,6 px ergeben 53,6 px und passen bis 360 px mit einem
   * Millimeter Luft. Wer ein siebtes Ziel einhängt, misst hier neu — die
   * Reserve ist aufgebraucht, nicht groß. */
  .navLabel { max-width: 100%; letter-spacing: 0.6px; }

  /* Der lange Name steht am Rechner, der kurze hier – vier Ziele à 94 px
     tragen "Opening galaxy" nicht, und ein abgeschnittenes Wort ist keine
     Beschriftung. Der vorgelesene Name bleibt in beiden Fällen der lange:
     er hängt am Link, nicht an der sichtbaren Zeile. */
  .navLabel { display: block; overflow: hidden; text-overflow: ellipsis; }

  /* Der Punkt sitzt am Rechner in der Ecke eines 46 px breiten Fachs. In
     einem 94 px breiten Daumenziel säße er einen Zentimeter neben dem
     Zeichen, auf das er zeigt – hier sagt das Wort ohnehin, wo man landet.

     Der Fuß fällt weg, weil vier Daumenziele die Reihe füllen. Wer geladen
     ist, steht auf dem Telefon im Inhalt jeder Fläche. */
  .navDot,
  .navFoot { display: none; }

  /* Was am unteren Rand klebt, muss über die Leiste rücken. */
  #legend { bottom: calc(14px + var(--nav-h) + env(safe-area-inset-bottom)); }
  #sidebar { bottom: calc(var(--nav-h) + env(safe-area-inset-bottom)); }
  #insights { max-height: calc(100vh - 180px - var(--nav-h)); }
}

/* Unter 340 px reicht auch die gekürzte Sperrung nicht: Bei 320 px sind sechs
   Wortfelder 48 px breit, und "PATTERNS" braucht allein an Buchstaben 48,8 —
   ohne jede Sperrung. Hier geht deshalb ein Punkt Schriftgröße, und die zwei
   Pixel Innenabstand je Seite gehen mit. Das betrifft das iPhone SE der
   ersten Bauart und sonst kaum ein Gerät; ein gekapptes Wort dort ist
   trotzdem ein gekapptes Wort. */
@media (max-width: 340px) {
  .navItem, .drawer { padding: var(--sp-2) 0; }
  .navLabel { font-size: 9px; letter-spacing: 0.3px; }
}

/* Im Querformat ist Höhe das knappe Gut, nicht Breite: 58 px sind dort 15,5 %
   des Bildschirms, während jedes Ziel 135 px Breite bekommt statt 61. Zeichen
   und Wort stellen sich deshalb nebeneinander statt übereinander — das
   halbiert die Höhe der Leiste und die Beschriftung bleibt, worauf es
   ankommt. Steht nach dem 340er-Block, damit es ihn überschreibt. */
@media (max-height: 560px) {
  :root { --nav-h: 44px; }
  .navItem, .drawer {
    flex-direction: row;
    gap: var(--sp-2);
    padding: var(--sp-1) var(--sp-2);
  }
  .navLabel { font-size: var(--fs-micro); letter-spacing: 0.6px; }
  .mark svg { width: 18px; height: 18px; }
}

/* ---------- Kein Feld unter 16 px, solange ein Finger tippt ----------
 *
 * iOS Safari zoomt die **ganze Seite** hinein, sobald ein Eingabefeld mit
 * weniger als 16 px Schrift den Fokus bekommt, und lässt den Besucher darin
 * stehen: Das Viewport-Meta trägt kein `maximum-scale`, herauszoomen geht nur
 * von Hand. Ein einziges Feld genügt für diesen Zustand.
 *
 * Die Regel war bekannt und stand als Kommentar zwanzig Zeilen weiter oben.
 * Angewandt war sie auf zwei Stellen. Am 23. August 2026 gemessen: **kein
 * einziges `<select>` war je abgedeckt**, und die drei jüngsten Flächen
 * kannten die Regel gar nicht — 14 Felder unter 16 px auf /galaxy, /board und
 * /plan.
 *
 * Deshalb steht sie hier als Netz und nicht als Einzelfall, und deshalb mit
 * `!important`: Die Felder werden auf ihren Seiten über ID angesprochen
 * (`#suColor`, `#posInput`), und keine Typregel schlägt eine ID. Das ist eine
 * Eigenschaft der Plattform, kein Geschmack — ein Entwurf, der sie
 * überstimmen will, hat sich geirrt.
 *
 * `pointer: coarse` statt einer Breite: Es geht um den Finger, nicht um den
 * Bildschirm. Ein Tablet mit 1024 px zoomt genauso. Auf der Maus bleibt die
 * Leiter aus tokens.css unangetastet.
 *
 * Ein flacher Wert und kein `max()`: Nachgezählt trägt **kein** Feld des
 * Projekts mehr als `--fs-base` (13 px), die Textfläche für die Stellung
 * sogar nur `--fs-small` (12). Es gibt also nichts, was diese Regel
 * verkleinern könnte. `max(16px, 1em)` hätte das Gegenteil getan: `1em` misst
 * den **Eltern**wert, nicht den eigenen — ein absichtlich großes Feld in
 * einem kleinen Kasten wäre damit geschrumpft statt geschützt worden.
 *
 * Die Zusage hängt nicht an dieser Regel allein: `.claude/skills/preflight`
 * misst jedes Feld jeder Fläche bei grobem Zeiger nach und schlägt fehl,
 * sobald eines darunter liegt. Wer hier etwas ändert, ändert eine Messung. */
@media (pointer: coarse) {
  input,
  select,
  textarea {
    font-size: 16px !important;
  }
}


/* ---------- Was jede Seite braucht, auch ohne style.css ----------
   privacy.html, feedback.html und 404.html laden shell.css, aber nicht
   style.css – dort steht der globale Reset und der Fokusring. Ohne diese
   Zeilen trug die Leiste dort die Absatzabstaende des Browsers (gemessen
   40 px Einzug, nur auf 404) und feedback.html schaltete den Fokusring sogar
   ausdruecklich ab, ohne Ersatz. */
#sideNav p, #sideNav ul, #sideNav li { margin: 0; padding: 0; }
#sideNav ul { list-style: none; }
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-xs);
}

/* ============================ DER WINKELHAKEN ============================
   Ein Metallkanal aus drei Kanten, rechts offen, der genau eine Zeile hält:
   Plattform, Name, und der eine Knopf. Er steht auf dem Hub und auf jeder
   Werkzeugseite — deshalb steht er hier.

   Bis zum 13. August 2026 gab es ihn zweimal, einmal in hub.css und einmal als
   `.entryCard .stick` in style.css. Zwei Kopien eines Griffs sind der Anfang
   von zwei Häusern; als der Laufzettel ihn als dritte Fläche brauchte, war das
   der Moment, ihn zusammenzuziehen statt eine dritte Kopie zu ziehen. */
.stick {
  background: var(--indigo-900);
  border-top: 5px solid var(--indigo-600);
  border-bottom: 7px solid var(--indigo-600);
  border-left: 5px solid var(--indigo-600);
  padding: var(--sp-5);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-4);
}
.stickRow { display: flex; gap: var(--sp-3); flex: 1 1 22rem; min-width: 0; margin: 0; }
.stickRow input {
  flex: 1 1 auto; min-width: 0;
  background: var(--indigo-950);
  border: 2px solid var(--accent);
  border-radius: var(--r-md);
  color: var(--text);
  font-family: inherit;
  /* 16px: darunter zoomt iOS Safari beim Hineintippen in die Seite. */
  font-size: 16px;
  min-height: var(--ctl-h-lg);
  padding: 11px 14px;
}
/* Gemessen 2,56:1 mit --indigo-500 – und das ist die Beschriftung im
   wichtigsten Feld der Seite. --text-dim liegt bei 5,66:1. */
.stickRow input::placeholder { color: var(--text-dim); opacity: 1; }
.stickRow input[aria-invalid="true"],
.stickRow input.err { border-color: var(--loss); }
.stickRow .solid {
  border: none; border-radius: var(--r-md);
  min-height: var(--ctl-h-lg);
  background: var(--btn-bg); color: var(--btn-fg);
  font-family: inherit; font-size: var(--fs-lead); font-weight: 700;
  padding: 12px 20px; cursor: pointer; white-space: nowrap;
}
.stickRow .solid:hover { background: var(--btn-bg-hover); }
.stickRow .solid:disabled { opacity: .5; cursor: default; }

/* Im schmaleren Fach der Werkzeugseiten sitzt der Umschalter auf einer eigenen
   Zeile im Kanal. Neben einer zweizeilig umgebrochenen Eingabezeile sah er aus
   wie ein Fehler; der Kanal bleibt derselbe, er hält hier zwei Zeilen. */
.entryCard .stick,
.entry .stick { margin-bottom: var(--sp-5); }
.entryCard .stick .platToggle,
.entry .stick .platToggle { margin: 0; flex: 1 1 100%; }
.entryCard .stickRow,
.entry .stickRow { flex: 1 1 16rem; }

/* Der Kanal kippt in die Senkrechte — aber nur im schmalen Fach der
   Werkzeugseiten. Beim Zusammenziehen stand das kurz für jeden `.stick`, und
   damit auch für den des Hubs: Dessen Fußleiste wuchs auf 519 px bei 390 px
   Fenster, gemessen, und die Seite scrollte seitlich. Der Hub hatte diese
   Regel nie, und er braucht sie nicht — sein Kanal bricht von selbst um. */
@media (max-width: 640px) {
  .entryCard .stick,
  .entry .stick { flex-direction: column; align-items: stretch; }
  .stickRow { flex: 1 1 100%; flex-wrap: wrap; }
  /* Im senkrechten Kanal ist die Hauptachse die Höhe. Die 16rem, die im
     breiten Fall die Zeilenbreite setzen, wurden dort zu 256 px Zeilenhöhe:
     gemessen ein 126 px hohes Feld und ein 123 px hoher Knopf bei 390 px. */
  .entry .stickRow,
  .entryCard .stickRow { flex: 0 0 auto; }
  .stickRow input, .stickRow .solid { flex: 1 1 100%; }
}

@media (pointer: coarse) {
  .stickRow input, .stickRow .solid { min-height: 44px; }
}
