/* Design system for the Assolvo organisation tool.
   Single source of truth: design.md in the repo root ("Sand" variant).
   Never write a colour, spacing or font size outside this file — use the tokens.
   Light and dark are maintained together; dark is not an afterthought. */

/* ---------- Tokens: light ---------- */
:root {
  --bg: #f2ede4;
  --surface: #fffdf9;
  --bar: #eae3d7;
  --fg: #231f19;
  --muted: #7a7164;
  --line: #ddd4c5;
  --line-soft: #ebe4d8;

  /* Blaugrün der Marke (Assolvo-Website, heller Block). Kontrast 7,1 auf der Karte. */
  --accent: #315c72;
  --accent-hover: #2a4e61;
  --on-accent: #ffffff;

  --st-ruhend-bg: #ebe4d8;  --st-ruhend-fg: #6b6154;  --st-ruhend-br: #ddd4c5;
  --st-aktiv-bg: #dceceb;   --st-aktiv-fg: #235a56;   --st-aktiv-br: #bfdbd9;
  --st-wartend-bg: #fdf0d9; --st-wartend-fg: #8a5a12; --st-wartend-br: #f0dcb8;
  --st-stockend-bg: #f4ece2;--st-stockend-fg: #8a6a4a;--st-stockend-br: #e3d5c4;
  --st-gut-bg: #e2efe6;     --st-gut-fg: #2c6540;     --st-gut-br: #c8e0d1;
  --st-aus-bg: #f9e3e0;     --st-aus-fg: #8f3324;     --st-aus-br: #eecdc7;

  --space-xs: 4px;  --space-sm: 8px;  --space-md: 12px;
  --space-lg: 16px; --space-xl: 24px; --space-2xl: 32px;

  --radius-sm: 6px; --radius-md: 10px; --radius-lg: 14px; --radius-full: 999px;

  --shadow-sm: 0 1px 2px rgba(60, 45, 20, .05);

  --font: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
}

/* ---------- Tokens: dark ---------- */
/* Applied when the OS asks for dark and the user has not explicitly chosen light. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #191612;
    --surface: #221e19;
    --bar: #1e1b16;
    --fg: #efe9df;
    --muted: #9b9184;
    --line: #332e26;
    --line-soft: #2b2721;

    --accent: #77abc5;
    --accent-hover: #8ab8ce;
    --on-accent: #0b1018;

    --st-ruhend-bg: #2a251e;  --st-ruhend-fg: #a09585;  --st-ruhend-br: #38322a;
    --st-aktiv-bg: #172b2a;   --st-aktiv-fg: #7cc0ba;   --st-aktiv-br: #234340;
    --st-wartend-bg: #3a2c14; --st-wartend-fg: #e8b562; --st-wartend-br: #4d3a1c;
    --st-stockend-bg: #302620;--st-stockend-fg: #c39a76;--st-stockend-br: #40332a;
    --st-gut-bg: #1c3227;     --st-gut-fg: #79c795;     --st-gut-br: #2a4636;
    --st-aus-bg: #3a201b;     --st-aus-fg: #e59182;     --st-aus-br: #4d2c25;

    --shadow-sm: none;
  }
}

/* The toggle wins in both directions. */
:root[data-theme="dark"] {
  --bg: #191612;
  --surface: #221e19;
  --bar: #1e1b16;
  --fg: #efe9df;
  --muted: #9b9184;
  --line: #332e26;
  --line-soft: #2b2721;

  --accent: #77abc5;
  --accent-hover: #8ab8ce;
  --on-accent: #0b1018;

  --st-ruhend-bg: #2a251e;  --st-ruhend-fg: #a09585;  --st-ruhend-br: #38322a;
  --st-aktiv-bg: #172b2a;   --st-aktiv-fg: #7cc0ba;   --st-aktiv-br: #234340;
  --st-wartend-bg: #3a2c14; --st-wartend-fg: #e8b562; --st-wartend-br: #4d3a1c;
  --st-stockend-bg: #302620;--st-stockend-fg: #c39a76;--st-stockend-br: #40332a;
  --st-gut-bg: #1c3227;     --st-gut-fg: #79c795;     --st-gut-br: #2a4636;
  --st-aus-bg: #3a201b;     --st-aus-fg: #e59182;     --st-aus-br: #4d2c25;

  --shadow-sm: none;
}

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { margin: 0; text-wrap: balance; letter-spacing: -.015em; }
h1 { font-size: 19px; font-weight: 700; line-height: 1.2; }
h2 { font-size: 16px; font-weight: 600; line-height: 1.3; }
p  { margin: 0; }

