/* ═══════════════════════════════════════════════════════════════════════════
   Morning Briefing — components built on the Bürgenstock token system.
   Rules honoured:
     1  taupe is a mark, never text, never data
     2  navy is reserved for the year-over-year series — unused here on purpose
     3  pastel accents always tint+tone as a pair
     4  Lora capped at 4 uses per screen (page title + up to 3 figures)
     5  no drop shadows — depth is a surface change plus a hairline
     letter-spacing is 0 everywhere except eyebrow labels
   ═══════════════════════════════════════════════════════════════════════════ */

/* Night Audit = the sanctioned inverse ground (ink), NOT a blue theme.
   Only the semantic layer flips; the palette itself is untouched. */
:root[data-mode="night"]{
  --surface-page:    #1D1D1F;
  --surface-raised:  #26262A;
  --surface-sunken:  #17171A;
  --text-primary:    #F1F0EB;
  --text-secondary:  rgb(241 240 235 / .68);
  --text-tertiary:   rgb(241 240 235 / .45);
  --border-subtle:   rgb(241 240 235 / .16);
  --border-strong:   rgb(241 240 235 / .30);
  --border-focus:    #F1F0EB;
}

/* Status pairs: tint fills and tone writes on the light ground; on the inverse
   ground the pair swaps so the tone never has to carry text on ink. */
:root{
  --ok-bg:var(--accent-sage-tint);   --ok-fg:var(--accent-sage-tone);
  --pd-bg:var(--accent-amber-tint);  --pd-fg:var(--accent-amber-tone);
  --ms-bg:var(--accent-clay-tint);   --ms-fg:var(--accent-clay-tone);
  --nf-bg:var(--accent-slate-tint);  --nf-fg:var(--accent-slate-tone);
  --rs-bg:var(--accent-rose-tint);   --rs-fg:var(--accent-rose-tone);
  --lk-bg:var(--accent-lake-tint);   --lk-fg:var(--accent-lake-tone);
  /* Signalwäsche für ganze Kacheln: kräftiger als nichts, deutlich leiser als
     ein Chip. Ein Chip füllt zwei Quadratzentimeter, eine Kachel dreissig — mit
     der Chip-Tönung würde die Seite bunt statt lesbar. */
  --wash-up:#EAF1E8; --wash-flat:#F5EFE5; --wash-down:#F6E7E3;
  /* Zwei Stufen einer Reihe, nicht zwei Farben — heute und morgen sind
     Zeitpunkte derselben Grösse. Gegen die Ordinal-Schwellen geprüft. */
  --occ-now:var(--data-ramp-1); --occ-next:var(--data-ramp-3);
}
:root[data-mode="night"]{
  --ok-bg:rgb(70 108 61 / .34);   --ok-fg:var(--accent-sage-tint);
  --pd-bg:rgb(121 87 42 / .38);   --pd-fg:var(--accent-amber-tint);
  --ms-bg:rgb(138 72 56 / .34);   --ms-fg:var(--accent-clay-tint);
  --nf-bg:rgb(85 95 109 / .34);   --nf-fg:var(--accent-slate-tint);
  --rs-bg:rgb(133 71 86 / .34);   --rs-fg:var(--accent-rose-tint);
  --lk-bg:rgb(66 99 128 / .34);   --lk-fg:var(--accent-lake-tint);
  /* Auf dem dunklen Grund mit Alpha, damit die angehobene Fläche darunter bleibt. */
  --wash-up:rgb(70 108 61 / .20); --wash-flat:rgb(121 87 42 / .22);
  --wash-down:rgb(138 72 56 / .20);
  /* Auf dem dunklen Grund eigene Stufen, keine Umkehr: die helle trägt jetzt
     «heute», damit sie das Gewicht behält. */
  --occ-now:#F1F0EB; --occ-next:var(--data-ramp-3);
}

*{box-sizing:border-box}
body{
  margin:0; background:var(--surface-page); color:var(--text-primary);
  font-family:var(--font-sans); font-size:var(--text-body);
  font-weight:var(--weight-regular); line-height:var(--leading-normal);
  letter-spacing:0; -webkit-font-smoothing:antialiased;
  transition:background var(--duration-base) var(--ease-standard),
             color var(--duration-base) var(--ease-standard);
}
.hide{display:none !important}
.eyebrow{
  font-size:var(--text-eyebrow); font-weight:var(--weight-semibold);
  letter-spacing:.09em; text-transform:uppercase; color:var(--text-secondary);
}
.serif{font-family:var(--font-display); font-weight:var(--weight-regular); letter-spacing:0}

/* ── Login ─────────────────────────────────────────────────────────────── */
#login{position:relative; min-height:100vh; display:grid; place-items:center;
  padding:var(--space-6); background:var(--surface-page);
  /* Das Band, das die Wortmarke oben für sich braucht. Es steht hier, weil die
     Kollage es kennen muss: sie ist mittig, also muss oben *und* unten je ein
     Band frei bleiben, sonst wandert sie unter die Marke. */
  --mark-h:30px;
  --mark-band:calc(var(--space-8) + var(--mark-h) + var(--space-6));
}

/* Bildkollage hinter der Anmeldung. Vier Aufnahmen als ein Satz, nicht als
   Hintergrundbild: die Karte liegt bewusst über ihnen, und die Anordnung muss
   als Komposition zusammenbleiben. Darum eine mittige Bühne mit festem
   Seitenverhältnis, in der jeder Rahmen prozentual sitzt — sonst wandern die
   Bilder auf einem breiten Schirm an die Ränder und die Mitte fällt auseinander. */
.loginart{
  /* Nicht ganz mittig, sondern um --space-6 nach unten versetzt: das Band oben
     ist zwar reserviert, aber die Wortmarke sitzt darin oben, sodass der Abstand
     unter ihr optisch der engste der Seite war. Der Versatz nimmt vom unteren
     Rand, wo ohnehin am meisten Luft ist, und gibt ihn der Marke. */
  position:absolute; top:calc(50% + var(--space-6)); left:50%;
  transform:translate(-50%,-50%);
  /* Die dritte Grenze ist die Fensterhöhe: aspect-ratio bindet Höhe an Breite,
     also muss die Breite selbst die Höhe berücksichtigen, sonst ragt die Bühne
     auf einem flachen Fenster (1440×900 ergibt gut 760 px Viewport) über den
     Rand. So schrumpft die Kollage statt zu verschwinden. */
  width:min(925px, 100%, calc((100vh - 2 * var(--mark-band)) * 1140 / 740));
  aspect-ratio:1140/740;
  pointer-events:none; user-select:none;
}
.la{position:absolute; width:100%; height:100%; object-fit:cover;
  background:var(--surface-sunken)}
.la-lift  {left: 2.5%; top: 0;     width:39.5%; height:46.5%}
.la-hotel {left:58%;   top: 0.7%;  width:42%;   height:43%}
.la-pool  {left: 0;    top:59.3%;  width:39%;   height:40.7%}
.la-spices{left:58%;   top:55.2%;  width:42%;   height:40.3%}

/* Nur die Breite entscheidet, ob die Kollage überhaupt erscheint: schmaler als
   900 px stünde sie fast vollständig hinter der Karte und machte die Felder
   unlesbar. Dann trägt der cremefarbene Grund die Karte allein. */
@media (max-width:900px){ .loginart{display:none} }

/* Die Wortmarke gehört jetzt der Seite, nicht der Karte: waagrecht mittig, oben
   im freien cremefarbenen Band über der Kollage. Nicht direkt über die Karte
   gesetzt, obwohl das der Mitte näher wäre — dort läge dunkle Schrift auf den
   Fotografien, und der freie Kanal zwischen den Bildspalten ist mit 148 px
   schmaler als die Marke selbst (viewBox 299.58×57.18, auf 30 px Höhe also
   157 px breit). Lesbarkeit vor Nähe. */
.loginmark{
  position:absolute; top:var(--space-8); left:50%; transform:translateX(-50%);
  z-index:1;
}
.loginmark .wm{height:var(--mark-h)}

.card{
  position:relative; z-index:1;
  width:100%; max-width:400px; background:var(--surface-raised);
  border:1px solid var(--border-subtle); border-radius:var(--radius-sm);
  padding:var(--space-12) var(--space-8);
  /* Die einzige freigegebene Ausnahme von Regel 5, auf ausdrücklichen Wunsch
     und so im Entwurf: allein hier liegt eine Fläche über Fotografien, und dort
     trägt eine Haarlinie die Kante nicht — auf dunklem Bild verschwindet sie,
     auf hellem franst sie aus. Tiefe bleibt überall sonst Flächenwechsel plus
     Haarlinie. Getönt mit --color-ink statt Schwarz, damit der Schatten warm
     bleibt wie der übrige Grund. Die Markierung ist die Freigabe: ohne sie
     lässt site/check.py jeden weiteren Schlagschatten fehlschlagen. */
  /* ds-ausnahme */ box-shadow:0 1px 2px color-mix(in srgb, var(--color-ink) 4%, transparent),
                               0 8px 32px color-mix(in srgb, var(--color-ink) 10%, transparent);
}
.crest{
  width:34px; height:34px; border:1px solid var(--accent-quiet); border-radius:var(--radius-sm);
  display:grid; place-items:center; font-family:var(--font-sans);
  font-weight:var(--weight-semibold); font-size:.6875rem; letter-spacing:.09em;
  color:var(--text-primary); margin-bottom:var(--space-6);
}
.card h1{
  /* Haupttitel der Karte, seit die Wortmarke darüber weggefallen ist — also
     Seitentitel-Rang. Bewusst nicht var(--text-title): dessen 3vw skalieren mit
     dem Fenster, was in einer Karte fester Breite nichts zu suchen hat.
     1.5rem ist der Boden genau dieses Tokens. */
  font-family:var(--font-display); font-weight:var(--weight-regular);
  font-size:1.5rem; line-height:var(--leading-snug); margin:0 0 var(--space-1);
}
.card .sub{margin:0 0 var(--space-8); color:var(--text-secondary); font-size:var(--text-body)}
.field{margin-bottom:var(--space-4)}
label{display:block; margin-bottom:var(--space-2);
  font-size:var(--text-eyebrow); font-weight:var(--weight-semibold);
  letter-spacing:.09em; text-transform:uppercase; color:var(--text-secondary)}
input{
  width:100%; padding:.625rem .75rem; font-family:inherit; font-size:var(--text-body);
  color:var(--text-primary); background:var(--surface-page);
  border:1px solid var(--border-subtle); border-radius:var(--radius-sm);
  transition:border-color var(--duration-fast) var(--ease-standard);
}
input:focus{outline:2px solid var(--border-focus); outline-offset:-1px; border-color:transparent}
.btn{
  font-family:inherit; font-size:var(--text-body); font-weight:var(--weight-medium);
  padding:.625rem 1rem; border-radius:var(--radius-sm); cursor:pointer;
  background:var(--surface-inverse); color:var(--text-inverse); border:1px solid var(--surface-inverse);
  transition:opacity var(--duration-fast) var(--ease-standard);
}
:root[data-mode="night"] .btn{background:var(--color-creme); color:var(--color-ink); border-color:var(--color-creme)}
@media (hover:hover){.btn:hover:not(:disabled){opacity:.86}}
.btn:disabled{opacity:.5; cursor:not-allowed}
.btn-block{width:100%}
.btn-quiet{
  background:transparent; color:var(--text-secondary); border:1px solid var(--border-subtle);
}
@media (hover:hover){.btn-quiet:hover{background:var(--surface-sunken); color:var(--text-primary)}}
:root[data-mode="night"] .btn-quiet{background:transparent; color:var(--text-secondary); border-color:var(--border-subtle)}
.msg{margin-top:var(--space-4); padding:.625rem .75rem; border-radius:var(--radius-sm);
  font-size:var(--text-body); display:none}
.msg.err{display:block; background:var(--ms-bg); color:var(--ms-fg)}

/* ── Header ────────────────────────────────────────────────────────────── */
/* Taller, with room to breathe, and it scrolls away with the content — the
   brand does not need to follow you down a list of twenty incidents.
   The glass is what makes that read as deliberate rather than as a header that
   simply vanished: translucent ground, blurred backdrop, one lit top edge. */
header{
  display:flex; align-items:center; gap:var(--space-6);
  height:76px; padding:0 var(--space-8);
  background:linear-gradient(180deg, rgb(255 255 255 / .55) 0, rgb(255 255 255 / .18) 100%),
             rgb(241 240 235 / .72);
  backdrop-filter:blur(16px) saturate(1.4);
  -webkit-backdrop-filter:blur(16px) saturate(1.4);
  box-shadow:inset 0 1px 0 rgb(255 255 255 / .6),
             inset 0 -1px 0 rgb(29 29 31 / .10);
  border-bottom:0;
  position:sticky; top:0; z-index:5; flex:0 0 auto;
  transition:background var(--duration-base) var(--ease-standard);
}
:root[data-mode="night"] header{
  background:linear-gradient(180deg, rgb(241 240 235 / .07) 0, rgb(241 240 235 / .02) 100%),
             rgb(29 29 31 / .72);
  box-shadow:inset 0 1px 0 rgb(241 240 235 / .10),
             inset 0 -1px 0 rgb(0 0 0 / .35);
}
@supports not (backdrop-filter: blur(1px)){
  header{background:var(--surface-page)}
  :root[data-mode="night"] header{background:var(--surface-page)}
}
.logo{display:flex; align-items:center; gap:var(--space-3); white-space:nowrap}
.logo .crest{width:28px; height:28px; margin:0; font-size:.6875rem}
.logo b{font-weight:var(--weight-medium); font-size:.875rem}
.logo small{display:block; font-size:var(--text-eyebrow); color:var(--text-secondary);
  letter-spacing:.09em; text-transform:uppercase; font-weight:var(--weight-medium)}
.spacer{flex:1}
.clock{font-size:var(--text-body); color:var(--text-secondary); white-space:nowrap;
  font-variant-numeric:tabular-nums}

.modesw{display:flex; border:1px solid var(--border-subtle); border-radius:var(--radius-sm); overflow:hidden}
.modesw button{
  font-family:inherit; font-size:var(--text-body); font-weight:var(--weight-medium);
  padding:.4375rem .75rem; border:0; cursor:pointer; letter-spacing:0;
  background:transparent; color:var(--text-secondary);
  transition:background var(--duration-fast) var(--ease-standard);
}
.modesw button + button{border-left:1px solid var(--border-subtle)}
@media (hover:hover){.modesw button:hover{background:var(--surface-sunken)}}
.modesw button.on{background:var(--surface-sunken); color:var(--text-primary); font-weight:var(--weight-semibold);
  box-shadow:inset 0 -2px 0 var(--accent-quiet)}   /* taupe as an active-state mark */
.mono{font-family:var(--font-mono); font-size:.75rem}

/* ── Shell ─────────────────────────────────────────────────────────────── */
nav{
  background:var(--surface-page); border-right:1px solid var(--border-subtle);
  padding:var(--space-4) var(--space-3);
  transition:background var(--duration-base) var(--ease-standard)
}
.navhead{padding:var(--space-3) var(--space-3) var(--space-2); display:flex; gap:var(--space-3)}
.navhead span{cursor:pointer; color:var(--text-tertiary)}
.navhead span.on{color:var(--text-primary); border-bottom:1px solid var(--accent-quiet); padding-bottom:2px}
nav a{
  position:relative;
  display:flex; align-items:center; gap:var(--space-3); cursor:pointer;
  padding:var(--space-3); margin-bottom:2px;
  border-radius:var(--radius-sm);
  color:var(--text-secondary); text-decoration:none;
  font-size:var(--text-body-lg); line-height:var(--leading-snug);
  min-height:46px;                    /* comfortable click target */
}
/* The active marker used to be a 2px border-left, which pushed the label 2px
   right of the group headings — every row was misaligned against its own
   heading. It is a positioned rule now, so padding is identical in both states. */
nav a::before{
  content:""; position:absolute; left:0; top:6px; bottom:6px; width:2px;
  border-radius:1px; background:transparent;
}
nav a.on::before{background:var(--accent-quiet)}
@media (hover:hover){nav a:hover{background:var(--surface-sunken); color:var(--text-primary)}}
nav a.on{background:var(--surface-sunken); color:var(--text-primary);
  font-weight:var(--weight-medium)}
nav a{white-space:nowrap; overflow:hidden; text-overflow:ellipsis}

main{padding:var(--space-8) var(--space-8); max-width:var(--layout-max-width)}
.crumb{color:var(--text-secondary); margin-bottom:var(--space-2)}
h2{
  font-family:var(--font-display); font-weight:var(--weight-regular);
  font-size:var(--text-title); line-height:var(--leading-tight);
  letter-spacing:0; margin:0 0 var(--space-3);
}
.lede{margin:0 0 var(--space-8); color:var(--text-secondary); max-width:var(--layout-measure)}

/* ── Cards, tiles, tables — depth by surface + hairline, never shadow ──── */
.grid{display:grid; grid-template-columns:repeat(auto-fit,minmax(210px,1fr));
  gap:var(--space-4); margin-bottom:var(--space-8)}
.tile,.panel,.prog{
  background:var(--surface-raised); border:1px solid var(--border-subtle);
  border-radius:var(--radius-sm);
  transition:background var(--duration-base) var(--ease-standard),
             border-color var(--duration-base) var(--ease-standard);
}
.tile{padding:var(--space-4) var(--space-4)}
.tile .v{
  font-family:var(--font-display); font-weight:var(--weight-regular);
  font-size:var(--text-figure); line-height:var(--leading-tight);
  margin:var(--space-3) 0 var(--space-1); font-variant-numeric:tabular-nums;
}
.tile .d{color:var(--text-secondary); font-size:var(--text-body)}
.panel{padding:var(--space-12); text-align:center; color:var(--text-secondary)}
.panel h3{font-size:var(--text-body-lg); font-weight:var(--weight-medium);
  color:var(--text-primary); margin:0 0 var(--space-2)}
.panel p{margin:0 auto; max-width:var(--layout-measure)}
.srcnote{margin-top:var(--space-6); color:var(--text-tertiary); font-size:var(--text-eyebrow);
  display:flex; align-items:center; gap:var(--space-2); letter-spacing:.09em; text-transform:uppercase}
.mark{width:5px; height:5px; background:var(--accent-quiet); flex:none}  /* taupe as a mark */

/* progress */
.prog{padding:var(--space-4) var(--space-6); margin-bottom:var(--space-6)}
/* Schlanke Variante direkt unter dem Titel: eine Zeile Zahlen, darunter ein
   Balken, der kräftig genug ist, um aus dem Augenwinkel zu tragen. Bewusst ohne
   Kartenfläche — .prog erbt sie von der Kachel-Regel, und ein Fortschritt ist
   kein Objekt auf der Seite, sondern eine Eigenschaft der Seite. */
.prog-slim{padding:0; margin-bottom:var(--space-8);
  background:none; border:0; border-radius:0}
.prog-slim .top{margin-bottom:var(--space-2)}
.prog-slim .top .c{font-size:var(--text-eyebrow); letter-spacing:.09em;
  text-transform:uppercase; color:var(--text-tertiary)}
.bar-lg{height:10px; border-radius:var(--radius-pill)}
.prog .top{display:flex; align-items:baseline; justify-content:space-between;
  gap:var(--space-4); margin-bottom:var(--space-3); flex-wrap:wrap}
.prog .top .c{color:var(--text-secondary); font-variant-numeric:tabular-nums}
.bar{height:6px; background:var(--surface-sunken); display:flex; overflow:hidden;
  border-radius:var(--radius-sm); border:1px solid var(--border-subtle)}
.bar i{height:100%; transition:width var(--duration-base) var(--ease-standard)}
.legend{display:flex; gap:var(--space-6); margin-top:var(--space-3); flex-wrap:wrap;
  color:var(--text-secondary); font-size:var(--text-eyebrow);
  letter-spacing:.09em; text-transform:uppercase}
.legend i{width:8px; height:8px; display:inline-block; margin-right:var(--space-2)}

table{width:100%; border-collapse:collapse; background:var(--surface-raised);
  border:1px solid var(--border-subtle); border-radius:var(--radius-sm); overflow:hidden}
th{
  text-align:left; padding:.625rem var(--space-4); background:var(--surface-sunken);
  border-bottom:1px solid var(--border-subtle); color:var(--text-secondary);
  font-size:var(--text-eyebrow); font-weight:var(--weight-semibold);
  letter-spacing:.09em; text-transform:uppercase;
}
td{padding:.625rem var(--space-4); border-bottom:1px solid var(--border-subtle); vertical-align:middle}
tr:last-child td{border-bottom:0}
td.q{color:var(--text-secondary)}
.st{display:inline-block; padding:.1875rem .5rem; border-radius:var(--radius-sm);
  font-size:var(--text-eyebrow); font-weight:var(--weight-semibold); letter-spacing:.09em;
  text-transform:uppercase; white-space:nowrap}
.st.up{background:var(--ok-bg); color:var(--ok-fg)}
.st.pd{background:var(--pd-bg); color:var(--pd-fg)}
.st.ms{background:var(--ms-bg); color:var(--ms-fg)}
.act{font-family:inherit; font-size:var(--text-eyebrow); font-weight:var(--weight-medium);
  letter-spacing:.09em; text-transform:uppercase; padding:.25rem .5rem; cursor:pointer;
  background:transparent; color:var(--text-secondary);
  border:1px solid var(--border-subtle); border-radius:var(--radius-sm)}
@media (hover:hover){.act:hover{background:var(--surface-sunken); color:var(--text-primary)}}

@media(max-width:900px){
  .body{grid-template-columns:1fr}
  .clock{display:none}
  main{padding:var(--space-4) var(--space-4) var(--space-8)}
}

/* ── Mobile shell ───────────────────────────────────────────────────────
   Below 900 px the navbar used to be switched off with nothing in its place,
   which left two of fourteen sections reachable. The same `nav` element is now
   a drawer: identical markup, identical order, identical 46 px rows. */
.drawer-btn, .hmob, .nav-acts{display:none}   /* desktop keeps them in the header */

