/**
 * Hub-Layout — Top-Bar, Side-Nav, Main-Container
 */

.app {
  display: grid;
  grid-template-rows: var(--topbar-height) 1fr;
  grid-template-columns: var(--sidenav-width) 1fr;
  grid-template-areas: "topbar topbar" "sidenav main";
  height: 100vh;
}

/* ===== TOP-BAR ===== */
/* Marken-Header wie in THEMIS: dunkelgruene Flaeche, weisse Schrift.
   Hier stand `#0F1114` — der einzige Hartwert der Inventur, der einen
   Theme-Wechsel wirklich kippt: Body hell, Kopfzeile schwarz. */
.topbar {
  grid-area: topbar;
  background: var(--brand);
  border-bottom: 1px solid var(--brand-hover);
  color: var(--text-on-brand);
  /* 10px 16px — der gemessene THEMIS-Wert. Zusammen mit 48px Zeichen ergibt
     das die 68px Gesamthoehe aus `--topbar-height`. */
  padding: 10px 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  /* FEINSCHLIFF C4 — siehe den Block vor `.topbar-brand`. */
  min-width: 0;
}
/* Marke: Bildzeichen + zweizeiliger Text, Proportionen wie THEMIS. */
.topbar-brand {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  color: var(--text-on-brand);
  cursor: pointer;
  border-radius: var(--radius-md);
  padding: 2px var(--space-2) 2px 0;
  /* Die Marke darf bis auf das Bildzeichen zusammengehen — aber nicht
     weiter: `min-width` ist genau die Logobreite unten. Mit `0` schrumpfte
     der Kasten auf 8 px, und das Bildzeichen stand daneben statt darin
     (gemessen 01.09.). Siehe den Block vor `.topbar-brand-text`. */
  min-width: 48px;
  overflow: hidden;
}
.topbar-brand:focus-visible {
  outline: 2px solid var(--text-on-brand);
  outline-offset: 2px;
}
.topbar-logo { width: 48px; height: 48px; display: block; flex-shrink: 0; }
/* ⚠️ SCHMALE FENSTER: TEXT KUERZEN, NICHT DIE SEITE BREITER MACHEN
   (FEINSCHLIFF C4, gemessen 01.09. an dieser Kopfzeile).

   BEFUND: Die Kopfzeile liess sich nicht unter **733 px** druecken. Marke und
   Aktionen hatten keine Erlaubnis zu schrumpfen, also wuchs stattdessen die
   SEITE: Auf einem 360-px-Telefon standen **373 px** Ueberlauf, und alles
   darunter — Menue, Inhalt, Dialoge — erbte diese Breite, weil `.app` ein
   Raster ist und die Kopfzeile seine erste Zeile.

   Die Behandlung ist KEINE neue Idee: `.topbar-context-title` und `-sub`
   kuerzen seit jeher mit Auslassungspunkten. Marke und Nutzername bekommen
   genau dieselbe — ein Name, der nicht passt, wird gekuerzt; er schiebt
   nicht die halbe Anwendung aus dem Bild.

   ERGEBNIS, gemessen: Die Kopfzeile passt jetzt in jedes Fenster ab **460 px**
   statt erst ab 733. Bei 750 px — der Breite aus der Meldung — ist kein
   Ueberlauf mehr messbar, bei 1280 px aendert sich nichts (Marke 192 px wie
   vorher).

   ⚠️ UNTER 460 px BLEIBT ES DABEI: Auf einem 360-px-Telefon schiebt sich die
   Seite weiter um 100 px zur Seite. Was dort noch Platz braucht, hat feste
   Groesse — Bildzeichen, Alarm, Glocke, Abmelde-Knopf. Eines davon
   auszublenden oder zu verkleinern ist eine GESTALTUNGSENTSCHEIDUNG; sie ist
   gemeldet, nicht selbst getroffen. */

