/* Kistn App - Terminal. Ein Geraet an der Wand, keine Website.
   Dunkel, Monospace fuer alles Maschinelle, duenne gluehende Kanten,
   dreistellige Produktcodes statt Emojis. */

/* ---------------------------------------------------------------- Schriften

   Selbst gehostet statt Google Fonts: das Tablet haengt im Gastraum an einem
   Netz, auf das man sich nicht verlassen kann. Beide sind variable Fonts -
   eine Datei je Subset deckt alle Gewichte ab. */

@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/archivo-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/archivo-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 100 800;
  font-display: swap;
  src: url('/fonts/jetbrains-mono-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 100 800;
  font-display: swap;
  src: url('/fonts/jetbrains-mono-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ---------------------------------------------------------------- Tokens

   Der Entwurf ist ausschliesslich dunkel - es gibt keine helle Variante mehr,
   also auch keine prefers-color-scheme-Umschaltung.
   Jeder oklch-Wert steht hinter einem Hex-Fallback: Browser ohne oklch()
   verwerfen die zweite Deklaration und behalten den Ersatzton.

   Dunkelblau seit 17.08.2026. Geaendert wurden ausschliesslich die Farben hier
   im Block - Maße, Abstaende und Formen sind unangetastet geblieben.
   Rot, Gruen und Orange bleiben ebenfalls, wie sie waren: sie bedeuten etwas
   (Schuld, Guthaben, nah am Limit) und duerfen sich nicht dem Farbton anpassen.

   Die Linien sind leicht blau eingefaerbt statt rein weiss - reines Weiss auf
   Blau wirkt grau und schmutzig. */
:root {
  --bg: #0b1120;
  --bg-deep: #060a14;
  --surface: #131c30;
  --surface-2: #0e1627;
  --surface-3: #10192b;

  --hairline: rgba(150, 180, 235, .12);
  --hairline-soft: rgba(150, 180, 235, .08);
  --border-el: rgba(150, 180, 235, .15);
  --border-el-2: rgba(150, 180, 235, .18);
  --border-btn: rgba(150, 180, 235, .22);
  --border-inv: rgba(150, 180, 235, .26);
  --track: rgba(150, 180, 235, .12);

  --text: #e7ecf6;
  --muted: #93a0b8;
  --muted-2: #74829c;
  --muted-3: #566379;

  --accent: #b9cdf2;
  --accent: oklch(0.84 0.055 260);
  --accent-08: rgba(185, 205, 242, .08);
  --accent-08: oklch(0.84 0.055 260 / .08);
  --accent-07: rgba(185, 205, 242, .07);
  --accent-07: oklch(0.84 0.055 260 / .07);
  --accent-35: rgba(185, 205, 242, .35);
  --accent-35: oklch(0.84 0.055 260 / .35);
  --accent-45: rgba(185, 205, 242, .45);
  --accent-45: oklch(0.84 0.055 260 / .45);
  --accent-55: rgba(185, 205, 242, .55);
  --accent-55: oklch(0.84 0.055 260 / .55);
  --accent-glow: rgba(185, 205, 242, .16);
  --accent-glow: oklch(0.84 0.055 260 / .16);

  --warn: #e2a04f;
  --warn: oklch(0.8 0.13 60);
  --warn-line: rgba(215, 143, 55, .45);
  --warn-line: oklch(0.75 0.13 60 / .45);
  --warn-fill: rgba(215, 143, 55, .05);
  --warn-fill: oklch(0.75 0.13 60 / .05);
  --danger: #e8695a;
  --danger: oklch(0.72 0.16 25);
  --danger-line: rgba(206, 82, 68, .70);
  --danger-line: oklch(0.65 0.16 25 / .70);
  --danger-fill: rgba(206, 82, 68, .16);
  --danger-fill: oklch(0.65 0.16 25 / .16);
  --ok: #4dc07d;
  --ok: oklch(0.78 0.14 145);

  --r-sm: 3px;
  --r: 4px;
  --r-md: 5px;
  --r-lg: 6px;
  --r-card-icon: 8px;

  /* Keine weichen Schatten mehr. Tiefe entsteht ueber Hairlines und Gluehen. */
  --glow-sm: 0 0 22px rgba(185, 205, 242, .12);
  --glow-sm: 0 0 22px oklch(0.84 0.055 260 / .12);
  --glow: 0 0 28px rgba(185, 205, 242, .14);
  --glow: 0 0 28px oklch(0.84 0.055 260 / .14);
  --glow-lg: 0 0 48px rgba(185, 205, 242, .16);
  --glow-lg: 0 0 48px oklch(0.84 0.055 260 / .16);
  --glow-card: 0 0 48px oklch(0.84 0.055 260 / .24), inset 0 0 26px oklch(0.84 0.055 260 / .07);
  --lift: 0 20px 50px rgba(2, 5, 14, .55);

  --font: 'Archivo', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, monospace;
}

/* ---------------------------------------------------------------- Keyframes */

@keyframes k-ring { 0% { transform: scale(.5); opacity: 0; } 10% { opacity: .9; } 100% { transform: scale(2); opacity: 0; } }
@keyframes k-rise { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: translateY(0); } }
@keyframes k-tick { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
@keyframes k-fill { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes k-glow { 0%, 100% { opacity: .3; } 50% { opacity: 1; } }
@keyframes k-blink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }
@keyframes k-shimmer { from { background-position: -220% 0; } to { background-position: 220% 0; } }
@keyframes k-draw { from { stroke-dashoffset: 62; } to { stroke-dashoffset: 0; } }
/* --spark-len setzt common.js aus der tatsaechlich gezeichneten Laenge. Der
   Rueckfallwert greift nur, falls die Messung nicht laeuft. */
@keyframes k-draw-long { from { stroke-dashoffset: var(--spark-len, 340); } to { stroke-dashoffset: 0; } }
@keyframes k-pop { 0% { transform: scale(.3); opacity: 0; } 55% { transform: scale(1.14); opacity: 1; } 100% { transform: scale(1); opacity: 1; } }
@keyframes k-scan { from { transform: translateY(-120%); } to { transform: translateY(1000%); } }
@keyframes k-sweep { 0% { transform: translateX(-140%); } 100% { transform: translateX(240%); } }
@keyframes k-sheen { 0% { transform: translateX(-100%); } 60%, 100% { transform: translateX(320%); } }
@keyframes k-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@keyframes k-grid { from { transform: translate(0, 0); } to { transform: translate(48px, 48px); } }
@keyframes k-cycle {
  0% { opacity: 0; transform: translateY(10px); }
  6% { opacity: 1; transform: translateY(0); }
  27% { opacity: 1; transform: translateY(0); }
  33% { opacity: 0; transform: translateY(-10px); }
  100% { opacity: 0; transform: translateY(-10px); }
}
@keyframes k-dot { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(2.6); opacity: .18; } }
@keyframes k-slide-up { from { transform: translateY(120%); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
@keyframes k-drift { 0%, 100% { transform: translateY(0) rotate(0deg); } 50% { transform: translateY(-10px) rotate(.6deg); } }

/* ---------------------------------------------------------------- Grundlage */

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--font);
  background: var(--bg);
  color: var(--text);
  line-height: 1.5;
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
  overflow-x: hidden;
}

h1, h2, h3 { margin: 0; font-weight: 700; letter-spacing: -.025em; line-height: 1.2; }
h1 { font-size: 36px; letter-spacing: -.035em; }
h2 { font-size: 21px; }
h3 { font-size: 17px; letter-spacing: -.02em; }
p { margin: 0; }

button, input, select { font: inherit; color: inherit; }
a { color: var(--accent); }

/* Alles Maschinelle laeuft in Mono und mit gleicher Ziffernbreite - sonst
   zappeln Spalten, sobald sich ein Betrag aendert. */
.mono, .amount, .stat-value, .hero-value, .tile-price, .tile-code {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums lining-nums;
}

.wrap { width: 100%; max-width: 1100px; margin: 0 auto; padding: 22px 24px; }
.wrap-narrow { width: 100%; max-width: 560px; margin: 0 auto; padding: 22px; }

.hidden { display: none !important; }
.muted { color: var(--muted); }
.small { font-size: 14px; }
.tiny { font-size: 12px; }
.center { text-align: center; }
.grow { flex: 1; min-width: 0; }
.row { display: flex; align-items: center; gap: 10px; }
.row-wrap { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.stack { display: flex; flex-direction: column; gap: 12px; }
.stack-sm { display: flex; flex-direction: column; gap: 6px; }

/* Grossbuchstaben-Beschriftung in Mono - die Sprache aller Statuszeilen. */
.label {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--muted);
}

.meta {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--muted-2);
}