a { color: var(--accent); text-underline-offset: .18em; text-decoration-thickness: 1px; }

/* Was der Browser sonst selbst einfärbt: Markierung, Eingabecursor, native
   Häkchen und Auswahlfelder. Ohne diese Zeilen trügen sie das Blau des Browsers. */
::selection { background: color-mix(in srgb, var(--accent) 22%, transparent); color: var(--fg); }
:root { accent-color: var(--accent); caret-color: var(--accent); }

/* Ausgeblendet heisst ausgeblendet.
   Das Merkmal `hidden` des Browsers verliert gegen jede eigene display-Regel —
   und fast jeder Baustein hier hat eine (.btn ist inline-flex, .notice ist flex).
   Ohne diese Zeile standen der Ein- und der Ausschalten-Knopf gleichzeitig da,
   und der leere Offline-Hinweis zeichnete einen Rahmen um nichts. */
[hidden] { display: none !important; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

.sub   { color: var(--muted); font-size: 13px; }
.meta  { color: var(--muted); font-size: 11.5px; font-variant-numeric: tabular-nums; }
.label {
  font-size: 10.5px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted);
}
.nums { font-variant-numeric: tabular-nums; }

/* ---------- Layout ---------- */
.app { min-height: 100dvh; display: flex; flex-direction: column; }

.topbar {
  display: flex; align-items: center; gap: var(--space-sm) var(--space-md);
  padding: var(--space-md) var(--space-lg);
  background: var(--bar); border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 10;
}

.topbar .brand { display: inline-flex; align-items: center; color: var(--fg); }
/* Der Schriftzug der Marke, eingebettet statt als Bild: So übernimmt er die
   Textfarbe und stimmt im hellen wie im dunklen Modus. Nicht kleiner als 100 px
   breit — die Serifen sind fein und zerfallen darunter. */
.brand svg { display: block; width: 104px; height: auto; }
.topbar .spacer { margin-left: auto; }

.main { flex: 1; width: 100%; max-width: 760px; margin: 0 auto;
        padding: var(--space-lg); display: flex; flex-direction: column; gap: var(--space-lg); }
.narrow { max-width: 420px; }

.stack   { display: flex; flex-direction: column; gap: var(--space-md); }
.stack-sm{ display: flex; flex-direction: column; gap: var(--space-sm); }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: var(--space-md); }

/* ---------- Card ---------- */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: var(--space-lg);
  box-shadow: var(--shadow-sm);
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-sm);
  min-height: 44px;                 /* thumb-sized: the app is used one-handed */
  padding: var(--space-md) var(--space-lg);
  font: inherit; font-weight: 600;
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--surface); color: var(--fg);
  cursor: pointer; text-decoration: none;
  transition: background .15s ease-out, border-color .15s ease-out;
}
.btn:hover { border-color: var(--muted); }
.btn-primary {
  background: var(--accent); color: var(--on-accent); border-color: var(--accent);
}
.btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.btn:disabled, .btn[aria-disabled="true"] {
  background: var(--bar); color: var(--muted); border-color: var(--line);
  cursor: not-allowed;
}
.btn-block { width: 100%; }
.btn-quiet {
  min-height: 0; padding: var(--space-xs) var(--space-sm);
  border: 0; background: transparent; color: var(--muted); font-size: 13px;
}

/* ---------- Forms ---------- */
.field { display: flex; flex-direction: column; gap: var(--space-xs); }
.field > label { font-weight: 600; font-size: 13px; }
.help { color: var(--muted); font-size: 12px; }

input[type="text"], input[type="email"], input[type="password"],
input[type="tel"], input[type="search"], input[type="date"],
input[type="datetime-local"], input[type="time"],
input[type="number"], input[type="url"], select, textarea {
  min-height: 44px;
  padding: var(--space-sm) var(--space-md);
  font: inherit;
  color: var(--fg); background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius-md);
  width: 100%;
}
textarea { min-height: 90px; resize: vertical; }
input::placeholder, textarea::placeholder { color: var(--muted); opacity: 1; }
input[type="search"]::-webkit-search-cancel-button { filter: grayscale(1); }
/* Safari and Chrome give date and time inputs their own font. Without this a
   date field sits in the form in monospace while everything else is IBM Plex Sans. */