.topbar-brand-text {
  display: flex;
  flex-direction: column;
  line-height: 1.15;
  min-width: 0;
  overflow: hidden;
}
/* Produktname: NUR „HERMES". Die Dachmarke steht ausschliesslich im Untertitel —
   „CONDA HERMES" im grossen Titel doppelte sie und machte den Namen kleiner,
   als er in THEMIS ist. 18px/700/0.36px sind gemessene Werte, keine Naeherung;
   deshalb hier in Pixel statt ueber die Token-Stufen. */
.topbar-brand-name {
  font-size: 18px;
  font-weight: 700;
  letter-spacing: 0.36px;
  /* Kuerzen statt schieben (FEINSCHLIFF C4) — wie beim Kontexttitel. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Dachmarke: klein, Versalien, gesperrt — wie in THEMIS. Der Ton ist eine
   aufgehellte Fläche des Headers, nicht `--text-tertiary`: dessen Wert ist auf
   HELLE Gründe gerechnet und wäre auf dem Dunkelgrün zu dunkel. */
.topbar-brand-sub {
  font-size: 10px;
  font-weight: 400;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.72);
  /* Kuerzen statt schieben (FEINSCHLIFF C4) — wie beim Kontexttitel. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Kontexttitel: durch einen senkrechten Strich vom Markenblock getrennt,
   Titel fett weiss, Unterzeile klein und gedaempft — wie THEMIS. */
.topbar-context {
  display: flex;
  flex-direction: column;
  justify-content: center;
  line-height: 1.2;
  padding-left: var(--space-4);
  margin-left: var(--space-2);
  border-left: 1px solid rgba(255, 255, 255, 0.28);
  min-height: 40px;
  flex: 1;
  min-width: 0;
}
/* Ohne Titel keine Trennlinie — sonst steht ein Strich im Nichts. */
.topbar-context:empty, .topbar-context.leer { border-left: none; padding-left: 0; margin-left: 0; }
.topbar-context-title {
  font-size: 15px;
  font-weight: 700;
  color: var(--text-on-brand);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.topbar-context-sub {
  font-size: 11px;
  color: rgba(255, 255, 255, 0.72);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* ⚠️ DIESER BLOCK SCHRUMPFT WEITERHIN NICHT — und das ist Absicht.
   Zwei Symbole und ein Knopf haben eine feste Groesse; laesst man den
   Behaelter schmaler werden, wandern seine Kinder einfach aus ihm heraus
   (gemessen: Behaelter 170 px, Inhalt 234 px, der Abmelde-Knopf stand
   ausserhalb). Ein Ueberlauf, den man nicht mehr sieht, ist schlechter als
   einer, den man scrollen kann. Nachgegeben wird deshalb bei der Marke und
   beim Kontexttitel, nicht hier. */
.topbar-actions { display: flex; align-items: center; gap: var(--space-3); flex-shrink: 0; }
/* HEADER-ELEMENTE, transluzent (HERMES-2026-08-14-HEADER-BUTTONS-HUB-KARTEN).
   An THEMIS gemessen (`hub.html`, Logout): `rgba(255,255,255,0.1)`, Text weiss,
   Radius 8, Padding 6/12, 11px, KEIN Rahmen. Getoentes Glas auf dem Gruen —
   voll weisse Flaechen wirkten wie Fremdkoerper im Header. */
/* Benachrichtigungen, Nutzer-Pill und Abmelden sind EINE Familie: gleiche
   Hoehe, gleicher Radius, gleiche helle Flaeche. Vorher standen hier drei
   Stile nebeneinander — nackter Text, helle Pill, weisser Knopf. */
.topbar-icon {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  padding: 6px 12px;
  border-radius: var(--radius-lg);
  background: rgba(255, 255, 255, 0.10);
  color: var(--text-on-brand);
  cursor: pointer;
  font-size: 11px;
  font-weight: var(--font-weight-medium);
}
.topbar-icon:hover { background: rgba(255, 255, 255, 0.18); }
.topbar-badge {
  position: absolute;
  top: 2px; right: 2px;
  background: var(--danger);
  color: var(--text-on-brand);
  font-size: 10px;
  padding: 0 5px;
  border-radius: var(--radius-pill);
  min-width: 16px;
  text-align: center;
}
/* Name + Rolle: TRANSLUZENT wie Abmelden und Benachrichtigungen.
   KORREKTUR 14.08.: Die frühere Vorgabe „hell mit dunklem Text" war eine
   Fehlableitung aus einem kleinen Screenshot; der Zoom zeigt dieselbe getönte
   Familie wie der Logout-Knopf. Die helle Regel ist ENTFERNT, nicht
   überschrieben — sonst stünde wieder eine Altregel im Weg, die beim nächsten
   Umbau gewinnt (genau das war der Fehler aus Runde 3). */
.topbar-user {
  display: flex; align-items: center; gap: var(--space-2);
  /* FEINSCHLIFF C4: Der Block gibt Text her, bevor die Seite breiter wird. */
  min-width: 0;
  min-height: 36px;
  padding: 4px 12px;
  border-radius: var(--radius-lg);
  cursor: pointer;
  background: rgba(255, 255, 255, 0.10);
  color: var(--text-on-brand);
}
.topbar-user:hover { background: rgba(255, 255, 255, 0.18); }
/* Der ganze Kopfzeilen-Block rechts ist transluzent — weisser Fokusrahmen
   ueberall. (Bis zur Korrektur war die Namensbox hell und brauchte einen
   dunklen; diese Ausnahme ist mit ihr entfallen.) */
.topbar-icon:focus-visible, .topbar-logout:focus-visible, .topbar-user:focus-visible {
  outline: 2px solid var(--text-on-brand);
  outline-offset: 2px;
}
.topbar-user-text {
  display: flex;
  flex-direction: column;
  line-height: 1.2;
  min-width: 0;
  overflow: hidden;
}
/* Rolle unter dem Namen — die Information, die bisher nur im Profildialog stand. */
.topbar-user-name {
  font-size: 13px;
  font-weight: 500;
  color: var(--text-on-brand);
  line-height: 1.2;
  /* Kuerzen statt schieben (FEINSCHLIFF C4) — wie beim Kontexttitel. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* ⚠️ ABWEICHUNG VON DER VORGABE, gemessen begruendet: Die Spezifikation nennt
   „~rgba(255,255,255,0.7)". Auf der transluzenten Flaeche (0.1 Weiss ueber dem
   Gruen) ergibt das gerechnet 3.69:1 — unter der AA-Schwelle, und das bei 10px.
   Der naechstliegende konforme Wert ist 0.85 (4.60:1). Die Tilde in der Vorgabe
   laesst den Spielraum; ein unlesbarer Rollentext waere die schlechtere Treue. */
.topbar-user-role {
  font-size: 10px;
  letter-spacing: 0.04em;
  color: rgba(255, 255, 255, 0.85);
  line-height: 1.2;
  /* Kuerzen statt schieben (FEINSCHLIFF C4) — wie beim Kontexttitel. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Abmelden ist ab jetzt SICHTBAR, nicht im Profildialog versteckt. Umriss statt
   Fläche: der Knopf soll auffindbar sein, aber nicht mit dem CTA konkurrieren. */
/* Abmelden als HELLE Schaltflaeche, Radius 8px — nicht als Outline-Knopf.
   Der Outline-Knopf der ersten Fassung war zu unscheinbar; in THEMIS ist die
   Abmeldung eine sichtbare Flaeche. */
.topbar-logout {
  background: rgba(255, 255, 255, 0.10);
  color: var(--text-on-brand);
  border: none;
  border-radius: var(--radius-lg);
  min-height: 36px;
  padding: 6px 12px;
  font-size: 11px;
  font-weight: var(--font-weight-medium);
  transition: background var(--transition-fast);
}
.topbar-logout:hover { background: rgba(255, 255, 255, 0.18); }
/* HIER STANDEN ZWEI ALTREGELN AUS RUNDE 1 (HERMES-2026-08-14-KOPFZEILE-RUNDE3):
     .topbar-user:hover { background: rgba(255,255,255,0.16); }
     .topbar-user-name  { color: var(--text-on-brand); }
   Beide stammen aus der Zeit, als die Pill noch gruen auf gruen war. Sie standen
   NACH den neuen Regeln von Runde 2 und haben sie damit ueberstimmt — gleiche
   Spezifitaet, spaeter im Dokument gewinnt. Ergebnis, am gerenderten Element
   gemessen: `color: rgb(255,255,255)` auf `background: rgba(255,255,255,0.92)`.
   Weiss auf Weiss. Die Regeln sind ENTFERNT, nicht ueberschrieben — eine dritte
   Regel obendrauf haette denselben Fehler nur eine Runde weiter verschoben. */

/* ===== SIDE-NAV ===== */
.sidenav {
  grid-area: sidenav;
  background: var(--bg-secondary);
  border-right: 1px solid var(--border);
  padding: var(--space-3) 0;
  overflow-y: auto;
}
/* Sektions-Label ueber einer Gruppe: klein, Versalien, gesperrt. */
/* Sektions-Label: `--tx-tertiary` wie vorgegeben. Gerechnet sind das 3.28:1 —
   bewusst so belassen und hier benannt: Es ist eine reine Gruppenueberschrift,
   die keine Information traegt, die nicht auch in den Eintraegen darunter
   steht. Waere es ein Zustand oder ein Wert, stuende hier der dunklere Ton. */
.nav-section {
  font-size: 10px;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--text-tertiary);
  padding: var(--space-3) var(--space-4) var(--space-1);
}
.nav-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin: 2px var(--space-2);
  padding: 9px 12px;
  border-radius: var(--radius-lg);
  color: var(--text-secondary);
  cursor: pointer;
  font-size: 14px;
  transition: background var(--transition-fast), color var(--transition-fast);
}
.nav-label { flex: 1; min-width: 0; }
/* Das Icon erbt die Textfarbe (`currentColor`) — in der aktiven Pille wird es
   dadurch weiss, ohne dass es dafuer eine eigene Regel braucht. */
.nav-icon { flex-shrink: 0; display: block; }
.nav-item:hover { background: var(--bg-tertiary); color: var(--text-primary); }
/* VARIANTE A: der aktive Eintrag ist eine markengruene Pille. */
.nav-item.active {
  background: var(--brand);
  color: var(--text-on-brand);
  font-weight: var(--font-weight-medium);
}
.nav-item.active:hover { background: var(--brand); color: var(--text-on-brand); }
.nav-item.disabled { color: var(--text-tertiary); cursor: not-allowed; }
.nav-item.disabled:hover { background: transparent; color: var(--text-tertiary); }
/* „· v2" im Text ist entfallen — der Zustand steht als eigenes Abzeichen rechts. */
/* ⚠️ ZWEITE ABWEICHUNG, ebenfalls gemessen: Die Vorgabe nennt `--tx-tertiary`
   fuer das Abzeichen. Auf `--bg-tertiary` sind das 3.11:1 — das Abzeichen ist
   aber die EINZIGE Stelle, an der „geplant" ausgeschrieben steht (die graue
   Schrift allein waere nur ein Farbsignal). Deshalb `--text-secondary`: 5.38:1,
   optisch weiterhin zurueckhaltend. */
.nav-badge {
  font-size: 10px;
  font-weight: var(--font-weight-medium);
  letter-spacing: 0.04em;
  padding: 2px 7px;
  border-radius: var(--radius-pill);
  background: var(--bg-tertiary);
  color: var(--text-secondary);
  flex-shrink: 0;
}
.nav-divider { height: 1px; background: var(--border); margin: var(--space-3) var(--space-4) 0; }

/* ===== MAIN ===== */
.main {
  grid-area: main;
  padding: var(--space-5) var(--space-6);
  overflow-y: auto;
}
.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-5);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--border);
}
.page-title {
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-medium);
  margin: 0;
}
.page-actions { display: flex; gap: var(--space-2); }
.breadcrumb {
  font-size: var(--font-size-xs);
  color: var(--text-secondary);
  margin-bottom: var(--space-2);
}
.breadcrumb a { color: var(--text-secondary); }
.breadcrumb .current { color: var(--text-primary); }