/* ---------------------------------------------------------------- Hintergrund

   Driftendes Raster. Liegt hinter allem, faengt keine Tipps ab.
   Das Feld drumherum ist noetig: das Raster ragt 60 px ueber jeden Rand
   hinaus, damit beim Driften keine Kante sichtbar wird. Ohne den
   abschneidenden Rahmen zaehlt dieser Ueberstand zur Seitenhoehe - und der
   Ruhebildschirm bekaeme eine Scrollleiste, obwohl er genau passt. */
.raster-feld {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
}

.raster-drift {
  position: absolute;
  inset: -60px;
  background-image:
    linear-gradient(var(--accent-07) 1px, transparent 1px),
    linear-gradient(90deg, var(--accent-07) 1px, transparent 1px);
  background-size: 48px 48px;
  animation: k-grid 18s linear infinite;
}

.raster-feld.schnell .raster-drift { animation-duration: 14s; }
.raster-feld.langsam .raster-drift { animation-duration: 22s; }

/* Bezugsrahmen fuer Raster, Lichtkegel und alles andere absolut Platzierte. */
#app { position: relative; min-height: 100dvh; }

/* Der Ruhebildschirm bekommt zusaetzlich einen Lichtkegel um das Kartensymbol. */
.kegel {
  position: absolute;
  inset: 0;
  background: radial-gradient(680px 420px at 50% 40%, var(--accent-08), transparent 68%);
  pointer-events: none;
  z-index: 0;
}

/* Lichtwisch quer ueber Kacheln, Karten und Hinweisbalken. */
.sweep {
  position: absolute;
  top: 0;
  left: 0;
  width: 40%;
  height: 100%;
  background: linear-gradient(100deg, transparent, var(--accent-07), transparent);
  animation: k-sweep 4.5s ease-in-out infinite;
  pointer-events: none;
}

/* Glanzstreifen ueber Fortschrittsbalken. */
.sheen {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 60px;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .45), transparent);
  animation: k-sheen 3s ease-in-out infinite;
  pointer-events: none;
}

/* ---------------------------------------------------------------- Marke */

.wortmarke {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: .26em;
  color: var(--accent);
  text-transform: uppercase;
}

.wortmarke.weit { letter-spacing: .3em; }

.statuspunkt {
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
  animation: k-glow 1.8s ease-in-out infinite;
}

/* Punkt, der einen Ring ausstoesst - Schichtleiste und Storno-Anfragen. */
.pulspunkt {
  position: relative;
  flex: none;
  width: 7px;
  height: 7px;
  display: grid;
  place-items: center;
}

.pulspunkt::before,
.pulspunkt::after {
  content: "";
  border-radius: 50%;
  background: var(--accent);
}

.pulspunkt::before { position: absolute; inset: 0; animation: k-dot 2s ease-out infinite; }
.pulspunkt::after { position: relative; width: 7px; height: 7px; }
.pulspunkt.warn::before, .pulspunkt.warn::after { background: var(--warn); }
.pulspunkt.warn::before { animation-duration: 1.8s; }

/* Initialen-Kaestchen. Ersetzt ueberall das Emoji: eckig, Mono, Akzentrahmen. */
.initialen {
  flex: none;
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border-radius: var(--r);
  border: 1px solid var(--accent-35);
  background: var(--accent-07);
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 700;
  color: var(--accent);
  letter-spacing: .02em;
}

.initialen.gross { width: 42px; height: 42px; border-radius: var(--r-md); border-color: var(--accent-45); background: var(--accent-08); font-size: 14px; }
.initialen.klein { width: 36px; height: 36px; font-size: 12px; }
/* In Listen ohne Akzent: das Kaestchen traegt dort nur die Kennung. */
.initialen.still { width: 40px; height: 32px; border-radius: var(--r-sm); border-color: var(--border-el-2); background: transparent; color: var(--muted); font-size: 11px; }

/* ---------------------------------------------------------------- Kopfleiste */

.topbar {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: calc(18px + env(safe-area-inset-top)) 22px 18px;
  border-bottom: 1px solid var(--hairline);
  background: var(--bg);
  z-index: 20;
}

.topbar .who { font-size: 15px; font-weight: 600; }

/* ---------------------------------------------------------------- Karten */

.card {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--r-lg);
  padding: 20px 22px;
}

.card + .card { margin-top: 18px; }
.card-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 14px; }

/* Container ohne Fuellung - Listen mit eigener Kopfzeile (Admin). */
.rahmen {
  border: 1px solid var(--hairline);
  border-radius: var(--r-lg);
  overflow: hidden;
}

.rahmen-kopf {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 15px 22px;
  border-bottom: 1px solid var(--hairline);
  background: var(--surface-3);
}

/* ---------------------------------------------------------------- Knoepfe */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
  touch-action: manipulation;
  user-select: none;
  padding: 11px 18px;
  border-radius: var(--r);
  border: 1px solid var(--border-btn);
  background: transparent;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .06em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color .2s ease, border-color .2s ease, background .2s ease;
}

.btn:hover { color: var(--accent); border-color: var(--accent); background: var(--accent-08); }
.btn:disabled { opacity: .45; cursor: not-allowed; }
.btn:disabled:hover { color: var(--muted); border-color: var(--border-btn); background: transparent; }

.btn-primary { border-color: var(--accent); color: var(--accent); }
.btn-primary:hover { background: oklch(0.84 0.055 260 / .14); }
.btn-danger { border-color: var(--danger-line); color: var(--danger); }
.btn-danger:hover { background: var(--danger-fill); border-color: var(--danger); color: var(--danger); }
.btn-ghost { border-color: transparent; color: var(--muted-2); }
.btn-ghost:hover { border-color: transparent; background: transparent; color: var(--accent); }
.btn-lg { min-height: 48px; padding: 12px 22px; font-size: 13px; }
.btn-block { width: 100%; }

input:focus, select:focus, .btn:focus-visible, button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

/* ---------------------------------------------------------------- Felder */

.field { display: flex; flex-direction: column; gap: 6px; }
.field label {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted-2);
}

input[type=text], input[type=password], input[type=number], input[type=date], input[type=search], select {
  width: 100%;
  padding: 11px 14px;
  border-radius: var(--r-md);
  border: 1px solid var(--border-el);
  background: var(--surface);
  color: var(--text);
  font-size: 15px;
}

input::placeholder { color: var(--muted-3); }

/* ---------------------------------------------------------------- Kennzahlen

   Ein Raster mit 1 px Luecke auf Hairline-Grund: so entstehen echte
   Trennlinien ohne doppelte Kanten an den Beruehrungspunkten. */
.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 1px;
  background: var(--hairline);
  border: 1px solid var(--hairline);
  border-radius: var(--r-lg);
  overflow: hidden;
}

.stat { position: relative; background: var(--surface); padding: 22px; overflow: hidden; }
.stat:has(.stat-value.big) { grid-column: 1 / -1; }

/* Feste Raster dort, wo die grosse Zahl neben den Nebenwerten steht statt
   ueber ihnen: Tablet-Sitzung und Admin-Uebersicht. */
.stats-sitzung { grid-template-columns: 1.45fr 1fr 1fr; }
.stats-admin { grid-template-columns: 2fr 1fr 1fr 1fr; }
.stats-sitzung .stat:has(.stat-value.big),
.stats-admin .stat:has(.stat-value.big) { grid-column: auto; }

.stat-label {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--muted);
}

.stat-value {
  font-size: 34px;
  font-weight: 700;
  letter-spacing: -.02em;
  line-height: 1.1;
  margin-top: 8px;
  white-space: nowrap;
}

.stat-value.big {
  font-size: 62px;
  letter-spacing: -.035em;
  line-height: 1.05;
  color: var(--accent);
  text-shadow: 0 0 34px oklch(0.84 0.055 260 / .32);
}

/* Ganze Zahlen statt Betraege - Admin zaehlt Leute, nicht Euro. */
.stat-value.zahl { font-size: 40px; letter-spacing: 0; }

.stat-sub {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted-2);
  margin-top: 10px;
}