input[type="date"], input[type="datetime-local"], input[type="time"] {
  font-family: var(--font);
}

input:focus-visible, select:focus-visible, textarea:focus-visible {
  /* every input takes its colours from the tokens — never a browser default */
  outline: 2px solid var(--accent); outline-offset: -1px; border-color: var(--accent);
}

.errorlist {
  list-style: none; margin: 0; padding: var(--space-sm) var(--space-md);
  background: var(--st-aus-bg); color: var(--st-aus-fg);
  border: 1px solid var(--st-aus-br); border-radius: var(--radius-sm);
  font-size: 13px;
}
.errorlist li + li { margin-top: var(--space-xs); }

/* ---------- State chips ----------
   Six roles cover all twelve states: colour codes urgency, not identity.
   Never colour alone — the chip always carries its label as text. */
.chip {
  display: inline-flex; align-items: center; gap: var(--space-xs);
  padding: var(--space-xs) var(--space-sm);
  font-size: 11.5px; font-weight: 600;
  border-radius: var(--radius-full); border: 1px solid transparent;
  white-space: nowrap;
}
.chip::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }
.chip-ruhend  { background: var(--st-ruhend-bg);  color: var(--st-ruhend-fg);  border-color: var(--st-ruhend-br); }
.chip-aktiv   { background: var(--st-aktiv-bg);   color: var(--st-aktiv-fg);   border-color: var(--st-aktiv-br); }
.chip-wartend { background: var(--st-wartend-bg); color: var(--st-wartend-fg); border-color: var(--st-wartend-br); }
.chip-stockend{ background: var(--st-stockend-bg);color: var(--st-stockend-fg);border-color: var(--st-stockend-br); }
.chip-gut     { background: var(--st-gut-bg);     color: var(--st-gut-fg);     border-color: var(--st-gut-br); }
.chip-aus     { background: var(--st-aus-bg);     color: var(--st-aus-fg);     border-color: var(--st-aus-br); }

/* ---------- Messages ---------- */
.msg {
  padding: var(--space-md); border-radius: var(--radius-md);
  border: 1px solid var(--line); background: var(--surface); font-size: 13px;
}
.msg-success { background: var(--st-gut-bg); color: var(--st-gut-fg); border-color: var(--st-gut-br); }
.msg-error   { background: var(--st-aus-bg); color: var(--st-aus-fg); border-color: var(--st-aus-br); }
.msg-info    { background: var(--st-aktiv-bg); color: var(--st-aktiv-fg); border-color: var(--st-aktiv-br); }

/* ---------- Lists ---------- */
.list { display: flex; flex-direction: column; }
.list-item {
  display: flex; align-items: center; gap: var(--space-md);
  padding: var(--space-md) 0; border-bottom: 1px solid var(--line-soft);
  min-height: 44px;
}
.list-item:last-child { border-bottom: 0; }
.list-item .grow { flex: 1; min-width: 0; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.table-scroll { overflow-x: auto; }

/* ---------- Motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* ---------- Phase 3: history, hints, overdue ---------- */

/* A row of chips or buttons that wraps on a narrow screen. */
.chips { display: flex; flex-wrap: wrap; gap: var(--space-sm); }

/* Screen readers keep the label, the eye gets the placeholder as the guide. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Two fields side by side; stacks below 380px so nothing gets cramped. */
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-md); }
@media (max-width: 380px) { .field-row { grid-template-columns: 1fr; } }

/* ---------- Notice: acceptance grid and duplicate warning ----------
   Takes its colours from a state role — colour means urgency here too, and the
   text always says the same thing as the colour. */
