/* nexograph.travel — Endkundenportal.

   Die WERTE stehen in tokens.css und werden dort gepflegt. Diese Datei sagt,
   wann und warum sie eingesetzt werden; bei Widerspruch gilt DESIGN.md.

   Zwei Dinge, die beim Anfassen dieser Datei gelten:

   - KEINE festen Farbwerte. Jede Farbe kommt aus einem Token, sonst bleibt sie
     beim Dunkelmodus stehen. Der Dunkelmodus ist hier nirgends eigens
     behandelt — er entsteht allein daraus, dass die Tokens sich ändern.
   - Radien nach Hierarchie, nicht einheitlich (DESIGN.md §4.3): --r-s für
     Eingaben und Chips, --r-m für Panels, Zeilen, Bilder, --r-l NUR für das
     Suchpanel im Hero.

   Weiterhin ohne Framework und ohne nachgeladene Schriftdatei: die Seite wird
   statisch gerendert und soll auf einer Mobilverbindung sofort stehen. Die
   Familien aus DESIGN.md §4.2 stehen in den Tokens mit Rückfallkette; sobald
   Barlow Semi Condensed und Atkinson Hyperlegible selbst gehostet werden,
   genügt ein @font-face-Block und diese Datei bleibt, wie sie ist. */

*, *::before, *::after { box-sizing: border-box; }

/* 17 px Basis (DESIGN.md §4.2) als Prozentwert, NICHT als px: ein fester Wert
   überschriebe die Grundschriftgröße, die der Besucher im Browser eingestellt
   hat, und genau die brauchen Menschen, die schlecht sehen. */
html { font-size: 106.25%; }

body {
    margin: 0;
    background: var(--c-paper);
    color: var(--c-ink);
    font-family: var(--font-body);
    font-size: var(--fs-m);
    line-height: var(--lh-body);
    -webkit-font-smoothing: antialiased;
}

.sprite { display: none; }

.wrap { max-width: var(--w-content); margin: 0 auto; padding: 0 var(--sp-5); }

/* Bewegung nur als Antwort auf eine Handlung (DESIGN.md §4.3). */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
}

/* ── Text ─────────────────────────────────────────────────────────────────

   Überschriften und Preise in der schmalen Schrift, Fließtext in der gut
   lesbaren. Keine Versalien für Labels, keine Überschriften-Labels über jedem
   Abschnitt — beides steht in DESIGN.md §4.2 ausdrücklich auf der Verbotsliste
   und war im alten Stylesheet an drei Stellen im Einsatz. */

h1, h2, h3, h4 {
    font-family: var(--font-display);
    line-height: var(--lh-tight);
    font-weight: 600;
    margin: 0 0 var(--sp-3);
    text-wrap: balance;
}
h1 { font-size: var(--fs-3xl); letter-spacing: -0.01em; }
h2 { font-size: var(--fs-xl); margin-top: var(--sp-7); }
h3 { font-size: var(--fs-l); margin-top: var(--sp-5); }

p { margin: 0 0 var(--sp-4); max-width: var(--w-text); }
.lede { font-size: var(--fs-l); color: var(--c-ink-muted); max-width: var(--w-text); }
.gedaempft { color: var(--c-ink-muted); }
.klein { font-size: var(--fs-s); color: var(--c-ink-muted); }

/* Bestandsklassen aus der Vorgängerfassung — noch in Gebrauch auf Seiten, die
   diese Runde nicht umgebaut wurden. */
.muted { color: var(--c-ink-muted); }
.faint { font-size: var(--fs-s); color: var(--c-ink-muted); }

a { color: var(--c-lake); text-underline-offset: 2px; }
a:hover { color: var(--c-lake-hover); }

/* Immer 3 px, immer sichtbar, nie entfernen (DESIGN.md §4.1). */
:focus-visible {
    outline: 3px solid var(--c-focus);
    outline-offset: 2px;
    border-radius: var(--r-s);
}

/* KEIN Abstand nach oben: der Hero der Startseite beginnt unmittelbar unter
   dem Kopf, und ein Abstand hier waere ein heller Streifen ueber der dunklen
   Flaeche. Den Abstand fuer gewoehnliche Seiten setzt SeitenLayout. */
main { padding: 0 0 var(--sp-8); }

/* Zahlen, die verglichen werden, stehen untereinander. */
.zahl { font-variant-numeric: tabular-nums; }

/* ── Kopf ─────────────────────────────────────────────────────────────────

   Der Kopf bleibt ruhig: die Kategorien stehen NICHT hier, sondern am
   Suchpanel. Sie gehören zur Suche, nicht zur Seite, und DESIGN.md §3 lässt
   pro Ansicht ein auffälliges Element zu — das ist der Hero. */