/* Im Detailfenster stehen drei Betraege nebeneinander in gut 160 px Spalten -
   in der grossen Skala wird "300,00 €" dort abgeschnitten. */
.modal .stats { grid-template-columns: repeat(3, 1fr); }
.modal .stat { padding: 14px 10px; }
.modal .stat-label { font-size: 10px; letter-spacing: .08em; }
.modal .stat-value { font-size: 18px; margin-top: 6px; }

.stat.gedaempft .stat-value { color: var(--muted); }
.stat.warn .stat-value { color: var(--warn); }
.stat.bad .stat-value { color: var(--danger); }
.stat.good .stat-value { color: var(--accent); }
.stat.warn .stat-value.big { text-shadow: 0 0 34px oklch(0.8 0.13 60 / .3); }
.stat.bad .stat-value.big { text-shadow: 0 0 34px oklch(0.72 0.16 25 / .3); }

/* ---------------------------------------------------------------- Balken */

.bar {
  position: relative;
  height: 8px;
  border-radius: var(--r-sm);
  background: var(--track);
  overflow: hidden;
}

.bar > span {
  display: block;
  height: 100%;
  background: var(--accent);
  transform-origin: left;
  transition: width .7s cubic-bezier(.2, .9, .3, 1);
  animation: k-fill 1.3s .3s cubic-bezier(.2, .9, .3, 1) both;
}

.bar.warn > span { background: var(--warn); }
.bar.bad > span { background: var(--danger); }
.bar.duenn { height: 6px; }
.bar.mittel { height: 7px; }

.badge {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 4px 9px;
  border-radius: var(--r-sm);
  border: 1px solid var(--border-btn);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}

.badge::before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: currentColor;
  animation: k-glow 1.5s ease-in-out infinite;
}

.badge-warn { border-color: oklch(0.75 0.13 60 / .6); color: var(--warn); }
.badge-bad { border-color: oklch(0.65 0.16 25 / .6); color: var(--danger); }
.badge-muted { border-color: var(--border-btn); color: var(--muted); }
/* Guthaben: mehr gezahlt als offen war. Gute Nachricht, deshalb gruen. */
.badge-ok { border-color: oklch(0.72 0.12 150 / .6); color: var(--ok); }
.badge-ok::before { background: var(--ok); }
.badge-muted::before, .badge-demo::before { display: none; }
.badge-demo {
  padding: 3px 8px;
  font-size: 12px;
  letter-spacing: .12em;
  border-color: var(--accent-45);
  color: var(--accent);
}

/* ---------------------------------------------------------------- Listen */

.list { display: flex; flex-direction: column; }

.list-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 0;
  border-bottom: 1px solid var(--hairline-soft);
}

.list-item:last-child { border-bottom: none; }
.list-item.clickable { cursor: pointer; padding-left: 10px; padding-right: 10px; transition: background .18s ease; }
.list-item.clickable:hover { background: var(--surface); }
.list-item.voided { opacity: .45; }
.list-item.voided .amount { text-decoration: line-through; }
.list-item .name { font-size: 17px; font-weight: 600; }

.amount { font-weight: 700; font-size: 17px; white-space: nowrap; }
.amount.gross { font-size: 20px; }
.amount.pay { color: var(--ok); }
/* Was jemand angeschrieben hat, steht rot; was er gezahlt hat, gruen. In einer
   langen Liste erkennt man dadurch ohne Lesen, wohin eine Zeile zeigt. */
.amount.schuld { color: var(--danger); }

.nav-link { text-decoration: none; color: inherit; }

/* Leerzustand: kein Emoji mehr, nur eine Hairline und der Satz darunter. */
.empty {
  padding: 26px 0 8px;
  border-top: 1px solid var(--hairline);
  margin-top: 4px;
}

.empty p + p { margin-top: 6px; }

/* ---------------------------------------------------------------- Meldungen */

.msg {
  padding: 12px 14px;
  border-radius: var(--r-md);
  border: 1px solid transparent;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .04em;
  line-height: 1.5;
}

.msg-error { border-color: var(--danger-line); color: var(--danger); }
.msg-ok { border-color: var(--accent-45); color: var(--accent); }
.msg-info { border-color: var(--hairline); color: var(--muted); }

/* Einordnender Hinweis ("Testmodus", "kein echtes Geld"). */
.note {
  position: relative;
  overflow: hidden;
  padding: 12px 14px;
  border: 1px solid var(--accent-35);
  border-radius: var(--r-md);
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .06em;
  line-height: 1.6;
  text-transform: uppercase;
  color: var(--accent);
}

.note .sweep { animation-duration: 4.5s; background: linear-gradient(90deg, transparent, oklch(0.84 0.055 260 / .12), transparent); }
.note strong { font-weight: 700; }

/* ---------------------------------------------------------------- Modal */

.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(3, 6, 16, .74);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  z-index: 50;
}

.modal {
  background: var(--surface);
  border-radius: var(--r-lg);
  border: 1px solid var(--border-el);
  box-shadow: var(--lift);
  width: 100%;
  max-width: 560px;
  max-height: 88dvh;
  overflow: auto;
  padding: 0 22px 22px;
}

.modal-zu { flex: none; min-width: 44px; padding: 11px 12px; }

.modal-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--surface);
  padding: 18px 0 14px;
  margin-bottom: 16px;
  border-bottom: 1px solid var(--hairline);
}

/* Die zwei Handgriffe im Personen-Dialog, farblich auseinandergehalten:
   Buchen erhoeht die Schuld (rot), Zahlung senkt sie (gruen). Dieselbe Logik
   wie bei den Betraegen in der Buchungsliste - wer sich einmal daran gewoehnt
   hat, greift nicht mehr daneben. */
.betrag-buchen,
.zahlung-eintragen {
  position: relative;
  margin-top: 18px;
  padding: 16px 16px 18px;
  border: 1px solid;
  border-radius: var(--r-md);
}

.betrag-buchen { border-color: var(--danger-line); background: oklch(0.65 0.16 25 / .07); }
.betrag-buchen h3 { color: var(--danger); }
.betrag-buchen .btn-primary { border-color: var(--danger); color: var(--danger); }
.betrag-buchen .btn-primary:hover:not(:disabled) { background: var(--danger-fill); }

.zahlung-eintragen { border-color: oklch(0.72 0.12 150 / .5); background: oklch(0.72 0.12 150 / .07); }
.zahlung-eintragen h3 { color: var(--ok); }
.zahlung-eintragen .btn-primary { border-color: var(--ok); color: var(--ok); }
.zahlung-eintragen .btn-primary:hover:not(:disabled) { background: oklch(0.72 0.12 150 / .14); }

/* Der Knopf bleibt grau, solange kein gueltiger Betrag drinsteht - sonst
   leuchtet er schon, bevor er etwas tut. */
.betrag-buchen .btn-primary:disabled,
.zahlung-eintragen .btn-primary:disabled { border-color: var(--border-btn); color: var(--muted); }

/* ---------------------------------------------------------------- Reiter */

.tabs {
  display: flex;
  gap: 2px;
  padding: 0 24px;
  border-bottom: 1px solid var(--hairline);
}

.tab {
  padding: 15px 18px;
  border: none;
  border-bottom: 2px solid transparent;
  background: transparent;
  color: var(--muted-2);
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .1em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color .2s ease, border-color .2s ease;
}

.tab:hover { color: var(--text); }
.tab.active { color: var(--text); border-bottom-color: var(--accent); }

/* ---------------------------------------------------------------- Tablet */

.kiosk { min-height: 100vh; display: flex; flex-direction: column; position: relative; }
.kiosk.idle-mode { min-height: 100dvh; }

/* Schichtleiste: wer darf gerade buchen. */
.schicht-leiste {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  padding: 15px 24px;
  border-bottom: 1px solid var(--hairline);
  background: rgba(11, 17, 32, .72);
  font-family: var(--font-mono);
  font-size: 13px;
  letter-spacing: .05em;
  text-transform: uppercase;
}

.schicht-leiste .stark { font-weight: 700; color: var(--text); }
.schicht-leiste .an { color: var(--accent); }
.teiler { width: 1px; height: 14px; background: var(--border-btn); }

.schicht-leiste .btn {
  min-height: 44px;
  padding: 10px 16px;
  font-size: 13px;
  letter-spacing: .05em;
}