/* ===== INBOX ===== */
.inbox-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 10px var(--space-3);
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background var(--transition-fast);
}
.inbox-row:last-child { border-bottom: none; }
.inbox-row:hover { background: var(--bg-tertiary); }
.inbox-dot { width: 8px; height: 8px; border-radius: var(--radius-pill); flex-shrink: 0; }
.inbox-dot-warning { background: var(--warning); }
.inbox-dot-success { background: var(--success); }
.inbox-dot-danger { background: var(--danger); }
.inbox-dot-info { background: var(--conda-sky); }
.inbox-content { flex: 1; }
.inbox-title { font-weight: var(--font-weight-medium); font-size: var(--font-size-sm); }
.inbox-meta { color: var(--text-secondary); font-size: var(--font-size-xs); }
.inbox-time { color: var(--text-tertiary); font-size: var(--font-size-xs); }

/* ===== MODULE GRID ===== */
.module-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--space-3);
  margin-top: var(--space-3);
}
/* MODUL-KARTEN im THEMIS-Board-Stil: weisse Karte, Radius 12, weicher Schatten,
   linker Akzentbalken, Status-Badge oben rechts, Fusszeile mit Meta links und
   Aktion rechts. Der Balken traegt den Zustand — aktiv gruen, geplant grau —
   und macht ihn auf einen Blick unterscheidbar, ohne Farbe als einziges Mittel:
   das Badge sagt es zusaetzlich im Klartext. */