header.site {
    background: var(--c-surface);
    border-bottom: 1px solid var(--c-line);
    position: sticky; top: 0; z-index: 20;
}
header.site .wrap {
    display: flex; align-items: center; gap: var(--sp-5);
    padding-top: var(--sp-3); padding-bottom: var(--sp-3);
}
.logo {
    font-family: var(--font-display);
    font-size: var(--fs-l); font-weight: 700; letter-spacing: -0.01em;
    color: var(--c-lake); text-decoration: none;
}
/* Die Wortmarke ist eine Domäne: ".travel" ist keine Beschriftung neben dem
   Namen, sondern seine zweite Hälfte. Zurückgenommen, nicht verkleinert. */
.logo span { color: var(--c-ink-muted); font-weight: 400; }

header.site nav { margin-left: auto; display: flex; gap: var(--sp-5); }
header.site nav a {
    font-size: var(--fs-s); color: var(--c-ink-muted); text-decoration: none;
    /* 44 px Mindesthöhe für Bedienelemente (DESIGN.md §7). */
    display: flex; align-items: center; min-height: 44px;
}
header.site nav a:hover { color: var(--c-lake); }

/* ── Hero (Startseite und Landeseiten) ────────────────────────────────────

   HELLER HIMMEL, nicht mehr dunkle Fläche. Ein Reiseportal soll Lust machen;
   eine tiefe Fläche als Erstes ist das Gegenteil. Der Verlauf ist zulässig,
   weil er Himmel DARSTELLT — dekorative Verläufe auf Flächen und Knöpfen
   bleiben verboten (DESIGN.md §4.4).

   Am unteren Rand ein Höhenzug, dessen vorderste Silhouette in --c-paper
   übergeht: der Übergang zur Seite ist die Bergkante selbst, keine Linie. Das
   Suchpanel liegt als weiße Karte darüber und überlappt sie.

   Die dunkle Orientierungsfläche gibt es weiterhin — sie ist jetzt der Fuß
   und die Karte, nicht der Einstieg. */

.hero {
    position: relative;
    background: linear-gradient(
        180deg, var(--c-sky) 0%, var(--c-sky-2) 58%, var(--c-paper) 100%);
    color: var(--c-ink);
    padding-top: var(--sp-8);
    /* Platz für das Panorama UND für das Suchpanel, das hineinragt. */
    padding-bottom: 150px;
    overflow: hidden;
    isolation: isolate;
}
.hero .wrap { position: relative; z-index: 2; }
.hero h1 {
    font-size: var(--fs-4xl);
    color: var(--c-ink);
    max-width: 16ch;
    margin-bottom: var(--sp-4);
}
.hero p {
    color: var(--c-ink-muted);
    font-size: var(--fs-l);
    max-width: 46ch;
    margin-bottom: 0;
}
.hero a { color: var(--c-lake); }

/* Höhenlinien und Panorama sind Dekoration und liegen deshalb als
   aria-hidden-SVG hinter dem Inhalt, nicht als Hintergrundbild: ein SVG im
   Markup skaliert mit und braucht keinen zweiten Netzaufruf. */
.hero-topo {
    position: absolute; inset: 0; width: 100%; height: 100%;
    z-index: 0; pointer-events: none;
}
.hero-sonne { position: absolute; top: var(--sp-7); right: 6%; z-index: 1; pointer-events: none; }
.hero-panorama {
    position: absolute; left: 0; right: 0; bottom: -1px;
    width: 100%; height: 190px; z-index: 1; pointer-events: none;
}

/* Das Suchpanel ragt in die helle Seite hinein. */
.hero-suche { margin-top: var(--sp-7); margin-bottom: -110px; position: relative; z-index: 3; }

@media (max-width: 760px) {
    .hero { padding-top: var(--sp-6); padding-bottom: 120px; }
    .hero h1 { font-size: var(--fs-2xl); }
    .hero p { font-size: var(--fs-m); }
    .hero-sonne { width: 74px; height: 74px; right: 8%; top: var(--sp-5); }
    .hero-panorama { height: 130px; }
    .hero-suche { margin-bottom: -90px; }
}

/* ── Suchpanel ────────────────────────────────────────────────────────────

   Das einzige Element mit --r-l und einem Schatten (DESIGN.md §4.3). */

