/* Vianir guest surface.

   THE RAMP IS THE ONE FROM pms. globals.css there derives the whole accent
   scale from a single --brand-base with color-mix(in oklab, ...); the same
   ladder is repeated verbatim below so both surfaces compute IDENTICAL colours
   for the same house. Re-deriving it in another formula would make two brands
   out of one hex value.

   AND IT IS DECLARED TWICE ON PURPOSE. A custom property is substituted on the
   element where it is DECLARED, so a scope that sets its own --brand-base would
   inherit the already-computed ramp of the root. The [data-brand] block
   re-declares the ladder so a branded scope actually recomputes it - the same
   reason pms needs two blocks (ADR-021 N-19).

   No Tailwind. The pms guest pages are Tailwind-classed, but a node build step
   inside a .NET image buys nothing here: what has to match between the two
   surfaces is the brand contract, not the class names. */

:root {
  --brand-base: #0f6e56;              /* Vianir primary, ADR-021 N-19 */
  /* ZEIGT SEIT 2026-09-09 AUF DEN TAILWIND-TOKEN, und das ist kein Umweg,
     sondern die Auflösung eines Widerspruchs: diese Datei lädt NACH dem
     Tailwind-Bundle und gewann deshalb — die Markenschrift des Markenblatts
     erreichte die Seite gar nicht, obwohl sie im Theme stand. Gemessen am
     laufenden Server: body trug den Systemstapel.

     Eine Schriftentscheidung, an einer Stelle (app.css, --font-sans). Der
     Rückfall hier bleibt stehen, falls diese Datei ohne das Bundle geladen
     wird. */
  --brand-font: var(--font-sans, system-ui, -apple-system, "Segoe UI", sans-serif);

  /* ── NEUTRALE UND SEMANTIK: SEIT 2026-09-09 AUS DEM MARKENBLATT ───────────
     Hier stand vorher durchweg TAILWINDS STANDARDGRAU — #111827, #4b5563,
     #6b7280, #e5e7eb, #f9fafb — also blaustichige Neutrale plus Tailwinds
     Rot/Grün/Amber. Das Markenblatt sagt dazu ausdrücklich das Gegenteil: „Grau
     mit Grünstich, nicht neutral". Damit war nicht nur die Textfarbe daneben,
     sondern die ganze neutrale Skala der Gaststrecke — und das ist der Grund,
     warum die Oberfläche neben einer grünen Akzentfarbe blass aussah.

     Jetzt zeigen alle auf die Theme-Token aus app.css; die Literale bleiben als
     Rückfall, falls diese Datei ohne das Bundle geladen wird. Eine
     Farbentscheidung, an einer Stelle.

     Jeder Wert, der Text trägt, ist nachgerechnet (WCAG 2.1, auf Papiersand):
     Tiefpetrol 14,10 · ink-soft 4,61 · Primär 5,59 · Ziegelrot 6,10 ·
     Bernstein-Dunkel 8,75. Bernstein PUR liegt bei 2,41 und ist deshalb nirgends
     eine Textfarbe — das sagt das Blatt auch so. */
  --ink:        var(--color-tiefpetrol, #0C2823);
  --ink-muted:  var(--color-ink-soft, #5F726C);
  /* Kein dritter, hellerer Schritt: `--ink-faint` trägt Text auf 0,8125rem, und
     eine Stufe unter ink-soft fällt unter 4,5. Das Blatt nennt auch keinen. */
  --ink-faint:  var(--color-ink-soft, #5F726C);
  --line:       var(--color-rule, #D6D2C7);
  --line-strong:var(--color-rule-strong, #B9B4A6);
  /* Karten bleiben weiß — der Kontrast gegen Papiersand ist die Trennung. */
  --paper:      #ffffff;
  --ground:     var(--color-papiersand, #F5F3EE);

  /* Fehler: dasselbe Ziegelrot wie `y-danger`, weil zwei Rottöne auf einer
     Oberfläche zwei Bedeutungen behaupten, die es nicht gibt. */
  --danger:     var(--color-y-danger, #A4342A);
  --danger-bg:  color-mix(in oklab, var(--color-y-danger, #A4342A) 8%, var(--color-papiersand, #F5F3EE));
  --danger-line:color-mix(in oklab, var(--color-y-danger, #A4342A) 30%, var(--color-papiersand, #F5F3EE));

  /* Gut: die Hausfarbe selbst. Ein zweites Grün neben Primär wäre eine
     Unterscheidung ohne Aussage. */
  --good:       var(--color-primaer, #0F6E56);
  --good-bg:    color-mix(in oklab, var(--color-primaer, #0F6E56) 8%, white);
  --good-line:  color-mix(in oklab, var(--color-primaer, #0F6E56) 30%, white);

  /* Warnung: Bernstein ist die Gegenfarbe des Blatts, pur aber nur 2,41 und
     damit keine Textfarbe. Für Text auf 55 % Schwarz gemischt (8,75), Fläche
     und Linie als helle Tönungen. */
  --warn:       color-mix(in oklab, var(--color-bernstein, #E8853A) 55%, black);
  --warn-bg:    color-mix(in oklab, var(--color-bernstein, #E8853A) 10%, var(--color-papiersand, #F5F3EE));
  --warn-line:  color-mix(in oklab, var(--color-bernstein, #E8853A) 35%, var(--color-papiersand, #F5F3EE));

  --radius:    10px;
  --radius-sm: 6px;
  --shadow:    0 1px 2px rgba(17, 24, 39, .06), 0 1px 3px rgba(17, 24, 39, .08);
}

:root,
[data-brand] {
  --brand-50:  color-mix(in oklab, var(--brand-base) 8%,  white);
  --brand-100: color-mix(in oklab, var(--brand-base) 16%, white);
  --brand-200: color-mix(in oklab, var(--brand-base) 30%, white);
  --brand-300: color-mix(in oklab, var(--brand-base) 48%, white);
  --brand-400: color-mix(in oklab, var(--brand-base) 72%, white);
  --brand-500: color-mix(in oklab, var(--brand-base) 88%, white);
  --brand-600: var(--brand-base);
  --brand-700: color-mix(in oklab, var(--brand-base) 82%, black);
  --brand-800: color-mix(in oklab, var(--brand-base) 66%, black);
  --brand-900: color-mix(in oklab, var(--brand-base) 50%, black);
}

*, *::before, *::after { box-sizing: border-box; }

html, body { margin: 0; padding: 0; }

body {
  font-family: var(--brand-font);
  font-size: 16px;
  line-height: 1.5;
  color: var(--ink);
  background: var(--ground);
  -webkit-text-size-adjust: 100%;
}

h1, h2, h3 { line-height: 1.25; margin: 0 0 .5rem; }
h1 { font-size: 1.5rem; font-weight: 700; }
h2 { font-size: 1.125rem; font-weight: 650; }
h3 { font-size: 1rem; font-weight: 600; }
p  { margin: 0 0 .75rem; }

a { color: var(--brand-700); }
a:hover { color: var(--brand-800); }

/* -- Geruest ------------------------------------------------------------ */

.shell { min-height: 100vh; display: flex; flex-direction: column; }
.shell > main { flex: 1; }

.wrap        { max-width: 56rem; margin: 0 auto; padding: 1.5rem 1rem 3rem; }
.wrap-narrow { max-width: 30rem; margin: 0 auto; padding: 2.5rem 1rem 3rem; }

.topbar { background: var(--paper); border-bottom: 1px solid var(--line); }
.topbar-inner {
  max-width: 56rem; margin: 0 auto; padding: .75rem 1rem;
  display: flex; align-items: center; gap: 1rem;
}
.topbar-brand {
  display: flex; align-items: center; gap: .625rem;
  font-weight: 700; color: var(--ink); text-decoration: none;
}
.topbar-brand img { height: 28px; width: auto; }
.topbar-spacer { flex: 1; }

.footer {
  border-top: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink-faint);
  font-size: .8125rem;
}
.footer-inner {
  max-width: 56rem; margin: 0 auto; padding: 1rem;
  display: flex; gap: 1rem; flex-wrap: wrap;
}
/* Die Adresse eines Hauses, wie pms sie speichert: MEHRZEILIG.
   `pre-line` haelt die gespeicherten Umbrueche und faltet alles andere
   (doppelte Leerzeichen, Einrueckung) wie gewohnt zusammen.

   Ohne das war es ein echter Anzeigefehler und kein Schoenheitsfehler: HTML
   faltet einen Umbruch zu einem LEERZEICHEN, der Gast las also
   „Mornewegstrasse 43 64293 Darmstadt" — Hausnummer direkt an der
   Postleitzahl. In den Metadaten loesen wir dasselbe Problem mit einem Komma
   (HotelSeoData.SingleLine), weil eine Beschreibung eine Zeile ist; hier ist
   mehr Platz, und zwei Zeilen sind die Form, in der eine Adresse gelesen
   wird. */
.adresse { white-space: pre-line; }

/* Zuschreibungszeile mit der Wortmarke am Ende. `baseline` statt `center`,
   damit der Bogen auf derselben Schriftlinie sitzt wie das vorangehende Wort —
   er ERSETZT ein `n`, also muss er wie ein Buchstabe stehen. Die Marke bleibt
   bewusst dunkler als der Fusstext (--ink-faint): sie ist eine Marke und kein
   Satzteil. */
.footer-marke {
  display: inline-flex; align-items: baseline; gap: .3em;
}

/* -- Karten und Listen -------------------------------------------------- */

.card {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.25rem;
  box-shadow: var(--shadow);
}
.card + .card { margin-top: 1rem; }
.card-tight { padding: .875rem 1rem; }

.stack    > * + * { margin-top: .75rem; }
.stack-lg > * + * { margin-top: 1.25rem; }
.row { display: flex; gap: .75rem; flex-wrap: wrap; align-items: center; }
.grid-2 { display: grid; gap: .75rem; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); }

.muted { color: var(--ink-muted); }
.faint { color: var(--ink-faint); font-size: .8125rem; }
.mono  { font-variant-numeric: tabular-nums; }

.code-badge {
  display: inline-block;
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: 1.375rem;
  font-weight: 700;
  letter-spacing: .18em;
  padding: .5rem .875rem;
  border-radius: var(--radius-sm);
  background: var(--brand-50);
  color: var(--brand-900);
  border: 1px solid var(--brand-200);
}

.kv { display: grid; grid-template-columns: auto 1fr; gap: .25rem 1rem; font-size: .9375rem; }
.kv dt { color: var(--ink-faint); }
.kv dd { margin: 0; }

.total-line {
  display: flex; justify-content: space-between; gap: 1rem;
  padding: .3125rem 0; font-size: .9375rem;
}
.total-line.sum {
  border-top: 1px solid var(--line-strong);
  margin-top: .375rem; padding-top: .625rem;
  font-weight: 700; font-size: 1.0625rem;
}

/* -- Formulare ---------------------------------------------------------- */

label.field { display: block; }
label.field > span {
  display: block; font-size: .8125rem; font-weight: 600;
  color: var(--ink-muted); margin-bottom: .25rem;
}

/* DIESE VORGABE GEHOERT IN `base`, und das ist der ganze Punkt: sie MUSS sich
   von einer Utility ueberschreiben lassen.

   Woran es aufgefallen ist (19.09.2026): im Zeitraumfeld lagen Kalendersymbol
   und Datum uebereinander. YDateRange setzt sich `pl-[50px]`, damit links Platz
   fuer sein Symbol bleibt — die Regel steht im Bundle, sie kam nur nie an. Zwei
   Gruende, jeder fuer sich schon toedlich: eine Regel OHNE Schicht schlaegt
   jede Regel MIT Schicht, und `input[type=text]` ist spezifischer als eine
   einzelne Klasse. Am laufenden Server gemessen, nicht geschlossen:
   padding-left 12px statt 50px, padding-right 12px statt 32px — und das Symbol
   sitzt bei 20px, also mitten im Text.

   `@layer base` stellt die Regel dorthin, wo Tailwind seine eigenen
   Element-Vorgaben haelt: sie gilt weiter fuer jedes nackte Feld dieser
   Oberflaeche (nichts anderes beansprucht diese Eigenschaften) und verliert
   genau dann, wenn ein Control ausdruecklich etwas anderes sagt. Innerhalb der
   Schicht entscheidet die Reihenfolge, und diese Datei laedt nach dem Bundle —
   gegen Tailwinds Preflight gewinnt sie also weiterhin.

   DER NAME IST NICHT FREI WAEHLBAR. Die Reihenfolge der Schichten entsteht beim
   ersten Auftreten, und das Bundle fuehrt `base` vor `utilities`. Ein eigener
   Name — `@layer vianir` — waere eine NEUE Schicht, kaeme ans Ende und gewaenne
   wieder gegen die Utilities. Der Fehler waere zurueck, nur schwerer zu
   finden. */
@layer base {
  input[type=text], input[type=email], input[type=tel], input[type=date],
  input[type=number], select, textarea {
    width: 100%;
    font: inherit;
    color: var(--ink);
    background: var(--paper);
    padding: .5625rem .75rem;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
  }
}
input:focus-visible, select:focus-visible, textarea:focus-visible,
button:focus-visible, a:focus-visible {
  outline: 2px solid var(--brand-600);
  outline-offset: 1px;
}
input.reference { text-transform: uppercase; letter-spacing: .18em; }
input.pin       { letter-spacing: .3em; }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  font: inherit; font-weight: 600;
  padding: .625rem 1rem;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
}
.btn:disabled { opacity: .5; cursor: default; }
.btn-primary { background: var(--brand-600); color: #fff; }
.btn-primary:hover:not(:disabled) { background: var(--brand-700); color: #fff; }
/* -- Das Gastmenue (GUEST-MENU-1) --------------------------------------- *
 *
 * Drei Ziele, eine Zeile, und auf dem Telefon umbrechend statt abgeschnitten.
 * Bewusst KEINE Knoepfe: das hier ist Wegweisung, keine Handlung — die
 * Hauptsache der Seite (speichern, abreisen, zahlen) muss die einzige Flaeche
 * bleiben, die wie ein Knopf aussieht.
 *
 * Die aktuelle Seite steht als TEXT da, nicht als Verweis auf sich selbst.     */
.gastmenue {
  display: flex; flex-wrap: wrap; gap: .25rem 1rem;
  font-size: .9375rem;
  padding-bottom: .625rem;
  border-bottom: 1px solid var(--line);
  margin-bottom: .25rem;
}
.gastmenue a { color: var(--brand-700); }
.gastmenue-hier { color: var(--ink); font-weight: 600; }

.btn-quiet { background: var(--paper); color: var(--ink); border-color: var(--line-strong); }
.btn-quiet:hover:not(:disabled) { background: var(--ground); color: var(--ink); }
.btn-block { width: 100%; }
.btn-link {
  background: none; border: none; padding: 0;
  color: var(--brand-700); cursor: pointer; font: inherit; text-decoration: underline;
}

.tabs { display: flex; gap: .5rem; border-bottom: 1px solid var(--line); margin-bottom: 1rem; }
.tabs button {
  font: inherit; font-weight: 600; cursor: pointer;
  background: none; border: none; border-bottom: 2px solid transparent;
  padding: .5rem .25rem; color: var(--ink-faint);
}
.tabs button[aria-selected=true] { color: var(--brand-700); border-bottom-color: var(--brand-600); }

/* -- Meldungen ---------------------------------------------------------- */

.note { border-radius: var(--radius-sm); padding: .625rem .75rem; font-size: .875rem; border: 1px solid; }
.note-error { background: var(--danger-bg); border-color: var(--danger-line); color: var(--danger); }
.note-good  { background: var(--good-bg);   border-color: var(--good-line);   color: var(--good); }
.note-warn  { background: var(--warn-bg);   border-color: var(--warn-line);   color: var(--warn); }
.note-plain { background: var(--ground);    border-color: var(--line);        color: var(--ink-muted); }

/* -- Hausinfos (pms ADR-033) -------------------------------------------- */

/* Der Text kommt als fertiges HTML aus pms, gewandelt gegen eine Positivliste
   (Absaetze, h3-h6, Listen, fett, kursiv, Verweise). Hier bekommt er nur
   Abstaende — die Marke des Hauses liefert BrandScope. */
.prose > * + *   { margin-top: .75rem; }
.prose h3        { font-size: 1.0625rem; }
.prose h4,
.prose h5,
.prose h6        { font-size: .9375rem; }
.prose ul,
.prose ol        { padding-left: 1.25rem; }
.prose li + li   { margin-top: .25rem; }
.prose a         { color: var(--brand-700); text-decoration: underline; }

/* -- Rechnungsanschrift in der Check-out-Bestaetigung -------------------- */

/* <address> ist in jedem Browser kursiv voreingestellt. Eine Anschrift, die
   der Gast auf Richtigkeit pruefen soll, liest sich aufrecht besser. */
.billto { font-style: normal; line-height: 1.5; color: var(--ink); }
.warn-text { color: var(--warn); }

/* -- Schritte ----------------------------------------------------------- */

.steps ol { display: flex; gap: .75rem; padding: 0; margin: 0 0 1.25rem; flex-wrap: wrap; font-size: .8125rem; }
.steps li { list-style: none; display: flex; align-items: center; gap: .375rem; color: var(--ink-faint); }
.steps li[aria-current=step] { color: var(--brand-700); font-weight: 650; }
.steps li .dot {
  width: 1.375rem; height: 1.375rem; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line-strong); font-size: .75rem;
}
.steps li[aria-current=step] .dot { background: var(--brand-600); border-color: var(--brand-600); color: #fff; }
.steps li.done .dot { background: var(--brand-100); border-color: var(--brand-300); color: var(--brand-900); }

/* -- Zimmer und Treffer ------------------------------------------------- */

.room {
  display: flex; gap: 1rem; align-items: flex-start; justify-content: space-between;
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: .875rem 1rem; background: var(--paper);
}
.room + .room { margin-top: .625rem; }
.room.selected { border-color: var(--brand-500); box-shadow: 0 0 0 1px var(--brand-500) inset; }
/* Ausgebucht: sichtbar, aber sichtbar nicht waehlbar. Zurueckgenommen statt
   versteckt — eine Zimmerart zu verbergen liesse den Gast glauben, das Haus
   habe sie gar nicht. */
.room.room-soldout { opacity: .62; }
.room-price { text-align: right; white-space: nowrap; }
.room-price .big { font-size: 1.125rem; font-weight: 700; }

.hit { border: 1px solid var(--line); border-radius: var(--radius); background: var(--paper); padding: 1rem; }
.hit + .hit { margin-top: .75rem; }
.hit-head { display: flex; gap: 1rem; justify-content: space-between; align-items: flex-start; }

/* -- Geraete ------------------------------------------------------------ */

.device { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: .75rem; }
.device + .device { margin-top: .5rem; }
.device-name { font-weight: 600; }

.spinner {
  display: inline-block; width: 1rem; height: 1rem;
  border: 2px solid var(--brand-200); border-top-color: var(--brand-600);
  border-radius: 999px; animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spinner { animation-duration: 2s; } }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
