/* =========================================================================
   Curriculum — matches the spaces.informatik.fhnw.ch reference layout.
   See docs/spaces_style_catalog.md for measured values.
   ========================================================================= */

:root {
    /* Brand — FHNW-Gelb mit demselben Wert wie Fabians Curriculum
       (spaces.informatik.fhnw.ch), damit beide Studiengänge gleich aussehen. */
    --brand-color: #FEE70C;

    /* Auszeichnung „prägendes Modul" — Petrol-Blau. Geht bewusst vom FHNW-Gelb weg
       (kühle Seite), damit der Balken frisch & sympathisch gegen Karte und gelben
       Grund poppt. Zentral: Balken, Legenden-Punkt und Umschalter teilen den Ton.
       Fallback: --spec-color wird pro Studienrichtung gesetzt (siehe unten) und
       überschreibt diesen Wert überall, wo ausgezeichnet wird. */
    --signature: #1488C2;
    --spec-color: var(--signature);

    /* Graustufen = Tailwind „slate", wie in Fabians Curriculum. */
    --slate-950: #020618;
    --slate-900: #0F172B;
    --slate-800: #1D293D;
    --slate-700: #314158;
    --slate-600: #45556C;
    --slate-500: #62748E;
    --slate-400: #90A1B9;
    --slate-300: #CAD5E2;
    --slate-200: #E2E8F0;
    --slate-100: #F1F5F9;
    --slate-50:  #F8FAFC;


    /* Karte: heller Grauton für Standardmodule, mittlerer Grauton für
       Assessment-Module. 90 % opak, lässt den gelben Body leicht durchschimmern.
       Niveau steht als Text-Tag unten links auf jeder Karte. */
    /* Kartenfarbe trägt zwei Informationen:
         Farbton   = Studienrichtung, aber NUR auf prägenden Modulen
         Helligkeit = Niveau (basic hell → advanced dunkel)
       Alles andere bleibt neutralgrau in derselben Abstufung, damit das Niveau
       auf jeder Karte ablesbar ist und nicht nur auf den ausgezeichneten.
       „Assessment" steht neu als Tag auf der Karte statt als dunklerer Grund. */
    /* Graustufen wie im Curriculum von spaces.informatik.fhnw.ch (Fabian):
       kein Niveau / basic / intermediate / advanced. */
    --module-bg-default:      #F5F5F5;   /* = kein Niveau */
    --module-bg-basic:        #E5E5E5;
    --module-bg-intermediate: #D4D4D4;
    --module-bg-advanced:     #A1A1A1;
    /* Fallback, solange keine Studienrichtung aktiv ist. */
    --spec-bg-basic:        var(--module-bg-basic);
    --spec-bg-intermediate: var(--module-bg-intermediate);
    --spec-bg-advanced:     var(--module-bg-advanced);
    --module-bg-assessment: rgba(210, 210, 210, 0.9);   /* nur noch Legenden-Badge */

    /* Kartenhöhe = ECTS × 23 px wie bei Fabian (3 ECTS = 69 px),
       6 px Abstand zwischen den Karten. */
    --ects-h:       23px;
    --card-gap:     6px;

    /* Layout */
    /* Feste Spaltenbreite — Spalten werden NIE schmaler, auch nicht wenn
       Kontext + GSW dazukommen. Das Brett wächst stattdessen über die
       Inhaltsbreite hinaus (siehe sizeColumnsToFitBoard). */
    --col-width:   200px;
    --col-gap:     10px;
    --card-radius: 10px;
    --col-radius:  8px;
    --badge-radius: 4px;
    /* Max-Breite der Kopfzeile (Logo, Menüs). Ab 1920 px Fensterbreite steht
       das Logo damit bündig über dem Titel. */
    --content-max: 1490px;

    --topband-h:   60px;
    --tabs-h:      52px;
    --footer-h:    48px;

    /* Card height (uniform) */
    --card-h:      69px;

    /* Drawer-Schließ-Animationsdauer; JS-Fallback nutzt den gleichen Wert */
    --drawer-out-duration: 350ms;
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    height: 100vh;
    font-family: "Inter", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
    color: var(--slate-950);
    background: var(--brand-color);
    font-size: 16px;
    line-height: 24px;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}
body { overflow: hidden; }
/* Bei Variante B (Modal) Scrollen blockieren wie bisher; Variante A (Drawer)
   lässt Board interaktiv. */
body.popover-open[data-popover="b"] .curriculum { overflow: hidden; }

/* =========================================================================
   App container
   ========================================================================= */

.curriculum {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100vh;
    overflow: auto;
    background: var(--brand-color);
}

/* =========================================================================
   Band 1 — dark slate with brand mark, language switcher and tabs.
   Aktiver Tab ist gelb und ragt 1 px in den gelben Inhalt → nahtloser Übergang.
   ========================================================================= */

.topband {
    flex: 0 0 auto;
    background: #fff;
    color: var(--slate-950);
    font-size: 14px;
    line-height: 20px;
}

.topband-row1 {
    max-width: var(--content-w, var(--content-max));
    margin: 0 auto;
    padding: 10px 24px 4px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    width: 100%;
    box-sizing: border-box;
}

/* --- Logo + Umschaltung Informatik / Data Science and AI --- */
.topband-left {
    display: flex;
    align-items: center;
    gap: 24px;
    min-width: 0;
}
.program-switch {
    display: flex;
    gap: 20px;
    overflow-x: auto;
    scrollbar-width: none;
}
.program-switch::-webkit-scrollbar { display: none; }
.program-btn {
    appearance: none;
    border: 0;
    background: transparent;
    color: var(--slate-500);
    font: inherit;
    font-size: 18px;
    line-height: 24px;
    font-weight: 600;
    padding: 4px 0;
    cursor: pointer;
    white-space: nowrap;
}
.program-btn:hover { color: var(--slate-950); }
.program-btn.active { color: var(--slate-950); font-weight: 700; cursor: default; }

/* Data Science and AI: nur Kopfzeile + iframe, das Informatik-Brett ruht */
.ds-frame { display: none; }
.curriculum.ds-view > :not(.topband):not(.ds-frame) { display: none; }
.curriculum.ds-view .ds-frame {
    display: block;
    flex: 1 1 auto;
    width: 100%;
    border: 0;
    background: #fff;
}

/* --- Brand mark (offizielles FHNW-Logo, schwarz auf weiss) --- */
.brand-mark {
    display: flex;
    align-items: center;
    text-decoration: none;
}
.brand-logo-img {
    height: 28px;
    width: auto;
    display: block;
}

/* --- Farbe je Studienrichtung ----------------------------------------------
   Ein Grundton pro Richtung, daraus drei Aufhellungen (80/60/38 % Weiss) fuer
   die Niveaustufen. Nur kuehle bis mittelwarme Toene: Gelbnachbarn wie Orange
   oder Limette verschwimmen auf dem FHNW-Gelb. Schwarzer Text erreicht auf der
   dunkelsten Stufe 7,5-9,3:1 und liegt damit ueber der AAA-Schwelle.
   data-spec wird in renderSpec() auf <body> gesetzt (aktive Studienrichtung).
   Farbe bleibt der aktiven Richtung vorbehalten — die Ergänzung ist grau. */
body[data-spec="ai_hpc"] {   /* Violett — AI & HPC */
    --spec-color:           #6D4AC4;
    --spec-bg-basic:        #E2DBF3;
    --spec-bg-intermediate: #C5B7E7;
    --spec-bg-advanced:     #A48FDA;
}
body[data-spec="gt_xr"] {   /* Magenta — Game Technologies & XR */
    --spec-color:           #BE3B84;
    --spec-bg-basic:        #F2D8E6;
    --spec-bg-intermediate: #E5B1CE;
    --spec-bg-advanced:     #D785B3;
}
body[data-spec="icomp"] {   /* Petrol — Design & Management (bisherige Auszeichnungsfarbe) */
    --spec-color:           #1488C2;
    --spec-bg-basic:        #D0E7F3;
    --spec-bg-intermediate: #A1CFE7;
    --spec-bg-advanced:     #6DB5D9;
}
body[data-spec="informatik"] {   /* Blau — Informatik (Generalist*in) */
    --spec-color:           #2F5FA8;
    --spec-bg-basic:        #D5DFEE;
    --spec-bg-intermediate: #ACBFDC;
    --spec-bg-advanced:     #7E9CC9;
}
body[data-spec="se_it"] {   /* Gruen — Software Engineering & IT */
    --spec-color:           #2E7D5B;
    --spec-bg-basic:        #D5E5DE;
    --spec-bg-intermediate: #ABCBBD;
    --spec-bg-advanced:     #7DAE99;
}
body[data-spec="spd"] {   /* Terrakotta — Security, Platforms & DevOps */
    --spec-color:           #B4472C;
    --spec-bg-basic:        #F0DAD5;
    --spec-bg-intermediate: #E1B5AB;
    --spec-bg-advanced:     #D08D7C;
}

