/*
 * Sand-Glas über dem Foto und die Ebenen, die darüber fahren.
 *
 * Gemeinsam: das ist das Menü selbst.
 * Die Zahl im Namen ist die Ladereihenfolge — bei CSS zählt sie.
 */

/*
 * Bis Alpine gelaufen ist, bleibt verborgen, was es erst danach ein- und
 * ausblendet.
 *
 * Stand bis hierher nur im Editor-Stylesheet — dabei nutzen die gemeinsamen
 * Partials x-cloak: Tabs.html für die Fläche jedes Tabs, AccordionItem.html
 * für den aufgeklappten Text. Im Frontend fehlte die Regel also, und beim
 * ersten Bild stünden alle Tabs übereinander, bis Alpine sie sortiert.
 * Aufgefallen ist das nicht, weil das Frontend noch nichts rendert.
 */
[x-cloak] {
    display: none !important;
}

/*
 * Die Seite steht still, solange eine Ebene offen ist (menuOverlay,
 * lockScroll). Das Menü liegt fest über ihr; ohne diese Regel rollt das Rad
 * über der Ebene die Seite darunter.
 *
 * Der Innenabstand ersetzt die Bildlaufleiste, die `hidden` wegnimmt — sonst
 * ruckte die Seite beim Öffnen um deren Breite nach rechts. Den Wert misst das
 * JavaScript und schreibt ihn an das Wurzelelement; ohne sichtbare Leiste ist
 * er null. Das feste Menü rechnet nicht mit, es steht am Fenster.
 *
 * Der Innenabstand hält aber nur den Fluss der Seite still, nicht ihre festen
 * Teile. Gemessen mit Windows-Edge an einer Seite mit festem Kopf, Leiste 15px:
 * der Inhalt des Kopfes sprang beim Öffnen um 7,5px nach rechts, weil ein
 * `position: fixed` am Fenster hängt und das ohne Leiste breiter ist — kein
 * Innenabstand an der Wurzel erreicht ihn. Genau dieser halbe Leistensprung ist
 * das Ruckeln, das beim Öffnen zu sehen war.
 */
.spo-scroll-locked {
    overflow: hidden;
    padding-right: var(--spo-scrollbar-width, 0);
}

/*
 * Deshalb, wo der Browser es kann: die Rinne der Leiste bleibt reserviert,
 * statt ihre Breite an anderer Stelle zu ersetzen. Dann verliert das Fenster
 * beim Sperren gar keine Breite — dieselbe Messung ergibt 0px, für den festen
 * Kopf wie für den zentrierten Inhalt.
 *
 * Die zweite Klasse setzt das JavaScript nur, wenn vorher wirklich eine Leiste
 * da war. Auf einer Seite, die von sich aus nicht rollt, wäre die Rinne neu und
 * der Sprung derselbe, nur andersherum: dieselbe Messung ohne Leiste ergibt
 * -7,5px.
 *
 * `@supports`, weil es die Rinne noch nicht überall gibt (Safari kennt sie erst
 * seit 18.2). Wo sie fehlt, bleibt der Innenabstand — er hält wenigstens den
 * Fluss der Seite ruhig.
 */
@supports (scrollbar-gutter: stable) {
    .spo-scroll-locked--gutter {
        scrollbar-gutter: stable;
        padding-right: 0;
    }
}

/*
 * Die Hülle im Frontend.
 *
 * Glas, Ebenen und Leiste sind absolut gesetzt. Im Editor ist die Bühne ihr
 * Bezugsrahmen — sie baut die Umgebung nach, in der das Menü liegt. Im
 * Frontend gibt es keine Bühne: dort ist das Fenster der Rahmen, und ohne
 * diese Regel läge alles am Dokument und rutschte beim Blättern mit.
 *
 * `pointer-events: none`, damit die Seite darunter bedienbar bleibt, solange
 * nichts offen ist. Glas, Ebene und Leiste schalten sich schon heute selbst
 * wieder scharf — das ist keine neue Zusage, sondern dieselbe, die im Editor
 * die Bühne durchlässig hält.
 */