/* Ruhebildschirm: Mitte, zentriert, kein Scrollen am Tablet. */
.idle {
  position: relative;
  z-index: 1;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 26px;
  padding: 24px;
  text-align: center;
}

/* Kartensymbol: Karte plus drei ausgestossene Funkwellen. Kein SVG mehr. */
.kartenfeld {
  position: relative;
  width: 320px;
  height: 320px;
  display: grid;
  place-items: center;
  flex: none;
}

.funkwelle {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1px solid var(--accent-45);
  animation: k-ring 3.2s ease-out infinite;
}

.funkwelle:nth-child(2) { animation-delay: 1.07s; }
.funkwelle:nth-child(3) { animation-delay: 2.14s; }

.karte {
  position: relative;
  width: 140px;
  height: 94px;
  border-radius: var(--r-card-icon);
  border: 2px solid var(--accent);
  background: var(--surface);
  box-shadow: var(--glow-card);
  overflow: hidden;
  display: flex;
  align-items: center;
  padding-left: 20px;
  animation: k-drift 6s ease-in-out infinite;
}

.karte-chip {
  width: 28px;
  height: 21px;
  border-radius: var(--r-sm);
  border: 1px solid oklch(0.84 0.055 260 / .7);
  background: oklch(0.84 0.055 260 / .16);
}

.karte .sweep {
  width: 40%;
  background: linear-gradient(90deg, transparent, oklch(0.84 0.055 260 / .18), transparent);
  animation-duration: 3.4s;
}

.idle-title {
  font-size: 46px;
  font-weight: 700;
  letter-spacing: -.032em;
  line-height: 1.1;
}

/* Blockcursor hinter der Ueberschrift - das Geraet wartet auf Eingabe. */
.cursor {
  display: inline-block;
  width: 14px;
  height: 40px;
  margin-left: 10px;
  vertical-align: -7px;
  background: var(--accent);
  animation: k-blink 1.05s step-end infinite;
}

/* Wechselnde Hinweiszeile: drei Zeilen uebereinander, versetzt eingeblendet. */
.hinweis-zyklus {
  position: relative;
  height: 20px;
  width: 560px;
  max-width: 100%;
  font-family: var(--font-mono);
  font-size: 13px;
  letter-spacing: .11em;
  text-transform: uppercase;
  color: var(--muted);
}

.hinweis-zyklus > * {
  position: absolute;
  inset: 0;
  opacity: 0;
  animation: k-cycle 12s ease-in-out infinite;
}

/* Kartenleiste im Testmodus. */
.sim-bar {
  position: relative;
  z-index: 1;
  padding: 18px 24px 20px;
  border-top: 1px solid var(--hairline);
  background: var(--surface-2);
}

.sim-head {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 14px;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--muted);
}

.sim-cards { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }

.sim-card {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  gap: 13px;
  min-height: 64px;
  padding: 12px 18px 12px 12px;
  border-radius: var(--r-md);
  border: 1px solid var(--border-el-2);
  background: var(--surface);
  color: var(--text);
  font-family: var(--font);
  font-size: 17px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  touch-action: manipulation;
  user-select: none;
  opacity: 0;
  transition: transform .12s ease, border-color .2s ease, box-shadow .2s ease;
  animation: k-rise .5s cubic-bezier(.2, .9, .3, 1) forwards;
}

.sim-card:hover { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent-45), var(--glow); }
.sim-card:active { transform: scale(.965); }
.sim-card.aktiv { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent-45); }

/* Laufband mit den letzten Buchungen. */
.laufband {
  position: relative;
  z-index: 1;
  overflow: hidden;
  border-top: 1px solid var(--hairline);
  background: var(--bg);
  height: 42px;
  display: flex;
  align-items: center;
}

.laufband-marke {
  flex: none;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 16px;
  height: 100%;
  background: oklch(0.84 0.055 260 / .1);
  border-right: 1px solid var(--accent-35);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent);
  z-index: 2;
}

.laufband-marke .statuspunkt { width: 5px; height: 5px; animation-duration: 1.4s; }

.laufband-fenster { flex: 1; overflow: hidden; position: relative; height: 100%; }

/* width: max-content, nicht 200%: die Buchungen sind zusammen breiter als das
   Fenster. Mit fester Prozentbreite schrumpfen die beiden Haelften auf
   Fensterbreite und die Eintraege liegen uebereinander. */
.marquee-inhalt {
  display: flex;
  width: max-content;
  height: 100%;
  animation: k-marquee 26s linear infinite;
}

.marquee-haelfte {
  display: flex;
  align-items: center;
  gap: 36px;
  flex: none;
  /* Der rechte Abstand traegt die Naht zwischen den beiden Haelften - ohne
     ihn klebt der letzte Eintrag am ersten der Wiederholung. */
  padding: 0 36px 0 24px;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--muted-2);
  white-space: nowrap;
}

.marquee-haelfte > span { flex: none; }

.laufband-fuss {
  flex: none;
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 0 20px calc(0px + env(safe-area-inset-bottom));
  height: 100%;
  border-left: 1px solid var(--hairline);
  background: var(--bg);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  z-index: 2;
}

/* Die Versionsnummer bleibt, wie sie geschrieben steht - "v0.9", nicht "V0.9". */
.laufband-fuss .version { color: var(--muted-3); text-transform: none; }
.laufband-fuss a { color: var(--accent); text-decoration: none; }

/* Alternative ohne Bewegung: die letzten drei Buchungen untereinander. */
.laufband-still {
  display: none;
  flex: 1;
  min-width: 0;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
  padding: 8px 24px;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--muted-2);
}

/* ------------------------------------------------- Sitzung am Tablet */

.sitzung-kopf {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 16px 24px;
  border-bottom: 1px solid var(--hairline);
}

.sitzung-titel { display: flex; flex-direction: column; min-width: 0; }
.sitzung-titel .kennung {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent);
}
.sitzung-titel .who { font-size: 25px; font-weight: 700; letter-spacing: -.025em; line-height: 1.15; }

/* Laufender Balken: zeigt, wie lange die Sitzung noch offen ist. */
.idle-countdown {
  position: absolute;
  left: 0;
  bottom: -1px;
  height: 2px;
  width: 100%;
  background: var(--accent);
  transform-origin: left;
  animation: k-fill 90s linear reverse forwards;
}

.sitzung-inhalt {
  position: relative;
  z-index: 1;
  padding: 22px 24px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.abschnitt { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; }
.abschnitt h2 { font-size: 21px; }

.fusszeile-sitzung {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted-2);
}

/* ------------------------------------------------- Produktkacheln */

.products { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }

.tile {
  position: relative;
  overflow: hidden;
  min-height: 158px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: space-between;
  padding: 18px;
  border-radius: var(--r-lg);
  border: 1px solid var(--border-el);
  background: var(--surface);
  color: var(--text);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  touch-action: manipulation;
  user-select: none;
  -webkit-touch-callout: none;
  opacity: 0;
  transition: transform .1s ease, border-color .22s ease, box-shadow .22s ease;
  animation: k-rise .48s cubic-bezier(.2, .9, .3, 1) forwards;
}

.tile:hover {
  border-color: oklch(0.84 0.055 260 / .75);
  box-shadow: inset 0 0 44px oklch(0.84 0.055 260 / .08), 0 0 26px oklch(0.84 0.055 260 / .12);
}

.tile:active {
  transform: scale(.955);
  border-color: var(--accent);
  box-shadow: inset 0 0 70px oklch(0.84 0.055 260 / .22);
}

.tile-code {
  font-size: 26px;
  font-weight: 500;
  letter-spacing: .12em;
  color: var(--accent-55);
}

.tile-text { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; }
.tile-name { font-size: 20px; font-weight: 600; letter-spacing: -.01em; }
.tile-price { font-size: 17px; font-weight: 700; color: var(--accent); }

.tile .sweep {
  width: 45%;
  animation-duration: 7s;
}

/* Nicht leistbar: bleibt tippbar, erklaert sich beim Tippen. */
.tile-blocked { border-style: dashed; }
.tile-blocked .tile-code, .tile-blocked .tile-name { color: var(--muted-2); }
.tile-blocked .tile-price { color: var(--danger); }
.tile-blocked .sweep { display: none; }

/* ------------------------------------------------- Menge waehlen */