/* --- Language switcher (DE / EN, schlicht) --- */
.topband-right {
    display: flex;
    align-items: center;
    gap: 8px;
}
.lang-btn {
    appearance: none;
    border: 0;
    background: transparent;
    color: var(--slate-500);
    font: inherit;
    font-weight: 400;
    padding: 4px 4px;
    cursor: pointer;
    font-size: 14px;
}
.lang-btn:hover { color: var(--slate-950); }
.lang-active { color: var(--slate-950); font-weight: 500; }

/* --- Tabs row 2: "Hochschule für Informatik | tab tab tab …" --- */
.topband-row2 {
    max-width: var(--content-w, var(--content-max));
    margin: 0 auto;
    padding: 0 24px 10px;
    display: flex;
    align-items: center;
    gap: 16px;
    overflow-x: auto;
    overflow-y: hidden;
    width: 100%;
    box-sizing: border-box;
}
.school-name {
    color: var(--slate-950);
    font-weight: 400;
    font-size: 15px;
    line-height: 20px;
    white-space: nowrap;
}
.row2-divider {
    width: 2px;
    height: 20px;
    background: var(--slate-950);
    flex: 0 0 auto;
}
.tabs-inner {
    display: flex;
    gap: 20px;
    align-items: center;
    flex-wrap: nowrap;
}
.tabs-inner[hidden] { display: none; }

.spec-chip {
    appearance: none;
    border: 0;
    background: transparent;
    color: var(--slate-950);
    font: inherit;
    font-size: 14px;
    line-height: 20px;
    font-weight: 400;
    padding: 4px 0;
    cursor: pointer;
    white-space: nowrap;
    position: relative;
    transition: color 0.15s ease;
}
.spec-chip:hover { color: var(--slate-700); }
.spec-chip.active {
    cursor: default;
}
/* Schwarze Unterstreichung beim aktiven Tab, direkt unter dem Text */
.spec-chip.active::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 2px;
    height: 2px;
    background: var(--slate-950);
}
.spec-chip:focus-visible {
    outline: 2px solid var(--brand-color);
    outline-offset: 3px;
}

/* =========================================================================
   Band 2 — header block (on the brand-colored body)
   ========================================================================= */

/* Einzug wie bei Fabian (Tailwind-Breakpoints md/lg/xl/2xl), damit der Titel
   beim Umschalten auf Data Science and AI nicht springt. Gilt auch für die
   Fusszeile (siehe .legend-footer-inner). */
.header-block,
.legend-footer-inner {
    --page-pl: 12px;
    --page-pr: 12px;
}
@media (min-width: 768px)  { .header-block, .legend-footer-inner { --page-pl: 72px;  --page-pr: 16px;  } }
@media (min-width: 1024px) { .header-block, .legend-footer-inner { --page-pr: 64px; } }
@media (min-width: 1280px) { .header-block, .legend-footer-inner { --page-pl: 192px; --page-pr: 80px;  } }
@media (min-width: 1536px) { .header-block, .legend-footer-inner { --page-pl: 240px; --page-pr: 240px; } }

/* Container höchstens 1920 px breit und zentriert (wie Fabians „container"):
   auf breiten Bildschirmen rückt der Titel damit zur Mitte. */
.header-block {
    flex: 0 0 auto;
    max-width: 1920px;
    margin: 0 auto;
    padding: 20px var(--page-pr) 8px var(--page-pl);
    width: 100%;
    box-sizing: border-box;
}

.page-h1 {
    margin: 0;
    font-size: 30px;
    line-height: 36px;
    font-weight: 400;
    color: #000;
}
.page-h1-bold { font-weight: 700; }
.page-h1-thin { margin-left: 8px; font-weight: 400; }

.page-desc {
    margin: 10px 0 0;
    font-size: 16px;
    line-height: 24px;
    max-width: 768px;
    color: #000;
    text-wrap: pretty;
    /* Platz für zwei Zeilen reservieren, auch wenn der Text nur eine braucht
       (Game Technologies, SPD). Sonst rückt das ganze Brett beim Umschalten
       der Studienrichtung um 20px hoch und runter. Die Zeilenzahl hängt nicht
       von der Fensterbreite ab — max-width begrenzt die Zeile vorher. */
    min-height: 48px;   /* 2 × line-height */
}
.page-desc strong { font-weight: 700; }

/* =========================================================================
   Board — CSS grid with subgrid, three rows shared across all columns
   ========================================================================= */

.board {
    flex: 1 1 auto;
    min-height: 0;
    width: 100%;   /* wie bei Fabian volle Breite, Spalten beginnen links */
    box-sizing: border-box;
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: var(--col-width);   /* fest 200 px wie bei Fabian */
    grid-template-rows: auto auto minmax(0, 1fr);
    gap: var(--col-gap);
    /* unten 20 px wie bei Fabian (pb-5): dort liegt der waagrechte Scrollbalken,
       der sich auf dem Mac sonst über die unterste Kartenreihe legt */
    padding: 12px 10px 20px;
    overflow-x: auto;
    overflow-y: hidden;
    align-content: stretch;
    transition: padding-right 0.22s ease;
}

/* Offenes Panel legt sich wie bei Fabian über das Brett; nichts rückt zur Seite. */

.status {
    grid-column: 1 / -1;
    padding: 24px;
    color: var(--slate-500);
    font-size: 14px;
}

/* Column section — spans all three rows, uses subgrid for its own children */
.col {
    grid-row: 1 / span 3;
    display: grid;
    grid-template-rows: subgrid;
    min-height: 0;
    margin-top: 1px;
    border-radius: var(--col-radius);
    background: rgba(255, 255, 255, 0.6);
    box-shadow: 0 0 0 1px #fff;
    position: relative;
    overflow: hidden;
}

/* min-width: 0 auf allen drei Grid-Kindern: ohne das wächst ein Kind über die
   Spaltenspur hinaus, sobald sein min-content breiter ist als 200px — z. B.
   „Sozialwissenschaften" als ein Wort. Die Spalte selbst bleibt 200px, der
   Inhalt ragte rechts heraus und wurde von .col{overflow:hidden} abgeschnitten. */
.col-head, .col-ects-row, .col-body { min-width: 0; }

/* Row 1 — title + watermark */
.col-head {
    grid-row: 1;
    display: flex;
    gap: 12px;
    padding: 6px 8px 0;
    position: relative;
}

.col-title {
    margin: 0;
    padding-right: 32px;
    font-size: 16px;
    line-height: 20px;
    font-weight: 700;
    color: #000;
    /* Lange Komposita dürfen trennen, statt die Spalte zu sprengen. */
    hyphens: auto;
    overflow-wrap: break-word;
    hyphens: none;
    text-wrap: pretty;
}

.col-watermark {
    position: absolute;
    top: 0;
    right: 4px;
    font-size: 72px;
    line-height: 72px;
    font-weight: 400;
    letter-spacing: -0.05em;
    color: #000;
    pointer-events: none;
    user-select: none;
}
.col-watermark .wm-d1 { opacity: 0.02; }
.col-watermark .wm-d2 { opacity: 0.06; }

/* Row 2 — ECTS line */
.col-ects-row {
    grid-row: 2;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    padding: 0 8px;
    font-size: 12px;
    line-height: 16px;
}

.col-ects {
    margin: 0 0 0 auto;
    text-align: right;
}

.col-ects .label { color: var(--slate-500); }
.col-ects .min-num,
.col-ects .total-num {
    font-family: inherit;
    font-size: 18px;
    line-height: 24.75px;
    font-variant-numeric: tabular-nums;
    margin-left: 4px;
}
.col-ects .min-num   { font-weight: 700; }
.col-ects .total-num { font-weight: 400; }

/* Row 3 — module list (scrollable). Scrollbars verborgen.
   Top-/Bottom-Fade nur wenn tatsächlich verdeckter Inhalt vorhanden ist:
   --fade-top / --fade-bottom werden von app.js auf Scroll-Position gesetzt. */
.col-body {
    grid-row: 3;
    min-height: 0;
    overflow-y: auto;
    padding: 4px 0;

    --fade-top: 0px;
    --fade-bottom: 0px;
    -webkit-mask-image: linear-gradient(
        to bottom,
        transparent 0,
        #000 var(--fade-top),
        #000 calc(100% - var(--fade-bottom)),
        transparent 100%
    );
            mask-image: linear-gradient(
        to bottom,
        transparent 0,
        #000 var(--fade-top),
        #000 calc(100% - var(--fade-bottom)),
        transparent 100%
    );
}
.col-body.fade-top    { --fade-top: 6rem; }
.col-body.fade-bottom { --fade-bottom: 6rem; }

/* Brett: Ausblendung am Rand, an dem weitere Spalten folgen (wie bei Fabian,
   12rem). --fade-left / --fade-right setzt updateBoardFade() in app.js. */
.board {
    --fade-left: 0px;
    --fade-right: 0px;
    -webkit-mask-image: linear-gradient(
        to right,
        transparent 0,
        #000 var(--fade-left),
        #000 calc(100% - var(--fade-right)),
        transparent 100%
    );
            mask-image: linear-gradient(
        to right,
        transparent 0,
        #000 var(--fade-left),
        #000 calc(100% - var(--fade-right)),
        transparent 100%
    );
}
.board.fade-left  { --fade-left: 12rem; }
.board.fade-right { --fade-right: 12rem; }