.spo-menu {
    position: fixed;
    inset: 0;
    z-index: 1000;
    pointer-events: none;
    font-family: var(--spo-font);
    color: var(--spo-blue-dark);
    /*
     * Die Höhe des Rahmens, in dem das Menü liegt — im Frontend das Fenster.
     * Sie steht als Custom Property da, weil eine Karte im Inneren wissen muss,
     * wie viel Platz überhaupt ist: das Accordion begrenzt sich daran und rollt
     * in sich, statt die Ebene zu verlängern (63-accordion.css). Im Editor ist
     * der Rahmen die Bühne, dort steht derselbe Name mit ihrem Wert
     * (editor/10-stage.css).
     *
     * `dvh` und nicht `vh`: auf einem Telefon zählt `vh` die Leiste des
     * Browsers mit, die beim Blättern verschwindet — das Menü liegt fest am
     * sichtbaren Bereich und nicht am gedachten. Der Vorrat davor ist für
     * Browser ohne `dvh` da; `@supports` fragt die Einheit ab, weil eine
     * Custom Property jeden Wert annimmt und der Fehler sonst erst in der
     * `calc()` auffällt, die sie benutzt.
     */
    --spo-frame-height: 100vh;
}

@supports (height: 100dvh) {
    .spo-menu {
        --spo-frame-height: 100dvh;
    }
}

/*
 * Die Schrift des Menüs, gegen die der Website.
 *
 * `font-family` an der Hülle war eine Vererbung und damit ein Angebot: sie
 * kommt nur dort an, wo niemand anderes etwas sagt. Im Seitentemplate einer
 * Website sagt aber ständig jemand etwas — `nav a`, `button`, `.menu li`,
 * `body h2` —, und jede dieser Regeln ist spezifischer als das Erbe von
 * .spo-menu. Eine Zeile des Accordions stand dann in der Hausschrift der Site,
 * die daneben in Outfit, und im Bild war es dieselbe Karte in zwei Schriften.
 *
 * Deshalb steht sie hier an jedem Element und mit `!important`: dieselbe Sperre
 * wie bei Farbe, Rahmen und Innenabstand (63-accordion.css, 65-button.css) und
 * aus demselben Anlass. Die Kette selbst steht weiter nur an einer Stelle
 * (--spo-font in tokens.css): Outfit, dann die Schrift des Systems.
 *
 * Die Bühne des Editors ist mit dabei, weil sie im Backend dieselbe Rolle hat
 * (dort ist es Bootstrap, das mitredet) — genau wie beim Fokus-Ring in
 * 95-a11y.css, der aus demselben Grund beide Hüllen nennt.
 *
 * Ohne `::before` und `::after`: die erben die Schrift ihres Elements schon, und
 * ein Zeichen, das eine Website über ein Pseudoelement einfügt, kommt in seiner
 * eigenen Icon-Schrift — die wäre unter dieser Sperre ein Kästchen.
 *
 * Die einzige Ausnahme ist der Claim auf der Bühne: er steht im Design in
 * Caveat. Seine Regel in editor/10-stage.css ist deshalb spezifischer als diese
 * hier und trägt selbst ein `!important`.
 */
.spo-menu,
.spo-menu *,
.spo-stage,
.spo-stage * {
    font-family: var(--spo-font) !important;
}

/*
 * Und dieselbe Sperre für das Kastenmodell.
 *
 * Jede Fläche des Menüs rechnet mit `border-box`: die Kachel ist 100 % ihrer
 * Zelle *einschließlich* ihrer 14px Innenabstand, der Störer 100 % einschließlich
 * seiner 62px rechts. Auf der Bühne des Editors steht das seit immer
 * (editor/10-stage.css); im Frontend kam es bis hierher vom Stylesheet der
 * Website — also von jemandem, der es auch anders haben kann. Mit
 * `content-box` legt sich der Innenabstand *neben* die 100 %, und jede Zelle
 * läuft um ihn zu breit: eine Reihe 1:1:2 steht dann über ihre Fläche hinaus,
 * und gesucht wird der Fehler im Raster.
 *
 * Damit gilt für Breite und Höhe des Menüs eine Rechnung und nicht die des
 * Gastgebers. Zusammen mit `width`/`height: 100% !important` (50-grid.css) heißt
 * "füll die Zelle" jetzt in jeder Umgebung dasselbe.
 */
.spo-menu,
.spo-menu *,
.spo-stage,
.spo-stage * {
    box-sizing: border-box !important;
}

/*
 * Sand-Glas: im Design eine eigene Ebene über dem Foto (inset:0), nicht das
 * Menü-Panel selbst. Werte aus dem Export: blur(16px) saturate(1.08) über
 * einem Sand-Gradienten.
 */