.qty-row { display: flex; align-items: center; justify-content: center; gap: 18px; margin: 20px 0; }

.qty-btn {
  width: 74px;
  height: 74px;
  border-radius: var(--r-md);
  border: 1px solid var(--border-el);
  background: var(--surface);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 26px;
  font-weight: 500;
  cursor: pointer;
  touch-action: manipulation;
  transition: transform .09s ease, background .18s ease, border-color .18s ease;
}

.qty-btn:hover { border-color: var(--accent-55); }
.qty-btn:active { transform: scale(.93); background: oklch(0.84 0.055 260 / .18); }

.qty-value {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums lining-nums;
  font-size: 44px;
  font-weight: 700;
  min-width: 74px;
  text-align: center;
  color: var(--accent);
}

.qty-actions { display: flex; flex-direction: column; gap: 10px; }

/* ------------------------------------------------- Bestaetigung */

/* Innerhalb der Tablet-Ansicht, nicht als Vollbild - der Kellner bucht in
   Serie und darf dabei nicht jedes Mal ausgebremst werden. */
.toast-lage {
  position: fixed;
  left: 0;
  right: 0;
  bottom: calc(0px + env(safe-area-inset-bottom));
  z-index: 60;
  padding: 22px 24px;
  display: flex;
  justify-content: center;
  pointer-events: none;
  animation: k-slide-up .34s cubic-bezier(.2, 1.1, .4, 1) both;
}

.toast {
  position: relative;
  overflow: hidden;
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: 20px;
  max-width: 92vw;
  padding: 18px 24px;
  border-radius: var(--r-lg);
  border: 1px solid var(--accent-55);
  background: var(--surface);
  box-shadow: var(--glow-lg), var(--lift);
}

.toast-titel { font-size: 19px; font-weight: 600; }
.toast-sub {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 5px;
}

.toast .btn { border-color: var(--border-inv); font-size: 11px; letter-spacing: .08em; }
.toast .btn:hover { border-color: var(--danger); color: var(--danger); background: transparent; }

.toast .sweep { width: 35%; animation-duration: 3.6s; }

/* Restzeitbalken - laeuft synchron mit dem Selbstschliessen ab. */
.restzeit {
  position: absolute;
  left: 0;
  bottom: 0;
  height: 2px;
  width: 100%;
  background: var(--accent);
  transform-origin: left;
  animation: k-fill 2.6s linear reverse both;
}

.haken { animation: k-draw .4s .1s cubic-bezier(.2, .9, .3, 1) both; }

/* ------------------------------------------------- Vollbild fuer Grenzfaelle */

.flash {
  position: fixed;
  inset: 0;
  z-index: 70;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  padding: 24px calc(24px + env(safe-area-inset-bottom));
  text-align: center;
  background: var(--bg);
}

.flash-mark {
  width: 96px;
  height: 96px;
  display: grid;
  place-items: center;
  border: 1px solid var(--accent-45);
  border-radius: var(--r-lg);
  font-family: var(--font-mono);
  font-size: 30px;
  font-weight: 500;
  letter-spacing: .06em;
  color: var(--accent);
}

.flash.bad .flash-mark { border-color: var(--danger-line); color: var(--danger); }
.flash.warn .flash-mark { border-color: var(--warn-line); color: var(--warn); }
.flash-title { font-size: 34px; font-weight: 700; letter-spacing: -.03em; }
.flash p { color: var(--muted); max-width: 46ch; }

/* ---------------------------------------------------------------- PIN */

.pin-screen {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  position: relative;
  padding: 22px;
}

/* Gluehen von unten: zieht den Blick in die Daumenzone. */
.pin-screen::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(420px 300px at 50% 78%, var(--accent-07), transparent 70%);
  pointer-events: none;
}

.pin-kopf { position: relative; text-align: center; padding: 26px 0 32px; }
.pin-kopf .name { font-size: 31px; font-weight: 700; letter-spacing: -.03em; }
.pin-kopf .hinweis {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 10px;
}

.pin-dots { position: relative; display: flex; justify-content: center; gap: 20px; margin-bottom: 32px; }

.pin-dot {
  position: relative;
  width: 16px;
  height: 16px;
  border-radius: var(--r-sm);
  border: 1px solid rgba(255, 255, 255, .2);
  display: grid;
  place-items: center;
}

.pin-dot.filled {
  border-color: transparent;
  background: var(--accent);
  box-shadow: 0 0 16px oklch(0.84 0.055 260 / .9);
  animation: k-pop .32s cubic-bezier(.2, 1.4, .4, 1) both;
}

/* Nur der zuletzt gefuellte Punkt stoesst einen Ring aus. */
.pin-dot .ring {
  position: absolute;
  inset: -6px;
  border-radius: var(--r);
  border: 1px solid var(--accent);
  animation: k-ring 1.8s ease-out infinite;
}

.pinpad { position: relative; display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }

.pin-key {
  min-height: 74px;
  border-radius: var(--r-md);
  border: 1px solid var(--border-el);
  background: var(--surface);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 26px;
  font-weight: 500;
  cursor: pointer;
  touch-action: manipulation;
  user-select: none;
  opacity: 0;
  transition: transform .09s ease, background .18s ease, box-shadow .18s ease, border-color .18s ease;
  animation: k-tick .34s cubic-bezier(.2, .9, .3, 1) forwards;
}

.pin-key:hover { border-color: var(--accent-55); }
.pin-key:active {
  transform: scale(.93);
  background: oklch(0.84 0.055 260 / .18);
  box-shadow: inset 0 0 30px oklch(0.84 0.055 260 / .26);
}

.pin-wechsel {
  position: relative;
  margin-top: 20px;
  min-height: 48px;
  border: none;
  background: transparent;
  color: var(--muted-2);
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .08em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color .2s ease;
}

.pin-wechsel:hover { color: var(--accent); }

/* ---------------------------------------------------------------- Handy */

/* Die Anmeldung ist fuer 390 px gebaut. Auf einem breiten Bildschirm wird sie
   deshalb nicht gedehnt, sondern mittig auf Handybreite gehalten. */
.anmelde-kopf {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 560px;
  margin: 0 auto;
  padding: calc(48px + env(safe-area-inset-top)) 22px 24px;
  border-bottom: 1px solid var(--hairline);
}

.anmelde-kopf h1 { margin-top: 14px; }
.anmelde-kopf p { margin-top: 8px; font-size: 15px; line-height: 1.5; color: var(--muted); }

.anmelde-inhalt {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 560px;
  margin: 0 auto;
  padding: 18px 22px calc(18px + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.people { display: flex; flex-direction: column; gap: 8px; }

.person {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  min-height: 62px;
  padding: 12px 16px;
  border-radius: var(--r-md);
  border: 1px solid var(--border-el);
  background: var(--surface);
  color: var(--text);
  font-family: inherit;
  font-size: 17px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  touch-action: manipulation;
  user-select: none;
  opacity: 0;
  transition: border-color .2s ease, box-shadow .2s ease, transform .1s ease;
  animation: k-rise .44s cubic-bezier(.2, .9, .3, 1) forwards;
}

.person:hover { border-color: var(--accent); box-shadow: var(--glow-sm); }
.person:active { transform: scale(.98); }
.person-pfeil { font-family: var(--font-mono); color: var(--muted-2); }

/* Die eine Zahl, die zaehlt: was schulde ich? */
.hero {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--hairline);
  border-radius: var(--r-lg);
  padding: 24px;
}

.hero-kopf { display: flex; align-items: center; justify-content: space-between; gap: 12px; }

.hero-label {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--muted);
}

.hero-value {
  font-size: 60px;
  font-weight: 700;
  letter-spacing: -.04em;
  line-height: 1.05;
  margin-top: 10px;
  text-shadow: 0 0 34px oklch(0.84 0.055 260 / .3);
}

.hero .bar { margin-top: 18px; }

.hero-sub {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 10px;
}

.hero.warn { border-color: var(--warn-line); background: linear-gradient(180deg, oklch(0.75 0.13 60 / .08), transparent); }
.hero.warn .hero-value { color: var(--warn); text-shadow: 0 0 34px oklch(0.8 0.13 60 / .3); }
.hero.bad { border-color: var(--danger-line); background: linear-gradient(180deg, oklch(0.65 0.16 25 / .08), transparent); }
.hero.bad .hero-value { color: var(--danger); text-shadow: 0 0 34px oklch(0.72 0.16 25 / .3); }
/* Guthaben statt Schulden - die einzige Zahl hier, die man gern sieht. */
.hero.gut { border-color: oklch(0.72 0.12 150 / .45); background: linear-gradient(180deg, oklch(0.72 0.12 150 / .08), transparent); }
.hero.gut .hero-value { color: var(--ok); text-shadow: 0 0 34px oklch(0.72 0.12 150 / .28); }