/* Scrollbalken nur in der Kopfzeile verstecken. Spalten und Brett zeigen wie
   bei Fabian die Scrollbalken des Systems. */
.topband-row2,
.topband-tabs {
    scrollbar-width: none;       /* Firefox */
    -ms-overflow-style: none;    /* alte Edge / IE */
}
.topband-row2::-webkit-scrollbar,
.topband-tabs::-webkit-scrollbar { display: none; }

/* Vertikales Raster: jede Karte = N Zeilen (N = ECTS). Karten in der
   Spalte bleiben damit auf einem festen Raster — bündig zu Nachbarspalten,
   wenn man die Spalten gleichartig befüllt. */
.col-cards {
    margin: 0 4px;
    display: flex;
    flex-direction: column;
    gap: var(--card-gap);
}
/* Curriculum: von unten aufgeschichtet wie bei Fabian. Die erste Karte im DOM
   liegt zuunterst, die Spalte füllt sich nach oben. */
.col-cards.stack-up {
    flex-direction: column-reverse;
    min-height: 100%;
}

.subgroup-label {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--slate-500);
    font-weight: 600;
    flex: none;
    margin: 6px 0 0;
    padding: 0 4px;
    /* Eine Zeile; lange Titel lieber kürzen als umbrechen. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* Minimum der Untergruppe, rechtsbündig neben ihrem Titel (nur Kontext). */
.subgroup-min {
    float: right;
    letter-spacing: 0;
    text-transform: none;
    font-weight: 400;
    color: var(--slate-400);
}



/* =========================================================================
   Module card
   ========================================================================= */

.card {
    /* Höhe = ECTS (3 = Basis), siehe --ects-h. */
    flex: none;
    height: calc(var(--ects-h) * var(--ects-span, 3));

    /* Wie bei Fabian: Name links oben, ECTS-Zahl rechts unten daneben.
       Assessment/Herkunft (falls vorhanden) unten links unter dem Namen. */
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-rows: 1fr auto;
    column-gap: 4px;
    align-content: stretch;
    padding: 6px 8px;
    border-radius: var(--card-radius);
    background: var(--module-bg, var(--module-bg-default));
    color: #000;
    font-size: 12px;
    line-height: 16px;
    box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.5);
    cursor: pointer;
    text-decoration: none;
    overflow: hidden;
    position: relative;          /* Anker für die Eck-Markierung */
    transition: filter 0.35s cubic-bezier(0, 0, 0.2, 1), background-color 0.35s cubic-bezier(0, 0, 0.2, 1);
}
.card:hover { filter: brightness(1.05); }

/* Prägendes Modul der Studienrichtung: linker Akzentbalken als eigenes Element.
   Linke Ecken folgen der Kartenrundung (overflow:hidden clippt), rechte Kante
   gerade — keine Fortsätze oben/unten. Inhalt erhält 5px mehr Platz links. */
/* Linker Akzentbalken auf ausgezeichneten Karten — trägt den gesättigten
   Grundton der Studienrichtung, nicht die Aufhellung.
   Grund: auf der Stufe „basic" liegt die Flächenfarbe nur ΔE 7–13 von der
   grauen Karte entfernt und ist damit auf dem gelben Grund praktisch nicht als
   Farbe erkennbar. Erst „advanced" trägt mit ΔE 22–43. Der Balken macht die
   Zugehörigkeit auf jeder Niveaustufe lesbar — und hilft zusätzlich bei
   Farbfehlsichtigkeit, wo Grün gegen Grau kaum steht.
   Nur auf prägenden Modulen der aktiven Studienrichtung — die Ergänzung
   bleibt vollständig grau. */
.card.signature { padding-left: 14px; }

.card.signature::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 6px;
    background: var(--spec-color);
    z-index: 1;
    pointer-events: none;
}

.card:focus-visible {
    outline: none;
    box-shadow: 0 0 0 2px rgba(21, 93, 252, 0.4);
}

/* --- Niveau = Helligkeit ---------------------------------------------------
   Neutralgrau für alle Module, die Richtungsfarbe nur für prägende. Beide
   Rampen haben dieselben drei Stufen, damit das Niveau überall gleich gelesen
   wird. Module ohne hinterlegtes Niveau (33 Stück, alle im Kontext) fallen auf
   die hellste Stufe — ihr Tag sagt „kein Niveau", die Karte behauptet nichts. */
.card[data-level="basic"],
.popover-header[data-level="basic"]        { --module-bg: var(--module-bg-basic); }
.card[data-level="intermediate"],
.popover-header[data-level="intermediate"] { --module-bg: var(--module-bg-intermediate); }
.card[data-level="advanced"],
.popover-header[data-level="advanced"]     { --module-bg: var(--module-bg-advanced); }

/* Farbe ist der aktiven Studienrichtung vorbehalten. Die Ergänzung bleibt grau —
   dort steht die Herkunft als Text im Kartenfuss, nicht als Farbe. */
.card.signature,
.popover-header.signature                            { --module-bg: var(--spec-bg-basic); }
.card.signature[data-level="intermediate"],
.popover-header.signature[data-level="intermediate"] { --module-bg: var(--spec-bg-intermediate); }
.card.signature[data-level="advanced"],
.popover-header.signature[data-level="advanced"]     { --module-bg: var(--spec-bg-advanced); }

/* Aktive Karte (im Panel geöffnet) — blauer Ring mit weissem Abstand wie bei Fabian */
.card.active {
    box-shadow: 0 0 0 1px #fff, 0 0 0 3px #155DFC;
    z-index: 1;
}

.card-name {
    grid-column: 1;
    grid-row: 1;
    align-self: start;
    font-weight: 700;
    line-height: 16.5px;
    overflow-wrap: normal;
    word-break: normal;
    hyphens: auto;
    /* Zeilenzahl nach Kartenhöhe (--name-lines setzt renderCard, Standard 2). */
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: var(--name-lines, 2);
    line-clamp: var(--name-lines, 2);
    overflow: hidden;
}

/* Assessment/Herkunft unten links unter dem Namen (siehe .card). */
.card-foot {
    grid-column: 1;
    grid-row: 2;
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
    margin-top: 4px;
}

/* Assessment — der einzige Tag auf der Karte. Das Niveau steckt in der
   Helligkeit, die Studienrichtung im Farbton, die ECTS in der Höhe; der
   Tag-Platz bleibt damit für die eine Angabe frei, die sonst nirgends steht. */
.card-source {
    font-size: 9.5px;
    line-height: 14px;
    color: rgba(0, 0, 0, 0.5);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

.card-assessment {
    font-size: 10px;
    line-height: 14px;
    padding: 1px 6px;
    border-radius: 3px;
    /* Zurückhaltend wie der frühere Niveau-Tag: eine Abtönung des Kartengrunds,
       kein Fremdkörper. Voll deckendes Schwarz wäre auf den hellen Karten der
       lauteste Punkt des ganzen Bretts — und Assessment ist eine Randnotiz,
       keine Warnung. */
    background: rgba(0, 0, 0, 0.11);
    color: var(--slate-800);
    letter-spacing: 0.02em;
    white-space: nowrap;
}

.card-ects {
    /* Zurückhaltend: der Umfang steckt schon in der Kartenhöhe, die Zahl
       bestätigt sie nur. Gleiche Grösse und Ruhe wie die übrigen Fusselemente,
       kein Fettdruck — sonst wäre die Nebensache das Lauteste auf der Karte.
       Bewusst kein Badge: das ist dem Assessment vorbehalten, das nur 10 von
       211 Modulen betrifft. Badge heisst Ausnahme, Fliesstext heisst immer da. */
    grid-column: 2;
    grid-row: 1 / span 2;
    align-self: end;
    font-size: 12px;
    line-height: 16px;
    font-weight: 400;
    color: #000;
    white-space: nowrap;
}

/* =========================================================================
   Sticky footer / legend
   ========================================================================= */

.legend-footer {
    flex: 0 0 auto;
    position: sticky;
    left: 0;
    bottom: 0;
    height: var(--footer-h);
    font-size: 12px;
    line-height: 16px;
    z-index: 5;
    background: linear-gradient(to top, var(--brand-color) 70%, transparent);
}

.legend-footer-inner {
    height: 100%;
    max-width: 1920px;
    margin: 0 auto;
    padding: 0 var(--page-pr) 0 var(--page-pl);
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 12px;
    flex-wrap: nowrap;
    overflow: hidden;
    white-space: nowrap;
    width: 100%;
    box-sizing: border-box;
}

.legend-cluster {
    display: flex;
    align-items: center;
    gap: 12px;
}
/* Trennpunkt zwischen den Gruppen der Fusszeile, wie bei Fabian */
.legend-sep { color: var(--slate-400); }

/* Anspruchsniveau als Farbfelder (wie bei Fabian) */
.legend-levels { display: inline-flex; align-items: center; gap: 8px; color: var(--slate-500); }
.legend-chips  { display: inline-flex; gap: 3px; }
.legend-chip {
    padding: 4px 6px;
    margin: 2px;
    border-radius: 4px;
    font-weight: 700;
    color: #000;
}
.legend-chip[data-level="none"]         { background: var(--module-bg-default); }
.legend-chip[data-level="basic"]        { background: var(--module-bg-basic); }
.legend-chip[data-level="intermediate"] { background: var(--module-bg-intermediate); }
.legend-chip[data-level="advanced"]     { background: var(--module-bg-advanced); }

.legend-label { color: var(--slate-500); }
/* In den Kontext-Spalten gilt „Höhe = ECTS" nicht — dort folgt die Karte dem
   Namen. Der Zusatz weicht bei knapper Breite als Erstes. */
.legend-context::before { content: "·"; margin-right: 8px; color: var(--slate-400); }
/* Fabians Teil (Stand, Anspruchsniveau) bleibt immer; die eigenen Einträge
   weichen bei knapper Breite, zuerst der Kontext. */
@media (max-width: 1599px) { .legend-context { display: none; } }
@media (max-width: 1279px) { .legend-cluster .legend-label { display: none; } }
@media (max-width: 1099px) { .legend-cluster, .legend-cluster-sep { display: none; } }
/* Unter 768 px blendet Fabian die Fusszeile ganz aus. */
@media (max-width: 767px)  { .legend-footer { display: none; } }

.badge {
    padding: 2px 8px;
    border-radius: var(--badge-radius);
    font-size: 12px;
    line-height: 16px;
    font-weight: 600;
    color: var(--slate-950);
    /* Gleicher zarte Outline wie auf den Karten — für visuelle Konsistenz */
    box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.7);
}
/* Spiegelt den Tag auf der Karte (.card-assessment), nicht mehr einen
   dunkleren Kartengrund. */