.module-tile {
  position: relative;
  background: var(--bg-primary);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  padding: var(--space-4) var(--space-4) var(--space-3) var(--space-5);
  cursor: pointer;
  box-shadow: var(--elev-2);
  transition: box-shadow var(--transition-fast), transform var(--transition-fast);
  overflow: hidden;
}
/* Akzentbalken links — 4px, ueber die volle Hoehe. */
.module-tile::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 4px;
  background: var(--brand);
}
.module-tile.disabled::before { background: var(--text-tertiary); }
.module-tile:hover { box-shadow: var(--elev-3); transform: translateY(-2px); }
.module-tile.disabled { cursor: not-allowed; }
.module-tile.disabled:hover { box-shadow: var(--elev-2); transform: none; }
.module-tile-icon {
  width: 36px; height: 36px;
  background: var(--bg-tertiary);
  border-radius: var(--radius-md);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: var(--space-3);
}
.module-tile-name { font-weight: var(--font-weight-bold); font-size: var(--font-size-md); margin-bottom: 4px; }
.module-tile-meta { color: var(--text-secondary); font-size: var(--font-size-xs); }

/* Status-Badge oben rechts. „Aktiv" in der CTA-Familie, „geplant" neutral. */
.module-badge {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
  font-size: 10px;
  font-weight: var(--font-weight-bold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 3px 9px;
  border-radius: var(--radius-pill);
  background: var(--brand-cta);
  color: var(--text-on-cta);
}
.module-badge.geplant { background: var(--bg-tertiary); color: var(--text-secondary); }

/* Fusszeile: Meta links, Aktion rechts — dunkelgruen und fett. */
.module-tile-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: var(--space-4);
  padding-top: var(--space-3);
  border-top: 1px solid var(--border);
}
.module-tile-action {
  color: var(--brand);
  font-weight: var(--font-weight-bold);
  font-size: var(--font-size-sm);
  white-space: nowrap;
}
.module-tile.disabled .module-tile-action { color: var(--text-tertiary); }
.module-tile-actions { display: flex; gap: var(--space-2); }
.module-tile-actions {
  display: flex; gap: var(--space-1);
  border-top: 1px solid var(--border);
  padding-top: var(--space-2);
  margin-top: var(--space-2);
}
.module-tile-actions .btn { font-size: var(--font-size-xs); padding: 4px 10px; }