.hinweis-text { font-size: 14px; line-height: 1.5; color: var(--muted); }

/* Monatsbloecke. Nur der laufende Monat ist offen. */
.month > summary {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  cursor: pointer;
  padding-top: 14px;
  border-top: 1px solid var(--hairline);
  list-style: none;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--muted-2);
}

.month > summary::-webkit-details-marker { display: none; }
.month > summary .amount { font-size: 17px; color: var(--text); letter-spacing: 0; }
.month > summary::after {
  content: '⌄';
  font-family: var(--font-mono);
  color: var(--muted-2);
  transition: transform .15s ease;
}
.month[open] > summary::after { transform: rotate(180deg); }
.month + .month { margin-top: 4px; }

.tag-kopf {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted-3);
  margin: 16px 0 2px;
  font-weight: 400;
}

/* Angebot, die Seite als App auf den Startbildschirm zu legen. Sitzt unten,
   damit sie beim Lesen des Stands nicht im Weg ist, und verschwindet für
   immer, sobald sie einmal weggetippt wurde. */
.verknuepfung {
  position: fixed;
  left: 12px;
  right: 12px;
  bottom: calc(12px + env(safe-area-inset-bottom));
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 12px;
  overflow: hidden;
  padding: 12px 12px 12px 16px;
  border: 1px solid var(--accent-35);
  border-radius: var(--r-md);
  background: var(--surface-2, var(--surface));
  box-shadow: var(--lift);
  font-size: 14px;
  line-height: 1.35;
  animation: k-slide-up .34s cubic-bezier(.2, 1.1, .4, 1) both;
}

.verknuepfung .btn { flex: none; }

.verknuepfung-zu {
  flex: none;
  min-width: 34px;
  min-height: 34px;
  border: none;
  background: transparent;
  color: var(--muted-2);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}

.verknuepfung-zu:hover { color: var(--text); }

/* Dauerhafter Platz in der Seite, damit "als App" nicht nur an der einmaligen
   Leiste unten hängt - die ist nach einem Tipp für immer weg. */
.install-zeile {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 4px;
  padding: 14px 16px;
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
  background: var(--surface-2);
}

.install-zeile img { flex: none; border-radius: 8px; }
.install-zeile .btn { flex: none; }
.install-titel { font-size: 15px; font-weight: 600; }

/* Anleitung im Installieren-Fenster: nummerierte Schritte, keine Fließtextwand. */
.anleitung { display: flex; flex-direction: column; gap: 2px; margin-top: 20px; }

.anleitung-schritt {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 13px 0;
  font-size: 15px;
  line-height: 1.35;
  border-bottom: 1px solid var(--hairline-soft);
}

.anleitung-schritt:last-child { border-bottom: none; }

.anleitung-nummer {
  flex: none;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border: 1px solid var(--accent-45);
  border-radius: 50%;
  background: var(--accent-08);
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--accent);
}

.ios-teilen { color: var(--muted); white-space: nowrap; }

/* Beim Neuaufbau derselben Ansicht (etwa nach einer Storno-Anfrage) laufen die
   Zeilen nicht noch einmal ein. Einmal beim Öffnen ist Bewegung, bei jedem
   Antippen ist sie Zappeln - und die Liste springt unter dem Finger weg. */
.ohne-einlauf .buchung,
.ohne-einlauf .month,
.ohne-einlauf .hero,
.ohne-einlauf .admin-zeile { animation: none; opacity: 1; }

/* Buchungszeile am Handy. */
.buchung {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 0;
  border-bottom: 1px solid var(--hairline-soft);
  opacity: 0;
  animation: k-tick .44s cubic-bezier(.2, .9, .3, 1) forwards;
}

.buchung.voided { opacity: .45; }
.buchung.voided .amount { text-decoration: line-through; }
.buchung .was { font-size: 16px; font-weight: 500; }
.buchung .wann { margin-top: 3px; }

.storno-link {
  border: none;
  background: transparent;
  padding: 0 4px;
  min-height: 44px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted-2);
  cursor: pointer;
  transition: color .2s ease;
}

.storno-link:hover { color: var(--danger); }
/* Löschen ist endgültig - deshalb schon im Ruhezustand rot angedeutet, damit
   es sich nicht wie ein zweites Stornieren anfühlt. */
.storno-link.loeschen { color: oklch(0.72 0.16 25 / .75); }
.storno-link.loeschen:hover { color: var(--danger); }

/* ---------------------------------------------------------------- Skeleton */

.skeleton {
  border-radius: var(--r-sm);
  background: linear-gradient(90deg, rgba(255, 255, 255, .05), rgba(255, 255, 255, .14), rgba(255, 255, 255, .05));
  background-size: 220% 100%;
  animation: k-shimmer 1.5s linear infinite;
}

.skeleton.still { background: rgba(255, 255, 255, .05); animation: none; }

.skeleton-karte {
  border: 1px solid var(--hairline);
  border-radius: var(--r-lg);
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.skeleton-zeile {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 0;
  border-bottom: 1px solid var(--hairline-soft);
}

.skeleton-kasten {
  flex: none;
  width: 40px;
  height: 32px;
  border-radius: var(--r-sm);
  border: 1px solid var(--hairline);
}

/* Scan-Streifen ueber dem ganzen Ladezustand. */
.scan {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  height: 96px;
  background: linear-gradient(180deg, transparent, var(--accent-08), transparent);
  animation: k-scan 2.6s linear infinite;
  pointer-events: none;
  z-index: 2;
}

.laedt {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted-2);
}

.laedt span { animation: k-blink 1s step-end infinite; }

/* ---------------------------------------------------------------- Admin */

.storno-karte {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--warn-line);
  border-radius: var(--r-lg);
  padding: 20px 22px;
  background: var(--warn-fill);
}

.storno-karte .sweep {
  width: 30%;
  background: linear-gradient(90deg, transparent, oklch(0.8 0.13 60 / .07), transparent);
  animation-duration: 5s;
}

.storno-kopf {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 14px;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--warn);
}

.storno-zeile { position: relative; display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.storno-zeile + .storno-zeile { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--hairline-soft); }
.storno-zeile .titel { font-size: 17px; font-weight: 600; }

/* Verlaufskurve: nur die Linie, keine Fuellflaeche. */
.spark { display: block; width: 100%; height: 52px; margin-top: 14px; overflow: visible; }
.spark-line {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
  /* Die Kurve wird in der Breite gestreckt, der Strich aber nicht - eine feste
     Strichlaenge passt deshalb immer nur zu einer einzigen Kachelbreite. Ist
     sie zu kurz, zerfaellt die Linie in Striche mit Luecken. */
  stroke-dasharray: var(--spark-len, 340);
  animation: k-draw-long 1.7s .4s cubic-bezier(.2, .9, .3, 1) both;
}
.spark-punkt { fill: var(--accent); animation: k-dot 1.9s ease-out infinite 2.1s; }

.delta {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .06em;
  text-transform: uppercase;
  margin-top: 4px;
}

.delta.up { color: var(--danger); }
.delta.down { color: var(--ok); }
.delta.gleich { color: var(--muted); }

/* Personenzeile im Admin. */
.admin-zeile {
  position: relative;
  overflow: hidden;
  display: grid;
  grid-template-columns: 60px 1fr 1.4fr 150px 130px;
  align-items: center;
  gap: 20px;
  padding: 16px 22px;
  border-bottom: 1px solid var(--hairline-soft);
  cursor: pointer;
  opacity: 0;
  transition: background .18s ease;
  animation: k-tick .46s cubic-bezier(.2, .9, .3, 1) forwards;
}

.admin-zeile:last-child { border-bottom: none; }
.admin-zeile:hover { background: var(--surface); }
.admin-zeile .name { font-size: 17px; font-weight: 600; }
.admin-zeile .anteil {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted-2);
  text-align: right;
}
.admin-zeile .amount { text-align: right; font-size: 20px; }
.admin-zeile.inaktiv { opacity: .55; }