.notice {
  padding: var(--space-md) var(--space-lg);
  border: 1px solid var(--line); border-left-width: 3px;
  border-radius: var(--radius-md);
  background: var(--surface);
  display: flex; flex-direction: column; gap: var(--space-xs);
  font-size: 13px;
}
.notice-title { font-weight: 700; }
.notice-ruhend {
  background: var(--st-ruhend-bg); color: var(--st-ruhend-fg);
  border-color: var(--st-ruhend-br); border-left-color: var(--st-ruhend-fg);
}
.notice-gut {
  background: var(--st-gut-bg); color: var(--st-gut-fg);
  border-color: var(--st-gut-br); border-left-color: var(--st-gut-fg);
}
.notice-wartend {
  background: var(--st-wartend-bg); color: var(--st-wartend-fg);
  border-color: var(--st-wartend-br); border-left-color: var(--st-wartend-fg);
}
.notice-aus {
  background: var(--st-aus-bg); color: var(--st-aus-fg);
  border-color: var(--st-aus-br); border-left-color: var(--st-aus-fg);
}
.notice a { color: inherit; font-weight: 600; }
.notice .meta { color: inherit; opacity: .8; }
.notice .list-item { border-bottom-color: currentColor; }

/* ---------- Overdue ----------
   Not its own colour: the card keeps the role of its state and gains a bar in
   that role's text colour (design.md). */
/* `solid` has to be stated: a list row has no left border of its own, so a
   width alone would draw nothing. */
.overdue { border-left: 3px solid; }
.list-item.overdue { padding-left: var(--space-sm); }
.overdue-ruhend   { border-left-color: var(--st-ruhend-fg); }
.overdue-aktiv    { border-left-color: var(--st-aktiv-fg); }
.overdue-wartend  { border-left-color: var(--st-wartend-fg); }
.overdue-stockend { border-left-color: var(--st-stockend-fg); }
.overdue-gut      { border-left-color: var(--st-gut-fg); }
.overdue-aus      { border-left-color: var(--st-aus-fg); }

/* ---------- Fold ----------
   A section that opens in place. 44px tall like every other tap target. */
.fold > summary {
  display: flex; align-items: center; min-height: 44px;
  cursor: pointer; font-weight: 600; font-size: 13px; color: var(--accent);
  list-style: none;
}
.fold > summary::-webkit-details-marker { display: none; }
.fold > summary::after { content: " ▾"; margin-left: var(--space-xs); }
.fold[open] > summary::after { content: " ▴"; }

/* ---------- Timeline ----------
   The history as plain separated lines, not as cards: it is read from top to
   bottom and gets long. */
.timeline { display: flex; flex-direction: column; }
.timeline-item {
  display: flex; flex-direction: column; gap: var(--space-xs);
  padding: var(--space-md) 0;
  border-top: 1px solid var(--line-soft);
}
.timeline-head { display: flex; flex-wrap: wrap; gap: var(--space-xs); align-items: baseline; }

/* ---------- Phase 5: tasks and the working area ---------- */

/* The tick box in front of a task. 44px like every tap target. */
.btn-check {
  flex: none; min-width: 44px; min-height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 18px; line-height: 1;
  border: 0; background: transparent; color: var(--muted); cursor: pointer;
}
.btn-check:hover { color: var(--accent); }

/* Three figures side by side. Tabular numerals so they line up under each other. */
.figures { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-md); }
.figures > div { display: flex; flex-direction: column; gap: var(--space-xs); }
.figure { font-size: 19px; font-weight: 700; font-variant-numeric: tabular-nums; }
.done { text-decoration: line-through; color: var(--muted); }

/* ---------- Phase 6: figures table ---------- */
.grid { width: 100%; border-collapse: collapse; font-size: 13px; }
.grid th, .grid td { padding: var(--space-sm) var(--space-md); text-align: left; }
.grid th {
  font-size: 10.5px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted); white-space: nowrap;
}
.grid tbody tr { border-top: 1px solid var(--line-soft); }
.grid .num { text-align: right; }

/* A list row whose content stacks instead of competing for width. */
.list-item.stacked { align-items: flex-start; }

/* ---------- Phase 8: permission matrix ---------- */
/* The whole row is the tap target, not just the little box. */
.check {
  display: flex; align-items: center; gap: var(--space-md);
  min-height: 44px; cursor: pointer;
}
/* Fest verdrahtet: sichtbar, aber erkennbar nicht bedienbar. Gedämpft statt
   halbtransparent — design.md verbietet halbtransparente Zustände. */