/* ===== RESPONSIVE ===== */
@media (max-width: 768px) {
  .app {
    grid-template-columns: 1fr;
    grid-template-rows: var(--topbar-height) auto 1fr;
    grid-template-areas: "topbar" "sidenav" "main";
  }
  .sidenav {
    border-right: none;
    border-bottom: 1px solid var(--border);
    display: flex;
    overflow-x: auto;
    padding: var(--space-2);
  }
  .nav-item { border-left: none; border-bottom: 3px solid transparent; }
  .nav-item.active { border-left: none; border-bottom-color: var(--conda-green); }
  }

/* ===========================================================================
   Inline-Edit-Zellen im Grid (HERMES-2026-08-15-NAECHTIGUNG-TAGE)
   ===========================================================================
   BEFUND (Roland, Screenshot): Ein Grid, in dem jede Zelle ein umrandetes
   Eingabekaestchen ist, liest sich wie ein Formular mit dreissig Feldern. Der
   Blick findet die Zeile nicht mehr, weil jede Zelle gleich laut ruft.

   LOESUNG: Im Ruhezustand steht dort Text wie in jeder anderen Zelle — kein
   Rahmen, kein Kaestchen, kein Hintergrund. Die Feld-Optik erscheint erst bei
   Hover und beim Fokus.

   ⚠️ BEWUSST EIN ECHTES <input>, KEIN span-zu-input-Tausch: Das Element bleibt
   damit im Tab-Fokus, meldet sich Screenreadern als Textfeld und laesst sich
   ohne Maus bedienen. Ein Tausch beim Klick haette genau das gekostet — die
   Zelle waere nur noch mit der Maus erreichbar gewesen. Die Optik ist eine
   Frage von CSS, nicht von Zustandslogik. */
