/* =============================================================================
   Eingangs-Display -- Hochkant-Kiosk

   Gestaltung nach dem Erscheinungsbild von dymatrix.de: tiefes Marineblau als
   Grund, Mint als einziger Akzent, ruhige Flaechen mit weichen 4px-Radien und
   eine einzige Schriftfamilie. Die gesaettigten Farbflaechen bleiben den
   Toilettenanzeigen vorbehalten -- dort soll das Auge aus vier Metern
   Entfernung zuerst landen.
   ========================================================================== */

/* Proxima Nova ist lizenzpflichtig und liegt nicht bei; Mulish steht ihr in
   Proportion und Duktus am naechsten und laeuft lokal, ohne Internet. */
@font-face {
  font-family: "Dyma Sans";
  src: url("/static/fonts/mulish-latin-400-normal.woff2") format("woff2");
  font-weight: 400;
  font-display: block;
}
@font-face {
  font-family: "Dyma Sans";
  src: url("/static/fonts/mulish-latin-600-normal.woff2") format("woff2");
  font-weight: 600;
  font-display: block;
}
@font-face {
  font-family: "Dyma Sans";
  src: url("/static/fonts/mulish-latin-700-normal.woff2") format("woff2");
  font-weight: 700;
  font-display: block;
}

:root {
  /* Farben aus dem Stylesheet von dymatrix.de */
  --navy: #11263d;        /* --bs-dark */
  --navy-deep: #0c1c2e;
  --navy-2: #17324f;      /* Kartenflaeche auf dunklem Grund */
  --navy-3: #415164;      /* Linien, Punkte */
  --mint: #3fd9bf;        /* --bs-primary */
  --mint-soft: #8ce8d9;   /* --bs-primary-text-emphasis */
  --light: #f4f5f6;       /* --bs-light */
  --light-dim: #9fb2c6;

  --free-bg: var(--mint);
  --free-edge: #65e1cc;
  --free-ink: var(--navy);
  --busy-bg: #dc3545;     /* --bs-danger */
  --busy-edge: #ea868f;
  --busy-ink: #fff;

  --sans: "Dyma Sans", "Proxima Nova", system-ui, sans-serif;

  --radius: 4px;
  --gap: 1.4rem;
  --pad: 1.9rem;
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  /* Der Schriftgrad haengt an Breite UND Hoehe zugleich. Das Hochformat-Layout
     braucht rund 108 Zeilenhoehen in der Senkrechten -- genau die gibt 0.93vh
     her, ob der Monitor nun 1280, 1920 oder 3840 Punkte hoch ist. Nach unten
     wird nicht mehr abgeschnitten: ein fester Mindestwert wuerde auf flachen
     Bildschirmen Inhalt aus dem Bild schieben. */
  font-size: clamp(7px, min(1.62vw, 0.93vh), 34px);
}

body {
  background: var(--navy);
  color: var(--light);
  font-family: var(--sans);
  height: 100svh;
  overflow: hidden;
  cursor: none;
  -webkit-font-smoothing: antialiased;
}

.display {
  display: flex;
  flex-direction: column;
  height: 100svh;
  /* Minimaler Versatz gegen Einbrennen, von display.js gesetzt. */
  transform: translate(var(--shift-x, 0px), var(--shift-y, 0px));
  transition: transform 2s linear;
}

/* Das Raster aus den Einstellungen. Spalten- und Zeilenzahl kommen als
   Custom Properties aus der Vorlage, damit hier und dort dieselbe Zahl gilt.
   Jede Zeile ist gleich hoch (1fr): ein Modul ueber zwei Zeilen nimmt genau ein
   Viertel der Hoehe ein -- "anteilig" heisst hier woertlich anteilig. */
.raster {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: repeat(var(--raster-spalten, 4), 1fr);
  grid-template-rows: repeat(var(--raster-zeilen, 8), 1fr);
  gap: 1px;
  background: rgba(255, 255, 255, 0.08);
  border-top: 1px solid rgba(63, 217, 191, 0.55);
}

.raster__leer {
  grid-column: 1 / -1;
  align-self: center;
  text-align: center;
  font-size: 1.5rem;
  color: var(--light-dim);
}

/* ------------------------------------------------------------------ Kopfzeile */

.masthead {
  flex: none;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--gap);
  padding: 1.6rem var(--pad) 1.3rem;
  background: var(--navy-deep);
}