@media(max-width:900px){
  header{height:56px; padding:0 var(--space-3); gap:var(--space-2)}
  .logo, .spacer, #startmeeting, .modesw{display:none}
  .drawer-btn{display:grid; place-items:center; width:40px; height:40px; flex:none}
  .hmob{display:flex; flex-direction:column; justify-content:center; gap:1px;
    flex:1 1 auto; min-width:0; overflow:hidden}
  .hmob b{font-size:.9375rem; font-weight:var(--weight-medium); line-height:1.2;
    white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
  .hmob span{font-size:var(--text-eyebrow); letter-spacing:.09em;
    text-transform:uppercase; color:var(--text-tertiary); white-space:nowrap}
  .wxmini{flex:none}

  /* Starts below the header on purpose: the hamburger stays reachable and
     toggles the drawer shut, and the section title stays on screen so you never
     lose track of where you are while choosing where to go. */
  nav{
    display:flex; position:fixed; top:56px; bottom:0; left:0; z-index:40;
    width:min(86vw, 320px); border-right:0;
    transform:translateX(-100%);
    transition:transform var(--duration-base) var(--ease-standard);
  }
  body.drawer nav{transform:none}
  #scrim{position:fixed; top:56px; right:0; bottom:0; left:0; z-index:30;
    background:rgb(29 29 31 / .48)}
  .nav-acts{display:flex; flex-direction:column; gap:var(--space-3);
    padding:var(--space-4) 0; margin:0 calc(var(--space-4) * -1);
    padding-left:var(--space-6); padding-right:var(--space-6);
    border-top:1px solid rgb(241 240 235 / .14)}
  .nav-acts .btn{width:100%; justify-content:center; background:transparent;
    color:rgb(241 240 235 / .88); border:1px solid rgb(241 240 235 / .24)}
  .nav-acts .modesw{width:100%}
  .nav-acts .modesw button{flex:1 1 0; justify-content:center}
  /* During the meeting the wizard is the navigation, so the drawer stands down.
     The exit button stays — it is the only way back, and on 320 px the progress
     bar would push it off the edge. */
  body.wizard .drawer-btn, body.wizard #wizprog{display:none}
  body.wizard .hmob{flex:1 1 auto}
}
@media(prefers-reduced-motion:reduce){ nav{transition:none} }

/* Tables clip inside main{overflow-x:hidden}; the wrapper is added after every
   render so a table written later is covered without anyone remembering. */
.tscroll{overflow-x:auto; max-width:100%; -webkit-overflow-scrolling:touch}
.tscroll table{min-width:max-content}

/* ── Icons ──────────────────────────────────────────────────────────────
   Stroke-only, inherit colour and optical weight from their context.
   Hard rule: no emoji anywhere in the interface. */
.ico{
  width:16px; height:16px; flex:none;
  fill:none; stroke:currentColor; stroke-width:1.75;   /* Lucide 24-grid -> ~1.17px at 16px */
  stroke-linecap:round; stroke-linejoin:round;
}
.modesw button .ico,
.btn .ico{margin-right:.4375rem; vertical-align:-3px}
nav a .ico{stroke:var(--text-tertiary)}
nav a.on .ico{stroke:var(--accent-quiet)}  /* taupe as an active mark, never as text */
.modesw button{display:inline-flex; align-items:center}
.btn{display:inline-flex; align-items:center; justify-content:center}
.btn-block{width:100%}

/* ── Brand wordmark ─────────────────────────────────────────────────────
   Two polarities of the same mark; the ground decides which shows. */
.wm{display:block; height:20px; width:auto}
/* .card .wm entfällt — die Marke steht nicht mehr in der Karte, s. .loginmark */
.wm-neg{display:none}
:root[data-mode="night"] .wm-pos{display:none}
:root[data-mode="night"] .wm-neg{display:block}
.vr{width:1px; height:22px; background:var(--border-subtle); flex:none}
.logo{gap:var(--space-4)}


/* ── Navigation surface ─────────────────────────────────────────────────
   #283153 is a client request and is NOT part of the token set — see
   docs/02-design-system.md. Promote it into tokens.json if it stays. */
:root{ --surface-nav:#283153; --on-nav:#F1F0EB; }
nav{
  background:var(--surface-nav);
  border-right-color:rgb(241 240 235 / .14);
}
nav a{color:rgb(241 240 235 / .74)}
@media (hover:hover){nav a:hover{background:rgb(241 240 235 / .07); color:var(--on-nav)}}
nav a.on{background:rgb(241 240 235 / .11); color:var(--on-nav)}
nav a .ico{stroke:rgb(241 240 235 / .55)}
nav a.on .ico{stroke:var(--accent-quiet)}
/* 55 % passed on the solid navy but not on the lighter glass surface —
   raised to 70 %, measured at 4.66:1 in the brightest (day) case. */
.navhead{color:rgb(241 240 235 / .70)}
.navhead span{color:rgb(241 240 235 / .70)}
.navhead span.on{color:var(--on-nav); border-bottom-color:var(--accent-quiet)}

/* ── Navigation layout: scrolling list, hero pinned to the bottom ───────── */
:root{ --surface-nav-rgb:40 49 83; }        /* #283153 as channels, for gradients */
nav{
  display:flex; flex-direction:column;
  padding:var(--space-6) var(--space-4) 0;
  overflow:hidden; min-height:0;
}
/* scrollbar-gutter reserves the track whether or not it is needed. Without it
   the nav shifts sideways the moment a page has more entries than fit — which
   read as the navbar "moving" when switching subpages. */
#navlist{flex:1 1 auto; overflow-y:auto; overflow-x:hidden; min-height:0;
  scrollbar-width:thin; scrollbar-gutter:stable;
  padding-bottom:var(--space-4)}
.navhead{padding:0 var(--space-3) var(--space-3); margin-top:var(--space-6)}
#navlist > .navhead:first-child{margin-top:0}


/* ── Shell height: header + weather band + body, body takes the remainder,
   so the nav hero pins to the bottom of the viewport and each column
   scrolls on its own rather than the whole page. ─────────────────────── */
/* The document scrolls, not an inner pane — that is what lets the header
   leave the screen. The nav stays put by sticking to the top once it gets
   there, so the column is still fixed without the header being fixed too. */
/* Header across the full width and staying put; nav and content share the
   space below it, each scrolling on its own. */
/* dvh, with vh kept above as the fallback: on iOS the browser chrome eats
   60–100 px of 100vh, and the frame is then taller than the visible viewport —
   the sticky header sits under the URL bar and the last row is unreachable. */
#app{height:100vh; height:100dvh; overflow:hidden; display:flex; flex-direction:column}
.body{display:grid; grid-template-columns:340px 1fr; flex:1 1 auto; min-height:0}
main{overflow-y:auto; overflow-x:hidden; min-height:0; scrollbar-gutter:stable}


/* ── User block, pinned to the bottom of the navbar ─────────────────────
   Sits outside #navlist so it never scrolls with the section list. */