.tabelle-inaktiv { opacity: .55; }

/* ---------------------------------------------------------------- Tabelle */

.table-scroll { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; }
th, td { text-align: left; padding: 12px 10px; border-bottom: 1px solid var(--hairline-soft); white-space: nowrap; }
th {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted-2);
  font-weight: 400;
}
tbody tr.clickable { cursor: pointer; }
tbody tr.clickable:hover { background: var(--surface); }

.footnote {
  margin-top: 22px;
  text-align: center;
  color: var(--muted-3);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .08em;
  line-height: 1.8;
  padding-bottom: calc(24px + env(safe-area-inset-bottom));
}

.footnote a { color: var(--muted-2); text-decoration: none; }
.footnote a:hover { color: var(--accent); }

/* ---------------------------------------------------------------- Tour

   Vorführhilfe: leuchtet das echte Element aus und erklärt es daneben.
   Der abgedunkelte Rest entsteht aus einem einzigen riesigen Schatten um das
   Loch herum - dadurch bleibt alles klickbar, ein Schatten fängt keine Tipps
   ab. Das ist Absicht: die Tour führt, sie sperrt nicht. */
.tour-loch {
  position: fixed;
  z-index: 88;
  border-radius: var(--r-md);
  box-shadow:
    0 0 0 9999px rgba(4, 8, 18, .84),
    0 0 0 1px var(--accent),
    var(--glow);
  pointer-events: none;
  transition: top .35s cubic-bezier(.2, .9, .3, 1), left .35s cubic-bezier(.2, .9, .3, 1),
              width .35s cubic-bezier(.2, .9, .3, 1), height .35s cubic-bezier(.2, .9, .3, 1);
}

/* Schritte ohne Ziel (Anfang, Ende): nur abdunkeln, nichts ausleuchten. */
.tour-loch.aus {
  top: 50%;
  left: 50%;
  width: 0;
  height: 0;
  box-shadow: 0 0 0 9999px rgba(4, 8, 18, .89);
}

.tour-karte {
  position: fixed;
  z-index: 89;
  overflow: hidden;
  width: min(360px, calc(100vw - 32px));
  padding: 18px 20px;
  border-radius: var(--r-lg);
  border: 1px solid var(--accent-55);
  background: var(--surface);
  box-shadow: var(--glow-lg), var(--lift);
  animation: k-slide-up .3s cubic-bezier(.2, 1.1, .4, 1) both;
}

.tour-karte .sweep { width: 35%; animation-duration: 4s; }

.tour-zaehler {
  position: relative;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent);
}

.tour-titel {
  position: relative;
  font-size: 21px;
  font-weight: 700;
  letter-spacing: -.025em;
  margin-top: 6px;
}

.tour-text {
  position: relative;
  font-size: 14px;
  line-height: 1.55;
  color: var(--muted);
  margin-top: 8px;
}

.tour-knoepfe {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 16px;
}

.tour-abbruch {
  border: none;
  background: transparent;
  padding: 0;
  min-height: 44px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted-3);
  cursor: pointer;
  transition: color .2s ease;
}

.tour-abbruch:hover { color: var(--danger); }

/* Schritte, bei denen der Zuschauer selbst tippen muss - der Knopf fehlt
   dort mit Absicht, sonst klickt man sich an der Handlung vorbei. */
.tour-warte {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--accent);
}

.tour-warte::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
  animation: k-glow 1.4s ease-in-out infinite;
}

/* Knopf, der die Tour startet - sitzt im Laufband neben den Links. */
.tour-start {
  border: 1px solid var(--accent-35);
  border-radius: var(--r-sm);
  background: transparent;
  padding: 5px 9px;
  min-height: 32px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--accent);
  cursor: pointer;
  transition: background .2s ease;
}

.tour-start:hover { background: var(--accent-08); }

@media (max-width: 560px) {
  .tour-karte { padding: 16px; }
  .tour-titel { font-size: 18px; }
  .tour-text { font-size: 13px; }
}

/* ---------------------------------------------------------------- Bewegung aus

   Im reduzierten Modus muss jede Endaufnahme stimmen: Balken auf Endbreite,
   Kacheln sichtbar, Haken fertig gezeichnet, Laufband weg. */
@media (prefers-reduced-motion: reduce) {
  .tile, .bar > span, .marquee-inhalt, .raster-drift, .sweep, .sheen, .scan,
  .skeleton, .hinweis-zyklus > *, .funkwelle, .statuspunkt, .pulspunkt::before,
  .cursor, .haken, .spark-line, .spark-punkt, .karte, .sim-card, .person,
  .pin-key, .pin-dot, .pin-dot .ring, .buchung, .admin-zeile, .badge::before,
  .toast-lage, .restzeit, .idle-countdown {
    animation: none !important;
  }

  * { transition-duration: .01ms !important; }

  .tile, .sim-card, .person, .pin-key, .buchung, .admin-zeile { opacity: 1; }
  .sweep, .sheen, .scan, .funkwelle, .cursor { display: none; }
  .haken { stroke-dashoffset: 0; }
  .spark-line { stroke-dasharray: none; }
  /* Erste Variante bleibt stehen, statt dass alle drei uebereinanderliegen. */
  .hinweis-zyklus > * { opacity: 0; }
  .hinweis-zyklus > *:first-child { opacity: 1; }
  /* Ein stehendes Laufband ist nur ein abgeschnittener Satz - lieber die
     letzten Buchungen untereinander. */
  .laufband-fenster { display: none; }
  .laufband-still { display: flex; }
  .laufband { height: auto; }
  .skeleton { background: rgba(255, 255, 255, .08); }
}

/* ------------------------------------------------------- Tablet, hochkant

   Zwischen Handy und Schreibtisch lag bisher nichts - ein Tablet im Hochformat
   (768 bis 834 px) bekam deshalb das Desktop-Raster: vier Kennzahlen
   nebeneinander, die grosse Zahl in einer 190 px schmalen Kachel mit
   white-space: nowrap. Sie wurde schlicht abgeschnitten.

   Muss VOR dem Handy-Block stehen: bei gleicher Spezifitaet gewinnt die spaetere
   Regel, und unter 560 px sollen die Handy-Regeln gelten. */

/* Zweite Bedingung fuer die breiteren Geraete: ein Surface meldet hochkant
   912 px und faellt sonst durch. Quer bleibt es beim breiten Raster. */
@media (max-width: 900px), (orientation: portrait) and (max-width: 1100px) {
  .wrap, .wrap-narrow { padding: 20px 18px calc(20px + env(safe-area-inset-bottom)); }

  /* Grosse Zahl ueber die volle Breite, die drei Zaehler darunter nebeneinander. */
  .stats-admin { grid-template-columns: repeat(3, 1fr); }
  .stats-admin .stat:has(.stat-value.big) { grid-column: 1 / -1; }
  .stat-value.big { font-size: 46px; }
  .stat-value.zahl { font-size: 32px; }
  .stat { padding: 18px; }
  /* Ueber die volle Breite waere die Kurve bei 52 px fast eine Gerade. */
  .spark { height: 68px; }

  /* Personenzeile zweizeilig: oben wer und wie viel - das ist die Zeile, auf
     die getippt wird. Balken und Anteil ruecken darunter, statt Name und Betrag
     auf je 90 px zusammenzuquetschen. */
  .admin-zeile {
    grid-template-columns: 52px minmax(0, 1fr) auto;
    grid-template-rows: auto auto;
    gap: 8px 14px;
    padding: 16px 18px;
  }
  .admin-zeile > .initialen { grid-column: 1; grid-row: 1 / span 2; align-self: center; }
  .admin-zeile > .row { grid-column: 2; grid-row: 1; }
  .admin-zeile > .amount { grid-column: 3; grid-row: 1; font-size: 22px; }
  .admin-zeile > .bar { grid-column: 2; grid-row: 2; align-self: center; }
  .admin-zeile > .anteil { grid-column: 3; grid-row: 2; }
  .admin-zeile .name { font-size: 19px; }

  /* Der Dialog ist am Tablet die eigentliche Arbeitsflaeche - er darf fast die
     ganze Hoehe nehmen, statt in der Mitte zu schweben. */
  .modal { max-width: 680px; max-height: 94dvh; padding: 0 20px 20px; }
  .modal .stat-value { font-size: 20px; }

  /* Schnellbetraege als greifbare Kacheln statt schmaler Knoepfe. */
  .betrag-buchen .row-wrap > .btn,
  .zahlung-eintragen .row-wrap > .btn { flex: 1 1 28%; min-height: 48px; }
  .betrag-buchen input,
  .zahlung-eintragen input { min-height: 52px; font-size: 17px; }

  /* Storno-Anfragen: Knoepfe unter den Text statt daneben. */
  .storno-zeile .btn { flex: 1 1 40%; }
}

