/*
 * MWFewoManager
 *
 * @author Küstenweb GmbH <info@mwfewomanager.de>
 * @copyright mwfewomanager.de
 */

:root {
    --font-family-sans-serif: system-ui, -apple-system, Segoe UI, Roboto, Inter, Arial, sans-serif;
    --font-size-base: 16px;
    --line-height: 1.5;

    /* Core */
    --color-primary: #0072ce;
    --color-primary-hover: #005fa3;
    --color-secondary: #6b7280;
    --color-secondary-hover: #4b5563;
    --color-bg: #ffffff;
    --color-surface: #ffffff;
    --white: #ffffff;
    --border-color: #e3e8ee;
    --color-border: var(--border-color);
    --color-text: #1f2937;
    --color-muted: #6b7280;
    /* Forms */
    --form-label-color: var(--color-text);

    --color-success: #10b981;
    --color-danger: #ef4444;
    --color-warning: #f59e0b;
    --color-info: #3b82f6;

    /* Akzentfarbe (z.B. Sterne/Bewertungen, Highlights) */
    --color-accent: #f59e0b;
    --color-accent-hover: #d97706;

    /* Flächen / Text-Aliase */
    --color-surface-alt: #f8fafc;
    --color-text-muted: var(--color-muted);

    /* --------------------------------------------------
       Skalen (Radius / Schatten / Abstände / Schriftgrößen)
       Diese Tokens werden von den Bundle-Komponenten genutzt und können
       im Theme (theme.css) per Token-Brücke auf die eigene Palette
       gemappt werden — siehe theme.css.
    -------------------------------------------------- */

    /* Radius-Skala */
    --radius-sm: 6px;
    --radius-md: 12px;
    --radius-card: 16px;
    --border-radius: 8px;
    --radius-button: var(--border-radius);
    --radius-lg: 16px;
    --radius-pill: 999px;

    /* Schatten-Skala */
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, .06), 0 1px 3px rgba(0, 0, 0, .05);
    --shadow-md: 0 6px 14px rgba(0, 0, 0, .08), 0 2px 4px rgba(0, 0, 0, .05);
    --shadow-lg: 0 18px 40px rgba(0, 0, 0, .12), 0 4px 12px rgba(0, 0, 0, .06);
    --shadow-card: 0 4px 12px rgba(0, 0, 0, .08);

    /* Abstands-Skala (4px-Raster) */
    --space-1: 0.25rem;
    --space-2: 0.5rem;
    --space-3: 0.75rem;
    --space-4: 1rem;
    --space-5: 1.25rem;
    --space-6: 1.5rem;
    --space-8: 2rem;
    --space-10: 2.5rem;
    --space-12: 3rem;
    --space-16: 4rem;
    --space-20: 5rem;
    --space-24: 6rem;

    /* Schriftgrößen-Skala (T-Shirt-Sizes, ergänzend zu --font-size-h1..h6) */
    --font-size-xs: 0.8125rem;
    --font-size-sm: 0.9375rem;
    --font-size-md: 1.0625rem;
    --font-size-lg: 1.25rem;
    --font-size-xl: 1.625rem;
    --font-size-2xl: 2.125rem;
    --font-size-3xl: 2.75rem;

    /* Layout / Motion */
    --container: 1200px;
    --transition: 200ms cubic-bezier(.2, .7, .3, 1);

    /* --------------------------------------------------
       Picker Tokens (shared)
    -------------------------------------------------- */

    /* Tooltip (Datepicker) */
    --tooltip-bg: var(--color-text);
    --tooltip-fg: var(--white);

    /* --------------------------------------------------
       Calendar Theme Tokens (project overrides)
    -------------------------------------------------- */

    --calendar-cell-width: 46px;
    --calendar-cell-height: 46px;
    --calendar-check-label-fg: var(--white);
    --calendar-price-on-check-fg: var(--white);
    --calendar-day-hover-bg: color-mix(in srgb, var(--color-primary) 8%, var(--color-surface));

    /* === Kalenderfarben: Hintergründe === */
    --calendar-bg-free: #eaf7ef;
    --calendar-bg-booked: #f6d2d2;
    --calendar-bg-blocked: #e0e0e0;
    --calendar-bg-owner: #ffe5b4;
    --calendar-bg-edit: #fff7d1;
    --calendar-bg-selected: #eaf3ff;
    --calendar-bg-check: #0072ce;

    /* === Kalenderfarben: Schrift/Iconfarben === */
    --calendar-fg-free: #46594d;
    --calendar-fg-booked: #e2a1a1;
    --calendar-fg-blocked: #bcbcbc;
    --calendar-fg-owner: #f3b97e;
    --calendar-fg-edit: #f0c36d;
    --calendar-fg-selected: #82b5f7;
    --calendar-fg-check: #fff;

    /* === Kalenderfarben: Rahmen (Borders) === */
    --calendar-border-free: #b3dfc1;
    --calendar-border-booked: #e2a1a1;
    --calendar-border-blocked: #bcbcbc;
    --calendar-border-owner: #f3b97e;
    --calendar-border-edit: #f0c36d;
    --calendar-border-selected: #82b5f7;
    --calendar-border-check: #0059a8;

    /* --------------------------------------------------
       Headings (Typography Tokens)
    -------------------------------------------------- */

    --font-family-heading: var(--font-family-sans-serif);
    --heading-color: var(--color-text);

    --font-size-h1: 2rem;
    --font-size-h2: 1.75rem;
    --font-size-h3: 1.5rem;
    --font-size-h4: 1.25rem;
    --font-size-h5: 1.125rem;
    --font-size-h6: 1rem;

    /* --------------------------------------------------
       Links (Color Tokens)
    -------------------------------------------------- */

    --link-color: var(--color-primary);
    --link-hover-color: var(--color-primary-hover);
    --link-visited-color: color-mix(in srgb, var(--color-primary) 70%, #6b7280);
    --link-active-color: var(--color-primary-hover);

    --link-decoration: underline;
    --link-hover-decoration: underline;
    --link-focus-ring: 0 0 0 3px color-mix(in srgb, var(--color-primary) 25%, transparent);

    /* --------------------------------------------------
       Buttons (Color Tokens)
    -------------------------------------------------- */

    /* Primary */
    --btn-primary-bg: var(--color-primary);
    --btn-primary-bg-hover: var(--color-primary-hover);
    --btn-primary-text: var(--white);
    --btn-primary-text-hover: var(--white);
    --btn-primary-border: var(--color-primary);

    /* Secondary */
    --btn-secondary-bg: var(--color-secondary);
    --btn-secondary-bg-hover: var(--color-secondary-hover);
    --btn-secondary-text: var(--white);
    --btn-secondary-text-hover: var(--white);
    --btn-secondary-border: var(--color-secondary);

    /* Clear */
    --btn-clear-bg: transparent;
    --btn-clear-text: var(--color-muted);
    --btn-clear-border: var(--border-color);

    /* Cancel */
    --btn-cancel-bg: transparent;
    --btn-cancel-text: var(--color-text);
    --btn-cancel-border: var(--border-color);

    /* Apply (Success) */
    --btn-apply-bg: var(--color-success);
    --btn-apply-bg-hover: color-mix(in srgb, var(--color-success) 85%, #000 10%);
    --btn-apply-text: var(--white);
    --btn-apply-text-hover: var(--white);
    --btn-apply-border: var(--color-success);

    /* Book */
    --btn-book-bg: var(--color-primary);
    --btn-book-bg-hover: var(--color-primary-hover);
    --btn-book-text: var(--white);
    --btn-book-text-hover: var(--white);
    --btn-book-border: var(--color-primary);

    /* Request */
    --btn-request-bg: var(--color-warning);
    --btn-request-bg-hover: color-mix(in srgb, var(--color-warning) 85%, #000 10%);
    --btn-request-text: var(--white);
    --btn-request-text-hover: var(--white);
    --btn-request-border: var(--color-warning);

    /* Danger */
    --btn-danger-bg: var(--color-danger);
    --btn-danger-bg-hover: color-mix(in srgb, var(--color-danger) 85%, #000 10%);
    --btn-danger-text: var(--white);
    --btn-danger-text-hover: var(--white);
    --btn-danger-border: var(--color-danger);

    /* Increment / Decrement (Stepper) */
    --btn-stepper-bg: var(--color-surface);
    --btn-stepper-bg-hover: color-mix(in srgb, var(--color-primary) 8%, var(--color-surface));
    --btn-stepper-text: var(--color-text);
    --btn-stepper-border: var(--border-color);
}
/*
 * MWFM Frontend — Theme-Overrides
 *
 * Diese Datei gehört DIR. Sie wird vom Install-Command einmalig angelegt
 * und beim Bundle-Update NICHT überschrieben. Hier definierst du dein
 * Branding, indem du die in root.css definierten Tokens überschreibst.
 *
 * Lade-Reihenfolge: theme.css MUSS nach root.css und vor base.css geladen
 * werden — siehe README.md.
 *
 * Alle verfügbaren Tokens findest du in root.css. Beispiele unten zur
 * Inspiration. Lösche, was du nicht brauchst, oder lass das ganze File
 * leer — dann gilt der Default aus root.css.
 */

:root {
    /* ----- Marke ---------------------------------------------------- */
    /* --color-primary: #d4145a;        */
    /* --color-primary-hover: #a30f47;  */
    /* --color-secondary: #6b7280;      */
    /* --color-secondary-hover: #4b5563; */

    /* ----- Typografie ---------------------------------------------- */
    /* --font-family-sans-serif: "Source Sans Pro", system-ui, sans-serif; */
    /* --font-size-base: 16px;          */
    /* --line-height: 1.55;             */

    /* ----- Form / Radius ------------------------------------------- */
    /* --border-radius: 12px;           */
    /* --border-color: #e3e8ee;         */

    /* ----- Hintergründe -------------------------------------------- */
    /* --color-bg: #fafafa;             */
    /* --color-surface: #ffffff;        */
}

/*
 * ----- Token-Brücke (optional) -----------------------------------------
 * Hast du bereits ein Theme mit eigenen Custom-Properties? Dann mappe die
 * Bundle-Tokens hier EINMALIG auf deine Palette — danach übernehmen ALLE
 * Bundle-Komponenten (Cards, Pagination, Buttons, Bewertungen …) dein
 * Design, ohne dass du einzelne Klassen überschreiben musst.
 *
 * :root {
 *     --color-primary:     var(--c-primary);
 *     --color-accent:      var(--c-accent);
 *     --color-text:        var(--c-text);
 *     --color-muted:       var(--c-text-muted);
 *     --color-text-muted:  var(--c-text-muted);
 *     --border-color:      var(--c-line);
 *     --color-surface:     var(--c-bg);
 *     --color-surface-alt: var(--c-bg-alt);
 *     --radius-md:         var(--r-md);
 *     --radius-card:       var(--r-lg);
 *     --shadow-card:       var(--shadow-md);
 *     --space-4:           var(--sp-4);
 *     --font-size-sm:      var(--fs-sm);
 *     // … restliche --space-* / --font-size-* analog mappen …
 * }
 */

/*
 * MWFewoManager
 *
 * @author Küstenweb GmbH <info@mwfewomanager.de>
 * @copyright mwfewomanager.de
 */

/* --------------------------------------------------
   Modern Reset (lightweight, framework-like)
-------------------------------------------------- */

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

html {
    -webkit-text-size-adjust: 100%;
    font-size: 100%; /* ensure base 16px to prevent mobile input zoom */
    text-size-adjust: 100%;
}

body {
    margin: 0;
    padding: 0;
    background: var(--color-bg);
    color: var(--color-text);
    font-family: var(--font-family-sans-serif);
    line-height: var(--line-height, 1.5);
    min-height: 100vh;
    text-rendering: optimizeLegibility;
}

/* Remove default margins */
h1, h2, h3, h4, h5, h6,
p,
figure,
blockquote,
dl,
dd {
    margin: 0;
}

/* --------------------------------------------------
   Headings – Base Typography
-------------------------------------------------- */

h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-family-heading);
    font-weight: 600;
    line-height: 1.2;
    color: var(--heading-color, var(--color-text));
    margin-bottom: .75rem;
}

h1 { font-size: var(--font-size-h1, 2rem); }
h2 { font-size: var(--font-size-h2, 1.75rem); }
h3 { font-size: var(--font-size-h3, 1.5rem); }
h4 { font-size: var(--font-size-h4, 1.25rem); }
h5 { font-size: var(--font-size-h5, 1.125rem); }
h6 { font-size: var(--font-size-h6, 1rem); }

/* Optional spacing utility for headings */
/*h1 + *,*/
/*h2 + *,*/
/*h3 + *,*/
/*h4 + *,*/
/*h5 + *,*/
/*h6 + * {*/
/*    margin-top: .5rem;*/
/*}*/

/* Consistent vertical rhythm for stacked headings */
h1:not(:first-child),
h2:not(:first-child),
h3:not(:first-child),
h4:not(:first-child),
h5:not(:first-child),
h6:not(:first-child) {
    margin-top: 1.5rem;
}

/* Larger separation for main section headings */
h1:not(:first-child),
h2:not(:first-child) {
    margin-top: 2rem;
}

/* Lists without default spacing */
ul, ol {
    margin: 0;
    padding: 0;
    list-style: none;
}

/* Media elements */
img,
picture,
video,
canvas {
    display: block;
    max-width: 100%;
}

/* Form elements inherit font */
input,
button,
textarea,
select {
    font: inherit;
    /*color: inherit;*/
}

figure { line-height: 0; }
label { margin: 0; }

/* --------------------------------------------------
   Form Controls – Base Layout (Contao)
   - 100% width for text-like controls (no checkbox/radio)
   - consistent height/border across input/select/textarea
-------------------------------------------------- */

:where(
      input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]),
      textarea,
      select
    ) {
    width: 100%;
    min-height: 2.5rem;

    padding: .6rem .9rem;

    border: 1px solid var(--border-color);
    border-radius: var(--border-radius);

    background-color: var(--color-surface);
    color: var(--color-text);

    font-size: 1rem; /* prevent iOS zoom */
    line-height: 1.4;

    transition: border-color .15s ease, box-shadow .15s ease;
}

:where(
      input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]),
      textarea,
      select
    ):focus-visible {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 25%, transparent);
}

:where(
      input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]),
      textarea,
      select
    ):disabled {
    background-color: color-mix(in srgb, var(--color-surface) 90%, #000 5%);
    cursor: not-allowed;
    opacity: .7;
}

/* --------------------------------------------------
   Form States & Validation
-------------------------------------------------- */

:where(
      input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]),
      textarea,
      select
    ):focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 20%, transparent);
}

/* Valid */
:where(
      input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]),
      textarea,
      select
    ).is-valid {
    border-color: var(--color-success);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-success) 20%, transparent);
}

/* Invalid */
:where(
      input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]),
      textarea,
      select
    ).is-invalid {
    border-color: var(--color-danger);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-danger) 20%, transparent);
}

/* Feedback blocks (always directly after field) */
.valid-feedback,
.invalid-feedback {
    display: block;
    font-size: .875rem;
}

.valid-feedback {
    color: var(--color-success);
}

.invalid-feedback {
    color: var(--color-danger);
}

:where(input, select, textarea).is-valid {
    border-color: var(--color-success);
    color: var(--color-success);
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2316a34a' stroke-width='2'><circle cx='12' cy='12' r='10'/><path d='M9 12l2 2 4-4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
    background-repeat: no-repeat;
    background-position: right .8rem center;
    background-size: 20px;
}
:where(input, select, textarea).is-invalid {
    border-color: var(--color-danger);
    color: var(--color-danger);
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23dc2626' stroke-width='2'><circle cx='12' cy='12' r='10'/><line x1='12' y1='8' x2='12' y2='13' stroke-linecap='round'/><circle cx='12' cy='17' r='1' fill='%23dc2626'/></svg>");
    background-repeat: no-repeat;
    background-position: right .8rem center;
    background-size: 20px;
}


:where(select).is-valid,
:where(select).is-invalid {
    background-position: right 0.9rem center;
    /*background-size: 14px 14px;*/
}

/* Contao form widget spacing + labels */
.formbody {
    display: grid;
    gap: 1rem;
}

form label {
    display: inline-block;
    margin-bottom: .5rem;
    font-weight: 600;
    font-size: .95rem;
    line-height: 1.3;
    /*color: var(--form-label-color, var(--color-text));*/
    color: inherit;
    letter-spacing: .01em;
}

/* Optional required indicator spacing */
.formbody .widget > label .mandatory {
    margin-left: .25rem;
    color: var(--color-danger);
    font-weight: 600;
}

/* Improved vertical layout for form widgets */
.formbody .widget {
    display: flex;
    flex-direction: column;
    gap: .4rem;
    position: relative;
}

/* Ensure consistent spacing between form rows */
.formbody {
    gap: 1.25rem;
}

/* Contao default field classes */
.formbody .widget input.text,
.formbody .widget textarea.textarea,
.formbody .widget select.select {
    width: 100%;
}

/* --------------------------------------------------
   Contao Checkbox / Radio Layout
-------------------------------------------------- */

.formbody .widget-checkbox .checkbox_container,
.formbody .widget-radio .radio_container {
    display: grid;
    gap: .5rem;
}

.formbody .widget-checkbox .checkbox_container span,
.formbody .widget-radio .radio_container span {
    display: flex;
    align-items: center;
    gap: .5rem;
}

.formbody .widget-checkbox input.checkbox,
.formbody .widget-radio input.radio {
    width: auto;
    min-height: auto;
    margin: 0;
}

.formbody .widget-checkbox label,
.formbody .widget-radio label {
    margin: 0;
    font-weight: 400;
}

/* --------------------------------------------------
   Form
-------------------------------------------------- */

.form-check label { display: inline-block; }

.form-group { position: relative; display: block; width: 100%; }
.input-group { position: relative; }

/* --------------------------------------------------
   Select – Base Layout
-------------------------------------------------- */

select {
    /* keep shared control sizing from Form Controls block */
    padding-right: 2.25rem; /* space for chevron */

    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;

    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 20 20' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 8 10 12 14 8'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right .75rem center;
    background-size: 14px;
}

/* Remove button defaults */
button {
    border: none;
    background: none;
    padding: 0;
    cursor: pointer;
}

/* Anchor baseline */
a {
    color: var(--link-color, var(--color-primary));
    text-decoration: none;
}

a:hover {
    color: var(--link-hover-color, var(--color-primary-hover));
}

a.active {
    color: var(--link-hover-color, var(--color-primary-hover));
}

/* Tables */
table {
    border-collapse: collapse;
    border-spacing: 0;
}
/*
 * MWFewoManager
 *
 * @author Küstenweb GmbH <info@mwfewomanager.de>
 * @copyright mwfewomanager.de
 */

:is(a, button, input[type="submit"]).btn--primary {
    --btn-bg: var(--btn-primary-bg);
    --btn-color: var(--btn-primary-text);
    --btn-border: var(--btn-primary-border);
}

:is(a, button, input[type="submit"]).btn--primary:hover {
    --btn-bg: var(--btn-primary-bg-hover);
    --btn-border: var(--btn-primary-bg-hover);
}

:is(a, button, input[type="submit"]).btn--secondary {
    --btn-bg: var(--btn-secondary-bg);
    --btn-color: var(--btn-secondary-text);
    --btn-border: var(--btn-secondary-border);
}

:is(a, button, input[type="submit"]).btn--secondary:hover {
    --btn-bg: var(--btn-secondary-bg-hover);
}

:is(a, button, input[type="submit"]).btn--clear {
    --btn-bg: var(--btn-clear-bg);
    --btn-border: var(--btn-clear-border);
    --btn-color: var(--btn-clear-text);
}

:is(a, button, input[type="submit"]).btn--cancel {
    --btn-bg: var(--btn-cancel-bg);
    --btn-border: var(--btn-cancel-border);
    --btn-color: var(--btn-cancel-text);
}

:is(a, button, input[type="submit"]).btn--apply {
    --btn-bg: var(--btn-apply-bg);
    --btn-border: var(--btn-apply-border);
    --btn-color: var(--btn-apply-text);
}

:is(a, button, input[type="submit"]).btn--apply:hover {
    --btn-bg: var(--btn-apply-bg-hover);
}

/* Booking */
:is(a, button, input[type="submit"]).btn--book {
    --btn-bg: var(--btn-book-bg);
    --btn-border: var(--btn-book-border);
    --btn-color: var(--btn-book-text);
}

:is(a, button, input[type="submit"]).btn--book:hover {
    --btn-bg: var(--btn-book-bg-hover);
    --btn-border: var(--btn-book-bg-hover);
}

/* Request */
:is(a, button, input[type="submit"]).btn--request {
    --btn-bg: var(--btn-request-bg);
    --btn-border: var(--btn-request-border);
    --btn-color: var(--btn-request-text);
}

:is(a, button, input[type="submit"]).btn--request:hover {
    --btn-bg: var(--btn-request-bg-hover);
    --btn-border: var(--btn-request-bg-hover);
}

/* Danger */
:is(a, button, input[type="submit"]).btn--danger {
    --btn-bg: var(--btn-danger-bg);
    --btn-border: var(--btn-danger-border);
    --btn-color: var(--btn-danger-text);
}

:is(a, button, input[type="submit"]).btn--danger:hover {
    --btn-bg: var(--btn-danger-bg-hover);
    --btn-border: var(--btn-danger-bg-hover);
}

/* Stepper Buttons */
:is(a, button, input[type="submit"]).btn--increment,
:is(a, button, input[type="submit"]).btn--decrement {
    width: var(--personpicker-stepper-min-width);
    height: var(--personpicker-stepper-min-width);
    padding: 0;
    font-size: 1.1rem;
    /*border-radius: 50%;*/
    --btn-bg: var(--btn-stepper-bg);
    --btn-border: var(--btn-stepper-border);
    --btn-color: var(--btn-stepper-text);
}

:is(a, button, input[type="submit"]).btn--increment:hover,
:is(a, button, input[type="submit"]).btn--decrement:hover {
    --btn-bg: var(--btn-stepper-bg-hover);
}

:is(a, button, input[type="submit"]).btn--prev,
:is(a, button, input[type="submit"]).btn--next,
:is(a, button, input[type="submit"]).btn--close {
    background: var(--btn-bg);
    color: var(--btn-color);
}

:is(a, button, input[type="submit"]).btn--prev:hover,
:is(a, button, input[type="submit"]).btn--next:hover,
:is(a, button, input[type="submit"]).btn--close:hover{
    background: color-mix(in srgb, var(--btn-bg) 90%, #000 5%);
    color: var(--btn-color);
}
/*
 * MWFewoManager
 *
 * @author Küstenweb GmbH <info@mwfewomanager.de>
 * @copyright mwfewomanager.de
 */

/* --------------------------------------------------
   Buttons – Base Layout
-------------------------------------------------- */

:is(a, button, input[type="submit"]).btn,
button.submit {
    --btn-bg: transparent;
    --btn-color: var(--color-text);
    --btn-border: var(--border-color);

    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;

    min-height: 2.5rem;
    padding: .5rem 1rem;

    font-size: .95rem;
    font-weight: 500;
    line-height: 1;

    border-radius: var(--border-radius);
    border: 1px solid var(--btn-border);

    background: var(--btn-bg);
    color: var(--btn-color);

    transition: background-color .15s ease,
    border-color .15s ease,
    color .15s ease,
    box-shadow .15s ease,
    transform .05s ease;
}

:is(a, button, input[type="submit"]).btn:hover {
    background: color-mix(in srgb, var(--btn-bg) 90%, #000 5%);
    color: var(--btn-color);
}

:is(a, button, input[type="submit"]).btn:active {
    transform: translateY(1px);
}

:is(a, button, input[type="submit"]).btn:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

:is(a, button, input[type="submit"]).btn:disabled,
:is(a, button, input[type="submit"]).btn[disabled] {
    opacity: .6;
    cursor: not-allowed;
}

button.submit {
    --btn-bg: var(--btn-primary-bg);
    --btn-color: var(--btn-primary-text);
    --btn-border: var(--btn-primary-border);
}

button.submit:hover {
    --btn-bg: var(--btn-primary-bg-hover);
    --btn-border: var(--btn-primary-bg-hover);
}

.price-range {
    display: flex;
    align-items: center;
    gap: .5rem;
}
/*
 * MWFewoManager
 *
 * @author Küstenweb GmbH <info@mwfewomanager.de>
 * @copyright mwfewomanager.de
 */

.text-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.text-muted { color: var(--frontend-core-color-muted); }
.text-center { text-align: center; }
.text-right { text-align: right; }
.hidden { display: none; }
/*
 * MWFewoManager
 *
 * @author Küstenweb GmbH <info@mwfewomanager.de>
 * @copyright mwfewomanager.de
 */

/* --------------------------------------------------------------------------
   Listing layout
   -------------------------------------------------------------------------- */

/* Wrapper (keeps flexibility for future modifiers) */
.accommodation-list {
    /* intentionally minimal */
}

/* Grid container */
.accommodation-list__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 1.5rem;
    align-items: stretch;
}

.accommodation-list__grid > * {
    display: flex;
}

.accommodation-list__grid > * > * {
    width: 100%;
}

.accommodation-list__rows {
    display: grid;
    gap: 1.5rem;
}

/* --------------------------------------------------------------------------
   Card
   -------------------------------------------------------------------------- */

.accommodation-card {
    background: var(--color-surface);
    border-radius: var(--radius-card);
    overflow: hidden;
    box-shadow: var(--shadow-card);
    display: flex;
    flex-direction: column;
    height: 100%;
    width: 100%;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.accommodation-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
}

/* Row modifier (image left, content right) */
.accommodation-list--row .accommodation-card {
    flex-direction: row;
    gap: 1rem;
}

@media (max-width: 768px) {
    .accommodation-list--row .accommodation-card {
        flex-direction: column;
        gap: 0;
    }
}

/* --------------------------------------------------------------------------
   Card: image
   -------------------------------------------------------------------------- */

.accommodation-card__image {
    width: 100%;
    height: 200px;
    display: block;
    flex-shrink: 0;
    overflow: hidden;
}

.accommodation-card__image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Row: image sizing */
.accommodation-list--row .accommodation-card__image {
    width: 320px;
    max-width: 40%;
    height: auto;
}

@media (max-width: 768px) {
    .accommodation-list--row .accommodation-card__image {
        width: 100%;
        max-width: 100%;
    }
}

/* --------------------------------------------------------------------------
   Card: content
   -------------------------------------------------------------------------- */

.accommodation-card__content {
    padding: 1rem 1.25rem 1.25rem;
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
    height: 100%;
}

/* Row: content padding */
.accommodation-list--row .accommodation-card__content {
    padding: 1rem 1.25rem;
}

/* Title + location */
.accommodation-card__title {
    font-size: 1.25rem;
    margin: 0 0 0.25rem 0;
}

.accommodation-card__location {
    font-size: 0.9rem;
    color: var(--color-muted);
    margin: 0 0 0.75rem 0;
}

/* Meta line */
.accommodation-card__meta {
    margin: 0 0 0.75rem 0;
    color: var(--color-text);
}

/* Price */
.accommodation-card__price {
    font-size: 1rem;
    margin: 0 0 0.75rem 0;
}

.accommodation-card__price .muted,
.accommodation-card__price-meta {
    color: var(--color-muted);
    font-weight: normal;
}

.accommodation-card__price-old {
    text-decoration: line-through;
    color: #888;
    margin-right: 6px;
}

.accommodation-card__discount-badge {
    display: inline-flex;
    align-items: center;
    padding: 0.1rem 0.4rem;
    border-radius: 999px;
    font-size: 0.8em;
    font-weight: 700;
    background: #d92d20;
    color: #fff;
    margin-left: 6px;
}

/* Features */
.accommodation-card__features {
    list-style: none;
    padding: 0;
    margin: 0 0 1rem 0;
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 0.8rem;
    color: var(--color-text);
    font-size: 0.85rem;
}

.accommodation-card__features li::before {
    content: "• ";
    color: var(--color-primary);
}

/* v135: Highlighted-In-List Features als Chips mit Icon + Label.
   Wenn die neuen .card-features__item-Klassen verwendet werden, greift
   das gepunktete ::before nicht — wir blenden es per :has() aus, damit
   keine doppelte Markierung entsteht. */
.accommodation-card__features:has(.card-features__item) li::before,
.accommodation-row__features:has(.card-features__item) li::before {
    content: none;
}

.card-features__item {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.25rem 0.6rem;
    background: var(--color-surface, #f6f6f4);
    border-radius: var(--border-radius, 6px);
    font-size: 0.85rem;
}

.card-features__icon {
    display: inline-flex;
    width: 1.2rem;
    height: 1.2rem;
    align-items: center;
    justify-content: center;
    color: var(--color-primary, #0071c2);
    font-size: 0.9rem;
    flex: 0 0 auto;
}

.card-features__initial {
    display: inline-flex;
    width: 1.2rem;
    height: 1.2rem;
    align-items: center;
    justify-content: center;
    background: var(--color-primary, #0071c2);
    color: #fff;
    border-radius: 50%;
    font-size: 0.7rem;
    font-weight: 600;
}

.card-features__label {
    line-height: 1.2;
}

/* v136: Icon-Only-Variante — der Titel steht im data-tooltip statt im
   sichtbaren Label. Die Chips werden rund und etwas größer, damit das
   Icon vernünftig sichtbar ist und das Tap-Target stimmt. */
.card-features--icons .card-features__item--icon-only {
    padding: 0;
    width: 2rem;
    height: 2rem;
    border-radius: 50%;
    justify-content: center;
    cursor: help;
    transition: background-color 120ms ease, transform 120ms ease;
}

.card-features--icons .card-features__item--icon-only:hover,
.card-features--icons .card-features__item--icon-only:focus-visible {
    background: color-mix(in srgb, var(--color-primary, #0071c2) 14%, var(--color-surface, #f6f6f4));
    outline: 0;
}

.card-features--icons .card-features__item--icon-only:focus-visible {
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-primary, #0071c2) 45%, transparent);
}

.card-features--icons .card-features__item--icon-only .card-features__icon {
    width: 1.1rem;
    height: 1.1rem;
    font-size: 1rem;
}

/* v136a: SVG-Sprite-Icons (z.B. <use href="…/feature-icons.svg#icon-wifi">) —
   currentColor wird vom Sprite genutzt, also nimmt das Icon die Chip-Farbe. */
.card-features__svg {
    width: 100%;
    height: 100%;
    display: block;
    color: var(--color-primary, #0071c2);
    fill: none;
    stroke: currentColor;
}

/* hide the (no longer rendered) label defensively — falls Theme-Overrides
   noch ein Label injizieren, bleibt die Card visuell sauber. */
.card-features--icons .card-features__item--icon-only .card-features__label {
    display: none;
}

/* CTA */
.accommodation-card__cta {
    margin-top: auto;
    width: 100%;
    display: block;
}

.accommodation-card__content > .accommodation-card__cta,
.accommodation-card__content > .btn,
.accommodation-card__content > a.btn {
    margin-top: auto;
}

.accommodation-card__cta.btn,
.accommodation-card__content > .btn,
.accommodation-card__content > a.btn {
    width: 100%;
    display: inline-flex;
    justify-content: center;
}

/* --------------------------------------------------------------------------
   Row layout (image left, content center, price / CTA right)
   -------------------------------------------------------------------------- */

.accommodation-row {
    display: grid;
    grid-template-columns: 320px 1fr 220px;
    gap: 1.5rem;
    align-items: center;
    background: var(--color-surface);
    border-radius: var(--radius-card);
    padding: 1rem;
    box-shadow: var(--shadow-card);
}

.accommodation-row:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
}

.accommodation-row__image img,
.accommodation-row__img {
    width: 100%;
    height: auto;
    display: block;
    border-radius: var(--radius-card);
    object-fit: cover;
}

.accommodation-row__content {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.accommodation-row__title {
    margin: 0;
    font-size: 1.25rem;
}

.accommodation-row__location {
    font-size: 0.9rem;
    color: var(--color-muted);
    margin: 0 0 0.35rem 0;
}

.accommodation-row__meta {
    font-size: 0.9rem;
    color: var(--color-text);
}

.accommodation-row__features {
    list-style: none;
    padding: 0;
    margin: 0.5rem 0 0 0;
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 0.6rem;
    font-size: 0.85rem;
}

.accommodation-row__features li::before {
    content: "• ";
    color: var(--color-primary);
}

.accommodation-row__availability {
    margin-top: 0.5rem;
}

.accommodation-row__aside {
    text-align: right;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.5rem;
}

.accommodation-row__price strong {
    font-size: 1.1rem;
}

.accommodation-row__price .muted,
.accommodation-row__price .price-meta {
    color: var(--color-muted);
    font-size: 0.85rem;
}

.accommodation-row__price-old {
    text-decoration: line-through;
    color: #888;
    margin-bottom: 4px;
}

.accommodation-row__discount-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.15rem 0.45rem;
    border-radius: 999px;
    font-size: 0.85em;
    font-weight: 700;
    line-height: 1;
    background: #d92d20;
    color: #fff;
    margin-top: 4px;
}

.accommodation-row__cta {
    margin-top: 0.25rem;
}

@media (max-width: 900px) {
    .accommodation-row {
        grid-template-columns: 240px 1fr 180px;
    }
}

@media (max-width: 768px) {
    .accommodation-row {
        grid-template-columns: 1fr;
        gap: 0.75rem;
    }

    .accommodation-row__aside {
        align-items: flex-start;
        text-align: left;
    }
}

/* --------------------------------------------------------------------------
   Pagination
   -------------------------------------------------------------------------- */

.accommodation-pagination {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 0.75rem;
    margin-top: 2rem;
    flex-wrap: wrap;
}

/* If pagination is wrapped in a nav or div and contains a list */
.accommodation-pagination ul {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.accommodation-pagination li {
    margin: 0;
}

/* Links / buttons */
.accommodation-pagination a,
.accommodation-pagination button {
    appearance: none;
    border: 1px solid var(--border-color);
    background: var(--color-surface);
    color: inherit;
    border-radius: var(--radius-button);
    padding: 0.45rem 0.75rem;
    line-height: 1;
    font-size: 0.95rem;
    text-decoration: none;
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}

.accommodation-pagination a:hover,
.accommodation-pagination button:hover {
    background: color-mix(in srgb, var(--color-text) 3%, var(--color-surface));
    border-color: color-mix(in srgb, var(--border-color) 60%, var(--color-text));
}

.accommodation-pagination a:active,
.accommodation-pagination button:active {
    transform: translateY(1px);
}

/* Active page */
.accommodation-pagination .is-active a,
.accommodation-pagination a.is-active,
.accommodation-pagination button.is-active,
.accommodation-pagination [aria-current="page"] {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: #fff;
}

/* Disabled */
.accommodation-pagination .is-disabled a,
.accommodation-pagination a[aria-disabled="true"],
.accommodation-pagination button:disabled {
    opacity: 0.45;
    cursor: not-allowed;
    pointer-events: none;
}

/* Previous/next buttons (optional helper classes) */
.accommodation-pagination .pagination-prev a,
.accommodation-pagination .pagination-next a,
.accommodation-pagination .pagination-prev button,
.accommodation-pagination .pagination-next button {
    padding-left: 0.85rem;
    padding-right: 0.85rem;
}

@media (max-width: 480px) {
    .accommodation-pagination {
        gap: 0.5rem;
        margin-top: 1.5rem;
    }

    .accommodation-pagination a,
    .accommodation-pagination button {
        padding: 0.4rem 0.6rem;
        font-size: 0.9rem;
    }
}

/* --------------------------------------------------------------------------
   Availabilities
   -------------------------------------------------------------------------- */

.accommodation-card__availability {
    margin-top: 0.75rem;
    margin-bottom: 0.75rem;
    flex: 0 0 auto;
    min-height: 3rem;
}

.availability-list {
    border-top: 1px solid var(--border-color);
    margin-top: 0.75rem;
    padding-top: 0.75rem;
}

.availability-title {
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--color-text);
    margin: 0 0 0.5rem 0;
}

.availability-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.4rem 0.6rem;
    margin: 0.25rem 0;
    background: color-mix(in srgb, var(--color-text) 4%, var(--color-surface));
    border-radius: var(--border-radius);
    text-decoration: none;
    color: var(--color-text);
    transition: background 0.2s ease;
}

.availability-item:hover {
    background: color-mix(in srgb, var(--color-primary) 8%, var(--color-surface));
}

.availability-item.secondary {
    color: var(--color-muted);
}

.availability-item .dates {
    color: var(--color-text);
}

.availability-item .price {
    color: var(--color-success);
    font-weight: 600;
}

/* “More” (details/summary) */
.more-availability summary {
    margin-top: 0.5rem;
    font-size: 0.85rem;
    color: var(--link-color);
    cursor: pointer;
}

.more-availability[open] summary {
    color: var(--link-hover-color);
}

/* Empty states */
.accommodation__no-availability {
    color: var(--color-muted);
    font-size: 0.9rem;
    margin-top: 0.5rem;
}

.accommodation__no-period {
    color: var(--color-muted);
    font-size: 0.9rem;
    margin-top: 0.5rem;
}

/* Buttons in availability section */
.show-more {
    background: none;
    border: none;
    color: var(--link-color);
    cursor: pointer;
    margin-top: 0.5rem;
    font-size: 0.85rem;
}

.show-more:hover {
    text-decoration: underline;
}
/*
 * MWFewoManager — Reviews (Bewertungen)
 *
 * @author Küstenweb GmbH <info@mwfewomanager.de>
 * @copyright mwfewomanager.de
 *
 * Komponenten-Styles für:
 *   - accommodation_reviews_showcase  ("Das sagen unsere Gäste")
 *   - Leerzustand der Detail-Bewertungen (accommodation-reviews-summary--empty)
 *
 * Es werden ausschließlich die zentralen Tokens aus root.css verwendet
 * (jeweils mit hartem Fallback), damit Theme-Overrides (theme.css) sofort
 * greifen, ohne einzelne Klassen überschreiben zu müssen.
 */

/* --------------------------------------------------------------------------
   „Das sagen unsere Gäste" (accommodation_reviews_showcase)
   -------------------------------------------------------------------------- */

.reviews-showcase {
    max-width: var(--container, 1200px);
    margin-inline: auto;
}

.reviews-showcase__title {
    text-align: center;
    margin: 0 0 var(--space-3, 0.75rem);
}

.reviews-showcase__summary {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: var(--space-1, 0.25rem) var(--space-2, 0.5rem);
    margin: 0 0 var(--space-6, 1.5rem);
    color: var(--color-text-muted, #6b7280);
    font-size: var(--font-size-sm, 0.9375rem);
}

.reviews-showcase__summary strong {
    color: var(--color-text, #1f2937);
    font-size: var(--font-size-lg, 1.25rem);
}

.reviews-showcase__summary-stars {
    display: inline-flex;
    gap: 2px;
}

.reviews-showcase__grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-5, 1.25rem);
}

@media (min-width: 640px) {
    .reviews-showcase__grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (min-width: 980px) {
    .reviews-showcase__grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

.reviews-showcase__card {
    display: flex;
    flex-direction: column;
    gap: var(--space-2, 0.5rem);
    padding: var(--space-5, 1.25rem);
    background: var(--color-surface, #ffffff);
    border: 1px solid var(--border-color, #e3e8ee);
    border-radius: var(--radius-md, 12px);
    box-shadow: var(--shadow-md, 0 6px 14px rgba(0, 0, 0, .08));
}

.reviews-showcase__rating {
    display: inline-flex;
    gap: 2px;
}

.reviews-showcase__star {
    width: 18px;
    height: 18px;
    fill: var(--border-color, #e3e8ee);
}

.reviews-showcase__star.is-filled {
    fill: var(--color-accent, #f59e0b);
}

.reviews-showcase__summary-stars .reviews-showcase__star {
    width: 16px;
    height: 16px;
}

.reviews-showcase__card-title {
    margin: 0;
    font-size: var(--font-size-md, 1.0625rem);
}

.reviews-showcase__text {
    color: var(--color-text, #1f2937);
    display: -webkit-box;
    -webkit-line-clamp: 5;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.reviews-showcase__text p {
    margin: 0 0 var(--space-2, 0.5rem);
}

.reviews-showcase__text p:last-child {
    margin-bottom: 0;
}

.reviews-showcase__meta {
    margin-top: auto;
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1, 0.25rem) var(--space-3, 0.75rem);
    font-size: var(--font-size-sm, 0.9375rem);
    color: var(--color-text-muted, #6b7280);
}

.reviews-showcase__author {
    font-weight: 600;
    color: var(--color-text, #1f2937);
}

/* --------------------------------------------------------------------------
   Detail-Bewertungen: Leerzustand (keine Bewertungen vorhanden)
   -------------------------------------------------------------------------- */

.accommodation-reviews-summary--empty {
    padding: var(--space-5, 1.25rem);
    background: var(--color-surface-alt, #f8fafc);
    border-radius: var(--radius-lg, 16px);
    color: var(--color-text-muted, #6b7280);
}

.accommodation-reviews-summary--empty p {
    margin: 0;
}

/*
 * MWFewoManager
 *
 * @author Küstenweb GmbH <info@mwfewomanager.de>
 * @copyright mwfewomanager.de
 */

#toast-container {
    position: fixed;
    top: 1rem;
    right: 1rem;
    z-index: 9999;
    display: flex;
    flex-direction: column;
    gap: .75rem;
    pointer-events: none;
}

.toast {
    position: relative;
    pointer-events: auto;
    min-width: 280px;
    max-width: 380px;
    background: var(--frontend-core-color-surface);
    color: var(--frontend-core-color-text);
    border-radius: .75rem;
    padding: 1rem 1.2rem 1rem 1rem;
    box-shadow: var(--frontend-core-shadow-light);
    border-left: 4px solid var(--frontend-core-color-info);
    display: flex;
    align-items: flex-start;
    gap: .8rem;
    opacity: 0;
    transform: translateY(-10px);
    animation: toast-in .3s ease forwards;
}

.toast--success { border-left-color: var(--frontend-core-color-success); }
.toast--error   { border-left-color: var(--frontend-core-color-danger); }
.toast--info    { border-left-color: var(--frontend-core-color-info); }
.toast--warn    { border-left-color: var(--frontend-core-color-warning); }

.toast__icon { flex-shrink: 0; font-size: 1.4rem; margin-top: .2rem; }
.toast__body { flex: 1; display: flex; flex-direction: column; }
.toast__title { font-weight: 600; margin-bottom: .25rem; font-size: .95rem; color: var(--frontend-core-color-text); }
.toast__message { line-height: 1.4; color: var(--frontend-core-color-muted); font-size: .9rem; }

.toast__counter {
    position: absolute;
    top: .6rem;
    right: 2rem;
    font-size: .8rem;
    color: var(--frontend-core-color-muted);
    font-variant-numeric: tabular-nums;
    font-weight: 500;
}

.toast__close {
    position: absolute;
    top: .4rem;
    right: .4rem;
    background: transparent;
    border: none;
    font-size: 1.1rem;
    color: var(--frontend-core-color-muted);
    cursor: pointer;
    padding: .2rem;
    transition: color .2s;
}

.toast__close:hover { color: var(--frontend-core-color-text); }

@keyframes toast-in { to { opacity: 1; transform: translateY(0); } }
@keyframes toast-out { to { opacity: 0; transform: translateY(-10px); } }
/*
 * MWFM Frontend — Site-spezifische Component-Overrides
 *
 * Diese Datei gehört DIR. Sie wird vom Install-Command einmalig angelegt
 * und beim Bundle-Update NICHT überschrieben.
 *
 * Reicht ein Token-Override (theme.css) nicht aus, schreibst du hier
 * gezielte Selektoren mit höherer Specificity, OHNE die Bundle-Component-
 * Dateien (components.css, accommodation.css, …) anzufassen.
 *
 * Lade-Reihenfolge: override.css ist die LETZTE Datei — sie darf alles
 * davor überstimmen. Siehe README.md.
 *
 * Beispiele zur Inspiration — lösche, was du nicht brauchst, oder lass
 * das File leer.
 */

/* ===== Cards =================================================== */
/* .mwfm-card {                              */
/*     border-radius: 16px;                  */
/*     box-shadow: 0 6px 24px rgba(0,0,0,.08); */
/* }                                         */

/* ===== Suchergebnis-Bilder ==================================== */
/* .mwfm-result-item__image {                */
/*     aspect-ratio: 16 / 10;                */
/* }                                         */

/* ===== Buchungs-Button-Akzent ================================ */
/* .mwfm-booking-form .btn--primary::before { */
/*     content: "→ ";                        */
/*     font-weight: 700;                     */
/* }                                         */

/* ===== Eigene Section-Headlines =============================== */
/* .mwfm-detail__section-title {             */
/*     font-family: var(--font-family-serif, Georgia, serif); */
/*     letter-spacing: -.01em;               */
/* }                                         */

/*
 * MWFewoManager – root.css (Design Tokens / Theme)
 * Küstenweb GmbH
 *
 * Purpose:
 * - Only CSS Custom Properties (tokens) + theming (light/dark)
 * - No component/layout rules
 *
 * Recommended load order:
 *   1) root.css  2) base.css  3) default.css
 */

:root {
    /* Shadows */
    --frontend-core-shadow-light: 0 2px 6px rgba(0,0,0,0.06);
    --frontend-core-shadow-card: 0 4px 16px rgba(0,0,0,0.06);
    --frontend-core-shadow-hover: 0 8px 24px rgba(0,0,0,0.12);

    /* Radii */
    --frontend-core-radius-card: var(--border-radius, 16px);

    /* Layout */
    --frontend-core-color-bg: #f5f7fa;
    --frontend-core-color-surface: var(--color-surface, #ffffff);
    --frontend-core-color-text: var(--color-text, #111827);
    --frontend-core-color-muted: var(--color-muted, #6b7280);
    --frontend-core-container: 1180px;
    --frontend-core-section-max-width: 1200px;
    --frontend-core-section-medium-max-width: 900px;
    --frontend-core-section-small-max-width: 600px;
    --frontend-core-section-padding: 1rem;

    /* Modal */
    --frontend-core-modal-border-radius: 12px;
    --frontend-core-modal-background: var(--color-surface, #ffffff);
    --frontend-core-modal-shadow: 0 8px 24px rgba(0,0,0,.18);
    --frontend-core-modal-backdrop: rgba(15, 23, 42, .45);

    --frontend-core-review-star-color: #fbbf24;
    --frontend-core-color-secondary-bg: #f0f4f8;
    --frontend-core-color-secondary-border: #cce0f5;
    --frontend-core-color-secondary-hover: #e5f0fa;

    /* STATUSFARBEN — ÜBERNOMMEN, NICHT GEWÄHLT.
     *
     * Welche Farbe „gebucht" hat, ist im Backoffice längst entschieden und
     * steht dort als `--badge-*-bd` in `ui-default.css`. Hier standen
     * daneben eigene Werte: ein anderes Grün (#3e9620 statt 25/135/84), ein
     * oranges statt eines grauen Grau für die Blockierung, dasselbe Blau
     * zweimal für zwei verschiedene Zustände. Der Eigentümer sieht dieselbe
     * Buchung im Login also in einem anderen Ton als der Betreiber im
     * Backoffice — und beim nächsten Abgleich der Palette laufen die beiden
     * Sätze weiter auseinander, weil niemand weiß, dass es zwei gibt.
     *
     * Jede Zeile nennt deshalb ihre Quelle. Wer einen Ton ändern will,
     * ändert ihn im Backoffice und trägt ihn hier nach — nicht umgekehrt.
     * Die Zuordnung Status → Ton stammt aus `ui-pages.css` (Abschnitt
     * `--ev-tone`), sie ist dieselbe wie im Belegungsplan.
     *
     * Ein Fallback steht hier bewusst NICHT: Diese Datei ist die Definition,
     * nicht die Verwendung. */
    --frontend-core-status-booked: rgba(25, 135, 84, .9);       /* --badge-green-bd */
    --frontend-core-status-reserved: rgba(253, 126, 20, .9);    /* --badge-orange-bd */
    --frontend-core-status-request: rgba(0, 102, 204, .9);      /* --badge-blue-bd */
    --frontend-core-status-cancel: rgba(220, 53, 69, .9);       /* --badge-red-bd */
    --frontend-core-status-blocked: rgba(108, 117, 125, .9);    /* --badge-gray-bd */
    --frontend-core-status-ical: rgba(111, 66, 193, .9);        /* --badge-purple-bd */
    --frontend-core-status-owner: rgba(156, 28, 139, .9);       /* --badge-teal-bd */
    --frontend-core-status-expired: rgba(121, 85, 72, .9);      /* --badge-brown-bd */
    --frontend-core-status-channel: rgba(10, 10, 215, .9);      /* --badge-indigo-bd */

    /* Die alten Namen desselben Zustands. `new` und `booking` heißen seit der
     * Status-Konsolidierung `reserved` (siehe `BookingModel`); sie bleiben als
     * Verweis stehen, damit eine Bestandsvorlage mit dem alten Namen nicht
     * farblos rendert — und tragen denselben Ton, statt einen zweiten. */
    --frontend-core-status-booking: var(--frontend-core-status-reserved);
    --frontend-core-status-new: var(--frontend-core-status-reserved);
    --frontend-core-status-canceled-by-owner: var(--frontend-core-status-cancel);
    --frontend-core-status-self-assignment: var(--frontend-core-status-owner);
    --frontend-core-status-draft: var(--frontend-core-color-muted);

    /* Optional container vars previously present */
    --frontend-core-container-background: #fff;
    --frontend-core-container-border-color: #e9e9e9;

    /* Status colors */
    --frontend-core-color-info: #2f6fe4;
    --frontend-core-color-success: #16a34a;
    --frontend-core-color-danger: #dc2626;
    --frontend-core-color-warning: #f59e0b;

    /* Borders */
    --frontend-core-border-color: #e5e7eb;

    --frontend-core-color-primary: var(--color-primary, #0072ce);
    --frontend-core-color-primary-hover: var(--color-primary-hover, #6aaa4e);

    /* "Sichere Verbindung"-Hinweis: bewusst unabhängig von der Markenfarbe
       (immer blau). Bei Bedarf separat via --color-secure überschreibbar. */
    --frontend-core-color-secure: var(--color-secure, #2f6fe4);

    --frontend-core-border-radius: 8px;
    --frontend-core-border-radius-md: 12px;
}
/*
 * MWFewoManager
 *
 * @author Küstenweb GmbH <info@mwfewomanager.de>
 * @copyright mwfewomanager.de
 */

/* =========================================================
   BASE / RESET
   ========================================================= */
body {
    background: var(--frontend-core-color-bg);
}

small,
.small {
    font-size: 0.875em;
    font-weight: 400;
}

p {
    margin: 0 0 1rem;
    color: var(--frontend-core-color-text);
    font-size: .95rem;
    line-height: 1.6;
}

p:last-child {
    margin-bottom: 0;
}

./* =========================================================
   TABLES
   ========================================================= */
.table { width: 100%; }
.table th,
.table td {
    padding: 0.75rem;
    vertical-align: top;
    border-top: 1px solid var(--frontend-core-border-color);
}

/* =========================================================
   FORMS – ELEMENT DEFAULTS
   ========================================================= */
/* Make room for validation icon on some input types */
:where(
    input[type="text"],
    input[type="email"],
    input[type="tel"],
    input[type="url"],
    input[type="search"],
    input[type="time"],
    input[type="datetime-local"],
    input[type="password"],
    input[type="file"],
    input[type="number"],
    input[type="date"]
  ).is-valid,
:where(
    input[type="text"],
    input[type="email"],
    input[type="tel"],
    input[type="url"],
    input[type="search"],
    input[type="time"],
    input[type="datetime-local"],
    input[type="password"],
    input[type="file"],
    input[type="number"],
    input[type="date"]
  ).is-invalid {
    padding-right: 2.4rem;
}

/* Inline options */
.form__check--inline { display: inline-block; margin-right: .5rem; }
.radio-item,
.checkbox-item { display: flex; align-items: center; margin-right: 0.8rem; }
.radio-item label,
.checkbox-item label { font-weight: 400; margin-bottom: 0; font-size: 0.9rem; }

/* Checkbox field layout: checkbox + label in row, feedback below */
.section__field--checkbox {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    column-gap: 0.5rem;
    row-gap: 0.25rem;
}

.section__field--checkbox input[type="checkbox"] {
    flex: 0 0 auto;
    width: auto;
    margin: 0;
    margin-top: 0.3em;
}

.section__field--checkbox label {
    flex: 1 1 0;
    margin: 0;
}

.section__field--checkbox .invalid-feedback,
.section__field--checkbox .valid-feedback {
    flex-basis: 100%; /* forces new line */
    margin-top: 0.25rem;
}

/*!
 * MWFewoManager – default.css (Components / Layout / BEM)
 * Küstenweb GmbH
 *
 * Purpose:
 * - Layout shell + components
 * - BEM blocks, modifiers, elements
 * - Can contain legacy aliases so existing templates keep working
 */

/* ─────────────────────────────────────────────
   Layout shell
──────────────────────────────────────────────*/
#container {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}
#main {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
}
#footer {
    flex: 0 0 auto;
    padding: 1rem;
    text-align: center;
    padding-bottom: 2rem;
}
#header { display: flex; justify-content: center; padding-top: 2rem; }

#footer ul {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    margin: 0;
    list-style: none;
    gap: 14px;
}
#footer a {
    padding: 0 1rem;
    font-size: .9rem;
    color: var(--frontend-core-color-muted);
}

/* ─────────────────────────────────────────────
   Header / Navigation (BEM + legacy)
──────────────────────────────────────────────*/
.header {
    flex: 0 0 auto;
    background: var(--frontend-core-color-surface);
    border-bottom: 1px solid var(--frontend-core-border-color);
    box-shadow: var(--frontend-core-shadow-light);
    position: sticky;
    top: 0;
    z-index: 10;
}

.header__inner {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1.5rem;
    padding: 1rem 2rem;
}

.header__brand img {
    height: 40px;
    width: auto;
}

.header__logout {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    color: var(--frontend-core-color-primary);
    font-weight: 600;
    font-size: .95rem;
    text-decoration: none;
    transition: all .2s ease;
    padding: .5rem .8rem;
    border-radius: 8px;
}
.header__logout svg { stroke: currentColor; }
.header__logout:hover {
    color: #fff;
    background: var(--frontend-core-color-primary);
}

.header__logout--mobile { display: none; }
.header__logout--desktop { display: inline-flex; }

@media (max-width: 980px) {
    .header__logout--desktop { display: none; }
    .header__logout--mobile {
        display: flex !important;
        align-items: center;
        justify-content: center;
        margin: 1rem 1.5rem 1.2rem;
        padding: .8rem;
        border-radius: var(--frontend-core-border-radius);
        background: var(--frontend-core-color-primary);
        color: #fff;
        font-weight: 600;
        font-size: 1rem;
        text-align: center;
        border: none;
    }
    .header__logout--mobile:hover {
        background: var(--frontend-core-color-primary-hover);
        color: #fff;
    }
}

@media (max-width: 640px) {
    .header__inner { flex-wrap: wrap; gap: 1rem; }
    .header__brand img { height: 36px; }
}

/* ─────────────────────────────────────────────
   Main wrapper (legacy .main kept)
──────────────────────────────────────────────*/
.main {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
}

.main__header {
    max-width: 1200px;
    margin: 0 auto 2rem;
    padding: 0 1rem;
    text-align: center;
}
.main__headline {
    color: var(--frontend-core-color-primary);
    margin-top: 2rem;
}
.main__teaser {
    max-width: 60ch;
    margin: 0 auto;
    color: var(--frontend-core-color-muted);
    font-size: .95rem;
    line-height: 1.5;
}

/* ─────────────────────────────────────────────
   Message card (BEM)
──────────────────────────────────────────────*/
.message { display: flex; justify-content: center; padding: 2rem; }
.message__header { display: grid; gap: 1rem; }

.message__container {
    max-width: 600px;
    width: 100%;
    text-align: center;
}

.message__icon {
    margin-bottom: 1rem;
}

.icon--success { color: var(--frontend-core-color-success); }
.icon--alert { color: var(--frontend-core-color-warning); vertical-align: middle; }
.icon--error { color: var(--frontend-core-color-danger); }

h1.message__title {
    font-size: 1.8rem;
    font-weight: 700;
    color: color-mix(in srgb, var(--frontend-core-color-text) 90%, #000);
    margin-bottom: 2rem;
    margin-top: 0;
}

.message__section-title {
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--booking-color-text-label);
    margin-bottom: 1rem;
}

.message__card {
    background: var(--frontend-core-color-surface);
    border: 1px solid var(--frontend-core-border-color);
    border-radius: var(--frontend-core-radius-card);
    padding: 2rem;
    box-shadow: var(--frontend-core-shadow-card);
}

.message__content p {
    color: color-mix(in srgb, var(--frontend-core-color-text) 75%, var(--frontend-core-color-muted));
    font-size: .95rem;
    line-height: 1.6;
    margin-bottom: 1rem;
}

.message__actions {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 1rem;
    margin-top: 2rem;
    flex-wrap: wrap;
}

.message__button {
    display: inline-block;
    background-color: var(--frontend-core-color-primary);
    color: #fff;
    font-weight: 600;
    text-decoration: none;
    padding: .75rem 1.75rem;
    border-radius: var(--frontend-core-border-radius);
    transition: transform .15s ease, background .2s ease;
    text-align: center;
    min-width: 180px;
}
.message__button:hover {
    background-color: var(--frontend-core-color-primary-hover);
    color: #fff;
    transform: translateY(-1px);
}
.message__button:active { transform: translateY(0); }

@media (max-width: 600px) {
    .message__actions { flex-direction: column; gap: .75rem; }
    .message__button { width: 100%; max-width: 320px; }
}

/* ─────────────────────────────────────────────
   Security note (BEM)
──────────────────────────────────────────────*/
.security-note {
    display: inline-flex;
    align-items: center;
    gap: .6rem;
    background: color-mix(in srgb, var(--frontend-core-color-secure) 6%, var(--frontend-core-color-surface));
    border: 1px solid color-mix(in srgb, var(--frontend-core-color-secure) 18%, var(--frontend-core-border-color));
    border-radius: var(--frontend-core-border-radius-md);
    padding: .8rem 1.2rem;
    color: color-mix(in srgb, var(--frontend-core-color-secure) 35%, var(--frontend-core-color-text));
    font-size: .9rem;
    text-align: left;
}
.security-note__icon { color: var(--frontend-core-color-secure); flex-shrink: 0; }
.security-note__text small { color: var(--frontend-core-color-muted); font-size: .8rem; }

/* ─────────────────────────────────────────────
   Booking data (BEM)
──────────────────────────────────────────────*/
.booking-data__card {
    border: 1px solid var(--frontend-core-border-color);
    border-radius: 16px;
    padding: 1.6rem 1.8rem;
    margin-bottom: 1rem;
}

/* IM GERAHMTEN ABSCHNITT KEIN ZWEITER RAHMEN.
 *
 * `.section__container` hat bereits Rahmen, Radius 16px und Schatten. Steckt
 * die Buchungsdaten-Karte darin und zieht denselben Rahmen noch einmal, sitzt
 * ein gerundeter Kasten in einem gerundeten Kasten mit ein paar Pixeln
 * Abstand — das liest sich als Fehler, nicht als Gliederung.
 *
 * Getrennt bleiben die Buchungsdaten trotzdem: Die Überschrift und der
 * Abstand darunter reichen. Außerhalb eines Abschnitts-Containers behält die
 * Karte ihren Rahmen, dort ist er die einzige Begrenzung. */
.section__container > .booking-data__card {
    border: 0;
    border-radius: 0;
    padding: 0;
    margin-bottom: 1.6rem;
}
.booking-data__section-title { font-size: 1.1rem; font-weight: 700; margin-bottom: 1rem; }
.booking-data__details { display: grid; gap: .5rem; }
/* BESCHRIFTUNG UND WERT IN ZWEI SPALTEN, NICHT IN EINER ZEILE.
 *
 * Mit `display: flex` und `space-between` stießen Beschriftung und Wert
 * aneinander, sobald der Wert lang war, und der Wert brach unter der
 * Beschriftung schief um („MietobjektFerienwohnung / Dünenblick …"). Die
 * Beschriftung hat jetzt eine feste Mindestbreite und einen Abstand, der
 * Wert steht rechtsbündig und bricht in seiner eigenen Spalte. In einer
 * schmalen Spalte (Seitenleiste, Telefon) steht die Beschriftung über dem
 * Wert — siehe unten und `area.css`. */
.booking-data__details > div {
    display: grid;
    grid-template-columns: minmax(7.5rem, max-content) minmax(0, 1fr);
    align-items: baseline;
    column-gap: 1rem;
    border-bottom: 1px solid var(--frontend-core-border-color);
    padding-bottom: .35rem;
}
.booking-data__details dt { color: var(--frontend-core-color-muted); font-weight: 500; margin: 0; }
.booking-data__details dd {
    min-width: 0;
    margin: 0;
    color: var(--frontend-core-color-text);
    text-align: right;
    overflow-wrap: anywhere;
}
.booking-data__details dd.booking-data__period { justify-content: flex-end; }

/* Ein leiser Satz unter den Buchungsdaten — etwa, ab wann bewertet werden
 * kann. Kein Knopf: Er sagt, was kommt, nicht, was zu tun ist. */
.booking-data__note {
    margin: .75rem 0 0;
    font-size: .85rem;
    line-height: 1.5;
    color: var(--frontend-core-color-muted);
}

/* Reisezeitraum mit Pfeil + "· x Nächte" (wie im Backend) */
.booking-data__period {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .35rem;
}
.booking-data__period-arrow { color: var(--frontend-core-color-muted); }
.booking-data__period-nights { color: var(--frontend-core-color-muted); }

.is-green { color: var(--frontend-core-color-success) !important; }
.is-red { color: var(--frontend-core-color-danger) !important; }

@media (max-width: 640px) {
    .booking-data__card { padding: 1.4rem; }
    .booking-data__details > div {
        grid-template-columns: minmax(0, 1fr);
        row-gap: .25rem;
        padding-bottom: .7rem;
    }
    .booking-data__details dd { font-weight: 500; margin: 0; padding: 0; text-align: left; }
    .booking-data__details dd.booking-data__period { justify-content: flex-start; }
    .booking-data__details > div:last-child { border-bottom: none; }
}

/* ─────────────────────────────────────────────
   Payment plan (kept API)
──────────────────────────────────────────────*/
.section__payment-plan {
    margin-top: 1.6rem;
    background: color-mix(in srgb, var(--frontend-core-border-color) 25%, var(--frontend-core-color-surface));
    border: 1px solid var(--frontend-core-border-color);
    border-radius: 12px;
    padding: 1rem 1.2rem;
}
.section__payment-title { font-size: 1rem; font-weight: 700; color: var(--frontend-core-color-text); margin-bottom: .8rem; }
.section__payment {
    display: flex;
    justify-content: space-between;
    align-items: center;
    border-top: 1px solid var(--frontend-core-border-color);
    padding: .8rem 0;
}
.section__payment:first-of-type { border-top: none; }
.section__payment-info { display: flex; flex-direction: column; }
.section__payment-label { font-weight: 700; color: color-mix(in srgb, var(--frontend-core-color-text) 92%, #000); }
.section__payment-date { color: var(--frontend-core-color-muted); font-size: .9rem; }
.section__payment-amount { text-align: right; }
.section__payment-status { display: inline-block; font-size: .85rem; font-weight: 600; margin-top: .2rem; }
.section__actions { margin-top: 1.4rem; text-align: right; }
.section__note { color: var(--frontend-core-color-muted); font-size: .9rem; margin-top: .2rem; text-align: center; }

/* ─────────────────────────────────────────────
   Login (legacy BEM)
──────────────────────────────────────────────*/
.login { display: grid; place-items: center; padding: 2rem; }
/* Form fields should have consistent spacing */
.login__form {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

/* Logo-Container im Seiten-Header (z. B. Gastdaten-Formular). */
/* DER ABSTAND NACH OBEN GEHÖRT DAZU.
 *
 * Die Seiten, die ihr Logo selbst in den Inhalt setzen, überschreiben den
 * Block `header` der Basisvorlage leer — sonst stünde das Logo doppelt.
 * Damit fällt aber auch dessen `padding-top` weg (`#header`, 2rem), und das
 * Logo klebte am oberen Rand des Fensters.
 *
 * Derselbe Wert wie dort, damit alle Gastseiten gleich beginnen: die mit
 * eigener Kopfzeile (`.header__inner`) und die mit `.main__logo`. */
.main__logo { display: flex; justify-content: center; margin: 2rem 0 1.5rem; }

/* EINHEITLICHE Logo-Größe auf allen Gastseiten (login, booking-details,
   complete-details, …). Feste Höhe (nicht height:auto) funktioniert auch für
   nur per viewBox definierte SVG-Logos und verhindert, dass die generische
   img-Regel das Logo über die volle Breite aufbläht. */
.site-logo { height: 56px; width: auto; max-width: 100%; margin: 0; }

.login__subtitle {
    color: var(--frontend-core-color-muted);
    font-size: .95rem;
    margin-bottom: 2rem;
    line-height: 1.45;
    text-align: center;
}

.login__field--optional label::after {
    content: " optional";
    color: #94a3b8;
    font-weight: 500;
}

.login__field--2fa { display: none; }

.login__row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: .2rem;
}

.login__remember {
    color: color-mix(in srgb, var(--frontend-core-color-text) 78%, var(--frontend-core-color-muted));
    font-size: .9rem;
    display: inline-flex;
    gap: .45rem;
    align-items: center;
}
.login__remember input { transform: translateY(1px); }

.login__link { font-size: .9rem; color: var(--frontend-core-color-primary); text-decoration: none; }
.login__link:hover { text-decoration: underline; }

.login__button {
    margin-top: .6rem;
    width: 100%;
    /* Basis (greift für Login-Buttons OHNE .btn-Klassen). */
    background: var(--frontend-core-color-primary);
    color: #fff;
    border: none;
    border-radius: var(--frontend-core-border-radius);
    padding: .95rem 1.2rem;
    font-size: 1rem;
    font-weight: 800;
    cursor: pointer;
    transition: background .2s ease, transform .02s ease;
}
.login__button:hover {
    background: var(--frontend-core-color-primary-hover);
    color: #fff;
}
/* Ohne !important: Die Skeleton-Regel :is(a,button,input[type="submit"]).btn
   (Spezifität 0-2-1) setzt background:var(--btn-bg) und gewinnt sonst gegen
   .login__button (0-1-0). Drei Klassen (.login__button.btn.btn--primary = 0-3-0)
   schlagen das sauber per Spezifität – und wir setzen ZUSÄTZLICH --btn-bg,
   falls das Projekt die Buttons über das Variablen-System (.btn{background:var(--btn-bg)}) malt. */
.login__button.btn.btn--primary {
    background: var(--frontend-core-color-primary);
    color: #fff;
    border: none;
    --btn-bg: var(--frontend-core-color-primary);
    --btn-color: #fff;
    --btn-border: var(--frontend-core-color-primary);
}
.login__button.btn.btn--primary:hover {
    background: var(--frontend-core-color-primary-hover);
    color: #fff;
    --btn-bg: var(--frontend-core-color-primary-hover);
}
.login__button:active { transform: translateY(1px); }

/* ---------------------------------------------------------------------------
   Primary-Buttons systemweit branden – über EINE Variable überschreibbar.
   Standard = --frontend-core-color-primary (= var(--color-primary, #0072ce)).
   Zum Umbranden im Projekt genügt EINE Zeile auf :root:
       :root { --color-primary: #b5a48a; --color-primary-hover: #9c8c72; }
   Spezifität 0-3-1 schlägt die Skeleton-Basis :is(...).btn (0-2-1) sauber,
   daher KEIN !important. Setzt zusätzlich die --btn-*-Variablen, falls das
   Projekt Buttons über das Variablen-System (.btn{background:var(--btn-bg)}) malt.
   --------------------------------------------------------------------------- */
:is(a, button, input[type="submit"]).btn.btn--primary {
    --btn-bg: var(--frontend-core-color-primary);
    --btn-color: #fff;
    --btn-border: var(--frontend-core-color-primary);
    background: var(--frontend-core-color-primary);
    color: #fff;
    border-color: var(--frontend-core-color-primary);
}
:is(a, button, input[type="submit"]).btn.btn--primary:hover {
    --btn-bg: var(--frontend-core-color-primary-hover);
    background: var(--frontend-core-color-primary-hover);
    border-color: var(--frontend-core-color-primary-hover);
    color: #fff;
}

.login__info { margin-top: 1.8rem; color: var(--frontend-core-color-muted); font-size: .85rem; line-height: 1.4; }
.login__field--error input {
    border-color: color-mix(in srgb, var(--frontend-core-color-danger) 80%, var(--frontend-core-border-color));
    box-shadow: 0 0 0 2px rgba(239, 68, 68, .12);
}
.login__error-msg { margin-top: .35rem; color: #b91c1c; font-size: .85rem; }

/* ─────────────────────────────────────────────
   Zwei Anmeldewege, einer sichtbar

   Untereinander gestellt lasen sich die beiden Formulare wie EINES: Beide
   beginnen mit der E-Mail-Adresse, und wer oben ausgefüllt hatte, suchte
   unten weiter. Der Umschalter macht daraus eine Entscheidung.

   Das Umschalten machen zwei versteckte Radio-Felder und der
   Geschwister-Wähler `~`. Ohne Skript heißt: kein Zustand, der beim
   Nachladen verloren geht, und die Seite funktioniert auch dort, wo
   JavaScript blockiert ist.
──────────────────────────────────────────────*/
.login__modes { margin-bottom: .5rem; }

/* Nicht display:none — sonst nimmt das Feld keinen Tastaturfokus mehr an und
   der Umschalter wäre nur noch mit der Maus bedienbar. */
.login__mode-input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: 0;
    opacity: 0;
    pointer-events: none;
}

.login__tabs {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: .25rem;
    margin-bottom: 1.6rem;
    padding: .25rem;
    border: 1px solid var(--frontend-core-border-color);
    border-radius: var(--frontend-core-border-radius);
    background: color-mix(in srgb, var(--frontend-core-color-muted) 8%, var(--frontend-core-color-surface));
}

.login__tab {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 2.6rem;
    padding: .45rem .7rem;
    border-radius: calc(var(--frontend-core-border-radius) - 2px);
    color: var(--frontend-core-color-muted);
    font-size: .86rem;
    font-weight: 700;
    line-height: 1.25;
    text-align: center;
    cursor: pointer;
    transition: background .15s ease, color .15s ease;
}

/* Gewählt wird über `value` und `data-mode`, nicht über IDs. Der Umschalter
   sitzt auf zwei Seiten — Gast und Eigentümer — mit verschiedenen Inhalten;
   IDs im Wähler hießen zwei Regelsätze, die auseinanderlaufen können. */
.login__mode-input[value="a"]:checked ~ .login__tabs .login__tab[data-mode="a"],
.login__mode-input[value="b"]:checked ~ .login__tabs .login__tab[data-mode="b"] {
    background: var(--frontend-core-color-surface);
    color: var(--frontend-core-color-text);
    box-shadow: 0 1px 2px rgba(15, 23, 42, .08);
    cursor: default;
}

/* Das Feld selbst ist unsichtbar, also muss der Fokusring am Reiter sitzen.
   Ohne das springt beim Tabben sichtbar gar nichts. */
.login__mode-input[value="a"]:focus-visible ~ .login__tabs .login__tab[data-mode="a"],
.login__mode-input[value="b"]:focus-visible ~ .login__tabs .login__tab[data-mode="b"] {
    outline: 2px solid var(--frontend-core-color-primary);
    outline-offset: 2px;
}

.login__pane { display: none; }

.login__mode-input[value="a"]:checked ~ .login__pane[data-mode="a"],
.login__mode-input[value="b"]:checked ~ .login__pane[data-mode="b"] {
    display: block;
}

/* DER HINWEIS IM FORMULAR STEHT IM TAKT DER FELDER.
 *
 * `.login__form` ist eine Flex-Spalte mit `gap: 1rem`; `.hint` bringt für
 * den Fließtext eigene 1,25 rem oben und unten mit. In einer Flex-Spalte
 * fallen Außenabstände nicht zusammen — zwischen Feld, Hinweis und Knopf
 * stünden 36 statt 16 Pixel, und der Satz, der VOR dem Knopf gelesen werden
 * soll, rückte optisch von beiden weg. */
.login__form > .hint {
    margin: 0;
}

/* Drei Klassen (0-3-0) schlagen die Skeleton-Regel
   :is(a,button,input[type="submit"]).btn (0-2-1) sauber per Spezifität —
   derselbe Weg wie beim Primärknopf weiter oben, und ebenso ohne
   !important. */
.login__button.login__button--secondary.btn {
    background: transparent;
    color: var(--frontend-core-color-text);
    border: 1px solid var(--frontend-core-border-color);
    font-weight: 700;
    --btn-bg: transparent;
    --btn-color: var(--frontend-core-color-text);
    --btn-border: var(--frontend-core-border-color);
}
.login__button.login__button--secondary.btn:hover {
    background: color-mix(in srgb, var(--frontend-core-color-primary) 8%, transparent);
    border-color: var(--frontend-core-color-primary);
    color: var(--frontend-core-color-text);
    --btn-bg: transparent;
}

/* ─────────────────────────────────────────────
   Buchungswechsel des Gastes

   Erscheint nur, wenn zu einer Adresse mehrere laufende Buchungen gehören.
   Jede Kachel ist ein Absendeknopf — kein Auswahlfeld mit „Wechseln"-Knopf
   daneben, weil das zwei Handgriffe für eine Entscheidung wären. Die
   laufende Buchung ist markiert und gesperrt: Sie anzubieten, hieße, eine
   Handlung anzubieten, die nichts tut.
──────────────────────────────────────────────*/
.booking-switch { margin: 1.5rem 0 0; }

.booking-switch__label {
    display: block;
    margin-bottom: .6rem;
    color: var(--frontend-core-color-muted);
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
}

/* Raster statt Fließlayout: Im Fließlayout ist jede Kachel so breit wie
   ihr Objektname, die Zeilen werden ungleich lang und die letzte steht
   zentriert für sich — ab vier, fünf Buchungen sieht das wie verrutscht
   aus. Gleich breite Spalten lesen sich als Liste. */
.booking-switch__list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr));
    gap: .6rem;
}

.booking-switch__item {
    display: flex;
    flex-direction: column;
    gap: .1rem;
    min-width: 0;
    padding: .65rem 1rem;
    border: 1px solid var(--frontend-core-border-color);
    border-radius: var(--frontend-core-border-radius);
    background: var(--frontend-core-color-surface);
    color: var(--frontend-core-color-text);
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: border-color .15s ease, background .15s ease;
}
.booking-switch__item:hover { border-color: var(--frontend-core-color-primary); }

/* Ohne diese Zeilen malt der Browser den gesperrten Knopf grau und
   halbdurchsichtig — er sähe defekt aus statt „Sie sind hier". */
.booking-switch__item[aria-current] {
    border-color: var(--frontend-core-color-primary);
    background: color-mix(in srgb, var(--frontend-core-color-primary) 10%, var(--frontend-core-color-surface));
    color: var(--frontend-core-color-text);
    opacity: 1;
    cursor: default;
}

.booking-switch__accommodation { font-size: .92rem; font-weight: 700; }
.booking-switch__dates { font-size: .82rem; color: var(--frontend-core-color-muted); }
.booking-switch__number { font-size: .75rem; color: var(--frontend-core-color-muted); }

/* ─────────────────────────────────────────────
   Sections (kept API)
──────────────────────────────────────────────*/
.section {
    padding: var(--frontend-core-section-padding);
    max-width: var(--frontend-core-section-max-width);
    margin: 0 auto;
}
.section--medium { max-width: var(--frontend-core-section-medium-max-width); }
.section--small { max-width: var(--frontend-core-section-small-max-width); }

.section__container {
    background: var(--frontend-core-color-surface);
    border: 1px solid var(--frontend-core-border-color);
    border-radius: 16px;
    padding: 3rem 2rem 2.5rem;
    box-shadow: var(--frontend-core-shadow-card);
}

@media (max-width: 640px) {
    .section__container {
        padding-left: 1rem;
        padding-right: 1rem;
    }
}

.section__list h2 {
    font-size: 1.3rem;
    margin-bottom: 1rem;
    margin-top: 0;
    color: var(--frontend-core-color-primary);
}

.section__subtitle {
    font-size: 1.2rem;
    margin-bottom: 1.5rem;
    color: color-mix(in srgb, var(--frontend-core-color-text) 80%, var(--frontend-core-color-muted));
}

.section__header {
    background: var(--frontend-core-color-surface);
    border-radius: var(--frontend-core-radius-card);
    box-shadow: var(--frontend-core-shadow-light);
    padding: 1rem;
    margin-bottom: 2rem;
    gap: 0 .5rem;
}

.section__titlebar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: .75rem;
    margin-bottom: 1rem;
}
.section__titlebar h1 {
    font-size: 1.4rem;
    color: var(--frontend-core-color-primary);
    margin: 0;
}

.section__details { display: grid; gap: .5rem; }
.section__details > div {
    display: flex;
    justify-content: space-between;
    border-bottom: 1px solid var(--frontend-core-border-color);
    padding-bottom: .2rem;
}
.section__details dt { color: color-mix(in srgb, var(--frontend-core-color-text) 75%, var(--frontend-core-color-muted)); font-weight: 600; }
.section__details dd { color: var(--frontend-core-color-text); }

.section__footer { margin-top: 2.5rem; text-align: center; }

/* Default spacing between section form fields */
.section__field {
    margin-bottom: .25rem;
}
.section__field:last-child {
    margin-bottom: 0;
}

/* Section form "card" variant (preferred; matches booking-data__card look) */
fieldset.section-form__card {
    border: 1px solid var(--frontend-core-border-color);
    border-radius: 16px;
    padding: 1.6rem 1.8rem;
    margin: 0 0 1rem;
    background: var(--frontend-core-color-surface);
    min-inline-size: 0;
}

/* Section form grid (fluent / responsive) */
.section-form__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 1rem;
}

/* Slightly wider minimum for deliberate 2-col groupings (e.g., first/last name) */
.section-form__grid--2 {
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}

/* Success variants (used by success pages; keeps layout identical, only changes vibe) */
.section--success .section__container {
    background: color-mix(in srgb, var(--frontend-core-color-success) 7%, var(--frontend-core-color-surface));
    border-color: color-mix(in srgb, var(--frontend-core-color-success) 22%, var(--frontend-core-border-color));
}

.card--success {
    border: 1px solid color-mix(in srgb, var(--frontend-core-color-success) 22%, var(--frontend-core-border-color));
    background: color-mix(in srgb, var(--frontend-core-color-success) 6%, var(--frontend-core-color-surface));
}

/* KEIN ZWEITER RAHMEN IM EINGEFÄRBTEN ABSCHNITT.
 *
 * `.section__container` hat bereits Rahmen, Radius und Schatten, und
 * `.section--success` färbt ihn ein. Steckt die Karte da drin und zieht
 * ihren eigenen Rahmen, sitzt ein eckiger Kasten in einem runden —
 * genau das war auf der Erfolgsseite der Gastdatenerfassung zu sehen.
 *
 * Auf diesen Seiten IST der Container die Karte. Die Auszeichnung am
 * `div` bleibt, weil `.card__header--success` daran hängt und das
 * Zeichen einfärbt; nur Rahmen und Fläche entfallen.
 *
 * Nicht `.card--success` selbst entschärfen: Außerhalb eines
 * eingefärbten Abschnitts — mehrere Karten nebeneinander etwa — ist der
 * Rahmen richtig. */
.section--success .section__container > .card--success,
.section--danger .section__container > .card--danger {
    border: 0;
    background: none;
}

.card__header--success .card__icon,
.card__header--success svg {
    color: var(--frontend-core-color-success);
    stroke: currentColor;
}

@media (max-width: 640px) {
    .section__details dt { font-size: .9rem; color: var(--frontend-core-color-muted); font-weight: 600; margin: 0; }
    .section__details dd { font-size: 1rem; color: var(--frontend-core-color-text); font-weight: 800; margin: 0; line-height: 1.4; }
    .section__details > div:last-child { border-bottom: none; }
}

.card__header--center {
    text-align: center;
}

.card__body {
    margin-top: 1rem;
    margin-bottom: 1rem;
}


.card__body--center {
    text-align: center;
}

/* ─────────────────────────────────────────────
   Buttons (kept .btn API)
──────────────────────────────────────────────*/

.btn--icon { display: inline-flex; align-items: center; gap: .4rem; }

.btn svg {
    width: 18px;
    height: 18px;
    flex: 0 0 auto;
    display: block;
}

/* Legacy alias: section-form submit button (used in older templates) */
.section-form__submit {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .4rem;
    border: none;
    border-radius: var(--frontend-core-border-radius);
    padding: .45rem .9rem;
    font-size: .9rem;
    font-weight: 700;
    cursor: pointer;
    transition: background .2s ease, color .2s ease, transform .02s ease;
    text-decoration: none;
    background: var(--frontend-core-color-primary);
    color: #fff;
}
.section-form__submit:hover {
    background: var(--frontend-core-color-primary-hover);
    color: #fff;
}
.section-form__submit:active { transform: translateY(1px); }

/* Legacy form actions container */
.section-form__actions {
    display: flex;
    gap: .75rem;
    justify-content: flex-end;
    align-items: center;
    flex-wrap: wrap;
}

.section__button {
    display: inline-block;
    background: var(--frontend-core-color-primary);
    color: #fff;
    border-radius: var(--frontend-core-border-radius);
    padding: .8rem 1.2rem;
    font-weight: 700;
    text-decoration: none;
    transition: background .2s ease;
}
.section__button:hover {
    background: var(--frontend-core-color-primary-hover);
    color: #fff;
}

.section__back-button {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    background: color-mix(in srgb, var(--frontend-core-border-color) 35%, var(--frontend-core-color-surface));
    color: var(--frontend-core-color-primary);
    border: 1px solid color-mix(in srgb, var(--frontend-core-border-color) 55%, #94a3b8);
    border-radius: var(--frontend-core-border-radius);
    padding: .45rem .9rem;
    font-size: .9rem;
    font-weight: 700;
    line-height: 1;
    text-decoration: none;
    transition: all .2s ease;
}
.section__back-button:hover {
    background: var(--frontend-core-color-primary);
    color: #fff;
    border-color: var(--frontend-core-color-primary);
}
.section__back-button svg {
    stroke: currentColor;
    width: 18px;
    height: 18px;
    flex: 0 0 auto;
    display: block;
}

/* ─────────────────────────────────────────────
   Modal (from core bundle, deduped + tokenized)
──────────────────────────────────────────────*/
.kw-modal-backdrop {
    position: fixed;
    inset: 0;
    background: var(--frontend-core-modal-backdrop);
    display: none;
    cursor: pointer;
}

.kw-modal {
    position: fixed;
    display: none;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    pointer-events: auto;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

.kw-modal[aria-hidden="false"] { display: flex; }
.kw-modal-backdrop[aria-hidden="false"] { display: block; }

/* Primary dialog */
.kw-modal__dialog {
    background: var(--frontend-core-modal-background);
    color: var(--frontend-core-color-text);
    border-radius: var(--frontend-core-modal-border-radius);
    box-shadow: var(--frontend-core-modal-shadow);
    width: 100%;
    max-width: 480px;
    max-height: 90dvh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    animation: kw-modal-fade-in .2s ease;
}
/* ZWEI SCHREIBWEISEN FÜR DASSELBE — UND WELCHE GILT.
 *
 * Im Frontend stehen `.kw-modal-dialog` / `.kw-modal-dialog__header`
 * neben `.kw-modal__dialog` / `.kw-modal__header`. Beide funktionieren,
 * beide werden benutzt: die Bindestrich-Form in dieser Datei und im
 * Datepicker, die BEM-Form im Merkzettel, in der Buchungsstrecke und im
 * Eigentümerlogin. Sie kollidieren nicht — sie styleN verschiedene
 * Modale und stehen nur unglücklich nebeneinander.
 *
 * FÜR NEUES MARKUP GILT DIE BEM-FORM (`__`). Das ist die Konvention des
 * Hauses, und sie macht auf einen Blick sichtbar, was Block und was
 * Element ist: `.kw-modal-dialog__header` liest sich wie ein eigener
 * Block namens „kw-modal-dialog", ist aber das Element „header" von
 * „kw-modal".
 *
 * DER BESTAND WIRD NICHT AUF VERDACHT UMGESTELLT. Ein Massenumbau über
 * fünf Dateien, den niemand im Browser nachsehen kann, bringt fünf
 * Gelegenheiten für einen Fehler und keine sichtbare Verbesserung.
 * Wird eine dieser Vorlagen aus anderem Anlass ohnehin angefasst, zieht
 * sie mit.
 *
 * Geprüft wird die Vollständigkeit mit
 * `python3 tools/css-token-lint.py` (Tokens) und beim Bauplan mit
 * `mockup-fidelity-lint.py --context=frontend` (Klassen). */

.kw-modal__header,
.kw-modal__footer {
    padding: 1rem 1.25rem;
    background: inherit;
}

/* Der Inhaltsrahmen zwischen Dialog und seinen Teilen.
 *
 * Stand als `.kw-modal__content` im Markup der Buchungsstrecke
 * (`mwfm_booking/booking/index.html.twig:195`) und war nirgends
 * definiert — der Dialog trug seine Flex-Spalte selbst, der Wrapper
 * dazwischen war ein bloßes `div`. Das ging gut, solange nichts
 * dazwischenkam; sobald der Dialog aber eine Fußzeile bekommt, fehlt
 * genau hier die Spalte, und der Körper wächst über den Dialog hinaus.
 *
 * Deshalb wird die Eigenschaft nicht am Dialog dupliziert, sondern
 * dorthin gesetzt, wo das Markup sie erwartet. */
.kw-modal__content {
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
}

/* Der breite Dialog.
 *
 * `--lg` stand im Markup der Buchungsstrecke und tat nichts; die Breite
 * kam dort aus einer seitenspezifischen Regel
 * (`.kw-modal__booking-price .kw-modal__dialog`). Ein Modifier, den es
 * nur in einem Kontext gibt, ist keiner — jetzt wirkt er überall, und
 * die seitenspezifische Regel darf ihn weiterhin übersteuern. */
.kw-modal__dialog--lg { max-width: 760px; }

.kw-modal__header h2 {
    margin: 0;
    font-size: 1.2rem;
    color: var(--frontend-core-color-primary);
}

.kw-modal-dialog__header h1,
.kw-modal-dialog__header h2,
.kw-modal-dialog__header h3 {
    margin: 0;
    margin-right: 1rem;
    font-size: clamp(1.05rem, 1.6vw, 1.35rem);
    line-height: 1.2;
}

.kw-modal__body {
    padding: .5rem 1.25rem 1rem;
    overflow: auto;
    -webkit-overflow-scrolling: touch;
}

.kw-modal__footer {
    display: flex;
    gap: .6rem;
    justify-content: flex-end;
}

.kw-modal-dialog__header,
.kw-modal-dialog__footer {
    padding: 1rem 1.25rem;
    border-color: var(--frontend-core-border-color);
}

.kw-modal-dialog__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    border-bottom: 1px solid var(--frontend-core-border-color);
    padding: 1rem;
    background: color-mix(in srgb, var(--frontend-core-border-color) 25%, var(--frontend-core-color-surface));
}

.kw-modal-dialog__footer {
    border-top: 1px solid var(--frontend-core-border-color);
    display: flex;
    justify-content: flex-end;
    gap: .75rem;
    align-items: center;
}

.kw-modal-dialog__content {
    padding: 1rem 1.25rem;
    overflow-y: auto;
}

@media (max-width: 820px) {
    .kw-modal {
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        transform: none;
    }
    .kw-modal-dialog { width: 100%; height: 100%; border-radius: 0 !important; }
    .kw-modal-dialog__header {
        position: sticky;
        top: 0;
        z-index: 10;
        box-shadow: 0 1px 4px rgba(0,0,0,0.05);
    }
    .kw-modal-dialog__footer {
        position: sticky;
        bottom: 0;
        border-top: 1px solid var(--frontend-core-border-color);
        justify-content: space-around;
        padding: 0.75rem 1rem;
    }
}

@media (max-width: 640px) {
    .kw-modal__dialog {
        width: 100%;
        max-width: none;
        height: 100dvh;
        max-height: 100dvh;
        border-radius: 0;
    }
    .kw-modal__header,
    .kw-modal__footer {
        position: sticky;
        z-index: 1;
    }
    .kw-modal__header { top: 0; }
    .kw-modal__footer { bottom: 0; border-top: 1px solid var(--frontend-core-border-color); }
}

@keyframes kw-modal-fade-in {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* ─────────────────────────────────────────────
   Filter (kept API; already BEM-ish)
──────────────────────────────────────────────*/
.filter { display: flex; flex-wrap: wrap; gap: 1.25rem; align-items: flex-start; margin-bottom: 1rem; }
.filter .form-group { display: flex; flex-direction: column; align-self: flex-start; }
.filter__label { font-weight: 700; margin-bottom: .3rem; font-size: .95rem; }

.filter__range { display: flex; align-items: center; gap: .5rem; }
.filter__range-sep { color: var(--frontend-core-color-muted); font-weight: 600; }

.filter__textarea {
    display: block;
    width: 100%;
    min-height: 3.5rem;
    padding: .6rem .8rem;
    border: 1px solid var(--frontend-core-border-color);
    border-radius: 6px;
    font-size: .95rem;
    font-family: inherit;
    line-height: 1.4;
    resize: vertical;
    background-color: var(--frontend-core-color-surface);
    color: var(--frontend-core-color-text);
    transition: border-color .2s, box-shadow .2s;
}

.filter__actions { display: flex; gap: 1rem; align-items: center; width: 100%; order: 999; }

.btn--filter-open {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    background: var(--frontend-core-color-primary);
    color: #fff;
    border: none;
    border-radius: 0;
    padding: .9rem 1rem;
    font-size: 1rem;
    font-weight: 600;
    cursor: pointer;
}

.btn--filter-open:hover {
    background: var(--frontend-core-color-primary-hover);
    color: #fff;
}

.kw-modal-dialog--filter {
    background: var(--frontend-core-color-surface);
    border-radius: 0;
    display: flex;
    flex-direction: column;
    max-height: 100%;
    box-shadow: 0 8px 24px rgba(0,0,0,0.2);
    overflow: hidden;
    transform: translateY(30px);
    opacity: 0;
    transition: transform .25s ease, opacity .25s ease;
}

.filter-modal[aria-hidden="false"] .kw-modal { top: 0; bottom: 0; left: auto; right: 0; transform: none; }

.filter-modal[aria-hidden="false"] .kw-modal-dialog--filter { transform: translateY(0); opacity: 1; }

@media (min-width: 769px) {
    .kw-modal-dialog--filter {
        position: fixed;
        top: 0;
        right: 0;
        width: 420px;
        height: 100%;
        border-radius: 0;
        box-shadow: none;
        transform: translateX(100%);
        transition: transform .25s ease-in-out;
    }
    .filter-modal[aria-hidden="false"] .kw-modal-dialog--filter { transform: translateX(0); }
}
/* ============================================================
   KNÖPFE
   ============================================================

   `.btn--ghost`, `.btn--sm`, `.btn--link` und `.btn--block` standen hier
   als Nachträge zu Modifiern, die das Markup benutzte und kein Stylesheet
   kannte. Sie stehen jetzt mit allen anderen Stufen und Größen in
   `area.css` (Abschnitt „Knöpfe"), das auf denselben Seiten lädt — EINE
   Stelle für die Form aller Knöpfe der Anmeldebereiche. */

/* ============================================================
   .section__card — BENUTZT, ABER NIE DEFINIERT
   ============================================================

   Steht in zwei ausgelieferten Vorlagen:
     contao-mwfm-guest-booking-bundle/…/booking_details/index.html.twig:57
     contao-mwfm-review-bundle/…/mwfm_review/index.html.twig:13

   und in keinem Stylesheet. Die „Karte" im Gästeportal und im
   Bewertungsformular hat deshalb weder Hintergrund noch Rahmen noch
   Polster — sie rendert als blanker Block, und der Abstand darunter
   kommt allein vom nächsten Element.

   Aufgefallen beim Bauplan für das Gästeportal: `mockup-fidelity-lint`
   meldete die Klasse als erfunden, obwohl sie live im Einsatz ist. Das
   ist der Fall, für den es den Prüfer gibt — er unterscheidet nicht
   zwischen „im Mockup erfunden" und „im Produkt vergessen", und beide
   Male ist die Antwort dieselbe: Die Komponente gehört definiert.

   Die Werte folgen `.message__card` in derselben Datei; ein zweiter
   Kartenton für dieselbe Sache wäre eine zweite Sprache. */

.section__card {
    background: var(--frontend-core-color-surface);
    border: 1px solid var(--frontend-core-border-color);
    border-radius: var(--frontend-core-radius-card);
    box-shadow: var(--frontend-core-shadow-card);
    padding: 1.5rem;
    margin-bottom: 1.25rem;
}

.section__card > h2 {
    margin-top: 0;
    margin-bottom: 1rem;
    font-size: 1.15rem;
    color: var(--frontend-core-color-primary);
}

/* Die Zahlungskarte trägt dieselbe Hülle; unterschieden wird sie nur
   durch das, was drinsteht. Der Modifier bleibt trotzdem, weil das
   Markup ihn führt — und eine Klasse im Markup ohne Regel ist genau
   der Zustand, der oben beschrieben ist. */
.section__card--payments { }

/* ============================================================
   .auth — DIE HÜLLE DER VIER ANMELDEBEREICHE
   ============================================================

   Gästezugang, Zahlungsseite, Eigentümerzugang und Reinigungsliste sind
   vier Bundles, aber für den Anwender eine Sorte Seite: ein schmaler
   Kasten in der Mitte, das Logo des Betriebs darüber, ein ruhiger Grund
   dahinter. Bis hierher hat jeder Bereich das für sich gebaut — mit
   eigenen Abständen, eigener Kastenbreite und einem Logo mal darin und
   mal darüber. Wer nach einem abgelaufenen Link auf der Anmeldeseite
   landet, sieht dann zwei verschiedene Seiten und hält die zweite für
   eine fremde.

   Die Hülle sagt deshalb nur, WO etwas steht, nie WAS. Die Karte bringt
   ihre eigene Gestaltung mit (`.section__card`), der Knopf seine, der
   Leerzustand seine — hier steht die Anordnung und sonst nichts.

   DIE KARTE IST `.section__card` UND NICHT `.card`. Hier stand beides
   nebeneinander, und das war keine Großzügigkeit, sondern ein Versprechen,
   das nur ein Viertel der Seiten halten kann: `.card` ist nirgends zentral
   definiert, sondern ausschließlich in
   `contao-mwfm-owner-login-bundle/public/override.css`. Im
   Eigentümerzugang zeichnet sie eine Karte, im Gästezugang, auf der
   Zahlungsseite und in der Reinigungsliste gar nichts — dort stünde das
   Fehlerbild ohne Fläche, ohne Rahmen und ohne Polsterung mitten auf dem
   grauen Grund. Genau dieselbe Sorte Fehler wie bei `.section__card`
   selbst, ein paar Zeilen weiter oben.

   Warum 400 Pixel und nicht mehr: Ein Anmeldeformular hat ein Feld pro
   Zeile, ein Fehlerbild einen Satz. Beides wird breiter nicht besser,
   nur schwerer zu lesen. Am Telefon greift die Regel unten und der
   Kasten nimmt die volle Breite. */

.auth {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1.25rem;
    padding: 3rem 1.5rem;
    background: var(--frontend-core-color-bg);
}

/* DER GRUND GEHT BIS AN DEN RAND. Trug nur `.auth` die Fläche, endete sie
   unter dem Kasten, und darunter stand die Fußzeile mit Impressum und
   Datenschutz auf Weiß — die Seite sah aus wie zwei. Deshalb trägt die
   ganze Seite den Grund, sobald sie eine Anmeldehülle enthält. */
body:has(.auth) {
    background: var(--frontend-core-color-bg);
}

/* DER EIGENE AUSSENABSTAND DER KARTE FÄLLT HIER WEG.
 *
 * `.section__card` bringt `margin-bottom: 1.25rem` mit — richtig dort, wo
 * mehrere Karten untereinander stehen und selbst für ihren Abstand sorgen
 * müssen. `.auth` ist aber eine Flex-Spalte mit `gap: 1.25rem`: Beide
 * Abstände addieren sich, und zwischen Karte und Fußzeile stünden 40
 * statt 20 Pixel. Der `gap` gewinnt, weil er für ALLE Kinder gilt — auch
 * für das Logo und die Fußzeile, die keinen eigenen Abstand mitbringen. */
.auth > .section__card {
    margin-bottom: 0;
}

.auth > .section__card,
.auth__foot {
    width: 400px;
    max-width: 100%;
}

/* DAS LOGO IST EIN BEHÄLTER, KEIN BILD.
 *
 * Was hineinkommt, entscheidet der Betrieb — `_logo.html.twig` rendert
 * es nur, wenn eines gepflegt ist. Die Höhe steht deshalb am Bild und
 * nicht am Kasten: Ohne Bild soll hier kein leerer Streifen stehen
 * bleiben. */
.auth__logo {
    display: flex;
    align-items: center;
    justify-content: center;
    max-width: 180px;
    margin: 0 auto 1.25rem;
}

/* FESTE HÖHE, NICHT `height: auto`.
 *
 * Das Logo ist oft ein SVG, das nur eine `viewBox` trägt und keine eigene
 * Größe. Mit `height: auto` hat es keine, und der Kasten fiel auf null
 * Pixel zusammen: Über der Anmeldung stand nur der Abstand, in dem das Logo
 * hätte stehen sollen (gemessen am 04.10.2026 auf contao5.mwfm.de: Höhe 0,
 * Bild geladen). Dieselbe Falle ist bei `.login__logo` schon einmal
 * aufgefallen und dort beschrieben. Die Breite folgt dem Seitenverhältnis. */
.auth__logo img {
    height: 40px;
    width: auto;
    max-width: 100%;
    margin: 0;
}

.auth__title {
    margin: 0 0 .5rem;
    font-size: 1.125rem;
    font-weight: 700;
    letter-spacing: -.01em;
    text-align: center;
    color: var(--frontend-core-color-text);
}

/* Die Zeile UNTER der Karte: „Verschlüsselte Verbindung", die Wege in
   die anderen drei Bereiche, der Satz „schreiben Sie uns". Sie gehört
   nicht in die Karte, weil sie nicht zum Vorgang gehört — sie steht für
   die Seite, nicht für den Schritt. */
.auth__foot {
    margin: 0;
    text-align: center;
    font-size: .75rem;
    line-height: 1.6;
    color: var(--frontend-core-color-muted);
}

/* DER LEISE ZWEITE WEG.
 *
 * Ein Fehlerbild hat genau einen Hauptknopf. Was daneben noch möglich
 * ist — „mit der Buchungsnummer anmelden", „lieber überweisen" —, steht
 * als Text darunter: sichtbar, aber ohne Fläche. Zwei gleich starke
 * Knöpfe sind eine Frage, und wer hier ankommt, ist gerade gescheitert
 * und will keine Frage. */
.auth__alt {
    margin: .75rem 0 0;
    text-align: center;
    font-size: .8125rem;
    line-height: 1.55;
    color: var(--frontend-core-color-muted);
}

/* DAS TELEFON IST DER HAUPTFALL.
 *
 * Der Gast kommt aus einer Mail, die Reinigungsfirma steht vor der Tür.
 * Am schmalen Fenster nimmt der Kasten die ganze Breite, und der Knopf
 * wird 44 Pixel hoch — das ist die Fläche, die ein Daumen sicher
 * trifft. */
@media (max-width: 760px) {
    .auth {
        padding: 2rem 1rem;
    }

    .auth > .section__card,
    .auth__foot {
        width: 100%;
    }

    .auth .btn {
        min-height: 44px;
    }
}

/* ============================================================
   .empty — DER LEER- UND FEHLERZUSTAND
   ============================================================

   Die Karte, die statt einer Liste oder statt eines Formulars steht:
   Zeichen, Überschrift, ein Satz, eine Fortsetzung. Sie trägt beides —
   „keine Reinigung offen" ist eine gute Nachricht, „dieser Link gilt
   nicht mehr" eine schlechte, und die Form ist dieselbe. Unterschieden
   wird über den Ton des Zeichens, nicht über den Bau.

   Der Block steht hier, weil `.empty__icon--disc` ihn braucht: Ein
   Modifier ohne seinen Block ist eine Klasse, die nichts verändert.
   Dieselben vier Namen zeichnet die Entwurfsgrundlage
   (`MOCKUP-ENTWURF-BASE.css`), damit Entwurf und Anwendung sich nicht
   in den Namen unterscheiden. */

.empty {
    padding: 2.5rem 1.5rem;
    text-align: center;
    color: var(--frontend-core-color-muted);
}

/* DER LEERZUSTAND, DER EINE GANZE LISTE ERSETZT.
 *
 * Im Fehlerbild steht `.empty` in einem 400 Pixel breiten Kasten und ist
 * dort der ganze Inhalt — 2,5 Rem Luft oben und unten sind reichlich.
 * Auf einer Listenseite des Eigentümerzugangs steht derselbe Satz an der
 * Stelle, an der sonst eine Tabelle mit zwanzig Zeilen steht. Mit der
 * kleinen Polsterung schnurrt die Seite auf eine Zeile zusammen: Kopf,
 * ein grauer Satz, Fuß — und das sieht nicht nach „nichts vorhanden"
 * aus, sondern nach „noch nicht fertig geladen".
 *
 * Deshalb ein Modifier und keine zweite Definition. Der Wert stammt aus
 * der Fassung, die im Eigentümerzugang bis hierher galt (4 Rem senkrecht,
 * waagerecht nichts); die Farbe kommt jetzt aus dem Token und nicht mehr
 * aus einem festen Grau, und damit folgt der Satz der Hausfarbe, die der
 * Betrieb einstellt. */
.empty--list {
    padding: 4rem 1.5rem;
}

.empty__icon {
    display: flex;
    justify-content: center;
    color: var(--frontend-core-border-color);
}

.empty__title {
    margin: var(--frontend-core-space-3) 0 0;
    font-weight: 600;
    color: var(--frontend-core-color-text);
}

/* 46 Zeichen je Zeile — darüber sucht das Auge beim Umbruch die
   nächste Zeile, und genau das passiert auf einem Fehlerbild am
   wenigsten gern. */
.empty__text {
    margin: var(--frontend-core-space-1) auto var(--frontend-core-space-4);
    max-width: 46ch;
    font-size: .8125rem;
    line-height: 1.55;
}

/* DAS ZEICHEN AUF EINER GETÖNTEN SCHEIBE.
 *
 * `.empty__icon` allein ist ein Strich in der Linienfarbe. Über einer
 * leeren Liste ist das genau richtig: Dort soll das Zeichen nicht
 * stören. Auf einem Fehlerbild ist es das Erste, was gelesen wird, und
 * braucht Gewicht.
 *
 * Die Scheibe gibt ihm das, ohne eine neue Farbe zu erfinden: Sie
 * mischt den Ton, den das Bild ohnehin trägt, mit der Fläche. `--tone`
 * steht dabei an genau einer Stelle, statt Schrift-, Flächen- und
 * Rahmenfarbe einzeln zu hinterlegen — dann kann die Scheibe nicht halb
 * umgestellt werden und im Dunkeln stehen. Dieselbe Rechnung benutzen
 * die Statuspillen im Eigentümerzugang.
 *
 * Einen eigenen Dark-Mode-Block gibt es hier nicht, und das ist eine
 * Aussage: Beide Werte kommen aus `--frontend-core-*`, und die Tokens
 * tragen das Thema. Ein zweiter Satz Farben daneben wäre die Stelle, an
 * der die beiden auseinanderlaufen. */
.empty__icon--disc {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    border-radius: 999px;
    color: var(--tone, var(--frontend-core-color-muted));
    background: color-mix(in srgb, var(--tone, var(--frontend-core-color-muted)) 12%, var(--frontend-core-color-surface));
}

.empty__icon--ok { --tone: var(--frontend-core-color-success); }
.empty__icon--warning { --tone: var(--frontend-core-color-warning); }
.empty__icon--danger { --tone: var(--frontend-core-color-danger); }
.empty__icon--info { --tone: var(--frontend-core-color-primary); }

/* Unter einer Scheibe ist der Abstand des Titels zu eng — sie ist
   höher als ein Strich. */
.empty__icon--disc + .empty__title {
    margin-top: 1.25rem;
}

/* ============================================================
   .factlist — DIE AUSKUNFT IN ZWEI SPALTEN
   ============================================================

   Steht auf den Zahlungsbildern zwischen Satz und Knopf und beantwortet
   die zwei Fragen, die der Gast in dieser Sekunde hat: „ist mein Geld
   weg" und „was passiert jetzt". Als Fließtext muss er beide aus einem
   Absatz heraussuchen; als Zeile mit Frage links und Antwort rechts
   steht die Auskunft da, wo er hinsieht.

   Links schmal, rechts breit: Die Antwort ist der Inhalt, die
   Beschriftung nur ihr Wegweiser. Wird der Block zu schmal, fällt die
   Zeile in zwei Zeilen um, statt die Antwort auf drei Wörter je Zeile zu
   quetschen.

   NICHT dasselbe wie `.booking-data__details`: Dort stehen Stammdaten
   einer Buchung, hier steht, was gerade gilt. Der Unterschied ist nicht
   die Form, sondern der Rahmen — dieser Block hebt sich ab, weil er
   gelesen werden MUSS, bevor der Anwender den Knopf drückt. */

/* DER UMBRUCH HÄNGT AM BLOCK, NICHT AM FENSTER.
 *
 * Hier stand `@media (max-width: 760px)`. Die Abfrage misst das FENSTER
 * — die Frage ist aber eine ganz andere: Passt die Antwort neben ihre
 * Beschriftung in DIESEN Kasten? Ein breites Fenster mit einem schmalen
 * Kasten darin beantwortet die Medienabfrage falsch, und zwar in beide
 * Richtungen.
 *
 * Nachgemessen, alle drei Zahlen sind die Breite des Zeileninhalts
 * (Kastenbreite abzüglich 2px Rahmen und 48px Polsterung der Karte,
 * nochmals abzüglich 2px Rahmen und 24px Polsterung dieses Blocks).
 * Davon nimmt die Beschriftung 8,5em = 110,5px und der Zwischenraum
 * 8px; der Rest ist die Antwort:
 *
 *   Karte 400px am Rechner   → Zeile 324px → Antwort 205,5px. Liest sich.
 *   Fenster 375px am Telefon → Zeile 267px → Antwort 148,5px. Zu schmal.
 *   Kasten 380px im Entwurf  → Zeile 206px → Antwort  91,75px.
 *
 * Der letzte Fall ist der gemeldete: Die Antwort ist dort SCHMALER als
 * ihre eigene Beschriftung, und „nicht noch einmal zahlen" steht mit
 * einem Wort je Zeile untereinander. Die Medienabfrage hat ihn nie
 * gesehen, weil das Fenster daneben 1600px breit war.
 *
 * Die Grenze liegt deshalb bei 290px: Darunter wäre die Antwort keine
 * anderthalb Beschriftungsbreiten mehr wert, und die zwei Spalten kosten
 * mehr, als sie einbringen. Sie liegt zugleich über dem Telefon (267px)
 * und unter der Karte am Rechner (324px) — den zwei Maßen, die auf
 * verschiedene Seiten gehören.
 *
 * Nebenbei richtet das einen zweiten Fall: Am 700px breiten Fenster fiel
 * die Zeile bisher um, obwohl der Block dort 592px breit ist.
 *
 * Dasselbe Argument und dieselbe Lösung wie in `booking/override.css`
 * 16.5 für die Seitenleiste der Buchungsstrecke. */
.factlist {
    container-type: inline-size;
    container-name: factlist;

    margin: 1.25rem 0;
    padding: .75rem;
    border: 1px solid var(--frontend-core-border-color);
    border-radius: var(--frontend-core-border-radius-md);
    background: var(--frontend-core-color-bg);
    text-align: left;
}

/* Die Zeile, die eine ANWEISUNG ist und keine Auskunft — „zahlen Sie
   nicht noch einmal". Sie trägt den Warnton, weil ein zweiter Versuch
   an dieser Stelle Geld kostet. */
.factlist--warning {
    border-color: color-mix(in srgb, var(--frontend-core-color-warning) 45%, transparent);
    background: color-mix(in srgb, var(--frontend-core-color-warning) 10%, var(--frontend-core-color-surface));
}

.factline {
    display: flex;
    gap: .5rem;
    align-items: flex-start;
    padding: .5rem 0;
    border-top: 1px solid var(--frontend-core-border-color);
    font-size: .8125rem;
    line-height: 1.5;
}

.factline:first-child {
    border-top: 0;
    padding-top: 0;
}

.factline__key {
    flex: 0 0 8.5em;
    color: var(--frontend-core-color-muted);
}

.factline__val {
    flex: 1 1 auto;
    min-width: 0;
    color: var(--frontend-core-color-text);
}

@container factlist (max-width: 290px) {
    .factline {
        flex-direction: column;
        gap: .125rem;
    }

    .factline__key {
        flex: none;
    }
}

/* ============================================================
   .hint — DER SATZ, DER NEBENBEI STEHT UND TROTZDEM GELESEN WERDEN MUSS
   ============================================================

   „Wenn auch ein neuer Link nicht funktioniert, ist Ihr Zugang
   abgeschaltet — fordern Sie nicht weiter Links an." Als weiterer Absatz
   unter dem Fließtext geht dieser Satz unter: Wer die Überschrift gelesen
   hat, sucht schon den Knopf. Der getönte Kasten hält ihn auf, ohne dass
   der Satz in die Überschrift muss.

   Er ist NICHT `.factlist`: Dort stehen Frage und Antwort in zwei
   Spalten, hier steht ein Satz. Und er ist nicht `.message__card` — die
   IST die ganze Seite, dieser Kasten steht auf einer.

   Nur ein Ton, keine Ausprägungen. `--tone` steht an genau einer Stelle
   und mischt daraus Rahmen und Fläche; eine warnende oder eine grüne
   Fassung ist damit eine Zeile — aber erst, wenn eine Vorlage sie
   wirklich braucht. Ein Modifier, den niemand setzt, ist Gestaltung auf
   Verdacht.

   DAS ZEICHEN KOMMT AUS DEM CSS, NICHT AUS DEM MARKUP. Es ist eine Maske
   über `background-color`, also ein SVG, das die Farbe des Tons
   annimmt — dasselbe, was ein Inline-SVG mit `stroke="currentColor"`
   täte, nur ohne dass jede Vorlage es mitschleppt. Die
   Entwurfsgrundlage (`MOCKUP-ENTWURF-BASE.css`) zeichnet es an derselben
   Stelle und mit denselben Maßen; stünde es hier zusätzlich im Markup,
   zeichnete der Entwurf zwei Zeichen nebeneinander. */

.hint {
    --tone: var(--frontend-core-color-primary);

    display: block;
    position: relative;
    margin: 1.25rem 0;
    padding: .75rem .75rem .75rem 2.5rem;
    border: 1px solid color-mix(in srgb, var(--tone) 45%, transparent);
    border-radius: var(--frontend-core-border-radius-md);
    background: color-mix(in srgb, var(--tone) 10%, var(--frontend-core-color-surface));
    color: var(--frontend-core-color-text);
    font-size: .8125rem;
    line-height: 1.5;
    text-align: left;
}

/* AUF HÖHE DER ERSTEN TEXTZEILE, nicht darüber. Der Text beginnt bei der
   Polsterung von 12 Pixeln, seine Zeile ist 13 × 1,5 = 19,5 Pixel hoch,
   das Zeichen misst 16. Die Mitte der Zeile liegt also bei 12 + 9,75, die
   Mitte des Zeichens soll dorthin — das sind 13,75 Pixel von oben und
   nicht 12. Geraten wäre hier ein Zeichen, das eine Haaresbreite über
   seinem Satz schwebt; genau das stand in der Entwurfsgrundlage, bis es
   jemand nachgerechnet hat. */
.hint::before {
    content: '';
    position: absolute;
    left: .75rem;
    top: .86rem;
    width: 16px;
    height: 16px;
    background-color: var(--tone);
    pointer-events: none;
    -webkit-mask: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%23000'%20stroke-width='1.9'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Ccircle%20cx='12'%20cy='12'%20r='10'/%3E%3Cline%20x1='12'%20y1='11'%20x2='12'%20y2='16.5'/%3E%3Cline%20x1='12'%20y1='7.6'%20x2='12.01'%20y2='7.6'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%23000'%20stroke-width='1.9'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Ccircle%20cx='12'%20cy='12'%20r='10'/%3E%3Cline%20x1='12'%20y1='11'%20x2='12'%20y2='16.5'/%3E%3Cline%20x1='12'%20y1='7.6'%20x2='12.01'%20y2='7.6'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* DIE EINE STELLE IM SATZ, DIE DEN AUSSCHLAG GIBT — „Es wurde nichts
 * abgebucht."
 *
 * Kein `<strong>`, und das ist eine Entscheidung: 700 gegen 400 reißt
 * die halbe Zeile aus dem Absatz heraus, und auf einem Fehlerbild ist
 * der Absatz kurz genug, dass danach nichts mehr ruhig wirkt. 600 hebt
 * den Satzteil an, ohne ihn herauszubrechen. Dieselbe Anhebung braucht
 * der Betrag in der Auskunftszeile — der ist keine Betonung im Satz,
 * sondern eine Zahl, und genau deshalb steht hier eine Auszeichnung und
 * kein Element. */
.is-strong {
    font-weight: 600;
}

/* Was als Einheit gelesen wird, bricht nicht: eine Buchungsnummer wie
 * „B-160" trennte der Browser sonst am Bindestrich. */
.is-nowrap {
    white-space: nowrap;
}

/*
 * MWFewoManager
 *
 * @author Küstenweb GmbH <info@mwfewomanager.de>
 * @copyright mwfewomanager.de
 */

/*
 * Toast-Meldungen im Frontend (Gästebereich, Eigentümer- und
 * Reinigungs-Login, Buchungsstrecke).
 *
 * Die Gestaltung steht hier im Core-Bundle und lädt NACH dem Skelett und dem
 * Kunden-Theme (CssCombinerService, Schritt 3). Vorher lag sie nur im Skelett
 * `skeleton/css/toast.css`, das beim Einrichten nach `files/layout/css`
 * kopiert wird — eine Änderung erreichte bestehende Instanzen nie. Die Note
 * des Kunden bleibt trotzdem: Alle Farben kommen aus den Theme-Variablen
 * (`--frontend-core-color-*`), die das Kunden-Theme setzt.
 *
 * Die Farbe der Meldung liegt im Rahmen und im Zeichen, nicht in einem
 * Balken links: Ein einseitiger Balken läuft an den runden Ecken eckig aus,
 * und drei Meldungen übereinander mit vollem Farbrand wären zu laut. Dieselbe
 * Form wie die Toasts im Backoffice.
 */

#toast-container {
    position: fixed;
    top: 1rem;
    right: 1rem;
    z-index: 9999;
    display: flex;
    flex-direction: column;
    gap: .75rem;
    pointer-events: none;
}

.toast {
    --toast-accent: var(--frontend-core-color-info);
    position: relative;
    pointer-events: auto;
    display: flex;
    align-items: flex-start;
    gap: .75rem;
    min-width: 280px;
    max-width: 380px;
    padding: 1rem 2.75rem 1rem 1rem;
    border: 1px solid color-mix(in srgb, var(--toast-accent) 45%, var(--frontend-core-color-surface));
    border-radius: var(--frontend-core-border-radius-md, 12px);
    background: var(--frontend-core-color-surface);
    box-shadow: 0 2px 6px rgba(15, 23, 42, .08), 0 12px 32px rgba(15, 23, 42, .14);
    color: var(--frontend-core-color-text);
    opacity: 0;
    transform: translateY(-10px);
    animation: toast-in .3s ease forwards;
}

.toast--success { --toast-accent: var(--frontend-core-color-success); }
.toast--error   { --toast-accent: var(--frontend-core-color-danger); }
.toast--info    { --toast-accent: var(--frontend-core-color-info); }
.toast--warn    { --toast-accent: var(--frontend-core-color-warning); }

.toast__icon {
    flex: 0 0 auto;
    display: flex;
    margin-top: .1rem;
    color: var(--toast-accent);
}

.toast__body {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: .25rem;
}

.toast__title {
    font-size: .95rem;
    font-weight: 500;
    line-height: 1.3;
    color: var(--frontend-core-color-text);
}

.toast__message {
    font-size: .9rem;
    line-height: 1.45;
    color: var(--frontend-core-color-muted);
    overflow-wrap: break-word;
}

.toast__counter {
    position: absolute;
    top: .75rem;
    right: 2.5rem;
    font-size: .8rem;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
    color: var(--frontend-core-color-muted);
}

.toast__close {
    position: absolute;
    top: .6rem;
    right: .6rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.75rem;
    height: 1.75rem;
    padding: 0;
    border: 0;
    border-radius: 999px;
    background: transparent;
    box-shadow: none;
    color: var(--frontend-core-color-muted);
    cursor: pointer;
    transition: color .2s, background-color .2s;
}

.toast__close:hover,
.toast__close:focus-visible {
    color: var(--frontend-core-color-text);
    background: color-mix(in srgb, var(--frontend-core-color-text) 8%, transparent);
}

@media (max-width: 600px) {
    #toast-container {
        top: auto;
        right: .75rem;
        bottom: .75rem;
        left: .75rem;
    }

    .toast {
        min-width: 0;
        max-width: none;
    }
}

@keyframes toast-in { to { opacity: 1; transform: translateY(0); } }
@keyframes toast-out { to { opacity: 0; transform: translateY(-10px); } }

/*!
 * MWFewoManager – area.css (Bauteile der Anmeldebereiche)
 * Küstenweb GmbH
 */

/*
 * DAS GEMEINSAME BASISLAYOUT DER FRONTEND-BEREICHE.
 *
 * Eigentümer-Login, Reinigungs-Login, Zahlungsseite und später der
 * Gästebereich sind für den Anwender eine Sorte Seite: Kopfleiste mit dem
 * Namen des Angemeldeten, Navigation, Seitenkopf, Inhalt. Bis 5.9.0 hat
 * jedes Bundle das für sich gebaut — `owner-head` im Eigentümer-Login,
 * `cl-head` in der Reinigungsliste, zwei Kopfzeilen mit verschiedenen
 * Abständen für dieselbe Sache. Hier steht EIN Bauteil je Sache; die
 * Bundles tragen in ihrer `override.css` nur noch, was es nur bei ihnen
 * gibt (Belegungsraster, Schadenmeldung).
 *
 * Gerüst: `mwfm_frontend_core/area.html.twig`. Geladen wird diese Datei
 * von `CssCombinerService::addBaseStyles()` nach `default.css` und
 * `toast.css` und VOR dem Instanz-Stylesheet aus den Frontend-
 * Einstellungen — eine Instanz überschreibt hier also ohne Kopie.
 *
 * DIE NAMEN SIND MIT ABSICHT KEINE DER WEBSEITE. `.section`, `.card`,
 * `.tag` oder `.filter-drawer` stehen im Theme der öffentlichen Webseite
 * (`files/fewomanager-theme/css/style.css` der Demo) und würden, weil das
 * Instanz-Stylesheet zuletzt lädt, die Bereiche umgestalten. Deshalb
 * `area-section`, `item-card`, `status-pill`, `filter-sheet`.
 *
 * HALBFETT IST 500. Kein 600, kein 700: Zwei Abstufungen über dem
 * Fließtext lesen sich in einer Liste wie zwei Bedeutungen.
 */

/* ============================================================
   GESTALTUNG ÜBER VARIABLEN
   ============================================================

   Was eine Instanz anpassen will, stellt sie hier um — im eigenen
   Stylesheet oder über die Frontend-Einstellungen (Hausfarbe, Schrift),
   die `FrontendThemeStyle` als Variablen in den Kopf der Seite schreibt.
   Jeder Wert fällt auf den Token des Skeletts zurück, damit eine Instanz
   ohne eigene Angaben genau so aussieht wie vorher. */

:root {
    --frontend-core-font: var(--font-family-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif);
    --frontend-core-fw-medium: 500;

    --frontend-core-radius: var(--frontend-core-border-radius-md, 12px);
    --frontend-core-radius-sm: var(--frontend-core-border-radius, 8px);
    --frontend-core-radius-pill: 999px;

    --frontend-core-space-1: 4px;
    --frontend-core-space-2: 8px;
    --frontend-core-space-3: 12px;
    --frontend-core-space-4: 16px;
    --frontend-core-space-5: 24px;
    --frontend-core-space-6: 32px;

    --frontend-core-color-line: var(--frontend-core-border-color, #e5e7eb);
    --frontend-core-color-line-strong: color-mix(in srgb, var(--frontend-core-color-line) 70%, var(--frontend-core-color-muted, #6b7280));
    --frontend-core-color-surface-alt: var(--color-surface-alt, #f8fafc);
    --frontend-core-color-soft: color-mix(in srgb, var(--frontend-core-color-primary, #0072ce) 10%, var(--frontend-core-color-surface, #fff));
    --frontend-core-color-on-primary: #fff;
    --frontend-core-scrim: var(--frontend-core-modal-backdrop, rgba(15, 23, 42, .45));
    --frontend-core-sheet-width: 400px;

    /* Knöpfe. Die Fläche des Hauptknopfs ist die Hausfarbe; Schrift und
       Fläche setzt `FrontendThemeStyle` so, dass der Kontrast WCAG AA
       (4,5:1) erreicht — eine helle Hausfarbe bekommt dunkle Schrift. */
    --frontend-core-button-radius: 10px;
    --frontend-core-button-primary: var(--frontend-core-color-primary, #0072ce);
    --frontend-core-button-primary-hover: color-mix(in srgb, var(--frontend-core-button-primary) 92%, #000);
    --frontend-core-button-primary-contrast: #fff;
    --frontend-core-button-danger: #b42318;
    --frontend-core-button-danger-hover: #912018;
    --frontend-core-sheet-speed: 200ms;

    /* Feldschrift auf Touch-Geräten, siehe „FELDSCHRIFT AUF DEM TELEFON". */
    --frontend-core-field-fs-touch: max(1rem, 16px);
}

/* FELDSCHRIFT AUF DEM TELEFON — EINE REGEL FÜR ALLE FELDER.

   Safari auf iPhone und iPad zoomt die Seite, sobald ein Feld mit weniger
   als 16px Schrift den Fokus bekommt, und zoomt nicht zurück. In der
   Anmeldung, im Eigentümer- und im Reinigungsbereich steht das Feld dann
   halb außerhalb des Bilds.

   `:not(#frontend-core-touch-field)` — die ID gibt es nicht — hebt die
   Regel über jede Klassenregel eines Bauteils und über das
   Instanz-Stylesheet, das nach dieser Datei lädt, ohne `!important`.
   `maximum-scale` im Viewport wäre der andere Weg; er nimmt aber auch das
   Vergrößern mit zwei Fingern. Geprüft wird das mit
   `python3 tools/touch-font-lint.py`. */
html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

@media (pointer: coarse), (max-width: 760px) {
    :is(input, select, textarea):not(#frontend-core-touch-field) {
        font-size: var(--frontend-core-field-fs-touch, 16px);
    }
}

/* Der Sprunglink ans Seitenende der Tastatur — stand als `<style>` in
   `base.html.twig` und gehört in ein Stylesheet. */
.skip-link {
    position: absolute;
    top: 0;
    left: -9999px;
    z-index: 1000;
    padding: 8px 14px;
    border-radius: 0 0 6px 0;
    background: #000;
    color: #fff;
}

.skip-link:focus { left: 0; }

/* Für Vorleseprogramme da, auf dem Bildschirm nicht: etwa die Überschrift
   „Aktionen" über einer Spalte, deren Knöpfe für sich sprechen. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
}

@supports (padding: env(safe-area-inset-top)) {
    body {
        padding-top: env(safe-area-inset-top);
        padding-bottom: env(safe-area-inset-bottom);
    }
}

/* ============================================================
   DAS GERÜST — Kopfleiste, Navigation, Seite, Seitenspalte
   ============================================================ */

/* DIE KOPFLEISTE KLEBT NICHT. Mit der Navigation darunter wäre sie drei
 * Zeilen hoch und nähme auf dem Telefon ein Drittel des Bildes weg. */
.area-header {
    position: static;
    font-family: var(--frontend-core-font);
}

.area-user {
    display: inline-flex;
    align-items: center;
    gap: var(--frontend-core-space-3);
    min-width: 0;
}

.area-user__name {
    overflow: hidden;
    font-size: .875rem;
    font-weight: var(--frontend-core-fw-medium);
    color: var(--frontend-core-color-muted);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.area-user__logout { white-space: nowrap; }

/* ---- DIE NAVIGATION ----
 *
 * Oben die Gruppen, darunter — nur für die Gruppe der aktuellen Seite —
 * ihre Bereiche. Die Einträge kommen von außen (`areaNavigation`); das
 * Gerüst weiß nicht, ob es einen Eigentümer oder eine Reinigungsfirma
 * vor sich hat. Beide Zeilen laufen auf dem Telefon waagerecht, statt
 * umzubrechen — ein Burger-Menü braucht es damit nicht. */
.area-nav {
    border-top: 1px solid var(--frontend-core-color-line);
}

.area-nav__bar,
.area-nav__sub {
    display: flex;
    gap: var(--frontend-core-space-1);
    max-width: var(--frontend-core-section-max-width, 1200px);
    margin: 0 auto;
    padding: 0 var(--frontend-core-space-4);
    overflow-x: auto;
    scrollbar-width: none;
}

.area-nav__bar::-webkit-scrollbar,
.area-nav__sub::-webkit-scrollbar { display: none; }

.area-nav__item {
    flex: 0 0 auto;
    padding: var(--frontend-core-space-3) var(--frontend-core-space-4);
    border-bottom: 2px solid transparent;
    font-size: .9rem;
    font-weight: var(--frontend-core-fw-medium);
    color: var(--frontend-core-color-muted);
    text-decoration: none;
    white-space: nowrap;
}

.area-nav__item:hover { color: var(--frontend-core-color-text); }

.area-nav__item.is-on {
    border-bottom-color: var(--frontend-core-color-primary);
    color: var(--frontend-core-color-primary);
}

.area-nav__sub {
    padding-top: var(--frontend-core-space-2);
    padding-bottom: var(--frontend-core-space-2);
    border-top: 1px solid var(--frontend-core-color-line);
}

.area-nav__subitem {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: var(--frontend-core-space-2);
    padding: var(--frontend-core-space-2) var(--frontend-core-space-3);
    border-radius: var(--frontend-core-radius-sm);
    font-size: .85rem;
    color: var(--frontend-core-color-text);
    text-decoration: none;
    white-space: nowrap;
}

.area-nav__subitem:hover { background: var(--frontend-core-color-surface-alt); }

.area-nav__subitem.is-on {
    background: var(--frontend-core-color-soft);
    color: var(--frontend-core-color-primary);
    font-weight: var(--frontend-core-fw-medium);
}

.area-nav__icon {
    display: inline-flex;
    width: 16px;
    height: 16px;
}

.area-nav__icon svg { width: 16px; height: 16px; }

/* ---- DIE SEITE ----
 *
 * Eine Spalte, so breit wie die Abschnitte der übrigen Seiten. Mit
 * Seitenspalte (`area-layout--aside`) steht rechts ein schmaler Streifen,
 * der auf dem Telefon unter den Inhalt rutscht. */
.area-page {
    font-family: var(--frontend-core-font);
    padding-bottom: var(--frontend-core-space-6);
}

.area-layout {
    max-width: var(--frontend-core-section-max-width, 1200px);
    margin: 0 auto;
    padding: 0 var(--frontend-core-space-4);
}

.area-layout--aside {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 320px;
    gap: var(--frontend-core-space-5);
    align-items: start;
}

.area-layout__main { min-width: 0; }

.area-aside {
    display: grid;
    gap: var(--frontend-core-space-4);
}

/* Die Seitenleiste beginnt auf derselben Höhe wie der erste Abschnitt
   links. Der bringt sein oberes Polster mit (`.area-section`), die
   Leiste nicht — ihre erste Karte stand deshalb 16px höher als die
   linke. */
.area-layout--aside > .area-aside { padding-top: var(--frontend-core-space-4); }

@media (max-width: 900px) {
    .area-layout--aside {
        grid-template-columns: minmax(0, 1fr);
        gap: 0;
    }

    .area-layout--aside > .area-aside { padding-top: var(--frontend-core-space-5); }
}

/* Ein Abschnitt der Seite. Ein Abstand zwischen zwei Abschnitten, nicht
 * zwei: Jeder bringt nur seinen unteren mit. */
.area-section { padding: var(--frontend-core-space-4) 0 0; }
.area-section + .area-section { padding-top: var(--frontend-core-space-5); }

/* ---- DER SEITENKOPF ----
 *
 * EINE Überschrift je Seite, in Textfarbe. Darunter ein Satz mit den
 * Kennzahlen der Seite („4 offen · 2 erledigt"), rechts die Handlungen.
 * Über dem ganzen Kopf, wenn es ein Zurück gibt, der Weg dorthin — klein
 * und leise, denn er ist der zweite Weg, nicht der erste. */
.page-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--frontend-core-space-4);
    max-width: var(--frontend-core-section-max-width, 1200px);
    margin: 0 auto;
    padding: var(--frontend-core-space-6) var(--frontend-core-space-4) var(--frontend-core-space-2);
    font-family: var(--frontend-core-font);
}

.page-head__titles { flex: 1 1 320px; min-width: 0; }

/* Ein Bild links neben dem Titel — die Objektseite zeigt so, um welches
   Mietobjekt es geht, ohne eine Bildkarte darunter. */
.page-head__media {
    align-self: center;
    flex: 0 0 88px;
    width: 88px;
    height: 66px;
    overflow: hidden;
    border-radius: 10px;
    background: var(--frontend-core-color-surface-alt);
}

.page-head__media figure { width: 100%; height: 100%; margin: 0; }
.page-head__media img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* Der Rückweg ist eine eigene Zeile über dem ganzen Kopf, bündig mit dessen
   linker Kante — bei der Objektseite also mit dem Bild, nicht mit dem Titel
   daneben. Stand er in der Titelspalte, begann er dort, wo der Titel
   beginnt, und wirkte neben dem Bild eingerückt und verrutscht. Den Abstand
   zur Kopfzeile gibt der `gap` des Kopfes, wie zwischen allen Teilen dort.
   Die Zeile ist `__trail`, nicht der Link selbst: Ein Link über die volle
   Breite wäre auch rechts neben seinem Text anklickbar. */
.page-head__trail { flex: 0 0 100%; }

.page-head__back {
    display: inline-flex;
    align-items: center;
    gap: var(--frontend-core-space-1);
    font-size: .85rem;
    color: var(--frontend-core-color-muted);
    text-decoration: none;
}

.page-head__back:hover { color: var(--frontend-core-color-primary); }
.page-head__back svg { width: 14px; height: 14px; }

.page-head__title {
    margin: 0;
    font-size: 1.5rem;
    font-weight: var(--frontend-core-fw-medium);
    line-height: 1.25;
    letter-spacing: -.01em;
    color: var(--frontend-core-color-text);
}

.page-head__facts {
    margin: var(--frontend-core-space-1) 0 0;
    font-size: .875rem;
    color: var(--frontend-core-color-muted);
}

.page-head__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--frontend-core-space-2);
}

/* Die Zwischenüberschrift eines Abschnitts — kleiner als der Seitenkopf
 * und in Textfarbe, damit sie nicht gleichrangig neben dem Titel steht. */
.page-subhead {
    margin: 0 0 var(--frontend-core-space-3);
    font-size: 1.05rem;
    font-weight: var(--frontend-core-fw-medium);
    color: var(--frontend-core-color-text);
}

/* AM TELEFON: LOGO LINKS, ABMELDEN RECHTS, ALLES ANDERE DARUNTER.
 *
 * In der Kopfzeile stehen neben Logo und Abmelden je nach Bereich noch der
 * Buchungswechsler oder der leise Link „Weitere Buchungen? Anmeldelink
 * anfordern". Alles in einer Zeile ging auf 375px nicht auf: Der Link lief
 * rechts aus dem Bild und nahm „Abmelden" mit (gemessen: Abmelden bei
 * 322–436px, Seite 436px breit; das Logo auf 0px gedrückt). Abmelden
 * muss immer erreichbar sein — deshalb gibt `.area-user` hier seine Kinder
 * an die Kopfzeile ab (`display: contents`), Abmelden bleibt in der ersten
 * Zeile, und Wechsler und Link rücken in eine eigene zweite. */
@media (max-width: 640px) {
    .area-header .header__inner {
        flex-wrap: wrap;
        row-gap: var(--frontend-core-space-2);
        padding: var(--frontend-core-space-3) var(--frontend-core-space-4);
    }
    .area-header .header__inner > :first-child { min-width: 0; }
    .area-header .area-user { display: contents; }
    .area-header .header__logout { order: 1; flex: 0 0 auto; margin-left: auto; padding: var(--frontend-core-space-2); }
    .area-header .area-user__alt,
    .area-header .booking-switcher { order: 2; }
    .area-header .area-user__alt { flex: 1 1 100%; white-space: normal; }
    .area-nav__item { padding: var(--frontend-core-space-3) 10px; }
    .area-user__name { display: none; }
    .page-head { padding-top: var(--frontend-core-space-5); }
    .page-head__title { font-size: 1.3rem; }
}

/* ============================================================
   KARTE, RASTER, GRUPPE
   ============================================================

   `item-card` ist die Karte für EINEN Eintrag — eine Reinigung, ein
   Aufenthalt, eine Bewertung. Drei Lautstärken über Modifier: erledigt
   tritt zurück (`--muted`), heute fällig ist leicht getönt (`--accent`),
   überfällig tritt vor (`--danger`). Der Ton liegt im Rahmen rundum und
   in einer Tönung von sechs Prozent — nie als Balken links. */

.item-card {
    padding: var(--frontend-core-space-4);
    border: 1px solid var(--frontend-core-color-line);
    border-radius: var(--frontend-core-radius);
    background: var(--frontend-core-color-surface);
}

.item-card--muted { opacity: .62; }

.item-card--accent {
    border-color: color-mix(in srgb, var(--frontend-core-status-booked) 55%, var(--frontend-core-color-surface));
    background: color-mix(in srgb, var(--frontend-core-status-booked) 6%, var(--frontend-core-color-surface));
}

.item-card--danger {
    border-color: color-mix(in srgb, var(--frontend-core-status-cancel) 55%, var(--frontend-core-color-surface));
    background: color-mix(in srgb, var(--frontend-core-status-cancel) 6%, var(--frontend-core-color-surface));
}

.item-card__top {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--frontend-core-space-3);
    margin-bottom: var(--frontend-core-space-1);
}

.item-card__lead {
    font-size: 1rem;
    font-weight: var(--frontend-core-fw-medium);
    font-variant-numeric: tabular-nums;
}

.item-card__title {
    margin: var(--frontend-core-space-1) 0;
    font-size: 1rem;
    font-weight: var(--frontend-core-fw-medium);
}

.item-card__sub {
    margin: 0;
    font-size: .85rem;
    color: var(--frontend-core-color-muted);
}

.item-card__sub a { color: var(--frontend-core-color-primary); text-decoration: none; }

/* Werte als Chips nebeneinander: Wer die Karte überfliegt, sucht einen
   Wert, keinen Satz. */
.item-card__meta {
    display: flex;
    flex-wrap: wrap;
    gap: var(--frontend-core-space-2);
    margin: var(--frontend-core-space-3) 0;
}

/* Ein abgesetzter Teil der Karte: abgesetzt durch eine Linie, nicht
   durch eine Fläche. */
.item-card__section {
    margin-top: var(--frontend-core-space-3);
    padding-top: var(--frontend-core-space-3);
    border-top: 1px solid var(--frontend-core-color-line);
}

.item-card__label {
    margin: 0 0 var(--frontend-core-space-1);
    font-size: .7rem;
    font-weight: var(--frontend-core-fw-medium);
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--frontend-core-color-muted);
}

.item-card__text {
    margin: 0;
    font-size: .85rem;
    line-height: 1.5;
}

.item-card__text + .item-card__text { margin-top: var(--frontend-core-space-2); }
.item-card__text--muted { color: var(--frontend-core-color-muted); }

/* Eine Antwort, ein Zitat: auf getönter Fläche, ohne Kante links. */
.item-card__quote {
    margin-top: var(--frontend-core-space-3);
    padding: var(--frontend-core-space-3) var(--frontend-core-space-4);
    border-radius: var(--frontend-core-radius-sm);
    background: var(--frontend-core-color-surface-alt);
}

/* Die Knöpfe sind 44px hoch: die Größe, die eine Fingerkuppe zuverlässig
   trifft. Dieselbe Gewichtung wie die Grundregel des Skeletts
   (`:is(a, button, input[type="submit"]).btn`), sonst verlöre sie;
   `summary` gehört dazu, weil ein aufklappendes `<details>` ein Knopf
   sein darf. */
.item-card__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--frontend-core-space-2);
    margin-top: var(--frontend-core-space-3);
}

.item-card__actions :is(a, button, summary).btn { min-height: 44px; }

/* Die Kurzangabe oben rechts — „Wechseltag", „in 3 Tagen", „Erledigt". */
.item-card__badge {
    padding: 2px var(--frontend-core-space-2);
    border-radius: var(--frontend-core-radius-pill);
    background: color-mix(in srgb, var(--frontend-core-color-line) 60%, var(--frontend-core-color-surface));
    font-size: .75rem;
    font-weight: var(--frontend-core-fw-medium);
    letter-spacing: .02em;
    color: var(--frontend-core-color-muted);
    white-space: nowrap;
}

.item-card__badge--danger {
    background: color-mix(in srgb, var(--frontend-core-status-cancel) 13%, var(--frontend-core-color-surface));
    color: var(--frontend-core-status-cancel);
}

.item-card__badge--success {
    background: color-mix(in srgb, var(--frontend-core-status-booked) 13%, var(--frontend-core-color-surface));
    color: var(--frontend-core-status-booked);
}

/* EIN FORMULAR AUS KARTEN: `card-form`.
 *
 * Je Feldsatz eine `item-card` mit Titel — die Gastdaten etwa eine Karte je
 * Reisendem —, darunter Knöpfe und Hinweis, alles im Takt der Karten. Der
 * Feldsatz IST die Karte (`fieldset.item-card`, Name über
 * `aria-labelledby`); vorher lag er als zweiter Rahmen in einem gerahmten
 * Behälter mit 48px Leerraum oben. */
.card-form {
    display: grid;
    gap: var(--frontend-core-space-3);
}

fieldset.item-card {
    margin: 0;
    min-inline-size: 0;
}

.card-form .item-card__top { margin-bottom: var(--frontend-core-space-3); }
.card-form > .section__note { margin: 0; }

/* Eine Spalte auf dem Telefon, zwei ab 900px. Dieselbe Karte in beiden
   Breiten. */
.card-grid {
    display: grid;
    gap: var(--frontend-core-space-3);
    align-items: stretch;
}

/* GLEICH HOCH, DIE HANDLUNG UNTEN. Karten in einer Zeile sind gleich hoch;
 * eine Karte mit Fuß (`item-card__foot`: Knöpfe, Formular, Zustand) setzt
 * ihn an den unteren Rand, damit die Knöpfe nebeneinanderliegender Karten
 * auf einer Linie stehen. Der Abstand zwischen Inhalt und Fuß ist immer
 * derselbe: Der letzte Rand im Inhalt und der erste im Fuß fallen weg, das
 * Polster des Fußes gibt ihn vor — sonst addierten sich in der Flexbox die
 * Ränder, die im Blockfluss zusammenfallen. */
.item-card:has(> .item-card__foot) {
    display: flex;
    flex-direction: column;
}

.item-card__body > :last-child { margin-bottom: 0; }

.item-card__foot {
    margin-top: auto;
    padding-top: var(--frontend-core-space-3);
}

.item-card__foot:empty { display: none; }
.item-card__foot > :first-child { margin-top: 0; }

@media (min-width: 900px) {
    .card-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Eine Gruppe von Karten mit eigener Überschrift. */
.group + .group,
.group + .card-grid { margin-top: var(--frontend-core-space-5); }

.group__head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--frontend-core-space-1) var(--frontend-core-space-3);
    margin-bottom: var(--frontend-core-space-2);
    padding-bottom: var(--frontend-core-space-2);
    border-bottom: 1px solid var(--frontend-core-color-line);
}

.group__title { margin: 0; font-size: 1rem; font-weight: var(--frontend-core-fw-medium); }
.group__title--danger { color: var(--frontend-core-status-cancel); }
.group__meta { flex: 1 1 auto; font-size: .85rem; color: var(--frontend-core-color-muted); }
.group__link { font-size: .85rem; color: var(--frontend-core-color-primary); }

/* ============================================================
   KACHELN
   ============================================================

   Je Bereich eine Kachel: Name, — wo es sie billig gibt — eine Zahl MIT
   dem, was sie zählt, und ein Satz, was dort zu finden ist. Als Link ist
   die ganze Kachel der Link; als Kennzahl (Statistik) steht sie ohne. */

.tiles__title {
    margin: var(--frontend-core-space-5) 0 var(--frontend-core-space-2);
    font-size: .7rem;
    font-weight: var(--frontend-core-fw-medium);
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--frontend-core-color-muted);
}

.tiles__title:first-child { margin-top: 0; }

.tiles {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: var(--frontend-core-space-3);
}

.tiles + .tiles__title,
.tiles + .area-section { margin-top: var(--frontend-core-space-5); }

.tile {
    display: flex;
    flex-direction: column;
    gap: var(--frontend-core-space-1);
    padding: var(--frontend-core-space-4);
    border: 1px solid var(--frontend-core-color-line);
    border-radius: var(--frontend-core-radius);
    background: var(--frontend-core-color-surface);
    color: inherit;
    text-decoration: none;
    transition: border-color .15s ease;
}

.tile[href]:hover { border-color: var(--frontend-core-color-primary); }

.tile__label {
    display: inline-flex;
    align-items: center;
    gap: var(--frontend-core-space-2);
    font-size: .9rem;
    font-weight: var(--frontend-core-fw-medium);
}

.tile__icon {
    display: inline-flex;
    width: 18px;
    height: 18px;
    color: var(--frontend-core-color-primary);
}

.tile__icon svg { width: 18px; height: 18px; }

.tile__value {
    display: inline-flex;
    align-items: center;
    gap: var(--frontend-core-space-2);
    margin-top: var(--frontend-core-space-1);
    font-size: 1.6rem;
    font-weight: var(--frontend-core-fw-medium);
    line-height: 1.15;
    font-variant-numeric: tabular-nums;
}

.tile__caption {
    font-size: .8rem;
    font-weight: var(--frontend-core-fw-medium);
    color: var(--frontend-core-color-muted);
}

.tile__sub {
    margin-top: var(--frontend-core-space-1);
    font-size: .8rem;
    line-height: 1.45;
    color: var(--frontend-core-color-muted);
}

/* ============================================================
   DIE LISTE — Tabelle am Rechner, Zeilenkarte am Telefon
   ============================================================

   Ein Rahmen statt eines Schattens, eine leise Kopfzeile in Kapitälchen,
   ruhige Zeilen mit gleichem Abstand.

   AUF DEM TELEFON IST JEDE ZEILE EINE KARTE (Entwurf `own-card`), und
   zwar eine, die man lesen kann: oben der Zeitraum bzw. das Datum
   (`list-table__lead`) und rechts daneben der Stand, darunter der Name
   (`list-table__title`), darunter leise die übrigen Werte, unten Betrag
   und Knöpfe. Die Spaltenüberschrift steht nur dort vor dem Wert, wo der
   Wert sie braucht („Personen 2"); vor einem Namen, einem Datum, einem
   Stand oder einem Knopf stand sie bisher auch — „Aktionen" über einem
   Knopf, „Objekt" vor dem Objektnamen — und das liest niemand. Eine
   Zelle, deren Wert für sich spricht, trägt `list-table__plain`. */

.list-table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    table-layout: auto;
    overflow: hidden;
    border: 1px solid var(--frontend-core-color-line);
    border-radius: var(--frontend-core-radius);
    background: var(--frontend-core-color-surface);
    font-size: .875rem;
}

.list-table th,
.list-table td {
    padding: var(--frontend-core-space-3) var(--frontend-core-space-4);
    border-bottom: 1px solid var(--frontend-core-color-line);
    text-align: left;
    vertical-align: top;
    overflow-wrap: anywhere;
}

.list-table tbody tr:last-child td { border-bottom: 0; }

.list-table thead th {
    padding-top: var(--frontend-core-space-2);
    padding-bottom: var(--frontend-core-space-2);
    background: var(--frontend-core-color-surface-alt);
    font-size: .7rem;
    font-weight: var(--frontend-core-fw-medium);
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--frontend-core-color-muted);
    overflow-wrap: normal;
}

.list-table tbody tr { background: var(--frontend-core-color-surface); }
.list-table tbody tr:hover { background: var(--frontend-core-color-surface-alt); }

.list-table__row--highlight,
.list-table tbody tr.list-table__row--highlight {
    background: color-mix(in srgb, var(--frontend-core-color-primary) 8%, var(--frontend-core-color-surface));
}

.list-table__title { font-weight: var(--frontend-core-fw-medium); }
.list-table__lead { white-space: nowrap; font-variant-numeric: tabular-nums; }
.list-table__muted { display: block; color: var(--frontend-core-color-muted); font-size: .8rem; }

/* Die Spalten. Breiten nur, wo ein Wert eine feste Form hat — Datum,
 * Stand, Zahl. Alles andere teilt sich den Rest. `1%` mit `nowrap` heißt
 * bei `table-layout: auto` „so schmal wie der Inhalt"; bei `fixed` hieße
 * es wörtlich ein Prozent, deshalb steht die Liste auf `auto`. */
.list-table__col-status { width: 1%; white-space: nowrap; }
.list-table__col-date { width: 1%; white-space: nowrap; font-variant-numeric: tabular-nums; }
.list-table__col-period { white-space: nowrap; font-variant-numeric: tabular-nums; }
.list-table__col-kind { width: 1%; white-space: nowrap; }
.list-table__col-note { min-width: 120px; }

/* Die zwei Spalten, die sich nach dem Inhalt richten: Gast und Mietobjekt
 * tragen die langen Namen. Eine Mindestbreite hält sie lesbar, wenn die
 * festen Spalten daneben breit werden; ein sehr langes Wort bricht um,
 * statt die Tabelle über den Rand zu schieben. */
.list-table__col-guest,
.list-table__col-accommodation { min-width: 140px; overflow-wrap: anywhere; }

.list-table th.list-table__col-amount,
.list-table td.list-table__col-amount,
.list-table__col-amount {
    width: 1%;
    text-align: right;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.list-table__col-number,
.list-table th.list-table__col-number,
.list-table td.list-table__col-number {
    width: 1%;
    text-align: right;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.list-table .list-table__col-actions {
    width: 1%;
    text-align: right;
    white-space: nowrap;
}

.list-table th.text-right,
.list-table td.text-right,
.text-right { text-align: right; }

/* Die Spaltenraster der Listen. Gesetzt waren sie in den Vorlagen seit
 * 5.14, definiert in keinem Stylesheet. Sie tragen nur, was die Liste von
 * der Grundform unterscheidet. */
.list-table--bookings .list-table__col-note,
.list-table--occupancies .list-table__col-note { max-width: 220px; }
.list-table--settlements .list-table__col-invoice,
.list-table--owner-invoices .list-table__col-invoice,
.list-table--free-invoices .list-table__col-invoice { width: 1%; white-space: nowrap; }
.list-table--statistics .list-table__col-booking-number { width: 1%; white-space: nowrap; font-variant-numeric: tabular-nums; }
.list-table--blacklist .list-table__col-contact { min-width: 180px; }
.list-table--blacklist .list-table__col-last-booking { width: 1%; white-space: nowrap; }
.list-table--stays-overview .list-table__col-persons,
.list-table--occupancy-periods .list-table__col-persons { width: 1%; white-space: nowrap; }

/* Die Summenzeile trägt dieselbe Ausrichtung wie die Spalte darüber und
 * hebt sich nur durch Linie und Schnitt ab. */
.list-table__row--total td {
    border-top: 2px solid var(--frontend-core-color-line);
    border-bottom: 0;
    background: var(--frontend-core-color-surface-alt);
    font-weight: var(--frontend-core-fw-medium);
}

/* Zeitraum mit Zeichen davor, in einer Zeile. */
.list-table__period {
    display: inline-flex;
    align-items: center;
    gap: var(--frontend-core-space-2);
    white-space: nowrap;
}

.list-table__period svg { flex: 0 0 auto; color: var(--frontend-core-color-muted); }

.list-table__period-values {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
}

.list-table__guest {
    display: inline-flex;
    align-items: flex-start;
    gap: var(--frontend-core-space-2);
    font-weight: var(--frontend-core-fw-medium);
}

.list-table__guest svg { flex: 0 0 auto; margin-top: 3px; }

.list-table__actions {
    display: inline-flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    align-items: center;
    gap: var(--frontend-core-space-2);
}

/* Die Zelle, in der es nichts zu tun gibt. Leer liest sie sich wie „hier
 * fehlt etwas"; der leise Satz sagt, wer es stattdessen tut. */
.list-table__actions-empty {
    font-size: .8rem;
    color: var(--frontend-core-color-muted);
    white-space: normal;
}

@media (max-width: 760px) {
    .list-table thead { display: none; }

    .list-table,
    .list-table tbody,
    .list-table tfoot {
        display: block;
        width: 100%;
    }

    .list-table {
        overflow: visible;
        border: 0;
        border-radius: 0;
        background: none;
    }

    .list-table tr,
    .list-table tbody tr {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto;
        gap: 2px var(--frontend-core-space-3);
        margin-bottom: var(--frontend-core-space-2);
        padding: var(--frontend-core-space-3) var(--frontend-core-space-4);
        border: 1px solid var(--frontend-core-color-line);
        border-radius: var(--frontend-core-radius);
        background: var(--frontend-core-color-surface);
    }

    .list-table td {
        grid-column: 1 / -1;
        width: auto;
        padding: 0;
        border: 0;
        font-size: .8rem;
        text-align: left;
        white-space: normal;
        color: var(--frontend-core-color-muted);
    }

    .list-table td[data-label]:not([data-label=""])::before {
        content: attr(data-label) " ";
        color: var(--frontend-core-color-muted);
    }

    /* Dieselbe Stärke wie die Regel darüber (0-3-2) und danach: Mit einer
       Klasse weniger gewann die Beschriftung, und vor dem Zeitraum stand
       wieder „Zeitraum". */
    .list-table td[data-label].list-table__plain::before,
    .list-table td[data-label].list-table__lead::before,
    .list-table td[data-label].list-table__title::before,
    .list-table td[data-label].list-table__col-status::before,
    .list-table td[data-label].list-table__col-actions::before { content: none; }

    .list-table td.list-table__lead {
        grid-row: 1;
        grid-column: 1;
        font-size: .875rem;
        font-weight: var(--frontend-core-fw-medium);
        color: var(--frontend-core-color-text);
    }

    .list-table td.list-table__col-status {
        grid-row: 1;
        grid-column: 2;
        justify-self: end;
        width: auto;
    }

    .list-table td.list-table__title {
        margin-top: var(--frontend-core-space-1);
        font-size: .875rem;
        color: var(--frontend-core-color-text);
    }

    .list-table td.list-table__col-amount {
        grid-column: 1;
        margin-top: var(--frontend-core-space-2);
        padding-top: var(--frontend-core-space-2);
        border-top: 1px solid var(--frontend-core-color-line);
        font-size: .875rem;
        font-weight: var(--frontend-core-fw-medium);
        color: var(--frontend-core-color-text);
        text-align: left;
    }

    .list-table td.list-table__col-actions {
        grid-column: 1 / -1;
        margin-top: var(--frontend-core-space-2);
        text-align: left;
    }

    .list-table td.list-table__col-amount + td.list-table__col-actions {
        grid-column: 2;
        align-self: end;
        padding-top: var(--frontend-core-space-2);
        border-top: 1px solid var(--frontend-core-color-line);
    }

    .list-table__actions { justify-content: flex-start; }
    .list-table__period { white-space: normal; }

    .list-table__row--total td { border-top: 0; background: none; }
}

/* DER LEERZUSTAND STEHT AUF EINER KARTE, wo sonst die Liste stünde —
 * derselbe Rahmen, dieselbe Rundung. Ohne Fläche schwebte der Satz mittig
 * im Grau der Seite und las sich wie „noch nicht geladen". Zeichen, Titel
 * und Satz kommen aus `.empty` (`default.css`). */
.empty--panel {
    border: 1px solid var(--frontend-core-color-line);
    border-radius: var(--frontend-core-radius);
    background: var(--frontend-core-color-surface);
}

/* Nur das schlichte Symbol bekommt die Linienfarbe. Die Scheibe
   (`empty__icon--disc`) trägt ihren Ton selbst — grün bei „erledigt“,
   gelb bei Warnung. Diese Regel ist spezifischer als die Scheibe und
   färbte deren Zeichen sonst grau, während der Grund grün blieb. */
.empty--panel .empty__icon:not(.empty__icon--disc) { color: var(--frontend-core-color-line-strong); }
.empty--panel .empty__title { font-weight: var(--frontend-core-fw-medium); }
.empty--panel .empty__text { margin-bottom: 0; }

/* ============================================================
   STATUS — PUNKT UND PILLE
   ============================================================

   DER STATUS IST EIN WORT MIT FARBE, KEIN KASTEN (`status-label`). Acht
   farbige Kästen lesen sich wie eine Warnung, acht farbige Punkte wie
   eine Liste. Der Ton steht in der Grundregel: Wer eine Ausprägung
   vergisst, bekommt ein graues Wort, nicht nichts (#701).

   Die Pille (`status-pill`) ist für die Stelle, an der der Stand das
   Einzige ist, was eine Zeile trägt — der Stand einer Schadenmeldung.

   FARBEN NUR AUS `--frontend-core-status-*` (`root.css`), dieselben Werte
   wie die Statusfarben im Backoffice (`--badge-*-bd`). */

.status-label {
    --status-tone: var(--frontend-core-status-blocked, rgba(108, 117, 125, .9));
    display: inline-flex;
    align-items: center;
    gap: var(--frontend-core-space-2);
    font-size: .82rem;
    font-weight: var(--frontend-core-fw-medium);
    line-height: 1.3;
    color: var(--status-tone);
    white-space: nowrap;
}

.status-label::before {
    content: '';
    flex: 0 0 7px;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: currentColor;
}

/* Gedämpft: ein Stand, der keine Aufmerksamkeit braucht („Abreise
   heute", „Kommende Anreise"). Die Farbe gehört dem, was zählt. */
.status-label--quiet { color: var(--frontend-core-color-muted); }

/* Die Zustände der Belege — Rechnungen, Abrechnungen, Sperrliste. */
.status-label--paid,
.status-label--active,
.status-label--booking { --status-tone: var(--frontend-core-status-booked, rgba(25, 135, 84, .9)); }
.status-label--open { --status-tone: var(--frontend-core-status-reserved, rgba(253, 126, 20, .9)); }
.status-label--overdue,
.status-label--blocked,
.status-label--cancel { --status-tone: var(--frontend-core-status-cancel, rgba(220, 53, 69, .9)); }
.status-label--new { --status-tone: var(--frontend-core-status-request, rgba(0, 102, 204, .9)); }
.status-label--draft { --status-tone: var(--frontend-core-status-draft, #6b7280); }

/* Die Buchungsstatus — alle neun. Zuordnung wie im Belegungsplan des
 * Backoffice (`ui-pages.css`, `--ev-tone`). `--unknown` ist der
 * Auffangfall: ein grauer, beschrifteter Platz statt einer leeren Zelle. */
.status--blocked { --status-tone: var(--frontend-core-status-blocked, rgba(108, 117, 125, .9)); }
.status--booking_request { --status-tone: var(--frontend-core-status-request, rgba(0, 102, 204, .9)); }
.status--reserved,
.status--new,
.status--booking { --status-tone: var(--frontend-core-status-reserved, rgba(253, 126, 20, .9)); }
.status--booked { --status-tone: var(--frontend-core-status-booked, rgba(25, 135, 84, .9)); }
.status--owner { --status-tone: var(--frontend-core-status-owner, rgba(156, 28, 139, .9)); }
.status--expired { --status-tone: var(--frontend-core-status-expired, rgba(121, 85, 72, .9)); }
.status--cancel { --status-tone: var(--frontend-core-status-cancel, rgba(220, 53, 69, .9)); }
.status--unknown { --status-tone: var(--frontend-core-status-blocked, rgba(108, 117, 125, .9)); }

.status-pill {
    --status-tone: var(--frontend-core-status-blocked, rgba(108, 117, 125, .9));
    display: inline-flex;
    align-items: center;
    padding: 2px var(--frontend-core-space-2);
    border: 1px solid color-mix(in srgb, var(--status-tone) 45%, transparent);
    border-radius: var(--frontend-core-radius-pill);
    background: color-mix(in srgb, var(--status-tone) 13%, var(--frontend-core-color-surface));
    font-size: .75rem;
    font-weight: var(--frontend-core-fw-medium);
    color: var(--status-tone);
    white-space: nowrap;
}

.status-pill--info { --status-tone: var(--frontend-core-status-request); }
.status-pill--warning { --status-tone: var(--frontend-core-status-reserved); }
.status-pill--success { --status-tone: var(--frontend-core-status-booked); }
.status-pill--muted { --status-tone: var(--frontend-core-status-blocked); }

/* Der Zustand als Satz, kein Knopf: gemeldet, abgesagt, noch nicht dran. */
.state-note {
    display: flex;
    align-items: center;
    gap: var(--frontend-core-space-2);
    margin: 0;
    font-size: .85rem;
    color: var(--frontend-core-color-muted);
}

.state-note svg { flex: 0 0 15px; width: 15px; height: 15px; }
.state-note--done svg { color: var(--frontend-core-status-booked); }
.state-note--declined { color: var(--frontend-core-status-cancel); font-weight: var(--frontend-core-fw-medium); }

/* ============================================================
   KNÖPFE
   ============================================================

   Nach `MOCKUP-FRONTEND-DIALOGE-KNOEPFE-ENTWURF.html` (K1–K6). EINE Form —
   ein leicht gerundetes Rechteck (`--frontend-core-button-radius`, 10px) —
   und vier Stufen, nicht mehr:

     Haupt  `btn--primary`   Fläche in der Hausfarbe
     Zweit  `btn--secondary` weiß, grauer Rahmen, ganz leichter Schatten
     Leise  `btn--quiet`     nur Text, Fläche beim Überfahren
                             (`btn--ghost` und `btn--link` sind dieselbe Stufe)
     Gefahr `btn--danger`    gedämpftes Rot, nur für Unumkehrbares

   Zwei Größen: 44px (Fingerbreite, auch am Rechner) und 36px (`btn--sm`)
   für Werkzeuge in Listen. Kein Leuchtschatten, kein farbiger Rahmen in
   einer Fremdfarbe. Gesperrt heißt 40 % Deckkraft; ein Knopf, den
   `form.js` nach dem Absenden sperrt (`aria-busy`), zeigt einen Kreis.

   DIE STÄRKE IST ABSICHT. `:is(a, button, input[type="submit"],
   summary).btn` steht so stark wie die Grundregel des Skeletts und eine
   Stufe über einem `.btn` im Theme der Webseite: Das Theme der öffentlichen
   Seite lädt nach diesem Stylesheet und gestaltet seine eigenen Knöpfe
   anders. In den Anmeldebereichen gilt diese Form; die Instanz ändert sie
   über die Variablen oben, für alle Knöpfe zugleich. */

:is(a, button, input[type="submit"], summary).btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--frontend-core-space-2);
    min-height: 44px;
    padding: 0 20px;
    border: 1px solid var(--frontend-core-color-line-strong);
    border-radius: var(--frontend-core-button-radius);
    background: var(--frontend-core-color-surface);
    box-shadow: 0 1px 2px rgba(15, 23, 42, .05);
    color: var(--frontend-core-color-text);
    font-family: var(--frontend-core-font);
    font-size: 15px;
    font-weight: var(--frontend-core-fw-medium);
    line-height: 1.2;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

:is(a, button, input[type="submit"], summary).btn:hover {
    background: var(--frontend-core-color-surface-alt);
    color: var(--frontend-core-color-text);
}

:is(a, button, input[type="submit"], summary).btn:focus-visible {
    outline: 2px solid var(--frontend-core-button-primary);
    outline-offset: 2px;
}

:is(a, button, input[type="submit"], summary).btn.btn--secondary {
    border-color: var(--frontend-core-color-line-strong);
    border-radius: var(--frontend-core-button-radius);
    background: var(--frontend-core-color-surface);
    color: var(--frontend-core-color-text);
    font-weight: var(--frontend-core-fw-medium);
}

:is(a, button, input[type="submit"], summary).btn.btn--secondary:hover {
    background: var(--frontend-core-color-surface-alt);
    color: var(--frontend-core-color-text);
}

:is(a, button, input[type="submit"], summary).btn.btn--primary {
    border-color: transparent;
    background: var(--frontend-core-button-primary);
    box-shadow: none;
    color: var(--frontend-core-button-primary-contrast);
}

:is(a, button, input[type="submit"], summary).btn.btn--primary:hover {
    background: var(--frontend-core-button-primary-hover);
    color: var(--frontend-core-button-primary-contrast);
}

:is(a, button, input[type="submit"], summary).btn:is(.btn--quiet, .btn--ghost) {
    border-color: transparent;
    background: transparent;
    box-shadow: none;
}

:is(a, button, input[type="submit"], summary).btn:is(.btn--quiet, .btn--ghost):hover {
    background: var(--frontend-core-color-surface-alt);
}

:is(a, button, input[type="submit"], summary).btn.btn--link {
    min-height: 0;
    padding: 0;
    border-color: transparent;
    background: transparent;
    box-shadow: none;
    color: var(--frontend-core-color-primary);
    text-decoration: underline;
    text-underline-offset: .2em;
}

:is(a, button, input[type="submit"], summary).btn.btn--danger {
    border-color: transparent;
    background: var(--frontend-core-button-danger);
    box-shadow: none;
    color: #fff;
}

:is(a, button, input[type="submit"], summary).btn.btn--danger:hover {
    background: var(--frontend-core-button-danger-hover);
    color: #fff;
}

:is(a, button, input[type="submit"], summary).btn.btn--sm {
    min-height: 36px;
    padding: 0 14px;
    font-size: 14px;
}

:is(a, button, input[type="submit"], summary).btn.btn--block {
    display: flex;
    width: 100%;
}

:is(a, button, input[type="submit"], summary).btn:disabled,
:is(a, button, input[type="submit"], summary).btn[aria-disabled="true"] {
    opacity: .4;
    cursor: not-allowed;
}

/* Lädt: Kreis vor der Aufschrift, Knopf gesperrt. Volle Deckkraft — der
   Knopf ist beschäftigt, nicht unerreichbar. */
:is(a, button, input[type="submit"], summary).btn[aria-busy="true"] {
    opacity: 1;
    cursor: progress;
}

:is(a, button, input[type="submit"], summary).btn[aria-busy="true"]::before {
    content: '';
    flex: 0 0 16px;
    width: 16px;
    height: 16px;
    border: 2px solid color-mix(in srgb, currentColor 40%, transparent);
    border-top-color: currentColor;
    border-radius: 50%;
    animation: area-spin .8s linear infinite;
}

:is(a, button, input[type="submit"], summary).btn[aria-busy="true"] svg { display: none; }

@keyframes area-spin { to { transform: rotate(360deg); } }

.btn svg { flex: 0 0 auto; }

/* Der reine Symbolknopf: Kreuz, Pfeil. 36px, 8px Rundung, ohne Rahmen,
   immer mit `aria-label`. */
.icon-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    padding: 0;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--frontend-core-color-muted);
    cursor: pointer;
}

.icon-button:hover { background: var(--frontend-core-color-surface-alt); color: var(--frontend-core-color-text); }

.icon-button:focus-visible {
    outline: 2px solid var(--frontend-core-button-primary);
    outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
    :is(a, button, input[type="submit"], summary).btn[aria-busy="true"]::before { animation-duration: 2s; }
}

/* ============================================================
   CHIPS UND SEGMENT
   ============================================================

   Ein Chip ist eine Angabe (`chip`) oder eine Wahl (`chip` mit Feld
   darin). Gewählt zeigt er es an Rahmen, Fläche und — bei Mehrfachwahl —
   am Haken RECHTS neben dem Wort: Links stünde der Haken vor dem Wort,
   das man sucht, und schöbe es beim Antippen zur Seite. */

.chip {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 32px;
    padding: 0 var(--frontend-core-space-3);
    border: 1px solid var(--frontend-core-color-line);
    border-radius: var(--frontend-core-radius-pill);
    background: var(--frontend-core-color-surface);
    color: var(--frontend-core-color-text);
    font: inherit;
    font-size: .85rem;
    text-decoration: none;
    white-space: nowrap;
}

.chip svg { flex: 0 0 13px; width: 13px; height: 13px; }
.chip a { color: inherit; font-weight: var(--frontend-core-fw-medium); text-decoration: none; }

/* Angabe: leicht getönt, damit sie sich vom wählbaren Chip unterscheidet. */
.chip--info {
    min-height: 0;
    padding: 4px var(--frontend-core-space-2);
    background: color-mix(in srgb, var(--frontend-core-color-line) 30%, var(--frontend-core-color-surface));
    font-size: .8rem;
    white-space: normal;
}

.chip--ok {
    border-color: color-mix(in srgb, var(--frontend-core-status-booked) 45%, transparent);
    background: color-mix(in srgb, var(--frontend-core-status-booked) 13%, var(--frontend-core-color-surface));
    color: var(--frontend-core-status-booked);
    font-weight: var(--frontend-core-fw-medium);
}

/* Wahl: Als Verweis (Schnellfilter) oder als Feld im Filter. */
a.chip,
button.chip,
label.chip { min-height: 36px; cursor: pointer; }

.chip.is-on,
.chip:has(input:checked) {
    border-color: var(--frontend-core-color-primary);
    background: var(--frontend-core-color-soft);
    color: var(--frontend-core-color-primary);
    font-weight: var(--frontend-core-fw-medium);
}

.chip:has(input:focus-visible) {
    outline: 2px solid var(--frontend-core-color-primary);
    outline-offset: 2px;
}

.chip input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.chip__check { display: none; }
.chip:has(input:checked) .chip__check { display: inline; }
.chip[hidden] { display: none; }

/* `display: flex` an `.field` schlägt das `hidden` des Browsers. Ohne
   diese Zeile blieb im Schadendialog die Objektwahl sichtbar, obwohl das
   Objekt aus der Karte schon feststand. */
.field[hidden] { display: none; }

.chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--frontend-core-space-2);
}

/* Waagerecht scrollbar statt umbrechend: Vier Chips, die auf 375px in zwei
   Zeilen rutschen, kosten mehr Höhe als der Wischweg. */
.chips--scroll {
    flex-wrap: nowrap;
    overflow-x: auto;
    padding-bottom: 2px;
    -webkit-overflow-scrolling: touch;
}

.chips--scroll > .chip { flex: 0 0 auto; }

/* Ein Segment für bis zu vier Werte: Drei Werte sieht man auf einen
   Blick, eine Auswahl versteckt sie hinter einem Klick. Ob die Werte
   Verweise (`a`) oder Felder (`label` mit `input`) sind, ist dem Bauteil
   gleich. */
.segment {
    display: inline-grid;
    grid-auto-columns: minmax(0, 1fr);
    grid-auto-flow: column;
    gap: var(--frontend-core-space-1);
    padding: var(--frontend-core-space-1);
    border-radius: var(--frontend-core-radius-pill);
    background: var(--frontend-core-color-surface-alt);
}

.segment--block { display: grid; width: 100%; }

.segment__item {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 36px;
    padding: 0 var(--frontend-core-space-3);
    border: 0;
    border-radius: var(--frontend-core-radius-pill);
    background: transparent;
    color: var(--frontend-core-color-muted);
    font: inherit;
    font-size: .85rem;
    font-weight: var(--frontend-core-fw-medium);
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
}

.segment__item input { position: absolute; opacity: 0; pointer-events: none; }

/* Eine Beschriftung des Skeletts (`form label`) bringt Abstand und Block
   mit; hier gezielt zurückgesetzt, nicht global. Keine graue Fläche beim
   Überfahren oder als Textauswahl — der Hinweis ist die Schriftfarbe. */
label.segment__item,
label.chip {
    margin: 0;
    user-select: none;
    -webkit-user-select: none;
    -webkit-tap-highlight-color: transparent;
}

.segment__item:hover { color: var(--frontend-core-color-text); }

.segment__item.is-on,
.segment__item:has(input:checked) {
    background: var(--frontend-core-color-surface);
    color: var(--frontend-core-color-text);
    box-shadow: 0 1px 3px rgba(15, 23, 42, .12);
}

.segment__item:has(input:focus-visible) {
    outline: 2px solid var(--frontend-core-color-primary);
    outline-offset: 1px;
}

/* ============================================================
   DIE ZEILE ÜBER DER LISTE
   ============================================================

   Auf dem Telefon scrollt man durch viele Karten; die Zahl oben ist die
   einzige Orientierung. Sie klebt deshalb. */

.toolbar {
    position: sticky;
    top: 0;
    z-index: 2;
    margin-bottom: var(--frontend-core-space-4);
    padding: var(--frontend-core-space-3) 0;
    border-bottom: 1px solid var(--frontend-core-color-line);
    background: var(--frontend-core-color-surface);
}

.toolbar__row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--frontend-core-space-3);
}

.toolbar__count { flex: 1 1 auto; font-size: .95rem; font-weight: var(--frontend-core-fw-medium); }
.toolbar__count small { font-size: inherit; font-weight: 400; color: var(--frontend-core-color-muted); }

@media (max-width: 600px) {
    .toolbar__count { flex: 1 1 100%; }
}

/* ============================================================
   FELDER
   ============================================================

   Beschriftung über dem Feld, Feldhilfe darunter. Die Hilfe sagt, WELCHE
   Angabe gemeint ist — unter einem Feld liest sich das als Erklärung,
   mittig mit großem Abstand als neuer Absatz. */

.field-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--frontend-core-space-3);
    margin-top: var(--frontend-core-space-3);
}

@media (max-width: 600px) {
    .field-grid { grid-template-columns: minmax(0, 1fr); }
}

.field {
    display: flex;
    flex-direction: column;
    gap: var(--frontend-core-space-1);
    min-width: 0;
    margin: 0;
    padding: 0;
    border: 0;
}

.field + .field { margin-top: var(--frontend-core-space-4); }
.field-grid > .field + .field { margin-top: 0; }

.field__label {
    margin: 0;
    padding: 0;
    font-size: .85rem;
    font-weight: var(--frontend-core-fw-medium);
    color: var(--frontend-core-color-text);
}

.field__label--quiet { font-weight: 400; color: var(--frontend-core-color-muted); }

/* „Pflichtfeld" ausgeschrieben statt als Sternchen: Ein Stern muss
   erklärt werden, ein Wort nicht. */
.field__required {
    margin-left: var(--frontend-core-space-1);
    font-size: .75rem;
    font-weight: 400;
    color: var(--frontend-core-color-muted);
}

.field__input {
    box-sizing: border-box;
    width: 100%;
    min-width: 0;
    min-height: 44px;
    padding: 0 var(--frontend-core-space-3);
    border: 1px solid var(--frontend-core-color-line-strong);
    border-radius: var(--frontend-core-radius-sm);
    background: var(--frontend-core-color-surface);
    color: inherit;
    font: inherit;
    font-size: .9rem;
}

textarea.field__input {
    min-height: 96px;
    padding: var(--frontend-core-space-2) var(--frontend-core-space-3);
    line-height: 1.5;
    resize: vertical;
}

/* Das Auswahlfeld braucht einen eigenen Pfeil: Der native verschwindet,
   sobald ein Reset `appearance: none` setzt. Als SVG, nicht als Zeichen. */
select.field__input {
    padding-right: 34px;
    appearance: none;
    -webkit-appearance: none;
    background:
        url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2367737d' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E")
        no-repeat right 10px center / 16px 16px,
        var(--frontend-core-color-surface);
    cursor: pointer;
}

.field__input--search {
    padding-left: 38px;
    background:
        url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'/%3E%3C/svg%3E")
        no-repeat 12px center / 16px 16px,
        var(--frontend-core-color-surface);
}

/* Fokus in der Hausfarbe: Rand und ein weicher Ring, kein zweiter
   dunkler Fokusrand des Browsers darüber. */
.field__input:focus,
.field__input:focus-visible {
    outline: none;
    border-color: var(--frontend-core-color-primary);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--frontend-core-color-primary) 18%, transparent);
}

.field__help {
    margin: var(--frontend-core-space-1) 0 0;
    font-size: .8rem;
    line-height: 1.45;
    color: var(--frontend-core-color-muted);
}

/* Von – Bis in einer Zeile. */
.field-range {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    align-items: center;
    gap: var(--frontend-core-space-2);
}

.field-range__dash { color: var(--frontend-core-color-muted); }

/* ============================================================
   DIALOG
   ============================================================

   Nach `MOCKUP-FRONTEND-DIALOGE-KNOEPFE-ENTWURF.html` (M1–M9): EINE weiße
   Fläche mit 24px Innenabstand, keine Trennlinien. Oben der Titel (18px,
   500) und EIN grauer Satz, wofür der Dialog ist; rechts das Kreuz als
   leiser Symbolknopf. Über den Knöpfen steht, was danach passiert
   (`dialog__effect`). Im Fuß „Abbrechen" leise links, der Hauptknopf
   rechts — überall dieselbe Reihenfolge. Der Fuß klebt, wenn der Inhalt
   rollt. Auf dem Telefon kommt der Dialog als Blatt von unten, der
   Hauptknopf steht dort OBEN über die volle Breite, wo der Daumen ist.

   Öffnen und Schließen: `area.js` (`data-dialog-open`,
   `data-dialog-close`, Esc, Klick daneben). */

.dialog[hidden] { display: none; }

.dialog {
    position: fixed;
    inset: 0;
    z-index: 1050;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--frontend-core-font);
}

/* EINBLENDEN UND AUSBLENDEN.
 *
 * Ein Dialog, der ohne Übergang auf- und zuschnappt, wirkt wie ein
 * Seitenwechsel; man verliert kurz, wo man war. Hintergrund und Dialog
 * blenden deshalb über 200 ms ein, der Dialog mit einer kleinen Bewegung
 * nach oben — beim Schließen dasselbe rückwärts. `hidden` setzt `area.js`
 * erst, wenn die Bewegung zu Ende ist (`transitionend`, mit Rückfall auf
 * einen Zeitgeber, falls das Ereignis ausbleibt). */
.dialog__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(15, 23, 42, .32);
    opacity: 0;
    transition: opacity var(--frontend-core-sheet-speed) ease;
}

.dialog.is-open .dialog__backdrop { opacity: 1; }

.dialog__panel {
    position: relative;
    display: flex;
    flex-direction: column;
    width: calc(100% - 2rem);
    max-width: 480px;
    max-height: calc(100vh - 2rem);
    overflow: hidden;
    border-radius: 16px;
    background: var(--frontend-core-color-surface);
    box-shadow: 0 24px 64px rgba(15, 23, 42, .24);
    opacity: 0;
    transform: translateY(8px) scale(.98);
    transition:
        opacity var(--frontend-core-sheet-speed) ease,
        transform var(--frontend-core-sheet-speed) ease;
}

.dialog.is-open .dialog__panel {
    opacity: 1;
    transform: none;
}

.dialog__panel:focus { outline: none; }
.dialog__panel--narrow { max-width: 440px; }
.dialog__panel--wide { max-width: 640px; }

.dialog__grip {
    display: none;
    width: 40px;
    height: 4px;
    margin: var(--frontend-core-space-2) auto 0;
    border-radius: 4px;
    background: var(--frontend-core-color-line-strong);
}

.dialog__head {
    display: flex;
    align-items: flex-start;
    gap: var(--frontend-core-space-3);
    padding: 20px var(--frontend-core-space-5) 0;
}

.dialog__titles { flex: 1 1 auto; min-width: 0; }

.dialog__title {
    margin: 0;
    font-size: 18px;
    font-weight: var(--frontend-core-fw-medium);
    line-height: 1.3;
    color: var(--frontend-core-color-text);
}

.dialog__sub {
    margin: var(--frontend-core-space-1) 0 0;
    font-size: 14px;
    color: var(--frontend-core-color-muted);
}

.dialog__sub:empty { display: none; }

.dialog__close {
    flex: 0 0 auto;
    margin: -6px -8px 0 0;
}

.dialog__form {
    display: flex;
    flex-direction: column;
    min-height: 0;
    margin: 0;
}

.dialog__body {
    display: grid;
    gap: var(--frontend-core-space-4);
    padding: 20px var(--frontend-core-space-5);
    overflow-y: auto;
}

.dialog__body > * { margin-top: 0; margin-bottom: 0; }
.dialog__body .field + .field { margin-top: 0; }

/* Was nach dem Knopf passiert — auf leiser Fläche, nicht als Hinweisbalken. */
.dialog__effect {
    margin: 0;
    padding: var(--frontend-core-space-3) 14px;
    border-radius: 10px;
    background: var(--frontend-core-color-surface-alt);
    font-size: 14px;
    color: var(--frontend-core-color-muted);
}

.dialog__foot {
    position: sticky;
    bottom: 0;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--frontend-core-space-2);
    padding: 0 var(--frontend-core-space-5) var(--frontend-core-space-5);
    background: var(--frontend-core-color-surface);
}

.dialog__foot > .btn--quiet:first-child,
.dialog__foot > .btn--ghost:first-child { margin-right: auto; }

body.dialog-open { overflow: hidden; }

@media (max-width: 600px) {
    .dialog { align-items: flex-end; }

    .dialog__panel,
    .dialog__panel--narrow,
    .dialog__panel--wide {
        width: 100%;
        max-width: none;
        max-height: 92vh;
        border-radius: 20px 20px 0 0;
        opacity: 1;
        transform: translateY(100%);
    }

    .dialog__grip { display: block; }

    .dialog__foot {
        flex-direction: column;
        align-items: stretch;
    }

    .dialog__foot > .btn,
    .dialog__foot > form > .btn { width: 100%; }

    .dialog__foot > .btn--quiet:first-child,
    .dialog__foot > .btn--ghost:first-child {
        order: 2;
        margin-right: 0;
    }
}

/* Ohne Bewegung, wer sie abgeschaltet hat — nur ein kurzes Einblenden. */
@media (prefers-reduced-motion: reduce) {
    .dialog__backdrop,
    .dialog__panel,
    .dialog__panel--narrow,
    .dialog__panel--wide {
        transform: none;
        transition: opacity 120ms linear;
    }

    .dialog__panel { opacity: 0; }
}

/* ============================================================
   STERNE
   ============================================================

   Fünf Zeichen, gefüllt bis zur Note. Die Zahl steht daneben — der
   Stern ist das Zeichen, das jeder kennt, die Zahl das, was man vergleicht.
   Die Farbe ist die Sternfarbe des Themes. */

.stars {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    color: var(--frontend-core-review-star-color, #fbbf24);
    vertical-align: -2px;
}

.stars svg { width: 14px; height: 14px; }
.stars__empty { color: var(--frontend-core-color-line); }
.tile__value .stars svg { width: 18px; height: 18px; }

/* ============================================================
   DAS FILTER-SCHUBFACH
   ============================================================

   Nach `MOCKUP-FRONTEND-FILTER-ENTWURF.html`. Am Rechner schiebt es sich
   von rechts herein, am Telefon kommt es als Blatt von unten mit Griff.
   200 ms, mit abgedunkeltem Hintergrund; Esc, Kreuz und Klick auf den
   Hintergrund schließen (`area.js`).

   Der Fuß klebt unten und sagt, was passiert. „Zurücksetzen" steht leise
   im Kopf — nicht als zweiter gleich großer Knopf neben dem Hauptknopf,
   wo man ihn mit dem Anwenden verwechselt. */

.filter-sheet__open { gap: var(--frontend-core-space-2); }

.filter-sheet__count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 22px;
    height: 22px;
    padding: 0 7px;
    border-radius: var(--frontend-core-radius-pill);
    background: var(--frontend-core-color-soft);
    color: var(--frontend-core-color-primary);
    font-size: .75rem;
    font-weight: var(--frontend-core-fw-medium);
}

.filter-sheet {
    position: fixed;
    inset: 0;
    z-index: 1040;
    visibility: hidden;
    pointer-events: none;
    font-family: var(--frontend-core-font);
    transition: visibility 0s linear var(--frontend-core-sheet-speed);
}

.filter-sheet.is-open {
    visibility: visible;
    pointer-events: auto;
    transition-delay: 0s;
}

.filter-sheet__scrim {
    position: absolute;
    inset: 0;
    background: rgba(15, 23, 42, .32);
    opacity: 0;
    transition: opacity var(--frontend-core-sheet-speed) ease;
}

.filter-sheet.is-open .filter-sheet__scrim { opacity: 1; }

.filter-sheet__panel {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    display: flex;
    flex-direction: column;
    width: var(--frontend-core-sheet-width);
    max-width: 100%;
    margin: 0;
    background: var(--frontend-core-color-surface);
    box-shadow: -12px 0 40px rgba(15, 23, 42, .16);
    transform: translateX(100%);
    transition: transform var(--frontend-core-sheet-speed) ease;
}

.filter-sheet.is-open .filter-sheet__panel { transform: none; }

.filter-sheet__grip {
    display: none;
    width: 40px;
    height: 4px;
    margin: var(--frontend-core-space-2) auto 0;
    border-radius: 4px;
    background: var(--frontend-core-color-line-strong);
}

.filter-sheet__head {
    display: flex;
    align-items: center;
    gap: var(--frontend-core-space-3);
    padding: var(--frontend-core-space-4) 20px;
    border-bottom: 1px solid var(--frontend-core-color-line);
}

.filter-sheet__title {
    flex: 1 1 auto;
    margin: 0;
    font-size: 1.1rem;
    font-weight: var(--frontend-core-fw-medium);
    color: var(--frontend-core-color-text);
}

.filter-sheet__reset {
    padding: var(--frontend-core-space-1) var(--frontend-core-space-2);
    border: 0;
    background: none;
    color: var(--frontend-core-color-primary);
    font: inherit;
    font-size: .875rem;
    font-weight: var(--frontend-core-fw-medium);
    cursor: pointer;
}

.filter-sheet__body {
    flex: 1 1 auto;
    min-height: 0;
    display: grid;
    align-content: start;
    gap: var(--frontend-core-space-5);
    padding: 20px;
    overflow-y: auto;
}

.filter-sheet__foot {
    padding: var(--frontend-core-space-4) 20px;
    border-top: 1px solid var(--frontend-core-color-line);
    background: var(--frontend-core-color-surface);
}

/* DER RHYTHMUS: Beschriftung → Inhalt 8px, Abschnitt → Abschnitt 24px
 * (`filter-sheet__body`), Kopf und Fuß 20px. Ein `fieldset` mit `legend`
 * nimmt an einem Raster nicht teil — die Legende stünde ohne Abstand über
 * dem Inhalt oder mit dem Abstand des Browsers. Deshalb Block und feste
 * Abstände an den Kindern. */
.filter-sheet__group {
    display: block;
    min-width: 0;
    margin: 0;
    padding: 0;
    border: 0;
}

.filter-sheet__group > * + * { margin-top: var(--frontend-core-space-2); }

.filter-sheet__group-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--frontend-core-space-3);
    width: 100%;
    margin: 0 0 var(--frontend-core-space-2);
    padding: 0;
}

.filter-sheet__group > .filter-sheet__group-head + * { margin-top: 0; }

.filter-sheet__label {
    display: block;
    margin: 0;
    font-size: .75rem;
    font-weight: var(--frontend-core-fw-medium);
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--frontend-core-color-muted);
}

/* Chips stehen nebeneinander, solange Platz ist. Das Skelett gibt `label`
 * Block und Abstand mit; ohne diese Zeile stand jeder Chip in eigener
 * Zeile. */
.filter-sheet .chips > .chip,
.active-filters > .active-filters__chip {
    display: inline-flex;
    width: auto;
    margin: 0;
}

.filter-sheet__hint { font-size: .75rem; color: var(--frontend-core-color-muted); }

body.filter-sheet-open { overflow: hidden; }

@media (max-width: 600px) {
    .filter-sheet__panel {
        top: auto;
        left: 0;
        width: auto;
        max-height: 88%;
        border-radius: 20px 20px 0 0;
        box-shadow: 0 -12px 40px rgba(15, 23, 42, .18);
        transform: translateY(100%);
    }

    .filter-sheet__grip { display: block; }
}

@media (prefers-reduced-motion: reduce) {
    .filter-sheet,
    .filter-sheet__scrim,
    .filter-sheet__panel { transition: none; }
}

/* Die aktiven Filter über der Liste, jeder mit Kreuz. Man sieht, warum
   die Liste kurz ist, ohne das Schubfach zu öffnen. */
.active-filters {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--frontend-core-space-2);
    margin-bottom: var(--frontend-core-space-4);
}

.active-filters__chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 32px;
    padding: 0 6px 0 var(--frontend-core-space-3);
    border-radius: var(--frontend-core-radius-pill);
    background: var(--frontend-core-color-soft);
    color: var(--frontend-core-color-primary);
    font-size: .8rem;
    font-weight: var(--frontend-core-fw-medium);
}

.active-filters__remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    padding: 0;
    border: 0;
    border-radius: var(--frontend-core-radius-pill);
    background: transparent;
    color: inherit;
    cursor: pointer;
}

.active-filters__remove:hover { background: color-mix(in srgb, var(--frontend-core-color-primary) 15%, transparent); }

.active-filters__clear {
    padding: 0;
    border: 0;
    background: none;
    color: var(--frontend-core-color-muted);
    font: inherit;
    font-size: .8rem;
    text-decoration: underline;
    text-underline-offset: .2em;
    cursor: pointer;
}

/* ============================================================
   SORTIEREN
   ============================================================

   SORTIERUNG IST KEIN FILTER. Sie schränkt nichts ein, sie ordnet. Im
   Schubfach stand sie als Chips — je Feld zwei, „aufsteigend" und
   „absteigend", dazu „Alle", das es beim Sortieren nicht gibt. Jetzt ein
   kleiner Knopf neben „Filter": „Sortieren: Reisezeitraum ↓". Er öffnet
   ein Menü mit EINEM Eintrag je Feld (Haken an der aktiven Zeile) und dem
   Umschalter für die Richtung — dieselbe Bedienung wie das Sortiermenü im
   Backoffice. Am Telefon kommt das Menü als kleines Blatt von unten.

   Gespeichert wird wie bisher: Das Menü schreibt den Wert in das Feld des
   Filterformulars und schickt es ab (`area.js`). */

.sort-menu { position: relative; display: inline-flex; }

.sort-menu__toggle .sort-menu__current { font-weight: var(--frontend-core-fw-medium); }

.sort-menu__panel {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    z-index: 30;
    display: grid;
    gap: 2px;
    width: 260px;
    padding: var(--frontend-core-space-2);
    border: 1px solid var(--frontend-core-color-line);
    border-radius: 12px;
    background: var(--frontend-core-color-surface);
    box-shadow: 0 12px 32px rgba(15, 23, 42, .14);
}

.sort-menu__panel[hidden] { display: none; }

.sort-menu__title {
    margin: var(--frontend-core-space-1) var(--frontend-core-space-2) var(--frontend-core-space-1);
    font-size: .75rem;
    font-weight: var(--frontend-core-fw-medium);
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--frontend-core-color-muted);
}

.sort-menu__item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--frontend-core-space-2);
    min-height: 40px;
    padding: 0 var(--frontend-core-space-2);
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--frontend-core-color-text);
    font: inherit;
    font-size: .9rem;
    text-align: left;
    cursor: pointer;
}

.sort-menu__item:hover { background: var(--frontend-core-color-surface-alt); }
.sort-menu__item .chip__check { display: none; color: var(--frontend-core-color-primary); }
.sort-menu__item[aria-checked="true"] { font-weight: var(--frontend-core-fw-medium); }
.sort-menu__item[aria-checked="true"] .chip__check { display: inline; }
.sort-menu__direction { margin-top: var(--frontend-core-space-2); }

@media (max-width: 600px) {
    .sort-menu__panel {
        position: fixed;
        top: auto;
        right: 0;
        bottom: 0;
        left: 0;
        width: auto;
        padding: var(--frontend-core-space-4) var(--frontend-core-space-4) var(--frontend-core-space-5);
        border-radius: 20px 20px 0 0;
        box-shadow: 0 -12px 40px rgba(15, 23, 42, .18);
    }
}

/* ============================================================
   VIELE WERTE: AUSWAHLFELD MIT LISTE
   ============================================================

   Bis sechs Werte stehen als Chips mit Haken im Schubfach. Ab sieben
   wird die Chip-Wolke länger als das Schubfach selbst — zwanzig Objekte
   sind zwanzig Chips, und der Knopf „Anzeigen" rückt aus dem Bild. Dann
   steht dort ein Feld „Mietobjekte: Alle" bzw. „3 gewählt", das eine
   Liste mit Suchfeld und Haken aufklappt (feste Höhe, die Liste rollt).
   Darunter stehen die gewählten Werte als kleine Chips, höchstens drei und
   „+N weitere". Formularname und gespeicherte Werte bleiben dieselben.

   Am Telefon klappt die Liste im Blatt des Schubfachs auf statt als
   zweites Blatt darüber: Zwei Blätter übereinander verlieren den Rückweg. */

.combo__toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    text-align: left;
    cursor: pointer;
}

.combo__toggle svg { flex: 0 0 auto; color: var(--frontend-core-color-muted); transition: transform .15s ease; }
.combo__toggle[aria-expanded="true"] svg { transform: rotate(180deg); }

.combo__panel {
    padding: var(--frontend-core-space-2);
    border: 1px solid var(--frontend-core-color-line);
    border-radius: 12px;
    background: var(--frontend-core-color-surface);
}

.combo__panel[hidden] { display: none; }

.combo__list {
    max-height: 280px;
    margin-top: var(--frontend-core-space-2);
    overflow-y: auto;
}

.combo__option {
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--frontend-core-space-2);
    min-height: 40px;
    padding: 0 var(--frontend-core-space-2);
    border-radius: 8px;
    cursor: pointer;
}

.combo__option:hover { background: var(--frontend-core-color-surface-alt); }
.combo__option[hidden] { display: none; }
.combo__option input { position: absolute; opacity: 0; pointer-events: none; }

.combo__name {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    font-size: .9rem;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.combo__option .chip__check { display: none; color: var(--frontend-core-color-primary); }
.combo__option:has(input:checked) .chip__check { display: inline; }
.combo__option:has(input:checked) .combo__name { font-weight: var(--frontend-core-fw-medium); }
.combo__option:has(input:focus-visible) { outline: 2px solid var(--frontend-core-color-primary); outline-offset: -2px; }

.chip .combo__name { max-width: 240px; }

.combo__chosen {
    display: flex;
    flex-wrap: wrap;
    gap: var(--frontend-core-space-2);
}

.combo__chosen:empty { display: none; }

.combo__chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    max-width: 180px;
    min-height: 28px;
    padding: 0 4px 0 10px;
    border-radius: var(--frontend-core-radius-pill);
    background: var(--frontend-core-color-soft);
    color: var(--frontend-core-color-primary);
    font-size: .8rem;
    font-weight: var(--frontend-core-fw-medium);
}

.combo__chip span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.combo__more { align-self: center; font-size: .8rem; color: var(--frontend-core-color-muted); }


/* ============================================================
   GÄSTEPORTAL — Zahl am Reiter, Buchungswechsler, Aufgabenliste,
   Zahlungsstand, Unterlagen
   ============================================================

   Freigegebener Entwurf des Gästeportals (ZIEL 1 bis 10).
   Gerüst: `mwfm_frontend_core/guest_portal.html.twig`. Die Teile hier
   gibt es im Eigentümer- und Reinigungs-Login nicht, sie sind aber nicht
   an den Gast gebunden: Die Zahl am Reiter kann jede Navigation tragen. */

/* Die Zahl am Reiter ist eine Auskunft: „Gastdaten 2" sagt, dass für zwei
 * Reisende etwas fehlt. Rot nur, wenn etwas auf den Besucher wartet; eine
 * Zahl ungelesener Nachrichten ist keine Mahnung. */
.area-nav__count {
    display: inline-block;
    min-width: 18px;
    margin-left: var(--frontend-core-space-2);
    padding: 2px 5px;
    border-radius: var(--frontend-core-radius-pill);
    background: var(--frontend-core-color-surface-alt);
    color: var(--frontend-core-color-muted);
    font-size: .7rem;
    font-weight: var(--frontend-core-fw-medium);
    line-height: 1.3;
    text-align: center;
}

.area-nav__item.is-on .area-nav__count {
    background: var(--frontend-core-color-soft);
    color: var(--frontend-core-color-primary);
}

.area-nav__count--alert,
.area-nav__item.is-on .area-nav__count--alert {
    background: color-mix(in srgb, var(--frontend-core-status-cancel, #dc3545) 13%, var(--frontend-core-color-surface, #fff));
    color: var(--frontend-core-status-cancel, #dc3545);
}

/* Über welchen Weg der Besucher hereinkam — nur nach einem Link aus einer
 * Mail. Der Satz sagt, für WELCHE Buchung der Link gilt, damit niemand
 * eine weitergeleitete Mail für eine dauerhafte Anmeldung hält. */
.portal-entry {
    margin: 0;
    padding: var(--frontend-core-space-2) var(--frontend-core-space-4);
    border-top: 1px solid var(--frontend-core-color-line);
    background: var(--frontend-core-color-surface-alt);
    color: var(--frontend-core-color-muted);
    font-size: .8rem;
    text-align: center;
}

/* Der leise Weg zu den übrigen Buchungen, wenn die Anmeldung nur EINE
 * öffnet (Buchungsnummer, Link aus der Mail). */
.area-user__alt {
    font-size: .8rem;
    color: var(--frontend-core-color-muted);
    white-space: nowrap;
}

.area-user__alt:hover { color: var(--frontend-core-color-primary); }

/* ---- DER BUCHUNGSWECHSLER ----
 *
 * Nur ab zwei Buchungen und nur nach dem Anmeldelink. Der Knopf nennt die
 * aktuelle Buchung und die Zahl der Buchungen; die Liste steht im Dialog
 * aus dem Gerüst — am Telefon als Blatt von unten. */
.booking-switcher {
    display: inline-flex;
    align-items: center;
    gap: var(--frontend-core-space-2);
    min-width: 0;
    max-width: 320px;
    min-height: 36px;
    padding: 0 var(--frontend-core-space-3);
    border: 1px solid var(--frontend-core-color-line-strong);
    border-radius: var(--frontend-core-radius-pill);
    background: var(--frontend-core-color-surface, #fff);
    color: var(--frontend-core-color-text);
    font: inherit;
    font-size: .82rem;
    cursor: pointer;
}

.booking-switcher:hover { border-color: var(--frontend-core-color-primary); }

.booking-switcher__label {
    overflow: hidden;
    font-weight: var(--frontend-core-fw-medium);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.booking-switcher__count {
    flex: 0 0 auto;
    min-width: 18px;
    padding: 1px 5px;
    border-radius: var(--frontend-core-radius-pill);
    background: var(--frontend-core-color-soft);
    color: var(--frontend-core-color-primary);
    font-size: .7rem;
    font-weight: var(--frontend-core-fw-medium);
    text-align: center;
}

.booking-switcher svg { flex: 0 0 auto; width: 12px; height: 12px; }

.booking-switcher__group + .booking-switcher__group {
    margin-top: var(--frontend-core-space-2);
    padding-top: var(--frontend-core-space-2);
    border-top: 1px solid var(--frontend-core-color-line);
}

.booking-switcher__title {
    display: flex;
    align-items: center;
    gap: var(--frontend-core-space-2);
    margin: var(--frontend-core-space-1) var(--frontend-core-space-2);
    font-size: .7rem;
    font-weight: var(--frontend-core-fw-medium);
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--frontend-core-color-muted);
    list-style: none;
}

summary.booking-switcher__title { cursor: pointer; }
summary.booking-switcher__title::-webkit-details-marker { display: none; }

.booking-switcher__row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto 20px;
    align-items: center;
    gap: var(--frontend-core-space-3);
    width: 100%;
    min-height: 48px;
    padding: var(--frontend-core-space-2);
    border: 0;
    border-radius: var(--frontend-core-radius-sm);
    background: none;
    color: var(--frontend-core-color-text);
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.booking-switcher__row:hover { background: var(--frontend-core-color-surface-alt); }

.booking-switcher__row.is-current {
    background: var(--frontend-core-color-soft);
    cursor: default;
}

.booking-switcher__main {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.booking-switcher__object {
    overflow: hidden;
    font-weight: var(--frontend-core-fw-medium);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.booking-switcher__dates {
    font-size: .8rem;
    color: var(--frontend-core-color-muted);
}

/* Die offenen Punkte der Buchung — als Wort, nie nur als Farbe. Der Ton
 * ist der der Reservierung, zum Text hin abgedunkelt, damit die kleine
 * Schrift auf hellem Grund lesbar bleibt. */
.booking-switcher__todo {
    font-size: .8rem;
    color: color-mix(in srgb, var(--frontend-core-status-reserved, #fd7e14) 60%, var(--frontend-core-color-text));
}

.booking-switcher__check {
    display: inline-flex;
    color: var(--frontend-core-color-primary);
}

/* Am Telefon rückt der Name aus der Kopfleiste — die Buchung trägt der
 * Wechsler, den Gast kennt der Gast. */
@media (max-width: 640px) {
    .booking-switcher { max-width: 100%; }
    .booking-switcher ~ .area-user__name { display: none; }
}

/* ---- WAS NOCH OFFEN IST ----
 *
 * Die Aufgabenliste steht ganz oben: offene Zahlung, fehlende Gastdaten,
 * zu bestätigende Reservierung. Die Sache selbst steht da, nicht ihre
 * Anzahl — „Es fehlen: Geburtsdatum" statt „Es fehlen 2 Angaben". */
.todo-list {
    display: flex;
    flex-direction: column;
    margin: 0;
    padding: 0;
    list-style: none;
}

.todo-list__item {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: start;
    gap: var(--frontend-core-space-3);
    padding: var(--frontend-core-space-3) 0;
    border-bottom: 1px solid var(--frontend-core-color-line);
}

.todo-list__item:last-child { border-bottom: 0; }

.todo-list__mark {
    flex: 0 0 auto;
    display: inline-flex;
    margin-top: 2px;
    color: var(--frontend-core-color-muted);
}

.todo-list__item--warning .todo-list__mark { color: var(--frontend-core-status-reserved, #fd7e14); }
.todo-list__item--done .todo-list__mark { color: var(--frontend-core-status-booked, #198754); }

.todo-list__main {
    flex: 1 1 auto;
    min-width: 0;
}

.todo-list__title {
    display: block;
    font-weight: var(--frontend-core-fw-medium);
}

.todo-list__item--done .todo-list__title {
    color: var(--frontend-core-color-muted);
    font-weight: 400;
}

.todo-list__text {
    display: block;
    margin-top: var(--frontend-core-space-1);
    font-size: .85rem;
    color: var(--frontend-core-color-muted);
}

.todo-list__action {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
}

/* Am Telefon rückt der Knopf unter den Satz, bündig mit dem Text —
 * das Zeichen bleibt links daneben stehen. */
@media (max-width: 640px) {
    .todo-list__item { grid-template-columns: auto minmax(0, 1fr); }
    .todo-list__action { grid-column: 2; }
    .todo-list__action .btn { width: 100%; justify-content: center; }
}

/* ---- DER ZAHLUNGSSTAND: DREI ZAHLEN ----
 *
 * Gesamt, bezahlt, offen — nebeneinander, nicht als Definitionsliste mit
 * den Einzelzahlungen dazwischen. Die Farbe steht an der ZAHL, nicht an
 * der Fläche: offen in der Farbe einer offenen Forderung, bezahlt in der
 * einer gebuchten. Am Telefon zwei plus eine. */
.amounts {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1px;
    overflow: hidden;
    border: 1px solid var(--frontend-core-color-line);
    border-radius: var(--frontend-core-radius);
    background: var(--frontend-core-color-line);
}

.amounts--single { grid-template-columns: minmax(0, 1fr); }

.amounts__cell {
    padding: var(--frontend-core-space-3) var(--frontend-core-space-4);
    background: var(--frontend-core-color-surface, #fff);
}

.amounts__label {
    display: block;
    font-size: .7rem;
    font-weight: var(--frontend-core-fw-medium);
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--frontend-core-color-muted);
}

.amounts__value {
    display: block;
    margin-top: var(--frontend-core-space-1);
    font-size: 1.1rem;
    font-weight: var(--frontend-core-fw-medium);
    font-variant-numeric: tabular-nums;
}

.amounts__note {
    display: block;
    margin-top: var(--frontend-core-space-1);
    font-size: .78rem;
    color: var(--frontend-core-color-muted);
}

.amounts__cell--open .amounts__value { color: var(--frontend-core-status-reserved, #fd7e14); }
.amounts__cell--done .amounts__value { color: var(--frontend-core-status-booked, #198754); }

@media (max-width: 640px) {
    .amounts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .amounts--single { grid-template-columns: minmax(0, 1fr); }

    /* Die dritte Zahl nimmt die ganze Zeile — sonst stünde neben ihr eine
     * leere Fläche in der Linienfarbe. */
    .amounts__cell:last-child:nth-child(odd) { grid-column: 1 / -1; }
}


/* ---- DIE UNTERLAGEN ----
 *
 * Jede Zeile ist ganz der Verweis: Auf dem Telefon trifft man eine Zeile,
 * keinen Dateinamen. Unterstrichen wird nur der Name. */
.doc-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.doc-list__item + .doc-list__item { border-top: 1px solid var(--frontend-core-color-line); }

.doc-list__link {
    display: flex;
    align-items: center;
    gap: var(--frontend-core-space-3);
    min-height: 48px;
    padding: var(--frontend-core-space-2) 0;
    color: inherit;
    text-decoration: none;
}

.doc-list__icon {
    flex: 0 0 auto;
    display: inline-flex;
    color: var(--frontend-core-color-primary);
}

.doc-list__name {
    flex: 1 1 auto;
    min-width: 0;
    font-weight: var(--frontend-core-fw-medium);
}

.doc-list__link:hover .doc-list__name {
    color: var(--frontend-core-color-primary);
    text-decoration: underline;
}

.doc-list__meta {
    flex: 0 0 auto;
    font-size: .75rem;
    color: var(--frontend-core-color-muted);
}

/* Die Buchungsdaten in der Seitenleiste: 320 Pixel reichen nicht für
 * Beschriftung UND Wert nebeneinander. Die Beschriftung steht über dem
 * Wert, wie am Telefon — in derselben Karte wie die Unterlagen darunter. */
.area-aside .booking-data__card {
    margin: 0;
    padding: var(--frontend-core-space-4);
    border: 1px solid var(--frontend-core-color-line);
    border-radius: var(--frontend-core-radius);
    background: var(--frontend-core-color-surface);
}

.area-aside .booking-data__section-title {
    margin: 2px 0 var(--frontend-core-space-3);
    font-size: 1rem;
    font-weight: var(--frontend-core-fw-medium);
}

.area-aside .booking-data__details > div {
    grid-template-columns: minmax(0, 1fr);
    row-gap: var(--frontend-core-space-1);
    padding-bottom: var(--frontend-core-space-2);
}

.area-aside .booking-data__details > div:last-child { border-bottom: 0; padding-bottom: 0; }
.area-aside .booking-data__details dt { font-size: .8rem; }
.area-aside .booking-data__details dd { text-align: left; }
.area-aside .booking-data__details dd.booking-data__period { justify-content: flex-start; }

/* DER STAND BÜNDIG ZUR TITELZEILE.
 *
 * Der Seitenkopf richtet seine Teile am unteren Rand aus — für Knöpfe
 * neben einem Titel mit Kennzahlen darunter richtig. Eine Statusmarke
 * gehört dagegen zum Titel: Unten ausgerichtet schwebte sie auf Höhe der
 * Kennzahlen rechts über der Seitenleiste. `page-head--top` setzt sie auf
 * die Höhe der Titelzeile. */
.page-head--top { align-items: flex-start; }
.page-head--top .page-head__actions { min-height: calc(1.5rem * 1.25); }

/* ============================================================
   GÄSTEPORTAL — Zahl am Aufgabenkopf, Nachlauf, Nachrichten,
   Gastdaten je Reisendem, Link für Mitreisende
   ============================================================

   Entwurf `MOCKUP-GAESTEPORTAL-ENTWURF` (B, C, F, I, P, ZIEL 4) und
   `MOCKUP-GASTDATENERFASSUNG-ENTWURF`. Gerüst wie oben. */

/* Die Zahl offener Aufgaben am Kopf von „Das ist noch offen" — im Ton
 * einer offenen Forderung, nicht einer Mahnung. */
.item-card__badge--open {
    background: color-mix(in srgb, var(--frontend-core-status-reserved, #fd7e14) 13%, var(--frontend-core-color-surface));
    color: color-mix(in srgb, var(--frontend-core-status-reserved, #fd7e14) 80%, var(--frontend-core-color-text));
}

/* Nach der Abreise ist nichts mehr offen: zwei Zahlen statt drei. Eine
 * dritte mit „0,00" wäre eine Auskunft, nach der niemand gefragt hat. */
.amounts--pair { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* Die Summenzeile des Zahlplans bleibt am Telefon EINE Zeile: „Gesamt"
 * links, der Betrag rechts — keine eigene Karte mit gestapelten Zellen. */
@media (max-width: 760px) {
    .list-table .list-table__row--total td {
        grid-row: 1;
        margin: 0;
        padding: 0;
        font-size: .875rem;
        font-weight: var(--frontend-core-fw-medium);
        color: var(--frontend-core-color-text);
        background: none;
        border: 0;
    }

    .list-table .list-table__row--total td:first-child { grid-column: 1; }
    .list-table .list-table__row--total td:last-child { grid-column: 2; text-align: right; }
}

/* ---- NACHRICHTEN: EIN VERLAUF ----
 *
 * Jede Nachricht ist ein eigener Eintrag, keine Zeile in einer Karte.
 * Die eigene steht rechts in der Hausfarbe, die des Gastgebers links —
 * die Seite sagt, wer spricht, bevor man den Namen liest. Absender, Tag
 * und Uhrzeit stehen in EINER leisen Zeile, ohne Sekunden. */
.talk {
    display: flex;
    flex-direction: column;
    gap: var(--frontend-core-space-3);
}

.talk__msg {
    max-width: 78%;
    align-self: flex-start;
    padding: var(--frontend-core-space-2) var(--frontend-core-space-3);
    border: 1px solid var(--frontend-core-color-line);
    border-radius: var(--frontend-core-radius);
    background: var(--frontend-core-color-surface-alt);
}

.talk__msg--own {
    align-self: flex-end;
    border-color: color-mix(in srgb, var(--frontend-core-color-primary, #0072ce) 30%, var(--frontend-core-color-surface));
    background: var(--frontend-core-color-soft);
}

.talk__text {
    font-size: .9rem;
    line-height: 1.5;
    overflow-wrap: anywhere;
}

.talk__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--frontend-core-space-1);
    margin-top: var(--frontend-core-space-1);
    font-size: .75rem;
    color: var(--frontend-core-color-muted);
}

.talk__read { color: var(--frontend-core-color-primary); flex: 0 0 auto; vertical-align: -3px; }

/* Das Schreibfeld: an wen die Nachricht geht, darunter das Feld. */
.talk-form .field { margin-top: var(--frontend-core-space-4); }

@media (max-width: 640px) {
    .talk__msg { max-width: 92%; }
}

/* ---- GASTDATEN: EINE KARTE JE REISENDEM ----
 *
 * Statt eines langen Formulars eine Karte je Person mit Namen und Stand
 * („vollständig", „Fehlt: Geburtsdatum"). Vollständige Karten stehen
 * zugeklappt da; gespeichert wird weiter alles mit EINEM Knopf. */
.traveler-form {
    display: flex;
    flex-direction: column;
    gap: var(--frontend-core-space-3);
}

.traveler-card {
    border: 1px solid var(--frontend-core-color-line);
    border-radius: var(--frontend-core-radius);
    background: var(--frontend-core-color-surface);
}

.traveler-card__head {
    display: flex;
    align-items: center;
    gap: var(--frontend-core-space-3);
    min-height: 56px;
    padding: var(--frontend-core-space-3) var(--frontend-core-space-4);
    list-style: none;
    cursor: pointer;
}

.traveler-card__head::-webkit-details-marker { display: none; }

.traveler-card__titles {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    min-width: 0;
}

.traveler-card__name {
    overflow: hidden;
    font-weight: var(--frontend-core-fw-medium);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.traveler-card__role {
    font-size: .8rem;
    color: var(--frontend-core-color-muted);
}

.traveler-card__head .status-label {
    flex: 0 1 auto;
    min-width: 0;
    white-space: normal;
    text-align: right;
}

.traveler-card__chevron {
    flex: 0 0 auto;
    color: var(--frontend-core-color-muted);
    transition: transform .15s ease;
}

.traveler-card[open] .traveler-card__chevron { transform: rotate(180deg); }

.traveler-card__body {
    margin: 0;
    padding: var(--frontend-core-space-4);
    border-top: 1px solid var(--frontend-core-color-line);
}

.traveler-form__actions {
    display: flex;
    flex-direction: column;
    gap: var(--frontend-core-space-2);
    margin-top: var(--frontend-core-space-1);
}

@media (min-width: 641px) {
    .traveler-form__actions { align-items: flex-start; }
    .traveler-form__actions .btn--block { width: auto; }
}

@media (max-width: 640px) {
    .traveler-card__head { flex-wrap: wrap; }
    .traveler-card__head .status-label { order: 3; flex-basis: 100%; text-align: left; }
}

/* Die übermittelten Angaben, nur zum Ansehen: Beschriftung über dem Wert. */
.traveler-facts {
    margin: var(--frontend-core-space-2) 0 0;
}

.traveler-facts__row {
    display: grid;
    grid-template-columns: minmax(0, 9em) minmax(0, 1fr);
    gap: var(--frontend-core-space-3);
    padding: var(--frontend-core-space-2) 0;
    border-top: 1px solid var(--frontend-core-color-line);
    font-size: .9rem;
}

.traveler-facts__row dt { color: var(--frontend-core-color-muted); }
.traveler-facts__row dd { margin: 0; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }

/* ---- DER LINK FÜR MITREISENDE ----
 *
 * Je mitreisender Person eine Zeile: Name, Stand, der Link zum Kopieren
 * und die beiden leisen Handlungen „neu erstellen" und „sperren". */
.companion-links {
    margin: var(--frontend-core-space-3) 0;
    padding: 0;
    list-style: none;
}

.companion-links__item {
    display: flex;
    flex-direction: column;
    gap: var(--frontend-core-space-2);
    padding: var(--frontend-core-space-3) 0;
    border-top: 1px solid var(--frontend-core-color-line);
}

.companion-links__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--frontend-core-space-3);
}

.companion-links__name { font-weight: var(--frontend-core-fw-medium); }

.companion-links__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--frontend-core-space-2);
    margin: 0;
}

/* Der Link selbst: ein Feld zum Markieren und ein Knopf daneben — am
 * Telefon tippt niemand eine Adresse ab. */
.copy-field {
    display: flex;
    gap: var(--frontend-core-space-2);
}

.copy-field__input {
    flex: 1 1 auto;
    font-variant-numeric: tabular-nums;
    text-overflow: ellipsis;
}

.copy-field .btn { flex: 0 0 auto; }

@media (max-width: 640px) {
    .copy-field { flex-direction: column; }
}

/* ============================================================
   BEWERTUNG DES AUFENTHALTS — die Seite, die der Gast nach der Abreise
   öffnet (`mwfm_review/index.html.twig`)
   ============================================================

   Entwurf `MOCKUP-GASTBEWERTUNG-ENTWURF`, Bauplan `MOCKUP-GASTBEWERTUNG`.
   Die Regeln standen in `contao-mwfm-review-bundle/public/override.css`.
   Sie stehen hier, weil der Bauplan gegen die Stylesheets des Frontends
   geprüft wird (`mockup-fidelity-lint.py --context=frontend`) und die
   Seite area.css ohnehin lädt — dieselben Regeln, an der Stelle, an der
   das Designsystem sie kennt. Die Sternfarbe ist weiter
   `--frontend-core-review-star-color` aus root.css. */

/* Nur für Hilfsmittel sichtbar. Die Punktfelder der Sterne sind ausgeblendet,
      ihre Beschriftung („3 von 5 Sternen") muss der Screenreader trotzdem
      vorlesen können. `display: none` täte das nicht. */
.review__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;
}

/* ---- DIE EINE GROSSE FRAGE ----
      Sie steht allein und mittig. Wer die Seite öffnet, soll genau eine Sache
      sehen und genau eine Sache tun; alles Weitere kommt danach. */
.review__rate {
    text-align: center;
    padding: 1.2rem 0 .6rem;
}

.review__rate-question {
    margin: 0 0 .2rem;
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--color-text);
}

.review__rate-hint {
    margin: 0 0 .9rem;
    font-size: .85rem;
    color: var(--color-muted);
}

.review__rate .review__stars-selection {
    justify-content: center;
    gap: .35rem;
}

.review__group-box {
    background: color-mix(in srgb, var(--border-color) 18%, var(--color-surface));
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius);
    padding: 0.8rem 1rem;
}

/* Überschrift "Ihre Bewertung" */
.review__group-title {
    font-size: 1.15rem;
    font-weight: 700;
    margin-bottom: .2rem;
    color: var(--color-text);
}

.review__group-hint {
    margin: 0 0 .5rem;
    font-size: .85rem;
    color: var(--color-muted);
}

/* Jede Bewertungszeile */
.review__stars {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap; /* wichtig für Mobile */
}

/* Titel links */
.review__stars-label {
    font-weight: 500;
    font-size: 1rem;
    white-space: nowrap;
}

/* Sterne rechts.

      Rückwärts gesetzt, damit „gewählt" nach LINKS wirkt: In der Baumreihenfolge
      steht der höchste Wert zuerst, `input:checked ~ label` trifft also alles mit
      kleinerer Zahl. Ohne diesen Kniff bräuchte das Einfärben ein Skript. */
.review__stars-selection {
    display: inline-flex;
    flex-direction: row-reverse;
    justify-content: flex-end;
    gap: .15rem;
}

/* Ein Stern.

      Keine `font-size` mehr: Das Zeichen ist ein Inline-SVG mit fester
      Kantenlänge, kein Schriftzeichen. Gefärbt wird über `currentColor`, die
      Füllung schaltet das CSS — dann trägt der leere Stern dieselbe Kontur wie
      der volle, und im dunklen Modus geht beides mit. */
.review__star {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 2px;
    color: color-mix(in srgb, var(--border-color) 70%, var(--color-muted));
    cursor: pointer;
    transition: color .2s ease;
    user-select: none;
}

.review__star > svg {
    display: block;
    fill: none;
}

/* HOVER: Stern + alle links daneben einfärben */
.review__star:hover,
.review__star:hover ~ .review__star {
    color: color-mix(in srgb, var(--frontend-core-review-star-color) 62%, var(--color-surface));
}

.review__star:hover > svg,
.review__star:hover ~ .review__star > svg {
    fill: currentColor;
}

/* AKTIVE Auswahl */
.review__stars-selection input[type="radio"]:checked ~ .review__star {
    color: var(--frontend-core-review-star-color);
}

.review__stars-selection input[type="radio"]:checked ~ .review__star > svg {
    fill: currentColor;
}

/* Das Punktfeld erreicht die Tastatur weiterhin. Sichtbar ist es nicht, also
      bekommt es seinen Fokusring über den zugehörigen Stern — ohne diese Regel
      ließe sich die Seite mit der Tastatur bedienen, ohne zu sehen, wo man ist. */
.review__stars-selection input[type="radio"]:focus-visible + .review__star {
    outline: 2px solid var(--color-primary, currentColor);
    outline-offset: 2px;
    border-radius: 4px;
}

/* ---- DIE NAMENSFORM ---- */
.review__namepick {
    display: grid;
    gap: .4rem;
}

.review__namepick-option {
    display: flex;
    align-items: flex-start;
    gap: .6rem;
    padding: .6rem .8rem;
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius);
    background: var(--color-surface);
    cursor: pointer;
}

.review__namepick-option:has(input:checked) {
    border-color: var(--frontend-core-review-star-color);
    background: color-mix(in srgb, var(--frontend-core-review-star-color) 10%, var(--color-surface));
}

.review__namepick-body {
    display: grid;
    gap: .1rem;
}

.review__namepick-name {
    font-weight: 500;
}

.review__namepick-sub {
    font-size: .85rem;
    color: var(--color-muted);
}

/* Die wörtliche Vorschau. Sie steht bewusst abgesetzt unter der Wahl: Kein
      Gast soll raten müssen, was von ihm öffentlich wird. */
.review__byline {
    margin-top: .6rem;
    padding: .6rem .8rem;
    border: 1px dashed var(--border-color);
    border-radius: var(--border-radius);
}

.review__byline-label {
    font-size: .8rem;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--color-muted);
}

.review__byline-value {
    font-weight: 500;
}

.review__consent {
    font-size: .85rem;
    color: var(--color-muted);
    margin: .4rem 0 .2rem;
}

.review__help {
    margin: .2rem 0 0;
    font-size: .85rem;
    color: var(--color-muted);
}

.review__optional {
    font-size: .8rem;
    font-weight: 400;
    color: var(--color-muted);
}

/* --- Mobile Optimierung --- */
@media (max-width: 480px) {
    .review__stars {
        flex-direction: column;
        align-items: flex-start;
        gap: .3rem;
    }

    .review__stars-selection {
        margin-top: .1rem;
    }
}

/* Die beiden Spalten des Formulars (Name und Ort) — am Telefon eine. */
.review__grid {
    display: grid;
    gap: 1rem;
    grid-template-columns: 1fr 1fr;
}

.review__field {
    display: grid;
    gap: .3rem;
}

@media (max-width: 640px) {
    .review__grid {
        grid-template-columns: 1fr;
    }
}


/* ============================================================
   OBJEKTSEITE DETAIL
   ============================================================

   Die Buchungsbox der Unterkunftsseite wird auf dem Telefon (bis 760px)
   zum Blatt: Unten steht eine feste Leiste mit dem „ab"-Preis und einem
   Knopf, ein Tipp öffnet die Box als Blatt über der Seite. Ohne Skript
   bleibt die Box, wo sie ist — die Klassen `is-sheet` und `is-open` setzt
   erst das Skript der Vorlage `reader/booking_form.html.twig`.

   Das Blatt (z-index 800 bis 860) liegt unter der Bildergalerie (1000 bis
   1100) und unter dem Fenster des Wählers (9998/9999): Beide öffnen sich
   also immer darüber, auch aus dem Blatt heraus. */

.booking-bar,
.booking-sheet__scrim,
.booking-sheet__close {
    display: none;
}

.accommodation-detail__gallery-counter {
    position: fixed;
    top: var(--frontend-core-space-3);
    left: var(--frontend-core-space-4);
    z-index: 1100;
    display: flex;
    align-items: center;
    min-height: 3rem;
    color: #fff;
    font-size: .9375rem;
    font-variant-numeric: tabular-nums;
}

@media (max-width: 760px) {
    body.booking-sheet-lock { overflow: hidden; }

    body:has(.booking-bar:not([hidden])) { padding-bottom: 88px; }

    .booking-bar:not([hidden]) {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 800;
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--frontend-core-space-3);
        padding: var(--frontend-core-space-3) var(--frontend-core-space-4) calc(var(--frontend-core-space-4) + env(safe-area-inset-bottom, 0px));
        border-top: 1px solid var(--frontend-core-color-line);
        background: var(--frontend-core-color-surface, #fff);
        box-shadow: 0 -4px 16px rgba(15, 23, 42, .1);
    }

    .booking-bar__price {
        min-width: 0;
        font-weight: var(--frontend-core-fw-medium);
    }

    .booking-bar__open {
        flex: none;
        min-height: 44px;
    }

    .booking-sheet__scrim:not([hidden]) {
        position: fixed;
        inset: 0;
        z-index: 850;
        display: block;
        background: var(--frontend-core-scrim);
    }

    .accommodation-detail__booking-box.is-sheet { display: none; }

    .accommodation-detail__booking-box.is-sheet.is-open {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 860;
        display: grid;
        max-height: 94%;
        margin: 0;
        overflow-y: auto;
        border-radius: 20px 20px 0 0;
        box-shadow: 0 -12px 40px rgba(15, 23, 42, .2);
        padding-bottom: calc(var(--frontend-core-space-5) + env(safe-area-inset-bottom, 0px));
    }

    .accommodation-detail__booking-box.is-sheet .accommodation-detail__booking-box-header {
        display: flex;
        flex-direction: row;
        align-items: center;
        gap: var(--frontend-core-space-3);
    }

    .accommodation-detail__booking-box.is-sheet .accommodation-detail__booking-box-header .accommodation-detail__booking-box-title {
        display: block;
        flex: 1 1 auto;
        margin: 0;
        font-weight: var(--frontend-core-fw-medium);
    }

    .accommodation-detail__booking-box.is-sheet .booking-sheet__close {
        display: inline-flex;
        flex: none;
        margin-left: auto;
        width: 44px;
        height: 44px;
        align-items: center;
        justify-content: center;
        border: 1px solid var(--frontend-core-color-line-strong);
        border-radius: var(--frontend-core-radius-pill);
        background: var(--frontend-core-color-surface, #fff);
        color: inherit;
        cursor: pointer;
    }

    .accommodation-detail__booking-box.is-sheet .booking-sheet__close:focus-visible,
    .booking-bar__open:focus-visible {
        outline: 2px solid var(--frontend-core-color-primary, #0072ce);
        outline-offset: 2px;
    }
}

.accommodation-detail__description-content.is-clamped {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 4;
    line-clamp: 4;
    overflow: hidden;
}

.accommodation-detail__description-toggle {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0;
    border: 0;
    background: none;
    color: var(--frontend-core-color-primary, #0072ce);
    font: inherit;
    font-weight: var(--frontend-core-fw-medium);
    cursor: pointer;
}

.accommodation-detail__description-toggle[hidden] { display: none; }

/* Vorschlag „nächster freier Zeitraum" unter dem Zeitraumfeld. Der Knopf
   steht nur, wenn der Server einen Zeitraum gleicher Länge gefunden hat;
   er nennt nie, warum der gewählte nicht geht. */
.accommodation__suggest { margin-top: var(--frontend-core-space-3); }
.accommodation__suggest[hidden] { display: none; }

.accommodation__suggest .accommodation__suggest-button {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--frontend-core-space-3);
    width: 100%;
    min-height: 48px;
    padding: 0 var(--frontend-core-space-4);
    border: 1px solid var(--frontend-core-color-primary, #0072ce);
    border-radius: 10px;
    background: var(--frontend-core-color-soft);
    color: var(--frontend-core-color-primary, #0072ce);
    font: inherit;
    font-size: .9375rem;
    font-weight: var(--frontend-core-fw-medium);
    text-align: left;
    cursor: pointer;
}

.accommodation__suggest .accommodation__suggest-button:focus-visible {
    outline: 2px solid var(--frontend-core-color-primary, #0072ce);
    outline-offset: 2px;
}

.booking-form__note {
    margin: var(--frontend-core-space-3) 0 0;
    color: var(--frontend-core-color-muted, #6b7280);
    font-size: .8125rem;
    text-align: center;
}

.booking-sheet__grip { display: none; }

.booking-bar__info {
    display: grid;
    min-width: 0;
    line-height: 1.25;
}

.booking-bar__summary {
    color: var(--frontend-core-color-muted, #6b7280);
    font-size: .8125rem;
    font-weight: 400;
}

.booking-bar__summary:empty { display: none; }

@media (max-width: 760px) {
    .accommodation-detail__booking-box.is-sheet.is-open .booking-sheet__grip {
        display: block;
        width: 40px;
        height: 4px;
        margin: 0 auto var(--frontend-core-space-3);
        border-radius: 4px;
        background: var(--frontend-core-color-line-strong);
    }
}

/* Preise und Saisonzeiten */
.accommodation-detail__prices { margin-top: var(--frontend-core-space-5); }

.accommodation-detail__prices-scroll { overflow-x: auto; }

.accommodation-detail__prices-table {
    width: 100%;
    border-collapse: collapse;
    font-size: .9375rem;
}

.accommodation-detail__prices-table th,
.accommodation-detail__prices-table td {
    padding: var(--frontend-core-space-3);
    border-bottom: 1px solid var(--frontend-core-color-line);
    text-align: left;
    vertical-align: top;
}

.accommodation-detail__prices-table th {
    color: var(--frontend-core-color-muted, #6b7280);
    font-size: .75rem;
    font-weight: var(--frontend-core-fw-medium);
    letter-spacing: .05em;
    text-transform: uppercase;
}

.accommodation-detail__prices-table .accommodation-detail__prices-num {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Ähnliche Unterkünfte: dieselbe Karte wie in der Objektliste */
.accommodation-detail__similar { margin-top: var(--frontend-core-space-5); }

.accommodation-detail__similar-title { margin: 0 0 var(--frontend-core-space-4); }

/* Gestaltung der Objektseite aus dem Entwurf MOCKUP-FRONTEND-DETAIL-ENTWURF.html,
   unter den Namen, die die Vorlagen der Objektseite wirklich tragen
   (`objecthead__*`, `facts-strip__*`, `accommodation-detail__*`).

   Die Grundabstände und -größen stehen in `:where()` und haben damit die
   Spezifität null: Das Theme einer Instanz, das danach lädt, gewinnt immer.
   Die `<style>`-Blöcke der Vorlagen (Galerie, Ausstattung, Buchungsbox,
   Bewertungen, Grundriss) tragen eigene Regeln und überstimmen diese hier,
   wo sie dieselbe Eigenschaft setzen. Nur die Größen der Zeichen stehen mit
   Typ-Selektor (Spezifität 0,1,1), weil die Zeichen der Vorlagen keine
   Klasse tragen und sonst ohne Maß blieben. Die Überschriften stehen mit
   einer Klasse (0,1,0), weil sonst die Regel `h1`/`h2` des Themes gewinnt. */

:where(.objecthead) { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--frontend-core-space-4); }
:where(.objecthead__location) { display: flex; flex-wrap: wrap; gap: var(--frontend-core-space-2); margin: 0; font-size: 13px; color: var(--frontend-core-color-muted, #6b7280); }
.objecthead__title { margin: 0; font-size: 28px; line-height: 1.2; font-weight: var(--frontend-core-fw-medium); }
:where(.objecthead__meta) { display: flex; flex-wrap: wrap; align-items: center; gap: var(--frontend-core-space-1) var(--frontend-core-space-4); margin-top: var(--frontend-core-space-2); font-size: 14px; color: var(--frontend-core-color-muted, #6b7280); }
:where(.objecthead__meta > span) { display: inline-flex; align-items: center; gap: 4px; }
:where(.objecthead__rating) { display: inline-flex; align-items: center; gap: 4px; font-weight: var(--frontend-core-fw-medium); color: var(--frontend-core-color-text); }
:where(.objecthead__actions) { display: flex; gap: var(--frontend-core-space-2); }
@media (max-width: 640px) { :where(.objecthead) { flex-direction: column; } }
.objecthead svg { width: 16px; height: 16px; flex: none; }
.objecthead__rating svg { width: 16px; height: 16px; color: #c98a00; }

:where(.facts-strip) { display: flex; flex-wrap: wrap; gap: var(--frontend-core-space-2) var(--frontend-core-space-5); padding-bottom: var(--frontend-core-space-5); border-bottom: 1px solid var(--frontend-core-color-line); }
:where(.facts-strip__item) { display: flex; align-items: center; gap: var(--frontend-core-space-2); min-height: 44px; font-size: 15px; }
.facts-strip svg { width: 20px; height: 20px; flex: none; color: var(--frontend-core-color-primary, #0072ce); }

:where(.accommodation-detail__section, .accommodation-detail__description, .accommodation-detail__distances, .accommodation-detail__map, .accommodation-detail__reviews, .accommodation-detail__ground-plan, .accommodation-detail__prices, .accommodation-detail__similar) { display: grid; gap: var(--frontend-core-space-3); }
.accommodation-detail__section-title,
.accommodation-detail__description-title,
.accommodation-detail__amenities-title,
.accommodation-detail__distances-title,
.accommodation-detail__map-title,
.accommodation-detail__prices-title,
.accommodation-detail__similar-title { margin: 0; font-size: 20px; font-weight: var(--frontend-core-fw-medium); }

:where(.accommodation-detail__description-content) { margin: 0; font-size: 16px; line-height: 1.6; }
:where(.accommodation-detail__description-toggle) { justify-self: start; font-size: 15px; }

:where(.accommodation-detail__amenities) { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: var(--frontend-core-space-5) var(--frontend-core-space-4); }
:where(.accommodation-detail__amenities-title) { grid-column: 1 / -1; }
:where(.accommodation-detail__amenities-category) { display: grid; gap: var(--frontend-core-space-1); align-content: start; }
:where(.accommodation-detail__amenities-category-title) { margin-bottom: var(--frontend-core-space-1); font-size: 12px; font-weight: var(--frontend-core-fw-medium); letter-spacing: .05em; text-transform: uppercase; color: var(--frontend-core-color-muted, #6b7280); }
:where(.accommodation-detail__amenities-item) { display: flex; align-items: center; gap: var(--frontend-core-space-3); min-height: 32px; font-size: 15px; }
.accommodation-detail__amenities-item svg { width: 20px; height: 20px; flex: none; color: var(--frontend-core-color-primary, #0072ce); }

:where(.accommodation-detail__booking-box) { display: grid; gap: var(--frontend-core-space-4); padding: var(--frontend-core-space-5); border: 1px solid var(--frontend-core-color-line); border-radius: var(--frontend-core-radius); background: var(--frontend-core-color-surface, #fff); box-shadow: 0 6px 24px rgba(15, 23, 42, .1); }
:where(.accommodation-detail__booking-box-picker) { display: grid; gap: var(--frontend-core-space-3); }
:where(.accommodation-detail__booking-box-from-price) { display: flex; align-items: baseline; gap: var(--frontend-core-space-2); font-size: 14px; color: var(--frontend-core-color-muted, #6b7280); }
:where(.accommodation-detail__booking-box-from-price strong) { font-size: 24px; font-weight: var(--frontend-core-fw-medium); color: var(--frontend-core-color-text); }
:where(.accommodation__message) { display: flex; gap: var(--frontend-core-space-2); align-items: flex-start; font-size: 14px; line-height: 1.4; color: var(--frontend-core-color-danger); }
.accommodation__message svg { flex: none; width: 1.15em; height: 1.15em; margin-top: 1px; }
.accommodation-detail__similar-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--frontend-core-space-4); }

/* ============================================================
   ZUSATZFRAGE BEI WENIGEN STERNEN (Gästebewertung)

   Bei zwei Sternen oder weniger klappt EINE freiwillige Frage auf. Die
   Bewertung wird dadurch nicht umgeleitet und nicht gefiltert: Der Knopf
   heißt weiter gleich, und wer nichts ergänzen möchte, sendet sofort.
   Die Warnfarbe trägt nur der Rahmen — der Gast hat nichts falsch
   gemacht, und eine rote Fläche wäre ein Vorwurf.
   ============================================================ */
.followup {
    margin-top: var(--frontend-core-space-3);
    padding: var(--frontend-core-space-3);
    border: 1px solid color-mix(in srgb, var(--frontend-core-color-warning) 45%, transparent);
    border-radius: var(--frontend-core-radius);
    background: var(--frontend-core-color-surface);
}

.followup[hidden] { display: none; }

.followup__title {
    margin: 0 0 var(--frontend-core-space-1);
    font-weight: var(--frontend-core-fw-medium);
    color: var(--frontend-core-color-text);
}

.followup__text {
    margin: 0 0 var(--frontend-core-space-3);
    font-size: .9rem;
    line-height: 1.45;
    color: var(--frontend-core-color-muted);
}

.check {
    display: flex;
    gap: var(--frontend-core-space-2);
    align-items: flex-start;
    min-height: 44px;
    padding-top: var(--frontend-core-space-2);
    line-height: 1.4;
    cursor: pointer;
}

.check > input[type="checkbox"] {
    flex: 0 0 auto;
    margin-top: .2em;
}

/* ============================================================
   ZAHLUNGSSEITE — was, wie, wohin auf einer Seite
   ============================================================

   Freigegebener Entwurf `MOCKUP-ZAHLUNGSSEITE-ENTWURF.html` (Z1 bis Z16),
   gebaut in payment 5.5.0. Vorlage: `mwfm_payment/index.html.twig`, der
   Abschnitt Zahlung des Gästeportals.

   Am Telefon steht alles untereinander: die Rate, der Weg, dann die
   Bankverbindung oder der Knopf zum Zahlungsdienst. Am Rechner links was
   und wie, rechts wohin — beides gleichzeitig sichtbar zu haben ist der
   einzige Vorteil der Breite; es kommt nichts dazu, was es schmal nicht
   gibt.

   WÄHLEN HEISST, EINEM LINK ZU FOLGEN. Jede Zeile der Auswahl ist ein
   Verweis mit der neuen Auswahl in der Adresse; die Seite braucht dafür kein
   Skript. Gewählt ist, was `aria-current` trägt. */

.pay-page {
    display: grid;
    gap: var(--frontend-core-space-4);
    align-items: start;
}

.pay-page__col {
    display: grid;
    gap: var(--frontend-core-space-4);
    min-width: 0;
}

@media (min-width: 900px) {
    .pay-page--split { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.pay-page .item-card__top { margin-bottom: var(--frontend-core-space-3); }
.pay-page .item-card__text + .pay-bank { margin-top: var(--frontend-core-space-3); }

.pay-choices {
    display: grid;
    gap: var(--frontend-core-space-2);
    margin: 0;
    padding: 0;
    list-style: none;
}

/* Die Zeile, die man wählt. Der Punkt links zeigt, ob sie gewählt ist; der
   Rahmen in der Hausfarbe zeigt es noch einmal für den, der den Punkt
   übersieht. Mindestens 44 Pixel hoch: eine Fingerkuppe. */
.pay-choice {
    display: flex;
    align-items: flex-start;
    gap: var(--frontend-core-space-3);
    min-height: 44px;
    padding: var(--frontend-core-space-3);
    border: 1px solid var(--frontend-core-color-line-strong);
    border-radius: var(--frontend-core-radius-sm);
    background: var(--frontend-core-color-surface);
    color: var(--frontend-core-color-text);
    text-decoration: none;
}

a.pay-choice:hover {
    color: var(--frontend-core-color-text);
    text-decoration: none;
}

a.pay-choice:not(.is-on):hover { border-color: var(--frontend-core-color-muted); }

a.pay-choice:focus-visible {
    outline: 2px solid var(--frontend-core-color-primary);
    outline-offset: 2px;
}

.pay-choice.is-on {
    border-color: var(--frontend-core-color-primary);
    background: var(--frontend-core-color-soft);
}

.pay-choice__mark {
    flex: 0 0 18px;
    width: 18px;
    height: 18px;
    margin-top: 1px;
    border: 1.5px solid var(--frontend-core-color-line-strong);
    border-radius: 50%;
    background: var(--frontend-core-color-surface);
}

.pay-choice.is-on .pay-choice__mark {
    border-color: var(--frontend-core-color-primary);
    box-shadow: inset 0 0 0 3px var(--frontend-core-color-surface);
    background: var(--frontend-core-color-primary);
}

/* GIBT ES NUR EINE MÖGLICHKEIT, STEHT SIE ALS SATZ DA — ohne Punkt und
   ohne Rahmen, denn es gibt nichts zu wählen. Dasselbe gilt für eine Rate,
   die schon bezahlt ist: Sie steht da, damit niemand fragt, ob die
   Anzahlung angekommen ist, und tritt zurück. */
.pay-choice--static {
    min-height: 0;
    padding: var(--frontend-core-space-1) 0;
    border-color: transparent;
    background: transparent;
}

.pay-choice--done { color: var(--frontend-core-color-muted); }

.pay-choice__body {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    gap: var(--frontend-core-space-1);
    min-width: 0;
}

.pay-choice__title { font-weight: var(--frontend-core-fw-medium); }

.pay-choice__sub {
    font-size: .85rem;
    color: var(--frontend-core-color-muted);
}

/* Der Betrag rechts in der Zeile: Wer zwischen Anzahlung und Restzahlung
   wählt, vergleicht Beträge — sie gehören untereinander auf eine Kante. */
.pay-choice__amount {
    flex: 0 0 auto;
    font-weight: var(--frontend-core-fw-medium);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.pay-choice--done .pay-choice__amount { font-weight: 400; }

.pay-choice__logos {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--frontend-core-space-2);
    margin-top: var(--frontend-core-space-1);
}

.pay-choice__logos img {
    display: block;
    width: auto;
    height: 20px;
}

/* Die Bankverbindung: Zeilen aus `factline` (`default.css`), ohne den
   Rahmen der `factlist` — sie steht schon in einer Karte. Der Behälter
   trägt denselben Containernamen, damit die Zeilen auf schmalem Platz
   Beschriftung und Wert untereinander stellen wie dort. */
.pay-bank { container: factlist / inline-size; }

/* „Verwendungszweck" ist breiter als die 8,5em der `factline`; die Werte
   stünden sonst in dieser einen Zeile weiter rechts als in den anderen. */
.pay-bank .factline__key { flex-basis: 10em; }

/* IBAN und Verwendungszweck tippt am Telefon niemand fehlerfrei ab. Ein
   Tipp oder Klick auf den Wert markiert ihn ganz, das Kopieren bleibt beim
   Gerät — ohne Skript. */
.pay-copy {
    -webkit-user-select: all;
    user-select: all;
    overflow-wrap: anywhere;
    font-variant-numeric: tabular-nums;
}

.pay-page .factline__val .pay-amount {
    font-weight: var(--frontend-core-fw-medium);
    font-variant-numeric: tabular-nums;
}

.pay-page .hint { margin: var(--frontend-core-space-3) 0 0; }

/* Der GiroCode. Der QR-Code steht immer auf Weiß, auch wenn die Seite
   getönt ist: Banking-Apps lesen dunkle Punkte auf hellem Grund. */
.pay-giro {
    display: flex;
    align-items: center;
    gap: var(--frontend-core-space-4);
    margin-top: var(--frontend-core-space-4);
    padding: var(--frontend-core-space-3);
    border: 1px solid var(--frontend-core-color-line);
    border-radius: var(--frontend-core-radius-sm);
    background: var(--frontend-core-color-surface-alt);
}

.pay-giro__img {
    flex: 0 0 132px;
    width: 132px;
    height: 132px;
    padding: var(--frontend-core-space-1);
    border: 1px solid var(--frontend-core-color-line);
    border-radius: var(--frontend-core-radius-sm);
    background: #fff;
}

.pay-giro__body { min-width: 0; }

.pay-giro__title {
    margin: 0;
    font-weight: var(--frontend-core-fw-medium);
}

.pay-giro__text {
    margin: var(--frontend-core-space-1) 0 0;
    font-size: .85rem;
    color: var(--frontend-core-color-muted);
}

.pay-page .item-card__actions .btn { justify-content: center; }
.pay-page .empty__text + .btn { margin-top: var(--frontend-core-space-4); }

@media (max-width: 640px) {
    .pay-giro { flex-direction: column; align-items: flex-start; }
}

/* =========================================================
   MW FewoManager – Theme (Modern Coastal, Mobile First)
   Marken-Palette aus Logo: Blau #3D5A92 / Gold #E89F3C
   Author: Küstenweb GmbH
   Mobile-first: Defaults für schmale Viewports, mit
   min-width Media-Queries auf größere Geräte hochgeschaltet.
   ========================================================= */

/* ---------- Design Tokens ---------- */
:root {
  --c-primary:        #3D5A92;
  --c-primary-700:    #2F487A;
  --c-primary-50:     #EDF1F8;
  --c-accent:         #E89F3C;
  --c-accent-600:     #D08A28;
  --c-accent-50:      #FCF1DF;

  --c-sea:            #5BA8B8;
  --c-sand:           #F6EFE0;
  --c-foam:           #FBF8F2;

  --c-text:           #1F2937;
  --c-text-muted:     #5B6779;
  --c-line:           #E4E7EE;
  --c-bg:             #FFFFFF;
  --c-bg-alt:         #F8FAFC;
  --c-success:        #2E9E6A;
  --c-danger:         #D24B4B;

  --ff-sans: "Inter", "Segoe UI", system-ui, -apple-system, Arial, sans-serif;
  --ff-display: "Plus Jakarta Sans", "Inter", "Segoe UI", system-ui, sans-serif;

  --fs-xs: 0.8125rem;
  --fs-sm: 0.9375rem;
  --fs-base: 1rem;
  --fs-md: 1.0625rem;
  --fs-lg: 1.25rem;
  --fs-xl: 1.625rem;
  --fs-2xl: 2.125rem;
  --fs-3xl: 2.75rem;

  --sp-1: 0.25rem;
  --sp-2: 0.5rem;
  --sp-3: 0.75rem;
  --sp-4: 1rem;
  --sp-5: 1.25rem;
  --sp-6: 1.5rem;
  --sp-8: 2rem;
  --sp-10: 2.5rem;
  --sp-12: 3rem;
  --sp-16: 4rem;
  --sp-20: 5rem;
  --sp-24: 6rem;

  --r-sm: 6px;
  --r-md: 12px;
  --r-lg: 18px;
  --r-xl: 28px;
  --r-pill: 999px;

  --shadow-sm: 0 1px 2px rgba(31,41,55,.06), 0 1px 3px rgba(31,41,55,.05);
  --shadow-md: 0 6px 14px rgba(31,41,55,.08), 0 2px 4px rgba(31,41,55,.05);
  --shadow-lg: 0 18px 40px rgba(31,41,55,.12), 0 4px 12px rgba(31,41,55,.06);

  --container: 1200px;
  --container-narrow: 880px;

  --header-h: 72px;
  --transition: 200ms cubic-bezier(.2,.7,.3,1);
}

/* ---------- Token-Brücke: MWFM-Bundle → Theme ----------
   Bildet die zentralen Bundle-Tokens (root.css des Frontend-Bundles) auf die
   Theme-Palette oben ab. Dadurch übernehmen ALLE Bundle-Komponenten
   (Karten, Pagination, Buttons, Detail-Bewertungen, "Das sagen unsere Gäste" …)
   automatisch das Theme – ohne dass einzelne Klassen überschrieben werden.
   --shadow-sm/md/lg, --container und --transition heißen in beiden Welten
   gleich und müssen daher NICHT gemappt werden. */
:root {
  /* Farben */
  --color-primary:        var(--c-primary);
  --color-primary-hover:  var(--c-primary-700);
  --color-secondary:      var(--c-text-muted);
  --color-secondary-hover: var(--c-text);
  --color-accent:         var(--c-accent);
  --color-accent-hover:   var(--c-accent-600);
  --color-bg:             var(--c-bg);
  --color-surface:        var(--c-bg);
  --color-surface-alt:    var(--c-bg-alt);
  --color-text:           var(--c-text);
  --color-muted:          var(--c-text-muted);
  --color-text-muted:     var(--c-text-muted);
  --border-color:         var(--c-line);
  --color-border:         var(--c-line);
  --color-success:        var(--c-success);
  --color-danger:         var(--c-danger);

  /* CTA-Buttons in allen Frontend-Bundles auf den Akzent-Orange umleiten,
     damit Buchung/Reinigungsliste/Owner-Login/Review/Payment + die Date-/
     Personpicker-Apply-Buttons denselben orangefarbenen Look bekommen wie
     die Theme-eigenen .btn--primary-Buttons.
     WICHTIG: !important ist hier kein Stilfehler, sondern Cascade-Pflicht.
     Im Buchungsstrecken-Standalone laedt der CssCombinerService das Booking-
     Bundle-root.css NACH dem Theme; es wuerde --booking-color-primary sonst
     auf var(--color-primary) zuruecksetzen. Mit !important auf den Variablen
     gewinnt das Theme unabhaengig von der Ladereihenfolge. */

  /* Booking-Bundle-Tokens */
  --booking-color-primary:        var(--c-accent) !important;
  --booking-color-primary-hover:  var(--c-accent-600) !important;

  /* Frontend-Core-Bundle-Tokens (Owner-Login, Cleaning-List, Guest-Booking,
     Review, Payment greifen alle auf --frontend-core-color-primary zurueck -
     z. B. fuer .message__button "Zur Startseite"). */
  --frontend-core-color-primary:       var(--c-accent) !important;
  --frontend-core-color-primary-hover: var(--c-accent-600) !important;
}

/* Belt-and-suspenders: ein paar konkrete Buttons direkt forcen, damit
   sie unabhaengig von der Token-Cascade orange werden. Das ist noetig, weil
   das frontend-core-bundle/root.css NACH dem Theme laedt und ohne explizites
   !important auf den Variablen die Buttons sonst die Bundle-Defaults zeigen. */
.login__button {
  background: var(--c-accent) !important;
  color: #fff !important;
  border-color: var(--c-accent) !important;
}
.login__button:hover {
  background: var(--c-accent-600) !important;
  color: #fff !important;
  border-color: var(--c-accent-600) !important;
}
.message__button {
  background: var(--c-accent) !important;
  color: #fff !important;
}
.message__button:hover {
  background: var(--c-accent-600) !important;
  color: #fff !important;
}

/* ============================================================
   UNIVERSAL-CTA-BUTTONS – einheitlicher Orange-Look fuer alle
   Aktions-/Anwenden-/Buchen-/Submit-Varianten der Suite.
   Bewusst hoch-spezifisch + !important, weil die einzelnen
   Bundles (api, booking, owner-login, frontend-core) jeweils
   eigene Selektoren mit unterschiedlicher Spezifitaet bringen.
   ============================================================ */
.btn--primary,
.btn--apply,
.btn--book,
.btn--book-now,
.calendar__btn--apply,
.personpicker__btn--apply,
button[name="apply"],
button[name="submit"].btn:not(.btn--secondary):not(.btn--cancel):not(.btn--clear):not(.btn--danger):not(.btn--ghost),
:is(a, button, input[type="submit"]).btn--primary,
:is(a, button, input[type="submit"]).btn--apply,
:is(a, button, input[type="submit"]).btn--book {
  background: var(--c-accent) !important;
  color: #ffffff !important;
  border-color: var(--c-accent) !important;
}
.btn--primary:hover,
.btn--apply:hover,
.btn--book:hover,
.btn--book-now:hover,
.calendar__btn--apply:hover,
.personpicker__btn--apply:hover,
button[name="apply"]:hover,
button[name="submit"].btn:not(.btn--secondary):not(.btn--cancel):not(.btn--clear):not(.btn--danger):not(.btn--ghost):hover,
:is(a, button, input[type="submit"]).btn--primary:hover,
:is(a, button, input[type="submit"]).btn--apply:hover,
:is(a, button, input[type="submit"]).btn--book:hover {
  background: var(--c-accent-600) !important;
  color: #ffffff !important;
  border-color: var(--c-accent-600) !important;
}

/* Sekundaere Buttons (.btn--secondary) bekommen den prominenten Outline-
   Look der Startseiten-Hero-CTA: dicker Primary-Border, Primary-Text,
   Pill-Shape, weisser Hintergrund. Cancel/Clear/Ghost bleiben unauffaellig
   (schmaler Border, Body-Text), Danger bleibt rot. */
.btn--secondary,
:is(a, button, input[type="submit"]).btn--secondary {
  background: #ffffff !important;
  color: var(--c-primary) !important;
  border: 2px solid var(--c-primary) !important;
  border-radius: 999px !important;
  font-weight: 700 !important;
}
.btn--secondary:hover,
:is(a, button, input[type="submit"]).btn--secondary:hover {
  background: var(--c-primary) !important;
  color: #ffffff !important;
  border-color: var(--c-primary) !important;
}

.btn--cancel,
.btn--clear,
.btn--ghost,
:is(a, button, input[type="submit"]).btn--cancel,
:is(a, button, input[type="submit"]).btn--clear,
:is(a, button, input[type="submit"]).btn--ghost {
  background: #ffffff !important;
  color: var(--c-text) !important;
  border: 1px solid var(--c-line) !important;
}
/* Datepicker-Footer „Zurücksetzen" ist ein Ghost-Link (datepicker.css), KEINE
   weiße Box — die generische .btn--clear-Box-Regel hier kontextspezifisch
   zurücknehmen (sonst sitzt der Text bei padding:0 an der Border). */
.calendar-modal__footer .btn.btn--clear,
.calendar-modal__footer .btn.btn--clear.btn--ghost {
  background: transparent !important;
  border-color: transparent !important;
}
.btn--danger,
:is(a, button, input[type="submit"]).btn--danger {
  background: var(--c-danger) !important;
  color: #ffffff !important;
  border-color: var(--c-danger) !important;
}

/* ============================================================
   LOGIN-LOGO – stellt sicher, dass das Logo immer sichtbar ist
   und die Layout-Struktur nicht zerlegt, falls externe CSS-
   Regeln img mit max-width:0/0 height ueberschreiben.
   ============================================================ */
.login__logo {
  display: flex !important;
  justify-content: center !important;
  align-items: center !important;
  min-height: 80px !important;
  margin-bottom: 1rem;
}
.login__logo a { display: inline-flex; }
.login__logo img {
  display: block !important;
  max-width: 220px !important;
  width: auto !important;
  height: 80px !important;
  object-fit: contain !important;
  margin: 0 !important;
}

/* Security-Note (z. B. SSL-Hinweis "Sichere Verbindung" im Owner-Login)
   soll bewusst BLAU bleiben - sie ist kein Aktionselement, sondern ein
   Trust-Marker. Box-Background, Border, Text und Icon werden komplett auf
   --c-primary umgezogen, sonst sind sie aus dem orange Accent-Mix gefaerbt. */
.security-note {
  background: color-mix(in srgb, var(--c-primary) 6%, #ffffff) !important;
  border-color: color-mix(in srgb, var(--c-primary) 18%, var(--c-line)) !important;
  color: color-mix(in srgb, var(--c-primary) 35%, var(--c-text)) !important;
}
.security-note__icon { color: var(--c-primary) !important; }
.security-note a,
.security-note__link { color: var(--c-primary) !important; }
:root {
  /* Marker, damit das oeffnende :root unten wieder schliessend bleibt –
     keine zusaetzlichen Werte hier. */

  /* Skeleton-Button-Tokens (Primary) */
  --btn-primary-bg:               var(--c-accent) !important;
  --btn-primary-bg-hover:         var(--c-accent-600) !important;
  --btn-primary-border:           var(--c-accent) !important;
  --btn-primary-text:             #ffffff !important;
  --btn-primary-text-hover:       #ffffff !important;

  /* Skeleton-Button-Tokens (Apply = z. B. Filter anwenden, Datepicker
     "Übernehmen", Personpicker "Übernehmen") */
  --btn-apply-bg:                 var(--c-accent) !important;
  --btn-apply-bg-hover:           var(--c-accent-600) !important;
  --btn-apply-border:             var(--c-accent) !important;
  --btn-apply-text:               #ffffff !important;

  /* Skeleton-Button-Tokens (Book = .btn--book auf Karten/Detail) */
  --btn-book-bg:                  var(--c-accent) !important;
  --btn-book-bg-hover:            var(--c-accent-600) !important;
  --btn-book-border:              var(--c-accent) !important;
  --btn-book-text:                #ffffff !important;

  /* Radius */
  --border-radius:        var(--r-sm);
  --radius-sm:            var(--r-sm);
  --radius-md:            var(--r-md);
  --radius-lg:            var(--r-lg);
  --radius-card:          var(--r-lg);
  --radius-pill:          var(--r-pill);

  /* Schatten-Sonderfall (Bundle: --shadow-card) */
  --shadow-card:          var(--shadow-md);

  /* Abstände */
  --space-1:  var(--sp-1);
  --space-2:  var(--sp-2);
  --space-3:  var(--sp-3);
  --space-4:  var(--sp-4);
  --space-5:  var(--sp-5);
  --space-6:  var(--sp-6);
  --space-8:  var(--sp-8);
  --space-10: var(--sp-10);
  --space-12: var(--sp-12);
  --space-16: var(--sp-16);
  --space-20: var(--sp-20);
  --space-24: var(--sp-24);

  /* Schriftgrößen */
  --font-size-xs:  var(--fs-xs);
  --font-size-sm:  var(--fs-sm);
  --font-size-base: var(--fs-base);
  --font-size-md:  var(--fs-md);
  --font-size-lg:  var(--fs-lg);
  --font-size-xl:  var(--fs-xl);
  --font-size-2xl: var(--fs-2xl);
  --font-size-3xl: var(--fs-3xl);

  /* Schrift-Familien */
  --font-family-sans-serif: var(--ff-sans);
  --font-family-heading:    var(--ff-display);
}

/* ---------- Reset / Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--ff-sans);
  font-size: var(--fs-base);
  line-height: 1.6;
  color: var(--c-text);
  background: var(--c-bg);
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; height: auto; display: block; }
a { color: var(--c-primary); text-decoration: none; transition: color var(--transition); }
a:hover { color: var(--c-accent-600); }
h1, h2, h3, h4 { font-family: var(--ff-display); font-weight: 800; line-height: 1.15; color: var(--c-text); margin: 0 0 var(--sp-4); letter-spacing: -.01em; }
h1 { font-size: clamp(1.75rem, 6vw, var(--fs-3xl)); }
h2 { font-size: clamp(1.5rem, 4.5vw, var(--fs-2xl)); }
h3 { font-size: var(--fs-xl); }
h4 { font-size: var(--fs-lg); }
p  { margin: 0 0 var(--sp-4); }
hr { border: 0; border-top: 1px solid var(--c-line); margin: var(--sp-10) 0; }

.container { width: 100%; max-width: var(--container); margin: 0 auto; padding: 0 var(--sp-4); }
.container--narrow { max-width: var(--container-narrow); }
.section { padding: var(--sp-12) 0; }
.section--alt { background: var(--c-bg-alt); }
.section--sand { background: var(--c-sand); }
/* Startseite (Hero): schlichte .section deckt das dahinterliegende Hero-Bild ab,
   damit kein Text (z. B. USP "Persoenlich geprueft") ueber den durchscheinenden
   Sand ragt. section--alt/--sand behalten ihre eigene Toenung. */
.mod_article:has(.hero) .section:not(.section--alt):not(.section--sand) { background: var(--c-bg); position: relative; }
.eyebrow {
  display: inline-block;
  text-transform: uppercase;
  letter-spacing: .14em;
  font-weight: 700;
  font-size: var(--fs-xs);
  color: var(--c-accent-600);
  margin-bottom: var(--sp-3);
}
.lead { font-size: var(--fs-md); color: var(--c-text-muted); }

@media (min-width: 640px) {
  .container { padding: 0 var(--sp-6); }
  .section { padding: var(--sp-16) 0; }
}
@media (min-width: 900px) {
  .section { padding: var(--sp-20) 0; }
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-5);
  border-radius: var(--r-pill);
  font-weight: 700;
  font-size: var(--fs-sm);
  border: 2px solid transparent;
  cursor: pointer;
  transition: all var(--transition);
  text-align: center;
  white-space: nowrap;
  font-family: inherit;
}
.btn--primary { background: var(--c-accent); color: #fff; box-shadow: 0 6px 16px rgba(232,159,60,.30); }
.btn--primary:hover { background: var(--c-accent-600); color: #fff; transform: translateY(-1px); box-shadow: 0 10px 22px rgba(232,159,60,.40); }
.btn--secondary { background: var(--c-primary); color: #fff; }
.btn--secondary:hover { background: var(--c-primary-700); color: #fff; transform: translateY(-1px); }
.btn--ghost { background: transparent; color: var(--c-primary); border-color: var(--c-primary); }
.btn--ghost:hover { background: var(--c-primary); color: #fff; }
.btn--sm { padding: var(--sp-2) var(--sp-4); font-size: var(--fs-xs); }
.btn--lg { padding: var(--sp-4) var(--sp-8); font-size: var(--fs-base); }
.btn--block { display: flex; width: 100%; }

/* ---------- Utility-Bar (über dem Header) ---------- */
.utility-bar {
  background: var(--c-primary);
  color: rgba(255,255,255,.95);
  font-size: var(--fs-xs);
  border-bottom: 1px solid rgba(255,255,255,.1);
}
.utility-bar__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3);
  padding: 6px 0;
  min-height: 36px;
}
.utility-bar__left { display: none; }
.utility-bar__right { display: flex; align-items: center; gap: var(--sp-2); margin-left: auto; }
.util-link {
  display: inline-flex; align-items: center; gap: 6px;
  color: #fff !important; font-weight: 600;
  padding: 4px 8px; border-radius: var(--r-sm);
}
.util-link:hover { background: rgba(255,255,255,.1); color: #fff !important; }
.util-link svg { width: 14px; height: 14px; }

.util-select {
  position: relative;
  display: inline-flex; align-items: center; gap: 4px;
  padding: 4px 8px;
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: background var(--transition);
}
.util-select:hover { background: rgba(255,255,255,.1); }
.util-select svg.util-select__icon { width: 20px; height: 20px; color: rgba(255,255,255,.9); }
.util-select svg.util-select__chev { width: 12px; height: 12px; color: rgba(255,255,255,.7); }
.util-select select {
  appearance: none; -webkit-appearance: none;
  background: transparent; border: 0;
  color: #fff; font: inherit; font-size: var(--fs-xs); font-weight: 700;
  padding: 0 2px;
  cursor: pointer;
  outline: none;
}
.util-select select option { background: #fff; color: var(--c-text); }

@media (min-width: 700px) { .utility-bar__left { display: flex; gap: var(--sp-2); } }

/* ---------- Utility-Bar (ueber dem Header) – Design-Vorlage ---------- */
.utility-bar { background: var(--c-primary); color: rgba(255,255,255,.95); font-size: var(--fs-xs); border-bottom: 1px solid rgba(255,255,255,.1); }
.utility-bar__inner { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); padding: 6px 0; min-height: 36px; }
.utility-bar__left { display: none; }
.utility-bar__right { display: flex; align-items: center; gap: var(--sp-2); margin-left: auto; }
.util-link { display: inline-flex; align-items: center; gap: 6px; color: #fff; font-weight: 600; text-decoration: none; padding: 4px 8px; border-radius: var(--r-sm); }
.util-link:hover { background: rgba(255,255,255,.1); color: #fff; }
.util-link svg { width: 14px; height: 14px; }

.util-select { position: relative; display: inline-flex; align-items: center; gap: 4px; padding: 4px 8px; border-radius: var(--r-sm); cursor: pointer; transition: background var(--transition); }
.util-select:hover { background: rgba(255,255,255,.1); }
.util-select svg.util-select__icon { width: 20px; height: 20px; color: rgba(255,255,255,.9); }
.util-select svg.util-select__chev { width: 12px; height: 12px; color: rgba(255,255,255,.7); }
.util-select select { appearance: none; -webkit-appearance: none; background: transparent; border: 0; color: #fff; font: inherit; font-size: var(--fs-xs); font-weight: 700; padding: 0 2px; cursor: pointer; outline: none; }
.util-select select option { background: #fff; color: var(--c-text); }

/* Waehrung: currency_change rendert Form+Label+Select -> kompakt einbetten */
.util-select--currency .currency-changer__form { display: inline-flex; align-items: center; gap: 4px; margin: 0; }
.util-select--currency .currency-changer__label { display: none; }
.util-select--currency .currency-changer__select { background: transparent; border: 0; color: #fff; font: inherit; font-size: var(--fs-xs); font-weight: 700; padding: 0 2px; }

/* Sprache: changelanguage liefert Links statt Select -> als "DE · EN" stylen */
.util-select--lang .mod_changelanguage, .util-select--lang nav, .util-select--lang ul, .util-select--lang .level_1 { margin: 0; padding: 0; list-style: none; display: inline-flex; align-items: center; gap: 0; }
.util-select--lang li { display: inline-flex; align-items: center; }
.util-select--lang li + li::before { content: "·"; color: rgba(255,255,255,.5); margin: 0 6px; }
.util-select--lang a, .util-select--lang strong { color: #fff; font-weight: 700; font-size: var(--fs-xs); text-decoration: none; }
.util-select--lang a { opacity: .75; }
.util-select--lang a:hover, .util-select--lang strong, .util-select--lang .active { opacity: 1; }

@media (min-width: 700px) { .utility-bar__left { display: flex; gap: var(--sp-2); } }

.site-header {
  position: sticky; top: 0; z-index: 50;
  background: rgba(255,255,255,.94);
  backdrop-filter: saturate(180%) blur(10px);
  border-bottom: 1px solid var(--c-line);
  /* iOS: Inhalt unter Notch/Status-/URL-Leiste schieben. Der blur-Bar-
     Hintergrund fuellt den Inset-Bereich oben mit aus, die Header-Inhalte
     (Logo/Nav) sitzen darunter. Greift nur mit viewport-fit=cover (Layout). */
  padding-top: env(safe-area-inset-top, 0px);
}
.site-header__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-4);
  height: var(--header-h);
}
.site-header__logo img { height: 44px; width: auto; display: block; }
.site-nav { display: none; align-items: center; gap: var(--sp-5); }
.site-nav a {
  color: var(--c-text); font-weight: 600; font-size: var(--fs-sm);
  position: relative; padding: var(--sp-2) 0;
}
.site-nav a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -2px; height: 2px;
  background: var(--c-accent); transform: scaleX(0); transform-origin: left;
  transition: transform var(--transition);
}
.site-nav a:hover, .site-nav a.is-active { color: var(--c-primary); }
.site-nav a:hover::after, .site-nav a.is-active::after { transform: scaleX(1); }

/* Merkzettel als Notification-Bell-Pattern.
   WICHTIG: Selektor doppelt notiert (mit .site-nav__menu-Kontext), damit
   die Pille gegenueber `.site-nav__menu a { padding: var(--sp-2) 0 }`
   die hoehere Spezifitaet (0,2,1) hat – sonst wird unser horizontales
   Polster vom generischen Nav-a-Padding ueberschrieben. */
.nav-merkzettel,
.site-nav__menu .nav-merkzettel,
.site-nav .nav-merkzettel {
  display: inline-flex; align-items: center; gap: 8px;
  /* Spuerbares horizontales Polster, damit Herz + Label als eigenstaendige
     Pille wirken und der Tap-Bereich groesser ist. */
  padding: 8px 18px;
  border-radius: var(--r-pill);
  color: var(--c-text);
  font-weight: 600; font-size: var(--fs-sm);
  transition: background var(--transition), color var(--transition);
}
.nav-merkzettel::after { display: none !important; }
.nav-merkzettel:hover, .nav-merkzettel.is-active { background: var(--c-primary-50); color: var(--c-primary); }
.nav-merkzettel__icon {
  position: relative; display: inline-flex;
  width: 22px; height: 22px;
}
.nav-merkzettel__icon svg { width: 22px; height: 22px; color: currentColor; }
.nav-merkzettel.is-active .nav-merkzettel__icon svg { fill: currentColor; }
.nav-merkzettel__count {
  position: absolute; top: -6px; right: -8px;
  background: var(--c-accent); color: #fff;
  border-radius: var(--r-pill);
  min-width: 18px; height: 18px;
  font-size: 10px; font-weight: 800;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0 5px;
  border: 2px solid #fff;
  line-height: 1;
}
.nav-merkzettel__label { display: none; }
@media (min-width: 1180px) { .nav-merkzettel__label { display: inline; } }

.site-nav__cta {
  background: var(--c-accent) !important; color: #fff !important;
  padding: 10px 20px !important;
  border-radius: var(--r-pill) !important;
  font-weight: 700 !important;
  box-shadow: 0 6px 18px rgba(232,159,60,.30);
  transition: all var(--transition);
}
.site-nav__cta:hover { background: var(--c-accent-600) !important; transform: translateY(-1px); box-shadow: 0 10px 22px rgba(232,159,60,.40); }
.site-nav__cta::after { display: none !important; }

.nav-toggle {
  display: inline-flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 5px;
  background: transparent; border: 1px solid var(--c-line); border-radius: var(--r-sm);
  padding: 10px;
  cursor: pointer;
  width: 44px; height: 44px;
}
.nav-toggle span {
  display: block; width: 22px; height: 2px; background: var(--c-text); border-radius: 2px;
  transition: transform var(--transition), opacity var(--transition);
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

@media (min-width: 1000px) {
  :root { --header-h: 84px; }
  .site-header__logo img { height: 64px; }
  .site-nav { display: flex; }
  .nav-toggle { display: none; }
  /* Hauptmenü horizontal in der Kopfzeile zentrieren: Logo links, Aktionen
     (Merkzettel + „Jetzt buchen") rechts, Menü absolut mittig. */
  .site-header__inner { position: relative; }
  .site-nav__menu {
    position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  }
}

@media (max-width: 999px) {
  .site-nav.is-open {
    display: flex;
    /* top muss den Safe-Area-Inset mitrechnen, da .site-header (position:sticky)
       der Containing-Block ist und jetzt ein padding-top:env(safe-area-inset-top)
       hat – sonst rutscht das Dropdown um den Inset-Betrag in den Header. */
    position: absolute; top: calc(var(--header-h) + env(safe-area-inset-top, 0px)); left: 0; right: 0;
    flex-direction: column; align-items: stretch;
    background: #fff; border-bottom: 1px solid var(--c-line);
    padding: var(--sp-4) var(--sp-6);
    box-shadow: var(--shadow-md);
    gap: 0;
  }
  .site-nav.is-open a {
    padding: var(--sp-3) 0; border-bottom: 1px solid var(--c-line);
  }
  .site-nav.is-open a:last-child { border-bottom: 0; }
  .site-nav.is-open .nav-merkzettel { margin: var(--sp-2) 0; align-self: flex-start; padding: var(--sp-3) var(--sp-4); }
  /* Im mobilen Menue das Merkzettel-Label ausschreiben (im Desktop-Bar bleibt es
     unter 1180px aus Platzgruenden nur das Icon). */
  .site-nav.is-open .nav-merkzettel__label { display: inline; }
  .site-nav.is-open .site-nav__cta { margin-top: var(--sp-3); align-self: stretch; text-align: center; }
}

/* ---------- Hero ---------- */
.hero {
  position: relative;
  min-height: 60vh;
  display: flex; align-items: center;
  color: #fff;
  padding: var(--sp-12) 0 var(--sp-16);
  background:
          linear-gradient(180deg, rgba(31,41,55,.30) 0%, #1f2937 100%),
          url("https://images.unsplash.com/photo-1507525428034-b723cf961d3e?auto=format&fit=crop&w=2000&q=70") center/cover no-repeat;
}
.hero h1 { color: #fff; max-width: 18ch; }
.hero p.lead { color: rgba(255,255,255,.92); max-width: 50ch; font-size: var(--fs-md); }

@media (min-width: 900px) {
  .hero { min-height: 78vh; padding: var(--sp-20) 0 var(--sp-24); }
  .hero p.lead { font-size: var(--fs-lg); }
}

/* Search widget – mobile first: stacked */
.search-widget {
  background: #fff; color: var(--c-text);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
  padding: var(--sp-4);
  margin-top: var(--sp-6);
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--sp-3);
}
.search-widget label {
  display: block; font-size: var(--fs-xs); font-weight: 700;
  color: var(--c-text-muted); text-transform: uppercase; letter-spacing: .08em;
  margin-bottom: var(--sp-1);
}
.search-widget input, .search-widget select {
  width: 100%;
  padding: var(--sp-3);
  border: 1px solid var(--c-line);
  border-radius: var(--r-sm);
  font: inherit;
  background: #fff;
  font-size: 16px; /* iOS-Zoom verhindern */
}
.search-widget input:focus, .search-widget select:focus { outline: 2px solid var(--c-primary); border-color: var(--c-primary); }
.search-widget .btn { height: 48px; }

@media (min-width: 640px) {
  .search-widget { grid-template-columns: 1fr 1fr; padding: var(--sp-5); }
}
@media (min-width: 1000px) {
  .search-widget { grid-template-columns: 1.1fr 1.4fr 1.4fr auto; align-items: end; }
}

/* Sekundäre Schnellsuche (Objektnummer/Titel) – Mobile First */
.search-secondary {
  margin-top: var(--sp-5);
  display: flex; flex-direction: column; gap: var(--sp-2);
  color: rgba(255,255,255,.95);
}
.search-secondary__label {
  font-size: var(--fs-sm); font-weight: 600;
  display: inline-flex; align-items: center; gap: 6px;
}
.search-secondary__label svg { width: 16px; height: 16px; }
.search-secondary__row {
  display: flex; gap: var(--sp-2);
  background: rgba(255,255,255,.18);
  border: 1px solid rgba(255,255,255,.25);
  border-radius: var(--r-md);
  padding: 4px;
  backdrop-filter: blur(6px);
}
.search-secondary__row input {
  flex: 1 1 auto; min-width: 0;
  border: 0; background: transparent; color: #fff;
  padding: 10px 12px;
  font: inherit; font-size: 16px;
  outline: none;
}
.search-secondary__row input::placeholder { color: rgba(255,255,255,.7); }
.search-secondary__row .btn { flex: 0 0 auto; padding: 8px 18px; font-size: var(--fs-sm); }

@media (min-width: 700px) {
  .search-secondary { flex-direction: row; align-items: center; gap: var(--sp-4); }
  .search-secondary__row { flex: 1 1 auto; max-width: 520px; }
}

/* ---------- USP strip ---------- */
.usp-grid { display: grid; grid-template-columns: 1fr; gap: var(--sp-6); }
@media (min-width: 640px) { .usp-grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 900px) { .usp-grid { grid-template-columns: repeat(4, 1fr); } }
.usp { display: flex; gap: var(--sp-4); align-items: flex-start; }
.usp__icon {
  flex: 0 0 auto;
  width: 52px; height: 52px;
  border-radius: var(--r-md);
  background: var(--c-primary-50); color: var(--c-primary);
  display: flex; align-items: center; justify-content: center;
}
.usp h4 { margin-bottom: var(--sp-1); }
.usp p { color: var(--c-text-muted); margin: 0; font-size: var(--fs-sm); }

/* ---------- Cards / Listings ---------- */
.cards { display: grid; grid-template-columns: 1fr; gap: var(--sp-6); }
@media (min-width: 600px) { .cards { grid-template-columns: 1fr 1fr; gap: var(--sp-6); } }
@media (min-width: 1000px) { .cards { grid-template-columns: repeat(3, 1fr); gap: var(--sp-8); } }

.card {
  background: #fff;
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  transition: transform var(--transition), box-shadow var(--transition);
  display: flex; flex-direction: column;
  border: 1px solid var(--c-line);
}
.card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }

/* Info-/Status-Karten (direkt im bereits gerahmten .section__container, z. B.
   Buchungsuebersicht/Login/Logout): kein doppelter Rahmen und kein Hover-Lift.
   Die Listing-Karten liegen im .cards-Grid und sind NICHT betroffen. */
.section__container > .card {
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}
.section__container > .card:hover {
  transform: none;
  box-shadow: none;
}

.card__media {
  position: relative; aspect-ratio: 4/3; overflow: hidden;
  isolation: isolate; /* eigener Stacking-Context, damit z-index sauber zieht */
}
.card__media img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 600ms ease;
  position: relative; z-index: 1;
}
.card:hover .card__media img { transform: scale(1.06); }

/* Bugfix: Badge & Fav müssen ÜBER dem (transformierten) Bild bleiben */
.card__badge {
  position: absolute; top: var(--sp-3); left: var(--sp-3);
  z-index: 3;
  background: var(--c-accent); color: #fff;
  font-weight: 700; font-size: var(--fs-xs);
  padding: var(--sp-1) var(--sp-3); border-radius: var(--r-pill);
  letter-spacing: .04em; text-transform: uppercase;
}
.card__fav {
  position: absolute; top: var(--sp-3); right: var(--sp-3);
  z-index: 3;
  background: rgba(255,255,255,.92); width: 36px; height: 36px;
  border-radius: 50%; display:flex; align-items:center; justify-content:center;
  color: var(--c-primary); cursor: pointer; border: 0;
  transition: background var(--transition), transform var(--transition);
}
.card__fav:hover { background: #fff; transform: scale(1.08); }
.card__fav.is-active { color: var(--c-accent); }
.card__fav.is-active svg { fill: var(--c-accent); }

.card__body { padding: var(--sp-5); display: flex; flex-direction: column; gap: var(--sp-2); flex: 1; }
.card__location { font-size: var(--fs-xs); color: var(--c-text-muted); text-transform: uppercase; letter-spacing: .08em; font-weight: 600; }
.card__title { font-size: var(--fs-lg); margin: 0; }
.card__title a { color: inherit; }
.card__meta { display: flex; flex-wrap: wrap; gap: var(--sp-3); font-size: var(--fs-sm); color: var(--c-text-muted); }
.card__meta span { display: inline-flex; gap: 4px; align-items: center; }
.card__footer {
  display: flex; align-items: center; justify-content: space-between;
  margin-top: auto; padding-top: var(--sp-4);
  border-top: 1px solid var(--c-line);
}
.card__price { font-family: var(--ff-display); font-weight: 800; color: var(--c-primary); font-size: var(--fs-lg); }
.card__price small { display: block; font-weight: 500; font-size: var(--fs-xs); color: var(--c-text-muted); }
.card__rating { color: var(--c-accent); font-weight: 700; font-size: var(--fs-sm); display: inline-flex; align-items: center; gap: 4px; }
.card__rating svg { width: 14px; height: 14px; color: var(--c-accent); }

/* ---------- Listing Layout: Sidebar + Content ---------- */
.listing-layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--sp-8);
}
@media (min-width: 1000px) {
  .listing-layout {
    grid-template-columns: 280px 1fr;
    gap: var(--sp-10);
    align-items: start;
  }
}

.filter-sidebar {
  display: none; /* mobil als Drawer, siehe unten */
  background: #fff;
  border: 1px solid var(--c-line);
  border-radius: var(--r-lg);
  padding: var(--sp-5);
  position: sticky;
  top: calc(var(--header-h) + var(--sp-4));
  max-height: calc(100vh - var(--header-h) - var(--sp-8));
  overflow-y: auto;
}
@media (min-width: 1000px) { .filter-sidebar { display: block; } }

.filter-group { padding-bottom: var(--sp-5); margin-bottom: var(--sp-5); border-bottom: 1px solid var(--c-line); }
.filter-group:last-child { border-bottom: 0; padding-bottom: 0; margin-bottom: 0; }
.filter-group h4 { font-size: var(--fs-sm); text-transform: uppercase; letter-spacing: .08em; margin-bottom: var(--sp-3); color: var(--c-text); }
.filter-options { display: flex; flex-direction: column; gap: var(--sp-2); }
.filter-options label {
  display: flex; align-items: center; gap: var(--sp-2);
  font-size: var(--fs-sm); cursor: pointer;
  color: var(--c-text);
}
.filter-options label:hover { color: var(--c-primary); }
.filter-options .count { color: var(--c-text-muted); font-size: var(--fs-xs); margin-left: auto; }
.filter-pills { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.filter-pill {
  padding: 6px 12px;
  border-radius: var(--r-pill);
  border: 1px solid var(--c-line);
  background: #fff; font-size: var(--fs-xs); font-weight: 600;
  color: var(--c-text); cursor: pointer;
  transition: all var(--transition);
}
.filter-pill:hover, .filter-pill.is-active { border-color: var(--c-primary); background: var(--c-primary-50); color: var(--c-primary); }
.range-row { display: flex; gap: var(--sp-2); align-items: center; font-size: var(--fs-sm); }
.range-row input { width: 100%; padding: 8px; border: 1px solid var(--c-line); border-radius: var(--r-sm); font: inherit; font-size: 14px; }

/* Mobile-Filter-Toolbar + Drawer */
.mobile-filter-toolbar {
  display: flex; gap: var(--sp-3); margin-bottom: var(--sp-5);
}
@media (min-width: 1000px) { .mobile-filter-toolbar { display: none; } }
.mobile-filter-toolbar .btn { flex: 1; }

.filter-drawer-backdrop {
  display: none;
  position: fixed; inset: 0; background: rgba(31,41,55,.55); z-index: 60;
}
.filter-drawer-backdrop.is-open { display: block; }
.filter-drawer {
  position: fixed; bottom: 0; left: 0; right: 0;
  background: #fff; z-index: 61;
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  max-height: 85vh; overflow-y: auto;
  padding: var(--sp-5);
  transform: translateY(100%);
  transition: transform var(--transition);
  box-shadow: 0 -10px 30px rgba(0,0,0,.2);
}
.filter-drawer.is-open { transform: translateY(0); }
.filter-drawer__head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: var(--sp-4); padding-bottom: var(--sp-3);
  border-bottom: 1px solid var(--c-line);
}
.filter-drawer__head h3 { margin: 0; font-size: var(--fs-lg); }
.filter-drawer__close {
  background: transparent; border: 0; cursor: pointer;
  width: 36px; height: 36px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: var(--c-text-muted);
}
.filter-drawer__actions { display: flex; gap: var(--sp-3); margin-top: var(--sp-5); }
.filter-drawer__actions .btn { flex: 1; }

/* ---------- View Toggle: Liste / Karte ---------- */
.view-toggle { display: inline-flex; border: 1px solid var(--c-line); border-radius: var(--r-pill); padding: 4px; background: #fff; }
.view-toggle button {
  background: transparent; border: 0; padding: 8px 14px;
  font: inherit; font-size: var(--fs-xs); font-weight: 700;
  color: var(--c-text-muted); cursor: pointer; border-radius: var(--r-pill);
  display: inline-flex; align-items: center; gap: 6px;
}
.view-toggle button.is-active { background: var(--c-primary); color: #fff; }
.view-toggle svg { width: 16px; height: 16px; }

.results-toolbar {
  display: flex; flex-wrap: wrap; gap: var(--sp-3);
  justify-content: space-between; align-items: center;
  margin-bottom: var(--sp-5);
}
.results-count { color: var(--c-text-muted); font-size: var(--fs-sm); }

/* ---------- Karten-Mockup (OSM/Leaflet Optik) ---------- */
.map-view {
  position: relative;
  height: 70vh; min-height: 480px;
  border: 1px solid var(--c-line); border-radius: var(--r-lg);
  overflow: hidden;
  background: #DCEAF0;
}
.map-view__tiles {
  position: absolute; inset: 0;
  background-image:
          linear-gradient(135deg, transparent 48%, rgba(91,168,184,.18) 49%, rgba(91,168,184,.18) 51%, transparent 52%),
          linear-gradient(45deg, transparent 48%, rgba(91,168,184,.12) 49%, rgba(91,168,184,.12) 51%, transparent 52%),
          repeating-linear-gradient(0deg, rgba(255,255,255,.4) 0 1px, transparent 1px 60px),
          repeating-linear-gradient(90deg, rgba(255,255,255,.4) 0 1px, transparent 1px 60px),
          radial-gradient(circle at 30% 40%, #C8E1A8 0%, transparent 35%),
          radial-gradient(circle at 70% 30%, #B8D89A 0%, transparent 30%),
          radial-gradient(circle at 60% 70%, #DCEAF0 0%, #97C8D8 80%);
}
.map-view__pin {
  position: absolute;
  width: 36px; height: 36px;
  transform: translate(-50%, -100%);
  cursor: pointer;
  filter: drop-shadow(0 4px 6px rgba(0,0,0,.25));
}
.map-view__pin svg { width: 100%; height: 100%; color: var(--c-accent); }
.map-view__pin .price-tag {
  position: absolute; top: -28px; left: 50%; transform: translateX(-50%);
  background: var(--c-primary); color: #fff;
  font-weight: 700; font-size: 12px;
  padding: 4px 10px; border-radius: var(--r-pill);
  white-space: nowrap;
}
.map-view__pin:hover svg { color: var(--c-primary); transform: scale(1.15); transition: transform var(--transition); }

.map-view__attribution {
  position: absolute; bottom: 4px; right: 4px;
  font-size: 10px; background: rgba(255,255,255,.85);
  padding: 2px 6px; border-radius: 3px; color: var(--c-text-muted);
}
.map-view__zoom {
  position: absolute; top: var(--sp-3); left: var(--sp-3);
  display: flex; flex-direction: column;
  background: #fff; border-radius: var(--r-sm); box-shadow: var(--shadow-sm); overflow: hidden;
}
.map-view__zoom button {
  width: 36px; height: 36px; background: #fff; border: 0;
  border-bottom: 1px solid var(--c-line); cursor: pointer;
  font-size: 18px; font-weight: 700; color: var(--c-text);
}
.map-view__zoom button:last-child { border-bottom: 0; }
.map-view__hint {
  position: absolute; top: var(--sp-3); left: 50%; transform: translateX(-50%);
  background: rgba(255,255,255,.95); padding: 8px 16px;
  border-radius: var(--r-pill); box-shadow: var(--shadow-sm);
  font-size: var(--fs-xs); color: var(--c-text-muted); font-weight: 600;
  white-space: nowrap;
}

/* ---------- Detail page ---------- */
.gallery {
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-2);
  border-radius: var(--r-lg); overflow: hidden;
}
.gallery img { width: 100%; height: 100%; object-fit: cover; }
.gallery__main { grid-column: 1 / -1; aspect-ratio: 16/9; }
.gallery__thumb { aspect-ratio: 4/3; }
@media (min-width: 800px) {
  .gallery { grid-template-columns: 2fr 1fr 1fr; }
  .gallery__main { grid-column: auto; grid-row: span 2; aspect-ratio: 4/3; }
}

.detail-grid {
  display: grid; grid-template-columns: 1fr; gap: var(--sp-8);
  margin-top: var(--sp-8);
}
@media (min-width: 1000px) {
  .detail-grid { grid-template-columns: 1fr 380px; gap: var(--sp-12); }
}

.facts {
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3);
  background: var(--c-foam); border-radius: var(--r-md);
  padding: var(--sp-4);
  margin-bottom: var(--sp-6);
}
@media (min-width: 800px) { .facts { grid-template-columns: repeat(4, 1fr); padding: var(--sp-5); gap: var(--sp-4); } }
.fact { display: flex; gap: var(--sp-3); align-items: center; }
.fact__icon { width: 40px; height: 40px; border-radius: var(--r-sm); background: #fff; display:flex; align-items:center; justify-content:center; color: var(--c-primary); flex: 0 0 auto; }
.fact__icon svg { width: 20px; height: 20px; }
.fact__label { font-size: var(--fs-xs); color: var(--c-text-muted); text-transform: uppercase; letter-spacing: .08em; }
.fact__value { font-weight: 700; color: var(--c-text); }

.amenities ul { padding: 0; margin: 0; list-style: none; columns: 1; column-gap: var(--sp-8); }
.amenities li { padding: var(--sp-2) 0; display: flex; gap: var(--sp-2); align-items: center; break-inside: avoid; }
.amenities li svg { flex: 0 0 auto; color: var(--c-success); width: 18px; height: 18px; }
@media (min-width: 640px) { .amenities ul { columns: 2; } }

/* Booking sidebar */
.booking-card {
  background: #fff; border: 1px solid var(--c-line); border-radius: var(--r-lg);
  padding: var(--sp-5);
  box-shadow: var(--shadow-md);
}
@media (min-width: 1000px) {
  .booking-card { position: sticky; top: calc(var(--header-h) + var(--sp-4)); padding: var(--sp-6); }
}
.booking-card__price { display: flex; align-items: baseline; gap: var(--sp-2); margin-bottom: var(--sp-4); }
.booking-card__price strong { font-family: var(--ff-display); font-size: var(--fs-2xl); color: var(--c-primary); }
.booking-card__price span { color: var(--c-text-muted); font-size: var(--fs-sm); }
.booking-card .field { margin-bottom: var(--sp-3); }
.booking-card label { font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase; letter-spacing: .08em; color: var(--c-text-muted); display: block; margin-bottom: var(--sp-1); }
.booking-card input, .booking-card select { width:100%; padding: var(--sp-3); border:1px solid var(--c-line); border-radius: var(--r-sm); font: inherit; font-size: 16px; background: #fff; }
.booking-card .summary {
  background: var(--c-bg-alt); border-radius: var(--r-md);
  padding: var(--sp-4); margin-top: var(--sp-4); margin-bottom: var(--sp-4);
  font-size: var(--fs-sm);
}
.booking-card .summary .row { display:flex; justify-content: space-between; padding: var(--sp-1) 0; }
.booking-card .summary .total { border-top:1px solid var(--c-line); margin-top: var(--sp-2); padding-top: var(--sp-3); font-weight: 800; color: var(--c-text); font-size: var(--fs-md); }

/* Buchungs-Preisbox – Demo-Feinschliff. Grundlayout (Flex-Zeilen, Stapeln der
   Rabattzeile, Badge-Form) liegt im booking-bundle (_price.html.twig); hier nur
   die markentypischen Farben fuer Streichpreis, Preis und Rabatt-Badge. */
.booking-price__value .old-price { color: var(--c-text-muted); opacity: 1; }
.booking-price__value .new-price { color: var(--c-primary); }
.booking-price__value .discount-badge { background: #FBEAEA; color: #B42318; }

/* Calendar mockup */
.calendar { border:1px solid var(--c-line); border-radius: var(--r-md); padding: var(--sp-4); background:#fff; }
.calendar__head { display:flex; justify-content: space-between; align-items: center; margin-bottom: var(--sp-3); font-weight: 700; }
.calendar__nav { background:transparent; border:1px solid var(--c-line); width: 32px; height:32px; border-radius:50%; cursor:pointer; font: inherit; }
.calendar__grid { display:grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.calendar__dow { text-align:center; font-size: var(--fs-xs); color: var(--c-text-muted); padding: var(--sp-1) 0; font-weight: 700; }
.calendar__day {
  aspect-ratio: 1; display:flex; align-items:center; justify-content:center;
  font-size: var(--fs-sm); border-radius: var(--r-sm);
  background: var(--c-primary-50); color: var(--c-primary); font-weight: 600;
}
.calendar__day--out { background: transparent; color: var(--c-line); }
.calendar__day--booked { background: var(--c-line); color: var(--c-text-muted); text-decoration: line-through; cursor: not-allowed; }
.calendar__day--selected { background: var(--c-accent); color: #fff; }
.calendar__legend { display:flex; flex-wrap: wrap; gap: var(--sp-3); margin-top: var(--sp-3); font-size: var(--fs-xs); color: var(--c-text-muted); }
.calendar__legend i { display: inline-block; width:14px; height:14px; border-radius:3px; margin-right: 4px; vertical-align: -2px; }

/* Map placeholder Detailseite */
.map-placeholder {
  height: 280px; border-radius: var(--r-lg); overflow: hidden; position: relative;
  background:
          radial-gradient(circle at 50% 60%, rgba(232,159,60,.18), transparent 60%),
          linear-gradient(135deg, #DCEAF0 0%, #C1DCE3 100%);
  border: 1px solid var(--c-line);
  display:flex; align-items:flex-end; justify-content:center;
  padding-bottom: var(--sp-5);
}
.map-placeholder__pin {
  position:absolute; left: 50%; top: 50%; transform: translate(-50%, -120%);
  width: 44px; height: 44px; color: var(--c-accent);
  filter: drop-shadow(0 4px 8px rgba(0,0,0,.18));
}
.map-placeholder span { background: rgba(255,255,255,.9); padding: var(--sp-2) var(--sp-4); border-radius: var(--r-pill); font-weight: 600; }

/* ---------- Testimonials (ohne Avatar) ---------- */
.quotes { display: grid; grid-template-columns: 1fr; gap: var(--sp-6); }
@media (min-width: 800px) { .quotes { grid-template-columns: repeat(3, 1fr); } }
.quote {
  background: #fff; border-radius: var(--r-lg);
  padding: var(--sp-6); border: 1px solid var(--c-line);
  position: relative;
}
.quote::before {
  content: "\201C"; position: absolute; top: -28px; left: 16px;
  font-family: Georgia, serif; font-size: 80px; color: var(--c-accent); line-height: 1;
}
.quote p { font-style: italic; color: var(--c-text); margin-bottom: var(--sp-3); }
.quote-meta { display: flex; gap: var(--sp-2); align-items: center; font-size: var(--fs-sm); color: var(--c-text-muted); }
.quote-meta strong { color: var(--c-text); }
.quote-meta__sep { opacity: .5; }
.quote-rating { color: var(--c-accent); display: inline-flex; gap: 2px; }
.quote-rating svg { width: 14px; height: 14px; }

/* ---------- Region teaser ---------- */
.region-grid { display: grid; grid-template-columns: 1fr; gap: var(--sp-8); align-items: center; }
@media (min-width: 800px) { .region-grid { grid-template-columns: 1.2fr 1fr; gap: var(--sp-10); } }
.region-grid img { border-radius: var(--r-lg); box-shadow: var(--shadow-md); aspect-ratio: 4/3; object-fit: cover; width: 100%; }
.region-facts { list-style: none; padding: 0; margin: var(--sp-4) 0 0; display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-2); font-size: var(--fs-sm); color: var(--c-text-muted); }
.region-facts li::before { content: "✓"; color: var(--c-accent); font-weight: 800; margin-right: 6px; }

/* ---------- CTA banner ---------- */
.cta-banner {
  background: linear-gradient(135deg, var(--c-primary) 0%, var(--c-primary-700) 100%);
  color: #fff;
  border-radius: var(--r-xl);
  padding: var(--sp-8) var(--sp-6);
  display: grid; grid-template-columns: 1fr; gap: var(--sp-5);
  position: relative; overflow: hidden;
}
.cta-banner::before {
  content:""; position:absolute; right:-80px; top:-80px; width: 320px; height: 320px;
  background: radial-gradient(circle, rgba(232,159,60,.35) 0%, transparent 70%);
  pointer-events: none; /* sonst faengt das Overlay die Klicks auf den Button ab */
}
.cta-banner > * { position: relative; z-index: 1; }
.cta-banner h2 { color: #fff; margin: 0; }
.cta-banner p { color: rgba(255,255,255,.85); margin: var(--sp-3) 0 0; }
@media (min-width: 800px) {
  .cta-banner { grid-template-columns: 2fr 1fr; gap: var(--sp-8); padding: var(--sp-12) var(--sp-10); align-items: center; }
  .cta-banner .btn { justify-self: end; }
}

/* ---------- Forms ---------- */
.form { display: grid; grid-template-columns: 1fr; gap: var(--sp-5); }
@media (min-width: 700px) { .form { grid-template-columns: 1fr 1fr; } }
.form .field--full { grid-column: 1 / -1; }
.form label { display: block; font-weight: 600; margin-bottom: var(--sp-1); font-size: var(--fs-sm); }
.form input, .form select, .form textarea {
  width: 100%; padding: var(--sp-3); border: 1px solid var(--c-line); border-radius: var(--r-sm);
  font: inherit; font-size: 16px; background: #fff;
}
.form textarea { min-height: 160px; resize: vertical; }
.form input:focus, .form textarea:focus, .form select:focus { outline: 2px solid var(--c-primary); border-color: var(--c-primary); }

/* Custom Checkbox */
.checkbox {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--sp-3);
  align-items: start;
  font-size: var(--fs-sm);
  color: var(--c-text);
  cursor: pointer;
  line-height: 1.5;
}
.checkbox input[type="checkbox"] {
  appearance: none; -webkit-appearance: none;
  width: 22px; height: 22px;
  border: 2px solid var(--c-line); border-radius: 5px;
  background: #fff; cursor: pointer;
  position: relative;
  margin: 0;
  flex: 0 0 auto;
  transition: all var(--transition);
}
.checkbox input[type="checkbox"]:hover { border-color: var(--c-primary); }
.checkbox input[type="checkbox"]:checked {
  background: var(--c-primary); border-color: var(--c-primary);
}
.checkbox input[type="checkbox"]:checked::after {
  content: "";
  position: absolute; left: 6px; top: 2px;
  width: 6px; height: 11px;
  border: solid #fff; border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.checkbox input[type="checkbox"]:focus-visible { outline: 3px solid var(--c-primary-50); outline-offset: 2px; }

/* ---------- Page hero (sub pages) ---------- */
.page-hero {
  background: linear-gradient(135deg, var(--c-primary) 0%, var(--c-primary-700) 100%);
  color: #fff; padding: var(--sp-10) 0 var(--sp-8);
}
@media (min-width: 800px) { .page-hero { padding: var(--sp-16) 0 var(--sp-12); } }
.page-hero h1 { color: #fff; margin: 0; }
.page-hero .lead { color: rgba(255,255,255,.85); margin-top: var(--sp-3); max-width: 65ch; }
.breadcrumbs { font-size: var(--fs-sm); color: rgba(255,255,255,.75); margin-bottom: var(--sp-2); }
.breadcrumbs a { color: rgba(255,255,255,.9); }

/* ---------- Footer ---------- */
.site-footer {
  background: var(--c-primary); color: #C8D2E3;
  padding: var(--sp-12) 0 var(--sp-6);
  margin-top: var(--sp-16);
}
.site-footer h5 { color: #fff; font-family: var(--ff-display); font-weight: 700; margin: 0 0 var(--sp-4); font-size: var(--fs-base); text-transform: uppercase; letter-spacing: .08em; }
.site-footer a { color: #C8D2E3; }
.site-footer a:hover { color: var(--c-accent); }
.footer-grid { display: grid; grid-template-columns: 1fr; gap: var(--sp-8); }
@media (min-width: 600px) { .footer-grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1000px) { .footer-grid { grid-template-columns: 1.5fr 1fr 1fr 1fr; gap: var(--sp-10); } }
.footer-grid ul { list-style: none; padding: 0; margin: 0; }
.footer-grid li { padding: var(--sp-1) 0; }
.footer-brand img { height: 60px; width: auto; margin-bottom: var(--sp-4); }
.footer-login {
  display: inline-flex; align-items: center; gap: 6px;
  margin-top: var(--sp-3);
  padding: 8px 14px;
  background: rgba(255,255,255,.08);
  border: 1px solid rgba(255,255,255,.15);
  border-radius: var(--r-pill);
  font-weight: 600; font-size: var(--fs-xs);
  color: #fff !important;
}
.footer-login:hover { background: var(--c-accent); border-color: var(--c-accent); color: #fff !important; }
.footer-login svg { width: 14px; height: 14px; }
.footer-bottom {
  margin-top: var(--sp-10); padding-top: var(--sp-5); border-top: 1px solid rgba(255,255,255,.1);
  display: flex; justify-content: space-between; gap: var(--sp-4); flex-wrap: wrap;
  font-size: var(--fs-xs); color: #8FA0BB;
}

/* Währungsumschalter im Footer (currency_change Content-Element) */
.footer-currency { margin-top: var(--sp-4); }
.site-footer .currency-changer__form { gap: var(--sp-2); align-items: center; margin: 0; }
.site-footer .currency-changer__label { color: #C8D2E3; font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: .06em; }
.site-footer .currency-changer__select {
  background: rgba(255,255,255,.08); color: #fff;
  border: 1px solid rgba(255,255,255,.18); border-radius: var(--r-pill);
  padding: 8px 30px 8px 14px; font: inherit; font-size: var(--fs-xs); font-weight: 600;
  cursor: pointer;
}
.site-footer .currency-changer__select option { color: #1F2937; }
.site-footer .currency-changer__select:hover { border-color: var(--c-accent); }
.site-footer .currency-changer__select:focus { outline: 2px solid var(--c-accent); outline-offset: 1px; }

/* ---------- Utility ---------- */
.text-center { text-align: center; }
.mt-0 { margin-top: 0; }
.mt-2 { margin-top: var(--sp-2); }
.mt-4 { margin-top: var(--sp-4); }
.mt-6 { margin-top: var(--sp-6); }
.mt-8 { margin-top: var(--sp-8); }
.flex { display: flex; gap: var(--sp-3); align-items: center; flex-wrap: wrap; }
.flex--between { justify-content: space-between; }
.tag {
  display:inline-block; background: var(--c-primary-50); color: var(--c-primary);
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: .04em;
  padding: 4px 10px; border-radius: var(--r-pill);
}
.tag--accent { background: var(--c-accent-50); color: var(--c-accent-600); }

/* ---------- Merkzettel-Badge: leer ausblenden ---------- */
.nav-merkzettel__count.is-empty,
.nav-merkzettel__count[hidden] { display: none; }

/* ---------- Dynamische Navigation (navigation-Modul im Header-HTML) ----------
   Der Header ist ein Custom-HTML-Modul; die Hauptnavigation kommt per
   {{insert_module::6}} aus dem Contao-navigation-Modul (mod_navigation > ul > li).
   Aktiver Menüpunkt wird von Contao als <strong class="active"> ausgegeben. */
.site-nav__menu ul {
  display: flex; align-items: center; gap: var(--sp-5);
  list-style: none; margin: 0; padding: 0;
}
.site-nav__menu li { margin: 0; }
.site-nav__menu a,
.site-nav__menu strong {
  color: var(--c-text); font-weight: 600; font-size: var(--fs-sm);
  position: relative; padding: var(--sp-2) 0; display: inline-block;
}
.site-nav__menu a::after,
.site-nav__menu strong::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: var(--c-accent); transform: scaleX(0); transform-origin: left;
  transition: transform var(--transition);
}
.site-nav__menu a:hover { color: var(--c-primary); }
/* Aktiver/gehoverter Menüpunkt: animierte Accent-Border – greift auch für das
   Contao-Markup des aktiven Eintrags (<strong class="active"> bzw.
   <li class="active|trail"><a>), damit es auf Desktop wie mobil erscheint. */
/* Aktive Akzentlinie auf Desktop + Mobile:
   - Hover auf Link
   - <strong> ist in Contaos Navigation IMMER das aktuell gewaehlte Item -> Linie an
   - active/trail-Klassen (Contao-Markup) ebenfalls
*/
.site-nav__menu a:hover::after,
.site-nav__menu strong::after,
.site-nav__menu strong.active::after,
.site-nav__menu li.active > a::after,
.site-nav__menu li.active > strong::after,
.site-nav__menu li.trail > a::after,
.site-nav__menu li.trail > strong::after,
.site-nav__menu a.active::after,
.site-nav__menu a.trail::after { transform: scaleX(1); }
.site-nav__menu strong.active,
.site-nav__menu li.active > a,
.site-nav__menu li.trail > a,
.site-nav__menu a.active,
.site-nav__menu a.trail { color: var(--c-primary); }

@media (max-width: 999px) {
  .site-nav.is-open .site-nav__menu { width: 100%; }
  .site-nav.is-open .site-nav__menu ul { flex-direction: column; align-items: stretch; gap: 0; width: 100%; }
  .site-nav.is-open .site-nav__menu li a,
  .site-nav.is-open .site-nav__menu li strong {
    display: block; padding: var(--sp-3) 0; border-bottom: 1px solid var(--c-line);
  }
}

/* ----------------------------------------------------------------------
   Untermenuesvz (mod_navigation gibt verschachtelte <ul class="level_2">
   pro Eltern-li aus). Desktop: Dropdown per Hover. Mobile: ausgeklappt
   inline mit Einrueckung, weil Hover auf Touch nicht greift.
   ---------------------------------------------------------------------- */
@media (min-width: 1000px) {
  /* Contao gibt dem Navi-Modul die Klasse `.block`, die aus dem Layout-CSS
     `overflow:hidden` traegt – das kappt das absolut positionierte Dropdown
     (ul.level_2), bevor es ueberhaupt sichtbar wird. Auf Desktop daher die
     ganze Kette bis zum Modul explizit auf sichtbar zwingen. */
  .site-nav__menu nav.mod_navigation,
  .site-nav__menu .mod_navigation.block,
  .site-nav__menu .level_1,
  .site-nav__menu .level_1 > li { overflow: visible !important; }

  /* Eltern muss position:relative + Hover-Target sein, damit die
     absolut positionierte Sub-Liste daran haengt. */
  .site-nav__menu li { position: relative; }

  /* Sub-Liste standardmaessig versteckt, ueberlagert per absolute. */
  .site-nav__menu ul.level_2 {
    position: absolute;
    top: 100%;
    left: 0;
    min-width: 220px;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: #fff;
    border: 1px solid var(--c-line);
    border-radius: var(--radius-md, 8px);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.10);
    padding: var(--sp-2, 0.5rem) 0;
    margin-top: 0;
    opacity: 0;
    pointer-events: none;
    transform: translateY(4px);
    transition: opacity 0.15s ease, transform 0.15s ease;
    z-index: 50;
  }

  /* Hover oder Tastatur-Fokus auf Elternpunkt -> Dropdown sichtbar.
     :focus-within deckt Tastatur-Nutzer ab. */
  .site-nav__menu li:hover > ul.level_2,
  .site-nav__menu li:focus-within > ul.level_2 {
    opacity: 1;
    pointer-events: auto;
    transform: translateY(0);
  }

  /* Hauptmenuepunkt aktiv halten (Akzentlinie + Primary-Farbe), solange die Maus
     im Eltern-li ist – also auch beim Hineinfahren ins Dropdown, nicht nur ueber
     dem Link selbst. Sonst verschwindet die Markierung, sobald man den Link
     verlaesst und ins Submenu wechselt. */
  .site-nav__menu li:hover > a,
  .site-nav__menu li:hover > strong { color: var(--c-primary); }
  .site-nav__menu li:hover > a::after,
  .site-nav__menu li:hover > strong::after { transform: scaleX(1); }

  /* Sub-Items haben keine animierte Akzentlinie (das ist die Top-Level-Optik) */
  .site-nav__menu ul.level_2 li { display: block; }
  .site-nav__menu ul.level_2 a,
  .site-nav__menu ul.level_2 strong {
    display: block;
    padding: var(--sp-2, 0.5rem) var(--sp-4, 1rem);
    white-space: nowrap;
  }
  .site-nav__menu ul.level_2 a::after,
  .site-nav__menu ul.level_2 strong::after { display: none; }
  .site-nav__menu ul.level_2 a:hover,
  .site-nav__menu ul.level_2 li.active a,
  .site-nav__menu ul.level_2 li.trail a {
    background: var(--c-surface-alt, #f5f5f5);
    color: var(--c-primary);
  }
}

/* Mobile: Sub-Liste eingerueckt unter dem Eltern-Link sichtbar, damit
   auf Touch nichts klemmt. */
@media (max-width: 999px) {
  .site-nav.is-open .site-nav__menu ul.level_2 {
    padding-left: var(--sp-4, 1rem);
  }
  .site-nav.is-open .site-nav__menu ul.level_2 li a {
    font-weight: 500;
    color: var(--c-text-muted, var(--c-text));
  }
}

/* ---------- Sprachumschalter (terminal42/contao-changelanguage) ---------- */
.site-nav__lang { display: inline-flex; align-items: center; }
.mod_changelanguage ul { list-style: none; display: inline-flex; gap: 4px; margin: 0; padding: 0; }
.mod_changelanguage li { margin: 0; }
.mod_changelanguage a,
.mod_changelanguage .active {
  display: inline-flex; align-items: center;
  padding: 4px 10px; border-radius: var(--r-pill);
  font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: var(--c-text-muted); border: 1px solid var(--c-line);
}
.mod_changelanguage a:hover { color: var(--c-primary); border-color: var(--c-primary); background: var(--c-primary-50); }
.mod_changelanguage .active { color: #fff; background: var(--c-primary); border-color: var(--c-primary); }

/* ---------- FAQ Accordion (<details>) ---------- */
.faq { display: grid; gap: var(--sp-3); }
.faq details {
  background: #fff; border: 1px solid var(--c-line); border-radius: var(--r-md);
  padding: 0 var(--sp-5); overflow: hidden;
  transition: box-shadow var(--transition);
}
.faq details[open] { box-shadow: var(--shadow-sm); border-color: var(--c-primary-50); }
.faq summary {
  list-style: none; cursor: pointer;
  font-family: var(--ff-display); font-weight: 700; color: var(--c-text);
  padding: var(--sp-4) 0; position: relative; padding-right: var(--sp-8);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+"; position: absolute; right: 0; top: 50%; transform: translateY(-50%);
  font-size: var(--fs-xl); font-weight: 400; color: var(--c-accent-600); line-height: 1;
  transition: transform var(--transition);
}
.faq details[open] summary::after { content: "\2212"; }
.faq details p { margin: 0 0 var(--sp-4); color: var(--c-text-muted); }

/* Icons */
.icon { width: 18px; height: 18px; flex: 0 0 auto; vertical-align: -3px; }
.icon--sm { width: 14px; height: 14px; }
.icon--lg { width: 22px; height: 22px; }
.with-icon { display: inline-flex; gap: 6px; align-items: center; }
.usp__icon svg { width: 26px; height: 26px; }
.btn svg { width: 18px; height: 18px; }
.card__fav svg { width: 18px; height: 18px; }
/* Nummernsuche: Styling lebt gebündelt weiter unten (eine Reihe, Referenz-
   Layout .search-secondary). Hier bewusst keine Overrides mehr. */
/* ============================================================
   Unterkunfts-Listen & -Karten (frontend-bundle) im Theme-Look
   Markup: .accommodation-list > .accommodation-list__grid
            > article.accommodation-card (BEM .accommodation-card__*)
   Theme-CSS lädt zuletzt -> überschreibt die Skeleton-Defaults.
   ============================================================ */
.accommodation-list { max-width: var(--container); margin: 0 auto; padding: 0 var(--sp-4); }
@media (min-width: 640px) { .accommodation-list { padding: 0 var(--sp-6); } }

.accommodation-list__grid {
  display: grid; grid-template-columns: 1fr; gap: var(--sp-6);
  align-items: stretch; /* alle Karten einer Zeile gleich hoch */
}
@media (min-width: 600px)  { .accommodation-list__grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1000px) { .accommodation-list__grid { grid-template-columns: repeat(3, 1fr); gap: var(--sp-8); } }

.accommodation-card {
  position: relative; display: flex; flex-direction: column;
  height: 100%; /* füllt die (durch align-items:stretch) gleich hohe Grid-Zelle */
  background: #fff; border: 1px solid var(--c-line);
  border-radius: var(--r-lg); overflow: hidden;
  box-shadow: var(--shadow-sm);
  transition: transform var(--transition), box-shadow var(--transition);
}
.accommodation-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }

/* WICHTIG: .accommodation-card__image ist im echten Markup die <figure>-Huelle
   (das <img> steckt darin). Sie darf KEIN height:100% bekommen – sonst frisst das
   Bild die ganze Kartenhoehe und der Inhalt wird auf ~40px gequetscht und per
   overflow abgeschnitten. Die Figure bemisst sich ueber aspect-ratio; object-fit
   gehoert aufs innere <img>. (Skeleton setzt height:200px / height:100% – hier ueberschrieben.) */
.accommodation-card figure,
.accommodation-card__image { margin: 0; position: relative; aspect-ratio: 4/3; width: 100%; height: auto; flex: 0 0 auto; overflow: hidden; background: var(--c-bg-alt); display: block; }
.accommodation-card figure img,
.accommodation-card__image img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 600ms ease; }
.accommodation-card:hover figure img,
.accommodation-card:hover .accommodation-card__image img { transform: scale(1.06); }

.accommodation-card__fav {
  position: absolute; top: var(--sp-3); right: var(--sp-3); z-index: 3;
  width: 38px; height: 38px; border-radius: 50%;
  background: rgba(255,255,255,.92); border: 0; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--c-primary); box-shadow: var(--shadow-sm);
  transition: background var(--transition), transform var(--transition), color var(--transition);
}
.accommodation-card__fav:hover { background: #fff; transform: scale(1.08); }
.accommodation-card__fav-icon { width: 18px; height: 18px; }
.accommodation-card__fav.is-active { color: var(--c-accent); }
.accommodation-card__fav.is-active .accommodation-card__fav-icon { fill: var(--c-accent); }

.accommodation-card__content { display: flex; flex-direction: column; gap: var(--sp-2); padding: var(--sp-5); flex: 1 1 auto; height: auto; min-height: 0; }
.accommodation-card__title { font-size: var(--fs-lg); margin: 0; line-height: 1.25; }
.accommodation-card__title a { color: inherit; }
.accommodation-card__location { font-size: var(--fs-xs); color: var(--c-text-muted); text-transform: uppercase; letter-spacing: .06em; font-weight: 600; margin: 0; }
.accommodation-card__meta, .accommodation-row__meta { font-size: var(--fs-sm); color: var(--c-text-muted); margin: 0; display: flex; flex-wrap: wrap; gap: var(--sp-3); align-items: center; }
.accommodation-card__meta .with-icon, .accommodation-row__meta .with-icon { display: inline-flex; align-items: center; gap: 5px; }
.accommodation-card__meta .icon, .accommodation-row__meta .icon { width: 16px; height: 16px; flex: 0 0 auto; color: var(--c-text-muted); }
/* Badge oben-links (Vorlage .card__badge): ein Badge pro Karte – kleine Pille,
   KEINE volle Leiste. Hohe Spezifitaet + explizite Overrides (right/width/display),
   damit eine evtl. Basis-Regel aus der Layout-CSS (volle Breite) nicht gewinnt. */
.accommodation-card .accommodation-card__badge {
  position: absolute !important; top: var(--sp-3); left: var(--sp-3); right: auto !important; bottom: auto;
  z-index: 3; width: auto !important; max-width: calc(100% - var(--sp-6));
  display: inline-flex !important; align-items: center; line-height: 1.4;
  background: var(--c-accent); color: #fff; font-weight: 700; font-size: var(--fs-xs);
  padding: var(--sp-1) var(--sp-3); border-radius: var(--r-pill);
  letter-spacing: .04em; text-transform: uppercase; box-shadow: var(--shadow-sm);
}
.accommodation-card .accommodation-card__badge--top { background: var(--c-primary); }
.accommodation-card .accommodation-card__badge--lastminute { background: var(--c-danger, #d23f57); }
.accommodation-card__reviews { font-size: var(--fs-sm); color: var(--c-accent-600); font-weight: 700; }
.accommodation-card__reviews .muted { color: var(--c-text-muted); font-weight: 500; }

.accommodation-card__offer { margin-top: var(--sp-1); }
.accommodation-card__offer-badge {
  display: inline-block; background: var(--c-accent); color: #fff;
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: .03em;
  padding: 3px 10px; border-radius: var(--r-pill); text-transform: uppercase;
}
.accommodation-card__discount-badge {
  display: inline-block; background: var(--c-danger); color: #fff;
  font-size: var(--fs-xs); font-weight: 800; padding: 2px 8px; border-radius: var(--r-pill);
}

.accommodation-card__price { margin: var(--sp-2) 0 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px; }
.accommodation-card__price strong { font-family: var(--ff-display); font-weight: 800; color: var(--c-primary); font-size: var(--fs-lg); }
.accommodation-card__price .muted,
.accommodation-card__price-meta { color: var(--c-text-muted); font-weight: 500; font-size: var(--fs-xs); }
.accommodation-card__price-old { color: var(--c-text-muted); text-decoration: line-through; font-size: var(--fs-sm); }

.accommodation-card__features { list-style: none; margin: var(--sp-3) 0 var(--sp-1); padding: 0; display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
/* Die moderne Kachel-Optik liefert feature-chips.css (.card-features__item--icon-only).
   Hier NUR die Markenfarbe für das Icon setzen — KEINE zweite Box, sonst säße eine
   Box in der Chip-Kachel. */
.accommodation-card__features .card-features__icon { color: var(--c-primary); }
.accommodation-card__features .card-features__svg { width: 18px; height: 18px; }
.accommodation-card__features .card-features__initial { font-size: var(--fs-xs); font-weight: 700; }

.accommodation-card__cta { margin-top: auto; align-self: flex-start; }
/* Mobil (einspaltig) braucht der Button nicht ans Karten-Ende geschoben werden
   (margin-top:auto erzeugt bei kurzen Karten einen grossen Leerraum). Fester
   Abstand statt auto. */
@media (max-width: 599px) {
  .accommodation-card__cta { margin-top: var(--sp-4); }
}

/* Pagination / Mehr laden */
.accommodation-pagination { max-width: var(--container); margin: var(--sp-8) auto 0; padding: 0 var(--sp-4); text-align: center; display: flex; flex-direction: column; align-items: center; gap: var(--sp-3); }
.accommodation-pagination__status { color: var(--c-text-muted); font-size: var(--fs-sm); }
#load-more-btn {
  display: inline-flex; align-items: center; justify-content: center;
  padding: var(--sp-3) var(--sp-6); border-radius: var(--r-pill);
  border: 2px solid var(--c-primary); background: transparent; color: var(--c-primary);
  font-weight: 700; font-size: var(--fs-sm); cursor: pointer; font-family: inherit;
  transition: all var(--transition);
}
#load-more-btn:hover:not(:disabled) { background: var(--c-primary); color: #fff; }
#load-more-btn:disabled { opacity: .5; cursor: not-allowed; }
.accommodation-pagination .hidden { display: none; }

/* Zeilen-Layout (mwfm_layout = row) */
.accommodation-list__rows { display: flex; flex-direction: column; gap: var(--sp-5); }
.accommodation-row {
  position: relative; display: grid; grid-template-columns: 1fr;
  background: #fff; border: 1px solid var(--c-line); border-radius: var(--r-lg);
  overflow: hidden; box-shadow: var(--shadow-sm); transition: box-shadow var(--transition);
}
.accommodation-row:hover { box-shadow: var(--shadow-md); }
@media (min-width: 700px) { .accommodation-row { grid-template-columns: 240px 1fr 180px; } }
@media (min-width: 1000px) { .accommodation-row { grid-template-columns: 320px 1fr 220px; } }
.accommodation-row figure { margin: 0; aspect-ratio: 4/3; overflow: hidden; }
.accommodation-row .accommodation-card__image, .accommodation-row img { width: 100%; height: 100%; object-fit: cover; }
.accommodation-row .accommodation-card__content { padding: var(--sp-5); }

/* ============================================================
   Suchformulare (Contao-Formulare 3/4/5/6) im Theme-Look
   Markup: .ce_form.search-box--* > form > .formbody
            > .widget(.widget-text | .widget-submit | .widget-checkbox |
                      .widget-price-range)
   Felder: input.text (place/date/persons), button.submit, fieldset.checkbox_
   container (features), .price-range (zwei number-Inputs).
   ============================================================ */
.search-box { margin: 0 0 var(--sp-6); }
.search-box .formbody { display: flex; flex-direction: column; gap: var(--sp-3); margin: 0; }
.search-box .widget { display: flex; flex-direction: column; gap: 5px; margin: 0; min-width: 0; }
.search-box .widget > label,
.search-box .widget legend,
.search-box .widget-price-range > label,
.search-box .pick__label {
  font-size: var(--fs-xs); font-weight: 700; color: var(--c-text);
  text-transform: uppercase; letter-spacing: .04em; padding: 0;
}
.search-box input.text,
.search-box .price-range input.text {
  width: 100%; height: 46px; padding: 0 var(--sp-3); margin: 0;
  border: 1px solid var(--c-line); border-radius: var(--r-md);
  background: #fff; font: inherit; font-size: 1rem; color: var(--c-text);
  transition: border-color var(--transition), box-shadow var(--transition);
}
.search-box input.text:focus {
  outline: none; border-color: var(--c-primary);
  box-shadow: 0 0 0 3px var(--c-primary-50);
}
.search-box input.text::placeholder { color: var(--c-text-muted); }
.search-box input[readonly] { cursor: pointer; background: #fff; }

/* DER WÄHLER ÜBERNIMMT DIE MASSE DIESER FILTERLEISTE.

   Zeitraum und Reisende sind kein `input`, sondern das Bauteil aus dem
   api-Bundle (`.pick`). Es bringt eigene Vorgaben mit — bewusst, denn es
   läuft auch auf Seiten ohne dieses Theme. Damit es hier nicht neben den
   anderen Feldern auffällt, setzt die Filterleiste die Maße, an denen man
   es sonst sieht: Rundung, Rahmenfarbe, Höhe, Polsterung und Beschriftung.

   DIE TOKENS STEHEN AN `.pick`, NICHT AN `.search-box`. Das Bauteil
   deklariert jedes `--pick-*` an sich selbst; ein Wert am Elternelement
   wird dort wieder überschrieben. `.search-box .pick` trifft dasselbe
   Element mit einer Klasse mehr und gewinnt unabhängig von der
   Ladereihenfolge.

   DIE HÖHE RECHNET WIE `input.text` DARÜBER: feste 46px, keine senkrechte
   Polsterung. `min-height` allein reicht nicht — das Bauteil kommt mit
   seiner eigenen Polsterung auf knapp 50px, und eine Mindesthöhe macht
   ein Feld nie kleiner. Erst die Polsterung auf null bringt beide auf
   dieselbe Zahl. */
.search-box .pick {
  --pick-border-radius: var(--r-md);
  --pick-border-color: var(--c-line);
  --pick-field-padding-y: 0px;
  --pick-field-padding-x: var(--sp-3);
}
.search-box .pick__trigger { min-height: 46px; }
/* Die Beschriftung des Wählers ist kein direktes Kind von `.widget` und
   sitzt deshalb nicht in der Liste oben. Schrift und Farbe kommen von
   dort; Zeilenhöhe und Abstand stellt das Bauteil selbst ein und müssen
   hier auf die Werte der anderen Beschriftungen zurück: 1.3 und 0.5rem
   aus `form label`, dazu die 5px Abstand, die `.widget` zwischen
   Beschriftung und Feld legt. */
.search-box .pick__label {
  line-height: 1.3;
  margin-bottom: calc(var(--sp-2) + 5px);
}

.search-box .widget-submit { margin: 0; }
.search-box .submit {
  display: inline-flex; align-items: center; justify-content: center;
  height: 46px; padding: 0 var(--sp-5); margin: 0;
  border: 1px solid var(--c-primary); border-radius: var(--r-md);
  background: var(--c-primary); color: #fff;
  font: inherit; font-weight: 700; line-height: 1; cursor: pointer; white-space: nowrap;
  transition: background var(--transition), color var(--transition), border-color var(--transition);
}
.search-box .submit:hover { background: var(--c-primary-700); border-color: var(--c-primary-700); }
.search-box button[name="reset"].submit { background: #fff; color: var(--c-primary); }
.search-box button[name="reset"].submit:hover { background: var(--c-primary-50); }

/* Ausstattungsmerkmale (fieldset) + Preisbereich */
.search-box .checkbox_container { border: 0; margin: 0; padding: 0; }
.search-box .checkbox_container legend { margin-bottom: 6px; }
.search-box .price-range { display: flex; align-items: center; gap: var(--sp-2); margin-top: 5px; }
.search-box .price-range__sep { color: var(--c-text-muted); }

/* --- Startseite: Suchleiste im durchgehenden Hero-Band -------------------- */
.search-box--home { max-width: none; margin: 0; padding: var(--sp-8) var(--sp-4) var(--sp-6); background: #1f2937; }
.search-box--home .formbody {
  max-width: 980px; margin: 0 auto;
  background: #fff; border: 1px solid var(--c-line); border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg); padding: var(--sp-4);
}
@media (min-width: 820px) {
  .search-box--home .formbody { flex-direction: row; align-items: flex-end; gap: var(--sp-3); }
  .search-box--home .widget { flex: 1 1 0; }
  .search-box--home .widget-submit { flex: 0 0 auto; }
  .search-box--home .submit { padding: 0 var(--sp-6); }
}

/* --- Suchseite: horizontale Suchbar --------------------------------------- */
.search-box--horizontal .formbody {
  background: #fff; border: 1px solid var(--c-line); border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm); padding: var(--sp-4);
}
@media (min-width: 700px) {
  .search-box--horizontal .formbody { flex-direction: row; align-items: flex-end; gap: var(--sp-3); }
  .search-box--horizontal .widget { flex: 1 1 0; }
  .search-box--horizontal .widget-submit { flex: 0 0 auto; }
}

/* --- Suchseite: Filter-Sidebar links -------------------------------------- */
.search-box--left .formbody {
  background: #fff; border: 1px solid var(--c-line); border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm); padding: var(--sp-5); gap: var(--sp-4);
}
.search-box--left .submit { width: 100%; }

/* Full-Bleed-Grid im Such-Artikel — an ALLEN Breiten (auch mobil), damit der
   Seitenkopf ueberall ueber full-start/full-end die volle Viewport-Breite spannt.
   Aeussere Spacer-Spalten (1fr, min sp-4) zentrieren den Inhalt; KEINE max-width/
   padding am Artikel. Mobil: EINE Content-Spalte (gestapelt). Ab 1000px: 290px-
   Filterspalte + Hauptspalte (Media-Query unten).
   <script>-Knoten sind per UA display:none und stoeren das Grid nicht. */
.mod_article:has(> .search-box--horizontal) {
  display: grid;
  grid-template-columns:
    [full-start] minmax(var(--sp-4), 1fr)
    [content-start] minmax(0, var(--container))
    [content-end] minmax(var(--sp-4), 1fr)
    [full-end];
  row-gap: var(--sp-6);
  align-items: start;
}
/* Seitenkopf ueber die volle Viewport-Breite (an ALLEN Breiten). */
.mod_article:has(> .search-box--horizontal) > .page-header,
.mod_article:has(> .search-box--horizontal) > *:has(.page-header--content) { grid-column: full-start / full-end; }
/* Uebrige Inhalte in der zentrierten Content-Spalte (mobil einspaltig gestapelt). */
.mod_article:has(> .search-box--horizontal) > .search-box--horizontal,
.mod_article:has(> .search-box--horizontal) > .search-box--mobile,
.mod_article:has(> .search-box--horizontal) > .search-box--left,
.mod_article:has(> .search-box--horizontal) > .accommodation-list,
.mod_article:has(> .search-box--horizontal) > .accommodation-pagination { grid-column: content-start / content-end; }

@media (min-width: 1000px) {
  /* Ab 1000px: 290px-Filterspalte + Hauptspalte nebeneinander. */
  .mod_article:has(> .search-box--horizontal) {
    grid-template-columns:
      [full-start] minmax(var(--sp-4), 1fr)
      [content-start] 290px
      [main-start] minmax(0, calc(var(--container) - 290px))
      [content-end] minmax(var(--sp-4), 1fr)
      [full-end];
  }
  /* Horizontale Suchleiste ueber beide Content-Spalten, ueber der Ergebnisliste. */
  .mod_article:has(> .search-box--horizontal) > .search-box--horizontal { grid-column: content-start / content-end; position: relative; z-index: 6; }
  /* Linker Filter in der 290px-Spalte, sticky. */
  .mod_article:has(> .search-box--horizontal) > .search-box--left {
    grid-column: content-start / main-start;
    position: sticky;
    top: calc(var(--header-h) + var(--sp-4));
    align-self: start;
    z-index: 5;
  }
  /* Ergebnisliste + Pagination in der Hauptspalte; padding-left = optischer Spalt zum Filter. */
  .mod_article:has(> .search-box--horizontal) > .accommodation-list { grid-column: main-start / content-end; max-width: none; margin: 0; padding: 0 0 0 var(--sp-6); }
  .mod_article:has(> .search-box--horizontal) > .accommodation-pagination { grid-column: main-start / content-end; padding-left: var(--sp-6); }
  /* Mit Sidebar nur zwei Karten pro Zeile (sieht ruhiger aus) */
  .mod_article:has(> .search-box--horizontal) .accommodation-list__grid { grid-template-columns: 1fr 1fr; }
}

/* --- Responsiv: mobile Suche statt horizontal/links ----------------------- */
.search-box--mobile { display: none; }
@media (max-width: 999px) {
  .search-box--horizontal, .search-box--left { display: none; }
  .search-box--mobile { display: block; }
  .search-box--mobile .formbody {
    background: #fff; border: 1px solid var(--c-line); border-radius: var(--r-lg);
    box-shadow: var(--shadow-sm); padding: var(--sp-4); gap: var(--sp-3);
  }
}

/* ============================================================
   Inhaltsabstand der (Unter-)Seiten
   - Abstand zu Header/Footer (vertikales Padding am Artikel)
   - zentrierte Inhaltsbreite + seitlicher Abstand fuer Standard-Textinhalte
   Full-Bleed-Elemente (Hero, .section, Hero-Suchband) brechen bewusst aus.
   ============================================================ */
.mod_article { padding-block: var(--sp-12); }
/* Startseite: Hero direkt unter dem Header, kein zusaetzlicher Abstand oben/unten */
.mod_article:has(.hero) { padding-block: 0; }

/* Inhaltsseiten (Rechtliches, Service, Widget): KEINE max-width am ARTIKEL selbst
   (sonst wird u. a. der Seitenkopf eingeengt). Stattdessen bekommen die direkten
   Inhalts-Kinder – AUSSER dem Seitenkopf – die Containerbreite + seitlichen
   Abstand. So bleibt der Seitenkopf voll breit, der Textinhalt lesbar zentriert. */
.mod_article.content-page > *:not(.page-header):not(:has(.page-header--content)) {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--sp-4);
}
@media (min-width: 640px) {
  .mod_article.content-page > *:not(.page-header):not(:has(.page-header--content)) { padding-inline: var(--sp-6); }
}

/* Merkzettel: die Wishlist-Bloecke (Zaehler, Liste/Empty, Sammelanfrage-Button)
   gleichmaessig untereinander statt uneinheitlicher Luecken. Leeres Ergebnis-Grid
   nimmt keine Hoehe ein. */
.accommodation-wishlist { display: flex; flex-direction: column; gap: var(--sp-5); }
.accommodation-wishlist > .accommodation-list__grid:not(:has(.accommodation-card)) { display: none; }

/* Standard-Textinhalte: Containerbreite + seitlicher Abstand.
   Ausgenommen: Elemente, die eine eigene Full-Bleed-Section/Hero mitbringen,
   sowie die Such-Formulare (eigene Breitenlogik).
   Hinweis: Contao 5.3 verwendet die modernen Template-Klassen .content-*
   (z. B. .content-text, .content-html). Die alten .ce_*-Klassen werden
   ebenfalls weiter unterstuetzt, falls aelteren Templates verwendet werden. */
.mod_article > .ce_text:not(:has(.section)):not(:has(.hero)),
.mod_article > .ce_html:not(:has(.section)):not(:has(.hero)),
.mod_article > .ce_headline,
.mod_article > .ce_form:not(.search-box),
.mod_article > .ce_hyperlink,
.mod_article > .ce_list,
.mod_article > .ce_table,
.mod_article > .ce_accordionStart,
.mod_article > .ce_text:has(.faq),
.mod_article > .ce_html:has(.faq),
.mod_article > .content-text:not(:has(.section)):not(:has(.hero)),
.mod_article > .content-html:not(:has(.section)):not(:has(.hero)),
.mod_article > .content-headline,
.mod_article > .content-form:not(.search-box),
.mod_article > .content-hyperlink,
.mod_article > .content-list,
.mod_article > .content-table,
.mod_article > .content-accordion-start,
.mod_article > .content-accordion-single,
.mod_article > .content-text:has(.faq),
.mod_article > .content-html:has(.faq) {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--sp-4);
}

/* Vertikaler Abstand (oben + unten) fuer Text-Inhaltselemente im Artikel, damit
   sie nicht an angrenzende Elemente (Seitenkopf, weitere Inhalte) stossen. */
.mod_article > .content-text,
.mod_article > .ce_text {
  margin-block: var(--sp-6);
}

/* Hinweis: Der Such-Artikel hat bewusst KEINE max-width/margin/padding mehr.
   Zentrierung des Inhalts + voller Seitenkopf laufen komplett ueber das
   Full-Bleed-Grid (siehe oben) — an allen Breiten, also auch mobil. */

/* ============================================================
   Startseite-Hero im "Crystal"-Look (ueberschreibt frueheres Hero-Band)
   Banner-Bild liegt HINTER Headline + Suchformular + Nummernsuche;
   die beiden Such-Boxen sind Glas-Karten darauf.
   ============================================================ */
.mod_article:has(.hero) { position: relative; padding-block: 0; }
.mod_article:has(.hero)::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 900px; z-index: 0;
  background:
          linear-gradient(180deg, rgba(20,30,50,.52) 0%, rgba(20,30,50,.18) 42%, rgba(20,30,50,.55) 100%),
          url("https://images.unsplash.com/photo-1507525428034-b723cf961d3e?auto=format&fit=crop&w=2000&q=70") center/cover no-repeat;
}
@media (min-width: 820px) { .mod_article:has(.hero)::before { height: 680px; } }
.mod_article:has(.hero) > * { position: relative; z-index: 1; }

/* Hero-Text: transparent (Bild kommt vom Banner), hell, oben ausgerichtet */
.hero { background: none; min-height: 0; align-items: flex-start; padding: var(--sp-16) 0 var(--sp-6); }
@media (min-width: 900px) { .hero { min-height: 0; padding: var(--sp-20) 0 var(--sp-8); } }

/* Suchformular: weisse Karte auf dem Hero – exakt wie Vorlage (.search-widget):
   weisser Grund, dunkler Text, Labels in gedaempftem Grau (#5B6779). */
.search-box--home { background: none; max-width: none; margin: 0; padding: 0 var(--sp-4) var(--sp-5); }
.search-box--home .formbody {
  max-width: 1100px; margin: 0 auto;
  background: #fff; color: var(--c-text);
  border: 0;
  border-radius: var(--r-lg); box-shadow: var(--shadow-lg);
  padding: var(--sp-5);
}
.search-box--home .widget > label,
.search-box--home .widget legend,
.search-box--home .pick__label { color: var(--c-text-muted); }

/* Nummernsuche = MWFM-Variante des Referenz-Bausteins .search-secondary.
   Das EINE-Reihe-Layout (Label links, Glas-Zeile rechts, Zeile max 520px),
   die Glasoptik und die weisse Schrift kommen komplett aus .search-secondary
   (oben). Hier nur: Breite/Ausrichtung wie die Suchbox darueber + die paar
   MWFM-spezifischen Ergaenzungen (Lupe vor der Headline, Feld-Wrapper). */
.mwfm-number-search { max-width: var(--container); margin-inline: auto; padding: 0 var(--sp-4) var(--sp-16); }
/* Mobil: kleiner Abstand unter der Nummernsuche, damit die weissen USP-Kacheln
   direkt anschliessen und kein grosser leerer Sand-Bereich im Bild bleibt. */
@media (max-width: 819px) { .mwfm-number-search { padding-bottom: var(--sp-6); } }
/* Headline ist ein <h2> -> Standard-Margin entfernen. Farbe explizit WEISS
   erzwingen: das h2 erbt sonst die dunkle Default-Ueberschriftsfarbe statt das
   Weiss von .search-secondary (Hero-Band). */
.mwfm-number-search .search-secondary__label,
.mwfm-number-search__headline { margin: 0; color: #fff; }
/* Weisse Hero-Texte ueber dem Bild immer lesbar halten (Schlagschatten), damit
   sie auf hellen Bildstellen (z. B. Sand) mobil nicht "im Bild verschwinden". */
.mod_article:has(.hero) .hero :is(h1, h2, p),
.mwfm-number-search__headline,
.mwfm-number-search .search-secondary__label {
  text-shadow: 0 1px 4px rgba(10, 20, 35, .6);
}
/* Lupen-Icon vor der Headline: im Headline-Zweig rendert das Template kein SVG. */
.mwfm-number-search__headline::before {
  content: ""; flex: 0 0 auto; width: 16px; height: 16px; background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M21 21l-5-5'/%3E%3C/svg%3E") center/contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M21 21l-5-5'/%3E%3C/svg%3E") center/contain no-repeat;
}
/* Das Input sitzt in einem Wrapper (Dropdown-Anker) statt direkt in der Zeile:
   der Wrapper nimmt den freien Platz, das Input fuellt ihn. */
.mwfm-number-search__field { position: relative; flex: 1 1 auto; min-width: 0; }
.mwfm-number-search__input { width: 100%; }

/* Autocomplete-Vorschlaege: solide weisse Karte, dunkle Schrift, ueber der
   Objektliste. Der Hero gibt jedem direkten Kind z-index:1; zusaetzlich kapselt
   backdrop-filter das Dropdown in einen eigenen Stacking-Context. Daher das
   CE-Wrapper-Element der Suchbox/Nummernsuche anheben, sonst verschwinden die
   Vorschlaege hinter den Karten (und erbten zudem die helle Hero-Schrift). */
.mod_article:has(.hero) > *:has(.search-box--home) { z-index: 30; }
.mod_article:has(.hero) > *:has(.mwfm-number-search) { z-index: 20; }
/* Autocomplete-Dropdown: solide weisse Karte, dunkle Schrift. Klassen bewusst
   ohne mwfm-Präfix (suggest-pop-Familie), da das <ul> ins <body> portiert wird. */
.suggest-pop {
  z-index: 9999;
  background: #fff;
  color: var(--c-text);
  -webkit-backdrop-filter: none; backdrop-filter: none;
}
.suggest-pop__item,
.suggest-pop__title { color: var(--c-text); }
.suggest-pop__num { color: var(--c-text-muted); }
/* Ins <body> portiertes Dropdown (per main.js positioniert) – frei vom
   Stacking-Context der Glas-Leiste. */
.suggest-pop { position: absolute; }

/* Such-Buttons in Akzentfarbe (Orange) wie im Layout */
.search-box .submit { background: var(--c-accent); border-color: var(--c-accent); color: #fff; }
.search-box .submit:hover { background: var(--c-accent-600); border-color: var(--c-accent-600); }
.search-box button[name="reset"].submit { background: #fff; color: var(--c-primary); border-color: var(--c-line); }

/* ============================================================
   Sticky Footer: Seite immer mind. Viewport-Hoehe, Footer unten —
   auch wenn der Main-Inhalt kurz ist. Greift fuer beide moeglichen
   Contao-Strukturen (Footer in #wrapper ODER direkt unter <body>).
   ============================================================ */
html { min-height: 100%; }
/* position:sticky (Buchungsbox) braucht: KEIN Vorfahr mit overflow:hidden/auto/scroll.
   Etliche Layout-CSS setzen body{overflow-x:hidden} -> das bricht Sticky. `clip`
   verhindert horizontales Scrollen, erzeugt aber KEINEN Scroll-Container. */
html, body { overflow-x: clip; }
body { min-height: 100vh; display: flex; flex-direction: column; }
body > #wrapper { flex: 1 0 auto; display: flex; flex-direction: column; min-width: 0; }
#wrapper > #container, body > #container { flex: 1 0 auto; min-width: 0; }
#main { flex: 1 0 auto; min-width: 0; }
#footer { flex: 0 0 auto; }

/* ============================================================
   Blaue Seitentitel-Leiste (#46) auf Innenseiten.
   Kommt aus dem Header-Modul ({{page::title}}). Auf der Startseite
   (.hero) und der Detailseite (.accommodation__headline) ausgeblendet,
   da diese ihre eigene Kopf-Optik mitbringen.
   ============================================================ */
.page-header { background: var(--c-primary); color: #fff; }
.page-header .container { padding-block: var(--sp-10); }
.page-header__title { color: #fff; margin: 0; font-size: var(--fs-2xl); letter-spacing: -.01em; }
/* Modul-Leiste entfaellt: der Seitenkopf ist jetzt ein Element je Artikel
   (rsce_mwfm_page_header). Start (.hero) und Detail haben ihre eigene Kopf-Optik. */

/* Anzahl-Zeile über der Ergebnisliste der Suchseite. */
.accommodation-list__count { margin: 0; font-size: var(--fs-sm); color: var(--c-text-muted); }
/* Kopfzeile der Ergebnisliste: Trefferzahl links, Sortier-Select rechts. */
.accommodation-list__toolbar {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: var(--sp-2) var(--sp-4); margin: 0 0 var(--sp-4);
}
.accommodation-list__sort { display: inline-flex; align-items: center; gap: var(--sp-2); }
.accommodation-list__sort-label { font-size: var(--fs-sm); color: var(--c-text-muted); white-space: nowrap; }
.accommodation-list__sort-select {
  appearance: none; -webkit-appearance: none;
  font: inherit; font-size: var(--fs-sm); color: var(--c-text);
  background: #fff; border: 1px solid var(--c-line); border-radius: var(--r-sm);
  padding: var(--sp-2) calc(var(--sp-6) + 4px) var(--sp-2) var(--sp-3);
  cursor: pointer; line-height: 1.2;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right var(--sp-3) center;
}
.accommodation-list__sort-select:hover { border-color: var(--c-primary); }
.accommodation-list__sort-select:focus-visible { outline: 2px solid var(--c-primary); outline-offset: 1px; }

/* ============================================================
   Picker-Popups (#37): an die Theme-Linienfarbe angleichen. Die
   Kalender-/Personen-/Ortspicker-CSS der Bundles liest --border-color
   (mit Fallback) -> hier auf die Theme-Variable mappen, damit Raender
   und Trennlinien zum restlichen Design passen.
   ============================================================ */
:root { --border-color: var(--c-line); }

/* ============================================================
   Picker-Popups an das Fewo-Design angleichen (#37).
   Die Aktions-Buttons der Picker sind im Bundle nur `.btn` mit
   Modifier (--clear/--cancel/--apply), aber ohne Theme-Regel ->
   sie rendern weiss (Basis-.btn ist transparent). Hier branden:
   Apply = Akzent (orange, wie "Suchen"/"Anzeigen"), Cancel/Clear = Ghost.
   ============================================================ */
.btn--apply { background: var(--c-accent); color: #fff; box-shadow: 0 6px 16px rgba(232,159,60,.30); }
.btn--apply:hover:not(:disabled) { background: var(--c-accent-600); color: #fff; }
.btn--apply:disabled { opacity: .5; cursor: not-allowed; box-shadow: none; }
.btn--cancel, .btn--clear { background: #fff; color: var(--c-primary); border-color: var(--c-line); }
.btn--cancel:hover, .btn--clear:hover { background: var(--c-primary); color: #fff; border-color: var(--c-primary); }

/* Personenpicker +/- Stepper sichtbar machen (waren fast weiss). Hoehere
   Spezifitaet als die Bundle-Regel `.personpicker__control button`, damit es
   unabhaengig von der Ladereihenfolge greift. */
.personpicker .personpicker__control button {
  border: 1px solid var(--c-primary);
  background: #fff;
  color: var(--c-primary);
}
.personpicker .personpicker__control button:hover:not(:disabled) { background: var(--c-primary); color: #fff; }
.personpicker__actions { margin-top: var(--sp-4); }
.personpicker__actions .btn--apply { min-width: 200px; }

/* ============================================================
   Kalender-Modal (#37): auf Desktop nicht mehr ueber die ganze Breite.
   Im Bundle ist die Desktop-Breite des Dialogs auskommentiert -> faellt
   auf width:100% zurueck. Hier mit hoeherer Spezifitaet nachziehen.
   ============================================================ */
@media (min-width: 820px) {
  .calendar-modal .calendar-modal__dialog {
    width: min(880px, 92vw);
    max-width: 880px;
    /* KEINE max-height – der Datepicker wird so gross wie noetig (zwei Monate
       ohne Innen-Scrollbalken). height bleibt auto. */
    margin: auto;
    border-radius: var(--r-lg);
  }
}

/* ============================================================
   Startseiten-/Layout-Feinschliff (Design-Vorlage)
   ============================================================ */
/* Lieblingswohnungen als ein abgesetztes Band (Kopf + Liste + Button-Fuss).
   Die Liste traegt per CE-cssID die Klasse `featured-list`. Da `.accommodation-list`
   max-width-zentriert ist, wuerde ein einfacher Hintergrund nur die Spalte faerben
   und auf breiten Viewports einen weissen Streifen zwischen den beiden alt-Baendern
   lassen. box-shadow (100vw Spread) + clip-path ziehen die Alt-Flaeche full-bleed bis
   zum Viewport-Rand, ohne das Layout zu veraendern. */
/* Naht zwischen Kopf-Band und Liste schliessen: ein nach unten versetzter,
   blur-/spread-loser Alt-Schatten am Kopf fuellt einen evtl. schmalen weissen
   Spalt (CE-/Section-Margin) bis zur Liste. Liegt UNTER der nachfolgenden Liste
   und unterhalb des Kopf-Inhalts -> ueberdeckt keinen Text. */
.section--featured-head {
  padding-bottom: 0;
  box-shadow: 0 var(--sp-8) 0 var(--c-bg-alt);
}
/* Section hat padding-bottom:0 -> das margin-bottom des letzten Kindes (.lead
   ODER ein anderes Element) kollabiert sonst aus der getoenten Section heraus
   und zeigt einen weissen Body-Streifen vor der Lieblings-Liste. Sowohl .lead
   gezielt als auch generisch das letzte Kind neutralisieren (robust gegen
   geaenderte Reihenfolge / zusaetzliche p-Tags). */
.section--featured-head .lead { margin-bottom: 0; }
.section--featured-head > .container > :last-child,
.section--featured-head .container > :last-child { margin-bottom: 0; }
.accommodation-list.featured-list {
  background: var(--c-bg-alt);
  box-shadow: 0 0 0 100vw var(--c-bg-alt);
  clip-path: inset(0 -100vw);
  padding-top: var(--sp-8);
}
.section--featured-foot { padding-top: var(--sp-8); }
/* Der Lieblings-Kopf laeuft als rsce_mwfm_section (.section--alt.section--pb0),
   nicht als .section--featured-head. Deshalb hier dieselbe Bruecke: graue Flaeche
   sp-8 nach unten + margin des letzten Kindes (Teaser) neutralisieren, sonst
   entsteht ein weisser Streifen zwischen Kopf und featured-list. Auf die
   Startseite beschraenkt. */
.mod_article:has(.hero) .section--alt.section--pb0 { box-shadow: 0 var(--sp-8) 0 var(--c-bg-alt); }
.mod_article:has(.hero) .section--alt.section--pb0 .container > :last-child { margin-bottom: 0; }
/* Generischer Section-Block (rsce_mwfm_section): Abstaende & Ausrichtung */
.section--pt0 { padding-top: 0; }
.section--pb0 { padding-bottom: 0; }
.section-block--center { max-width: 60ch; margin: 0 auto; text-align: center; }
.section-block__cta { margin: var(--sp-4) 0 0; }

/* Home-Suche buendig mit dem Hero-Container */
.search-box--home { max-width: var(--container); margin-inline: auto; }
.search-box--home .formbody { max-width: none; margin: 0; }

/* Waehrungs-Select schmaler + gleicher Pfeil wie Sprache (Bundle-Inline-Style ueberschreiben) */
.util-select--currency .currency-changer__select { -webkit-appearance: none; appearance: none; min-width: 0; width: auto; padding: 0 2px; background-image: none; }
/* Topbar-Selects nicht hoch: min-height der Bundle/Browser-Defaults zuruecksetzen */
.util-select select,
.util-select--currency .currency-changer__select { min-height: 0; height: auto; line-height: 1.3; }
.util-select--currency .currency-changer__form { min-height: 0; }

/* Navigation – animierter Unterstrich: diese Kondensat-Regel war ein Duplikat
   zu der ausfuehrlichen Definition weiter oben (.site-nav__menu a::after etc.)
   und hat sie durch ihre spaetere Position in der Datei ueberschrieben –
   insbesondere mit `bottom: -2px` (Linie lag ausserhalb des sichtbaren
   Bereichs des Containers) und einer reduzierten Aktiv-/Trail-Selektorliste,
   die die Contao-5-Markups `li.active > a` / `li.trail > a` nicht abdeckte.
   Bewusst nur die Farbgebung des aktiven/gehoverten Eintrags hier behalten –
   die Unterstrich-Geometrie und -Auslosung gehoert in die kanonische Regel
   oben (Zeile ~1061). */
.site-nav__menu a:hover,
.site-nav__menu a.active,
.site-nav__menu li.active > a,
.site-nav__menu li.trail > a,
.site-nav__menu strong { color: var(--c-primary); }

/* Page-Header (blaues Band): Breadcrumb + Teaser */
.page-header__crumb { display: block; color: rgba(255,255,255,.8); font-size: var(--fs-sm); margin-bottom: var(--sp-2); }
.page-header__crumb a { color: rgba(255,255,255,.8); text-decoration: none; }
.page-header__crumb a:hover { color: #fff; }
/* Contao-Breadcrumb-Modul im (dunklen) Page-Header – weiß auf Blau. */
.page-header__crumb .mod_breadcrumb ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.page-header__crumb .mod_breadcrumb li { display: inline-flex; align-items: center; gap: var(--sp-2); color: rgba(255,255,255,.8); }
.page-header__crumb .mod_breadcrumb li:not(:last-child)::after { content: "/"; color: rgba(255,255,255,.45); }
.page-header__crumb .mod_breadcrumb a { color: rgba(255,255,255,.8); text-decoration: none; }
.page-header__crumb .mod_breadcrumb a:hover { color: #fff; }
.page-header__crumb .mod_breadcrumb .last,
.page-header__crumb .mod_breadcrumb strong { color: #fff; font-weight: 600; }
.page-header__teaser { color: rgba(255,255,255,.85); margin: var(--sp-3) 0 0; max-width: 70ch; font-size: var(--fs-md); }
.page-header__teaser:empty { display: none; }

/* ============================================================
   Kontaktseite (rsce_mwfm_contact): 2 Spalten – Formular links,
   Info-Block (Direkter Draht) + FAQ rechts. Vorlage: kontakt.html.
   ============================================================ */
.contact-grid { display: grid; grid-template-columns: 1fr; gap: var(--sp-8); align-items: start; }
@media (min-width: 860px) { .contact-grid { grid-template-columns: 1fr 1fr; gap: var(--sp-12); } }
.contact-form h2, .contact-info__title { margin: 0 0 var(--sp-5); }
/* Eingebettetes Contao-Formular (per insert_content) im Kontakt-Look. */
.contact-form .formbody { display: grid; gap: var(--sp-4); }
.contact-form .widget label { display: block; font-weight: 600; margin-bottom: var(--sp-1); }
.contact-form input.text, .contact-form textarea, .contact-form select {
  width: 100%; padding: var(--sp-3); border: 1px solid var(--c-line);
  border-radius: var(--r-sm); font: inherit; font-size: 16px; background: #fff;
}
.contact-form textarea { min-height: 150px; resize: vertical; }
.contact-form .widget-submit { margin-top: var(--sp-2); }
.contact-form .submit {
  background: var(--c-accent); border: 1px solid var(--c-accent); color: #fff;
  padding: var(--sp-3) var(--sp-6); border-radius: var(--r-pill, 999px);
  font-weight: 700; cursor: pointer;
}
.contact-form .submit:hover { background: var(--c-accent-600); border-color: var(--c-accent-600); }
/* Datenschutz-/Consent-Checkbox in Anfrage- & Kontaktformularen.
   Contao rendert <fieldset class="checkbox_container"> mit <input class="checkbox">
   + <label> – also fieldset-Rahmen weg, Checkbox + Label sauber ausrichten und
   den Input als Custom-Checkbox mit Haken stylen (die Klasse sitzt am <input>,
   nicht an einem Wrapper). Bewusst NUR in .booking-form/.contact-form, damit die
   Filter-Checkboxen der Such-Sidebar unberuehrt bleiben. */
.booking-form .widget-checkbox,
.contact-form .widget-checkbox { font-size: var(--fs-sm); color: var(--c-text-muted); }
.booking-form .widget-checkbox .checkbox_container,
.contact-form .widget-checkbox .checkbox_container { border: 0; margin: 0; padding: 0; }
.booking-form .widget-checkbox .checkbox_container > span,
.booking-form .widget-checkbox > span,
.contact-form .widget-checkbox .checkbox_container > span,
.contact-form .widget-checkbox > span { display: flex; align-items: flex-start; gap: var(--sp-3); }
.booking-form .widget-checkbox label,
.contact-form .widget-checkbox label { display: block; font-weight: 400; line-height: 1.45; margin: 0; }
.booking-form .widget-checkbox input[type="checkbox"],
.contact-form .widget-checkbox input[type="checkbox"] {
  appearance: none; -webkit-appearance: none;
  width: 22px; height: 22px; flex: 0 0 auto; margin: 1px 0 0;
  border: 2px solid var(--c-line); border-radius: 5px;
  background: #fff; cursor: pointer; position: relative;
  transition: all var(--transition);
}
.booking-form .widget-checkbox input[type="checkbox"]:hover,
.contact-form .widget-checkbox input[type="checkbox"]:hover { border-color: var(--c-primary); }
.booking-form .widget-checkbox input[type="checkbox"]:checked,
.contact-form .widget-checkbox input[type="checkbox"]:checked { background: var(--c-primary); border-color: var(--c-primary); }
.booking-form .widget-checkbox input[type="checkbox"]:checked::after,
.contact-form .widget-checkbox input[type="checkbox"]:checked::after {
  content: ""; position: absolute; left: 6px; top: 2px;
  width: 6px; height: 11px; border: solid #fff; border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.booking-form .widget-checkbox input[type="checkbox"]:focus-visible,
.contact-form .widget-checkbox input[type="checkbox"]:focus-visible { outline: 3px solid var(--c-primary-50); outline-offset: 2px; }
.booking-form .widget-checkbox a,
.contact-form .widget-checkbox a { color: var(--c-primary); text-decoration: underline; }
.contact-info { background: var(--c-foam); border-radius: var(--r-lg); padding: var(--sp-6); }
.contact-info__row { display: flex; gap: var(--sp-4); align-items: flex-start; padding: var(--sp-3) 0; }
.contact-info__row + .contact-info__row { border-top: 1px solid var(--c-line); }
.contact-info__icon {
  flex: 0 0 auto; width: 44px; height: 44px; border-radius: 50%; background: #fff;
  color: var(--c-primary); display: inline-flex; align-items: center; justify-content: center;
}
.contact-info__icon svg { width: 22px; height: 22px; }
.contact-info__body strong { display: block; }
.contact-info__text { color: var(--c-text-muted); font-size: var(--fs-sm); margin-top: 2px; }
.contact-info__text a { color: inherit; }
.contact-faq {
  margin-top: var(--sp-6); padding: var(--sp-5); border: 1px solid var(--c-line);
  border-radius: var(--r-lg); background: #fff;
}
.contact-faq h4 { margin: 0 0 var(--sp-2); }
.contact-faq__item { font-size: var(--fs-sm); color: var(--c-text-muted); margin: 0 0 var(--sp-2); }
.contact-faq__item:last-child { margin-bottom: 0; }

/* ============================================================
   Detailseite (Objekt-Reader): 2 Spalten – Inhalt links, Buchungs-
   karte rechts (sticky). Greift nur auf der Reader-Seite (erkennbar
   an .accommodation__headline). Die Fewo-Reader-Elemente sind einzelne,
   gestapelte Content-Elemente; sie werden hier per Grid platziert.
   Titel + Galerie volle Breite, Buchungsbox in die rechte Spalte.
   ============================================================ */
/* Der Reader-Artikel bekommt im Dump die Klasse .detail-layout (tl_article.cssID),
   damit das Grid zuverlässig greift – unabhängig von :has()-Erkennung. Die
   Reader-Content-Elemente sind die direkten Grid-Items. */
/* Container: Reader-Inhalte klatschen sonst an die Fensterränder (die Reader-
   Elemente bringen kein .container mit). Breite/Padding wie .container. */
.mod_article.detail-layout { display: block; max-width: var(--container); margin-inline: auto; padding: var(--sp-8) var(--sp-4) 0; }
@media (min-width: 640px) { .mod_article.detail-layout { padding: var(--sp-8) var(--sp-6) 0; } }
@media (min-width: 980px) {
  .mod_article.detail-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 360px;
    column-gap: var(--sp-12);
    row-gap: var(--sp-8);
    align-items: start;
    /* Wichtig fuer position:sticky der Buchungsbox: kein Clipping erzwingen. */
    overflow: visible;
  }
  .mod_article.detail-layout > * { grid-column: 1; min-width: 0; }
  /* Breadcrumb + Titel + Galerie über die volle Breite (Reihen 1–3). */
  .mod_article.detail-layout > *:has(.mod_breadcrumb),
  .mod_article.detail-layout > .mod_breadcrumb,
  .mod_article.detail-layout > *:has(.accommodation__headline),
  .mod_article.detail-layout > .accommodation__headline,
  .mod_article.detail-layout > *:has(.accommodation-detail__gallery),
  .mod_article.detail-layout > .accommodation-detail__gallery {
    grid-column: 1 / -1;
  }
  /* Buchungsformular: rechte Spalte, sticky über die Inhaltshöhe. Start
     Reihe 4 – also UNTER Breadcrumb (1), Titel/Objekt-Kopf (2), Galerie
     (3); Galerie + Titel spannen weiterhin über volle Breite. */
  .mod_article.detail-layout > *:has(.accommodation-detail__booking-box),
  .mod_article.detail-layout > .accommodation-detail__booking-box {
    grid-column: 2;
    /* Nur über die tatsächlichen Inhaltszeilen spannen (Breadcrumb=1,
       Kopf=2, Galerie=3, dann linke Spalte: Fakten=4 … Bewertungen=9 →
       Endlinie 10). Ein zu großer Endwert erzeugt leere Zeilen-Tracks,
       deren row-gap als großer Leerraum NACH den Bewertungen sichtbar
       wird. */
    grid-row: 4 / 10;
    position: sticky;
    top: var(--sp-6);
    align-self: start;
  }
}
/* Breadcrumb-Optik (Contao mod_breadcrumb) auf der Detailseite. Eng an den Titel:
   der Breadcrumb-Block zieht sich per negativer Margin näher an die H1 (das
   row-gap des Grids würde sonst zu viel Luft lassen). */
.mod_article.detail-layout .mod_breadcrumb { margin: 0; }
/* Breadcrumb auf der Detailseite: positiver Abstand zum Folgeelement
   (Titel/Objekt-Kopf). Der frueher genutzte negative calc()-Wert hat den
   Titel aktiv nach oben gezogen, sodass es optisch nicht zueinander stand. */
.mod_article.detail-layout > *:has(.mod_breadcrumb),
.mod_article.detail-layout > .mod_breadcrumb { margin-bottom: var(--sp-4); }
.mod_article.detail-layout .accommodation__headline { margin-top: 0; }
.mod_article.detail-layout .mod_breadcrumb ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--sp-2); font-size: var(--fs-sm); color: var(--c-text-muted); }
.mod_article.detail-layout .mod_breadcrumb li { display: inline-flex; align-items: center; gap: var(--sp-2); }
.mod_article.detail-layout .mod_breadcrumb li:not(:last-child)::after { content: "/"; color: var(--c-line); }
.mod_article.detail-layout .mod_breadcrumb a { color: var(--c-text-muted); text-decoration: none; }
.mod_article.detail-layout .mod_breadcrumb a:hover { color: var(--c-primary); }

/* ============================================================
   Detailseite – Galerie (Fewo .accommodation-detail__gallery) wie Vorlage:
   1 großes Bild links + Thumbs rechts. Leere Slots (.figure--dummy) ausblenden,
   damit bei < 5 Bildern keine schwarzen Kästen erscheinen.
   ============================================================ */
.accommodation-detail__gallery { margin: 0 0 var(--sp-6); }
/* Stage-Layout mit erhoehter Spezifitaet + !important, weil das gleiche
   Layout auch im Twig-Template inline definiert ist und Browser-/Contao-
   Output-Filter den <style>-Block im Template manchmal stripen oder
   Skeleton-Defaults reingrätschen. */
.accommodation-detail__gallery .accommodation-detail__gallery-stage,
.accommodation-detail__gallery-stage {
  position: relative;
  display: grid !important;
  grid-template-columns: 2fr 1fr 1fr !important;
  grid-template-rows: 1fr 1fr !important;
  grid-auto-rows: 1fr;
  gap: var(--sp-2);
  height: clamp(280px, 40vw, 460px) !important;
  border-radius: var(--r-lg);
  overflow: hidden;
}
.accommodation-detail__gallery-stage-item {
  overflow: hidden;
  border-radius: var(--r-sm);
  background: var(--c-bg-alt);
  min-width: 0;   /* Grid-Items duerfen nicht ueber ihre fr-Spalte wachsen */
  min-height: 0;
}
.accommodation-detail__gallery-stage-item figure,
.accommodation-detail__gallery-stage-item picture {
  width: 100%; height: 100%; margin: 0; display: block;
}
.accommodation-detail__gallery-stage-item img {
  width: 100% !important;
  height: 100% !important;
  object-fit: cover !important;
  display: block;
}
.accommodation-detail__gallery-stage-item--main { grid-column: 1 !important; grid-row: 1 / span 2 !important; }

/* Mobil: Das 3-Spalten-Stage-Grid (2fr 1fr 1fr) quetscht das Hauptbild in eine
   schmale, hohe Zelle -> ein Landschaftsbild wird zum Hochformat beschnitten
   ("halb abgeschnitten"). Auf schmalen Viewports daher EIN einspaltiges Bild im
   4:3-Querformat; die weiteren Bilder oeffnet der User ueber "Bildergalerie
   oeffnen"/Foto-Zaehler (Overlay). */
@media (max-width: 600px) {
  .accommodation-detail__gallery .accommodation-detail__gallery-stage,
  .accommodation-detail__gallery-stage {
    grid-template-columns: 1fr !important;
    grid-template-rows: auto !important;
    height: auto !important;
    aspect-ratio: 4 / 3;
  }
  .accommodation-detail__gallery-stage-item:not(.accommodation-detail__gallery-stage-item--main) {
    display: none !important;
  }
  .accommodation-detail__gallery-stage-item--main {
    grid-column: 1 !important;
    grid-row: auto !important;
  }
}

/* Overlay-Grid (Vollbild-Galerie nach Klick auf Stage / Foto-Zaehler) –
   im Twig liegt das CSS inline, aber wir spiegeln es hier mit !important,
   damit die Tiles auf jeden Fall ein 4:3-Raster bekommen und die Bilder
   nicht in Original-Ratio nebeneinander stehen. */
.accommodation-detail__gallery-overlay--grid .accommodation-detail__gallery-grid-content,
.accommodation-detail__gallery-grid-content {
  display: grid !important;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)) !important;
  gap: 8px;
  width: min(1400px, 100%);
  padding: 0 24px 24px;
  box-sizing: border-box;
  align-content: start;
}
.accommodation-detail__gallery-grid-tile {
  aspect-ratio: 4 / 3 !important;
  border-radius: var(--r-md);
  overflow: hidden;
  cursor: pointer;
  background: #222;
  min-width: 0;
}
.accommodation-detail__gallery-grid-tile figure,
.accommodation-detail__gallery-grid-tile picture {
  width: 100%; height: 100%; margin: 0; display: block;
}
.accommodation-detail__gallery-grid-tile img {
  width: 100% !important;
  height: 100% !important;
  object-fit: cover !important;
  display: block;
}
@media (max-width: 768px) {
  .accommodation-detail__gallery-grid-content {
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)) !important;
    gap: 4px;
    padding: 0 12px 12px;
  }
}
/* Leere Bild-Slots als heller Platzhalter mit Bild-Icon (statt schwarzer Kachel),
   damit das Raster bei < 5 Bildern vollständig bleibt. */
.accommodation-detail__gallery-stage-item .figure--dummy {
  width: 100%; height: 100%; background: var(--c-bg-alt);
  display: flex; align-items: center; justify-content: center;
}
.accommodation-detail__gallery-stage-item .figure--dummy::after {
  content: ""; width: clamp(28px, 5vw, 46px); height: clamp(28px, 5vw, 46px);
  background: var(--c-text-muted); opacity: .35;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='5' width='18' height='14' rx='2'/%3E%3Ccircle cx='9' cy='11' r='2'/%3E%3Cpath d='M3 17l5-5 4 4 5-5 4 4'/%3E%3C/svg%3E") center/contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='5' width='18' height='14' rx='2'/%3E%3Ccircle cx='9' cy='11' r='2'/%3E%3Cpath d='M3 17l5-5 4 4 5-5 4 4'/%3E%3C/svg%3E") center/contain no-repeat;
}
.accommodation-detail__gallery-cta,
.accommodation-detail__gallery-count {
  position: absolute; z-index: 2; top: var(--sp-3);
  display: inline-flex; align-items: center; gap: 6px;
  padding: var(--sp-1) var(--sp-3); border-radius: var(--r-pill);
  font-size: var(--fs-xs); font-weight: 700; line-height: 1.4;
}
.accommodation-detail__gallery-cta { left: var(--sp-3); background: #fff; color: var(--c-text); border: 0; cursor: pointer; box-shadow: var(--shadow-sm); }
.accommodation-detail__gallery-count { right: var(--sp-3); background: rgba(0,0,0,.6); color: #fff; }

/* ============================================================
   Detailseite – Buchungsbox als Karte (rechte Spalte, sticky kommt aus dem Grid).
   Buttons .btn--book / .btn--request bekommen Look (primär / sekundär).
   ============================================================ */
.accommodation-detail__booking-box {
  background: #fff; border: 1px solid var(--c-line); border-radius: var(--r-lg);
  box-shadow: var(--shadow-md); padding: var(--sp-6);
}
.accommodation-detail__booking-box-header { margin-bottom: var(--sp-4); }
.accommodation-detail__booking-box-title { margin: 0 0 var(--sp-1); font-size: var(--fs-lg); }
.accommodation-detail__booking-box-from-price { display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--sp-1) var(--sp-2); }
.accommodation-detail__booking-box-from-price.hidden { display: none; }
.accommodation-detail__booking-box-from-price-value { font-family: var(--ff-display); font-size: var(--fs-2xl); color: var(--c-primary); font-weight: 800; }
.accommodation-detail__booking-box-from-price-label,
.accommodation-detail__booking-box-from-price-note { color: var(--c-text-muted); font-size: var(--fs-sm); }
.accommodation-detail__booking-box .input-group { margin-bottom: var(--sp-3); }
.accommodation-detail__booking-box label { display: block; font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--c-text-muted); margin-bottom: var(--sp-1); }
.accommodation-detail__booking-box input,
.accommodation-detail__booking-box select {
  width: 100%; padding: var(--sp-3); border: 1px solid var(--c-line);
  border-radius: var(--r-sm); font: inherit; font-size: 16px; background: #fff;
}
/* WICHTIG: Diese Regel galt frueher global fuer .booking-form__actions und hat
   in der eigentlichen Buchungsstrecke die Buttons untereinander/full-width
   gestapelt – obwohl das booking-bundle dort bewusst Inline-Flex-Buttons mit
   natuerlicher Breite vorsieht. Sie wird hier auf die schmale Buchungsbox in
   der Detailseite (accommodation-detail__booking-box) eingegrenzt, damit der
   Buchungsstrecken-Look unangetastet bleibt. */
.accommodation-detail__booking-box .booking-form__actions { display: flex; flex-direction: column; gap: var(--sp-2); margin-top: var(--sp-4); }
.accommodation-detail__booking-box .booking-form__actions .btn { width: 100%; }
.btn--book { background: var(--c-accent); color: #fff; box-shadow: 0 6px 16px rgba(232,159,60,.30); }
.btn--book:hover { background: var(--c-accent-600); color: #fff; transform: translateY(-1px); }
.btn--request { background: transparent; color: var(--c-primary); border-color: var(--c-primary); }
.btn--request:hover { background: var(--c-primary); color: #fff; }

/* Preisaufstellung in der Buchungsbox – grauer Panel-Hintergrund, OHNE
   Trennlinien. Label links / Wert rechts, Gesamt fett hervorgehoben.
   Höhere Spezifität als die Template-Inline-CSS, damit Theme-Optik greift. */
/* Grauer Panel-Hintergrund nur, wenn tatsächlich Preise drin stehen.
   Leeres Panel (keine Preise geladen) komplett ausblenden. */
.accommodation-detail__booking-box .accommodation__prices:empty { display: none !important; }
.accommodation-detail__booking-box .accommodation__prices:not(:empty) {
  gap: 0; margin: var(--sp-2) 0;
  background: var(--c-bg-alt); border-radius: var(--r-md); padding: var(--sp-4) var(--sp-5);
}
.accommodation-detail__booking-box .accommodation__prices .booking-price {
  padding: var(--sp-1) 0; border-bottom: 0;
}
.accommodation-detail__booking-box .accommodation__prices .booking-price__label { color: var(--c-text-muted); font-size: var(--fs-sm); }
.accommodation-detail__booking-box .accommodation__prices .booking-price__value { color: var(--c-text); font-size: var(--fs-md); font-weight: 700; }
/* Rabattzeile (alle Breiten): Die Bundle-Regel `.booking-price--discount
   .booking-price__value { width:100% }` sprengt im Grid (display:grid,
   grid-template-columns: minmax(0,1fr) auto) die Wert-Spalte → Label-Spalte
   kollabiert auf 0 → Label ragt ueber den Preis. Fix: width zuruecksetzen und
   den Wert vertikal stapeln (Streichpreis oben, Preis/Badge darunter). Hoehere
   Spezifitaet (4 Klassen) als die Bundle-Regel, NICHT media-gebunden. */
.accommodation-detail__booking-box .accommodation__prices .booking-price--discount .booking-price__value {
  width: auto;
  flex-direction: column;
  align-items: flex-end;
  flex-wrap: nowrap;
  gap: 0.1rem;
}
/* Label oben statt zentriert (das Grid setzt align-items:center). */
.accommodation-detail__booking-box .accommodation__prices .booking-price--discount {
  align-items: start;
}

/* Rabattzeile KONTEXTUEBERGREIFEND (Detail-Box UND Buchungsstrecke):
   Label links, Wert rechts daneben, Wert vertikal gestapelt (Streichpreis oben,
   Preis + Badge darunter). Doppelte Klasse `.booking-price.booking-price--discount`
   = Spezifitaet 0,2,0 (Zeile) bzw. 0,3,0 (Wert) und schlaegt damit das inline-
   <style> des Bundles (das im Checkout sonst die ganze Zeile linksbuendig stapelt). */
.booking-price.booking-price--discount {
  flex-direction: row;
  align-items: flex-start;
}
.booking-price.booking-price--discount .booking-price__value {
  width: auto;
  margin-left: auto;
  flex-direction: column;
  align-items: flex-end;
  flex-wrap: nowrap;
  justify-content: flex-start;
  gap: 0.1rem;
}
/* Angebotszeile: neuer Preis prominent oben (erbt fs-md/700 vom Wert),
   darunter Streichpreis + Rabatt als dezente, kleine Unterzeile. Setzt das
   umgestellte Markup voraus (new-price zuerst, dann .price-sub). */
.booking-price__value .price-sub {
  display: inline-flex;
  flex-direction: row-reverse; /* Badge links, Streichpreis rechts -> rechte Kante bündig mit dem neuen Preis */
  align-items: baseline;
  gap: 0.4rem;
  font-size: 0.72rem;
  font-weight: 400;
  line-height: 1.1;
  color: var(--c-text-muted);
  white-space: nowrap;
}
.booking-price__value .price-sub .old-price { font-size: inherit; opacity: 0.6; }
.booking-price__value .price-sub .discount-badge { font-size: 0.7rem; padding: 0.08rem 0.38rem; }

.accommodation-detail__booking-box .accommodation__prices .booking-price--total {
  border-top: 0; border-bottom: 0; margin-top: var(--sp-2); padding-top: 0;
}
.accommodation-detail__booking-box .accommodation__prices .booking-price--total .booking-price__label { color: var(--c-text); font-weight: 800; font-size: var(--fs-md); }
.accommodation-detail__booking-box .accommodation__prices .booking-price--total .booking-price__value { color: var(--c-text); font-weight: 800; font-size: var(--fs-lg); white-space: nowrap; }
/* Mobil: Das Inline-CSS der Buchungsbox (booking_form.html.twig) stapelte unter
   640px ALLE Preiszeilen auf eine Spalte -> Betrag landete unter dem Label und
   wirkte "verschoben". Hier ALLE Zeilen (nicht nur Gesamt) zweispaltig halten:
   Label links, Betrag rechts. Hoehere Spezifitaet (3 Klassen) als das Inline-CSS,
   daher gewinnt diese Regel auch ohne frontend-bundle-Deploy. */
@media (max-width: 640px) {
  .accommodation-detail__booking-box .accommodation__prices .booking-price,
  .accommodation-detail__booking-box .accommodation__prices .booking-price--total {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: baseline;
    column-gap: var(--sp-3);
  }
  .accommodation-detail__booking-box .accommodation__prices .booking-price__value {
    text-align: right;
    /* mobil kleiner, damit Label + Betrag sicher in eine Zeile passen */
    font-size: var(--fs-md);
  }
  /* Rabattzeile: dreiteiliger Wert (Streichpreis + Preis + Badge) passt mobil
     nicht neben das Label und ragt darueber. Daher den Wert rechtsbuendig
     VERTIKAL stapeln (Streichpreis oben, Preis + Badge darunter). Hoehere
     Spezifitaet (4 Klassen) als die obige Zeilenregel, daher gewinnt sie. */
  .accommodation-detail__booking-box .accommodation__prices .booking-price--discount .booking-price__value {
    flex-direction: column;
    align-items: flex-end;
    flex-wrap: nowrap;
    gap: 0.1rem;
  }
  .accommodation-detail__booking-box .accommodation__prices .booking-price__d {
    text-align: right;
  }
  /* Kopf-Preis ("ab X €/Nacht") mobil verkleinern, damit er nicht umbricht. */
  .accommodation-detail__booking-box .accommodation-detail__booking-box-from-price-value {
    font-size: var(--fs-xl);
  }
}

/* Buchungsbox-Kopf wie Vorlage: großer Preis oben, KEIN „Ihre Reisedaten &
   Preise"-Titel; „ab" klein vorangestellt, „/ Nacht" gedämpft dahinter. */
.accommodation-detail__booking-box .accommodation-detail__booking-box-header { display: block; }
.accommodation-detail__booking-box .accommodation-detail__booking-box-title { display: none; }
.accommodation-detail__booking-box .accommodation-detail__booking-box-from-price { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0 var(--sp-2); }
.accommodation-detail__booking-box .accommodation-detail__booking-box-from-price-label { order: -1; color: var(--c-text-muted); font-size: var(--fs-sm); font-weight: 600; }
.accommodation-detail__booking-box .accommodation-detail__booking-box-from-price-value { font-family: var(--ff-display); font-size: var(--fs-2xl); font-weight: 800; color: var(--c-primary); line-height: 1.1; }
.accommodation-detail__booking-box .accommodation-detail__booking-box-from-price-note { color: var(--c-text-muted); font-size: var(--fs-sm); }

/* Ausstattung: hat ein Eintrag KEIN eigenes Icon, kommt ein grüner Haken davor
   (Eintrag MIT Icon zeigt das gewählte Icon). */
.accommodation-detail__amenities-item-title:not(:has(.accommodation-detail__amenities-icon))::before {
  content: "✓"; flex: 0 0 auto; color: var(--c-success, #2e9e6b); font-weight: 800; line-height: 1;
}

/* Detailseite: vertikale Abstände der Reader-Blöcke (accommodation-detail__*).
   Desktop über row-gap des Grids; mobil (Block-Ansicht) über Geschwister-Margin.
   Zusätzlich etwas Luft unter den Block-Überschriften. */
@media (max-width: 979px) {
  .mod_article.detail-layout > * + * { margin-top: var(--sp-8); }
}
.mod_article.detail-layout > * > h2:first-child { margin-top: 0; }
.mod_article.detail-layout h2 { margin-bottom: var(--sp-4); }
.accommodation-detail__distances,
.accommodation-detail__map { margin-top: var(--sp-2); }

/* ============================================================
   Objekt-Kopf (accommodation_objecthead_reader): Ort/Nr über dem Titel,
   Bewertung + Entfernung darunter, Merken/Teilen rechts.
   ============================================================ */
.objecthead { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--sp-3) var(--sp-5); }
.objecthead__main { min-width: 0; flex: 1 1 320px; }
.objecthead__location { font-size: var(--fs-xs); color: var(--c-text-muted); text-transform: uppercase; letter-spacing: .06em; font-weight: 600; margin: 0 0 var(--sp-1); }
.objecthead__title { margin: 0 0 var(--sp-2); }
.objecthead__meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); font-size: var(--fs-sm); color: var(--c-text-muted); }
.objecthead__rating { display: inline-flex; align-items: center; gap: 4px; color: var(--c-text); font-weight: 700; }
.objecthead__rating svg { width: 16px; height: 16px; color: var(--c-accent); }
.objecthead__meta-sep { color: var(--c-line); }
.objecthead__actions { display: flex; gap: var(--sp-2); flex: 0 0 auto; }

/* Merken/Teilen als prominente Outline-Pills: dicker Primary-Border,
   Primary-Text/Icon, Bold (analog zum .btn--secondary auf der Startseite).
   Hat hoehere Spezifitaet als das Universal-Override fuer .btn--ghost,
   damit die Header-Buttons sich konsistent zum Sekundaer-CTA verhalten. */
.objecthead__action,
:is(a, button, input[type="submit"]).objecthead__action,
.objecthead__action.btn,
.objecthead__action.btn--ghost {
  background: #ffffff !important;
  color: var(--c-primary) !important;
  border: 2px solid var(--c-primary) !important;
  border-radius: 999px !important;
  font-weight: 700 !important;
  padding: var(--sp-2) var(--sp-4) !important;
}
.objecthead__action:hover,
:is(a, button, input[type="submit"]).objecthead__action:hover {
  background: var(--c-primary) !important;
  color: #ffffff !important;
  border-color: var(--c-primary) !important;
}
.objecthead__action svg { color: currentColor; }

/* Aktiver Merken-Status: Herz orange gefuellt, Border/Text bleiben Primary. */
.objecthead__action.is-active { color: var(--c-primary) !important; }
.objecthead__action.is-active svg {
  color: var(--c-accent);
  fill: var(--c-accent);
}
/* Zurück-Button (zur Ergebnisliste) */
.objecthead__back { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-sm); font-weight: 600; color: var(--c-primary); text-decoration: none; margin-bottom: var(--sp-2); padding: var(--sp-2) var(--sp-3); border: 1px solid var(--c-line); border-radius: var(--r-md); background: #fff; transition: background .15s ease, border-color .15s ease, color .15s ease; }
.objecthead__back:hover { background: var(--c-primary); color: #fff; border-color: var(--c-primary); }
.objecthead__back svg { width: 16px; height: 16px; }
/* Teilen-Dropdown (Link kopieren / E-Mail / WhatsApp) */
.objecthead__share { position: relative; }
.objecthead__share-menu { position: absolute; right: 0; top: calc(100% + 4px); z-index: 20; min-width: 190px; background: #fff; border: 1px solid var(--c-line); border-radius: var(--r-md); box-shadow: var(--shadow-md); padding: var(--sp-1); flex-direction: column; }
.objecthead__share-menu:not([hidden]) { display: flex; }
.objecthead__share-menu[hidden] { display: none; }
.objecthead__share-item { display: block; text-align: left; padding: var(--sp-2) var(--sp-3); border: 0; background: transparent; color: var(--c-text); font: inherit; font-size: var(--fs-sm); cursor: pointer; border-radius: var(--r-sm); text-decoration: none; }
.objecthead__share-item:hover { background: var(--c-bg-alt); }

/* ============================================================
   Fakten-Leiste (accommodation_facts_reader): Gäste/Schlafzimmer/Fläche/Hund.
   ============================================================ */
.facts-strip { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--sp-3) var(--sp-5); background: var(--c-bg-alt); border-radius: var(--r-lg); padding: var(--sp-5); }
@media (min-width: 720px) { .facts-strip { grid-template-columns: repeat(4, 1fr); } }
.facts-strip__item { display: flex; align-items: center; gap: var(--sp-3); min-width: 0; }
.facts-strip__icon { flex: 0 0 auto; width: 40px; height: 40px; border-radius: 50%; background: #fff; color: var(--c-primary); display: inline-flex; align-items: center; justify-content: center; }
.facts-strip__icon svg { width: 20px; height: 20px; }
.facts-strip__body { display: flex; flex-direction: column; min-width: 0; }
.facts-strip__label { font-size: var(--fs-xs); color: var(--c-text-muted); }
.facts-strip__value { font-weight: 700; }

/* ============================================================
   Rechtliches (rsce_mwfm_legal): Abschnitte mit Ankern. scroll-margin-top
   sorgt dafür, dass #-Sprünge nicht unter dem Header verschwinden.
   ============================================================ */
.legal__section { padding: var(--sp-6) 0; border-bottom: 1px solid var(--c-line); scroll-margin-top: calc(var(--header-h) + var(--sp-6)); }
.legal__section:last-child { border-bottom: 0; }
.legal__title { margin: 0 0 var(--sp-3); }
.legal__body p { margin: 0 0 var(--sp-3); }
.legal__body p:last-child { margin-bottom: 0; }

/* Contao-Standardklasse „invisible": Elemente, die ausgeblendet sein sollen
   (z. B. unsichtbar geschaltete Inhalte/Felder), zuverlässig verstecken. */
.invisible { display: none !important; }

/* Toggle-Utility: per JS umgeschaltete Elemente (z. B. Lade-/„alles geladen"-
   Hinweise, Modals) zuverlässig ausblenden. Liegt auch im Skeleton
   (utilities.css) – hier zusätzlich, falls die installierte Skeleton-Kopie
   noch alt ist. */
.hidden { display: none !important; }

/* Bewertungen (Leerzustand + „Das sagen unsere Gäste") werden jetzt vom Bundle
   geliefert: files/layout/css/reviews.css. Die Optik kommt automatisch über die
   Token-Brücke oben (--color-accent, --border-color, --radius-*, --space-* …).
   Hier daher KEINE Duplikate mehr – bei Bedarf gezielt in override.css ergänzen. */

/* ============================================================
   BACK-TO-TOP (Floating-Button)
   Wird von main.js dynamisch in den Body injiziert. Sichtbar
   ab Scroll > 600px, smooth scroll to top on click.
   ============================================================ */
.back-to-top {
  position: fixed;
  right: var(--sp-4, 1rem);
  bottom: var(--sp-4, 1rem);
  z-index: 90;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 50%;
  background: var(--c-accent, var(--c-primary, #d97706));
  color: #fff;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.18);
  opacity: 0;
  pointer-events: none;
  transform: translateY(8px);
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.back-to-top.is-visible {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0);
}
.back-to-top:hover,
.back-to-top:focus-visible {
  filter: brightness(1.08);
  outline: 0;
}
.back-to-top svg {
  display: block;
}

/* iOS Safe-Area (iPhone X+) - Button nicht auf Home-Indicator legen. */
@supports (padding: env(safe-area-inset-bottom)) {
  .back-to-top {
    bottom: calc(var(--sp-4, 1rem) + env(safe-area-inset-bottom));
  }
}

/* Content-getriebener Seitenkopf (rsce_mwfm_page_header) rendert
   .page-header--content und nutzt dieselbe (blaue) .page-header-Optik.
   Liegt so ein Element auf der Seite, die aus dem Header-Modul kommende
   Leiste ausblenden -> nur EINE Titel-Leiste. KEIN SEO – reiner Inhalt. */
body:has(.page-header--content) .page-header:not(.page-header--content) { display: none; }
/* Abstand nach unten zum folgenden Inhalt (z. B. Merkzettel, Texte). */
.page-header--content { margin: 0 0 var(--sp-8); }
/* Suchseite: dort erzeugt der Grid-row-gap den Abstand -> keine Doppel-Marge. */
.mod_article:has(> .search-box--horizontal) .page-header--content { margin-bottom: 0; }
.page-header--content .page-header__teaser:empty { display: none; }
/* Kein weisser Abstand ueber der Content-Leiste: den oberen Innenabstand des
   Artikels entfernen, wenn ein Content-Seitenkopf darin liegt (analog .hero). */
.mod_article:has(.page-header--content) { padding-top: 0; }

/* ============================================================
   CookieConsent (Orest Bida, v3) – Theming passend zum Demo-Theme.
   style.css laedt NACH cookieconsent.css -> diese Overrides gewinnen.
   ============================================================ */
#cc-main {
  --cc-font-family: inherit;
  --cc-btn-border-radius: 12px;
  --cc-modal-border-radius: var(--r-lg);
  --cc-primary-color: var(--c-text);
  --cc-secondary-color: var(--c-text-muted, #5B6779);
  --cc-link-color: var(--c-primary);
  --cc-btn-primary-bg: var(--c-accent);
  --cc-btn-primary-border-color: var(--c-accent);
  --cc-btn-primary-color: #fff;
  --cc-btn-primary-hover-bg: var(--c-accent-600);
  --cc-btn-primary-hover-border-color: var(--c-accent-600);
  --cc-btn-primary-hover-color: #fff;
  --cc-btn-secondary-bg: #eef1f6;
  --cc-btn-secondary-color: var(--c-text);
  --cc-btn-secondary-hover-bg: #e3e8f0;
  --cc-btn-secondary-hover-color: var(--c-text);
  --cc-toggle-on-bg: var(--c-primary);
  --cc-toggle-readonly-bg: #c8d0dd;
}
/* Buttons als Pillen (wie die Theme-CTAs); Kategorie-Kaesten moderat gerundet
   statt oval. */
#cc-main .cm__btn,
#cc-main .pm__btn { border-radius: 999px; }
#cc-main .pm__section { border-radius: 12px; overflow: hidden; }

/* TOKENS MÜSSEN EXISTIEREN, SONST FÄLLT DIE EIGENSCHAFT LAUTLOS AUS.
 *
 * Hier standen `var(--shadow-light)` und `var(--shadow-hover)` ohne
 * Definition und ohne Ersatzwert. Kein Fehler, keine Konsolenzeile —
 * die Karten und Kennzahlen-Kacheln hatten schlicht KEINEN Schatten,
 * und beim Zeigen passierte außer der Verschiebung nichts.
 *
 * Gemeint war offensichtlich `--frontend-core-shadow-light` bzw.
 * `-hover`; beide sind in `frontend-core/root.css` definiert und
 * tragen genau die Werte, die hier gewollt waren. Der Ersatzwert
 * daneben ist kein Zierrat: Auf der öffentlichen Webseite lädt
 * `frontend-core` gar nicht, und ohne ihn wäre der Schatten dort
 * wieder weg.
 *
 * Dasselbe eine Zeile weiter unten: `var(--frontend-core-status-booked,
 * var(--status-booked))` — der Ersatzwert zeigte selbst ins Leere und
 * war damit keiner. Jetzt steht dort der Farbwert.
 *
 * Gefunden mit `python3 tools/css-token-lint.py`.
 */

/* 1) Karten gleichmäßig hoch, auch bei unterschiedlicher Textlänge */
.owner-list {
    display: grid;
    gap: 1rem;
    padding: 0;
    margin: 0;
}
@media (min-width: 700px) {
    .owner-list {
        grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
        align-items: stretch; /* alle Cards gleich hoch */
    }
}

/* 2) Innerhalb der Card: Footer fix nach unten */
.card {
    display: flex;
    flex-direction: column;
    /*
     * DER FUSS WIRD NACH UNTEN GESCHOBEN, DER INHALT NICHT AUSEINANDER.
     *
     * Hier stand `space-between`. Das hält den Fuß zwar unten, verteilt
     * aber ALLE Abstände gleichmässig — bei einer Karte, die im Raster mehr
     * Höhe bekommt als ihr Inhalt braucht, reisst es Bild, Titel und
     * Kalender auseinander. Sichtbar war das als handbreite Leerfläche
     * zwischen Objektbild und Objektnamen.
     *
     * `flex-start` plus `margin-top: auto` am Fuß macht dasselbe, ohne den
     * Rest zu strecken: Der Leerraum sammelt sich an EINER Stelle, nämlich
     * über dem Fuß, wo er nicht stört.
     */
    justify-content: flex-start;
    height: 100%; /* sorgt für gleiche Höhe, wenn die Cards in einem Grid liegen */
}

.card__actions {
    margin-top: auto;
}
.card__body {
    flex: 0 0 auto; /* Inhalt bleibt in natürlicher Höhe */
}

/* === Karten (z. B. Buchung, Rechnung, Gast) === */
.card {
    background: var(--color-surface);
    border-radius: var(--radius-card);
    box-shadow: var(--frontend-core-shadow-light, 0 2px 6px rgba(0, 0, 0, .06));
    padding: 1rem;
    padding: 0;
    margin: 0;
    transition: transform .2s ease, box-shadow .2s ease;
}

.card:hover {
    transform: translateY(-2px);
    box-shadow: var(--frontend-core-shadow-hover, 0 8px 24px rgba(0, 0, 0, .12));
}

.card:has(.card__media) {
    padding: 0;
}

/* Inhalt nach Bild: links/rechts eingerückt */
.card:has(.card__media) .card__body,
.card:has(.card__media) .card__actions {
    padding: 1rem;
}

/* EIN ABSTAND, NICHT ZWEI.
 *
 * `default.css` gibt jedem `.card__body` ein `margin: 1rem 0` — sinnvoll
 * für eine Karte ohne Bild, wo der Textblock selbst für seinen Abstand
 * sorgen muss. Hier hat er aber schon den Innenrand von oben, und beide
 * addieren sich: 16 Pixel Außenabstand plus 16 Pixel Innenrand zwischen
 * Bild und Objektnamen, dieselben 32 noch einmal zwischen Text und
 * Kalender.
 *
 * Die zwei Werte stehen in zwei Dateien und meinen dasselbe. Wer eine
 * davon liest, sieht einen glaubwürdigen Abstand und sucht nicht weiter —
 * genau deshalb ist die Summe niemandem als Fehler aufgefallen, sondern
 * nur als „irgendwie viel Luft".
 *
 * Der Innenrand gewinnt, weil er zum Bild gehört: Er hält den Text auf
 * derselben Linie wie den Fuß darunter. Der Außenabstand fällt weg.
 *
 * NUR FÜR DEN TEXTBLOCK, nicht für den Fuß: Der trägt `margin-top: auto`
 * und schiebt sich damit nach unten. Stünde er in dieser Regel, verlöre
 * er das — die Regel hier ist spezifischer und gewänne. */
.card:has(.card__media) .card__body {
    margin-top: 0;
    margin-bottom: 0;
}

/* DIE <figure> IST DIE HÜLLE, NICHT DAS BILD — UND SIE BRAUCHT `margin: 0`.
 *
 * Contaos Bild-Bauteil legt um jedes Bild eine `<figure>`; die Klasse aus
 * `options.attr` landet auf ihr, nicht auf dem `<img>`. Ohne eigene Regel
 * gilt dort die Browser-Vorgabe `margin: 1em 40px` — ein Sechzehntel Zoll
 * über dem Bild, ebenso viel darunter und vierzig Pixel an beiden Seiten.
 *
 * Das ist ein Element, das im Template gar nicht auftaucht — es entsteht
 * erst im Bauteil, und deshalb fasst es niemand an. Das Frontend-Theme des
 * Kunden hat dieselbe Stelle längst mit `margin: 0` abgefangen, dieses
 * Bundle nicht.
 *
 * ES WAR NICHT DIE LEERFLÄCHE ZWISCHEN BILD UND TITEL, die hier gesucht
 * wurde — die kam aus dem Seitenverhältnis des Behälters (siehe unten,
 * `.card__media`). Gemessen hat die Hülle ohne diese Regel 16 Pixel oben,
 * 16 unten und 40 an jeder Seite; das ist für sich genommen falsch genug,
 * aber es erklärte die 92 Pixel nicht.
 *
 * Die Regel fasst das ELEMENT an, nicht die Klasse: Welchen Namen die Hülle
 * trägt, entscheidet die aufrufende Vorlage, und die nächste wird einen
 * anderen wählen. */
.card__media figure {
    display: block;
    margin: 0;
}

/* DER BEHÄLTER FOLGT DEM BILD, NICHT EINEM SEITENVERHÄLTNIS.
 *
 * Das Theme des Kunden gibt `.card__media` ein `aspect-ratio: 4/3` und
 * füllt es mit `img { height: 100% }`. Das ist in sich stimmig — solange
 * niemand die Bildhöhe überschreibt. Genau das tut die Regel weiter
 * unten: Sie setzt `height: 190px`, damit alle Objektbilder gleich hoch
 * sind. Und sie gewinnt, weil diese Datei zuletzt lädt.
 *
 * Danach ist der Behälter 4/3 der Kartenbreite hoch und das Bild 190
 * Pixel. Bei einer 376 Pixel breiten Karte sind das 282 gegen 190 — 92
 * Pixel leerer Behälter unter dem Bild, in der Farbe der Karte und damit
 * unsichtbar als Fläche. Sichtbar war nur ihre Wirkung: der Abstand
 * zwischen Objektbild und Objektnamen.
 *
 * DASS ZWEI REGELN DIESELBE HÖHE BESTIMMEN, IST DER FEHLER — nicht
 * welche von beiden gewinnt. Wer nur die eine liest, rechnet richtig und
 * kommt trotzdem auf das falsche Ergebnis. Aufgefallen ist es erst, als
 * die Höhen nebeneinander standen: Bild 190, Hülle 190, Behälter 282. */
.card__media {
    aspect-ratio: auto;
    height: auto;
    margin: 0;
    overflow: hidden;
    border-top-left-radius: var(--radius-card);
    border-top-right-radius: var(--radius-card);
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
}

/* ALLE OBJEKTBILDER GLEICH HOCH.
 *
 * `height: auto` hieß: Jede Karte ist so hoch wie ihr Bild. Die Bilder
 * kommen aus der Dateiverwaltung des Kunden und haben jedes Seitenverhältnis,
 * das eine Kamera hergibt — im Kartenraster stand deshalb eine Karte
 * sichtbar kürzer als ihre Nachbarn, und die Knöpfe darunter lagen auf drei
 * verschiedenen Höhen.
 *
 * Eine feste Höhe mit `object-fit: cover` schneidet den Ausschnitt zu, statt
 * das Bild zu verzerren. Verzerrt wäre die schlechtere Wahl: Ein gestauchtes
 * Haus fällt sofort auf, ein beschnittener Himmel nicht. */
.card__media img {
    display: block;
    width: 100%;
    height: 190px;
    object-fit: cover;
}

@media (max-width: 600px) {
    /* Auf dem Telefon ist die Karte so breit wie der Bildschirm; ein
     * 190 Pixel hohes Bild wäre dort ein Streifen. */
    .card__media img { height: 220px; }
}

.card__header {
    display: flex;
    align-items: center;
    margin-bottom: .5rem;
    padding-top: 1rem;
    padding-left: 1rem;
    padding-right: 1rem;
}

/* === Aktionen im Karten-Footer === */
.card__actions {
    display: flex;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: .5rem;
    padding: 1rem;
    border-top: 1px solid var(--border-color);
    margin-top: auto; /* Footer schiebt sich automatisch an das untere Ende */
}

@media (max-width: 600px) {
    .card__actions {
        flex-direction: column;
        align-items: stretch;
    }

    .card__actions .btn {
        width: 100%;
        text-align: center;
    }
}

/* ============================================================
   DREI BAUTEILE AUS DEM ENTWURF, DIE ES NOCH NICHT GAB
   ============================================================

   Aus `MOCKUP-EIGENTUEMERLOGIN-ENTWURF.html`. Sie stehen hier und nicht
   im Bauplan, weil die Reihenfolge so herum gilt: erst die benannte
   Komponente, dann das Markup, das sie benutzt.

   Der Eigentümer sieht seine Objekte vielleicht einmal im Monat an. Die
   drei Fragen, die er wirklich hat, lauten: Ist mein Haus belegt? Was
   kommt an Geld? Muss ich etwas tun? Für jede gibt es hier ein Bauteil.
   ============================================================ */

/* ---- WAS OFFEN IST ----
 *
 * Der Block, den er zuerst liest, und der verschwindet, wenn nichts
 * offen ist. Ein dauerhaft sichtbarer leerer Kasten wird nach zwei
 * Wochen nicht mehr gelesen — deshalb rendert die Vorlage ihn gar
 * nicht, statt ihn leer zu zeigen.
 *
 * Die Farbe sitzt am Rand und nicht in der Fläche: Ein eingefärbter
 * Kasten lässt den Text schlechter lesen. Der Rand ist ringsum gleich
 * breit — eine dickere farbige Kante links gibt es im System nicht. */
.owner-open {
    border: 1px solid var(--frontend-core-color-danger, #dc2626);
    border-radius: var(--radius-md, 12px);
    background: var(--color-surface, #fff);
    padding: 12px 16px;
    margin-bottom: 24px;
}

.owner-open__title {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: .85rem;
    font-weight: 700;
    margin: 0 0 8px;
}

.owner-open__title svg {
    width: 15px;
    height: 15px;
    flex: 0 0 15px;
    color: var(--frontend-core-color-danger, #dc2626);
}

.owner-open__list { display: grid; gap: 6px; }

.owner-open__row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 10px;
    font-size: .875rem;
    line-height: 1.45;
}

/* Rechts in der Zeile: „Ansicht" oder die beiden Knöpfe zum Entscheiden.
   Auf dem Telefon rutschen sie unter den Satz, statt ihn zu quetschen. */
.owner-open__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-left: auto;
}

.owner-open__actions > a:not(.btn) {
    font-weight: 600;
    white-space: nowrap;
}

/* ---- DIE GELDAUFSTELLUNG ----
 *
 * Die einzige Stelle im Eigentümerbereich, an der es auf den Cent
 * ankommt: tabellarische Ziffern, rechtsbündig, und die Auszahlung
 * optisch vom Rest getrennt.
 *
 * Der Satz zu Kurtaxe und Kaution gehört unter die Aufstellung, nicht
 * ins Telefonat. Es ist die häufigste Rückfrage, und sie entsteht, weil
 * die Summe nicht zur Rechnung des Gastes passt — was richtig ist, aber
 * erklärt gehört. */
.owner-money {
    border: 1px solid var(--color-border, #e5e7eb);
    border-radius: var(--radius-card, 10px);
    overflow: hidden;
    background: var(--color-surface, #fff);
}

.owner-money__row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 120px;
    gap: 12px;
    padding: 10px 16px;
    border-bottom: 1px solid var(--color-border, #e5e7eb);
    font-size: .875rem;
}

.owner-money__amount { text-align: right; font-variant-numeric: tabular-nums; }
.owner-money__amount--minus { color: var(--frontend-core-color-danger, #dc2626); }

.owner-money__row--sub { background: var(--color-surface-alt, #f8fafc); font-weight: 600; }

.owner-money__row--total {
    border-bottom: 0;
    border-top: 2px solid var(--color-muted, #6b7280);
    background: var(--color-surface-alt, #f8fafc);
    font-size: 1rem;
    font-weight: 700;
    padding-top: 13px;
    padding-bottom: 13px;
}

.owner-money__note {
    font-size: .8rem;
    color: var(--color-muted, #6b7280);
    padding: 10px 16px;
    border-top: 1px solid var(--color-border, #e5e7eb);
    line-height: 1.5;
}

/* ---- DIE FARBTAFEL DER BELEGUNGSKALENDER IM EIGENTÜMERBEREICH ----
 *
 * DIE STATUSFARBEN DES SYSTEMS, NICHT DIE PASTELLTAFEL DES GASTKALENDERS.
 *
 * Hier zeigten die Namen bis 5.15.0 auf `--calendar-bg-*`, die Tafel des
 * Datepickers für den Gast: frei zartgrün, Buchung zartrot, Reservierung
 * zartorange, Eigenbelegung zartgelb. Für den Gast ist das richtig — ihn
 * geht nur „zu haben oder nicht" an. Der Eigentümer liest auf dieser Seite
 * aber gerade die ART der Belegung, und zwei der vier Töne waren dafür zu
 * nah beieinander: Reservierung (#ffe0cc) und Eigenbelegung (#ffe5b4)
 * standen in der Legende als dasselbe Orange. Dazu war jedes Wochenende
 * grün hinterlegt und sah damit aus wie „frei".
 *
 * Jetzt tragen Balken, Monatsfelder und Legende die Töne, mit denen das
 * System den Status überall färbt (`--frontend-core-status-*`, Quelle
 * `--badge-*-bd` in `ui-default.css`, im Entwurf `--st-*`): Buchung grün,
 * Reservierung orange, Eigenbelegung magenta, Blockierung grau. Dieselbe
 * Buchung hat damit im Plan, im Monatskalender und als Status in der Liste
 * darunter dieselbe Farbe.
 *
 * FREI IST KEIN ZUSTAND, SONDERN DAS FEHLEN EINES — und trägt deshalb die
 * Rasterfarbe, ein neutrales Grau aus dem gedämpften Text des Themes.
 * Grün kann es nicht mehr sein: Grün ist hier „gebucht".
 *
 * Der Ersatzwert hinter jedem Token ist der Wert des hellen Schemas: Auf
 * der öffentlichen Webseite lädt `frontend-core/root.css` nicht. */
:root {
    --owner-cal-free: color-mix(in srgb, var(--color-muted, #6b7280) 12%, var(--color-surface, #fff));
    /* BELEGT IST ROT — NUR IM EIGENTÜMER-LOGIN (Entwurf
       MOCKUP-EIGENTUEMER-MIETOBJEKTE-ENTWURF, Nutzerwunsch). In den
       Belegungskalendern, die ein Eigentümer kennt, heißt Rot „belegt";
       im übrigen System ist Rot „storniert" und eine Buchung grün.
       Stornierungen kommen in den Kalendern des Logins nicht vor, Rot
       trägt hier also nichts anderes. Eigenes Token statt eines
       umgefärbten `--frontend-core-status-booked`: Die Statuspunkte der
       Listen und das Backoffice bleiben grün. */
    --frontend-core-occupancy-booked: #d64545;
    --owner-cal-guest: var(--frontend-core-occupancy-booked);
    --owner-cal-pending: var(--frontend-core-status-reserved, rgba(253, 126, 20, .9));
    --owner-cal-own: var(--frontend-core-status-owner, rgba(156, 28, 139, .9));
    --owner-cal-blocked: var(--frontend-core-status-blocked, rgba(108, 117, 125, .9));
    --owner-cal-today: var(--frontend-core-color-primary, #0072ce);
}

/* ---- DER ÜBERSICHTSKALENDER (#708) ----
 *
 * Je Zeile ein Objekt, je Spalte ein Tag. Er beantwortet die Frage, die
 * die Belegungsliste eines einzelnen Objekts nicht beantworten kann: Wo
 * ist am kommenden Wochenende noch etwas frei, und wo liegt meine eigene
 * Eigenbelegung?
 *
 * Das Vorbild im Frontend (`accommodation_availability_calendar`) kennt
 * frei und belegt, weil der Gast nichts anderes angeht. Der Eigentümer
 * sieht vier Belegungsarten, und genau die zu unterscheiden ist der
 * Zweck dieser Seite. */
.owner-plan {
    border: 1px solid var(--color-border, #e5e7eb);
    border-radius: var(--radius-md, 12px);
    background: var(--color-surface, #fff);
    overflow: hidden;
}

.owner-plan__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    padding: 12px 16px;
    border-bottom: 1px solid var(--color-border, #e5e7eb);
    background: var(--color-surface-alt, #f8fafc);
}

.owner-plan__nav {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

/* Die Pfeile sind Inline-SVG mit `stroke="currentColor"`, kein „‹" und
 * kein Emoji: Nur so nehmen sie die Farbe, die das CSS ohnehin setzt. */
.owner-plan__step {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: 1px solid var(--color-border, #e5e7eb);
    border-radius: 7px;
    background: var(--color-surface, #fff);
    color: inherit;
    text-decoration: none;
    cursor: pointer;
}

.owner-plan__step svg { width: 14px; height: 14px; }

/* Ein Pfeil am Rand des navigierbaren Fensters bleibt stehen — sichtbar
 * blass, nicht verschwunden, damit die Leiste nicht springt. */
.owner-plan__step[aria-disabled="true"],
.owner-plan__step:disabled { opacity: .35; cursor: default; }

.owner-plan__now {
    padding: 4px 12px;
    border: 1px solid var(--color-border, #e5e7eb);
    border-radius: 7px;
    background: var(--color-surface, #fff);
    color: inherit;
    font-size: .8rem;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
}

.owner-plan__now.is-on {
    border-color: var(--frontend-core-color-primary, #0072ce);
    color: var(--frontend-core-color-primary, #0072ce);
}

.owner-plan__month {
    margin-left: 8px;
    font-size: .875rem;
    font-weight: 700;
}

.owner-plan__legend {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 16px;
    font-size: .78rem;
    color: var(--color-muted, #6b7280);
}

.owner-plan__key {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

/* DAS FARBKÄSTCHEN DER LEGENDE IST DIE ZELLE IM KLEINEN. Ohne
 * Zustandsklasse steht es für den freien Tag und trägt die Rasterfarbe. */
.owner-plan__swatch {
    width: 11px;
    height: 11px;
    border-radius: 3px;
    background: var(--owner-cal-free);
}

/* DIE BREITE IST DAS PROBLEM DIESER FORM. Einunddreißig Spalten passen
 * auf kein Telefon. Gescrollt wird waagerecht, und die Objektspalte klebt
 * links — sonst weiß man nach drei Spalten nicht mehr, in welcher Zeile
 * man liest. Eine Kartenliste wäre hier falsch: Was das Raster beantwortet,
 * ist gerade das Nebeneinander. */
.owner-plan__scroll { overflow-x: auto; }

.owner-plan__grid {
    border-collapse: separate;
    border-spacing: 0;
    width: max-content;
    min-width: 100%;
}

.owner-plan__grid th,
.owner-plan__grid td { padding: 0; }

/* DIE NAMENSSPALTE HAT EINE FESTE BREITE. Zwei Klassen im Wähler, weil
 * `.owner-plan__grid th` sonst den Innenabstand auf null setzt. */
.owner-plan__grid .owner-plan__obj {
    position: sticky;
    left: 0;
    z-index: 2;
    width: 260px;
    min-width: 260px;
    max-width: 260px;
    padding: 0;
    background: var(--color-surface, #fff);
    border-right: 1px solid var(--color-border, #e5e7eb);
    border-bottom: 1px solid var(--color-border, #e5e7eb);
    font-size: .82rem;
    font-weight: 500;
    text-align: left;
}

/* DER NAME STEHT IN EINER ZEILE. Dreizeilig gesetzt machte er jede
 * Objektzeile dreimal so hoch wie ihre Balken, und bei drei Objekten stand
 * mehr Name als Belegung da. Was nicht passt, endet mit Auslassungspunkten;
 * der volle Name steht im `title` des Links. */
.owner-plan__name {
    display: block;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    color: inherit;
    text-decoration: none;
}

.owner-plan__name:hover { color: var(--frontend-core-color-primary, #0072ce); }

/* Die obere linke Ecke steht über der klebenden Spalte UND in der
 * Kopfzeile; ohne die höhere Ebene schiebt sich beim Scrollen ein Tag
 * darunter hervor. */
.owner-plan__corner {
    z-index: 3;
    background: var(--color-surface-alt, #f8fafc);
}

.owner-plan__grid .owner-plan__day {
    min-width: 32px;
    padding: 6px 0;
    background: var(--color-surface-alt, #f8fafc);
    border-bottom: 1px solid var(--color-border, #e5e7eb);
    border-left: 1px solid var(--color-border, #e5e7eb);
    font-size: .68rem;
    font-weight: 600;
    line-height: 1.25;
    text-align: center;
    color: var(--color-muted, #6b7280);
    font-variant-numeric: tabular-nums;
}

.owner-plan__day b {
    display: block;
    margin: 2px auto 0;
    width: 22px;
    height: 22px;
    border-radius: 999px;
    font-size: .78rem;
    line-height: 22px;
    color: var(--frontend-core-color-text, #111827);
}

/* DAS WOCHENENDE STEHT NUR IM KOPF. Eine durchgehend getönte Spalte las
 * sich als Zustand — grün wie „frei" oder grau wie „gesperrt", je nach
 * Tafel. Der Kopf trägt deshalb eine Tönung und kräftigere Schrift, die
 * Zellen darunter bleiben, was sie sind. */
.owner-plan__grid .owner-plan__day--weekend {
    background: color-mix(in srgb, var(--color-muted, #6b7280) 10%, var(--color-surface-alt, #f8fafc));
    color: var(--frontend-core-color-text, #111827);
}

/* HEUTE IST EINE MARKIERUNG, NICHT ZWEI LINIEN. Zwei senkrechte Striche
 * links und rechts der Spalte lasen sich als Rahmen um einen Tag — oder,
 * über einem Balken, als zwei Belegungsgrenzen. Jetzt steht die Zahl im
 * Kopf auf einer Scheibe in der Markenfarbe, und die Spalte darunter trägt
 * einen hauchdünnen Schleier derselben Farbe, auch über den Balken. */
.owner-plan__grid .owner-plan__day--today { color: var(--owner-cal-today); }

.owner-plan__day--today b {
    background: var(--owner-cal-today);
    color: #fff;
}

.owner-plan__cell {
    position: relative;
    min-width: 32px;
    height: 36px;
    border-bottom: 1px solid var(--color-border, #e5e7eb);
    border-left: 1px solid var(--color-border, #e5e7eb);
    background: var(--owner-cal-free);
}

.owner-plan__cell--today::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    background: color-mix(in srgb, var(--owner-cal-today) 14%, transparent);
}

/* ---- DIE BALKEN ----
 *
 * EIN BALKEN JE BELEGUNG, NICHT EINE FARBE JE TAG. Der Balken beginnt am
 * Nachmittag des Anreisetags und endet am Vormittag des Abreisetags; an
 * einem Wechseltag stehen zwei Balken mit einer Lücke dazwischen. Über die
 * Zellgrenze läuft er durch (ein Pixel nach links), sonst stünde mitten in
 * einer Woche Belegung alle 32 Pixel ein Strich.
 *
 * Die Klasse `owner-plan__cell--…` sitzt am Balken und trägt die Farbe;
 * Grau bleibt der Auffangton für einen Zustand ohne eigene Farbe. */
.owner-plan__cell .owner-plan__bar {
    position: absolute;
    top: 8px;
    bottom: 8px;
    left: -1px;
    right: 0;
    background: var(--owner-cal-blocked);
}

.owner-plan__cell .owner-plan__bar--full {
    left: -1px;
    right: 0;
}

.owner-plan__cell .owner-plan__bar--am {
    right: calc(50% + 2px);
    border-radius: 0 6px 6px 0;
}

.owner-plan__cell .owner-plan__bar--pm {
    left: calc(50% + 1px);
    border-radius: 6px 0 0 6px;
}

/* ---- DER MONATSKALENDER JE OBJEKT ----
 *
 * Er steht in der Objektkarte und auf der Belegungsseite eines Objekts.
 * Das Raster darüber vergleicht Objekte, dieser hier zeigt EIN Objekt über
 * den Monat: Wochen untereinander, Wochenenden immer an derselben Stelle.
 *
 * Die Tabelle ist fest geteilt — sieben Spalten zu je einem Siebtel, damit
 * die Wochentage in allen Karten auf derselben senkrechten Linie stehen. */
.owner-month {
    padding: 0 16px 16px;
}

.owner-month__grid {
    width: 100%;
    table-layout: fixed;
    border-collapse: separate;
    border-spacing: 2px;
}

/* SO VIELE MONATE, WIE IN DIE ZEILE PASSEN. `auto-fit` mit einer
 * Mindestbreite legt so viele Spalten nebeneinander, wie hineingehen. Das
 * Skript liest `--owner-month-min` über `getComputedStyle` zurück und fragt
 * genau so viele Monate nach — die Zahl steht deshalb nur hier. */
.owner-months {
    --owner-month-min: 260px;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(var(--owner-month-min), 1fr));
    gap: 20px;
    padding: 16px;
}

/* `min-width: 0`, sonst wächst die Rasterzelle mit ihrer Tabelle über die
 * Mindestbreite hinaus, und aus vier Monaten nebeneinander werden drei. */
.owner-months__item { min-width: 0; }

.owner-months__title {
    margin: 0 0 8px;
    font-size: .875rem;
    font-weight: 600;
    text-align: center;
    color: var(--color-muted, #6b7280);
}

.owner-months .owner-month { padding: 0; }

.owner-months .owner-month__day {
    height: 32px;
    font-size: .8rem;
    line-height: 32px;
}

.owner-months .owner-month__weekday { font-size: .74rem; }

.owner-month__weekday {
    padding: 0 0 4px;
    font-size: .68rem;
    font-weight: 600;
    text-align: center;
    color: var(--color-muted, #6b7280);
}

/* Wie im Raster steht das Wochenende nur im Kopf. */
.owner-month__weekday--weekend { color: var(--frontend-core-color-text, #111827); }

/* EIN FELD, ZWEI HÄLFTEN.
 *
 * Der Monatskalender kennt keine Balken, aber dieselbe Regel: Am Anreisetag
 * ist nur der Nachmittag belegt, am Abreisetag nur der Vormittag. Gezeichnet
 * wird das entlang der Diagonale — oben links der Vormittag, unten rechts
 * der Nachmittag, dazwischen ein schmaler Streifen Rasterfarbe, auf dem die
 * Tageszahl lesbar bleibt. Vorher stand der Abreisetag hier ganz frei,
 * während der Plan darüber ihn halb belegt zeigte.
 *
 * Die Hälften sind zwei Variablen und EIN Verlauf; welche Farbe sie tragen,
 * setzen die Klassen `owner-month__am--…` und `owner-month__pm--…`. Ohne
 * Klasse sind beide die Rasterfarbe, und das Feld ist schlicht frei. */
.owner-month__day {
    --owner-day-am: var(--owner-cal-free);
    --owner-day-pm: var(--owner-cal-free);
    height: 28px;
    padding: 0;
    border-radius: 5px;
    background: linear-gradient(135deg, var(--owner-day-am) 0 50%, var(--owner-day-pm) 50% 100%);
    font-size: .72rem;
    line-height: 28px;
    text-align: center;
    font-variant-numeric: tabular-nums;
    color: var(--frontend-core-color-text, #111827);
}

/* Die Felder vor dem Ersten und nach dem Letzten gehören nicht zum Monat. */
.owner-month__day--empty { background: none; }

.owner-month__am--booked { --owner-day-am: var(--owner-cal-guest); }
.owner-month__am--reserved { --owner-day-am: var(--owner-cal-pending); }
.owner-month__am--owner { --owner-day-am: var(--owner-cal-own); }
.owner-month__am--blocked { --owner-day-am: var(--owner-cal-blocked); }
.owner-month__pm--booked { --owner-day-pm: var(--owner-cal-guest); }
.owner-month__pm--reserved { --owner-day-pm: var(--owner-cal-pending); }
.owner-month__pm--owner { --owner-day-pm: var(--owner-cal-own); }
.owner-month__pm--blocked { --owner-day-pm: var(--owner-cal-blocked); }

/* Ein ganz belegter Tag ist eine Fläche mit heller Zahl. Grau ist der
 * Auffangton: Ein Zustand ohne eigene Farbe soll sichtbar belegt sein,
 * nicht sichtbar frei (#701). */
.owner-month__day--occupied {
    background: var(--owner-cal-blocked);
    color: #fff;
}

/* ---- DIE FARBEN DER BELEGUNG — EINE TABELLE FÜR ALLE DREI STELLEN ----
 *
 * Balken im Raster, ganz belegtes Monatsfeld und Kästchen der Legende
 * tragen dieselbe Klasse `owner-plan__cell--…`. Die Tabelle steht zuletzt,
 * weil über ihr drei Regeln derselben Tiefe ebenfalls einen Hintergrund
 * setzen; die letzte gewinnt. Die Namen sind die Buchungsstatus selbst,
 * damit die Vorlage den Wert aus dem Raster ohne Übersetzungstabelle
 * anhängen kann. */
.owner-plan__cell--booked { background: var(--owner-cal-guest); }
.owner-plan__cell--reserved { background: var(--owner-cal-pending); }
.owner-plan__cell--owner { background: var(--owner-cal-own); }
.owner-plan__cell--blocked { background: var(--owner-cal-blocked); }

/* Der Balken braucht die Tabelle mit zwei Klassen: Seine Grundregel
 * (`.owner-plan__cell .owner-plan__bar`) ist zwei Klassen tief und schlüge
 * die einfachen Zeilen darüber — jeder Balken stünde grau da. */
.owner-plan__bar.owner-plan__cell--booked { background: var(--owner-cal-guest); }
.owner-plan__bar.owner-plan__cell--reserved { background: var(--owner-cal-pending); }
.owner-plan__bar.owner-plan__cell--owner { background: var(--owner-cal-own); }
.owner-plan__bar.owner-plan__cell--blocked { background: var(--owner-cal-blocked); }

/* Heute ist im Monatskalender ein Ring um den Tag — eine Spalte gibt es
 * dort nicht, jede Spalte ist ein Wochentag. */
.owner-month__day--today {
    box-shadow: inset 0 0 0 2px var(--frontend-core-color-text, #111827);
    font-weight: 500;
}

/* Auf dem Telefon werden die Spalten schmaler, damit mehr als eine Woche
 * ins Bild passt. Die Namensspalte bleibt stehen und wird schmaler. */
@media (max-width: 600px) {
    .owner-plan__grid .owner-plan__obj { width: 120px; min-width: 120px; max-width: 120px; padding: 8px 12px; }
    .owner-plan__grid .owner-plan__day,
    .owner-plan__cell { min-width: 28px; }
}

/* Der Hinweis unter den offenen Anfragen: wie man sie entscheidet. */
.owner-open__hint {
    margin: 8px 0 0;
    font-size: .8rem;
    color: var(--color-muted, #6b7280);
}

/* ==========================================================================
   MIETOBJEKTE — Liste, Plan, Objektseite
   ==========================================================================

   Nach `MOCKUP-EIGENTUEMER-MIETOBJEKTE-ENTWURF.html` (V1–V7). Eine Ansicht
   je Seite: Die Übersicht zeigt die Objekte als Liste (oder als Plan), die
   Objektseite den Monatskalender — nie beide für dieselben Tage. */

/* HALBE TAGE ALS FLÄCHE HINTER DER ZIFFER (V4). Der Abreisetag oben links
   belegt, der Anreisetag unten rechts; die Ziffer steht frei darauf und
   bekommt einen hellen Schein, damit sie auf beiden Hälften lesbar bleibt. */
.owner-month__day:is([class*="owner-month__am--"], [class*="owner-month__pm--"]) {
    font-weight: 500;
    text-shadow: 0 0 3px var(--color-surface, #fff), 0 0 3px var(--color-surface, #fff);
}

.owner-month__day--past { opacity: .45; }

.owner-months { --owner-month-min: 420px; }

@media (max-width: 600px) {
    .owner-months { --owner-month-min: 260px; }
}

.object-row__img img,
.owner-plan__thumb img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.object-row__img figure,
.owner-plan__thumb figure { width: 100%; height: 100%; margin: 0; }

/* DIE LISTE DER OBJEKTE (V2b). Die ganze Zeile ist der Link zur
   Objektseite; je Objekt Bild, Name, Ort, heute, nächste Anreise und die
   Auslastung des Monats. */
.objects {
    container-type: inline-size;
    overflow: hidden;
    border: 1px solid var(--color-border, #e5e7eb);
    border-radius: 12px;
    background: var(--color-surface, #fff);
}

.object-row {
    display: grid;
    grid-template-columns: 96px minmax(0, 1.7fr) minmax(0, 1.3fr) minmax(0, .9fr) 120px 24px;
    align-items: center;
    gap: 20px;
    padding: 14px 20px;
    border-top: 1px solid var(--color-border, #e5e7eb);
    color: var(--frontend-core-color-text, #111827);
    text-decoration: none;
}

.object-row:first-child { border-top: 0; }
.object-row:hover { background: var(--color-surface-alt, #f8fafc); }

.object-row__img {
    width: 96px;
    height: 68px;
    overflow: hidden;
    border-radius: 10px;
    background: var(--color-surface-alt, #f8fafc);
}

.object-row__main,
.object-row__cell {
    display: flex;
    flex-direction: column;
    gap: var(--frontend-core-space-1, 4px);
    min-width: 0;
}

.object-row__name {
    overflow: hidden;
    font-weight: 500;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.object-row__meta,
.object-row__sub {
    overflow: hidden;
    font-size: .8rem;
    color: var(--color-muted, #6b7280);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.object-row__key {
    font-size: .7rem;
    font-weight: 500;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--color-muted, #6b7280);
}

.object-row__value { font-weight: 500; font-variant-numeric: tabular-nums; }

.object-row__state {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-weight: 500;
}

.object-row__state::before {
    content: '';
    flex: 0 0 8px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: currentColor;
}

.object-row__state--booked { color: var(--owner-cal-guest); }
.object-row__state--reserved { color: var(--owner-cal-pending); }
.object-row__state--owner { color: var(--owner-cal-own); }
.object-row__state--blocked { color: var(--owner-cal-blocked); }
.object-row__state--free { color: var(--color-muted, #6b7280); }

.object-row__bar {
    display: block;
    height: 6px;
    margin-top: var(--frontend-core-space-1, 4px);
    overflow: hidden;
    border-radius: 6px;
    background: var(--owner-cal-free);
}

.object-row__fill {
    display: block;
    height: 100%;
    border-radius: 6px;
    background: var(--owner-cal-guest);
}

.object-row__go { color: var(--color-muted, #6b7280); }

/* NACH DER BREITE DER LISTE, NICHT DES FENSTERS. Die Liste steht auch in
 * schmalen Spalten — und im Bauplan in einem 375-px-Rahmen auf einem
 * breiten Bildschirm, wo eine Fensterregel nie greift. */
@container (max-width: 760px) {
    .object-row {
        grid-template-columns: 72px minmax(0, 1fr) 20px;
        gap: 6px 14px;
        padding: 12px 14px;
    }

    .object-row__img { grid-row: span 3; width: 72px; height: 54px; }
    .object-row__cell { grid-column: 2; flex-direction: row; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; }
    .object-row__bar { display: none; }
    .object-row__name,
    .object-row__meta { white-space: normal; }
    .object-row__go { grid-column: 3; grid-row: 1; }
}

/* Der Hauptknopf der Seitenköpfe („Eigenbelegung eintragen") füllt auf dem
   Telefon die Breite, wie im Entwurf: eine breite Fläche für den Daumen,
   darüber der Umschalter. */
@media (max-width: 760px) {
    .page-head__actions { flex: 1 1 100%; }

    .page-head__actions > .btn--primary {
        flex: 1 1 100%;
        justify-content: center;
    }
}

/* Die Namensspalte des Plans: Bild, Name, Ort und darunter Auslastung und
   nächste Anreise (V2). Die Zeile ist der Link zur Objektseite. */
.owner-plan__name {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
    padding: 10px 16px;
    color: var(--frontend-core-color-text, #111827);
    text-decoration: none;
}

.owner-plan__thumb {
    flex: 0 0 40px;
    width: 40px;
    height: 40px;
    overflow: hidden;
    border-radius: 8px;
    background: var(--color-surface-alt, #f8fafc);
}

.owner-plan__label {
    display: flex;
    flex-direction: column;
    min-width: 0;
    font-weight: 500;
}

.owner-plan__label > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.owner-plan__place,
.owner-plan__facts {
    font-size: .75rem;
    font-weight: 400;
    color: var(--color-muted, #6b7280);
    font-variant-numeric: tabular-nums;
}

.owner-plan__cell { height: 72px; }

/* Auf dem Telefon fehlt der Platz für das Bild; der Name bekommt die
   Spalte und darf umbrechen. */
@media (max-width: 600px) {
    .owner-plan__grid .owner-plan__obj { width: 140px; min-width: 140px; max-width: 140px; }
    .owner-plan__thumb { display: none; }
    .owner-plan__name { padding: 8px 10px; }
    .owner-plan__label > span:first-child { white-space: normal; }
}

/* KOMMENDE BELEGUNGEN auf der Objektseite: Zeitraum, Gast oder Art,
   Stand, Nächte. Am Telefon zwei Zeilen. */
.upcoming { margin: 0; padding: 0; list-style: none; container-type: inline-size; }

.upcoming__item {
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr) 140px 80px auto;
    align-items: center;
    gap: 12px;
    padding: 12px 0;
    border-top: 1px solid var(--color-border, #e5e7eb);
}

.upcoming__item:first-child { border-top: 0; }
.upcoming__dates { font-weight: 500; font-variant-numeric: tabular-nums; white-space: nowrap; }
.upcoming__who { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.upcoming__nights { text-align: right; font-size: .85rem; color: var(--color-muted, #6b7280); }
.upcoming__actions { display: flex; gap: 8px; justify-content: flex-end; }

@container (max-width: 640px) {
    .upcoming__item { grid-template-columns: minmax(0, 1fr) auto; gap: 4px 12px; }
    .upcoming__who { grid-column: 1; }
    .upcoming__nights { grid-row: 1; grid-column: 2; }
    .upcoming__actions { grid-column: 1 / -1; justify-content: flex-start; }
}


/* ==========================================================================
   UNTERLAGEN — der Bereich „Unterlagen"

   Nach `MOCKUP-UNTERLAGEN-ENTWURF.html` (C und D), Bauplan
   `MOCKUP-EIGENTUEMERLOGIN.html`, Abschnitt „Unterlagen". Zwei Bauteile:

   `owner-docs` ist die Liste: Gruppen mit kleiner Überschrift in Versalien,
   darunter Zeilen mit Haarlinie dazwischen. Eine Zeile hat drei Spalten —
   Unterlage, Datum, Knopf. Am Telefon wird die Zeile zur Karte: Das Datum
   wandert in die Zeile darunter (`owner-doc__when`), „Öffnen" nimmt die
   volle Breite, damit ihn der Daumen trifft.

   `owner-doc` ist die Zelle: Zeichen der Dateiart in einem ruhigen Feld,
   Titel mit der Marke „Neu", darunter Art, Größe und für welches Objekt
   sie gilt. „Neu" ist `status-pill--info` in der Hausfarbe der Anfrage —
   eine Unterlage hat keinen Buchungsstatus.
   ========================================================================== */
.owner-docs__group + .owner-docs__group { margin-top: var(--frontend-core-space-5); }

.owner-docs__title {
    margin: 0 0 var(--frontend-core-space-2);
    font-size: .75rem;
    font-weight: var(--frontend-core-fw-medium);
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--frontend-core-color-muted);
}

.owner-docs__row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto auto;
    align-items: center;
    gap: var(--frontend-core-space-3) var(--frontend-core-space-4);
    padding: var(--frontend-core-space-3) 0;
    border-top: 1px solid var(--frontend-core-color-line);
}

.owner-docs__title + .owner-docs__row { border-top: 0; }

.owner-docs__date {
    font-size: .8rem;
    color: var(--frontend-core-color-muted);
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.owner-doc {
    display: flex;
    align-items: center;
    gap: var(--frontend-core-space-3);
    min-width: 0;
}

.owner-doc__type {
    display: inline-flex;
    flex: 0 0 36px;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: var(--frontend-core-radius-sm);
    background: var(--frontend-core-color-surface-alt);
    color: var(--frontend-core-color-muted);
}

.owner-doc__main { min-width: 0; }

.owner-doc__title {
    margin: 0;
    font-weight: var(--frontend-core-fw-medium);
    overflow-wrap: anywhere;
}

.owner-doc__title .status-pill { margin-left: var(--frontend-core-space-1); vertical-align: 1px; }

.owner-doc__meta {
    margin: 2px 0 0;
    font-size: .8rem;
    color: var(--frontend-core-color-muted);
}

.owner-doc__when { display: none; }

/* Der Text einer Unterlage — eine Mitteilung der Verwaltung, mit oder ohne
   Datei. In der Schrift des Fließtexts und nicht gedämpft wie die Zeile
   mit Art und Größe: Er IST der Inhalt, nicht seine Beschreibung. Das
   Zeichen der Dateiart steht dann oben am Titel statt mittig neben einem
   Absatz. */
.owner-doc:has(.owner-doc__text) { align-items: flex-start; }

.owner-doc__text {
    margin: var(--frontend-core-space-1) 0 0;
    overflow-wrap: anywhere;
}

@media (max-width: 760px) {
    .owner-docs__row { grid-template-columns: minmax(0, 1fr); }
    .owner-docs__date { display: none; }
    .owner-doc__when { display: inline; }
    .owner-docs__row .btn { width: 100%; justify-content: center; }
}

