/* Bühne und Folien der Speisekarten-Monitore.
 *
 * Lag früher als <style>-Block im Player-Component. Jetzt eine echte Datei, weil
 * dieselben Regeln zwei Arten von DOM gestalten müssen: das von Blazor gerenderte
 * und das, was der clientseitige Player selbst einfügt. Ein scoped .razor.css
 * ginge dafür nicht — es hängt seine Regeln an b-xxxxx-Attribute, die per
 * JavaScript erzeugte Knoten nicht tragen.
 *
 * Zielplattform ist unter anderem Chromium M94 (Samsung Tizen 7): kein Nesting,
 * kein :has(), kein color-mix(), keine Container-Queries. Erlaubt und hier
 * benutzt: inset (M87), aspect-ratio (M88), Flex-gap (M84), clamp() (M79),
 * Custom Properties.
 */

    .signage-stage {
        position: fixed;
        inset: 0;
        overflow: hidden;
        background: #0b0d11;
        color: #f4f5f7;
    }

    .signage-layer {
        position: absolute;
        inset: 0;
        display: flex;
        align-items: center;
        justify-content: center;
    }

    .signage-media {
        width: 100%;
        height: 100%;
        object-fit: cover;
        /* Applies the slide's own zoom even without a Ken-Burns/pan effect. */
        transform: scale(var(--img-zoom, 1));
    }

    /* Transitions are animations (not CSS transitions): a freshly rendered layer
       plays them right away, without a second render pass to flip a class. */
    .enter-none { animation: none; }
    .enter-fade { animation: signage-fade-in var(--slide-transition, 600ms) ease both; }
    .enter-slide-left { animation: signage-slide-left var(--slide-transition, 600ms) ease both; }
    .enter-slide-right { animation: signage-slide-right var(--slide-transition, 600ms) ease both; }
    .enter-slide-up { animation: signage-slide-up var(--slide-transition, 600ms) ease both; }
    .enter-slide-down { animation: signage-slide-down var(--slide-transition, 600ms) ease both; }
    .enter-zoom { animation: signage-zoom-in var(--slide-transition, 600ms) ease both; }
    .enter-flip { animation: signage-flip-in var(--slide-transition, 600ms) ease both; }

    .exit-none { opacity: 0; }
    .exit-fade { animation: signage-fade-out var(--slide-transition, 600ms) ease both; }

    @keyframes signage-fade-in { from { opacity: 0; } to { opacity: 1; } }
    @keyframes signage-fade-out { from { opacity: 1; } to { opacity: 0; } }
    @keyframes signage-slide-left { from { transform: translateX(100%); } to { transform: translateX(0); } }
    @keyframes signage-slide-right { from { transform: translateX(-100%); } to { transform: translateX(0); } }
    @keyframes signage-slide-up { from { transform: translateY(100%); } to { transform: translateY(0); } }
    @keyframes signage-slide-down { from { transform: translateY(-100%); } to { transform: translateY(0); } }
    @keyframes signage-zoom-in { from { opacity: 0; transform: scale(1.15); } to { opacity: 1; transform: scale(1); } }
    @keyframes signage-flip-in {
        from { opacity: 0; transform: perspective(1200px) rotateY(90deg); }
        to { opacity: 1; transform: perspective(1200px) rotateY(0); }
    }

    /* Slow motion on stills so a static image does not look frozen. */
    .fx-ken-burns { animation: signage-ken-burns var(--slide-duration, 10s) ease-out both; }
    .fx-zoom-out { animation: signage-zoom-out var(--slide-duration, 10s) ease-out both; }
    .fx-pan-left { animation: signage-pan-left var(--slide-duration, 10s) ease-in-out both; }
    .fx-pan-right { animation: signage-pan-right var(--slide-duration, 10s) ease-in-out both; }

    @keyframes signage-ken-burns {
        from { transform: scale(var(--img-zoom, 1)) translate(0, 0); }
        to { transform: scale(calc(var(--img-zoom, 1) * 1.12)) translate(-2%, -2%); }
    }

    @keyframes signage-zoom-out {
        from { transform: scale(calc(var(--img-zoom, 1) * 1.12)); }
        to { transform: scale(var(--img-zoom, 1)); }
    }

    @keyframes signage-pan-left {
        from { transform: scale(calc(var(--img-zoom, 1) * 1.08)) translateX(2%); }
        to { transform: scale(calc(var(--img-zoom, 1) * 1.08)) translateX(-2%); }
    }

    @keyframes signage-pan-right {
        from { transform: scale(calc(var(--img-zoom, 1) * 1.08)) translateX(-2%); }
        to { transform: scale(calc(var(--img-zoom, 1) * 1.08)) translateX(2%); }
    }

    @media (prefers-reduced-motion: reduce) {
        .signage-layer, .signage-media { animation: none !important; }
    }

    .signage-menu {
        width: 100%;
        height: 100%;
        padding: 4vh 5vw;
        display: flex;
        flex-direction: column;
        gap: 1.5vh;
        color: var(--menu-text, #f4f5f7);
        font-family: var(--menu-font, inherit);
        font-weight: var(--menu-weight, inherit);
        background: var(--menu-bg2, #0b0d11);
        background: radial-gradient(circle at 20% 0%, var(--menu-bg, #1b2030) 0%, var(--menu-bg2, #0b0d11) 70%);
    }

    .signage-menu-headline {
        margin: 0;
        font-size: clamp(2rem, 5vw, 4.5rem);
        font-weight: var(--menu-headline-weight, 800);
        font-family: var(--menu-headline-font, var(--menu-font, inherit));
        color: var(--menu-headline-color, var(--menu-text, #f4f5f7));
        letter-spacing: -.02em;
    }

    .signage-menu-subline {
        margin: 0;
        font-size: clamp(1rem, 2vw, 1.75rem);
        font-weight: var(--menu-subline-weight, inherit);
        font-family: var(--menu-subline-font, var(--menu-font, inherit));
        color: var(--menu-subline-color, #9aa3b2);
    }

    .signage-menu-empty { color: #9aa3b2; }

    /* Free text keeps the operator's line breaks — it is usually a short notice
       or a list of allergens, not a paragraph. */
    .signage-menu-text {
        margin: 0;
        white-space: pre-line;
        font-size: clamp(.9rem, 1.6vw, 1.6rem);
        color: #d6dbe4;
    }

    .signage-menu-grid {
        flex: 1;
        display: grid;
        grid-template-columns: repeat(var(--menu-columns, 3), minmax(0, 1fr));
        /* Die Zeilen teilen sich die Hoehe der Folie. Ohne diese Vorgabe wuchs jede Karte
           mit ihrem 4:3-Bild ueber die Zeile hinaus, und bei drei Reihen mit Fotos schnitt
           das Raster Name und Preis ab - ein Menueboard, das nur noch Bildstreifen zeigte. */
        grid-auto-rows: minmax(0, 1fr);
        gap: 2vh 2vw;
        align-content: start;
        overflow: hidden;
    }

    .signage-card {
        background: rgba(255, 255, 255, .05);
        border: 1px solid rgba(255, 255, 255, .08);
        border-radius: 1rem;
        overflow: hidden;
        display: flex;
        flex-direction: column;
    }

    .signage-card img {
        width: 100%;
        aspect-ratio: 4 / 3;
        object-fit: cover;
        /* 4:3 ist die Wunschgroesse; wird die Zeile knapp, gibt das Bild nach und
           der Ausschnitt wird flacher - Name und Preis bleiben immer im Bild. */
        flex: 0 1 auto;
        min-height: 0;
    }

    .signage-card-body {
        padding: 1.2vh 1.2vw;
        display: flex;
        justify-content: space-between;
        align-items: baseline;
        gap: 1rem;
        font-size: clamp(1rem, 1.8vw, 2rem);
    }

    .signage-card-text {
        display: flex;
        flex-direction: column;
        min-width: 0;
    }

    /* Die Beschreibung soll den Namen stützen, nicht mit ihm konkurrieren: auf
       einem Monitor aus fünf Metern Entfernung liest der Gast zuerst „Döner-Menü“
       und erst dann, was dazugehört. */
    .signage-card-text .description,
    .signage-menu-list .description {
        display: block;
        font-size: .62em;
        opacity: .72;
        line-height: 1.25;
    }

    /* Ein Kombiangebot ist der Grund, warum die Speisekarte hängt — es darf sich
       von den Einzelgerichten abheben. */
    .signage-card.is-menu {
        background: rgba(255, 200, 87, .10);
        border-color: rgba(255, 200, 87, .38);
    }

    .signage-menu-list li.is-menu .name {
        color: var(--menu-accent, #ffe6a8);
    }

    /* Preise mit Tabellenziffern: in einer Liste untereinander stehen „9,50“ und
       „12,00“ dann ziffernbündig. Die Schrift selbst bleibt die vom Betreiber
       gewählte (--menu-font) — ein Speisekarten-Monitor ist Markenfläche, kein
       Bon. font-variant-numeric kann M94 (Chrome 52+). */
    .signage-card-body .price,
    .signage-menu-list .price {
        font-weight: 700;
        color: var(--menu-accent, #ffc857);
        white-space: nowrap;
        font-variant-numeric: tabular-nums;
    }

    /* Ausverkauft: ruhig durchgestrichen statt entfernt — der Gast sieht, dass es
       das Gericht gibt, nur gerade nicht. Der Badge ist ein zusätzlicher, expliziter
       Hinweis und daher standardmäßig aus. */
    .signage-card.is-out-of-stock,
    .signage-menu-list li.is-out-of-stock {
        opacity: .55;
    }

    .signage-card.is-out-of-stock .name,
    .signage-menu-list li.is-out-of-stock .name {
        text-decoration: line-through;
    }

    .signage-oos-badge {
        display: inline-block;
        margin-left: .5em;
        padding: .1em .5em;
        border-radius: .3em;
        font-size: .55em;
        font-weight: 700;
        text-decoration: none;
        text-transform: uppercase;
        letter-spacing: .03em;
        color: #2a1200;
        background: #ffb84d;
        vertical-align: middle;
    }

    /* Kennzeichnung (LMIV). Bewusst leise: die Kürzel gehören zum Gericht, nicht ins
       Blickfeld — ein Gast, der sie braucht, sucht sie, alle anderen lesen darüber hinweg.
       Deshalb hochgestellt, klein und gedämpft statt als weiteres Abzeichen; die einzige
       auffällige Marke auf dieser Karte bleibt „Ausverkauft". */
    .signage-labels {
        margin-left: .35em;
        font-size: .5em;
        font-weight: 600;
        letter-spacing: .04em;
        color: rgba(214, 219, 228, .75);
        vertical-align: super;
        white-space: nowrap;
    }

    .signage-menu-legend {
        margin: 1.2vh 0 0;
        display: flex;
        flex-wrap: wrap;
        column-gap: 1.4em;
        row-gap: .3em;
        font-size: clamp(.7rem, 1.1vw, 1.1rem);
        color: rgba(214, 219, 228, .7);
    }

    .signage-legend-item b {
        font-weight: 700;
        color: rgba(255, 255, 255, .85);
        margin-right: .3em;
    }

    .signage-menu-list {
        flex: 1;
        list-style: none;
        margin: 0;
        padding: 0;
        display: flex;
        flex-direction: column;
        gap: 1.4vh;
        overflow: hidden;
        font-size: clamp(1rem, 2.2vw, 2.4rem);
    }

    .signage-menu-list li {
        display: flex;
        align-items: baseline;
        gap: .75rem;
    }

    .signage-menu-list .name {
        min-width: 0;
    }

    .signage-menu-list .dots {
        flex: 1;
        border-bottom: 2px dotted rgba(255, 255, 255, .2);
        transform: translateY(-.35em);
    }

    .signage-idle {
        position: absolute;
        inset: 0;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: .75rem;
        text-align: center;
        padding: 2rem;
    }

    .signage-idle i { font-size: 4rem; color: #e63946; }
    .signage-idle p { color: #9aa3b2; max-width: 34rem; }

    /* Vorbereitete, noch unsichtbare Folie.
       Bewusst opacity:0 statt display:none oder visibility:hidden — beide
       überspringen das Paint, wodurch Dekodierung und GPU-Upload wieder auf der
       Folengrenze landeten. Genau der Ruckler, den das Vorbereiten beseitigt. */
    .signage-layer.is-staged {
        opacity: 0;
        pointer-events: none;
    }

    /* =====================================================================
       Erweiterte Folien: Sektionen, Hintergrundbild, Logo, Textskalierung,
       Overlay auf Bildfolien.

       Alles hängt an Custom Properties mit Vorgabewerten. Eine Folie, die keine
       davon setzt, rendert exakt wie zuvor — genau das ist die Bedingung dafür,
       dass laufende Monitore von der Erweiterung nichts merken.
       ===================================================================== */

    /* Textskalierung. Ein Board mit sechs Gerichten und eines mit vierzig
       brauchen verschiedene Schriftgrößen, und das Stylesheet kann nicht wissen,
       welches gerade hängt. 1 ist die Identität. */
    .signage-menu {
        font-size: calc(1em * var(--menu-text-scale, 1));
    }

    /* Hintergrundbild liegt UNTER dem Inhalt, mit eigener Abdunkelung. Als
       Pseudo-Element und nicht als background des Containers, weil sonst der
       Scrim auch den Text mit abdunkeln würde. */
    .signage-menu.has-bg-image {
        position: relative;
        background: #0b0d11;
    }

    .signage-menu.has-bg-image::before {
        content: "";
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        background-image: var(--menu-bg-image);
        background-size: var(--menu-bg-size, cover);
        background-position: center;
        background-repeat: no-repeat;
        z-index: 0;
    }

    /* Der Scrim. Ohne ihn ist Text über einem beliebigen Foto Glückssache:
       dasselbe Bild, das hinter einer Überschrift gut liest, schluckt eine
       Preisliste. */
    .signage-menu.has-bg-image::after {
        content: "";
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        background: #000;
        opacity: var(--menu-bg-overlay, .45);
        z-index: 0;
    }

    .signage-menu.has-bg-image > * {
        position: relative;
        z-index: 1;
    }

    /* Logo */
    .signage-logo {
        position: absolute;
        height: var(--menu-logo-size, 10%);
        width: auto;
        max-width: 30%;
        object-fit: contain;
        z-index: 2;
    }

    .signage-logo.logo-top-left { top: 3vh; left: 3vw; }
    .signage-logo.logo-top-right { top: 3vh; right: 3vw; }
    .signage-logo.logo-bottom-left { bottom: 3vh; left: 3vw; }
    .signage-logo.logo-bottom-right { bottom: 3vh; right: 3vw; }

    /* -----------------------------------------------------------------
       Sektionen
       ----------------------------------------------------------------- */

    .signage-sections {
        flex: 1;
        min-height: 0;
        display: grid;
        gap: 2vh 3vw;
    }

    /* Untereinander: jede Sektion so hoch, wie sie braucht, die letzte füllt auf. */
    .signage-sections.as-stacked {
        grid-auto-flow: row;
        grid-auto-rows: minmax(0, auto);
        align-content: start;
    }

    /* Nebeneinander — die Form einer gedruckten Speisekarte. Die Spaltenbreiten
       kommen aus den Gewichten der Sektionen: Gerichte brauchen meist mehr Platz
       als eine Getränkeliste. */
    .signage-sections.as-columns {
        grid-auto-flow: column;
        grid-template-columns: var(--menu-section-columns, 1fr);
        align-items: start;
    }

    .signage-section {
        display: flex;
        flex-direction: column;
        gap: 1vh;
        min-width: 0;
        min-height: 0;
    }

    .signage-section-heading {
        margin: 0;
        font-size: clamp(1.2rem, 2.6vw, 2.4rem);
        font-weight: var(--menu-headline-weight, 700);
        font-family: var(--menu-headline-font, var(--menu-font, inherit));
        color: var(--menu-accent, #ffc857);
        letter-spacing: -.01em;
        border-bottom: 2px solid currentColor;
        padding-bottom: .3em;
    }

    /* -----------------------------------------------------------------
       Textoverlay auf Bildfolien
       ----------------------------------------------------------------- */

    .signage-overlay {
        position: absolute;
        left: 0;
        right: 0;
        display: flex;
        padding: 4vh 5vw;
        color: var(--overlay-text, #f4f5f7);
        font-family: var(--overlay-font, inherit);
        z-index: 1;
    }

    .signage-overlay.overlay-top { top: 0; align-items: flex-start; }
    .signage-overlay.overlay-center { top: 0; bottom: 0; align-items: center; }
    .signage-overlay.overlay-bottom { bottom: 0; align-items: flex-end; }

    /* Abdunkelung nur hinter dem Textblock, nicht über dem ganzen Foto — sonst
       verliert das Bild genau die Wirkung, wegen der es gewählt wurde. */
    .signage-overlay::before {
        content: "";
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        background: #000;
        opacity: var(--overlay-darken, .4);
        z-index: 0;
    }

    .signage-overlay-inner {
        position: relative;
        z-index: 1;
        display: flex;
        flex-direction: column;
        gap: .4vh;
    }

    .signage-overlay-headline {
        margin: 0;
        font-size: clamp(2rem, 6vw, 6rem);
        font-weight: 800;
        line-height: 1.05;
        letter-spacing: -.02em;
    }

    .signage-overlay-subline {
        margin: 0;
        font-size: clamp(1rem, 2.4vw, 2.4rem);
        opacity: .85;
    }

    .signage-overlay-price {
        margin: .4vh 0 0;
        font-size: clamp(1.6rem, 4.5vw, 4.5rem);
        font-weight: 800;
        color: var(--overlay-accent, #ffc857);
        font-variant-numeric: tabular-nums;
    }