.nav-user{
  flex:0 0 auto;
  margin:0 calc(var(--space-4) * -1);
  padding:var(--space-4) var(--space-6);
  border-top:1px solid rgb(241 240 235 / .14);
  display:flex; flex-direction:column; gap:var(--space-3);
}
.nav-user-mail{
  color:rgb(241 240 235 / .72); font-size:.75rem;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.nav-user .btn{
  width:100%; background:transparent; color:rgb(241 240 235 / .88);
  border:1px solid rgb(241 240 235 / .24);
}
@media (hover:hover){.nav-user .btn:hover{background:rgb(241 240 235 / .09); color:var(--on-nav); opacity:1}}
.nav-user .btn .ico{stroke:currentColor}


/* ── Morning Meeting wizard ─────────────────────────────────────────────
   A third view. While it runs the navbar, the weather band and the mode
   switch step aside so one Bereich has the whole screen. */
#wizprog, #wizexit{display:none}
body.wizard #startmeeting,
body.wizard .modesw,
body.wizard .clock{display:none}
/* Night Audit has no use for a guest-facing forecast */
body.wizard nav{display:none}
body.wizard .body{grid-template-columns:1fr}
body.wizard #wizprog{display:flex; align-items:center; gap:var(--space-3)}
body.wizard #wizexit{display:inline-flex}

.wiz-bar{display:block; width:120px; height:4px; background:var(--surface-sunken);
  border:1px solid var(--border-subtle); border-radius:var(--radius-sm); overflow:hidden}
.wiz-bar i{display:block; height:100%; background:var(--accent-quiet);
  transition:width var(--duration-base) var(--ease-standard)}

.wiz{max-width:var(--layout-max-width); margin:0 auto; display:flex; flex-direction:column;
  min-height:100%}
.wiz h2{margin-bottom:var(--space-6)}

.wiz-saved{margin-top:var(--space-2); min-height:1.1em;
  font-size:var(--text-eyebrow); letter-spacing:.09em; text-transform:uppercase;
  color:var(--text-tertiary)}

.wiz-foot{
  margin-top:auto; position:sticky; bottom:0;
  display:flex; align-items:center; justify-content:space-between; gap:var(--space-4);
  padding:var(--space-4) 0; background:var(--surface-page);
  border-top:1px solid var(--border-subtle);
}
.wiz-foot .btn{min-width:150px; justify-content:center}
.wiz-foot .btn .ico{margin:0 0 0 var(--space-2)}
.wiz-foot #wizback .ico{margin:0 var(--space-2) 0 0}
.wiz-dots{display:flex; gap:5px; flex-wrap:wrap; justify-content:center}
.wiz-dots i{width:7px; height:7px; border-radius:var(--radius-pill);
  background:var(--border-subtle); display:block}
.wiz-dots i.has{background:var(--accent-quiet); opacity:.55}
.wiz-dots i.on{background:var(--accent-quiet); opacity:1;
  transform:scale(1.35)}

.wiz-sum{border:1px solid var(--border-subtle); border-radius:var(--radius-sm);
  background:var(--surface-raised); margin-bottom:var(--space-8)}
.wiz-sum-row{padding:var(--space-4); border-bottom:1px solid var(--border-subtle)}
.wiz-sum-row:last-child{border-bottom:0}
.wiz-sum-t{font-size:var(--text-eyebrow); letter-spacing:.09em; text-transform:uppercase;
  color:var(--text-secondary); margin-bottom:var(--space-2)}
.wiz-sum-n{font-size:var(--text-body-lg); line-height:var(--leading-relaxed)}

@media(max-width:900px){
  .wiz-foot .btn{min-width:0}
  .wiz-dots{display:none}
}

/* ── Night Audit: import center ─────────────────────────────────────────*/
.blocking{
  margin-top:var(--space-3); padding:var(--space-2) var(--space-3);
  background:var(--accent-clay-tint); color:var(--accent-clay-tone);
  border-radius:var(--radius-sm); font-size:var(--text-body);
}
:root[data-mode="night"] .blocking{
  background:rgb(138 72 56 / .30); color:var(--accent-clay-tint);
}
td .fn{font-size:var(--text-eyebrow); color:var(--text-tertiary); margin-top:2px;
  font-family:var(--font-mono); letter-spacing:0; text-transform:none}
.opt{margin-left:var(--space-2); font-size:var(--text-eyebrow); letter-spacing:.09em;
  text-transform:uppercase; color:var(--text-tertiary)}
.iss{font-size:var(--text-body); line-height:var(--leading-snug); margin-bottom:4px}
.iss:last-child{margin-bottom:0}
main code{font-family:var(--font-mono); font-size:.8125rem;
  background:var(--surface-sunken); padding:2px 6px; border-radius:var(--radius-sm)}

/* ── Watchdog heartbeat ─────────────────────────────────────────────────*/
.wd{
  display:flex; align-items:center; gap:var(--space-3); flex-wrap:wrap;
  padding:var(--space-3) var(--space-4); margin-bottom:var(--space-6);
  border:1px solid var(--border-subtle); border-radius:var(--radius-sm);
  background:var(--surface-raised); font-size:var(--text-body);
}
.wd b{font-weight:var(--weight-semibold)}
.wd .q{color:var(--text-secondary); font-size:var(--text-eyebrow);
  letter-spacing:.09em; text-transform:uppercase}
.wd .mark{width:7px; height:7px; border-radius:var(--radius-pill)}
.wd-ok   .mark{background:var(--accent-sage-tone)}
.wd-busy .mark{background:var(--accent-amber-tone)}
.wd-off  .mark{background:var(--accent-clay-tone)}
.mono{font-family:var(--font-mono); font-size:.75rem}

/* ── VIP 6 · GOF engine ─────────────────────────────────────────────────*/
.v6{
  border:1px solid var(--border-subtle); border-radius:var(--radius-sm);
  background:var(--surface-raised); padding:var(--space-4) var(--space-6);
  margin-bottom:var(--space-4);
}
.v6-head{display:flex; align-items:flex-start; justify-content:space-between;
  gap:var(--space-4); margin-bottom:var(--space-3)}
.v6-name{font-size:var(--text-body-lg); font-weight:var(--weight-semibold)}
.v6-sub{font-size:var(--text-eyebrow); letter-spacing:.09em; text-transform:uppercase;
  color:var(--text-secondary); margin-top:2px}
.v6-bg{font-size:var(--text-body); color:var(--text-secondary);
  padding:var(--space-2) var(--space-3); background:var(--surface-sunken);
  border-radius:var(--radius-sm); margin-bottom:var(--space-3)}
.v6-bg b{color:var(--text-primary); font-weight:var(--weight-semibold); margin-right:var(--space-2)}
.v6-grid{display:grid; grid-template-columns:repeat(auto-fit,minmax(160px,1fr));
  gap:var(--space-3); margin-bottom:var(--space-3)}
.v6-grid > div{display:flex; flex-direction:column; gap:2px; font-size:var(--text-body)}
.v6-grid .eyebrow{color:var(--text-tertiary)}
.v6-det{margin-bottom:var(--space-3)}
.v6-det summary{cursor:pointer; font-size:var(--text-eyebrow); letter-spacing:.09em;
  text-transform:uppercase; color:var(--text-secondary); padding:var(--space-2) 0}
@media (hover:hover){.v6-det summary:hover{color:var(--text-primary)}}
.v6-orig{font-size:var(--text-body); line-height:var(--leading-relaxed);
  padding:var(--space-3); background:var(--surface-sunken);
  border-left:2px solid var(--accent-quiet); border-radius:var(--radius-sm)}
.v6-src{margin-top:var(--space-2); font-family:var(--font-mono); font-size:.6875rem;
  color:var(--text-tertiary)}
.v6-sug{border-top:1px solid var(--border-subtle); padding-top:var(--space-3)}
.v6-sug-h{display:flex; align-items:center; justify-content:space-between;
  margin-bottom:var(--space-2)}
.v6-text{width:100%; font-family:inherit; font-size:var(--text-body);
  line-height:var(--leading-relaxed); padding:var(--space-3);
  color:var(--text-primary); background:var(--surface-page);
  border:1px solid var(--border-subtle); border-radius:var(--radius-sm); resize:vertical}
.v6-text:focus{outline:2px solid var(--border-focus); outline-offset:-1px; border-color:transparent}
.v6-none{font-size:var(--text-body); color:var(--text-secondary);
  padding:var(--space-3); background:var(--surface-sunken); border-radius:var(--radius-sm)}

/* ── Import-Wizard ──────────────────────────────────────────────────────
   Arbeitsblatt links, Detailansicht rechts. Die Boxen sind gestrichelt, solange
   nichts drin liegt — das ist der einzige Zustand, der zum Handeln auffordert.
   Sobald gelesen wurde, wird der Rand durchgezogen und ruhig; die Sage-Kante
   links trägt das «erledigt», nicht eine Füllfläche, die den Text tönen würde. */
.linklike{background:none; border:0; padding:0; font:inherit; cursor:pointer;
  color:var(--text-primary); text-decoration:underline; text-underline-offset:2px}

.imp{display:grid; grid-template-columns:1fr; gap:var(--space-6); align-items:start}
.imp-open{grid-template-columns:minmax(300px,7fr) 11fr}
.imp-boxes{display:grid; grid-template-columns:repeat(auto-fill,minmax(288px,1fr));
  gap:var(--space-4); align-content:start}
.imp-open .imp-boxes{grid-template-columns:1fr}

/* Der Kasten ist zentriert und ruhig: Titel, Zeichen, Dateiname, eine Zeile
   Substanz. Gestrichelt heisst leer — das ist der einzige Zustand, der zum
   Handeln auffordert; gefüllt wird der Rahmen durchgezogen und still. */
.ddrop{
  position:relative; display:flex; flex-direction:column; align-items:center;
  justify-content:center; text-align:center; gap:var(--space-2);
  min-height:208px; padding:var(--space-8) var(--space-4) var(--space-4);
  border:1px dashed var(--accent-quiet); border-radius:var(--radius-drop);
  background:var(--surface-raised); cursor:pointer;
  transition:background var(--duration-fast) var(--ease-standard),
             border-color var(--duration-fast) var(--ease-standard);
}
@media (hover:hover){.ddrop:hover{background:var(--surface-sunken)}}
.ddrop:focus-visible{outline:2px solid var(--border-focus); outline-offset:2px}
.ddrop.over{background:var(--surface-sunken); border-color:var(--text-primary)}
.ddrop.on{background:var(--surface-sunken); border-color:var(--text-secondary)}

.ddrop-done{border-style:solid; border-color:var(--accent-sage-tone)}
.ddrop-warn{border-style:solid; border-color:var(--accent-amber-tone)}
.ddrop-bad {border-style:solid; border-color:var(--accent-clay-tone)}
.ddrop-busy{border-style:solid; border-color:var(--accent-lake-tone)}

.ddrop-st{position:absolute; top:var(--space-3); right:var(--space-3)}
.ddrop-t{font-family:var(--font-display); font-size:1.0625rem; line-height:1.2}
.ddrop-t .opt{display:block; margin:2px 0 0}
.ddrop-ico{width:30px; height:30px; stroke:var(--accent-quiet); stroke-width:1.25;
  margin:var(--space-2) 0}
.ddrop-done .ddrop-ico{stroke:var(--accent-sage-tone)}
.ddrop-warn .ddrop-ico{stroke:var(--accent-amber-tone)}
.ddrop-bad  .ddrop-ico{stroke:var(--accent-clay-tone)}
.ddrop-busy .ddrop-ico{stroke:var(--accent-lake-tone)}

.ddrop-file{font-size:var(--text-body); font-variant-numeric:tabular-nums;
  word-break:break-word; max-width:30ch}
/* Kleine Zeilenzeichen: gleiche Familie, gleiche Strichstärke, tertiär gefärbt —
   sie sollen die Zeile auffindbar machen, nicht mit dem grossen Zeichen konkurrieren. */
.ddrop-mi{width:13px; height:13px; flex:none; stroke:var(--text-tertiary);
  stroke-width:1.5; vertical-align:-2px; margin-right:6px}
.ddrop-bad .ddrop-msg .ddrop-mi{stroke:var(--ms-fg)}
.ddrop-act .linklike .ddrop-mi{margin-right:5px}
.ddrop-empty .ddrop-file{color:var(--text-tertiary)}
/* Not our night auditor's problem: a source in development, or one the house
   never sends. Dashed like an empty box but visibly quieter — nothing here
   asks to be acted on today. */
.ddrop-dev{border-style:dashed; border-color:var(--border-subtle); opacity:.72}
.ddrop-dev .ddrop-ico{stroke:var(--text-tertiary)}
.ddrop-meta{font-size:var(--text-eyebrow); line-height:var(--leading-snug);
  color:var(--text-secondary); max-width:34ch}
.ddrop-msg{font-size:var(--text-body); line-height:var(--leading-snug);
  color:var(--text-secondary); max-width:36ch}
.ddrop-bad .ddrop-msg{color:var(--ms-fg)}
.ddrop-act{margin-top:var(--space-2); font-size:var(--text-eyebrow);
  letter-spacing:.09em; text-transform:uppercase; color:var(--text-tertiary)}
.ddrop-act .linklike{font:inherit; color:var(--text-secondary)}

/* Ladebalken: bekannte Prozente beim Hochladen, laufender Streifen beim Lesen —
   der Watchdog meldet keinen Fortschritt, also darf der Balken keinen vortäuschen. */
.ddrop-bar{width:100%; height:4px; margin-top:var(--space-2);
  border-radius:var(--radius-pill); background:var(--surface-sunken); overflow:hidden}
.ddrop-bar i{display:block; height:100%; background:var(--accent-lake-tone);
  border-radius:var(--radius-pill); transition:width var(--duration-fast) linear}
.ddrop-bar.busy i{background:linear-gradient(90deg,
  var(--surface-sunken) 0%, var(--accent-lake-tone) 50%, var(--surface-sunken) 100%);
  background-size:220% 100%; animation:wizpulse 1.4s linear infinite}
@keyframes wizpulse{from{background-position:120% 0} to{background-position:-120% 0}}
@media(prefers-reduced-motion:reduce){
  .ddrop-bar.busy i{animation:none; background:var(--accent-lake-tone); opacity:.5}
}

/* ── Detailansicht ──────────────────────────────────────────────────────*/
.imp-detail{position:sticky; top:0; border:1px solid var(--border-subtle);
  border-radius:var(--radius-sm); background:var(--surface-raised);
  max-height:calc(100dvh - 190px); overflow:auto}
.pv-idle{padding:var(--space-8); text-align:center; color:var(--text-secondary)}
.pv-idle .ico{width:26px; height:26px; stroke:var(--text-tertiary);
  margin-bottom:var(--space-3)}
.pv-idle b{display:block; font-family:var(--font-display); font-size:var(--text-body-lg);
  color:var(--text-primary); margin-bottom:var(--space-2)}
.pv-idle p{margin:0 auto; max-width:38ch}

.pv-h{display:flex; align-items:flex-start; justify-content:space-between;
  gap:var(--space-4); padding:var(--space-4) var(--space-4);
  border-bottom:1px solid var(--border-subtle)}
.pv-h b{font-family:var(--font-display); font-size:1.125rem}
.pv-h .q{color:var(--text-secondary); font-size:var(--text-eyebrow);
  word-break:break-all; margin-top:2px}
.pv-iss{padding:var(--space-3) var(--space-4); background:var(--pd-bg); color:var(--pd-fg)}
.pv-cols{display:grid; grid-template-columns:1fr 1fr; gap:var(--space-4);
  padding:var(--space-4)}
.pv-col{min-width:0}
.pv-col h4{margin:0 0 var(--space-2); color:var(--text-tertiary)}
.pv-col h4 + *{margin-top:0}
.pv-col > h4:not(:first-child){margin-top:var(--space-4)}

.pv-sheet{margin-bottom:var(--space-4)}
.pv-sheet .eyebrow{display:block; color:var(--text-tertiary); margin-bottom:var(--space-2)}
.pv-grid{overflow:auto; max-height:340px; border:1px solid var(--border-subtle);
  border-radius:var(--radius-sm)}
table.gx{border-collapse:collapse; font-size:var(--text-eyebrow);
  font-variant-numeric:tabular-nums; background:var(--surface-raised); width:auto}
table.gx th{position:sticky; left:0; background:var(--surface-sunken);
  color:var(--text-tertiary); text-align:right; padding:2px var(--space-2);
  border:1px solid var(--border-subtle); font-weight:var(--weight-regular)}
table.gx td{padding:2px var(--space-2); border:1px solid var(--border-subtle);
  white-space:nowrap; max-width:190px; overflow:hidden; text-overflow:ellipsis}

.pv-pdf{height:420px; border:1px solid var(--border-subtle);
  border-radius:var(--radius-sm); overflow:hidden; background:var(--surface-sunken)}
.pv-pdf iframe{width:100%; height:100%; border:0; display:block}
.pv-pdf p{padding:var(--space-4); margin:0}

.pv-slides{max-height:420px; overflow:auto}
.pv-slide{padding:var(--space-3) 0; border-bottom:1px solid var(--border-subtle)}
.pv-slide:last-child{border-bottom:0}
.pv-slide .eyebrow{color:var(--text-tertiary)}
.pv-slide ul{margin:var(--space-2) 0 0; padding-left:1.1em; font-size:var(--text-body);
  line-height:var(--leading-snug)}

.pv-g{padding:var(--space-3) 0; border-bottom:1px solid var(--border-subtle)}
.pv-g:last-child{border-bottom:0}
.pv-gh{display:flex; align-items:baseline; justify-content:space-between; gap:var(--space-3)}
.pv-gh b{font-variant-numeric:tabular-nums; font-weight:var(--weight-semibold)}
.pv-rows{list-style:none; margin:var(--space-2) 0 0; padding:0;
  font-size:var(--text-eyebrow)}
.pv-rows li{display:flex; align-items:baseline; justify-content:space-between;
  gap:var(--space-3); padding:2px 0; color:var(--text-secondary)}
.pv-rows code{font-family:var(--font-mono); flex:none;
  color:var(--text-tertiary); white-space:nowrap}
.pv-steps{margin:0; padding-left:1.1em; font-size:var(--text-body);
  line-height:var(--leading-relaxed); color:var(--text-secondary)}
.pv-steps li{margin-bottom:var(--space-2)}

@media(max-width:1100px){
  .imp-open{grid-template-columns:1fr}
  .imp-open .imp-boxes{grid-template-columns:repeat(auto-fill,minmax(290px,1fr))}
  .imp-detail{position:static; max-height:none}
  .pv-cols{grid-template-columns:1fr}
}

/* ── Dashboard pages ────────────────────────────────────────────────────*/
.sub-h{font-family:var(--font-sans); font-size:var(--text-body-lg);
  font-weight:var(--weight-semibold); letter-spacing:0;
  margin:var(--space-8) 0 var(--space-3)}
.tabs{display:flex; gap:2px; margin-bottom:var(--space-4);
  border:1px solid var(--border-subtle); border-radius:var(--radius-sm);
  overflow:hidden; width:fit-content}
.tab{font:inherit; font-size:var(--text-body); font-weight:var(--weight-medium);
  padding:.4375rem var(--space-4); border:0; cursor:pointer;
  background:transparent; color:var(--text-secondary)}
.tab + .tab{border-left:1px solid var(--border-subtle)}
@media (hover:hover){.tab:hover{background:var(--surface-sunken)}}
.tab.on{background:var(--surface-sunken); color:var(--text-primary);
  font-weight:var(--weight-semibold); box-shadow:inset 0 -2px 0 var(--accent-quiet)}
.rainbar{display:inline-block; width:70px; height:5px; margin-right:var(--space-2);
  background:var(--surface-sunken); border:1px solid var(--border-subtle);
  border-radius:var(--radius-sm); overflow:hidden; vertical-align:middle}
.rainbar i{display:block; height:100%; background:var(--accent-lake-tone)}
table details summary{cursor:pointer; color:var(--text-secondary);
  font-size:var(--text-eyebrow); letter-spacing:.09em; text-transform:uppercase}
table details .v6-orig{margin-top:var(--space-2); max-width:60ch}

/* ── VIP cards (SOP 03_VIP_Sheet layout) ────────────────────────────────*/
.vip{display:grid; grid-template-columns:132px 1fr; gap:var(--space-6);
  border:1px solid var(--border-subtle); border-radius:var(--radius-sm);
  background:var(--surface-raised); padding:var(--space-4) var(--space-6);
  margin-bottom:var(--space-4)}
.vip-l{display:flex; flex-direction:column; align-items:center; gap:var(--space-2)}
.vip-photo{width:120px; height:132px; object-fit:cover; border-radius:var(--radius-sm);
  border:1px solid var(--border-subtle); display:block}
.vip-photo-none{display:grid; place-items:center; background:var(--surface-sunken)}
.vip-photo-none .ico{width:30px; height:30px; stroke:var(--text-tertiary)}
.vip-badge{width:100%; text-align:center}
.st.nf{background:var(--nf-bg); color:var(--nf-fg)}
.vip-top{display:flex; align-items:flex-start; justify-content:space-between;
  gap:var(--space-4); margin-bottom:var(--space-3)}
.vip-name{font-family:var(--font-display); font-size:1.25rem; line-height:1.2}
.vip-sub{font-size:var(--text-body); color:var(--text-secondary); margin-top:2px}
.vip-eta{display:flex; gap:var(--space-4); flex:none}
.vip-eta span span{display:block}
.vip-eta > span{font-variant-numeric:tabular-nums; font-size:var(--text-body)}
.vip-acc{font-size:var(--text-body); color:var(--text-secondary); margin-bottom:var(--space-3)}
.vip-rooms{display:flex; flex-wrap:wrap; gap:var(--space-2); margin-bottom:var(--space-3)}
.vip-room{display:flex; align-items:baseline; gap:var(--space-2);
  padding:var(--space-2) var(--space-3); background:var(--surface-sunken);
  border-radius:var(--radius-sm); font-size:var(--text-body); font-variant-numeric:tabular-nums}
.vip-room b{font-weight:var(--weight-semibold)}
.vip-notes{display:grid; grid-template-columns:repeat(auto-fit,minmax(230px,1fr));
  gap:var(--space-3); padding-top:var(--space-3); border-top:1px solid var(--border-subtle)}
.vip-notes-stay .vip-note{border-left:2px solid var(--accent-lake-tone); padding-left:var(--space-3)}
.vip-note{font-size:var(--text-body); line-height:var(--leading-relaxed)}
.vip-note .eyebrow{display:block; color:var(--text-tertiary); margin-bottom:2px}
.vip-gof{margin-top:var(--space-3); padding-top:var(--space-3);
  border-top:1px solid var(--border-subtle); font-size:var(--text-body)}
@media(max-width:760px){ .vip{grid-template-columns:1fr} .vip-l{flex-direction:row} }

/* ── Second icon family ─────────────────────────────────────────────────
   The SVGS set draws its outlines as filled paths, so it colours through
   `fill`, not `stroke` — the opposite of Lucide. Kept as its own class so the
   two families never get mixed inside one row of siblings. */
.ico-f{width:16px; height:16px; flex:none; fill:currentColor; stroke:none;
  vertical-align:-3px}
.tile-h{display:flex; align-items:center; gap:var(--space-2); color:var(--text-tertiary)}
.tile-h .ico-f{width:15px; height:15px}
.tab .ico-f{margin-right:var(--space-2); width:15px; height:15px}
.st .ico-f{width:12px; height:12px; margin-right:5px; vertical-align:-2px}
.sub-h .ico-f{width:17px; height:17px; margin-right:var(--space-2);
  color:var(--accent-quiet)}

/* ── Compact weather in the header ──────────────────────────────────────
   Replaces the full-width band: current symbol and temperature, then the next
   two 3-hour blocks as symbols only. Clicking opens the weather page. */
/* Sits directly on the header bar — no container. Hover only lifts the
   opacity so there is still an affordance without drawing a box. */
.wxmini{
  display:flex; align-items:center; gap:var(--space-2);
  padding:0 var(--space-2); font:inherit; cursor:pointer;
  background:transparent; color:var(--text-primary);
  border:0; border-radius:var(--radius-sm);
  white-space:nowrap; opacity:.92;
  transition:opacity var(--duration-fast) var(--ease-standard);
}
@media (hover:hover){.wxmini:hover{opacity:1}}
.wxmini:focus-visible{outline:2px solid var(--border-focus); outline-offset:2px}
.wxmini[hidden]{display:none}
.wxmini-now{width:26px; height:26px; display:block}
.wxmini-t{font-family:var(--font-display); font-size:1.0625rem; line-height:1;
  font-variant-numeric:tabular-nums}
.wxmini-next{display:flex; align-items:center; gap:2px; opacity:.7}
.wxmini-next img{width:17px; height:17px; display:block}
.wxmini-warn{width:6px; height:6px; border-radius:var(--radius-pill);
  background:var(--accent-clay-tone); flex:none}
@media(max-width:900px){ .wxmini-next{display:none} }

/* ── Feedback & Tickets ─────────────────────────────────────────────────
   Erste schreibende Oberfläche der App. Bewusst keine neuen Bausteine: die
   Filter sind .gof-filter/.pill wie bei GOF und Ankünften, die Statusplaketten
   .st mit den bestehenden Tonpaaren, die Herkunftszeile .srcnote. Neu ist nur
   das Blatt (Overlay) und die Ticketzeile. */
.hbtn{
  display:grid; place-items:center; width:34px; height:34px; flex:none;
  background:transparent; border:0; border-radius:var(--radius-sm);
  color:var(--text-secondary); cursor:pointer;
  transition:color var(--duration-fast) var(--ease-standard),
             background var(--duration-fast) var(--ease-standard);
}
.hbtn:focus-visible{outline:2px solid var(--border-focus); outline-offset:2px}
@media (hover:hover){@media (hover:hover){ .hbtn:hover{color:var(--text-primary); background:var(--surface-sunken)} }}

/* Das Blatt. Tiefe ist Flächenwechsel plus Haarlinie — kein Schlagschatten;
   die Abdunklung dahinter trägt die Ebene. */
.sheet-wrap{position:fixed; inset:0; z-index:20; display:none}
.sheet-wrap.on{display:grid; place-items:center; padding:var(--space-6)}
/* Abdunklung aus dem Ink-Token gemischt, nicht als eigener Farbwert notiert —
   dieselbe Regel wie beim Schatten der Anmeldekarte. */
.sheet-scrim{position:absolute; inset:0;
  background:color-mix(in srgb, var(--color-ink) 42%, transparent)}
.sheet{
  position:relative; width:100%; max-width:520px; max-height:calc(100dvh - 3rem);
  overflow-y:auto; background:var(--surface-raised);
  border:1px solid var(--border-subtle); border-radius:var(--radius-sm);
  padding:var(--space-8);
}
.sheet-h{display:flex; align-items:flex-start; justify-content:space-between;
  gap:var(--space-4); margin-bottom:var(--space-6)}
.sheet-ctx{font-size:var(--text-body); color:var(--text-secondary); margin-top:2px}
.sheet-f{display:flex; align-items:center; justify-content:flex-end;
  gap:var(--space-3); margin-top:var(--space-6)}
.sheet-f .msg{margin-right:auto}
.sheet textarea, .sheet input{
  width:100%; padding:.625rem .75rem; font-family:inherit; font-size:var(--text-body);
  color:var(--text-primary); background:var(--surface-page);
  border:1px solid var(--border-subtle); border-radius:var(--radius-sm);
  margin-bottom:var(--space-4); resize:vertical;
}
.sheet textarea:focus, .sheet input:focus{
  outline:2px solid var(--border-focus); outline-offset:-1px; border-color:transparent}
.fb-hint{display:flex; align-items:flex-start; gap:var(--space-2);
  font-size:var(--text-eyebrow); color:var(--text-secondary); letter-spacing:0;
  text-transform:none}
.fb-hint .ico{width:14px; height:14px; margin-top:1px}
.fb-thanks{margin:0; font-size:var(--text-body-lg); line-height:var(--leading-relaxed)}

/* Ticketzeile: geschlossen eine Zeile, offen ein Block — dasselbe Muster wie
   die GOF-Karten, damit nichts Neues zu lernen ist. */
.fb-t{background:var(--surface-raised); border:1px solid var(--border-subtle);
  border-radius:var(--radius-sm); margin-bottom:2px}
.fb-t.on{border-color:var(--border-strong)}
.fb-t-h{display:flex; align-items:center; gap:var(--space-3); flex-wrap:wrap;
  padding:var(--space-3) var(--space-4); cursor:pointer; min-height:44px}
.fb-t-h:focus-visible{outline:2px solid var(--border-focus); outline-offset:-2px}
@media (hover:hover){@media (hover:hover){ .fb-t-h:hover{background:var(--surface-sunken)} }}
.fb-ref{font-size:.75rem; color:var(--text-secondary); flex:none}
.fb-t-title{flex:1 1 12rem; min-width:0; font-size:var(--text-body)}
.fb-t-sec{font-size:var(--text-eyebrow); letter-spacing:.09em; text-transform:uppercase}
.fb-t-b{padding:0 var(--space-4) var(--space-4); border-top:1px solid var(--border-subtle)}
.fb-t-b > label{margin-top:var(--space-4)}
.fb-t-b textarea, .fb-t-b input{
  width:100%; padding:.5rem .625rem; font-family:inherit; font-size:var(--text-body);
  color:var(--text-primary); background:var(--surface-page);
  border:1px solid var(--border-subtle); border-radius:var(--radius-sm); resize:vertical}
.fb-body{margin:var(--space-4) 0 var(--space-2); font-size:var(--text-body);
  line-height:var(--leading-relaxed); white-space:pre-wrap}
.fb-triage{display:flex; flex-wrap:wrap; gap:var(--space-4); margin-top:var(--space-4)}
.fb-triage label{display:flex; align-items:center; gap:var(--space-2); margin:0}
.fb-sel{font-family:inherit; font-size:var(--text-body); padding:.3125rem var(--space-2);
  color:var(--text-primary); background:var(--surface-page);
  border:1px solid var(--border-subtle); border-radius:var(--radius-sm)}
.fb-sel:disabled{color:var(--text-secondary); background:var(--surface-sunken)}
.fb-plan{margin-top:var(--space-4); font-size:var(--text-body);
  line-height:var(--leading-relaxed)}
.fb-plan .eyebrow{margin-right:var(--space-2)}
.fb-events{margin-top:var(--space-4); border-top:1px solid var(--border-subtle);
  padding-top:var(--space-3)}
.fb-ev{font-size:var(--text-eyebrow); letter-spacing:0; text-transform:none;
  color:var(--text-primary); margin-bottom:2px}
.fb-ev .q{margin-right:var(--space-2); font-variant-numeric:tabular-nums}
.fb-t-f{display:flex; align-items:center; gap:var(--space-3); margin-top:var(--space-4)}
.fb-t-f input{flex:1}
/* Für «Idee» wird die bestehende Plakette .st.nf mitbenutzt (neutraler Slate-Ton,
   keine Wertung). Hier stand zuerst eine zweite Definition mit denselben Farben
   fest verdrahtet — sie hätte den Nachtmodus zerlegt, weil --nf-bg/--nf-fg dort
   auf einen halbtransparenten Ton umschalten und meine Kopie später kam und
   gewonnen hätte. Nicht duplizieren, mitbenutzen. */

/* ── Tagesverlauf-Diagramm ──────────────────────────────────────────────
   Drei Streifen, je eine Grösse, ein Zeitstrahl. Keine Farbe steht im JS: die
   Marken tragen Klassen, die Farbe kommt aus den Tokens. Niederschlag und
   Risiko teilen den Lake-Ton — dieselbe Sache, zwei Auflösungen; Böen tragen
   Slate, das im System als «supplementary / quiet» geführt wird.

   Gemessen, nicht geschätzt: Lake-Ton auf --surface-raised ergibt 5.78:1,
   Slate-Ton 5.93:1 — beide über der Grenze von 3:1 für grafische Objekte. Die
   Tints liegen bei 1.19:1 und dürfen deshalb nur Fläche sein, nie Linie. Im
   Nachtmodus fällt der Lake-Ton auf 2.67:1 gegen Ink, also übernimmt dort der
   Tint die Linie — der Dunkelmodus ist gewählt, nicht gespiegelt. */
.wxc-wrap{width:min(720px,100%); margin-bottom:var(--space-6)}
.wxc{width:100%; height:auto; display:block; overflow:visible}
.wxc-lab{font-family:var(--font-sans); font-size:9px; font-weight:var(--weight-semibold);
  letter-spacing:.09em; text-transform:uppercase; fill:var(--text-secondary)}
.wxc-tick{font-family:var(--font-sans); font-size:9px; fill:var(--text-tertiary);
  font-variant-numeric:tabular-nums}
.wxc-tick.mid{fill:var(--text-secondary)}
.wxc-note{font-family:var(--font-sans); font-size:8px; fill:var(--text-tertiary)}
.wxc-max{font-family:var(--font-sans); font-size:9px; fill:var(--text-tertiary);
  font-variant-numeric:tabular-nums}
/* «jetzt» und das Ende der hochauflösenden Reihe sind Marken, keine Daten —
   also Taupe, das im System genau dafür da ist. */
.wxc-now{stroke:var(--accent-quiet); stroke-width:1}
.wxc-end{stroke:var(--accent-quiet); stroke-width:1; stroke-dasharray:2 2}
.wxc-base{stroke:var(--border-subtle); stroke-width:1}
.wxc-grid{stroke:var(--border-subtle); stroke-width:1; opacity:.55}
.wxc-grid.mid{opacity:1}
.wxc-line{fill:none; stroke-width:2; stroke-linejoin:round; stroke-linecap:round}
.wxc-band{stroke:none; opacity:.45}
.wxc-area{stroke:none; opacity:.28}
.wxc-rain .wxc-line, .wxc-prob .wxc-line{stroke:var(--accent-lake-tone)}
.wxc-rain .wxc-area, .wxc-prob .wxc-area,
.wxc-rain .wxc-band{fill:var(--accent-lake-tone)}
.wxc-gust .wxc-line{stroke:var(--accent-slate-tone)}
.wxc-gust .wxc-band{fill:var(--accent-slate-tone)}
:root[data-mode="night"] .wxc-rain .wxc-line,
:root[data-mode="night"] .wxc-prob .wxc-line{stroke:var(--accent-lake-tint)}
:root[data-mode="night"] .wxc-gust .wxc-line{stroke:var(--accent-slate-tint)}
:root[data-mode="night"] .wxc-rain .wxc-area,
:root[data-mode="night"] .wxc-prob .wxc-area,
:root[data-mode="night"] .wxc-rain .wxc-band{fill:var(--accent-lake-tint)}
:root[data-mode="night"] .wxc-gust .wxc-band{fill:var(--accent-slate-tint)}
.wxc-cross{stroke:var(--accent-quiet); stroke-width:1; pointer-events:none}
.wxc-read{margin-top:var(--space-2); font-size:var(--text-eyebrow);
  letter-spacing:.09em; text-transform:uppercase; color:var(--text-secondary);
  font-variant-numeric:tabular-nums; min-height:1.2em}

/* ── Radar ──────────────────────────────────────────────────────────────*/
/* Quadratische Bühne, die mitskaliert. Vorher war die Karte 768 px breit und
   hoch verdrahtet, mit absolut in Pixeln platzierten Kacheln — auf einem
   Telefon blieb davon der linke obere Ausschnitt übrig und die Bürgenstock-
   Markierung lag ausserhalb. Kachelmaße und Markierung sind jetzt in Prozent,
   also ist eine Breitenangabe die ganze Anpassung. */
.radar-map{position:relative; overflow:hidden; border:1px solid var(--border-subtle);
  border-radius:var(--radius-sm); background:var(--surface-sunken);
  width:min(768px, 100%); aspect-ratio:1}
.radar-map img{position:absolute; display:block}
/* Die Graukarte trägt schon keine Farbe mehr; die leichte Entsättigung bleibt
   nur, um die Reliefschattierung hinter den Niederschlagsklassen zu beruhigen. */
.radar-base{filter:saturate(.75)}
:root[data-mode="night"] .radar-base{filter:saturate(.6) brightness(.75)}
/* Halbdurchlässig, damit das Relief durchkommt. Mit PNG8 trägt jede Klasse
   volle Deckung — die Palette kennt nur «transparent» oder «Farbe» — deshalb
   sitzt die Durchlässigkeit hier und nicht im Bild. So bleibt eine Datei bei
   ~33 KB statt als RGBA auf ein Vielfaches zu wachsen.
   Kein image-rendering:pixelated mehr: die Klassengrenzen werden serverseitig
   bilinear interpoliert, also sollen sie weich bleiben. */
.radar-now{inset:0; width:100%; height:100%; opacity:.78}
/* Position kommt aus dem Markup (aus Länge/Breite gerechnet), nicht von hier —
   die feste Mitte war rund 10 km neben dem Resort. */
.radar-pin{position:absolute; width:11px; height:11px;
  margin:-6px 0 0 -6px;
  border-radius:var(--radius-pill); background:var(--accent-quiet);
  outline:2px solid var(--surface-raised); pointer-events:none}
/* Der einzige Ortsname auf der Karte. Punkt und Schrift tragen Ink auf einem
   schmalen cremefarbenen Träger, damit der Name über jeder Niederschlagsklasse
   lesbar bleibt — Taupe wäre hier falsch, das ist eine Marke, keine Schrift. */
.radar-place{position:absolute; transform:translate(-50%,-50%); display:flex;
  align-items:center; gap:4px; pointer-events:none; white-space:nowrap}
.radar-place i{width:5px; height:5px; flex:none; border-radius:var(--radius-pill);
  background:var(--text-primary); outline:1.5px solid rgb(241 240 235 / .85)}
.radar-place span{font-size:var(--text-eyebrow); font-weight:var(--weight-semibold);
  letter-spacing:.09em; text-transform:uppercase; color:var(--text-primary);
  background:rgb(241 240 235 / .78); padding:0 3px; border-radius:var(--radius-sm)}
.radar-err{position:absolute; inset:0; display:grid; place-items:center;
  color:var(--text-secondary); font-size:var(--text-body)}
.radar-ctl{display:flex; align-items:center; gap:var(--space-4);
  margin-top:var(--space-3); width:min(768px, 100%)}
.radar-win{margin-top:var(--space-3)}
/* Die Legende führt die Farbskala von MeteoSchweiz, nicht die Tokens: die
   Belegschaft liest genau diese Klassen täglich auf meteoschweiz.ch, und eine
   umgefärbte meteorologische Konvention wäre schwerer zu lesen, nicht
   markentreuer. Dieselbe Begründung wie bei den farbigen MeteoSchweiz-Symbolen
   (docs/03). Die Farben stehen ausschliesslich in radar.json — hier ist keine
   einzige davon fest verdrahtet. */
.radar-legend{display:flex; flex-wrap:wrap; align-items:center; gap:var(--space-3);
  margin-top:var(--space-3); width:min(768px, 100%);
  font-size:var(--text-eyebrow); color:var(--text-secondary)}
.radar-legend .rl{display:inline-flex; align-items:center; gap:var(--space-2);
  font-variant-numeric:tabular-nums}
.radar-legend .rl i{width:11px; height:11px; display:block;
  border:1px solid var(--border-subtle)}
.radar-ctl input[type=range]{flex:1; accent-color:var(--accent-quiet)}
.radar-time{font-variant-numeric:tabular-nums; font-size:var(--text-body);
  color:var(--text-secondary); min-width:9ch}

/* ── GOF cards ──────────────────────────────────────────────────────────
   One card per incident. The author line is set apart from the prose it
   introduces, because a thread of three entries run together as one block is
   what made the table version unreadable. */
.gof-filter{display:flex; flex-wrap:wrap; gap:var(--space-1); margin-bottom:var(--space-6);
  padding:var(--space-2); background:var(--surface-sunken);
  border:1px solid var(--border-subtle); border-radius:var(--radius-pill); width:fit-content;
  max-width:100%}
.pill{
  font:inherit; font-size:var(--text-eyebrow); font-weight:var(--weight-semibold);
  letter-spacing:.09em; text-transform:uppercase; cursor:pointer;
  padding:.3125rem var(--space-3); border-radius:var(--radius-pill);
  background:transparent; color:var(--text-secondary);
  border:1px solid var(--border-subtle);
}
.pill{border-color:transparent}
@media (hover:hover){.pill:hover{background:var(--surface-raised); color:var(--text-primary)}}
/* Active state uses the lake tint/tone pair — the system's "information"
   colour, and the only accent that stays above AA as text on its own tint. */
.pill.on{background:var(--accent-lake-tint); color:var(--accent-lake-tone);
  border-color:transparent}
:root[data-mode="night"] .pill.on{background:rgb(66 99 128 / .34);
  color:var(--accent-lake-tint)}

/* One card per incident. The card itself carries no padding — each section
   pads itself, so the header band can span the full width without negative
   margins. The earlier version pulled the band outward with -24px margins and
   it escaped the card entirely. */
/* The card itself is painted in the BAND colour and the sections below paint
   the card colour back over it. The band therefore has no top edge of its own
   to meet — the earlier version relied on a child's fill reaching the clipped,
   rounded corner exactly, and left a hairline of card background above it. */
.gof{
  border:1px solid var(--border-subtle); border-left:3px solid var(--border-subtle);
  border-radius:var(--radius-sm); background:rgb(159 146 135 / .11);
  margin-bottom:var(--space-4); overflow:hidden;
}
:root[data-mode="night"] .gof{background:rgb(241 240 235 / .05)}
.gof-open{border-left-color:var(--accent-clay-tone)}
.gof-solved{border-left-color:var(--accent-sage-tone)}

/* Header band: a shade darker so the identifying facts read as one block. */
.gof-h{
  display:flex; align-items:flex-start; justify-content:space-between;
  gap:var(--space-4); flex-wrap:wrap;
  padding:var(--space-4) var(--space-6);
  border-bottom:1px solid var(--border-subtle);
}
.gof-id{min-width:0; flex:1 1 260px}
.gof-name{font-family:var(--font-display); font-size:1.125rem; line-height:1.25}
.gof-meta{display:flex; align-items:center; flex-wrap:wrap; gap:var(--space-2) var(--space-4);
  margin-top:var(--space-2); font-size:var(--text-body); color:var(--text-secondary)}
.gof-meta > span{display:inline-flex; align-items:center; gap:var(--space-2);
  font-variant-numeric:tabular-nums; white-space:nowrap}
.gof-meta .ico{width:14px; height:14px; stroke:var(--text-tertiary)}
.gof-meta .ico-f{width:14px; height:14px; color:var(--text-tertiary)}
.gof-room{font-family:var(--font-display); font-size:1.0625rem; color:var(--text-primary)}
.gof-room .ico-f{color:var(--accent-quiet)}
.gof-by-h{color:var(--text-tertiary)}
.gof-tags{display:flex; gap:var(--space-2); flex-wrap:wrap; flex:0 1 auto;
  justify-content:flex-end}

.gof-cat{display:flex; align-items:center; gap:var(--space-3); flex-wrap:wrap;
  background:var(--surface-raised);
  padding:var(--space-3) var(--space-6);
  border-bottom:1px solid var(--border-subtle); font-size:var(--text-body)}
.gof-bereich{font-weight:var(--weight-semibold)}
.gof-issue{color:var(--text-secondary)}
.gof-cat .q{color:var(--text-tertiary); font-size:var(--text-eyebrow);
  letter-spacing:.09em; text-transform:uppercase}

.gof-sum{background:var(--surface-raised); padding:var(--space-3) var(--space-6);
  font-size:var(--text-body-lg); line-height:var(--leading-relaxed)}
.gof-sum .eyebrow{display:block; color:var(--text-tertiary); margin-bottom:2px}

/* The thread is closed by default: the Kurz line answers "what happened",
   the Verlauf answers "how", and only some cases need the second question. */
.gof-thread{background:var(--surface-raised);
  border-top:1px solid var(--border-subtle); padding:0 var(--space-6)}
.gof-thread > summary{
  cursor:pointer; list-style:none; display:flex; align-items:center; gap:var(--space-3);
  padding:var(--space-3) 0; color:var(--text-secondary);
}
.gof-thread > summary::-webkit-details-marker{display:none}
.gof-thread > summary::before{
  content:""; width:0; height:0; flex:none;
  border-left:5px solid currentColor; border-top:4px solid transparent;
  border-bottom:4px solid transparent; opacity:.6;
  transition:transform var(--duration-fast) var(--ease-standard);
}
.gof-thread[open] > summary::before{transform:rotate(90deg)}
@media (hover:hover){.gof-thread > summary:hover{color:var(--text-primary)}}
.gof-thread > summary .eyebrow{color:inherit}
.gof-cnt{font-size:var(--text-eyebrow); letter-spacing:.09em; text-transform:uppercase;
  color:var(--text-tertiary); font-variant-numeric:tabular-nums}
.gof-entries{padding-bottom:var(--space-3)}
.gof-entry{display:grid; grid-template-columns:170px minmax(0,1fr); gap:var(--space-4);
  padding-bottom:var(--space-3); margin-bottom:var(--space-3);
  border-bottom:1px solid var(--border-subtle)}
.gof-entry:last-child{border-bottom:0; padding-bottom:0; margin-bottom:0}
.gof-by{font-size:var(--text-body); font-weight:var(--weight-semibold); line-height:1.35}
.gof-by span{display:block; font-weight:var(--weight-regular);
  font-size:var(--text-eyebrow); letter-spacing:.09em; text-transform:uppercase;
  color:var(--text-tertiary); font-variant-numeric:tabular-nums; margin-top:2px}
.gof-text{font-size:var(--text-body); line-height:var(--leading-relaxed);
  color:var(--text-secondary); overflow-wrap:anywhere}
.gof-f{background:var(--surface-raised); padding:var(--space-3) var(--space-6);
  border-top:1px solid var(--border-subtle);
  font-size:var(--text-eyebrow); letter-spacing:.09em; text-transform:uppercase;
  color:var(--accent-sage-tone)}
@media(max-width:760px){ .gof-entry{grid-template-columns:1fr; gap:var(--space-2)} }

/* ── Terrace recommendation ─────────────────────────────────────────────*/
.terr{border:1px solid var(--border-subtle); border-left:3px solid var(--border-subtle);
  border-radius:var(--radius-sm); background:var(--surface-raised);
  padding:var(--space-4) var(--space-6); margin-bottom:var(--space-8)}
.terr-up{border-left-color:var(--accent-sage-tone)}
.terr-pd{border-left-color:var(--accent-amber-tone)}
.terr-ms{border-left-color:var(--accent-clay-tone)}
.terr-h{display:flex; align-items:center; gap:var(--space-3); margin-bottom:var(--space-3)}
.terr-h .eyebrow{color:var(--text-tertiary)}
.terr-r{margin:0; padding-left:1.1rem; font-size:var(--text-body-lg);
  line-height:var(--leading-relaxed)}
.terr-r:not(ul){padding-left:0; color:var(--text-secondary)}
.terr-f{margin-top:var(--space-3); padding-top:var(--space-3);
  border-top:1px solid var(--border-subtle);
  font-size:var(--text-eyebrow); letter-spacing:.06em; color:var(--text-tertiary);
  line-height:var(--leading-normal); text-transform:none}

/* ── VIP page additions ─────────────────────────────────────────────────*/
.vip-meta{display:flex; align-items:center; flex-wrap:wrap; gap:var(--space-2) var(--space-4);
  margin-top:var(--space-2); font-size:var(--text-body); color:var(--text-secondary)}
.vip-meta > span{display:inline-flex; align-items:center; gap:var(--space-2);
  font-variant-numeric:tabular-nums; white-space:nowrap}
.vip-meta .ico{width:14px; height:14px; stroke:var(--text-tertiary)}
.vip-flags{display:flex; flex-wrap:wrap; gap:var(--space-2); margin-bottom:var(--space-3)}
.vip-room .ico-f{width:13px; height:13px; color:var(--accent-quiet)}
.vip-hist{font-size:var(--text-eyebrow); letter-spacing:.06em; color:var(--text-tertiary);
  margin:calc(var(--space-3) * -1) 0 var(--space-3)}
.vip-src{display:flex; align-items:flex-start; gap:var(--space-2);
  padding:var(--space-3) var(--space-4); margin-bottom:var(--space-4);
  background:var(--surface-sunken); border-radius:var(--radius-sm);
  font-size:var(--text-body); line-height:var(--leading-relaxed);
  color:var(--text-secondary)}
.vip-src .mark{margin-top:.5em}


/* ── Restaurants — status pills ─────────────────────────────────────────
   Six outlets, one glance. The image is 26 px inside the pill: enough to
   recognise the place, small enough that colour still does the talking. */
.rp-row{display:flex; flex-wrap:wrap; gap:var(--space-3); margin-bottom:var(--space-4)}
.rp{
  display:inline-flex; align-items:center; gap:var(--space-3);
  padding:.3125rem var(--space-4) .3125rem .3125rem;
  border:1px solid transparent; border-radius:var(--radius-pill);
  font:inherit; font-size:var(--text-body); font-weight:var(--weight-medium);
  cursor:pointer; white-space:nowrap;
  transition:filter var(--duration-fast) var(--ease-standard);
}
@media (hover:hover){.rp:hover{filter:brightness(.97)}}
@media (hover:hover){:root[data-mode="night"] .rp:hover{filter:brightness(1.12)}}
.rp-img{width:26px; height:26px; border-radius:var(--radius-pill); overflow:hidden;
  flex:none; display:grid; place-items:center; background:var(--surface-sunken)}
.rp-img img{width:100%; height:100%; object-fit:cover; display:block}
.rp-mono{font-family:var(--font-display); font-size:.8125rem; color:var(--text-secondary)}
.rp-n{line-height:1}
.rp-dot{width:7px; height:7px; border-radius:var(--radius-pill);
  background:currentColor; opacity:.55; flex:none}
.rp-nf{background:var(--nf-bg); color:var(--nf-fg)}
.rp-up{background:var(--ok-bg); color:var(--ok-fg)}
.rp-pd{background:var(--pd-bg); color:var(--pd-fg)}
.rp-ms{background:var(--ms-bg); color:var(--ms-fg)}

.rp-legend{display:flex; flex-wrap:wrap; align-items:center; gap:var(--space-4);
  margin-bottom:var(--space-8); font-size:var(--text-eyebrow);
  letter-spacing:.09em; text-transform:uppercase; color:var(--text-secondary)}
.rp-legend span{display:inline-flex; align-items:center; gap:var(--space-2)}
.rp-legend .q{color:var(--text-tertiary); text-transform:none; letter-spacing:.04em}
.rp-key{width:11px; height:11px; border-radius:var(--radius-pill); display:inline-block}

/* ── Restaurant opening-hours matrix ────────────────────────────────────
   Reproduces the Daily Recap's own grid: services down, outlets across,
   green where open and red where closed. Vertical merges become rowspan. */
.rx-wrap{overflow-x:auto; margin-bottom:var(--space-4)}
table.rx{width:100%; min-width:760px; border-collapse:collapse;
  border:1px solid var(--border-subtle); border-radius:var(--radius-sm); overflow:hidden}
table.rx th, table.rx td{border:1px solid var(--surface-page); padding:.5rem var(--space-3);
  text-align:center; font-size:var(--text-body); font-variant-numeric:tabular-nums}
table.rx thead th{background:var(--surface-nav); color:var(--on-nav);
  font-family:var(--font-display); font-weight:var(--weight-regular);
  font-size:1.0625rem; letter-spacing:0; text-transform:none}
table.rx thead th.rx-corner{text-align:left; text-decoration:underline;
  text-underline-offset:3px}
.rx-svc{background:var(--surface-nav); color:var(--on-nav); text-align:left !important;
  font-size:var(--text-eyebrow); letter-spacing:.06em; font-weight:var(--weight-semibold);
  white-space:nowrap}
.rx-open{background:var(--accent-sage-tint); color:var(--color-ink);
  font-weight:var(--weight-medium)}
.rx-closed{background:var(--accent-clay-tint)}
:root[data-mode="night"] .rx-open{background:rgb(70 108 61 / .42); color:var(--color-creme)}
:root[data-mode="night"] .rx-closed{background:rgb(138 72 56 / .38)}

/* Stay length. Sits with the dates rather than among the status flags —
   it describes the stay, it is not a warning about it. */
.vip-nights{
  display:inline-flex; align-items:center;
  padding:.125rem var(--space-3); border-radius:var(--radius-pill);
  background:var(--surface-sunken); color:var(--text-primary);
  border:1px solid var(--border-subtle);
  font-size:var(--text-eyebrow); font-weight:var(--weight-semibold);
  letter-spacing:.06em; font-variant-numeric:tabular-nums; white-space:nowrap;
}
/* A week or more is the case the LONG status exists for — worth its own weight. */
.vip-nights-long{background:var(--nf-bg); color:var(--nf-fg); border-color:transparent}

/* ── Datenpflege ────────────────────────────────────────────────────────*/
.care-sum{display:flex; flex-wrap:wrap; gap:var(--space-2); margin-bottom:var(--space-6)}
.care{border:1px solid var(--border-subtle); border-left:3px solid var(--accent-quiet);
  border-radius:var(--radius-sm); background:var(--surface-raised);
  padding:var(--space-3) var(--space-4); margin-bottom:var(--space-3)}
.care-t{display:flex; align-items:center; justify-content:space-between; gap:var(--space-3);
  font-size:var(--text-body-lg); font-weight:var(--weight-medium)}
.care-d{margin-top:var(--space-2); font-size:var(--text-body);
  line-height:var(--leading-relaxed); color:var(--text-secondary)}
.care-w{margin-top:var(--space-2); font-size:var(--text-eyebrow);
  letter-spacing:.09em; text-transform:uppercase; color:var(--text-tertiary)}
.care-w .eyebrow{color:var(--text-tertiary); margin-right:var(--space-2)}

/* ═══════════════════════════════════════════════════════════════════════
   Single ground: every surface in the day view is creme #F1F0EB.

   The token set ships three surfaces — page #F1F0EB, raised #F6F5EF and
   sunken #EDECEA — and cards, table headers and inset panels used the
   difference to separate themselves. Flattening them to one colour means
   structure now rests entirely on the hairline, which is the other half of
   the system's own rule ("depth is a surface change plus a hairline").

   Two things are deliberately NOT flattened:
   · the navbar, which is #283153 by request
   · night mode, which is a different ground by design
   ═══════════════════════════════════════════════════════════════════════ */
:root{
  --surface-raised:#F1F0EB;
  --surface-sunken:#F1F0EB;
  /* Interaction still needs to answer. A hover is a state, not a surface, so
     it is a taupe wash rather than a second background colour. */
  --wash:rgb(159 146 135 / .12);
}

@media (hover:hover){/* Anything that used a surface change to read as interactive gets the wash. */
.pill:hover,
.seg:hover,
.tab:hover,
.modesw button:hover,
.btn-quiet:hover,
.act:hover,
nav a:hover,
.linkbtn:hover{background:var(--wash)}}

/* Selected states were also carried by the sunken tone; give them the wash
   plus the weight they already had. */
.tab.on,
.modesw button.on{background:var(--wash)}

/* Table headers and the filter track lose their fill, so their rule does the
   separating instead. */
table th{background:transparent; border-bottom:1px solid var(--border-strong)}
.gof-filter{background:transparent}
.rest-seg,
.rp-img{background:var(--wash)}

/* Quoted source text kept its taupe edge; without a fill the edge carries it. */
.v6-orig,
.gof-orig{background:transparent}
.vip-src,
.care-d,
.v6-none,
.rest-none{background:transparent}
.vip-bg{background:var(--wash)}

/* ── Geburtstage ────────────────────────────────────────────────────────
   Two columns, unit before person: the department or room is what the room
   scans for, the name is what they read once they have found it. */
table.bd{width:auto; min-width:min(420px,100%)}
table.bd td{padding:.4375rem var(--space-4); border-bottom:1px solid var(--border-subtle)}
table.bd tr:last-child td{border-bottom:0}
.bd-unit{font-family:var(--font-display); font-size:1.0625rem; white-space:nowrap;
  font-variant-numeric:tabular-nums; padding-left:0 !important}
.bd-person{color:var(--text-secondary); width:100%}
.bd-src{margin-top:var(--space-4); display:flex; align-items:center; gap:var(--space-2);
  font-size:var(--text-eyebrow); letter-spacing:.09em; text-transform:uppercase;
  color:var(--text-tertiary)}

/* ── Ankünfte ───────────────────────────────────────────────────────────
   Gleiche Anatomie wie die VIP-Karte, nur ohne Foto: links eine schmale
   Zimmerspalte als Anker, rechts der Satz. Die Rate steht rechts oben, weil
   sie im PMS-Bericht dort steht — die Reihenfolge der Quelle bleibt lesbar. */
.st.rs{background:var(--rs-bg); color:var(--rs-fg)}
.st.lk{background:var(--lk-bg); color:var(--lk-fg)}

.arr{display:grid; grid-template-columns:104px 1fr; gap:var(--space-6);
  border:1px solid var(--border-subtle); border-radius:var(--radius-sm);
  background:var(--surface-raised); padding:var(--space-4) var(--space-6);
  margin-bottom:var(--space-3)}
.arr-room{display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:2px; padding:var(--space-2); background:var(--surface-sunken);
  border-radius:var(--radius-sm); text-align:center}
.arr-room .ico-f{color:var(--accent-quiet); width:15px; height:15px}
.arr-room b{font-size:1.25rem; font-weight:var(--weight-semibold);
  font-variant-numeric:tabular-nums; line-height:1.1}
.arr-room .q{font-size:var(--text-eyebrow); color:var(--text-tertiary)}
.arr-top{display:flex; align-items:baseline; justify-content:space-between;
  gap:var(--space-4); margin-bottom:var(--space-2)}
.arr-name{font-family:var(--font-display); font-size:1.125rem; line-height:1.2}
.arr-rate{flex:none; text-align:right; font-variant-numeric:tabular-nums}
.arr-rate .eyebrow{display:block; color:var(--text-tertiary)}
.arr-rate b{font-weight:var(--weight-semibold)}
.arr-meta{display:flex; flex-wrap:wrap; gap:var(--space-2) var(--space-4);
  color:var(--text-secondary); font-size:var(--text-body); margin-bottom:var(--space-3)}
.arr-meta .ico{width:14px; height:14px; vertical-align:-2px; margin-right:4px;
  stroke:var(--text-tertiary)}
.arr-flags{display:flex; flex-wrap:wrap; gap:var(--space-2)}
.arr-notes{display:grid; grid-template-columns:repeat(auto-fit,minmax(240px,1fr));
  gap:var(--space-3); margin-top:var(--space-3); padding-top:var(--space-3);
  border-top:1px solid var(--border-subtle)}
.arr-note{font-size:var(--text-body); line-height:var(--leading-relaxed)}
.arr-note .eyebrow{display:block; color:var(--text-tertiary); margin-bottom:2px}

.arr-house{margin-top:var(--space-6)}
.arr-house summary{cursor:pointer; color:var(--text-secondary);
  padding:var(--space-3) 0; font-size:var(--text-body)}
@media (hover:hover){.arr-house summary:hover{color:var(--text-primary)}}
.arr-house table{margin-top:var(--space-2); width:auto; min-width:min(380px,100%)}

@media(max-width:760px){
  .arr{grid-template-columns:1fr}
  .arr-room{flex-direction:row; gap:var(--space-3); justify-content:flex-start}
  .arr-top{flex-direction:column; gap:var(--space-1)}
  .arr-rate{text-align:left}
}

/* ── Gästezufriedenheit (Qualtrics) ─────────────────────────────────────────
   The three headline figures inherit .tile .v, so Lora is spent there and on
   the page title — exactly the four-use cap. Everything below stays Montserrat.
   No navy anywhere: the benchmark set is a peer comparison, and navy means the
   year-over-year series and nothing else. Emphasis on the house column is a
   surface change plus a hairline, in keeping with the no-shadow rule. */
.qx-tile .v{display:flex; align-items:baseline; gap:.25rem}
.qx-sc{font-family:var(--font-sans); font-size:var(--text-body);
  color:var(--text-secondary); font-weight:var(--weight-regular)}
.qx-tile .d{display:flex; align-items:center; gap:var(--space-2); flex-wrap:wrap}
.qx-n{font-size:var(--text-eyebrow)}

.qx-block{margin-bottom:var(--space-8)}
.qx-block>.eyebrow{display:block; margin-bottom:var(--space-2)}
.qx-bench td{font-variant-numeric:tabular-nums}
.qx-bench td.qx-own{background:var(--surface-sunken);
  border-left:1px solid var(--border-subtle);
  border-right:1px solid var(--border-subtle)}
.qx-d{margin-left:.375rem; font-size:var(--text-eyebrow)}
.qx-resid{margin:var(--space-3) 0 0; max-width:var(--layout-measure)}

.qx-warn{display:flex; gap:var(--space-3); align-items:flex-start;
  padding:var(--space-4); margin-bottom:var(--space-8);
  background:var(--ms-bg); color:var(--ms-fg);
  border:1px solid var(--border-subtle); border-radius:var(--radius-sm)}
.qx-warn .ico{flex:none; width:18px; height:18px}

.qx-src{margin-top:var(--space-6); padding-top:var(--space-4);
  border-top:1px solid var(--color-hairline)}
.qx-src>.eyebrow{margin-right:var(--space-2)}
.qx-shots{display:flex; flex-wrap:wrap; gap:var(--space-2); margin-top:var(--space-3)}
.qx-shot{display:inline-flex; align-items:center; gap:.375rem;
  padding:.25rem .5rem; border:1px solid var(--border-subtle);
  border-radius:var(--radius-sm); background:var(--surface-raised);
  color:var(--text-secondary); text-decoration:none; font-size:var(--text-eyebrow)}
@media (hover:hover){.qx-shot:hover{border-color:var(--accent-quiet); color:var(--text-primary)}}
.qx-shot .ico{width:14px; height:14px}

/* ── Geschäftstags-Schalter ─────────────────────────────────────────────
   Eine Zeile, kein Kachelstreifen.

   Der erste Entwurf war ein Streifen aus Kacheln, einer je Tag. Er nahm ein
   Drittel des Schirms, war halb leer, hatte Löcher an den Tagen ohne Lieferung
   — und er stand in einem <nav>, wodurch er die Regeln der Seitenleiste erbte
   und marineblau wurde. Drei Fehler auf einmal, und der teuerste war der
   konzeptionelle: eine Information, die in eine Zeile passt, bekam eine Fläche.

   Jetzt trägt der Schalter genau das, wofür er da ist. Der Tag ausgeschrieben,
   weil jede Zahl auf der Seite zu ihm gehört und eine verwechselte Ziffer eine
   falsche Belegung bedeutet. Sein Zustand daneben. Zwei Pfeile für den
   Normalfall, «Heute» für zurück, und die Tage mit Daten in einer Klappliste
   hinter dem Datum für den seltenen Sprung. */
.dsw{display:flex; align-items:center; gap:var(--space-2); flex-wrap:wrap;
  padding-bottom:var(--space-3); margin-bottom:var(--space-4);
  border-bottom:1px solid var(--border-subtle)}
.dsw-nav{display:grid; place-items:center; width:30px; height:30px; flex:none;
  background:none; border:1px solid var(--border-subtle); cursor:pointer;
  border-radius:var(--radius-sm); color:var(--text-secondary)}
@media (hover:hover){.dsw-nav:hover{color:var(--text-primary); border-color:var(--border-strong);
  background:var(--surface-raised)}}
.dsw-nav .ico{width:15px; height:15px}

.dsw-mid{position:relative}
.dsw-date{display:flex; align-items:center; gap:var(--space-2); background:none;
  border:0; cursor:pointer; font:inherit; color:var(--text-primary);
  padding:var(--space-1) var(--space-2); border-radius:var(--radius-sm)}
@media (hover:hover){.dsw-date:hover{background:var(--surface-raised)}}
.dsw-txt{display:flex; flex-direction:column; align-items:flex-start; gap:1px;
  line-height:1.2; min-width:0}
.dsw-k{font-size:var(--text-eyebrow); letter-spacing:.09em; text-transform:uppercase;
  color:var(--text-tertiary); white-space:nowrap}
.dsw-d{font-size:var(--text-body-lg); font-weight:var(--weight-medium); white-space:nowrap}
.dsw-caret{width:13px; height:13px; flex:none; align-self:center;
  stroke:var(--text-tertiary); transform:rotate(90deg)}

.dsw-pop{position:absolute; top:calc(100% + 6px); left:0; z-index:6; min-width:270px;
  background:var(--surface-raised); border:1px solid var(--border-subtle);
  border-radius:var(--radius-sm); padding:var(--space-1);
  max-height:320px; overflow:auto}
.dsw-row{display:flex; align-items:center; justify-content:space-between;
  gap:var(--space-4); width:100%; background:none; border:0; cursor:pointer;
  font:inherit; text-align:left; color:var(--text-secondary);
  font-variant-numeric:tabular-nums;
  padding:var(--space-2) var(--space-3); border-radius:var(--radius-sm)}
@media (hover:hover){.dsw-row:hover{background:var(--surface-sunken); color:var(--text-primary)}}
.dsw-row.on{color:var(--text-primary); box-shadow:inset 2px 0 0 var(--accent-quiet)}

.dsw-today{flex:none; margin-left:auto; background:none; cursor:pointer; font:inherit;
  font-size:var(--text-eyebrow); letter-spacing:.09em; text-transform:uppercase;
  color:var(--text-secondary); border:1px solid var(--border-subtle);
  border-radius:var(--radius-pill); padding:.3rem .7rem}
@media (hover:hover){.dsw-today:hover{color:var(--text-primary); border-color:var(--border-strong)}}
.dsw button:focus-visible{outline:2px solid var(--border-focus); outline-offset:2px}

/* ── Morning Meeting ────────────────────────────────────────────────────
   Zwei Spalten: links der Bereich, genau wie er im Dashboard steht, rechts die
   Notiz und die Navigation.

   Rechts, weil die Kopfleiste durchscheinend ist und stehen bleibt — ein
   Textfeld, das darunter durchscrollt, kollidiert optisch mit der Unschärfe.
   Rechts steht es still. Und weil «Weiter» in einer Sitzung im Minutentakt
   gedrückt wird: am Seitenende wäre es hinter jedem langen Bereich versteckt. */
.mtg{display:grid; grid-template-columns:minmax(0,1fr) 320px;
  gap:var(--space-8); align-items:start}
.mtg-main{min-width:0}
.mtg-main .crumb{margin-bottom:var(--space-1)}
.mtg-main h2{display:flex; align-items:center; gap:var(--space-3);
  font-size:1.5rem; margin-bottom:var(--space-4)}
.mtg-ico{width:20px; height:20px; flex:none; stroke:var(--accent-quiet)}

/* Kompakter als im Dashboard: hier zählt, wie viel auf einen Schirm passt. */
.mtg-main .grid{gap:var(--space-3); margin-bottom:var(--space-6)}
.mtg-main .tile{padding:var(--space-3)}
.mtg-main .lede{margin-bottom:var(--space-4)}
.mtg-main .sub-h{margin-top:var(--space-6)}
.mtg-main .vip,.mtg-main .arr,.mtg-main .gof{margin-bottom:var(--space-3)}

.mtg-side{position:sticky; top:var(--space-2); display:flex; flex-direction:column;
  gap:var(--space-4)}
.mtg-note label{display:flex; align-items:center; gap:var(--space-2);
  margin-bottom:var(--space-2); color:var(--text-tertiary);
  font-size:var(--text-eyebrow); letter-spacing:.09em; text-transform:uppercase}
.mtg-note label .ico{stroke:var(--accent-quiet); width:15px; height:15px}
.mtg-note textarea{
  width:100%; padding:var(--space-3); font-family:inherit; font-size:var(--text-body);
  line-height:var(--leading-relaxed); color:var(--text-primary);
  background:var(--surface-raised); border:1px solid var(--border-subtle);
  border-radius:var(--radius-sm); resize:vertical;
}
.mtg-note textarea:focus{outline:2px solid var(--border-focus); outline-offset:-1px;
  border-color:transparent}

.mtg-move{display:grid; grid-template-columns:1fr 1fr; gap:var(--space-2)}
.mtg-move .btn{min-width:0; justify-content:center}
.mtg-move .btn .ico{margin:0 0 0 var(--space-2)}
.mtg-move #wizback .ico{margin:0 var(--space-2) 0 0}

.mtg-dots{display:flex; flex-wrap:wrap; gap:5px}
.mtg-dots button{width:9px; height:9px; padding:0; border:0; cursor:pointer;
  border-radius:var(--radius-pill); background:var(--border-subtle)}
.mtg-dots button.has{background:var(--accent-quiet); opacity:.55}
.mtg-dots button.on{background:var(--accent-quiet); opacity:1; transform:scale(1.3)}
.mtg-dots button:focus-visible{outline:2px solid var(--border-focus); outline-offset:2px}

@media(max-width:1000px){
  .mtg{grid-template-columns:1fr}
  .mtg-side{position:static; order:-1}
}

/* ── Qualtrics mirror ───────────────────────────────────────────────────────
   BOUNDED EXCEPTION, deliberate. These are not house tokens and must never be
   used outside the Gästezufriedenheit gauges. The section reproduces LHW's
   Qualtrics dashboard so the ExCom recognises it instantly, and it links to the
   original screenshot beside it. The house tones (#466C3D sage, #79572A amber)
   are built dark for text on a tint and read as earth tones at ring weight —
   they cannot carry that recognition. Recolouring another system's numbers into
   house pigment would also imply we own figures that are LHW's.
   Promote to tokens.json only if this mirroring becomes a pattern; otherwise
   it stays here, named and confined.
   The ring is a MARK, not text — AA applies to the figure inside it, which is
   ink on creme. The red band was never observed in the source decks and is
   inferred for completeness. */
:root{
  --qx-good:#77B843; --qx-warn:#FFCC00; --qx-bad:#D5573F;
  --qx-track:var(--color-hairline);
  --qx-bar:var(--data-ramp-1);
}
:root[data-mode="night"]{ --qx-track:rgb(255 255 255 / .16); --qx-bar:var(--data-ramp-4) }

.qx-cards{display:grid; grid-template-columns:repeat(auto-fit,minmax(232px,1fr));
  gap:var(--space-4); margin-bottom:var(--space-4)}
.qx-card{background:var(--surface-raised); border:1px solid var(--border-subtle);
  border-radius:var(--radius-sm); padding:var(--space-4)}
.qx-card-h{display:flex; align-items:center; gap:var(--space-2); margin-bottom:var(--space-2)}
.qx-card-h b{font-weight:var(--weight-medium); font-size:var(--text-body)}
.qx-chip{padding:.0625rem .375rem; border-radius:var(--radius-sm);
  background:var(--surface-sunken); color:var(--text-secondary);
  font-size:var(--text-eyebrow); font-variant-numeric:tabular-nums}
.qx-i{margin-left:auto; color:var(--text-tertiary); display:inline-flex}
@media (hover:hover){.qx-i:hover{color:var(--accent-quiet)}}
.qx-i .ico{width:15px; height:15px}

.qx-g{display:block; width:100%; height:auto; max-width:200px; margin:0 auto}
.qx-g .trk{fill:none; stroke:var(--qx-track); stroke-linecap:butt}
.qx-g .fil{fill:none; stroke-linecap:butt}
.qx-g .fil.good{stroke:var(--qx-good)} .qx-g .fil.warn{stroke:var(--qx-warn)}
.qx-g .fil.bad{stroke:var(--qx-bad)}   .qx-g .fil.na{stroke:var(--qx-track)}
.qx-g .tick{stroke:var(--surface-raised); stroke-width:2}
.qx-g .val{font-family:var(--font-display); font-weight:var(--weight-light);
  fill:var(--text-primary); font-size:35px; text-anchor:middle;
  font-variant-numeric:tabular-nums}
.qx-g .cap{fill:var(--text-secondary); font-size:10.5px; font-weight:var(--weight-semibold);
  text-anchor:middle}
.qx-g .sc{fill:var(--text-tertiary); font-size:9.5px; text-anchor:middle;
  font-variant-numeric:tabular-nums}

.qx-b{display:block; width:100%; height:auto}
.qx-b .grid-l{stroke:var(--color-hairline); stroke-width:1}
.qx-b .ax{fill:var(--text-tertiary); font-size:9.5px; font-variant-numeric:tabular-nums}
.qx-b .bar{fill:var(--qx-bar)}
.qx-b .bar.good{fill:var(--qx-good)} .qx-b .bar.warn{fill:var(--qx-warn)}
.qx-b .bar.bad{fill:var(--qx-bad)}
.qx-b .lbl{fill:var(--text-secondary); font-size:10px; text-anchor:middle}
.qx-b .vl{fill:var(--text-primary); font-size:10px; text-anchor:middle;
  font-variant-numeric:tabular-nums}

.qx-goal{display:flex; align-items:center; gap:var(--space-2); margin-top:var(--space-3);
  padding-top:var(--space-3); border-top:1px solid var(--color-hairline)}
.qx-sect{margin:var(--space-8) 0 var(--space-3)}
.qx-dot{display:inline-block; width:7px; height:7px; border-radius:50%;
  margin-right:.375rem; vertical-align:1px}
.qx-dot.good{background:var(--qx-good)} .qx-dot.warn{background:var(--qx-warn)}
.qx-dot.bad{background:var(--qx-bad)}   .qx-dot.na{background:var(--qx-track)}

/* ── Übersicht ──────────────────────────────────────────────────────────────
   Exceptions first. The attention list is the only thing on the page allowed
   to carry a colour edge, because it is the only thing that means "act". The
   cards below are neutral surfaces with coloured chips inside — colour marks a
   value, never a whole card. No shadows: depth is surface plus hairline. */
.ov-att{list-style:none; margin:0 0 var(--space-8); padding:0;
  background:var(--surface-raised); border:1px solid var(--border-subtle);
  border-radius:var(--radius-sm); overflow:hidden}
.ov-att-h{display:flex; align-items:center; gap:var(--space-2);
  padding:var(--space-3) var(--space-4); background:var(--surface-sunken);
  border-bottom:1px solid var(--border-subtle)}
.ov-n{margin-left:auto; min-width:1.375rem; text-align:center;
  padding:.0625rem .375rem; border-radius:var(--radius-sm);
  background:var(--pd-bg); color:var(--pd-fg);
  font-size:var(--text-eyebrow); font-variant-numeric:tabular-nums}
.ov-n-ok{background:var(--ok-bg); color:var(--ok-fg)}
.ov-a{display:flex; align-items:center; gap:var(--space-3);
  padding:var(--space-3) var(--space-4); border-bottom:1px solid var(--color-hairline);
  border-left:3px solid transparent}
.ov-a:last-child{border-bottom:0}
.ov-a>span{flex:1; min-width:0}
.ov-a .ico{flex:none; width:16px; height:16px; color:var(--text-secondary)}
.ov-a-ms{border-left-color:var(--accent-clay-tone);  background:var(--ms-bg); color:var(--ms-fg)}
.ov-a-pd{border-left-color:var(--accent-amber-tone); background:var(--pd-bg); color:var(--pd-fg)}
.ov-a-lk{border-left-color:var(--accent-lake-tone);  background:var(--lk-bg); color:var(--lk-fg)}
.ov-a-up{border-left-color:var(--accent-sage-tone);  background:var(--ok-bg); color:var(--ok-fg)}
.ov-a-ms .ico,.ov-a-pd .ico,.ov-a-lk .ico,.ov-a-up .ico{color:currentColor}
.ov-a[data-go]{cursor:pointer}
@media (hover:hover){.ov-a[data-go]:hover,.ov-a[data-go]:focus-visible{filter:brightness(.97); outline:none}}
.ov-ch{margin-left:auto; flex:none; width:15px; height:15px; opacity:.55}

.ov-sect{display:block; margin:0 0 var(--space-3)}
.ov-s .v{margin-bottom:var(--space-2)}
.ov-bar{height:4px; background:var(--surface-sunken); border-radius:var(--radius-pill);
  overflow:hidden; margin:0 0 var(--space-2)}
.ov-bar>i{display:block; height:100%; background:var(--accent-quiet)}  /* taupe as a mark */

.ov-cards{display:grid; grid-template-columns:repeat(auto-fit,minmax(290px,1fr));
  gap:var(--space-4); margin-bottom:var(--space-8)}
.ov-c{padding:var(--space-4)}
.ov-c[data-go]{cursor:pointer}
@media (hover:hover){.ov-c[data-go]:hover,.ov-c[data-go]:focus-visible{border-color:var(--accent-quiet); outline:none}}
.ov-c-h{display:flex; align-items:center; gap:var(--space-2); margin-bottom:var(--space-3)}
.ov-c-h b{font-weight:var(--weight-medium)}
.ov-c-h .ico,.ov-c-h .ico-f{flex:none; width:16px; height:16px; color:var(--text-secondary)}
.ov-big{font-family:var(--font-sans); font-size:var(--text-body-lg);
  font-weight:var(--weight-medium); font-variant-numeric:tabular-nums;
  margin-bottom:var(--space-3)}
.ov-big span{font-size:var(--text-eyebrow); font-weight:var(--weight-regular);
  color:var(--text-secondary); margin:0 var(--space-3) 0 .1875rem;
  letter-spacing:.09em; text-transform:uppercase}
.ov-l{display:flex; align-items:baseline; gap:var(--space-3);
  margin-bottom:var(--space-2); flex-wrap:wrap}
/* Fixed label gutter so the chip columns align down the card. It wraps rather
   than squeezing the chips when the card gets narrow. */
.ov-l>.eyebrow{flex:none; width:7rem; color:var(--text-tertiary)}
@media (max-width:520px){ .ov-l>.eyebrow{width:auto} }
.ov-chips{display:flex; flex-wrap:wrap; gap:.3125rem}
.ov-chip{padding:.0625rem .4375rem; border-radius:var(--radius-sm);
  background:var(--surface-sunken); color:var(--text-secondary);
  font-size:var(--text-eyebrow); font-variant-numeric:tabular-nums}
.ov-chip b{color:var(--text-primary); font-weight:var(--weight-semibold)}
.ov-chip-up{background:var(--ok-bg); color:var(--ok-fg)} .ov-chip-up b{color:inherit}
.ov-chip-pd{background:var(--pd-bg); color:var(--pd-fg)} .ov-chip-pd b{color:inherit}
.ov-chip-lk{background:var(--lk-bg); color:var(--lk-fg)} .ov-chip-lk b{color:inherit}
.ov-c-s .ov-ev{margin-bottom:var(--space-2)}
.ov-ev b{font-weight:var(--weight-medium)} .ov-ev span{margin-left:var(--space-2)}

/* ── Top-VIP quick list ─────────────────────────────────────────────────────
   The tier pill uses the ORDINAL data ramp, which is what that ramp is for:
   VIP 1 is not "good", it is first. A status colour here would claim a health
   meaning the number does not carry. VIP 6 / LONG are categories rather than
   ranks and take the quiet neutral. */
.tv{list-style:none; margin:0 0 var(--space-8); padding:0;
  background:var(--surface-raised); border:1px solid var(--border-subtle);
  border-radius:var(--radius-sm); overflow:hidden}
.tv[data-go]{cursor:pointer}
@media (hover:hover){.tv[data-go]:hover,.tv[data-go]:focus-visible{border-color:var(--accent-quiet); outline:none}}
.tv-l{list-style:none; margin:0; padding:0}
.tv-r{display:flex; align-items:center; gap:var(--space-3);
  padding:.5rem var(--space-4); border-bottom:1px solid var(--color-hairline)}
.tv-r:last-of-type{border-bottom:0}

/* Hero row for the highest tier. The portrait is the point: the ExCom
   recognises a face faster than a name, and the VIP sheet exists so nobody is
   greeted as a stranger. Photos come out of the workbook and are auth-gated, so
   loadPhotos() swaps them in as blob URLs; absent ones fall back to a monogram
   rather than a broken frame. */
.tv-hero{display:flex; gap:var(--space-4); padding:var(--space-4);
  border-bottom:1px solid var(--border-subtle); background:var(--surface-sunken)}
.tv-hb{flex:1; min-width:0}
.tv-h1{display:flex; align-items:center; gap:var(--space-2); flex-wrap:wrap;
  margin-bottom:var(--space-2)}
.tv-h1 b{font-size:var(--text-body-lg); font-weight:var(--weight-medium)}
.tv-h2{display:flex; flex-wrap:wrap; gap:var(--space-1) var(--space-4);
  color:var(--text-secondary); font-size:var(--text-eyebrow);
  font-variant-numeric:tabular-nums}
.tv-h2>span>i{margin-left:.3125rem; font-style:normal; color:var(--text-tertiary)}
.tv-bg{margin:var(--space-3) 0 0; color:var(--text-secondary);
  max-width:var(--layout-measure); font-size:var(--text-body)}

.tv-av{flex:none; display:block; border-radius:var(--radius-sm);
  object-fit:cover; object-position:center top; background:var(--color-warm-grey)}
.tv-av-lg{width:84px; height:96px}
.tv-av-sm{width:30px; height:34px}
.tv-av-m{display:flex; align-items:center; justify-content:center;
  color:var(--text-secondary); font-weight:var(--weight-semibold);
  letter-spacing:.02em; background:var(--color-warm-grey)}
.tv-av-m.tv-av-lg{font-size:var(--text-body-lg)}
.tv-av-m.tv-av-sm{font-size:var(--text-eyebrow)}
.vip-photo-none.tv-av-lg,.vip-photo-none.tv-av-sm{background:var(--color-warm-grey)}
.tv-t{flex:none; min-width:3.5rem; text-align:center; padding:.0625rem .375rem;
  border-radius:var(--radius-sm); font-size:var(--text-eyebrow);
  font-weight:var(--weight-semibold); color:var(--color-creme)}
.tv-t1{background:var(--data-ramp-1)} .tv-t2{background:var(--data-ramp-2)}
.tv-t3{background:var(--data-ramp-3)} .tv-t4{background:var(--data-ramp-4)}
.tv-t0{background:var(--surface-sunken); color:var(--text-secondary)}
.tv-n{flex:1 1 auto; min-width:0; font-weight:var(--weight-medium);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.tv-m{flex:none; color:var(--text-secondary); font-size:var(--text-eyebrow);
  font-variant-numeric:tabular-nums}
.tv-m>i{margin-left:.3125rem; font-style:normal; color:var(--text-tertiary)}
.tv-w{flex:none; min-width:7.5rem; text-align:center}
.tv-rate{min-width:5.5rem; text-align:right}
.tv-f{display:flex; align-items:center; gap:var(--space-2);
  padding:.4375rem var(--space-4); background:var(--surface-sunken);
  border-top:1px solid var(--border-subtle)}
@media (max-width:760px){
  .tv-r{flex-wrap:wrap} .tv-n{flex:1 1 100%; order:-1} .tv-rate{text-align:left}
  .tv-hero{flex-direction:column} .tv-av-lg{width:72px; height:82px}
}

/* ── Umsatz ─────────────────────────────────────────────────────────────
   Beträge rechtsbündig mit Tabellenziffern, damit Grössenordnungen in der
   Spalte übereinanderliegen. Die Abweichung trägt den Prozentwert als Chip und
   den Frankenbetrag leise daneben: der Prozentwert sagt, ob es viel ist, der
   Franken sagt, wie viel. */
td.rev-n, th.rev-n{text-align:right; font-variant-numeric:tabular-nums;
  white-space:nowrap}
.rev-abs{margin-left:var(--space-2); font-variant-numeric:tabular-nums;
  font-size:var(--text-eyebrow); color:var(--text-tertiary)}
/* CHF steht als leise Einheit vor der Zahl, nicht in der Beschriftung: so liest
   man «CHF 499'640» in einem Zug und die Zahl behält ihr Gewicht. */
.unit{font-family:var(--font-sans); font-size:var(--text-eyebrow);
  letter-spacing:.09em; color:var(--text-tertiary); margin-right:.4em;
  vertical-align:.35em}

/* Etwas breitere Kacheln, und die Unterzeile bricht ausgewogen statt ein
   einzelnes «12 %» auf die zweite Zeile zu setzen. */
.rev-kpi{grid-template-columns:repeat(auto-fit,minmax(248px,1fr))}
.rev-kpi .tile .d{font-size:var(--text-eyebrow); line-height:var(--leading-snug);
  text-wrap:balance}

/* Ziele, keine Ist-Zahlen — deshalb eine eigene Bank statt weiterer Kacheln,
   direkt unter den vier Kennzahlen. Die Resttage stehen einmal im Kopf statt
   zweimal unter den Beträgen.

   Bewusst in der Grotesk gesetzt: die Serife ist im System auf vier Verwendungen
   je Bildschirm begrenzt, und die vergibt schon die Überschrift mit den vier
   Kacheln. */
.rev-need{border:1px solid var(--border-subtle); border-radius:var(--radius-sm);
  background:var(--surface-sunken); padding:var(--space-4);
  margin-bottom:var(--space-8)}
.rev-need-h{display:flex; align-items:baseline; gap:var(--space-3);
  flex-wrap:wrap; margin-bottom:var(--space-3)}
.rev-need-h .q{color:var(--text-tertiary); font-size:var(--text-eyebrow)}
.rev-need-b{display:grid; gap:var(--space-4);
  grid-template-columns:repeat(auto-fit,minmax(210px,1fr))}
.rev-need-i{display:flex; flex-direction:column; gap:3px}
.rev-need-i .eyebrow{color:var(--text-tertiary)}
.rev-need-i b{font-weight:var(--weight-semibold); font-size:1.5rem;
  line-height:var(--leading-tight); font-variant-numeric:tabular-nums}
.rev-need-i b .unit{vertical-align:.2em}

/* ── GOF: zweite Filterachse nach VIP-Stufe ─────────────────────────────
   Zwei Reihen mit einer leisen Beschriftung davor. Ohne die Beschriftung
   lesen sich zwei Pillenreihen als eine einzige, und man sucht «F&B» neben
   «VIP 3». */
.gof-filter{align-items:center}
.gof-filter-l{flex:none; padding:0 var(--space-2) 0 var(--space-3);
  color:var(--text-tertiary)}
/* Steht eine VIP-Reihe darunter, rücken die beiden zusammen. */
.gof-filter:has(+ .gof-filter-vip){margin-bottom:var(--space-2)}
.gof-vip .ico-f{width:12px; height:12px; margin-right:5px; vertical-align:-2px}

/* ── Umsatz: Bewegung auf einen Blick ───────────────────────────────────
   Die Kachel wird nach dem Vorjahresvergleich getönt, der Pfeil sagt die
   Richtung, die Prozentzahl das Ausmass. Verglichen wird der **Monat**, nicht
   der Tag: die Tagesspalte «LY» im Bericht ist der Monatswert geteilt durch die
   Anzahl Tage, ein Tagesvergleich dagegen misst den Wochentag. Deshalb steht
   «Monat ggü. Vorjahr» ausgeschrieben auf jeder Kachel.

   Grün, Orange und Rot sagen hier die Richtung. Navy bleibt unangetastet — es
   bezeichnet im System die Vorjahresserie im Diagramm, nicht ihre Bewertung. */
.rev-t{background-repeat:no-repeat}
.rev-t-up{background-image:linear-gradient(var(--wash-up),var(--wash-up));
  border-color:color-mix(in srgb, var(--accent-sage-tone) 26%, var(--border-subtle))}
.rev-t-flat{background-image:linear-gradient(var(--wash-flat),var(--wash-flat));
  border-color:color-mix(in srgb, var(--accent-amber-tone) 26%, var(--border-subtle))}
.rev-t-down{background-image:linear-gradient(var(--wash-down),var(--wash-down));
  border-color:color-mix(in srgb, var(--accent-clay-tone) 26%, var(--border-subtle))}

.rev-yoy{display:flex; align-items:center; gap:.35rem; flex-wrap:wrap;
  margin-top:var(--space-3); padding-top:var(--space-2);
  border-top:1px solid var(--border-subtle);
  font-weight:var(--weight-semibold); font-variant-numeric:tabular-nums}
.rev-yoy .ico{width:15px; height:15px; flex:none; stroke-width:2.25}
.rev-yoy .q{font-weight:var(--weight-regular); font-size:var(--text-eyebrow);
  letter-spacing:.06em; text-transform:uppercase; color:var(--text-tertiary)}
.rev-t-up   .rev-yoy{color:var(--ok-fg)}
.rev-t-flat .rev-yoy{color:var(--pd-fg)}
.rev-t-down .rev-yoy{color:var(--ms-fg)}
.rev-t-up   .rev-yoy .ico{stroke:var(--ok-fg)}
.rev-t-flat .rev-yoy .ico{stroke:var(--pd-fg)}
.rev-t-down .rev-yoy .ico{stroke:var(--ms-fg)}

/* ── Belegung je Haus auf der Übersicht ─────────────────────────────────
   Kleine Kästen statt einer grossen Zahl: die Gesamtbelegung sagt nichts über
   ein Haus, das voll ist, während ein anderes leer steht. Am 19.08. steht das
   Waldhotel auf 94 % und die Taverne auf 50 % — der Mittelwert 80 % zeigt
   keines von beidem. Der Resortwert bleibt als Zeile darüber stehen, weil die
   Finanzsicht ihn braucht, aber er beansprucht keine Kachel mehr. */
.occ-row{margin-bottom:var(--space-6)}
.occ-h{display:flex; align-items:baseline; gap:var(--space-3); flex-wrap:wrap;
  margin-bottom:var(--space-3)}
.occ-h .q{color:var(--text-tertiary); font-size:var(--text-eyebrow);
  letter-spacing:.09em; text-transform:uppercase}
.occ-b{display:grid; gap:var(--space-3);
  grid-template-columns:repeat(auto-fit,minmax(170px,1fr))}

.occ{border:1px solid var(--border-subtle); border-radius:var(--radius-sm);
  background:var(--surface-raised); background-repeat:no-repeat;
  padding:var(--space-3) var(--space-4)}
.occ .eyebrow{color:var(--text-tertiary)}
.occ-v{font-family:var(--font-display); font-weight:var(--weight-regular);
  font-size:1.75rem; line-height:var(--leading-tight);
  font-variant-numeric:tabular-nums; margin:var(--space-2) 0 2px}
.occ-m{font-size:var(--text-body); color:var(--text-secondary);
  font-variant-numeric:tabular-nums}
.occ-d{display:flex; align-items:center; gap:.3rem; flex-wrap:wrap;
  margin-top:var(--space-2); padding-top:var(--space-2);
  border-top:1px solid var(--border-subtle);
  font-weight:var(--weight-semibold); font-variant-numeric:tabular-nums;
  font-size:var(--text-body)}
.occ-d .ico{width:14px; height:14px; flex:none; stroke-width:2.25}
.occ-d .q{font-weight:var(--weight-regular); font-size:var(--text-eyebrow);
  letter-spacing:.06em; text-transform:uppercase; color:var(--text-tertiary)}

/* Die Karte wird NICHT mehr flächig getönt.

   Drei getönte Flächen nebeneinander konkurrierten miteinander, und keine
   gewann: man sah drei farbige Kästen und musste die Namen lesen, um die
   Häuser auseinanderzuhalten. Jetzt trägt das Bild die Wiedererkennung und die
   Farbe nur noch die Richtung — am Pfeil und an der Zahl daneben, wo sie eine
   Aussage macht statt einen Hintergrund.

   Der Rahmen behält seinen leisen Farbstich. Er ist eine Haarlinie, kein
   Feld, und ordnet die Karte auf einen Blick ein, ohne mit dem Bild zu
   streiten. */
.occ-up  {border-color:color-mix(in srgb, var(--accent-sage-tone) 26%, var(--border-subtle))}
.occ-flat{border-color:color-mix(in srgb, var(--accent-amber-tone) 26%, var(--border-subtle))}
.occ-down{border-color:color-mix(in srgb, var(--accent-clay-tone) 26%, var(--border-subtle))}
.occ-up   .occ-d{color:var(--ok-fg)}
.occ-flat .occ-d{color:var(--pd-fg)}
.occ-down .occ-d{color:var(--ms-fg)}
.occ-up   .occ-d .ico{stroke:var(--ok-fg)}
.occ-flat .occ-d .ico{stroke:var(--pd-fg)}
.occ-down .occ-d .ico{stroke:var(--ms-fg)}

/* ── Auslastung als Balken (House Status) ───────────────────────────────
   Spur zeigt die Kapazität, Füllung den Anteil. Der Wert steht direkt neben
   dem Balken statt an einer Achse — bei acht Balken liest sich das schneller,
   und die Werte richten sich in einer Spalte aus. */
.occh{margin-bottom:var(--space-8)}
.occh-leg{display:flex; align-items:center; gap:var(--space-4); flex-wrap:wrap;
  margin-bottom:var(--space-4); font-size:var(--text-eyebrow);
  letter-spacing:.09em; text-transform:uppercase; color:var(--text-secondary)}
.occh-leg span{display:flex; align-items:center; gap:var(--space-2)}
.occh-leg .q{color:var(--text-tertiary); letter-spacing:.06em}
.occh-sw{width:12px; height:12px; border-radius:2px; flex:none}

.occh-g{margin-bottom:var(--space-4)}
.occh-g-sum{padding-top:var(--space-4); border-top:1px solid var(--border-subtle)}
.occh-l{display:block; color:var(--text-tertiary); margin-bottom:var(--space-2)}
/* Die Beschriftungsspalte trägt «TOMORROW» — acht Grossbuchstaben mit
   Sperrung. In 64 px passte das nicht und lief über den Balken; im Diagramm
   sah es aus, als begänne die Leiste mitten im Wort.

   Breite als Variable, damit sie an einer Stelle steht statt in drei
   Rasterangaben. Dazu Kürzung als Fangnetz: läuft eine Beschriftung je wieder
   über, wird sie abgeschnitten statt über den Balken gelegt — ein fehlender
   Buchstabe ist harmlos, ein unlesbares Diagramm nicht. */
.occh{--occ-lab:88px; --occ-val:58px}
.occh-b{display:grid; align-items:center; gap:var(--space-3); padding:2px 0;
  grid-template-columns:var(--occ-lab) 1fr var(--occ-val)}
.occh-p{font-size:var(--text-eyebrow); letter-spacing:.09em; text-transform:uppercase;
  color:var(--text-secondary); white-space:nowrap; min-width:0;
  overflow:hidden; text-overflow:ellipsis}
.occh-t{display:block; height:12px; background:var(--surface-sunken);
  border-radius:var(--radius-sm); overflow:hidden}
.occh-f{display:block; height:100%; border-radius:0 4px 4px 0;
  transition:width var(--duration-base) var(--ease-standard)}
.occh-f-1{background:var(--occ-now)}
.occh-f-2{background:var(--occ-next)}
.occh-v{text-align:right; font-variant-numeric:tabular-nums;
  font-size:var(--text-body); font-weight:var(--weight-medium)}

@media(prefers-reduced-motion:reduce){ .occh-f{transition:none} }
@media(max-width:560px){ .occh{--occ-lab:74px; --occ-val:50px} }

/* ── Ausblick auf der Übersicht ─────────────────────────────────────────
   Zwei Blöcke, weil es zwei verschiedene Horizonte sind: der laufende Monat
   mit Umsatz, der nächste nur mit Belegung. Sie nebeneinander zu stellen und
   den Unterschied anzuschreiben ist ehrlicher, als beide gleich aussehen zu
   lassen. */
.fc{display:grid; gap:var(--space-4); margin-bottom:var(--space-6);
  grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
.fc-c{border:1px solid var(--border-subtle); border-radius:var(--radius-sm);
  background:var(--surface-raised); padding:var(--space-4)}
.fc-h{display:flex; align-items:baseline; justify-content:space-between;
  gap:var(--space-3); flex-wrap:wrap; margin-bottom:var(--space-3)}
.fc-h .eyebrow{color:var(--text-tertiary)}
.fc-h .q{color:var(--text-tertiary); font-size:var(--text-eyebrow);
  letter-spacing:.09em; text-transform:uppercase}
.fc-n{font-family:var(--font-display); font-weight:var(--weight-regular);
  font-size:1.75rem; line-height:var(--leading-tight);
  font-variant-numeric:tabular-nums}
.fc-s{color:var(--text-secondary); font-size:var(--text-body);
  font-variant-numeric:tabular-nums; margin-bottom:var(--space-3)}
.fc-f{margin-top:var(--space-2); font-size:var(--text-body);
  color:var(--text-secondary); font-variant-numeric:tabular-nums}
.fc-f b{font-weight:var(--weight-semibold); color:var(--text-primary)}
.fc-occ{display:grid; gap:var(--space-3);
  grid-template-columns:repeat(auto-fit,minmax(96px,1fr))}
.fc-o{display:flex; flex-direction:column; gap:2px}
.fc-o .eyebrow{color:var(--text-tertiary)}
.fc-o b{font-family:var(--font-display); font-weight:var(--weight-regular);
  font-size:1.375rem; line-height:1.1; font-variant-numeric:tabular-nums}

/* ── Touch ──────────────────────────────────────────────────────────────
   A finger is not a pointer. Everything that can be tapped gets at least
   44 px of height, and text inputs get 16 px — below that Safari zooms the
   page on focus and never zooms back, which on the login screen looks like
   the app broke. Scoped to coarse pointers so the desktop stays dense. */
@media (pointer:coarse){
  .pill, .tab, .badge, .act, .linklike,
  .dsw-nav, .dsw-today, .dsw-date, .dsw-row,
  .modesw button, .rest-pill, .fb-t-h{
    min-height:44px;
  }
  .pill, .tab, .badge, .act, .dsw-today, .rest-pill{
    display:inline-flex; align-items:center;
  }
  .dsw-nav{width:44px; height:44px}
  .dsw-row{padding-top:var(--space-3); padding-bottom:var(--space-3)}
  .linklike{padding:var(--space-2) 0}
  .hbtn, .drawer-btn{min-width:44px; min-height:44px}
  /* Seit dem Kopfleisten-Umbau steht Feedback als Knopf in der Schublade, und
     die Ablagefelder haben eigene Knöpfe. Beide fehlten in dieser Liste. */
  .btn, .nav-user .btn, .nav-acts .btn{min-height:44px}
  .mtg-dots button{width:16px; height:16px}
  .mtg-dots{gap:var(--space-2)}
  .ov-a, .ov-c, .care{padding-top:var(--space-4); padding-bottom:var(--space-4)}
  .ddrop{min-height:200px}
  .occh-b{padding:var(--space-2) 0}

  input, select, textarea{font-size:16px}
  .mtg-note textarea, .fb-sheet textarea{font-size:16px}
}

/* ── Phone: give the content the width back ─────────────────────────────
   The grids were sized for a sidebar-less desktop column. On 390 px a
   two-column tile grid leaves 150 px per tile, which is narrower than the
   numbers it has to hold. */
@media(max-width:560px){
  .grid, .rev-kpi{grid-template-columns:1fr}
  .ov-cards{grid-template-columns:1fr}
  .imp-boxes{grid-template-columns:1fr}
  .fc{grid-template-columns:1fr}
  .occ-b{grid-template-columns:1fr 1fr}
  .rev-need-b{grid-template-columns:1fr}
  h2{font-size:1.5rem}
  .tile .v{font-size:2rem}
  .dsw{gap:var(--space-1)}
  .dsw-k{display:none}
  .srcnote{align-items:flex-start}
}

/* ── Why a section is empty ─────────────────────────────────────────────
   One panel, three readings. The one that asks for action carries a button
   and a warmer edge; the two that do not are deliberately quiet — a page that
   nags about something nobody can fix today teaches people to ignore it. */
.miss{border:1px solid var(--border-subtle); border-radius:var(--radius-sm);
  background:var(--surface-raised); padding:var(--space-6);
  max-width:var(--layout-measure)}
.miss-todo{border-left:3px solid var(--accent-amber-tone)}
.miss-wait{border-left:3px solid var(--border-strong); background:var(--surface-sunken)}
.miss-h{display:flex; align-items:center; gap:var(--space-3); margin-bottom:var(--space-3)}
.miss-h b{font-family:var(--font-display); font-weight:var(--weight-regular);
  font-size:1.25rem; line-height:1.2}
.miss-h .ico{width:20px; height:20px; flex:none; stroke:var(--text-tertiary)}
.miss-todo .miss-h .ico{stroke:var(--accent-amber-tone)}
.miss-n{font-size:var(--text-body-lg); font-weight:var(--weight-medium)}
.miss-f{margin-top:var(--space-2); font-size:var(--text-eyebrow);
  letter-spacing:.09em; text-transform:uppercase; color:var(--text-tertiary)}
.miss-w{margin:var(--space-3) 0 0; color:var(--text-secondary);
  font-size:var(--text-body); line-height:var(--leading-relaxed)}
.miss .btn{margin-top:var(--space-4)}
.miss .btn .ico{margin:0 0 0 var(--space-2)}

/* ── Weather in hindsight ───────────────────────────────────────────────
   No symbol, no radar, no curve. A record of what happened has a different
   shape from a forecast on purpose — if it looked the same, nobody would
   notice they are reading the past. */
.wxback{border:1px solid var(--border-subtle); border-radius:var(--radius-sm);
  background:var(--surface-raised); padding:var(--space-8) var(--space-6);
  max-width:var(--layout-measure)}
.wxback .eyebrow{color:var(--text-tertiary)}
.wxback-t{font-family:var(--font-display); font-weight:var(--weight-regular);
  font-size:clamp(2.2rem,7vw,3rem); line-height:1.05;
  font-variant-numeric:tabular-nums; margin:var(--space-3) 0 var(--space-2);
  display:flex; align-items:baseline; gap:var(--space-3); flex-wrap:wrap}
.wxback-t span{font-family:var(--font-sans); font-size:var(--text-body);
  color:var(--text-tertiary)}
.wxback-c{font-size:var(--text-body-lg); color:var(--text-secondary)}
.wxback-ly{margin-top:var(--space-4); padding-top:var(--space-3);
  border-top:1px solid var(--border-subtle);
  font-size:var(--text-body); color:var(--text-tertiary)}
.wxmini-past{font-size:var(--text-eyebrow); letter-spacing:.09em;
  text-transform:uppercase; color:var(--text-tertiary); margin-right:var(--space-2)}


/* ── Der Tagesschalter in der Kopfleiste ────────────────────────────────
   Er betrifft jede Zahl auf jeder Seite, gehört also nicht zum Inhalt eines
   Bereichs. Unten in der Seite sprang er bei jedem Wechsel neu ins Bild und
   schob den Titel; oben steht er still, und die Kopfleiste hatte den Platz.
   Unter 900 px übernimmt wieder die Fassung in der Seite. */
.dayslot{flex:none; display:flex; align-items:center; min-width:0}
.dayslot .dsw{padding:0; margin:0; border-bottom:0; flex-wrap:nowrap;
  gap:var(--space-1)}
.dayslot .dsw-d{font-size:.9375rem}
.dayslot .dsw-nav{width:28px; height:28px}
.dayslot .dsw-pop{left:auto; right:0}
@media(max-width:900px){ .dayslot{display:none} }
@media(max-width:1280px){ .dayslot .dsw .st{display:none} }

/* ── Ein Tag ohne jede Lieferung ────────────────────────────────────────
   Ganze Breite, weil ein leerer Tag eine Aussage ist und keine Randnotiz. Der
   gestrichelte Rand ist derselbe wie um die Ablagefelder im Import-Center:
   leer heisst überall dasselbe — wartet auf eine Datei. */
.dayempty{display:flex; flex-direction:column; align-items:center;
  text-align:center; gap:var(--space-3);
  padding:clamp(var(--space-8), 9vh, 96px) var(--space-6);
  border:1px dashed var(--border-strong); border-radius:var(--radius-sm);
  background:var(--surface-sunken)}
.dayempty-i{width:34px; height:34px; stroke:var(--text-tertiary); stroke-width:1.25}
.dayempty-k{font-size:var(--text-eyebrow); letter-spacing:.09em;
  text-transform:uppercase; color:var(--text-tertiary)}
.dayempty h3{margin:0; font-family:var(--font-display); font-weight:var(--weight-regular);
  font-size:1.5rem; line-height:1.2}
.dayempty p{margin:0; max-width:46ch; color:var(--text-secondary);
  line-height:var(--leading-relaxed)}
.dayempty-acts{display:flex; flex-wrap:wrap; justify-content:center;
  gap:var(--space-3); margin-top:var(--space-3)}

/* ── Wetter im Voraus ───────────────────────────────────────────────────
   Bewusst dieselbe Bauform wie der Rückblick, mit einem Unterschied: hier
   steht ein Symbol, dort keines. Ein Rückblick soll nicht wie eine Vorhersage
   aussehen — eine Vorhersage darf es. */
.wxfc{border:1px solid var(--border-subtle); border-radius:var(--radius-sm);
  background:var(--surface-raised); padding:var(--space-8) var(--space-6);
  max-width:var(--layout-measure)}
.wxfc .eyebrow{color:var(--text-tertiary)}
.wxfc-i{display:block; margin:var(--space-3) 0 var(--space-1); width:60px; height:60px}
.wxfc-t{font-family:var(--font-display); font-weight:var(--weight-regular);
  font-size:clamp(2.2rem,7vw,3rem); line-height:1.05;
  font-variant-numeric:tabular-nums; margin:0 0 var(--space-2);
  display:flex; align-items:baseline; gap:var(--space-3); flex-wrap:wrap}
.wxfc-t span{font-family:var(--font-sans); font-size:var(--text-body);
  color:var(--text-tertiary)}
.wxfc-p{font-size:var(--text-body-lg); color:var(--text-secondary)}
.wxfc-n{margin:var(--space-4) 0 0; padding-top:var(--space-3);
  border-top:1px solid var(--border-subtle);
  font-size:var(--text-body); color:var(--text-tertiary);
  line-height:var(--leading-relaxed)}

/* Der Vorwärtspfeil am Ende der Vorhersage. Ausgegraut statt entfernt: ein
   verschwundener Knopf lässt den Rückwärtspfeil an eine andere Stelle springen,
   und man tippt beim nächsten Mal daneben. */
.dsw-nav[disabled]{opacity:.32; cursor:default}
@media (hover:hover){.dsw-nav[disabled]:hover{color:var(--text-secondary);
  border-color:var(--border-subtle); background:none}}

/* Was heute niemand liefern kann, steht unten und leiser. */
.imp-later{margin-top:var(--space-8); padding-top:var(--space-4);
  border-top:1px solid var(--border-subtle)}
.imp-later .eyebrow{display:block; margin-bottom:var(--space-4);
  color:var(--text-tertiary)}
.imp-later .ddrop{opacity:.62}
@media (hover:hover){.imp-later .ddrop:hover{opacity:1}}

/* ── Ankunftstag als Zwischenüberschrift ────────────────────────────────
   Das VIP-Blatt führt zwei Tage. Ohne Trennung liest sich das als ein Schwung
   Gäste, und die erste Frage im Meeting ist, wer davon heute kommt. */
.arrday{display:flex; align-items:baseline; gap:var(--space-3); flex-wrap:wrap;
  margin:var(--space-8) 0 var(--space-4); padding-bottom:var(--space-2);
  border-bottom:1px solid var(--border-subtle)}
.arrday:first-child{margin-top:0}
.arrday-k{font-size:var(--text-eyebrow); letter-spacing:.09em; text-transform:uppercase;
  color:var(--text-tertiary)}
.arrday-now .arrday-k{color:var(--accent-sage-tone)}
.arrday-d{font-family:var(--font-display); font-weight:var(--weight-regular);
  font-size:1.125rem; line-height:1.2}
.arrday-n{margin-left:auto; font-size:var(--text-body); color:var(--text-tertiary);
  font-variant-numeric:tabular-nums}

/* ── Abweichung: Betrag vorn, Prozent leiser dahinter ───────────────────
   Für die Finanzseite ist der Franken-Betrag die Aussage und der Prozentsatz
   ihre Einordnung — vorher stand es umgekehrt. Grün nur beim Vorsprung, und
   dann das kräftige Grün des Systems statt der gedeckten Kachelfarbe. */
.rev-var{font-weight:var(--weight-medium); font-variant-numeric:tabular-nums;
  font-size:1.0625rem; white-space:nowrap}
.rev-var-up{color:var(--accent-sage-tone)}
.rev-var-dn{color:var(--text-primary)}
.rev-varp{margin-left:var(--space-2); font-size:var(--text-body);
  color:var(--text-tertiary); font-variant-numeric:tabular-nums; white-space:nowrap}

/* Bis das Porträt geladen ist, hat das <img> noch keine Quelle. Ohne Fläche
   zeichnet der Browser dort sein Bruchsymbol — ein ruhiger Kasten sieht aus
   wie «lädt» und nicht wie «kaputt». */
.vip-photo{background:var(--surface-sunken)}

/* ── Dritter Zellzustand: nicht geliefert ───────────────────────────────
   Grün heisst offen, rot heisst geschlossen — beide sind Aussagen über das
   Restaurant. Eine Periode, die im Blatt gar nicht vorkommt, ist keine von
   beiden. Sie bekommt eine Schraffur statt einer Farbe: sichtbar leer, ohne
   zu behaupten, dass nachts alles zu hat. */
/* Die Schraffur zeichnet eine Linie auf die Seitenfläche, NICHT zwei Flächen
   nebeneinander. Der erste Versuch nahm --surface-sunken gegen
   --surface-raised — beide sind im hellen Modus derselbe Wert (#F1F0EB, siehe
   die Abflachung weiter oben). Die Schraffur war dadurch Weiss auf Weiss und
   die Zelle sah schlicht leer aus. */
.rx-none{background-color:var(--surface-page);
  background-image:repeating-linear-gradient(45deg,
    transparent 0 5px, var(--border-strong) 5px 6px)}
.rx-svc-none{opacity:.55}
:root[data-mode="night"] .rx-none{background-color:var(--surface-page);
  background-image:repeating-linear-gradient(45deg,
    transparent 0 5px, rgb(241 240 235 / .22) 5px 6px)}

/* ── Monatskennzahlen unter der Tabelle ─────────────────────────────────
   RevPAR, ADR und Belegung. Nebeneinander statt als Tabellenzeilen: sie haben
   weder Forecast noch Budget, und leere Spalten sähen aus wie fehlende Daten. */
.rev-rats{display:flex; flex-wrap:wrap; align-items:flex-start;
  gap:var(--space-8); margin-top:var(--space-6); padding-top:var(--space-4);
  border-top:1px solid var(--border-subtle)}
.rev-rat .eyebrow{display:block; color:var(--text-tertiary);
  margin-bottom:var(--space-2)}
.rev-rat-v{font-family:var(--font-display); font-weight:var(--weight-regular);
  font-size:1.75rem; line-height:1; font-variant-numeric:tabular-nums;
  white-space:nowrap}
.rev-rat-v .unit{font-family:var(--font-sans); font-size:var(--text-body);
  color:var(--text-tertiary); margin-right:.35rem}
.rev-rat-d{margin-top:var(--space-2); white-space:nowrap}
.rev-rat-n{flex:1 1 14rem; min-width:0; align-self:flex-end;
  font-size:var(--text-body); line-height:var(--leading-relaxed)}
@media(max-width:640px){ .rev-rats{gap:var(--space-6)} }

/* ── Wo ist noch Platz? ─────────────────────────────────────────────────
   Ein Raster, keine Bänder. Entscheidend ist, dass eine Spalte in JEDER Zeile
   dieselbe Viertelstunde ist — nur dann beantwortet ein Blick nach unten die
   Frage «wer hat um 19:30 noch etwas frei». Vorher hatte jede Zeile ihren
   eigenen Massstab, und genau daran war es unlesbar.

   Grün heisst buchbar, wie an den Pillen darüber. Die Tiefe sagt zusätzlich,
   wie voll es schon ist — eine Farbe, zwei Ablesungen, kein Widerspruch. */
.al-wrap{overflow-x:auto; margin-top:var(--space-4)}
.al-grid{min-width:56rem}
.al-row{display:grid; align-items:center; gap:var(--space-3);
  grid-template-columns:minmax(6.5rem,9rem) minmax(6rem,8rem) 1fr 4.5rem 4.5rem}
.al-axis{font-size:var(--text-eyebrow); letter-spacing:.09em;
  text-transform:uppercase; color:var(--text-tertiary);
  padding-bottom:var(--space-1)}
.al-first{border-top:1px solid var(--border-subtle); margin-top:var(--space-2);
  padding-top:var(--space-2)}
.al-r1{font-weight:var(--weight-medium); line-height:1.2; font-size:var(--text-body)}
.al-r2{font-size:.8125rem; color:var(--text-secondary); line-height:1.2}
.al-r3,.al-r4{text-align:right; font-variant-numeric:tabular-nums;
  white-space:nowrap; font-size:.8125rem}
.al-r3 b{font-weight:var(--weight-medium)}
.al-over{color:var(--accent-clay-tone)}
.al-none{color:var(--accent-clay-tone)}

/* Das Raster selbst. Feste Spaltenzahl, damit alle Zeilen fluchten. */
/* --c setzt der Renderer inline auf die Spalte der aktuellen Uhrzeit. Der
   Vorgabewert steht hier, damit die Marke ohne Wert links steht statt zu erben. */
.al-g{position:relative; display:grid; gap:1px;
  grid-template-columns:repeat(68, 1fr); height:18px; --c:0}
.al-c{display:block; height:100%; border-radius:1px;
  background:transparent}                       /* geschlossen */
/* Vier Stufen, und die Farbe trägt die Aussage allein — ohne Legende lesbar,
   weil Grün-Orange-Rot im Haus dasselbe heisst wie überall.

   Bewusst die kräftigen Töne und nicht die Tints: die hellen Varianten sind
   für Flächen HINTER Text gedacht. Als 8 Pixel breite Zelle im Raster
   verschwinden sie gegen das Papier, und dann trägt die Farbe nichts mehr.

   «Filling» liegt zwischen Grün und Orange, damit der Sprung von «Platz» zu
   «eng» nicht in einem einzigen Schritt passiert — die Zwischenstufe ist der
   Moment, in dem man anfängt, den Tisch zu reservieren statt zu warten. */
/* Die Stufen werden nach unten DUNKLER, nicht nur andersfarbig.

   Der erste Entwurf nahm sage, amber und clay in ihrer Grundform. Gegen das
   Papier stehen die zwar alle gut (5,3 bis 6,0:1), gegeneinander aber bei
   1,05:1 — gleich hell, nur anders im Ton. Als 8 Pixel breite Zellen
   nebeneinander verschmelzen sie zu einer Masse, und bei Rot-Grün-Schwäche
   bleibt gar kein Unterschied.

   Deshalb eine Helligkeitsrampe, die durchgehend dunkler wird: 54 % → 29 % →
   11 % → 4 %. Die Reihenfolge ist damit auch in Graustufen lesbar, und «voll
   ist am dunkelsten» entspricht der Anschauung.

   Nachgerechnet, inklusive Deuteranopie-Simulation: jede Stufe steht mit
   mindestens 1,66:1 gegen die nächste, unter Rot-Grün-Schwäche mit 1,66:1.
   Eine erste Fassung war hier bei 1,03:1 — «füllt» und «eng» fielen für
   rot-grün-schwache Betrachter zusammen, und das ist genau der Übergang, an
   dem im Meeting die Entscheidung hängt. */
.al-free {background:#B7C6B3}   /* Platz  — helles Grün,  L 54 % */
.al-some {background:#7F9A79}   /* füllt  — sattes Grün,  L 29 % */
.al-tight{background:#79572A}   /* eng    — Amber,        L 11 % */
.al-full {background:#54322C}   /* voll   — dunkles Clay, L  4 % */
.al-lock{background-image:repeating-linear-gradient(45deg,
  transparent 0 2px, var(--border-strong) 2px 3px);
  background-color:var(--surface-sunken)}

/* Die Stundenmarken sitzen im selben Raster wie die Zellen, sonst wandern sie
   gegenüber den Spalten, sobald sich die Breite ändert. */
.al-t{display:block; height:9px; border-left:1px solid transparent; position:relative}
.al-t-h{border-left-color:var(--border-subtle)}
.al-t-h::after{content:attr(data-h); position:absolute; left:2px; top:-1px;
  font-size:.625rem; letter-spacing:0; color:var(--text-tertiary)}

.al-now{position:absolute; top:-2px; bottom:-2px; width:2px;
  left:calc(var(--c) * (100% / 68)); background:var(--accent-clay-tone)}

.al-lg{display:flex; flex-wrap:wrap; gap:var(--space-4);
  margin-top:var(--space-3); font-size:var(--text-body);
  color:var(--text-secondary)}
.al-lg span{display:flex; align-items:center; gap:var(--space-2)}
.al-lg .al-c{width:12px; height:12px; flex:none;
  outline:1px solid var(--border-subtle); outline-offset:-1px}
}

/* Der Frischestempel steht ÜBER dem Raster, nicht als Fussnote darunter — wer
   Zahlen liest, soll vorher wissen, ob sie noch gelten, nicht hinterher. */
.al-stamp{display:flex; align-items:center; gap:var(--space-3); flex-wrap:wrap;
  margin:calc(var(--space-3) * -1) 0 var(--space-3);
  font-size:var(--text-body); color:var(--text-secondary)}
.al-stamp b{font-weight:var(--weight-medium); color:var(--text-primary);
  font-variant-numeric:tabular-nums}

/* Zwei Zahlen, zwei Bedeutungen — die Spitze klein unter der Gästezahl.
   Sie gegeneinander zu teilen war der Fehler: die eine zählt den Abend, die
   andere einen Augenblick. */
.al-r3 .q{display:block; font-size:.75rem; letter-spacing:0}

/* ── Auslastungsraster auf dem Telefon ──────────────────────────────────
   Fünf Spalten nebeneinander gehen auf 375 px nicht auf, und 56 rem
   Zwangsbreite hiesse seitwärts scrollen für eine Information, die man im
   Vorbeigehen liest. Also gestapelt: wer und wann oben, das Band über die
   volle Breite darunter, die Antwort «ab wann frei» als eigene Zeile.

   Das Raster selbst bleibt unangetastet — eine Spalte ist weiterhin überall
   dieselbe Viertelstunde, nur schmaler. Genau das war ja der Punkt. */
@media(max-width:820px){
  .al-wrap{overflow-x:visible}
  .al-grid{min-width:0}
  .al-row{grid-template-columns:1fr auto; gap:2px var(--space-3);
    padding:var(--space-2) 0}
  .al-axis{padding-bottom:0}
  .al-r1{grid-column:1; grid-row:1}
  .al-r1:empty{display:none}            /* Folgezeilen einer Gruppe */
  .al-r2{grid-column:1}
  .al-r3{grid-column:2; grid-row:1 / span 2; align-self:start}
  .al-g{grid-column:1 / -1; height:22px; margin-top:var(--space-1)}
  .al-r4{grid-column:1 / -1; text-align:left; color:var(--text-tertiary)}
  /* Die Beschriftung hängt an der ZEIT, nicht an der Zelle — sonst stünde bei
     einem ausgebuchten Service «free from full». */
  .al-from::before{content:'free from '}
  /* Neun Stundenmarken sind hier zu viel — jede vierte genügt zur Orientierung. */
  .al-t-h:not(.al-t-q)::after{content:none}
  .al-t-h:not(.al-t-q){border-left-color:transparent}
}
@media(max-width:420px){
  .al-lg{gap:var(--space-3); font-size:.8125rem}
  .al-g{height:18px}
}

/* ── Kleinigkeiten fürs Telefon ─────────────────────────────────────────
   Bauteile, die seit dem letzten Mobil-Durchgang dazugekommen sind. */
@media(max-width:820px){
  /* Der Ankunftstag: die Zahl rechts fiel durch margin-left:auto auf eine
     eigene Zeile und stand dort allein. Neben dem Datum ist sie richtig. */
  .arrday{margin-top:var(--space-6); gap:var(--space-2)}
  .arrday-d{font-size:1rem}
  .arrday-n{margin-left:0}
  /* Die Restaurant-Pillen: acht Stück mit Bild sind auf 375 px vier Zeilen.
     Ohne Bild sind es zwei, und der Punkt trägt die Aussage ohnehin. */
  .rp-img{display:none}
  .rp{padding-left:var(--space-3)}
  /* Der Frischestempel steht sonst zu eng am Titel. */
  .al-stamp{margin-top:0}
}
@media(max-width:560px){
  /* Monatskennzahlen untereinander statt in einer Reihe, sonst brechen die
     Zahlen mitten im Betrag um. */
  .rev-rats{gap:var(--space-4)}
  .rev-rat{flex:1 1 100%}
  .rev-rat-n{flex:1 1 100%}
  .dayempty{padding:var(--space-8) var(--space-4)}
}

/* ── Tabellen als Karten, unter 700 px ──────────────────────────────────
   Eine Zeile wird zu einer Karte, eine Zelle zu einer Zeile darin:
   Beschriftung links, Wert rechts. Die Überschrift steht damit IMMER beim
   Wert — beim seitlichen Scrollen war sie längst aus dem Bild.

   `display:block` auf Tabellenelementen nimmt ihnen die Tabellensemantik.
   Für Bildschirmleser bleibt sie erhalten, weil die Rollen ausdrücklich
   wieder gesetzt werden. */
@media(max-width:700px){
  .tscroll{overflow-x:visible}
  table.tcards{display:block; width:100%}
  table.tcards thead{position:absolute; width:1px; height:1px;
    overflow:hidden; clip-path:inset(50%); white-space:nowrap}
  table.tcards tbody{display:block}
  table.tcards tr{display:block; padding:var(--space-3) 0;
    border-bottom:1px solid var(--border-subtle)}
  table.tcards tr:last-child{border-bottom:0}
  table.tcards td{display:flex; align-items:baseline;
    justify-content:space-between; gap:var(--space-4);
    padding:.2rem 0; border:0; text-align:right}
  table.tcards td[data-l]::before{
    content:attr(data-l);
    flex:0 0 auto; text-align:left;
    font-size:var(--text-eyebrow); letter-spacing:.09em;
    text-transform:uppercase; color:var(--text-tertiary);
    white-space:nowrap}
  /* Die erste Spalte ist der Name der Zeile — sie trägt die Karte und
     bekommt deshalb kein Etikett, sondern Gewicht. */
  table.tcards td.tc-lead{display:block; text-align:left;
    font-weight:var(--weight-medium); font-size:var(--text-body-lg);
    padding-bottom:var(--space-2)}
  table.tcards td.tc-lead::before{content:none}
  /* Leere Zellen tragen in einer Karte nichts bei. */
  table.tcards td:empty{display:none}
}

/* ── Öffnungszeiten-Matrix auf dem Telefon ──────────────────────────────
   Sie bleibt als Raster — Spalten sind Restaurants, Zeilen Services, und als
   Karten zerfiele genau der Vergleich, für den sie da ist. Aber 760 px sind
   auf einem 375-px-Schirm zwei volle Wischer.

   Enger gesetzt und kleiner geschrieben passt sie in gut die Hälfte: ein
   Wischer statt zwei. Die Zeiten bleiben lesbar, weil sie Ziffern sind und
   keine Fliesstexte. */
@media(max-width:700px){
  table.rx{min-width:30rem; font-size:.75rem}
  table.rx th, table.rx td{padding:.35rem .3rem}
  table.rx thead th{font-size:.8125rem}
  .rx-svc{font-size:.625rem; letter-spacing:.04em}
  /* Der Hinweis, dass hier gewischt werden kann — sonst sucht man ihn nicht. */
  .rx-wrap{position:relative}
  .rx-wrap::after{content:'swipe →'; position:absolute; top:calc(100% + 4px);
    right:0; font-size:var(--text-eyebrow); letter-spacing:.09em;
    text-transform:uppercase; color:var(--text-tertiary)}
}

/* ── Tagesschalter auf dem Telefon ──────────────────────────────────────
   Eine Zeile, 44 px hoch. Die grosse Fassung brach in drei Zeilen um und
   verbrauchte damit ein Drittel des Schirms, bevor die erste Zahl kam. */
.dswm{display:flex; align-items:center; gap:var(--space-2);
  margin-bottom:var(--space-4); position:relative}
.dswm-nav{display:grid; place-items:center; width:38px; height:38px; flex:none;
  background:none; border:1px solid var(--border-subtle); cursor:pointer;
  border-radius:var(--radius-sm); color:var(--text-secondary)}
.dswm-nav[disabled]{opacity:.32}
.dswm-nav .ico{width:16px; height:16px}
.dswm-d{flex:1 1 auto; min-width:0; display:flex; align-items:center;
  justify-content:center; gap:var(--space-1); background:none; border:0;
  font:inherit; font-size:1rem; font-weight:var(--weight-medium);
  color:var(--text-primary); cursor:pointer; padding:0; white-space:nowrap}
.dswm-d .ico{width:13px; height:13px; stroke:var(--text-tertiary);
  transform:rotate(90deg)}
.dswm .st{flex:none}
.dswm-pop{left:0; right:0; top:calc(100% + 4px); min-width:0}

/* ── Belegung je Haus auf dem Telefon ───────────────────────────────────
   Als Kacheln braucht jedes Haus rund 380 px Höhe — drei Häuser sind damit
   1150 px für drei Prozentzahlen. Auf einem Schirm von 2000 px ist das die
   halbe Seite für die erste Aussage.

   Als Zeilen sind es 66 px je Haus: Name links, Wert und Monat rechts, die
   Vorjahresveränderung darunter. Dieselben vier Angaben, ein Fünftel der
   Höhe — und untereinander lassen sich die Häuser leichter vergleichen als
   in nebeneinanderliegenden Kacheln. */
@media(max-width:640px){
  .occ-b{grid-template-columns:1fr; gap:0}
  .occ{display:grid; grid-template-columns:1fr auto; align-items:baseline;
    gap:2px var(--space-3); padding:var(--space-3) var(--space-4);
    border-radius:0; border-width:0 0 1px 0}
  .occ:first-child{border-top-width:1px}
  .occ > .eyebrow{grid-column:1; grid-row:1; align-self:center}
  .occ-v{grid-column:2; grid-row:1; font-size:1.5rem; text-align:right}
  .occ-m{grid-column:1; grid-row:2}
  .occ-d{grid-column:2; grid-row:2; margin-top:0; padding-top:0;
    border-top:0; justify-content:flex-end}
}

/* ── Die Zwischenstufen zwischen Telefon und breitem Schirm ─────────────
   Bisher gab es nur zwei Zustände: unter 900 px die Schublade, darüber die
   volle Kopfleiste. Dazwischen — Laptop, geteiltes Fenster, Tablet quer —
   drängten sich Wortmarke, Tagesschalter, Wetter, «Morning Meeting» und der
   Modusschalter auf einer Zeile. Die Knöpfe brachen zweizeilig um und der
   letzte wurde abgeschnitten.

   Die Reihenfolge des Abbaus folgt dem Nutzen: zuerst verliert der seltenste
   Knopf seine Beschriftung, zuletzt der Tagesschalter seine Länge. Nichts
   verschwindet ganz, und nichts bricht je um — ein zweizeiliger Knopf in einer
   76-px-Leiste sieht immer nach Fehler aus. */
header .btn, header .modesw button{white-space:nowrap}

/* Die Seitenleiste war fest 340 px — bei 1000 px Fensterbreite ein Drittel
   des Schirms für die Navigation. Jetzt mitwachsend, mit Boden und Deckel. */
@media(min-width:901px){
  .body{grid-template-columns:clamp(14rem, 20vw, 21.25rem) 1fr}
}

@media(max-width:1250px){
  /* «Morning Meeting» startet einen Ablauf, den man einmal am Tag braucht.
     Das Symbol genügt, der Titel steht im Tooltip. */
  #startmeeting .lbl, #wizexit .lbl{
    position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%)}
  #startmeeting, #wizexit{padding-left:.7rem; padding-right:.7rem}
  header{gap:var(--space-4)}
}
@media(max-width:1120px){
  /* Der Modusschalter behält seine zwei Symbole — Mond und Sonne sagen es
     deutlicher als die Wörter. */
  .modesw button .lbl{
    position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%)}
  .modesw button{padding-left:.6rem; padding-right:.6rem}
}
@media(max-width:1010px){
  /* Zuletzt der Tagesschalter: das Datum kurz statt ausgeschrieben. Er ist
     das Letzte, was gekürzt wird, weil er auf jeder Seite gilt. */
  .dayslot .dsw-k{display:none}
  .dayslot .dsw-d{font-size:.875rem}
  header{padding:0 var(--space-4)}
}
.dsw-d-brief{display:none}
@media(max-width:1010px){
  .dayslot .dsw-d-long{display:none}
  .dayslot .dsw-d-brief{display:inline}
}

/* ── Verlauf auf der Belegungskarte ─────────────────────────────────────
   Feiner als zuvor, und mit einer Aussage statt einer Silhouette.

   Die gestrichelte Marke ist der Monatsdurchschnitt. Sie ist der Grund, warum
   der Massstab eng um die Daten liegen darf: ohne beschrifteten Bezug wäre ein
   enger Massstab irreführend, weil jede kleine Schwankung dramatisch aussähe.
   Mit ihm liest man in einer Sekunde, ob die letzten Tage über oder unter dem
   Monat liegen — und das ist die Frage, die eine solche Karte beantworten soll.

   Keine Füllfläche mehr. Sie gab der Linie Gewicht, machte sie aber zugleich
   schwer, und über einem Foto war sie zu viel. Eine dünne Linie auf einem
   ruhigen Grund reicht. */
/* Ohne Kurve keine Lücke: das Feld verschwindet ganz, statt als leerer
   Abstand stehenzubleiben. */
.occ-s:empty{display:none}
.occ-s{margin-top:var(--space-3)}
.spark-w{display:inline-block}
.spark{display:block; width:132px; height:42px; overflow:visible}
.spark-l{fill:none; stroke:var(--data-ramp-1); stroke-width:1.4;
  stroke-linecap:round; stroke-linejoin:round; vector-effect:non-scaling-stroke}
/* Die Bezugsmarke: sichtbar, aber ruhiger als die Linie — sie ist der
   Massstab, nicht die Aussage. */
.spark-ref{stroke:var(--text-tertiary); stroke-width:1; stroke-dasharray:3 3;
  opacity:.75; vector-effect:non-scaling-stroke}
/* Senkrechte je Messtag, sehr fein — sie ordnen nur den Takt. */
.spark-v{stroke:var(--border-subtle); stroke-width:1; opacity:.55;
  vector-effect:non-scaling-stroke}
.spark-n{fill:var(--data-ramp-1); stroke:var(--surface-raised); stroke-width:1.4}

.spark-c{display:flex; align-items:baseline; gap:var(--space-2); flex-wrap:wrap;
  padding-top:var(--space-1); font-size:var(--text-eyebrow); letter-spacing:.06em;
  color:var(--text-tertiary); font-variant-numeric:tabular-nums}
.spark-r{text-transform:uppercase; letter-spacing:.09em}

:root[data-mode="night"] .spark-l{stroke:var(--color-creme)}
:root[data-mode="night"] .spark-n{fill:var(--color-creme)}

/* Ein Haus ohne Lieferung: die Karte bleibt, die Zahl nicht. */
.occ-none{background:var(--surface-raised)}
.occ-q{color:var(--text-tertiary)}

/* ── Das Haus im Hintergrund der Karte ──────────────────────────────────
   Die Bilder bringen ihren Verlauf im Alphakanal mit — sie brauchen weder
   Deckkraft noch Maske. Ein zusätzlicher `opacity`-Wert würde sie nur trüben
   und das sorgfältig gesetzte Ausblenden verdoppeln.

   Rechts ausgerichtet und an der Höhe der Karte gemessen: das Motiv sitzt in
   den Vorlagen rechts, links bleibt Fläche für Zahl und Text. `contain` statt
   `cover`, damit nichts angeschnitten wird — ein halbes Hotel liest sich nicht
   als Wiedererkennungszeichen.

   Die Farbtönung der Karte bleibt, wie sie ist. Sie steht für die Richtung
   gegenüber dem Vorjahr und ist die einzige Farbe hier; das Bild ist grau und
   tritt nicht mit ihr in Wettbewerb. */
.occ[data-h]{background-repeat:no-repeat;
  background-position:right center;
  background-size:auto 100%}
.occ[data-h="BH"] {background-image:url('/houses/palace.png')}
.occ[data-h="WH"] {background-image:url('/houses/waldhotel.png')}
.occ[data-h="PT"] {background-image:url('/houses/taverne.png')}

/* Zahl und Text stehen über dem Bild — ohne Stapelkontext läge das
   Hintergrundbild zwar hinten, die Kurve aber ohne eigene Fläche darauf. */
/* Der Verlauf, der die linke Kartenhälfte beruhigt. Er liegt über dem Bild
   und unter dem Text — deshalb ein eigenes Element und nicht `background`,
   das die Karte schon für das Foto braucht. */
.occ[data-h]{position:relative; isolation:isolate}
.occ[data-h]::before{content:''; position:absolute; inset:0; z-index:0;
  border-radius:inherit; pointer-events:none;
  background:linear-gradient(90deg,
    var(--surface-raised) 0 34%,
    color-mix(in srgb, var(--surface-raised) 55%, transparent) 62%,
    transparent 88%)}
.occ[data-h] > *{position:relative; z-index:1}

/* Auf schmalen Schirmen ist die Karte eine Zeile; ein Bild über die halbe
   Breite drängte den Text. Kleiner und weiter rechts, mehr Andeutung als Bild. */
@media(max-width:640px){
  .occ[data-h]{background-size:auto 132%; background-position:right -8% center}
}


/* ═══ Durchsicht 31.08. — Flächen und Hierarchie ═══════════════════════════
   Zwei Rückmeldungen:
     · «Boxen mehr aus dem Hintergrund herausholen, kleben zu fest drauf,
        gibt keine Differentiation.»
     · «Auch hier Hierarchie, man weiss nicht wo man hinschauen soll.» (Top VIP)

   Kein Schlagschatten — Regel 5 bleibt unangetastet. Tiefe entsteht weiter aus
   Flächenwechsel plus Haarlinie, nur mit Schritten, die man auch sieht. Es kommt
   keine neue Pigmentfarbe dazu: alle Werte sind vorhandene Palettentoken oder
   Mischungen daraus, wie beim freigegebenen Login-Schatten.
   ────────────────────────────────────────────────────────────────────────── */

/* Die Leiter war zu eng. Grund #F1F0EB und Karte #F6F5EF trennen fünf
   Helligkeitspunkte — auf einem Bildschirm bei Tageslicht praktisch nichts,
   und genau das liest sich als «klebt drauf». Neu stehen drei Stufen mit je
   rund dem Doppelten an Abstand: der Grund geht auf Warmgrau herunter, die
   Karte bleibt auf --color-light (dessen Kommentar in tokens.css lautet
   «Raised surfaces — cards, toolbars»), und die vertiefte Fläche liegt jetzt
   UNTER dem Grund statt darüber — vorher war «sunken» heller als die Seite.
   Die Kante wird zugleich etwas kräftiger, weil eine Fläche ohne fassende
   Linie bei diesem geringen Kontrast ausfranst.

   Night Audit bleibt unberührt: :root[data-mode="night"] ist spezifischer. */
:root{
  --surface-page:   color-mix(in srgb, var(--color-warm-grey) 70%, var(--color-hairline));
  --surface-raised: var(--color-light);
  --surface-sunken: color-mix(in srgb, var(--color-warm-grey) 25%, var(--color-hairline));
  --border-subtle:  color-mix(in srgb, var(--color-ink) 15%, transparent);
}

/* Top VIP — vier gleich laute Stimmen in einer Zeile.

   Die Zeile trug bisher ein dunkel gefülltes Tier-Schild, den Namen, einen
   farbigen Statuschip und die Rate, alle etwa gleich präsent. Vier Betonungen
   sind keine Betonung. Wer zuerst gelesen werden soll, muss allein stehen:

     · Der Name bekommt das Gewicht — er ist der Grund, warum die Liste
       existiert. Die ExCom erkennt einen Gast, keinen Datensatz.
     · Das Tier-Schild trägt nur noch auf der obersten Stufe die volle Füllung,
       darunter nur Kontur. Das macht die Rangfolge sichtbar, nach der die
       Liste ohnehin sortiert ist («Highest level first»), statt vier dunkle
       Blöcke gleich laut nebeneinanderzustellen.
     · Der Hero sitzt neu auf der gehobenen Fläche. Bisher lag ausgerechnet
       der wichtigste Gast auf der vertieften — optisch tiefer als die Liste
       unter ihm. Die Liste rückt dafür auf die vertiefte Fläche, damit der
       Kopf der Karte die hellste Zone ist und das Auge dort anfängt.
     · Die Zeilentrennung lief über --color-hairline, also über ein Pigment
       statt über das semantische Token. Jetzt --border-subtle wie überall. */
.tv-hero{background:var(--surface-raised)}
.tv-l{background:var(--surface-sunken)}
.tv-r{border-bottom-color:var(--border-subtle)}
.tv-n{font-weight:var(--weight-semibold)}
.tv-t2,.tv-t3,.tv-t4{
  background:transparent; color:var(--text-secondary);
  border:1px solid var(--border-subtle); padding:0 .3125rem;
}


/* ── Outlook-Karte: fünf gleich laute Bänder ─────────────────────────────
   «zu staffed» — die Karte stapelte Kopfzeile, Zahl, Bezug, Balken und
   Fusszeile in fünf gleich grossen Abständen übereinander, und der Balken
   war mit 10 px das kräftigste Element auf der Seite. Bei 101 % trägt ein
   voller Balken aber die geringste Information von allen: dass das Ziel
   erreicht ist, sagt die Fusszeile in vier Worten.

   Zwei Gruppen statt fünf Bändern: Zahl und Bezug rücken zusammen (sie sind
   eine Aussage — «13'198'938 von 13'022'741»), danach ein deutlicher
   Abstand, dann Balken und Fusszeile als zweite Gruppe. Der Balken wird auf
   4 px zurückgenommen und verliert die Pillenform; er begleitet die Zahl,
   statt mit ihr zu konkurrieren. */
.fc-n{margin-bottom:2px}
.fc-s{margin-bottom:var(--space-6)}
.fc .bar-lg{height:4px; border-radius:var(--radius-sm)}

/* ── Gäste-Karten: die drei Zahlen der Kopfzeile ─────────────────────────
   «15 an 2 ab 16 in resort» stand als ein einziger Textblock da — drei
   voneinander unabhängige Zählungen ohne Fuge dazwischen, und das Auge
   findet keinen Schnitt. Der Abstand nach jeder Einheit verdoppelt sich,
   damit drei Gruppen entstehen statt einer Kette. */
.ov-big span{margin-right:var(--space-6)}
.ov-big span:last-child{margin-right:0}

/* ── House Status: die Belegungsgrafik lag auf dem blanken Grund ──────────
   «alles sehr flach» — die Tabellen darunter sind Karten, die Grafik darüber
   war nur eine Ansammlung von Balken auf der Seite. Sie bekommt dieselbe
   gehobene Fläche wie jede andere Karte; damit hat der Abschnitt drei
   Behälter statt zwei Behältern und einem Rest. */
.occh{
  background:var(--surface-raised); border:1px solid var(--border-subtle);
  border-radius:var(--radius-sm); padding:var(--space-4);
}


/* ── Outlook-Karte, zweiter Anlauf ───────────────────────────────────────
   Die erste Runde hat nur Abstände verschoben. Das Problem liegt tiefer:
   Steht «Next month» nicht zur Verfügung, streckt auto-fit die eine Karte
   über die ganze Seitenbreite. Der Inhalt bleibt aber links in einer Spalte
   von vielleicht 300 px stehen, rechts daneben eine leere Fläche von tausend.
   Alles klebt zusammen, obwohl ringsum Platz ist — genau der Eindruck «zu
   nahe und zu wenig hierarchy». Mehr Abstand innerhalb der linken Spalte
   hätte daran nichts geändert.

   Also bekommt die Karte zwei Zonen, die sich die Breite teilen:

     links   die Aussage  — Betrag und woran er gemessen wird
     rechts  der Verlauf  — Balken und was daraus folgt

   Damit entsteht die Rangfolge aus der Anordnung und nicht mehr allein aus
   der Schriftgrösse: das Auge liest die Zahl, springt nach rechts und findet
   dort die Bewertung. Der Balken sitzt auf der Grundlinie der Zahl, seine
   Fusszeile auf einer Linie mit «of … forecast» — zwei Zeilen, zwei Höhen,
   keine fünf Bänder mehr.

   Der Betrag wächst auf --text-figure, das Token für Kennzahlen, das die
   Kacheln oben schon benutzen; die feste 1.75rem war kleiner als jede
   Kachel darüber, obwohl hier die grösste Zahl der Seite steht. Und die
   Karte bekommt mit --space-6 Innenabstand die Luft, die eine Fläche dieser
   Grösse braucht.

   Gesteuert über :has(.fc-n), damit die Nachbarkarte «Next month» mit ihrer
   Belegungsvorschau unberührt bleibt — sie trägt keine .fc-n. */
.fc-c{padding:var(--space-6)}
.fc-h{margin-bottom:var(--space-4)}
.fc-n{font-size:var(--text-figure)}

@media (min-width:760px){
  .fc-rev{
    display:grid; align-items:end;
    grid-template-columns:auto minmax(260px,1fr);
    column-gap:var(--space-12);
  }
  .fc-rev .fc-h{grid-column:1/-1}
  .fc-rev .fc-n{grid-column:1; grid-row:2}
  .fc-rev .fc-s{grid-column:1; grid-row:3; margin-bottom:0}
  .fc-rev .bar-lg{grid-column:2; grid-row:2; align-self:end; margin-bottom:.6rem}
  .fc-rev .fc-f{grid-column:2; grid-row:3; margin-top:0}
}


/* ── Revenue-Kacheln: vier Kacheln, die sich nicht vergleichen liessen ────
   «Nicht übersichtlich» — und der Grund steckt in der zweiten Zeile. Die
   vier Zusatzangaben sind verschieden lang («Rooms 64% · F&B 23% · OOD 12%»
   gegen «11 outlets with revenue»), und weil darunter direkt der
   Vorjahresvergleich folgt, sass er in jeder Kachel auf einer anderen Höhe.
   Vier Zahlen, die verglichen werden wollen, standen damit auf vier Linien.

   Die Kachel wird deshalb zur Spalte, und der Vergleich wandert mit
   margin-top:auto an ihren Fuss. Damit stehen die vier Prozentwerte quer
   über die Reihe auf einer Linie, egal wie lang die Zeile darüber ist — man
   liest sie in einem Zug, statt viermal die Augenhöhe zu wechseln.

   Der Betrag rückt zugleich etwas näher an seine Beschriftung: er gehört zu
   ihr, nicht zur Zeile darunter. */

/* Der Hinweis gilt für alle vier und steht deshalb einmal unter der Reihe.
   Er rückt direkt an die Kacheln heran — mit dem vollen Abstand des Rasters
   sähe er aus, als gehörte er zur nächsten Bank. */
.rev-kpi-note{
  /* .grid trägt margin-bottom:2rem, .srcnote ein margin-top:1.5rem — zusammen
     dreieinhalb Zentimeter Luft für eine Fussnote. Hier auf einen Abstand
     zurückgeholt, der sie noch der Reihe darüber zuordnet. */
  margin-top:calc(var(--space-3) - var(--space-8));
  margin-bottom:var(--space-8);
}

/* Der Satz gehört unter die drei Kennzahlen, nicht neben sie. Als vierter
   Flex-Eintrag sass er auf der Grundlinie der Zahlen und las sich wie eine
   vierte Spalte. Volle Breite, eigene Zeile. */
.rev-rat-n{flex:1 1 100%; align-self:auto; margin-top:var(--space-3)}


/* ── Revenue: eine Karte für die Summe, drei Teile darunter ──────────────
   Vier gleich grosse Kacheln für eine Summe und ihre Bestandteile — das war
   der Grund, warum sich die Zahlen nicht lesen liessen. 446'016 IST
   286'548 + 104'651 + 53'032, aber vier Kacheln nebeneinander behaupten vier
   unabhängige Grössen; die Rechnung musste man selbst mitbringen.

   Jetzt trägt die Summe die Karte — Betrag links, Vorjahresvergleich rechts
   auf derselben Höhe wie die Beschriftung —, und unter einer Haarlinie steht
   die Zerlegung. Die drei Teile sind bewusst kleiner gesetzt: sie sind der
   Aufschluss, nicht die Aussage. Ihre Vergleichswerte stehen alle auf einer
   Linie, weil sie in einem Raster liegen und nicht mehr in drei getrennten
   Behältern unterschiedlicher Höhe.

   «CHF» steht nur noch einmal, an der Summe. Die Währung ändert sich in der
   Zerlegung nicht, und viermal dieselbe Einheit ist dreimal zu viel. */
.rev-lead{margin-bottom:var(--space-6)}
.rev-lead-h{display:flex; align-items:center; justify-content:space-between;
  gap:var(--space-4)}
.rev-lead .v{margin:var(--space-2) 0 0}

.rev-parts{display:grid; gap:var(--space-4) var(--space-8);
  grid-template-columns:repeat(auto-fit,minmax(170px,1fr));
  margin-top:var(--space-4); padding-top:var(--space-4);
  border-top:1px solid var(--border-subtle)}
.rev-part .eyebrow{display:block; color:var(--text-tertiary)}
.rev-part-v{font-family:var(--font-display); font-weight:var(--weight-regular);
  font-size:1.5rem; line-height:var(--leading-tight);
  font-variant-numeric:tabular-nums; margin:.125rem 0}
.rev-part-d{display:flex; align-items:baseline; gap:var(--space-3);
  flex-wrap:wrap; font-size:var(--text-eyebrow); color:var(--text-secondary)}

/* Der Vergleichswert, überall gleich gesetzt — in der Kopfzeile wie in den
   Teilen. Die Farbe sagt die Richtung, der Pfeil sagt sie noch einmal für
   alle, die sie nicht unterscheiden. */
.rev-d{display:inline-flex; align-items:center; gap:.25rem;
  font-weight:var(--weight-semibold); font-variant-numeric:tabular-nums;
  font-size:var(--text-body); white-space:nowrap}
.rev-d .ico{width:14px; height:14px; flex:none; stroke-width:2.25}
.rev-d-up{color:var(--ok-fg)}   .rev-d-up .ico{stroke:var(--ok-fg)}
.rev-d-flat{color:var(--pd-fg)} .rev-d-flat .ico{stroke:var(--pd-fg)}
.rev-d-down{color:var(--ms-fg)} .rev-d-down .ico{stroke:var(--ms-fg)}


/* ── Stand-Zeitstempel ───────────────────────────────────────────────────
   Sitzt direkt unter dem Titel, wo man ihn sucht, und bleibt leise: er ist
   eine Zusicherung, keine Kennzahl. h2 trägt margin-bottom:space-3, das
   reicht als Abstand nach oben; nach unten der volle Abschnittsabstand. */
.stamp{margin:0 0 var(--space-6); color:var(--text-tertiary);
  font-size:var(--text-eyebrow); font-variant-numeric:tabular-nums}

/* ── Weniger Versalien ───────────────────────────────────────────────────
   Zehn Versalien-Etiketten auf einer Seite: jedes ist für sich leise,
   zusammen sind sie laut, und Grossbuchstaben lesen sich messbar langsamer,
   weil die Wortumrisse verschwinden — bei ganzen Sätzen wie der Quellenzeile
   («NO DELIVERY REACHES BEYOND THE END OF NEXT MONTH…») wird daraus ein
   Hindernis statt eines Hinweises.

   Versalien bleiben dort, wo sie Struktur anzeigen: Abschnittsköpfe und der
   Brotkrumen über dem Titel. Alles, was innerhalb einer Karte beschriftet,
   wird gemischt gesetzt. Die Sperrung geht mit den Versalien — gesperrte
   Kleinbuchstaben sind ein eigener Fehler, und das System erlaubt sie
   ausdrücklich nur für Versalien-Etiketten. */
.eyebrow{text-transform:none; letter-spacing:0}
.ov-sect,.crumb{text-transform:uppercase; letter-spacing:.09em}

.srcnote,.spark-r,.ov-big span,.occ-h .q,.occ-d .q,.fc-h .q,.dayempty-k{
  text-transform:none; letter-spacing:0;
}