.spo-glass {
    position: absolute;
    inset: 0;
    z-index: 2;
    background: linear-gradient(180deg, var(--spo-sand-top), var(--spo-sand-bottom));
    backdrop-filter: blur(var(--spo-glass-blur)) saturate(var(--spo-glass-saturate));
    -webkit-backdrop-filter: blur(var(--spo-glass-blur)) saturate(var(--spo-glass-saturate));
    /* Ein- und Ausblenden setzt Alpine als Inline-Animation (fadeAnim) */
}

/*
 * Fläche, in der das Menü liegt – das Panel selbst ist transparent.
 * Waagerecht mittig, senkrecht unten direkt über der Aktionsleiste; das
 * untere Padding hält deren Platz frei (Design: 128px).
 */
/*
 * Der Innenabstand steht in Custom Properties, weil zwei Seiten ihn brauchen:
 * die Fläche selbst und jede Karte darin, die sich auf den freien Platz
 * begrenzt (63-accordion.css rechnet Rahmenhöhe minus oben minus unten). Die
 * kleineren Fenster ändern deshalb nur noch die Werte und nicht die
 * Kurzschreibweise (90-responsive.css) — sonst stünde die Höhe an zwei Stellen
 * und liefe beim nächsten Wert auseinander.
 */
.spo-sheet {
    position: absolute;
    inset: 0;
    z-index: 9;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    --spo-sheet-pad-top: 40px;
    --spo-sheet-pad-inline: 40px;
    --spo-sheet-pad-bottom: 128px;
    padding: var(--spo-sheet-pad-top) var(--spo-sheet-pad-inline) var(--spo-sheet-pad-bottom);
    pointer-events: none;
}

.spo-sheet-inner {
    width: 100%;
    /*
     * Gelesen wird von oben, also fängt der Bildlauf oben an.
     *
     * Hier stand `column-reverse`, und das legte den Anfang des Bildlaufs an den
     * unteren Rand. Der Gedanke war der Stapel, der nach oben wächst; die Folge
     * war, dass ein Menü, das nicht in die Höhe passt, unten aufging und man
     * nach oben rollen musste, um seinen Anfang zu sehen — die Schnellzugriffe,
     * die Überschrift, die erste Reihe. Gemeldet als "quando ele abre o menu abre
     * no fundo e tenho de fazer scroll para cima nao faz sentido".
     *
     * Wo das Menü klebt, ändert das nicht: es steht weiter unten über der
     * Aktionsleiste (.spo-sheet: align-items: flex-end), und solange der Inhalt
     * passt, sieht man keinen Unterschied. Passt er nicht, ist jetzt der Kopf zu
     * sehen und man rollt nach unten.
     *
     * Was `column-reverse` daneben leistete, war eine Sache des Editors: die
     * zuletzt angelegte Reihe samt ihrem "+" lag im Bild. Das erledigt jetzt der
     * Editor selbst — er rollt die Auswahl ins Bild (menu-editor.js), so wie es
     * der Baum schon tat. Eine Frage des Bearbeitens gehört nicht in eine Regel,
     * die auch für Besucher:innen gilt.
     */
    display: flex;
    flex-direction: column;
    /*
     * Arbeitsfläche jeder Ebene: im Design hat der Container max-width 1150px
     * bei 40px seitlichem Innenabstand. Das Padding steuert .spo-sheet, hier
     * bleibt die Inhaltsbreite 1150 - 2 * 40 = 1070px. Wie breit eine Section
     * darin wirklich ist, entscheidet SectionWidth.
     */
    max-width: 1070px;
    max-height: 100%;
    overflow-y: auto;
    /*
     * Die 6px links und rechts sind Luft für den Fokus-Ring.
     *
     * `overflow-y: auto` macht auch waagerecht einen Bildlaufbereich — steht
     * eine der beiden Achsen nicht auf `visible`, rechnet die andere auf
     * `auto`. Damit schneidet die Fläche an ihrer Kante ab, und der Ring des
     * äußersten Elements einer Reihe (3px Strich, 2px Abstand) lag zur Hälfte
     * dahinter.
     */
    padding: 0 6px;
    background: transparent;
    color: var(--spo-blue-dark);
    pointer-events: auto;
    /* Auf- und Zufahren setzt Alpine als Inline-Animation (menuAnim) */
}