.check.is-fixed { color: var(--muted); cursor: default; border-style: dashed; }
.check.is-fixed .meta { display: block; }
.check input[type="checkbox"] {
  width: 20px; height: 20px; min-height: 0; flex: none;
  accent-color: var(--accent); cursor: pointer;
}

/* ---------- Phase 9: unread counter ---------- */
.badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 5px;
  border-radius: var(--radius-full);
  background: var(--accent); color: var(--on-accent);
  font-size: 10.5px; font-weight: 700;
}

/* ---------- Navigation ----------
   Zwei Formen, eine Auszeichnung.

   Handy: die Leiste oben, das Menü klappt darunter auf. Gebaut auf einer
   Checkbox statt auf <details>, weil ein details-Element seinen Inhalt so
   versteckt, dass CSS das im breiten Layout nicht zuverlässig überschreiben
   kann — die Navigation wäre dort dann ganz weg. Kein JavaScript: die App wird
   dort bedient, wo der Empfang schlecht ist, und ein Menü, das ein Skript
   braucht, ist ein Menü, das manchmal nicht aufgeht.

   Ab 900 px: die Navigation steht links am Rand und bleibt beim Blättern stehen.
   Bei zwölf Einträgen lief die obere Leiste über mehrere Zeilen und schob den
   Inhalt nach unten — links ist Platz nach unten. */
.menu-toggle { position: absolute; width: 1px; height: 1px; opacity: 0; }
.menu-button {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: var(--space-xs);
  min-height: 44px; padding: 0 var(--space-sm);
  cursor: pointer; font-size: 13px; font-weight: 600; color: var(--accent);
}
.menu-button::after { content: "▾"; }
.menu-toggle:checked ~ .menu-button::after { content: "▴"; }
.menu-toggle:focus-visible ~ .menu-button {
  outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--radius-sm);
}

.menu-panel {
  display: none;
  position: absolute; top: 100%; right: var(--space-lg); left: var(--space-lg);
  flex-direction: column; align-items: stretch; gap: var(--space-xs);
  padding: var(--space-sm);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-md); box-shadow: var(--shadow-sm);
  z-index: 20;
}
.menu-toggle:checked ~ .menu-panel { display: flex; }

.nav-link {
  display: flex; align-items: center; gap: var(--space-sm);
  min-height: 44px; padding: 0 var(--space-sm);
  font-size: 14px; text-align: left; text-decoration: none;
  color: var(--fg); border-radius: var(--radius-sm);
}
.nav-link:hover { background: var(--bar); }
/* Wo man gerade ist. Nicht nur Farbe: der Balken links trägt dieselbe
   Information noch einmal, für alle, die Petrol auf Sand nicht sicher sehen. */
.nav-link[aria-current="page"] {
  color: var(--accent); font-weight: 600;
  background: var(--bar); box-shadow: inset 3px 0 0 var(--accent);
}

/* Selten Gebrauchtes, zugeklappt. */
.nav-group { border-top: 1px solid var(--line); margin-top: var(--space-xs); padding-top: var(--space-xs); }
.nav-group > summary {
  cursor: pointer; list-style: none;
  min-height: 44px; display: flex; align-items: center;
  padding: 0 var(--space-sm);
  font-size: 10.5px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted);
}
.nav-group > summary::-webkit-details-marker { display: none; }
.nav-group > summary::after { content: " ▾"; margin-left: var(--space-xs); }
.nav-group[open] > summary::after { content: " ▴"; }

.nav-foot { border-top: 1px solid var(--line); margin-top: var(--space-xs); padding-top: var(--space-sm); }
.nav-foot > .meta { display: block; padding: 0 var(--space-sm) var(--space-xs); }
.nav-foot-row { display: flex; gap: var(--space-md); padding: 0 var(--space-sm); }
.nav-foot-row form { display: inline; }