.suchpanel {
    background: var(--c-surface);
    /* Die Textfarbe MUSS hier stehen. Im Hero liegt das Panel in einer Flaeche
       mit color: var(--c-on-night); Eingaben und Chips setzen ihre eigene
       Farbe, die nackten Labels erben. Ohne diese Zeile stehen "Land",
       "Region" und "Ausstattung" in Hell auf Weiss. */
    color: var(--c-ink);
    border: 1px solid var(--c-line);
    border-radius: var(--r-l);
    box-shadow: var(--shadow-overlay);
    padding: var(--sp-5);
}
/* Außerhalb des Hero steht dasselbe Panel ohne Schatten und mit kleinerem
   Radius — es überlagert dort nichts. */
.suchpanel.flach {
    border-radius: var(--r-m);
    box-shadow: none;
    margin-bottom: var(--sp-6);
}

/* ── Produktkategorien ────────────────────────────────────────────────────

   Der Umschalter sitzt am Suchpanel, nicht im Seitenkopf: er wechselt, WAS
   gesucht wird, und jede Kategorie bringt ihre eigene Maske mit — eine
   Strecke ist kein Ort, ein Abflugzeitpunkt kein Zeitraum (E11).

   Kategorien ohne Daten werden gezeigt und als solche gekennzeichnet. Sie zu
   verstecken wäre bequemer, aber der Umschalter behauptete dann, das Angebot
   ende bei Unterkünften. */

.kategorien {
    display: flex; flex-wrap: wrap; gap: var(--sp-1);
    margin: 0 0 var(--sp-5);
    padding: var(--sp-1);
    background: var(--c-sunken);
    border-radius: var(--r-pill);
}
.kategorie {
    display: inline-flex; align-items: center; gap: var(--sp-2);
    min-height: 44px; padding: 0 var(--sp-4);
    border-radius: var(--r-pill);
    font-size: var(--fs-s); text-decoration: none;
    color: var(--c-ink); background: transparent;
    border: 1px solid transparent;
}
.kategorie svg { width: 20px; height: 20px; flex: none; }
.kategorie:hover { background: var(--c-surface); color: var(--c-ink); }
.kategorie[aria-current="page"] {
    background: var(--c-lake); color: var(--c-on-lake);
    border-color: var(--c-lake);
}
.kategorie[aria-current="page"]:hover { background: var(--c-lake); color: var(--c-on-lake); }

/* Noch nicht buchbar. Die Kennzeichnung steht als WORT daneben, nicht nur als
   blasse Farbe — Farbe ist nie der einzige Informationsträger (DESIGN.md §7). */
/* :not(...) ist notwendig, nicht Zierde: ohne es gewinnt diese Regel gegen
   [aria-current] — gleiche Spezifitaet, spaeter notiert — und der aktive Reiter
   einer noch nicht buchbaren Kategorie stand in Grau auf Dunkelgruen. */
.kategorie.offen:not([aria-current="page"]) { color: var(--c-ink-muted); }
.kategorie .bald {
    font-size: var(--fs-xs);
    padding: 1px var(--sp-2);
    border-radius: var(--r-pill);
    background: var(--c-warn-soft); color: var(--c-warn);
    white-space: nowrap;
}

@media (max-width: 760px) {
    .kategorien { border-radius: var(--r-m); }
    .kategorie { padding: 0 var(--sp-3); }
    .kategorie .bald { display: none; }
}

/* ── Formularfelder ───────────────────────────────────────────────────────

   Sichtbare Labels über dem Feld, keine Platzhalter als Label (DESIGN.md §5). */

.felder {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    gap: var(--sp-3) var(--sp-4);
    align-items: end;
}
.feld { display: flex; flex-direction: column; gap: var(--sp-1); }
.feld label { font-size: var(--fs-s); font-weight: 700; }
.feld .hinweis-feld { font-size: var(--fs-xs); color: var(--c-ink-muted); }

/* --c-control, NICHT --c-line: der Rahmen eines Eingabefelds ist die Grenze
   eines Bedienelements und braucht 3:1 (WCAG 2.2, 1.4.11). Ein Trennstrich
   braucht das nicht, deshalb zwei Tokens. */
input, select, textarea {
    font: inherit; font-size: var(--fs-s);
    min-height: 44px; padding: var(--sp-2) var(--sp-3); width: 100%;
    border: 1px solid var(--c-control); border-radius: var(--r-s);
    background: var(--c-surface); color: var(--c-ink);
}
input[type="checkbox"] { width: auto; min-height: 0; }
input::placeholder { color: var(--c-ink-muted); }