.zelle-edit {
  width: 100%;
  min-width: 0;
  box-sizing: border-box;
  font: inherit;
  color: var(--text-primary);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  padding: 3px 6px;
  transition: background var(--transition-fast), border-color var(--transition-fast);
}
.zelle-edit:hover {
  background: var(--bg-tertiary);
  border-color: var(--border);
}
.zelle-edit:focus {
  background: var(--bg-primary);
  border-color: var(--brand);
  outline: 2px solid var(--brand);
  outline-offset: -1px;
}
/* Der Platzhalter gehoert in den Editiermodus. Im Ruhezustand waere „optional"
   in jeder leeren Zelle eine Wortwand, die keine Information traegt. */
.zelle-edit::placeholder { color: transparent; }
.zelle-edit:focus::placeholder { color: var(--text-tertiary); }

/* Mahlzeiten-Spalten: schmal und mittig, damit die Haken eine Spalte bilden
   und nicht in der Zeile schwimmen. */
.grid-haken { text-align: center; width: 84px; }
.grid-haken input { cursor: pointer; }

/* Regime-Untertitel in den Mahlzeiten-Spaltenköpfen
   (HERMES-2026-08-15-MAHLZEIT-GEMISCHTER-TAG). Sie erscheinen nur, wenn die
   Reise überhaupt einen Tag mit Grenzübertritt hat — sonst erklärt die Tabelle
   eine Unterscheidung, die es dort nicht gibt. */
.grid-haken-regime {
  font-size: 9px;
  font-weight: var(--font-weight-normal);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin-top: 1px;
}