.badge-pflicht { background: rgba(0, 0, 0, 0.11); }

/* Legenden-Eintrag für das prägende Modul: kleines Farbfeld in der Farbe der
   aktiven Studienrichtung — spiegelt die echte Darstellung, seit die Karte
   selbst die Farbe trägt und der Seitenbalken entfallen ist. */
.legend-sig { display: inline-flex; align-items: center; gap: 6px; color: var(--slate-500); }
.legend-sig-dot {
    width: 14px;
    height: 14px;
    background: var(--spec-bg-intermediate);
    box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.7);
    border-left: 4px solid var(--spec-color);
    border-radius: 3px;
    flex: none;
}

.footer-stand { margin: 0; display: flex; gap: 8px; flex: none; }
.footer-stand-label { color: var(--slate-500); }
.footer-stand-date  { color: var(--slate-900); }

/* =========================================================================
   Popover (module detail) — zwei Varianten via [data-popover="a"|"b"]
   a = Side-Drawer von rechts
   b = Hero-Center-Modal (Default)
   ========================================================================= */

.popover-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(2, 6, 23, 0.55);
    z-index: 100;
    display: flex;
    overflow-y: auto;
}
.popover-backdrop[hidden] { display: none; }

.popover {
    background: #fff;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.25);
    display: flex;
    flex-direction: column;
    color: var(--slate-950);
    overflow: hidden;
    position: relative;          /* Anker für den Schliessen-Knopf */
}

.popover-loading {
    padding: 60px;
    color: var(--slate-500);
    text-align: center;
}

/* Kopf wie bei Fabian: eine Karte in der Farbe des Moduls (Niveau bzw.
   Studienrichtung, siehe .card-Regeln), darin Modulgruppe und Titel. */
.popover-header {
    flex: none;
    display: flex;
    flex-direction: column;
    margin: 5px 5px 0;
    padding: 16px 56px 16px 20px;
    border-radius: 16px;
    background: var(--module-bg, var(--module-bg-default));
    color: #000;
}

.popover-back {
    align-self: flex-start;
    border: none;
    background: rgba(255, 255, 255, 0.5);
    border-radius: 9999px;
    padding: 2px 10px;
    margin-bottom: 8px;
    font: inherit;
    font-size: 12px;
    line-height: 16px;
    font-weight: 500;
    cursor: pointer;
    color: #000;
    white-space: nowrap;
}
.popover-back:hover { background: rgba(255, 255, 255, 0.75); }

.popover-group {
    margin: 0;
    font-size: 12px;
    line-height: 16px;
    font-weight: 500;
    opacity: 0.6;
}
.popover-header h2 {
    margin: 4px 0 0;
    font-size: 24px;
    line-height: 30px;
    font-weight: 700;
    overflow-wrap: normal;
    word-break: normal;
    hyphens: auto;
}

.popover-close {
    position: absolute;
    top: 21px;
    right: 21px;
    z-index: 2;
    width: 28px;
    height: 28px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 9999px;
    background: rgba(255, 255, 255, 0.5);
    color: var(--slate-950);
    padding: 0;
    cursor: pointer;
}
.popover-close:hover { background: rgba(255, 255, 255, 0.8); }
.popover-close svg { width: 16px; height: 16px; }

/* Body — scrollt allein; Kopf und Link-Fuss bleiben stehen. Ausblendung an
   den Rändern wie bei Fabian (8rem), gesetzt von updateColBodyFade(). */
.popover-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    padding: 24px 25px;
    font-size: 16px;
    line-height: 28px;

    --fade-top: 0px;
    --fade-bottom: 0px;
    -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 var(--fade-top), #000 calc(100% - var(--fade-bottom)), transparent 100%);
            mask-image: linear-gradient(to bottom, transparent 0, #000 var(--fade-top), #000 calc(100% - var(--fade-bottom)), transparent 100%);
}
.popover-body.fade-top    { --fade-top: 8rem; }
.popover-body.fade-bottom { --fade-bottom: 8rem; }

/* Link zur Modulseite auf fhnw.ch */
.popover-foot {
    flex: none;
    padding: 12px 25px 20px;
}
.popover-link {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    font-size: 14px;
    line-height: 20px;
    color: #155DFC;
    text-decoration: none;
    text-underline-offset: 4px;
    word-break: break-all;
}
.popover-link:hover { text-decoration: underline; }
.popover-link svg { width: 16px; height: 16px; flex: none; margin-top: 2px; }

/* ===== Variante A — Side-Drawer (floating, persistent, ohne Backdrop) === */
[data-popover="a"] .popover-backdrop {
    align-items: stretch;
    justify-content: flex-end;
    padding: 10px 0;        /* schwebt mit Abstand oben/unten */
    background: transparent; /* kein Verdunkeln */
    pointer-events: none;    /* Klicks fallen durch */
    animation: none;
}
[data-popover="a"] .popover {
    pointer-events: auto;
    /* --drawer-w setzt fitDrawerToDepTree() je Modul auf die Baumbreite
       (Basis 520px, Deckel 1200px). Ohne Baum bleibt es beim Default. */
    width: min(var(--drawer-w, 560px), 92vw);
    transition: width 0.25s cubic-bezier(0.16, 1, 0.3, 1);
    height: 100%;
    max-height: none;
    background: #F8FAFC;
    border-radius: 24px 0 0 24px;  /* links abgerundet, klebt rechts an */
    border: 1px solid #E5E5E5;
    border-right: none;
    box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
    animation: slideInRight 0.4s cubic-bezier(0.16, 1, 0.3, 1) both;
}

@keyframes slideInRight {
    from { transform: translateX(110%); opacity: 0; }
    to   { transform: translateX(0);    opacity: 1; }
}
@keyframes slideOutRight {
    from { transform: translateX(0);    opacity: 1; }
    to   { transform: translateX(110%); opacity: 0; }
}
@keyframes fadeIn {
    from { background: rgba(2,6,23,0); }
    to   { background: rgba(2,6,23,0.55); }
}
@keyframes fadeOut {
    from { background: rgba(2,6,23,0.55); }
    to   { background: rgba(2,6,23,0); }
}

/* Schließen-Animationen */
[data-popover="a"] .popover.closing {
    animation: slideOutRight var(--drawer-out-duration) cubic-bezier(0.55, 0, 0.55, 0.2) both;
}
[data-popover="b"] .popover.closing {
    animation: popOut 0.18s ease-in forwards;
}
[data-popover="b"] .popover-backdrop.closing {
    animation: fadeOut 0.18s ease-in forwards;
}
@keyframes popOut {
    from { transform: scale(1);    opacity: 1; }
    to   { transform: scale(0.96); opacity: 0; }
}

/* ===== Variante B — Hero-Center-Modal ============================== */
[data-popover="b"] .popover-backdrop {
    align-items: center;
    justify-content: center;
    padding: 40px 20px;
    animation: fadeIn 0.2s ease;
}
[data-popover="b"] .popover {
    width: min(820px, 100%);
    max-height: calc(100vh - 80px);
    border-radius: 16px;
    animation: popIn 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}

@keyframes popIn {
    from { transform: scale(0.96); opacity: 0; }
    to   { transform: scale(1);    opacity: 1; }
}

@media (max-width: 600px) {
    /* Drawer-Vollbild und Variant-B-Modal-Anpassungen wandern in den 600er
       Block, damit Drawer-Fullscreen und Board-Stacking gleichzeitig greifen
       (sonst überdeckt der Drawer im Bereich 601–700 px ein noch horizontales
       Board). */
}