/* ---------------------------------------------------------------- Handy */

@media (max-width: 560px) {
  .wrap, .wrap-narrow { padding: 18px 16px calc(18px + env(safe-area-inset-bottom)); }
  .topbar + .wrap-narrow, .topbar + .wrap { padding-top: 18px; }

  h1 { font-size: 30px; }

  /* Listenzeilen umbrechen lassen, sonst wird die Seite seitlich schiebbar. */
  .list-item { flex-wrap: wrap; row-gap: 8px; }
  .list-item > .grow { flex: 1 1 60%; min-width: 0; }
  .list-item > .amount { flex: 0 0 auto; margin-left: auto; }
  .list-item > .btn { flex: 0 1 auto; }
  .list-item > input { flex: 1 1 100%; width: 100%; }
  .list-item .row { flex-wrap: wrap; }

  /* Fuenf Reiter passen nicht in eine Zeile. */
  .tabs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px; padding: 0 16px; }
  .tab { padding: 13px 6px; min-height: 44px; }

  /* Detailfenster als Blatt von unten. */
  .modal-backdrop { padding: 0; align-items: flex-end; }
  .modal {
    max-width: none;
    max-height: 92dvh;
    border-radius: var(--r-lg) var(--r-lg) 0 0;
    overscroll-behavior: contain;
    padding-bottom: calc(22px + env(safe-area-inset-bottom));
  }

  .modal .stat { padding: 12px 8px; }
  .modal .stat-label { font-size: 9px; letter-spacing: .08em; }
  .modal .stat-value { font-size: 15px; margin-top: 4px; }

  .row-wrap > .btn { flex: 1 1 30%; }
  .row-wrap > .btn-primary { flex: 1 1 100%; }

  /* Produkttabelle gestapelt statt seitwaerts scrollen. */
  .table-scroll table, .table-scroll tbody { display: block; }
  .table-scroll tr {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: center;
    gap: 8px;
    padding: 12px 0;
    border-bottom: 1px solid var(--hairline-soft);
  }
  .table-scroll td { display: block; border: 0; padding: 0; white-space: normal; }
  .table-scroll td:nth-child(2) { font-weight: 600; }
  .table-scroll td:nth-child(3) input { width: 100%; }
  .table-scroll td .btn { width: 100%; }

  /* Produktkacheln zweispaltig - vier Spalten waeren am Handy 60 px breit. */
  .products { grid-template-columns: repeat(2, 1fr); gap: 10px; }
  .tile { min-height: 128px; padding: 14px; }
  .tile-code { font-size: 21px; }
  .tile-name { font-size: 16px; }
  .tile-price { font-size: 15px; }

  /* Kennzahlen: die grosse Zahl nach oben und ueber die volle Breite, die
     Nebenwerte darunter nebeneinander. Sonst entsteht eine Treppe aus
     vollbreiten Kaesten - oder die Hauptzahl steht in halber Breite. */
  .stats, .stats-sitzung, .stats-admin { grid-template-columns: 1fr 1fr; }
  .stat { padding: 16px; }
  .stat:has(.stat-value.big) { order: -1; }
  .stats-sitzung .stat:has(.stat-value.big),
  .stats-admin .stat:has(.stat-value.big) { grid-column: 1 / -1; }
  .stat-value { font-size: 26px; }
  .stat-value.big { font-size: 40px; }
  .stat-value.zahl { font-size: 30px; }

  .hero-value { font-size: 44px; }

  /* Ruhebildschirm zusammenziehen. */
  .idle { padding: 16px; gap: 16px; }
  .kartenfeld { width: 200px; height: 200px; }
  .karte { width: 108px; height: 72px; padding-left: 14px; }
  .idle-title { font-size: 28px; }
  .cursor { width: 10px; height: 26px; vertical-align: -4px; margin-left: 7px; }
  .hinweis-zyklus { font-size: 11px; letter-spacing: .08em; }

  .schicht-leiste { padding: 12px 16px; gap: 10px; font-size: 11px; }
  .sitzung-kopf { padding: 14px 16px; gap: 12px; flex-wrap: wrap; }
  .sitzung-titel .who { font-size: 20px; }
  /* "AUTO-ABMELDUNG LÄUFT" drueckt "Fertig" in eine eigene Zeile. Der
     ablaufende Balken unter der Kopfzeile sagt dasselbe ohne Worte. */
  .sitzung-kopf > .meta { display: none; }
  .sitzung-inhalt { padding: 16px; gap: 16px; }

  /* Kartenknoepfe zweispaltig statt acht Reihen untereinander. */
  .sim-bar { padding: 14px 16px calc(16px + env(safe-area-inset-bottom)); }
  .sim-cards { grid-template-columns: 1fr 1fr; gap: 8px; }
  .sim-card { min-height: 56px; padding: 10px 12px; font-size: 14px; gap: 10px; }
  .sim-card .initialen { width: 30px; height: 30px; font-size: 11px; }
  .sim-card .card-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  /* Das Laufband bleibt der einzige Weg zu den anderen Ansichten. */
  .laufband { height: auto; flex-wrap: wrap; position: sticky; bottom: 0; z-index: 10; }
  .laufband-marke { padding: 10px 14px; height: auto; }
  .laufband-fenster { height: 34px; order: 3; flex: 1 1 100%; border-top: 1px solid var(--hairline); }
  /* Die Ersatzliste bei reduzierter Bewegung braucht die ganze Zeilenbreite -
     neben Marke und Links gequetscht bricht sie nach jedem Wort um und wird
     dreihundert Pixel hoch. */
  .laufband-still {
    order: 3;
    flex: 1 1 100%;
    padding: 8px 14px;
    border-top: 1px solid var(--hairline);
  }
  .laufband-still > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .laufband-fuss { flex: 1; justify-content: flex-end; padding: 6px 14px calc(6px + env(safe-area-inset-bottom)); border-left: none; height: auto; }
  .laufband-fuss a { display: inline-flex; align-items: center; min-height: 44px; }

  /* Admin-Zeile: Kennung, Name und Betrag in die erste Zeile, Balken und
     Anteil darunter. Jede Zelle braucht ihren Platz ausdruecklich - sonst
     sucht sich der Betrag die naechste freie Zelle und landet eine Zeile
     tiefer ganz links, weit weg vom Namen. */
  .admin-zeile { grid-template-columns: 40px 1fr auto; gap: 8px 14px; padding: 14px 16px; }
  .admin-zeile > :first-child { grid-column: 1; grid-row: 1; }
  .admin-zeile > .row { grid-column: 2; grid-row: 1; }
  .admin-zeile > .amount { grid-column: 3; grid-row: 1; }
  .admin-zeile > .bar { grid-column: 2 / -1; grid-row: 2; }
  .admin-zeile > .anteil { grid-column: 2 / -1; grid-row: 3; text-align: left; }
  .rahmen-kopf { padding: 13px 16px; flex-wrap: wrap; gap: 6px; }
  .rahmen-kopf .meta { flex: 1 1 100%; }

  /* Code, Text, Betrag und Storno-Knopf passen am Handy nicht in eine Zeile -
     der Text wuerde auf drei Zeilen umbrechen. Der Knopf rutscht darunter. */
  .buchung { flex-wrap: wrap; row-gap: 6px; }
  .buchung .amount { margin-left: auto; }
  .buchung .storno-link { flex: 1 1 100%; min-height: 36px; text-align: right; padding: 0; }

  .toast-lage { padding: 14px; }
  .toast { flex-wrap: wrap; gap: 14px; padding: 16px 18px; }
  .toast-titel { font-size: 17px; }

  .qty-btn { width: 64px; height: 64px; font-size: 22px; }
  .qty-value { font-size: 36px; min-width: 64px; }

  .storno-zeile { gap: 10px; }
  .storno-zeile .amount { margin-left: auto; }

  .row { flex-wrap: wrap; }
}