/* Bestandsklassen der noch nicht umgebauten Seiten. */
.searchbox {
    background: var(--c-surface); border: 1px solid var(--c-line);
    border-radius: var(--r-m); padding: var(--sp-5); margin-bottom: var(--sp-6);
}
.searchgrid {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    gap: var(--sp-3) var(--sp-4); align-items: end;
}
.field { display: flex; flex-direction: column; gap: var(--sp-1); }
.field label { font-size: var(--fs-s); font-weight: 700; }
.checks { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4); font-size: var(--fs-s); }
.checks label { display: flex; align-items: center; gap: var(--sp-2); min-height: 44px; }
.checks input { width: auto; min-height: 0; }

/* ── Merkmalswahl in der Suchmaske ────────────────────────────────────────

   Merkmale mit Kategorie-Icon (DESIGN.md §5). Die Anzahl der Häuser je
   Merkmal fehlt noch — die Suchantwort liefert sie nicht. Ohne sie sind leere
   Ergebnisse für den Gast nicht vorhersehbar; das ist der wichtigste offene
   Punkt an dieser Maske. */

.merkmalswahl { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.merkmalswahl label {
    display: inline-flex; align-items: center; gap: var(--sp-2);
    min-height: 44px; padding: 0 var(--sp-3);
    border: 1px solid var(--c-control); border-radius: var(--r-pill);
    background: var(--c-surface); font-size: var(--fs-s);
    cursor: pointer;
}
.merkmalswahl label:hover { border-color: var(--c-lake); }
.merkmalswahl svg { width: 20px; height: 20px; flex: none; }
.merkmalswahl input { margin: 0; }
.merkmalswahl input:checked + svg + span { font-weight: 700; }
.merkmalswahl label:has(input:checked) {
    border-color: var(--c-lake); background: var(--c-lake-soft);
}

/* ── Knöpfe ───────────────────────────────────────────────────────────────

   --c-lake ist die Primäraktion, höchstens einer gefüllt je Gruppe.
   --c-marker gehört AUSSCHLIESSLICH dem Buchungspfad und kommt nirgends
   sonst vor — nicht für Rabatte, nicht für Hinweise, nicht als Dekoration
   (DESIGN.md §4.1). */

button, .btn {
    font-family: var(--font-body); font-size: var(--fs-s); font-weight: 700;
    min-height: 44px; padding: var(--sp-2) var(--sp-5); cursor: pointer;
    background: var(--c-lake); color: var(--c-on-lake);
    border: 1px solid var(--c-lake); border-radius: var(--r-s);
    text-decoration: none; display: inline-flex;
    align-items: center; justify-content: center; gap: var(--sp-2);
}
button:hover, .btn:hover {
    background: var(--c-lake-hover); border-color: var(--c-lake-hover);
    color: var(--c-on-lake);
}
.btn.ghost, button.ghost {
    background: transparent; color: var(--c-lake); border-color: var(--c-control);
}
.btn.ghost:hover, button.ghost:hover {
    background: var(--c-lake-soft); color: var(--c-lake-hover); border-color: var(--c-lake);
}
.btn.buchen {
    background: var(--c-marker); border-color: var(--c-marker); color: var(--c-on-marker);
}
.btn.buchen:hover { background: var(--c-marker-hover); border-color: var(--c-marker-hover); }
.btn.klein { min-height: 36px; padding: var(--sp-1) var(--sp-3); font-size: var(--fs-xs); }
.btn.breit { width: 100%; }

/* ── Ergebniskopf ─────────────────────────────────────────────────────── */

.trefferkopf {
    display: flex; align-items: baseline; gap: var(--sp-4); flex-wrap: wrap;
    margin-bottom: var(--sp-4); padding-bottom: var(--sp-3);
    border-bottom: 1px solid var(--c-line);
}
.trefferkopf h1 { margin: 0; font-size: var(--fs-2xl); }
.trefferkopf .anzahl { color: var(--c-ink-muted); font-size: var(--fs-s); }

.resulthead { /* Bestandsklasse */
    display: flex; align-items: baseline; gap: var(--sp-4); flex-wrap: wrap;
    margin-bottom: var(--sp-4); padding-bottom: var(--sp-3);
    border-bottom: 1px solid var(--c-line);
}
.resulthead h1 { margin: 0; font-size: var(--fs-2xl); }

.werkzeugleiste { display: flex; justify-content: flex-end; margin-bottom: var(--sp-4); }
.resultswitch { display: flex; justify-content: flex-end; margin-bottom: var(--sp-4); }

/* ── Ergebniszeile ────────────────────────────────────────────────────────

   ZEILEN mit variabler Höhe, keine identischen Kacheln im Raster
   (DESIGN.md §5). Der Grund ist nicht Geschmack: eine Kachel zwingt jedem
   Haus dieselbe Menge Text auf, und was nicht hineinpasst, fällt weg. Eine
   Zeile darf unterschiedlich viel tragen.

   Kein Schatten unter Ergebniszeilen. */

.treffer { display: grid; gap: var(--sp-4); }

.zeile {
    position: relative;
    display: grid;
    grid-template-columns: 280px minmax(0, 1fr) 200px;
    gap: var(--sp-5);
    background: var(--c-surface);
    border: 1px solid var(--c-line);
    border-radius: var(--r-m);
    padding: var(--sp-4);
}
.zeile:hover { border-color: var(--c-lake); }
/* Die ganze Zeile ist klickbar. Der gedehnte Link liegt UNTER allem, was
   selbst klickbar ist, damit er ihn nicht verdeckt. */
.zeile-link::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.zeile a:not(.zeile-link), .zeile button { position: relative; z-index: 2; }

/* Das Seitenverhältnis hält den Platz frei, BEVOR das Bild da ist. Ohne das
   springt die Trefferliste dem Gast unter dem Finger weg, sobald die Bilder
   nachtropfen — der häufigste Grund für Fehlklicks auf Mobilgeräten. */
.zeile-bild {
    position: relative; aspect-ratio: 4 / 3;
    background: var(--c-sunken); border-radius: var(--r-m); overflow: hidden;
}
.zeile-bild img { width: 100%; height: 100%; object-fit: cover; display: block; }
.zeile-bild.leer {
    display: flex; align-items: center; justify-content: center;
    color: var(--c-ink-muted); font-size: var(--fs-s); text-align: center; padding: var(--sp-3);
}
.zeile-bild .beispiel { position: absolute; left: var(--sp-2); bottom: var(--sp-2); }

.zeile-text { display: flex; flex-direction: column; gap: var(--sp-2); min-width: 0; }
.zeile-text .art { font-size: var(--fs-xs); color: var(--c-ink-muted); }
.zeile-text h2 {
    margin: 0; font-size: var(--fs-xl); font-weight: 700;
}
.zeile-text h2 a { color: var(--c-ink); text-decoration: none; }
.zeile:hover .zeile-text h2 a { color: var(--c-lake); }
.zeile-ort {
    display: flex; align-items: center; gap: var(--sp-2);
    font-size: var(--fs-s); color: var(--c-ink-muted);
}
.zeile-ort svg { width: 18px; height: 18px; flex: none; }

.zeile-preis {
    display: flex; flex-direction: column; align-items: flex-end;
    justify-content: flex-end; gap: var(--sp-1); text-align: right;
}
.zeile-preis .leistung { font-size: var(--fs-xs); color: var(--c-ink-muted); }
.zeile-preis .gesamt {
    font-family: var(--font-display); font-size: var(--fs-2xl); font-weight: 700;
    font-variant-numeric: tabular-nums; line-height: var(--lh-tight);
}
.zeile-preis .jenacht { font-size: var(--fs-xs); color: var(--c-ink-muted); }

/* Solange die Suchantwort keinen Preis trägt, steht hier kein Platzhalter und
   keine erfundene Zahl, sondern der Weg dorthin. */
.zeile-preis .ohnepreis {
    font-size: var(--fs-s); color: var(--c-ink-muted); max-width: 22ch;
}

@media (max-width: 1100px) {
    .zeile { grid-template-columns: 220px minmax(0, 1fr); }
    .zeile-preis {
        grid-column: 2; align-items: flex-start; text-align: left;
        border-top: 1px solid var(--c-line); padding-top: var(--sp-3);
    }
}
@media (max-width: 760px) {
    .zeile { grid-template-columns: minmax(0, 1fr); gap: var(--sp-3); }
    .zeile-preis { grid-column: 1; }
    .zeile-bild { aspect-ratio: 16 / 9; }
}

/* ── Merkmale als Chips ───────────────────────────────────────────────────

   Farbe trägt Bedeutung, aber NIE allein: immer mit Icon und Text
   (DESIGN.md §4.1).

   Die Klasse hieß früher `.tag`. Sie kollidierte mit dem `.tag` des
   Belegungskalenders — gleiche Spezifität, spätere Regel gewinnt, und die
   Merkmale bekamen aspect-ratio: 1 samt Kalenderfarben ab. Deshalb heißen
   beide jetzt nach dem, was sie sind. */

.merkmale { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.merkmal {
    display: inline-flex; align-items: center; gap: var(--sp-1);
    padding: 2px var(--sp-2);
    border-radius: var(--r-s);
    font-size: var(--fs-xs);
    background: var(--cat-comfort-soft); color: var(--cat-comfort);
}
.merkmal svg { width: 16px; height: 16px; flex: none; }
.merkmal--wasser   { background: var(--cat-water-soft);    color: var(--cat-water); }
.merkmal--berg     { background: var(--cat-mountain-soft); color: var(--cat-mountain); }
.merkmal--wellness { background: var(--cat-wellness-soft); color: var(--cat-wellness); }
.merkmal--kultur   { background: var(--cat-culture-soft);  color: var(--cat-culture); }
.merkmal--komfort  { background: var(--cat-comfort-soft);  color: var(--cat-comfort); }

/* Größere Fassung für die Detailseite: rundes Icon, Text daneben. */
.merkmalsliste {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: var(--sp-3); padding: 0; margin: 0; list-style: none;
}
.merkmalsliste li { display: flex; align-items: center; gap: var(--sp-3); font-size: var(--fs-s); }
.merkmalsliste .rund {
    display: flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; border-radius: 50%; flex: none;
}
.merkmalsliste .rund svg { width: 22px; height: 22px; }

/* Beispielbild: sichtbar, aber nicht schreierisch. Es ist eine Einordnung,
   keine Warnung. */
.beispiel {
    font-size: var(--fs-xs);
    padding: 2px var(--sp-2); border-radius: var(--r-s);
    background: var(--c-surface); color: var(--c-ink-muted);
    border: 1px solid var(--c-line);
}

/* ── Ideen-Mosaik und Zielseiten ──────────────────────────────────────────

   Kacheln unterschiedlicher Größe, eine große und vier kleine (DESIGN.md §5).
   Sie führen auf LANDESEITEN, nicht in eine Trefferliste: eine Landeseite ist
   indizierbar und altert nicht, eine Trefferliste tut beides nicht. */

/* DREI Spalten, nicht vier. Die grosse Kachel belegt 2 x 2; mit drei Spalten
   fuellen fuenf kleine die uebrigen Zellen genau auf. Bei vier Spalten bleibt
   eine angebrochene Zeile stehen. Wer Ziele hinzufuegt, achtet darauf: die
   Rechnung geht bei 1 + 5, 1 + 11, 1 + 17 auf. */
.mosaik {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-auto-rows: 180px;
    gap: var(--sp-4);
}
.kachel {
    position: relative; display: flex; flex-direction: column; justify-content: flex-end;
    min-height: 170px; padding: var(--sp-4);
    border-radius: var(--r-m); overflow: hidden;
    background: var(--c-sunken); color: var(--c-ink);
    text-decoration: none;
    border: 1px solid var(--c-line);
}
.kachel:first-child { grid-column: span 2; grid-row: span 2; }
.kachel:hover { color: var(--c-ink); border-color: var(--c-lake); }
.kachel:hover .kachel-name { text-decoration: underline; }
.kachel-bild { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; }
/* Der Text liegt AUF der Illustration. Ohne eigenen Grund haengt seine
   Lesbarkeit an dem, was zufaellig darunter gezeichnet ist - und beim ersten
   echten Foto ist das eine weisse Hauswand. */
.kachel-inhalt {
    position: relative; z-index: 1;
    display: flex; flex-direction: column; gap: var(--sp-1);
    background: var(--c-surface);
    margin: 0 calc(var(--sp-4) * -1) calc(var(--sp-4) * -1);
    padding: var(--sp-3) var(--sp-4);
}
.kachel-name { font-family: var(--font-display); font-size: var(--fs-l); font-weight: 700; }
.kachel:first-child .kachel-name { font-size: var(--fs-2xl); }
.kachel-note { font-size: var(--fs-s); color: var(--c-ink-muted); }

@media (max-width: 1100px) { .mosaik { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 760px) {
    .mosaik { grid-template-columns: 1fr; }
    .kachel:first-child { grid-column: span 1; grid-row: span 1; min-height: 170px; }
}

/* ── Hinweise, leere Zustände ─────────────────────────────────────────────

   Immer: was ist passiert, und was kann man tun — mit einer Aktion. Keine
   Entschuldigungen, keine Emojis (DESIGN.md §5). */

.notice {
    background: var(--c-surface); border: 1px solid var(--c-line);
    border-left: 3px solid var(--c-lake);
    padding: var(--sp-4) var(--sp-5); margin: 0 0 var(--sp-5);
    border-radius: var(--r-m);
}
.notice.warn { border-left-color: var(--c-warn); }
.notice.bad { border-left-color: var(--c-warn); }
.notice.good { border-left-color: var(--c-pine); }
.notice h2 { margin-top: 0; }
.notice p:last-child { margin-bottom: 0; }

.leer { text-align: center; padding: var(--sp-8) var(--sp-5); }
.leer h2 { margin-top: 0; }
.leer p { margin-left: auto; margin-right: auto; }
.empty { text-align: center; padding: var(--sp-8) var(--sp-5); }
.empty h2 { margin-top: 0; }
.empty p { margin-left: auto; margin-right: auto; }

.hinweis { font-size: var(--fs-s); color: var(--c-ink-muted); margin-top: var(--sp-3); }

.pager {
    display: flex; gap: var(--sp-3); align-items: center; justify-content: center;
    margin-top: var(--sp-7); font-size: var(--fs-s);
}

/* ── Objektseite ──────────────────────────────────────────────────────── */

.detail { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: var(--sp-7); align-items: start; }
@media (max-width: 1100px) { .detail { grid-template-columns: minmax(0, 1fr); } }

.booking-panel {
    background: var(--c-surface); border: 1px solid var(--c-line);
    border-radius: var(--r-m); padding: var(--sp-5); position: sticky; top: 84px;
}
.price {
    font-family: var(--font-display); font-size: var(--fs-2xl); font-weight: 700;
    font-variant-numeric: tabular-nums; color: var(--c-ink);
}
.price small { font-size: 0.5em; font-weight: 400; color: var(--c-ink-muted); }

table.units { width: 100%; border-collapse: collapse; font-size: var(--fs-s); }
table.units th {
    text-align: left; font-size: var(--fs-xs); font-weight: 700;
    color: var(--c-ink-muted); padding: 0 var(--sp-3) var(--sp-2) 0;
    border-bottom: 1px solid var(--c-ink);
}
table.units td {
    padding: var(--sp-3) var(--sp-3) var(--sp-3) 0;
    border-bottom: 1px solid var(--c-line); vertical-align: top;
}
table.units td.num { text-align: right; font-variant-numeric: tabular-nums; }

.galerie-titel { margin: 0 0 var(--sp-4); }
.galerie-titel img {
    width: 100%; height: auto; display: block;
    border-radius: var(--r-m); background: var(--c-sunken);
}
.galerie-titel figcaption, .galerie figcaption {
    font-size: var(--fs-xs); color: var(--c-ink-muted);
    margin-top: var(--sp-2); display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap;
}
.galerie { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: var(--sp-2); }
.galerie figure { margin: 0; }
.galerie img {
    width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block;
    border-radius: var(--r-s); background: var(--c-sunken);
}
.galerie-leer {
    border: 1px dashed var(--c-line); border-radius: var(--r-m);
    padding: var(--sp-6) var(--sp-5); text-align: center; background: var(--c-surface);
}
.galerie-leer p { margin: 0 auto var(--sp-1); font-size: var(--fs-s); }

/* ── Karte (E15) ──────────────────────────────────────────────────────────

   Dunkles Panel (DESIGN.md §5). Feste Höhe statt 100vh: die Karte sitzt unter
   Kopf und Navigation, und 100vh würde auf Mobilgeräten die Adresszeile
   mitrechnen. */

.kartekopf {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: var(--sp-4); flex-wrap: wrap; margin-bottom: var(--sp-4);
}
.kartekopf h1 { margin: 0 0 var(--sp-1); font-size: var(--fs-2xl); }
.kartekopf .lede { margin: 0; }

.karte {
    height: min(72vh, 720px);
    border: 1px solid var(--c-line);
    border-radius: var(--r-m);
    background: var(--c-night);
}
/* Leaflets eigene Flächen dürfen die dunkle Fläche nicht überstrahlen. */
.karte .leaflet-container { background: var(--c-night); border-radius: var(--r-m); }

/* Bündel und Einzelobjekte sind reines CSS — keine Bilddatei je Markierung. */
.buendel, .objekt { background: none; border: 0; }
.buendel span {
    display: flex; align-items: center; justify-content: center;
    border-radius: var(--r-pill);
    background: var(--c-lake); color: var(--c-on-lake);
    font-family: var(--font-display); font-weight: 700;
    font-variant-numeric: tabular-nums;
    border: 2px solid var(--c-surface);
    box-shadow: var(--shadow-overlay);
}
.buendel-klein span  { width: 30px; height: 30px; font-size: var(--fs-xs); }
.buendel-mittel span { width: 38px; height: 38px; font-size: var(--fs-s); }
.buendel-gross span  { width: 48px; height: 48px; font-size: var(--fs-s); }

.objekt span {
    display: block; width: 14px; height: 14px; border-radius: 50%;
    background: var(--c-surface); border: 3px solid var(--c-lake);
    box-shadow: var(--shadow-overlay);
}

.kartenblase { display: flex; flex-direction: column; gap: var(--sp-2); min-width: 170px; }
.kartenblase img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: var(--r-s); }
.kartenblase strong { font-family: var(--font-display); font-size: var(--fs-m); }
.kartenblase .beispiel { align-self: flex-start; }

/* ── Belegungskalender (E16) ────────────────────────────────────────────── */

.kalender-kopf {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--sp-3); margin-bottom: var(--sp-3);
}
.kalender-spanne { font-family: var(--font-display); font-size: var(--fs-l); font-weight: 600; }

.kalender { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: var(--sp-5); }
.monat h3 { margin: 0 0 var(--sp-2); font-size: var(--fs-m); color: var(--c-ink-muted); }

.tage { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; }
.wochentag { font-size: var(--fs-xs); text-align: center; color: var(--c-ink-muted); padding-bottom: var(--sp-1); }

/* Ein Tag ist entweder ein Link (wählbar) oder ein span (nicht wählbar).
   Beide sehen gleich aus, bis auf den Zeiger und den Fokusrahmen — ein toter
   Link wäre schlimmer als gar keiner. */
.kalendertag {
    display: flex; align-items: center; justify-content: center;
    aspect-ratio: 1; border-radius: var(--r-s);
    font-size: var(--fs-s); font-variant-numeric: tabular-nums;
    text-decoration: none; color: var(--c-ink);
    background: var(--c-sunken); border: 1px solid transparent;
}
.kalendertag.leer { background: none; }
/* Belegt: schraffiert statt nur blass — Farbe allein trägt die Auskunft
   nicht, und durchgestrichen las sich wie "gestrichener Preis". */
.kalendertag.belegt {
    color: var(--c-ink-muted); border-color: var(--c-line);
    background: repeating-linear-gradient(
        -45deg, transparent, transparent 3px, var(--c-line) 3px, var(--c-line) 4px);
}
.kalendertag.frei { background: var(--c-sunken); }
a.kalendertag.anreise, a.kalendertag.abreise {
    background: var(--c-lake-soft); border-color: var(--c-lake); font-weight: 700;
}
a.kalendertag.anreise:hover, a.kalendertag.abreise:hover {
    background: var(--c-lake); color: var(--c-on-lake);
}
.kalendertag.gewaehlt { background: var(--c-lake); color: var(--c-on-lake); font-weight: 700; }
.kalendertag.dazwischen { background: var(--c-lake-soft); }

.kalender-legende {
    display: flex; gap: var(--sp-4); flex-wrap: wrap; margin-top: var(--sp-3);
    font-size: var(--fs-xs); color: var(--c-ink-muted);
}
.kalender-legende span { display: flex; align-items: center; gap: var(--sp-2); }
.swatch { width: 14px; height: 14px; border-radius: var(--r-s); display: inline-block; flex: none; }
.swatch.frei { background: var(--c-sunken); border: 1px solid var(--c-line); }
.swatch.anreise { background: var(--c-lake-soft); border: 1px solid var(--c-lake); }
.swatch.belegt {
    border: 1px solid var(--c-line);
    background: repeating-linear-gradient(
        -45deg, transparent, transparent 3px, var(--c-line) 3px, var(--c-line) 4px);
}

.kalender-auswahl {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--sp-4); flex-wrap: wrap;
    margin-top: var(--sp-4); padding: var(--sp-3) var(--sp-4);
    border: 1px solid var(--c-line); border-radius: var(--r-m); background: var(--c-surface);
}
.kalender-auswahl strong { font-family: var(--font-display); font-size: var(--fs-l); }
.kalender-aktionen { display: flex; gap: var(--sp-2); align-items: center; }

/* ── Fuß ──────────────────────────────────────────────────────────────────

   Dunkle Orientierungsfläche (DESIGN.md §4.1). Zusammen mit dem Hero sind das
   zwei dunkle Flächen je Ansicht — das Maximum. Auf der Kartenseite trägt die
   Karte die zweite, deshalb hat sie keinen Hero. */

footer.site {
    background: var(--c-night); color: var(--c-on-night-muted);
    padding: var(--sp-6) 0; font-size: var(--fs-s);
    margin-top: var(--sp-8);
}
footer.site .wrap { display: flex; gap: var(--sp-5); flex-wrap: wrap; align-items: baseline; }
footer.site .marke { font-family: var(--font-display); font-weight: 700; color: var(--c-on-night); }
footer.site a { color: var(--c-larch); }

#blazor-error-ui { display: none; }