/* Fakten oben (Credits, Niveau, …): Raster 1:2, Trennlinien zwischen den Zeilen */
.popover-facts {
    margin: 0;
    padding-bottom: 32px;
    font-size: 14px;
    line-height: 20px;
}
.popover-facts > div {
    display: grid;
    grid-template-columns: 1fr 2fr;
    column-gap: 16px;
    position: relative;
}
.popover-facts > div + div { margin-top: 16px; }
.popover-facts > div + div::before,
.popover-section + .popover-section::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    border-top: 1px solid rgba(0, 0, 0, 0.1);
    pointer-events: none;
}
.popover-facts > div + div::before { top: -8px; }
.popover-facts dt { font-weight: 700; min-width: 0; hyphens: auto; }
.popover-facts dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }

/* Abschnitte (Inhalt, Lernziele, Voraussetzungen …) */
.popover-section { position: relative; min-width: 0; }
.popover-section + .popover-section { margin-top: 32px; }
.popover-section + .popover-section::before { top: -16px; }
.section-title {
    margin: 0;
    font-size: 18px;
    line-height: 28px;
    font-weight: 700;
    color: var(--slate-950);
    hyphens: auto;
}

/* Fliesstext wie Tailwind „prose" bei Fabian */
.field-content { margin-top: 8px; color: var(--slate-950); }
.field-content > :first-child { margin-top: 0; }
.field-content > :last-child  { margin-bottom: 0; }
.field-content p  { margin: 20px 0; }
.field-content ul, .field-content ol { margin: 20px 0; padding-left: 26px; }
.field-content li { margin: 8px 0; padding-left: 6px; }
.field-content li::marker { color: #D1D5DC; }
.field-content ol > li::marker { color: #6A7282; }
.field-content h4, .field-content h5, .field-content h6 { margin: 20px 0 8px; font-size: 16px; font-weight: 700; }

.empty {
    margin: 8px 0 0;
    color: var(--slate-500);
}

/* =========================================================================
   Vergleichs-Modal mit Spinnen-/Radar-Chart
   ========================================================================= */
.header-row {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 16px;
}

.compare-btn {
    appearance: none;
    background: transparent;
    color: var(--slate-700, #444444);
    border: 0;
    padding: 4px 0;
    font: inherit;
    font-weight: 500;
    font-size: 14px;
    cursor: pointer;
    white-space: nowrap;
    flex: 0 0 auto;
    margin-top: 6px;
    text-decoration: underline;
    text-decoration-color: rgba(0, 0, 0, 0.3);
    text-underline-offset: 4px;
    transition: color 0.15s ease, text-decoration-color 0.15s ease;
}
.compare-btn:hover {
    color: var(--slate-950);
    text-decoration-color: var(--slate-950);
}

.compare-modal {
    position: fixed;
    inset: 0;
    background: rgba(2, 6, 23, 0.30);
    z-index: 100;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    animation: fadeIn 0.2s ease;
}
.compare-modal[hidden] { display: none; }

.compare-modal-inner {
    background: #FFFFF8;
    border: 3px solid #fff;
    border-radius: 14px;
    max-width: 1100px;
    width: 100%;
    max-height: 92vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.25);
}

.compare-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    padding: 14px 20px;
    border-bottom: 1px solid var(--slate-200);
}
.spider-header-stack {
    display: flex;
    flex-direction: column;
    gap: 6px;
    flex: 1;
}
.compare-header h2 {
    margin: 0;
    font-size: 18px;
    font-weight: 700;
}
.compare-close {
    background: transparent;
    border: 0;
    font-size: 28px;
    color: rgba(0, 0, 0, 0.6);
    cursor: pointer;
    padding: 0 4px;
}
.compare-close:hover { color: var(--slate-950); }

.compare-chart-wrap {
    flex: 1;
    min-height: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 8px 16px 16px;
    overflow: hidden;        /* kein interner Scroll — SVG passt sich an */
}
.compare-svg {
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    display: block;
}

/* Header-Variante: Chooser im Header statt separater Zeile */
.compare-header--chooser {
    gap: 12px;
}
.compare-header--chooser .spider-chooser {
    flex: 1;
}

/* Spider-Chooser — als Titel-Element */
.spider-chooser {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}
.spider-pill {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 6px 12px;
    border-radius: 999px;
    background: var(--slate-50);
    font-size: 14px;
}
.spider-swatch {
    width: 12px;
    height: 12px;
    border-radius: 50%;
}
.spider-swatch[data-swatch="a"] {
    background: var(--spec-color);
}
.spider-swatch[data-swatch="b"] {
    background: var(--compare-color, var(--slate-600));
}
.spider-vs { color: var(--slate-500); }

/* Custom Dropdown — Brand-konform statt hässlichem System-<select> */
.dropdown {
    position: relative;
    display: inline-block;
}
.dropdown-trigger {
    appearance: none;
    background: transparent;
    border: 0;
    font: inherit;
    font-weight: 600;
    color: var(--slate-950);
    cursor: pointer;
    padding: 2px 0;
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.dropdown-trigger:hover .dropdown-label {
    text-decoration: underline;
    text-decoration-color: rgba(0, 0, 0, 0.3);
    text-underline-offset: 3px;
}
.dropdown-label--placeholder {
    color: var(--slate-500);
    font-weight: 500;
}
.dropdown-caret {
    width: 0;
    height: 0;
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
    border-top: 5px solid currentColor;
    opacity: 0.55;
}
.dropdown-trigger[aria-expanded="true"] .dropdown-caret {
    transform: rotate(180deg);
}
.dropdown-options {
    position: absolute;
    top: calc(100% + 8px);
    left: -10px;
    margin: 0;
    padding: 6px;
    list-style: none;
    background: #fff;
    border: 1px solid var(--slate-200);
    border-radius: 10px;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.15);
    min-width: 320px;
    max-width: 480px;
    z-index: 10;
}
.dropdown-option {
    padding: 8px 12px;
    border-radius: 6px;
    cursor: pointer;
    font-size: 14px;
    color: var(--slate-950);
    line-height: 1.3;
}
.dropdown-option:hover {
    background: var(--slate-50);
}
.dropdown-option[aria-selected="true"] {
    background: var(--brand-color);
    font-weight: 600;
}

/* Farbe der Vergleichs-Studienrichtung im Direktvergleich. data-compare wird
   beim Öffnen und beim Wechsel im Dropdown gesetzt. Dieselben Grundtöne wie auf
   dem Brett — die Farbwelt einer Studienrichtung ist überall dieselbe. */
#spider-modal[data-compare="informatik"] { --compare-color: #2F5FA8; }
#spider-modal[data-compare="ai_hpc"] { --compare-color: #6D4AC4; }
#spider-modal[data-compare="gt_xr"] { --compare-color: #BE3B84; }
#spider-modal[data-compare="icomp"] { --compare-color: #1488C2; }
#spider-modal[data-compare="se_it"] { --compare-color: #2E7D5B; }
#spider-modal[data-compare="spd"] { --compare-color: #B4472C; }

/* Spider/Radar-Chart */
.compare-svg .sp-axis,
.compare-svg .sp-ring {
    fill: none;
    stroke: var(--slate-300);
    stroke-width: 1;
}
.compare-svg .sp-label {
    fill: var(--slate-950);
    font-size: 11px;
    font-family: inherit;
}
.compare-svg .sp-poly-a {
    fill: var(--spec-color);
    fill-opacity: 0.28;
    stroke: var(--spec-color);
    stroke-width: 2;
}
/* Gestrichelt bleibt B auch dann unterscheidbar, wenn beide Farben für jemanden
   mit Farbfehlsichtigkeit ähnlich wirken. Grau, solange nichts gewählt ist. */
.compare-svg .sp-poly-b {
    fill: var(--compare-color, var(--slate-600));
    fill-opacity: 0.22;
    stroke: var(--compare-color, var(--slate-600));
    stroke-width: 2;
    stroke-dasharray: 4 3;
}
.compare-svg .sp-dot-a { fill: var(--spec-color); }
.compare-svg .sp-dot-b { fill: var(--compare-color, var(--slate-600)); }

/* Bubble-Matrix */
.compare-svg .bm-grid {
    stroke: var(--slate-300);
    stroke-width: 1;
}
.compare-svg .bm-col-label,
.compare-svg .bm-row-label {
    fill: var(--slate-950);
    font-size: 10px;
    font-family: inherit;
}
.compare-svg .bm-row-label--current {
    font-weight: 700;
}
.compare-svg .bm-bubble {
    fill: var(--slate-400);   /* helleres grau */
    fill-opacity: 0.4;        /* 60 % durchsichtig */
}
.compare-svg .bm-bubble--current {
    fill: var(--slate-500);   /* leicht dunkler für aktive Studienrichtung */
    fill-opacity: 0.5;
}

/* Voraussetzungen-Sektion im Popover */
.popover-deps {
    /* KEIN align-self: start — das ergibt in einem Column-Flex-Container
       max-content-Breite, die Sektion wächst also über das Panel hinaus und
       ihr eigenes overflow-x greift nie (scrollWidth == clientWidth). Statt
       dessen scrollte das GANZE Panel horizontal, Header inklusive.
       Default (stretch) + min-width: 0 hält die Sektion auf Panel-Breite. */
    min-width: 0;
}

/* Nur der Baum scrollt — Titel, Beschreibung und Header bleiben stehen. */
.dep-scroll {
    margin-top: 8px;
    overflow-x: auto;
    overflow-y: hidden;
    padding: 2px 0 6px;
    /* Scroll-Schatten an den Rändern: macOS blendet Scrollbalken aus, ohne
       diesen Hinweis sieht man nicht, dass der Baum weitergeht.
       (local = scrollt mit dem Inhalt und deckt den Schatten am Ende ab,
        scroll = bleibt am Rand stehen.) */
    background:
        linear-gradient(to right, #F8FAFC, rgba(248, 250, 252, 0)) 0 0 / 28px 100% no-repeat local,
        linear-gradient(to left,  #F8FAFC, rgba(248, 250, 252, 0)) 100% 0 / 28px 100% no-repeat local,
        radial-gradient(farthest-side at 0 50%, rgba(2, 6, 23, 0.16), rgba(2, 6, 23, 0)) 0 0 / 12px 100% no-repeat scroll,
        radial-gradient(farthest-side at 100% 50%, rgba(2, 6, 23, 0.16), rgba(2, 6, 23, 0)) 100% 0 / 12px 100% no-repeat scroll;
}

/* =========================================================================
   Mobile-Anpassungen (≤ 600 px) — MINIMAL
   1. Module untereinander statt nebeneinander
   2. Spalten scrollen NICHT intern, sondern wachsen mit Inhalt
   Alles andere (Header, Watermarks, Padding, Schriften) bleibt identisch.
   ========================================================================= */
@media (max-width: 600px) {
    /* Seite scrollt als Ganzes statt das Board */
    .curriculum { overflow-y: auto; overflow-x: hidden; }

    /* Board: vertikales Stacking statt Grid, kein eigener Scroll */
    .board {
        display: flex;
        flex-direction: column;
        gap: var(--col-gap);
        padding: 12px 10px 16px;
        overflow: visible;
        flex: 0 0 auto;
    }

    /* Spalte: eigenes 3-Zeilen-Grid (statt Subgrid) — bewahrt
       Titel / ECTS / Body-Layout identisch zur Desktop-Ansicht. */
    .col {
        grid-row: auto;
        display: grid;
        grid-template-rows: auto auto 1fr;
        width: 100%;
        overflow: visible;
    }
    /* Watermark (72 px hoch, absolute) braucht Platz im Titel-Bereich, sonst
       überlappt es die Mindestens-Zeile. Subgrid sorgt auf Desktop dafür. */
    .col-head { min-height: 72px; }

    /* Body: alle Karten sichtbar, kein Scroll, kein Mask */
    .col-body {
        max-height: none;
        overflow: visible;
        -webkit-mask-image: none;
                mask-image: none;
    }

    /* Drawer wird Vollbild — sonst zu schmal auf Mobile */
    [data-popover="a"] .popover-backdrop { padding: 0; }
    [data-popover="a"] .popover {
        width: 100vw;
        height: 100vh;
        border-radius: 0;
        border-left: none;
    }
    body.popover-open[data-popover="a"] .board { padding-right: 10px; }

    /* Größere Schriften auf Mobile für bessere Lesbarkeit ---------------- */
    .topband              { font-size: 16px; line-height: 22px; }
    .school-name          { font-size: 17px; line-height: 22px; }
    .lang-btn             { font-size: 16px; }
    .program-btn          { font-size: 18px; }
    .spec-chip            { font-size: 16px; line-height: 22px; }
    .col-title            { font-size: 19px; line-height: 24px; }
    .col-ects             { font-size: 14px; line-height: 18px; }
    .col-ects .min-num,
    .col-ects .total-num  { font-size: 20px; }
    .legend-label,
    .badge,
    .footer-stand-label,
    .footer-stand-date    { font-size: 13px; }
}

/* =========================================================================
   Abhängigkeitsbaum
   - Aktuelles Modul oben, darunter rekursiv die Voraussetzungen.
   - Verbindungslinien per ::before/::after-Pseudos (klassisches CSS-Tree-
     Pattern); Pfeilspitze (UP-Triangle) per ul::after am Top jedes Trunks.
   ========================================================================= */
.dep-tree,
.dep-tree ul {
    list-style: none;
    margin: 0;
    padding: 0;
}

.dep-tree {
    display: inline-block;
    padding-top: 4px;
    width: max-content;     /* lässt Baum frei wachsen → äusseres Scroll */
}

/* Nested-uls (= Kinder-Container) bekommen Top-Padding für den Trunk */
.dep-tree ul {
    padding-top: 44px;
    position: relative;
    display: flex;
    justify-content: center;
    align-items: flex-start;
}

/* li ist eine Spalte mit Karte (+ ggf. wieder nested ul darunter) */
.dep-tree li {
    text-align: center;
    list-style: none;
    position: relative;
    padding: 44px 10px 0;
}

/* Root: keine Verbindungslinie nach oben, kein Top-Padding */
.dep-tree > li { padding-top: 0; }

/* Karten haben dieselbe Breite und einheitliche Höhe (3 Zeilen, ohne ECTS-Skalierung) */
.dep-tree .card {
    width: var(--col-width);
    height: calc(var(--ects-h) * 3);
    margin: 0 auto;
    text-align: left;          /* überschreibt text-align: center vom li */
}

/* Trunk: vertikale Linie vom Kinder-ul nach oben zum Parent */
.dep-tree ul::before {
    content: '';
    position: absolute;
    top: 0;
    left: 50%;
    width: 0;
    height: 44px;
    border-left: 1.5px solid var(--slate-400);
    transform: translateX(-0.75px);
}

/* Pfeilspitze (Strich-Chevron via 45°-rotierte Border-Ecken) am Top des Trunks.
   transform-origin: top left → die Ecke (= Chevron-Spitze) bleibt fix auf dem
   Trunk-Top. */
.dep-tree ul::after {
    content: '';
    position: absolute;
    top: 0;
    left: 50%;
    width: 9px;
    height: 9px;
    border-top: 1.5px solid var(--slate-400);
    border-left: 1.5px solid var(--slate-400);
    transform: rotate(45deg);
    transform-origin: top left;
}

/* Horizontaler Balken-Stub an jedem Kind-li (linke + rechte Hälfte) */
.dep-tree ul li::before,
.dep-tree ul li::after {
    content: '';
    position: absolute;
    top: 0;
    width: 50%;
    height: 44px;
    border-top: 1.5px solid var(--slate-400);
}
.dep-tree ul li::before {
    right: 50%;
    border-right: 1.5px solid var(--slate-400);  /* vertikaler Drop zum Kind */
}
.dep-tree ul li::after { left: 50%; }

/* Einzelkind: kein Balken nötig — Trunk geht direkt zur Kindkarte */
.dep-tree ul li:only-child::before,
.dep-tree ul li:only-child::after { display: none; }
.dep-tree ul li:only-child { padding-top: 0; }

/* Aussenkanten des Balkens entfernen, damit er nicht über die Reihe hinausragt.
   ACHTUNG: nur den horizontalen Balken (border-top) abschneiden, nicht den
   vertikalen Drop (border-right) — sonst fehlt der Strich zum ersten Kind. */
.dep-tree ul li:first-child::before { border-top: 0; }
.dep-tree ul li:last-child::after   { border-top: 0; }

/* Aktuelles Modul (Root) — leichter Rahmen zur Hervorhebung */
.card.dep-current {
    box-shadow: 0 0 0 1px var(--slate-400);
    cursor: default;
}
.card.dep-current:hover {
    filter: none;
    box-shadow: 0 0 0 1px var(--slate-400);
}

.card.clickable { cursor: pointer; }


/* =========================================================================
   View-Navigation (Curriculum / Studienplan / Vergleich)
   ========================================================================= */
.view-nav { display: flex; align-items: center; gap: 20px; margin-left: auto; }
.view-link {
    appearance: none; border: 0; background: transparent; cursor: pointer;
    font: inherit; font-size: 15px; line-height: 20px; color: var(--slate-500);
    text-decoration: none; padding: 4px 0; position: relative; white-space: nowrap;
}
.view-link:hover { color: var(--slate-900); }
.view-link.active { color: var(--slate-950); font-weight: 600; }
.view-link.active::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: -2px;
    height: 2px; background: var(--slate-950);
}

/* =========================================================================
   Studienplan: Semesterspalten (gleiches .col-Design wie Curriculum) + Pool
   ========================================================================= */

/* Plan-Ansicht: Board volle Breite, rechts Platz für den fixen Pool. */
.curriculum.plan-view #board {
    max-width: none;
    padding-right: 312px;
    --col-width: 210px;
}
/* Curriculum-Legende passt nicht zur Plan-Sicht. */
.curriculum.plan-view .legend-footer { display: none; }

/* Curriculum-Edit mit offenem Modulpool: rechts Platz für die Palette. */
.curriculum.pool-open #board { max-width: none; padding-right: 312px; }

/* Suchfeld im Curriculum-Modulpool (Inc 6) */
.palette-search {
    margin-top: 8px;
    width: 100%;
    box-sizing: border-box;
    font: inherit;
    font-size: 13px;
    padding: 6px 10px;
    border: 1px solid var(--slate-300);
    border-radius: 6px;
}
.palette-search:focus-visible { outline: none; border-color: var(--slate-700); }

/* Im Edit-Mode sind Karten greifbar. */
body.edit-mode .col .card { cursor: grab; }

/* Drop-Ziel-Hervorhebung auf der Spalte (Semester & Curriculum-Gruppe) */
.col.drop-hover .col-cards {
    outline: 2px dashed var(--slate-500); outline-offset: 4px;
    border-radius: 8px; background: rgba(255, 255, 255, 0.4);
}

/* Plan-Auswahlleiste (Inc 7): mehrere Beispiel-Stundenpläne */
.plan-bar {
    max-width: var(--content-w, var(--content-max));
    margin: 0 auto 4px;
    padding: 4px 24px 8px;
    width: 100%;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
}
.plan-bar[hidden] { display: none; }
.plan-bar-label { font-size: 13px; font-weight: 600; color: var(--slate-500); }

/* Live-Bilanz unter der Plan-Leiste: Gesamt-ECTS + Gruppen-Minima */
.plan-summary {
    max-width: var(--content-w, var(--content-max));
    margin: 0 auto 8px;
    padding: 0 24px;
    width: 100%;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    font-size: 12px;
}
.plan-summary[hidden] { display: none; }
.plan-summary span {
    padding: 2px 9px;
    border-radius: 11px;
    line-height: 1.7;
    white-space: nowrap;
}
.plan-summary .ps-total { font-weight: 700; background: #eef2f9; color: var(--slate-700, #334); }
.plan-summary .ps-total.ok { background: #e3f5e3; color: #1d6b1d; }
.plan-summary .ps-total.under { background: #fff3d6; color: #8a6d00; }
.plan-summary .ps-total.over { background: #fde2e2; color: #a11; }
.plan-summary .ps-grp { background: #eef2f9; color: var(--slate-600, #556); }
.plan-summary .ps-grp.bad { background: #fde2e2; color: #a11; font-weight: 600; }
.plan-summary .ps-warn { background: #fff3d6; color: #8a6d00; font-weight: 600; cursor: help; }
.plan-summary .ps-total em { font-style: normal; font-weight: 400; opacity: 0.65; margin-left: 6px; }
.plan-summary .ps-sem { background: #eef2f9; color: var(--slate-600, #556); }
.plan-summary .ps-sem b { font-weight: 700; }
.plan-summary .ps-sem b.bad { color: #a11; }

/* Autorenwerkzeug: Ausgabe des bearbeiteten Datensatzes. */
.edit-download {
    margin-left: auto;
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    padding: 5px 14px;
    border: 1px solid var(--slate-950);
    border-radius: 999px;
    background: var(--slate-950);
    color: #fff;
    cursor: pointer;
}
.edit-download:hover { background: var(--slate-800); }
.plan-chip {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    border: 1px solid var(--slate-300);
    border-radius: 999px;
    padding: 2px 4px 2px 2px;
    background: #fff;
}
.plan-chip.active { border-color: var(--slate-950); background: var(--slate-950); }
.plan-chip-name {
    appearance: none;
    border: 0;
    background: transparent;
    font: inherit;
    font-size: 13px;
    color: var(--slate-700);
    padding: 2px 8px;
    border-radius: 999px;
    cursor: pointer;
    white-space: nowrap;
}
.plan-chip.active .plan-chip-name { color: #fff; font-weight: 600; }
.plan-ctrl {
    appearance: none;
    border: 0;
    background: transparent;
    font-size: 13px;
    line-height: 1;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    cursor: pointer;
    color: var(--slate-300);
}
.plan-chip.active .plan-ctrl { color: rgba(255, 255, 255, 0.7); }
.plan-chip.active .plan-ctrl:hover { color: #fff; background: rgba(255, 255, 255, 0.15); }
.plan-rename-input {
    font: inherit;
    font-size: 13px;
    padding: 3px 8px;
    border: 1px solid var(--slate-400);
    border-radius: 999px;
    width: 130px;
}
.plan-rename-input:focus-visible { outline: none; border-color: var(--slate-950); }
.plan-add {
    appearance: none;
    font: inherit;
    font-size: 13px;
    color: var(--slate-600);
    background: transparent;
    border: 1px dashed var(--slate-400);
    border-radius: 999px;
    padding: 4px 12px;
    cursor: pointer;
}
.plan-add:hover { border-color: var(--slate-700); color: var(--slate-950); }

/* Plan-Einstellungs-Panel (Edit-Mode) — Floating-Popover statt Mini-Buttons. */
.plan-settings-overlay {
    position: fixed;
    inset: 0;
    z-index: 60;
}
.plan-settings {
    position: fixed;
    width: 260px;
    background: #fff;
    border: 1px solid var(--slate-300);
    border-radius: 12px;
    box-shadow: 0 12px 32px rgba(15, 23, 42, 0.18);
    padding: 14px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    font-size: 13px;
}
.plan-settings .ps-head {
    font-weight: 600;
    font-size: 13px;
    color: var(--slate-950);
}
.plan-settings .ps-row {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.plan-settings .ps-label {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--slate-500);
}
.plan-settings .ps-input {
    font: inherit;
    font-size: 13px;
    padding: 7px 9px;
    border: 1px solid var(--slate-300);
    border-radius: 8px;
    background: #fff;
    width: 100%;
    box-sizing: border-box;
}
.plan-settings .ps-input:focus-visible {
    outline: none;
    border-color: var(--slate-950);
}
.plan-settings .ps-select { cursor: pointer; }
.plan-settings .ps-check {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    color: var(--slate-700);
}
.plan-settings .ps-check input[disabled] { cursor: default; }
.plan-settings .ps-actions {
    display: flex;
    justify-content: space-between;
    gap: 8px;
    margin-top: 2px;
}
.plan-settings .ps-btn {
    appearance: none;
    font: inherit;
    font-size: 13px;
    padding: 7px 14px;
    border-radius: 8px;
    border: 1px solid transparent;
    cursor: pointer;
}
.plan-settings .ps-btn-primary {
    background: var(--slate-950);
    color: #fff;
}
.plan-settings .ps-btn-danger {
    background: transparent;
    color: #b91c1c;
    border-color: var(--slate-300);
}
.plan-settings .ps-btn-danger:hover:not([disabled]) {
    border-color: #b91c1c;
    background: #fef2f2;
}
.plan-settings .ps-btn[disabled] {
    opacity: 0.4;
    cursor: default;
}

/* Einfügelinie beim Umsortieren (Inc 5, reflow-frei): liegt im Abstand zwischen
   den Karten, ohne das Layout zu verändern. */
.card.drop-before::after,
.card.drop-after::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    height: 3px;
    border-radius: 2px;
    background: var(--slate-950);
    z-index: 3;
    pointer-events: none;
}
.card.drop-before::after { top: 0; }
.card.drop-after::after  { bottom: 0; }
/* Von unten gestapelt: „vor" im DOM heisst optisch darunter. */
.stack-up .card.drop-before::after { top: auto; bottom: 0; }
.stack-up .card.drop-after::after  { bottom: auto; top: 0; }

/* Modul-Pool: fix am rechten Viewport-Rand (top/height per JS) */
.palette {
    position: fixed; right: 0; width: 300px;
    box-sizing: border-box; background: #fff; z-index: 6;
    box-shadow: -16px 0 36px rgba(0, 0, 0, 0.16);
    display: flex; flex-direction: column; border-top-left-radius: 10px;
}
.palette[hidden] { display: none; }
.palette-head { padding: 14px 16px 10px; border-bottom: 1px solid var(--slate-200); }
.palette-title { margin: 0; font-size: 14px; font-weight: 700; }
.palette-sub { margin: 3px 0 0; font-size: 12px; color: var(--slate-500); }
.palette-list {
    flex: 1 1 auto; overflow-y: auto; padding: 12px;
    display: flex; flex-direction: column; gap: 7px;
    outline: 2px dashed transparent; outline-offset: -4px;
    transition: outline-color 0.15s ease;
}
.palette.drop-hover .palette-list { outline-color: var(--slate-400); }
.palette-item {
    display: flex; justify-content: space-between; align-items: center; gap: 8px;
    padding: 8px 10px; border-radius: 6px; background: var(--module-bg-basic);
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.06); cursor: grab;
    font-size: 12px; line-height: 15px; color: #000;
}
/* Assessment wird auf der Karte als Tag gezeigt — im Pool reicht der
   normale Grund, sonst hiesse Helligkeit hier wieder etwas anderes. */
.palette-item .pi-name { overflow: hidden; }
.palette-item .pi-ects { font-weight: 600; flex: none; color: var(--slate-600); }
.palette-item.placed { opacity: 0.5; cursor: default; }

/* Plan-Karten: Drag-Cursor + Warnhinweis bei verletzter Vorbedingung */
.plan-view .col .card { cursor: grab; }
.card.dragging { opacity: 0.45; }
.card.warn { box-shadow: inset 5px 0 0 0 #c0392b, 0 0 0 1px rgba(255, 255, 255, 0.7); }
.card .warn-flag {
    position: absolute; top: 6px; right: 8px; font-size: 12px; line-height: 1;
    color: #c0392b; cursor: help;
}

/* --- Edit-Mode (Inc 1): Direktbearbeitung in der normalen Sicht --- */

/* Leiser Umschalter in der Topband (auf gelbem Grund). */
.edit-toggle {
    appearance: none;
    font: inherit;
    font-size: 13px;
    font-weight: 500;
    color: var(--slate-700);
    background: transparent;
    border: 1px solid rgba(2, 6, 23, 0.35);
    border-radius: 999px;
    padding: 3px 12px;
    margin-left: 4px;
    cursor: pointer;
    white-space: nowrap;
}
.edit-toggle:hover { border-color: var(--slate-950); color: var(--slate-950); }
.edit-toggle.active {
    background: var(--slate-950);
    border-color: var(--slate-950);
    color: #fff;
}

/* Schmale Aktionsleiste, nur im Bearbeiten-Modus sichtbar. */
.edit-bar {
    max-width: var(--content-w, var(--content-max));
    margin: 0 auto;
    padding: 0 24px;
    width: 100%;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    gap: 14px;
    font-size: 13px;
    color: var(--slate-600);
}
/* Kein leerer Streifen: ohne sichtbaren Indikator hat die Leiste 0 Höhe.
   Sobald „● Ungespeicherte Änderungen" o.ä. erscheint, bringt der Inhalt
   seine eigene Höhe + etwas Luft mit. */
.edit-bar > :not([hidden]) { padding: 6px 0; }
.edit-status { color: #1a7f37; font-weight: 600; white-space: nowrap; }
.edit-dirty { color: #c0392b; font-weight: 500; white-space: nowrap; }

/* Konflikt-Hinweis (optimistisches Sperren): jemand anderes hat gespeichert */
.edit-conflict {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    padding: 6px 10px;
    border-radius: 8px;
    background: #fff3d6;
    color: #8a4b00;
    font-size: 13px;
    font-weight: 500;
}
.edit-conflict[hidden] { display: none; }
.conflict-btn {
    border: 1px solid #c9a23a;
    background: #fff;
    color: #6b4b00;
    border-radius: 6px;
    padding: 3px 10px;
    font-size: 12px;
    cursor: pointer;
}
.conflict-btn:hover { background: #fffaf0; }
.conflict-btn-danger { border-color: #c0392b; color: #c0392b; }
.conflict-btn-danger:hover { background: #fdecea; }
.edit-save {
    appearance: none;
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    color: #fff;
    background: var(--slate-950);
    border: 0;
    border-radius: 6px;
    padding: 6px 14px;
    cursor: pointer;
    white-space: nowrap;
}
.edit-save:hover { background: var(--slate-800); }
/* Export ist nur noch sekundäres Backup → dezenter Umriss-Button. */
.edit-export {
    appearance: none;
    font: inherit;
    font-size: 13px;
    font-weight: 500;
    color: var(--slate-700);
    background: transparent;
    border: 1px solid var(--slate-300);
    border-radius: 6px;
    padding: 6px 12px;
    cursor: pointer;
    white-space: nowrap;
}
.edit-export:hover { border-color: var(--slate-700); color: var(--slate-950); }

/* Karten-Edit-Werkzeuge (Inc 2/3): Cluster oben rechts, nur im Edit-Mode. */
.card-edit-tools {
    position: absolute;
    top: 5px;
    right: 6px;
    z-index: 2;
    display: flex;
    align-items: center;
    gap: 4px;
}

/* Assessment-Umschalter: kleines „A". Aktiv = gefüllt. */
.card-assess-toggle {
    width: 16px;
    height: 16px;
    padding: 0;
    border-radius: 4px;
    border: 1px solid var(--slate-400);
    background: #fff;
    color: var(--slate-600);
    font-size: 10px;
    font-weight: 700;
    line-height: 14px;
    text-align: center;
    cursor: pointer;
}
.card-assess-toggle:hover { border-color: var(--slate-700); color: var(--slate-950); }
.card-assess-toggle.active {
    background: var(--slate-700);
    border-color: var(--slate-700);
    color: #fff;
}
.card-assess-toggle:focus-visible {
    outline: none;
    box-shadow: 0 0 0 2px var(--slate-950);
}

/* Prägend-Umschalter (Inc 2): hohler Punkt → aktiv im Signature-Petrolblau. */
.card-sig-toggle {
    width: 15px;
    height: 15px;
    padding: 0;
    border-radius: 50%;
    border: 1.5px solid var(--slate-400);
    background: #fff;
    cursor: pointer;
    line-height: 0;
}
.card-sig-toggle:hover { border-color: var(--slate-700); }
.card-sig-toggle.active {
    background: var(--signature);
    border-color: var(--signature);
}
.card-sig-toggle:focus-visible {
    outline: none;
    box-shadow: 0 0 0 2px var(--slate-950);
}

/* Entfernen-Button auf der Karte: kleines × in der Werkzeug-Leiste. */
.card-remove-btn {
    width: 16px;
    height: 16px;
    padding: 0;
    border-radius: 50%;
    border: 1px solid var(--slate-400);
    background: #fff;
    color: var(--slate-600);
    font-size: 13px;
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
    display: grid;
    place-items: center;
}
.card-remove-btn:hover {
    background: #c0392b;
    border-color: #c0392b;
    color: #fff;
}
.card-remove-btn:focus-visible {
    outline: none;
    box-shadow: 0 0 0 2px var(--slate-950);
}

/* Gruppen-Filter im Modulpool */
.palette-group {
    margin-top: 8px;
    width: 100%;
    box-sizing: border-box;
    font: inherit;
    font-size: 13px;
    padding: 6px 8px;
    border: 1px solid var(--slate-300);
    border-radius: 6px;
    background: #fff;
    cursor: pointer;
}
.palette-group:focus-visible { outline: none; border-color: var(--slate-700); }

/* =========================================================================
   Geführte Tour / „Studienreise" (read-only Discovery)
   ========================================================================= */

/* Start-Knopf in der View-Nav (CTA). Im Edit-Mode ausgeblendet. */
.tour-start {
    appearance: none;
    border: 0;
    cursor: pointer;
    font: inherit;
    font-size: 14px;
    font-weight: 600;
    color: #fff;
    background: var(--slate-950);
    border-radius: 999px;
    padding: 5px 14px;
    margin-left: 4px;
    white-space: nowrap;
}
.tour-start:hover { background: var(--slate-800); }
body.edit-mode .tour-start { display: none; }

/* Bühne: während der Tour Karten fokussieren. */
body.tour-active #board { pointer-events: none; }
body.tour-active.tour-focus #board .card { opacity: 0.18; transition: opacity 0.3s ease; }
body.tour-active.tour-focus #board .card.tour-on {
    opacity: 1;
    box-shadow: 0 0 0 2px var(--slate-950), 0 8px 22px rgba(0, 0, 0, 0.18);
}

/* Animierter Lernpfad über dem Board. */
.tour-path {
    position: fixed;
    inset: 0;
    width: 100vw;
    height: 100vh;
    pointer-events: none;
    z-index: 78;
    display: none;
}
.tour-path-line {
    fill: none;
    stroke: var(--slate-950);
    stroke-width: 3;
    stroke-linecap: round;
    stroke-linejoin: round;
}
.tour-path-dot { fill: var(--slate-950); }

/* Erzähl-Box (im Stil der bestehenden Panels). */
.tour-box {
    position: fixed;
    left: 50%;
    transform: translateX(-50%);
    bottom: 24px;
    width: min(560px, 92vw);
    background: #fff;
    border-radius: 12px;
    box-shadow: 0 16px 48px rgba(0, 0, 0, 0.22);
    padding: 18px 20px;
    z-index: 80;
}
.tour-box[hidden] { display: none; }
.tour-close {
    position: absolute;
    top: 8px;
    right: 12px;
    appearance: none;
    border: 0;
    background: transparent;
    font-size: 20px;
    line-height: 1;
    color: var(--slate-500);
    cursor: pointer;
}
.tour-close:hover { color: var(--slate-950); }
.tour-title { margin: 0 28px 0 0; font-size: 17px; font-weight: 700; color: var(--slate-950); }
.tour-stats {
    margin: 6px 0 0;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--slate-500);
}
.tour-text { margin: 8px 0 16px; font-size: 14px; line-height: 21px; color: var(--slate-800); }
.tour-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.tour-dots { display: flex; gap: 6px; }
.tour-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--slate-300); }
.tour-dot.on { background: var(--slate-950); }
.tour-actions { display: flex; gap: 8px; }
.tour-btn {
    appearance: none;
    border: 0;
    cursor: pointer;
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    color: #fff;
    background: var(--slate-950);
    border-radius: 6px;
    padding: 7px 14px;
}
.tour-btn:hover { background: var(--slate-800); }
.tour-btn:disabled { opacity: 0.4; cursor: default; }
.tour-btn-sec { background: transparent; color: var(--slate-700); border: 1px solid var(--slate-300); }
.tour-btn-sec:hover { border-color: var(--slate-700); color: var(--slate-950); }