.masthead__day {
  font-weight: 700;
  font-size: 3.1rem;
  line-height: 1;
  letter-spacing: -0.01em;
}

.masthead__date {
  font-size: 1.25rem;
  color: var(--light-dim);
  margin-top: 0.4rem;
}

.masthead__clock {
  font-weight: 700;
  font-size: 3rem;
  line-height: 1;
  color: var(--mint);
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------- Module */

/* Die Groesse bestimmt das Raster ueber grid-area, das jedes Modul selbst
   traegt -- hier steht nur, wie es sich darin einrichtet. min-height/min-width
   muessen sein: ohne sie sprengt langer Inhalt sein Rasterfeld auf. */
.module {
  padding: 1.5rem var(--pad) 1.6rem;
  min-height: 0;
  min-width: 0;
  overflow: hidden;
  background: var(--navy);
  display: flex;
  flex-direction: column;
  /* Groessen-Container: der Inhalt kann sich auf die Hoehe seines Rasterfeldes
     beziehen (cqh). Ein flach gezogenes Modul schrumpft dann seine Schrift,
     statt unten abgeschnitten zu werden. */
  container-type: size;
}

.module__head {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1.1rem;
  flex: none;
}

.module__eyebrow {
  font-weight: 700;
  font-size: min(1.6rem, 20cqh);
  color: var(--mint);
  white-space: nowrap;
}

/* Die Linie laeuft aus dem Titel heraus bis an den Rand. */
.module__head::after {
  content: "";
  flex: 1;
  height: 1px;
  background: rgba(255, 255, 255, 0.14);
}

.module__body {
  min-height: 0;
  flex: 1;
  display: flex;
  flex-direction: column;
}

.empty {
  font-size: 1.35rem;
  color: var(--light-dim);
  margin: auto 0;
}

/* --------------------------------------------------------------- Mittagstisch */

.lunch__pages {
  position: relative;
  flex: 1;
  min-height: 0;
}

.lunch__page {
  position: absolute;
  inset: 0;
  display: grid;
  grid-auto-rows: 1fr;
  gap: var(--gap);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.7s ease;
}

.lunch__page.is-active {
  opacity: 1;
  visibility: visible;
}

.card {
  background: var(--navy-2);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: var(--radius);
  padding: 1rem 1.3rem 0.7rem;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}

.card__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex: none;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.09);
}

.card__name {
  font-weight: 700;
  font-size: 1.95rem;
  line-height: 1.1;
  letter-spacing: -0.01em;
}

.card__address {
  font-size: 1.05rem;
  color: var(--light-dim);
  text-align: right;
  white-space: nowrap;
}

.dishes {
  list-style: none;
  margin-top: 0.6rem;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  min-height: 0;
  overflow: hidden;
}

.dish {
  display: flex;
  align-items: baseline;
  gap: 0.8rem;
  font-size: 1.45rem;
  line-height: 1.25;
}