/* --- Ab Tablet: Seitenleiste links --- */
@media (min-width: 900px) {
  .app { display: grid; grid-template-columns: 210px 1fr; grid-template-rows: auto 1fr; }
  .topbar {
    grid-column: 1; grid-row: 1 / -1;
    flex-direction: column; align-items: stretch; gap: var(--space-sm);
    padding: var(--space-lg) var(--space-md);
    border-bottom: 0; border-right: 1px solid var(--line);
    /* Bleibt beim Blättern stehen — sonst wäre die Navigation bei einer langen
       Kundenliste nach dem ersten Scrollen weg. */
    position: sticky; top: 0; align-self: start; height: 100dvh;
    overflow-y: auto;
  }
  .topbar .brand { padding: var(--space-xs) var(--space-sm) var(--space-md); }
  .brand svg { width: 132px; }
  .menu-button { display: none; }
  .menu-panel {
    display: flex; position: static; flex-direction: column; align-items: stretch;
    gap: 2px; margin: 0; padding: 0;
    background: none; border: 0; box-shadow: none;
    flex: 1;
  }
  .nav-foot { margin-top: auto; }
  .main { grid-column: 2; grid-row: 1 / -1; }
}

/* ---------- Filter, Blättern, Kontextmenü (02.09.) ----------
   Aus Jonas' erster Durchsicht: bei acht Testkunden reicht eine Liste, bei
   hundert nicht mehr. */

.filter-row { display: flex; flex-wrap: wrap; gap: var(--space-sm); align-items: center; }

/* Ein Filter ist ein Chip, aber ein anklickbarer — deshalb dieselbe runde Form
   wie beim Zustands-Chip und trotzdem 44 px hoch, weil er ein Tippziel ist. */
.chip-filter {
  display: inline-flex; align-items: center; gap: var(--space-xs);
  min-height: 44px; padding: 0 var(--space-md);
  font: inherit; font-size: 13px; font-weight: 600;
  border: 1px solid var(--line); border-radius: var(--radius-full);
  background: var(--surface); color: var(--muted);
  cursor: pointer;
}
.chip-filter:hover { border-color: var(--muted); }
.chip-filter .nums { opacity: .7; font-weight: 400; }
/* Gewählt: nicht nur Farbe — die Umrandung wird kräftiger und die Schrift
   dunkler, damit der Zustand auch ohne Farbwahrnehmung ablesbar ist. */
.chip-filter.is-on {
  background: var(--bar); color: var(--fg); border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.chip-filter input[type="checkbox"] { accent-color: var(--accent); }

.filter-row select {
  min-height: 44px; padding: 0 var(--space-md);
  font: inherit; font-size: 13px;
  border: 1px solid var(--line); border-radius: var(--radius-full);
  background: var(--surface); color: var(--fg);
}

/* Zwei Chips je Zeile: Kundenstatus und, wenn ein Vorgang offen ist, dessen
   Zustand. Auf dem Handy untereinander, sonst wird die Zeile zu breit. */
.chips-right { display: flex; flex-direction: column; align-items: flex-end; gap: var(--space-xs); }
@media (min-width: 560px) { .chips-right { flex-direction: row; align-items: center; } }

.pager {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-md); padding-top: var(--space-md);
  border-top: 1px solid var(--line-soft);
}

/* ---------- Monatsraster im Kalender (02.09.) ----------
   Aus Jonas' zweiter Durchsicht: „hätte ich gerne mehr als Raster wie bei
   Google oder Apple, damit man einen Überblick über die Tage hat."

   Erst ab 700 px. Sieben Spalten mit lesbarem Text passen nicht auf ein Handy —
   dort bleibt die Liste darunter die Ansicht, und die zeigt dieselben Termine.
   Lieber eine Ansicht weglassen als eine unlesbare anbieten. */
.raster-karte { display: none; }