.dish__name {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.dish__note {
  color: var(--light-dim);
  font-size: 1.05rem;
}

/* Geschlossen: der Grund gehoert vollstaendig lesbar hin, auch ueber zwei
   Zeilen -- er ist die eigentliche Auskunft. */
.dish--closed .dish__name {
  white-space: normal;
}

.dish--closed .dish__note {
  display: block;
}

.dish__price {
  font-weight: 700;
  font-size: 1.4rem;
  color: var(--mint-soft);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.card__foot {
  margin-top: auto;
  padding-top: 0.35rem;
  font-size: 0.95rem;
  color: var(--light-dim);
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  flex: none;
}

.card__stale {
  color: var(--mint-soft);
}

.lunch__pager {
  display: flex;
  gap: 0.45rem;
  justify-content: center;
  margin-top: 0.9rem;
  flex: none;
}

.lunch__dot {
  width: 0.55rem;
  height: 0.55rem;
  background: var(--navy-3);
  border-radius: 50%;
}

.lunch__dot.is-active {
  background: var(--mint);
}

/* --------------------------------------------------------------------- Spruch */

.quote {
  background: var(--navy-2);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-left: 3px solid var(--mint);
  border-radius: var(--radius);
  padding: 1.2rem 1.5rem;
  /* Fuellt sein Rasterfeld und setzt den Spruch mittig -- so sieht ein hoch
     gezogener Spruch nicht nach vergessenem Leerraum aus. */
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.quote__text {
  /* 1.95rem wie gehabt -- aber nie mehr, als in ein flaches Feld passt. */
  font-size: min(1.95rem, 26cqh);
  line-height: 1.4;
  text-wrap: balance;
}

.quote__author {
  font-weight: 700;
  font-size: min(1.25rem, 16cqh);
  color: var(--mint-soft);
  margin-top: 0.8rem;
}

/* ----------------------------------------------------------------------- Bild */

.picture {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.picture__frame {
  flex: 1;
  min-height: 0;
  background: var(--navy-2);
  border-radius: var(--radius);
  overflow: hidden;
}

.picture__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.picture__caption {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  font-size: 1.1rem;
  color: var(--light-dim);
  flex: none;
}

.picture__credit {
  font-size: 1rem;
  white-space: nowrap;
}

/* ------------------------------------------------------------------- Webseite */
/* Eine fremde Seite bringt ihr eigenes Aussehen mit. Ohne Ueberschrift
   bekommt sie die ganze Kachel, ohne Innenabstand. */

.module--randlos {
  padding: 0;
}

.webframe {
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.webframe__frame {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  /* Kiosk: niemand bedient die Seite, und ein Klick soll nichts ausloesen. */
  pointer-events: none;
}

/* Feste Entwurfsgroesse: das iframe behaelt sie, display.js skaliert es auf die
   Kachel. Zentriert, damit der Rest gleichmaessig an beiden Seiten bleibt. */
.webframe[data-skalieren] .webframe__frame {
  flex: none;
  transform-origin: center;
}

/* ------------------------------------------------------------------ Toiletten */
/* Die einzigen grossen Farbflaechen der Seite. Der Zustand ist dreifach codiert
   -- Farbe, Wort und Symbol -- damit er auch ohne Farbwahrnehmung eindeutig ist. */

.toilets {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--gap);
  flex: 1;
  min-height: 0;
}

.toilet {
  display: flex;
  align-items: center;
  gap: 1.2rem;
  padding: 1.3rem 1.5rem;
  border: 2px solid transparent;
  border-radius: var(--radius);
  min-height: 0;
}

.toilet--free {
  background: var(--free-bg);
  border-color: var(--free-edge);
  color: var(--free-ink);
}

.toilet--busy {
  /* Schraffur wie an einer belegten Tuer: zweite, farbunabhaengige Codierung. */
  background-color: var(--busy-bg);
  background-image: repeating-linear-gradient(
    -45deg,
    rgba(0, 0, 0, 0.16) 0 10px,
    transparent 10px 20px
  );
  border-color: var(--busy-edge);
  color: var(--busy-ink);
}

.toilet__icon {
  width: 3.4rem;
  height: 3.4rem;
  flex: none;
}

.toilet__text {
  min-width: 0;
}

.toilet__label {
  font-weight: 600;
  font-size: 1.45rem;
  opacity: 0.8;
}

.toilet__state {
  font-weight: 700;
  font-size: 3rem;
  line-height: 1.05;
  letter-spacing: -0.01em;
}

/* ------------------------------------------------------------------- Fusszeile */

.colophon {
  padding: 0.7rem var(--pad) 1rem;
  font-size: 0.95rem;
  color: #5b6f86;
  display: flex;
  justify-content: space-between;
}

/* ------------------------------------------------------------------- Querformat */
/* Ist der Bildschirm breiter als hoch, fehlt es an Hoehe, nicht an Breite.
   Dann stehen die Mittagskarten nebeneinander statt untereinander -- das
   spart den groessten Block in der Senkrechten, und der Schriftgrad darf
   wieder deutlich groesser ausfallen. */

@media (min-aspect-ratio: 1/1) {
  html {
    font-size: clamp(7px, min(1.15vw, 1.42vh), 34px);
  }

  /* Die Senkrechte ist knapp: weniger Luft ueber und unter den Modulen. */
  .module {
    padding: 1rem var(--pad) 1.1rem;
  }

  .module__head {
    margin-bottom: 0.7rem;
  }

  /* So viele Spalten, wie mit 22rem Mindestbreite hineinpassen. Bei mehr
     Karten je Seite entstehen weitere Reihen, die sich die Hoehe teilen. */
  .lunch__page {
    grid-template-columns: repeat(auto-fit, minmax(22rem, 1fr));
  }
}

@media (prefers-reduced-motion: reduce) {
  .display,
  .lunch__page {
    transition: none;
  }
}