@media (min-width: 700px) {
  .raster-karte { display: flex; }

  .monatsraster { width: 100%; border-collapse: collapse; table-layout: fixed; }
  .monatsraster th {
    padding: var(--space-xs) var(--space-sm); text-align: left;
    font-size: 10.5px; font-weight: 700; letter-spacing: .1em;
    text-transform: uppercase; color: var(--muted);
  }
  .monatsraster th.wochenende { color: var(--st-ruhend-fg); }
  .monatsraster td {
    /* Feste Höhe, damit die Wochen gleich hoch bleiben: eine Zeile, die mit
       ihren Terminen wächst, verschiebt beim Blättern den ganzen Monat. */
    height: 96px; vertical-align: top;
    padding: var(--space-xs);
    border: 1px solid var(--line-soft);
    background: var(--surface);
    overflow: hidden;
  }
  .monatsraster td.anderer-monat { background: var(--bg); }
  .monatsraster td.anderer-monat .tagzahl { color: var(--line); }
  /* Heute: Rahmen und fette Zahl, keine Fläche. Farbe gehört in diesem System
     dem Zustand — ein eingefärbter Tag würde mit den Zustands-Chips streiten. */
  .monatsraster td.ist-heute { box-shadow: inset 0 0 0 2px var(--accent); }
  .monatsraster td.ist-heute .tagzahl { color: var(--accent); font-weight: 700; }

  .tagzahl { display: block; font-size: 11.5px; color: var(--muted); margin-bottom: 2px; }

  .rastertermin {
    display: block; margin-bottom: 2px; padding: 2px var(--space-xs);
    font-size: 11.5px; line-height: 1.3;
    background: var(--bar); border-radius: var(--radius-sm);
    border-left: 2px solid var(--accent);
  }
  .rastertermin .nums { font-weight: 600; margin-right: 4px; }
  .rastertermin .truncate { display: block; }
  .rastertermin .meta { font-size: 10.5px; }
}

/* Aufklappen an Ort und Stelle, statt eines Dialogfensters.
   Ein natives confirm() blockiert die ganze Seite und trägt Chromes eigenen
   Rahmen — das sieht aus wie eine Betrugsmeldung und gehört keinem Design an.
   Hier braucht es zwei bewusste Tipps, ohne dass irgendetwas blockiert. */
.fold-inline > summary {
  list-style: none; cursor: pointer;
  display: inline-flex; align-items: center;
  min-height: 44px; padding: 0 var(--space-sm);
  font-size: 13px; color: var(--muted);
}
.fold-inline > summary::-webkit-details-marker { display: none; }
.fold-inline[open] > summary { color: var(--st-aus-fg); }
/* Erst nach dem Aufklappen bekommt der Knopf die Warnfarbe: vorher ist nichts
   zu warnen, nachher soll unübersehbar sein, was gleich passiert. */
.btn-quiet.danger { color: var(--st-aus-fg); font-weight: 600; }

/* Das Rechtsklick-Menü. Bewusst klein und ohne eigene Farbe: es ist eine
   Abkürzung zu Dingen, die es auch als sichtbaren Knopf gibt. */
.kontextmenue {
  position: absolute; z-index: 40; min-width: 160px;
  padding: var(--space-xs);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-md); box-shadow: 0 4px 16px rgba(60,45,20,.18);
  display: flex; flex-direction: column;
}
.kontextmenue a, .kontextmenue button {
  display: flex; align-items: center; min-height: 40px;
  padding: 0 var(--space-sm); border: 0; background: none;
  font: inherit; font-size: 13px; color: var(--fg); text-align: left;
  text-decoration: none; cursor: pointer; border-radius: var(--radius-sm);
}
.kontextmenue a:hover, .kontextmenue button:hover { background: var(--bar); }
.kontextmenue .titel {
  padding: var(--space-xs) var(--space-sm);
  font-size: 10.5px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ---------- Phase 10: outbox ---------- */
.outbox { list-style: none; margin: 0; padding: 0; font-size: 13px; }
.outbox li { padding: var(--space-xs) 0; border-top: 1px solid currentColor; opacity: .85; }
.outbox li:first-child { border-top: 0; }

/* ---------- Phase 12: second step ---------- */
.qr {
  display: flex; justify-content: center;
  padding: var(--space-lg);
  background: #fffdf9;                 /* QR codes need real white to scan */
  border: 1px solid var(--line); border-radius: var(--radius-md);
}
.qr svg { width: 100%; max-width: 220px; height: auto; }

.codes {
  list-style: none; margin: var(--space-sm) 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-xs);
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 15px; letter-spacing: .04em;
}
.codes li {
  padding: var(--space-sm); text-align: center;
  border: 1px solid currentColor; border-radius: var(--radius-sm);
}

/* ---------- Marke auf der Anmeldeseite ----------
   Das Ass der Marke, als einziges Zeichen über der Anmeldung. Linksbündig wie
   alles andere; 88 px breit, weil der kleine Schriftzug in der Karte darunter zum Fleck wird. */
.anmelde-marke { color: var(--fg); }
.anmelde-marke svg { display: block; width: 88px; height: auto; }

