/* antrag — Commodus BI design language.
 *
 * Source of truth: KC's Figma design system ("Overview Dashboard" frame,
 * extracted 2026-09-03). Every value below comes from that system: the deep
 * navy brand ground, white cards on a canvas page, tinted status pills,
 * Rajdhani Bold for display titles/numbers and Inter for everything else.
 *
 * Flat by construction — no translucency, no blur, no gradient grounds. The
 * only semi-transparent surfaces are modal scrims and the inverse pill on the
 * navy app bar, which are overlays, not glass.
 *
 * Light theme only (field device; the design system is light). Every ground is
 * painted explicitly; `color-scheme: light` keeps the UA from theming controls.
 *
 * This file replaces the 2026-07 stylesheet class-for-class — the same
 * selectors, restyled through the design tokens. No class was renamed.
 */

/* ══ Fonts — self-hosted (GDPR: a German client's field device never calls
   Google at runtime). OFL, see fonts/LICENSE-OFL.txt. Latin + Latin-Ext cover
   the German (ä ö ü ß) and Polish (ł ś ż ó ę ą) glyphs the app renders. ═════ */

@font-face {
  font-family: "Rajdhani";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/static/fonts/rajdhani-700-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Rajdhani";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/static/fonts/rajdhani-700-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Inter ships as one variable file per subset — the same woff2 serves 400 and
   600, so the face is declared once over the whole weight range. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/static/fonts/inter-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/static/fonts/inter-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ══ Tokens ═══════════════════════════════════════════════════════════════ */

:root {
  color-scheme: light;

  /* -- surfaces -- */
  --color-surface-brand: #071632;
  --color-surface-interactive: #071632;
  --color-surface-canvas: #f8fafc;
  --color-surface-default: #ffffff;
  --color-surface-subtle: #dde5f3;
  --color-surface-disabled: #f1f5f9;
  --color-surface-success: #dcfce7;
  --color-surface-warning: #fef3c7;
  --color-surface-danger: #fee2e2;

  /* -- text -- */
  --color-text-primary: #071632;
  --color-text-secondary: #475569;
  --color-text-tertiary: #64748b;
  --color-text-brand: #4368ad;
  --color-text-inverse: #ffffff;
  --color-text-success: #16a900;
  --color-text-warning: #d97706;
  --color-text-danger: #dc2626;

  /* -- borders -- */
  --color-border-default: #e2e8f0;
  --color-border-strong: #cbd5e1;

  /* -- data series (charts; this app has none yet, kept for parity) -- */
  --color-data-series-1: #4368ad;
  --color-data-series-2: #16a900;
  --color-data-series-3: #7c3aed;
  --color-data-series-4: #d97706;
  --color-data-series-5: #0891b2;

  /* -- dimensions -- */
  --dimension-radius-md: 8px;
  --dimension-radius-lg: 12px;
  --dimension-radius-full: 9999px;
  --dimension-space-4: 4px;
  --dimension-space-8: 8px;
  --dimension-space-12: 12px;
  --dimension-space-16: 16px;
  --dimension-space-20: 20px;
  --dimension-space-24: 24px;
  --dimension-space-32: 32px;
  --dimension-size-control-md: 44px;

  --elevation-card: 0 1px 3px rgba(7, 22, 50, 0.10);
  /* Overlay lift for sheets, modals and toasts — the card elevation is too
     quiet to separate a sheet from the page behind it. */
  --elevation-overlay: 0 -2px 16px rgba(7, 22, 50, 0.18);
  --elevation-float: 0 4px 16px rgba(7, 22, 50, 0.18);

  /* -- fonts -- */
  --font-display: "Rajdhani", "Segoe UI", system-ui, sans-serif;
  --font-body: "Inter", "Segoe UI", system-ui, sans-serif;

  /* -- accessible on-tint text (DEVIATION, see .context/DECISIONS.md) --
     The Figma tone colors are drawn as icon/graph colors; as 11-13 px text on
     their own tint they land at ~2.9:1 (success), ~2.9:1 (warning), ~4.0:1
     (danger) and ~4.3:1 (brand on subtle) — all under WCAG AA 4.5:1. These
     darker siblings keep the hue and clear 4.5:1 on the matching tint. */
  --color-text-success-on-tint: #15803d;   /* 4.57:1 on #dcfce7 */
  --color-text-warning-on-tint: #b45309;   /* 4.51:1 on #fef3c7 */
  --color-text-danger-on-tint: #b91c1c;    /* 5.30:1 on #fee2e2 */
  --color-text-brand-on-tint: #2f4f8f;     /* 6.29:1 on #dde5f3 */
  --color-text-series-3-on-tint: #6d28d9;  /* on #ede9fe */
  --color-surface-series-3: #ede9fe;
  /* A faint brand wash for "this came from Monday" and advisory note blocks. */
  --color-surface-brand-faint: #f2f6fc;
  /* The one accent that has to read on the navy chip ground. */
  --color-text-brand-inverse: #a8c4ee;

  /* -- legacy aliases -------------------------------------------------------
     The pre-restyle stylesheet exposed these names; kept so nothing that still
     reads them breaks. Nothing in this file uses them — every rule below reads
     a design token directly. */
  --primary: var(--color-surface-brand);
  --on-primary: var(--color-text-inverse);
  --surface: var(--color-surface-default);
  --surface-variant: var(--color-surface-canvas);
  --on-surface: var(--color-text-primary);
  --on-surface-muted: var(--color-text-secondary);
  --outline: var(--color-border-default);
  --error: var(--color-text-danger-on-tint);
  --success: var(--color-text-success-on-tint);
  --warning: var(--color-text-warning-on-tint);
  --shadow-1: var(--elevation-card);
  --shadow-2: var(--elevation-float);
  --radius: var(--dimension-radius-lg);
  --radius-2: var(--dimension-radius-lg);
  --space-1: var(--dimension-space-4);
  --space-2: var(--dimension-space-8);
  --space-3: var(--dimension-space-16);
  --space-4: var(--dimension-space-24);
  --space-5: var(--dimension-space-32);

  /* Semantic outcome vocabulary (spec ruling 11), expressed as the design
     system's status-badge tones. Green = positive, blue/info = neutral or in
     progress, red = negative. The glyph is NEVER optional — see .sem-glyph. */
  --sem-pos: var(--color-text-success-on-tint);
  --sem-pos-bg: var(--color-surface-success);
  --sem-neu: var(--color-text-brand-on-tint);
  --sem-neu-bg: var(--color-surface-subtle);
  --sem-neg: var(--color-text-danger-on-tint);
  --sem-neg-bg: var(--color-surface-danger);
}

/* ══ Base ═════════════════════════════════════════════════════════════════ */

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 20px;
  color: var(--color-text-primary);
  background: var(--color-surface-canvas);
  -webkit-text-size-adjust: 100%;
  overscroll-behavior: none;
}

[hidden] { display: none !important; }

p { margin: 0 0 var(--dimension-space-8); }

/* Display type — Rajdhani Bold carries every title and every big number.
   Deliberately set on the ELEMENT (specificity 0-0-1) so any component class
   below can restate a size without needing a descendant selector. */
h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: 0.005em;
  color: var(--color-text-primary);
}
h1, h2 { font-size: 28px; line-height: 32px; margin: 0 0 var(--dimension-space-12); }
h3 { font-size: 20px; line-height: 24px; margin: 0 0 var(--dimension-space-8); }
h4 { font-size: 17px; line-height: 22px; margin: 0 0 var(--dimension-space-8); }

a { color: var(--color-text-brand); }

.muted { color: var(--color-text-secondary); }
.error { color: var(--color-text-danger-on-tint); }

button, input, select, textarea { font-family: inherit; }

/* Every interactive surface answers the keyboard. */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--color-text-brand);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* ══ Buttons ══════════════════════════════════════════════════════════════
   Design system: Primary = navy fill / white Inter semibold 14 / min-height 44
   / padding 8-16 / radius 8. Secondary = white, 1 px border-strong, primary
   text. One primary per decision area; supporting actions are secondary. */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--dimension-space-8);
  min-height: var(--dimension-size-control-md);
  padding: var(--dimension-space-8) var(--dimension-space-16);
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  line-height: 20px;
  color: var(--color-text-primary);
  background: var(--color-surface-default);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--dimension-radius-md);
  cursor: pointer;
  text-decoration: none;
}
.btn-secondary {                       /* the explicit name for the same role */
  color: var(--color-text-primary);
  background: var(--color-surface-default);
  border-color: var(--color-border-strong);
}
.btn-primary {
  color: var(--color-text-inverse);
  background: var(--color-surface-interactive);
  border-color: var(--color-surface-interactive);
}
.btn-block { width: 100%; }

.btn-disabled,
.btn:disabled,
.btn[disabled] {
  color: var(--color-text-tertiary);
  background: var(--color-surface-disabled);
  border-color: var(--color-border-default);
  box-shadow: none;
  cursor: not-allowed;
}

/* Icon buttons in the app bar: glyph + a real text label (title= tooltips never
   appear on touch). They sit on the navy ground and inherit its white. */
.icon-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--dimension-space-4);
  min-height: var(--dimension-size-control-md);
  padding: var(--dimension-space-4) var(--dimension-space-8);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1;
  font-weight: 600;
  color: inherit;
  background: transparent;
  border: none;
  border-radius: var(--dimension-radius-md);
  cursor: pointer;
}
a.icon-btn { text-decoration: none; }
.icon-label { font-size: 13px; font-weight: 600; letter-spacing: 0.01em; }

/* ══ Status badges / pills ════════════════════════════════════════════════
   Pill, radius full, padding 5-10, Inter semibold 11, tinted ground + the
   matching darkened tone text. The tone classes (.sem-*) live at the END of
   this file so they win over any component that paints its own ground. */

.badge, .pill, .verbleib-chip, .tab-print-badge, .print-badge,
.monday-chip, .verbleib-board, .step-tag {
  display: inline-flex;
  align-items: center;
  gap: var(--dimension-space-4);
  flex: none;
  padding: 5px 10px;
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  line-height: 14px;
  border-radius: var(--dimension-radius-full);
  white-space: nowrap;
  color: var(--color-text-secondary);            /* neutral tone by default */
  background: var(--color-surface-disabled);
}
.badge-form { color: var(--color-text-brand-on-tint); background: var(--color-surface-subtle); }
.badge-letter { color: var(--color-text-series-3-on-tint); background: var(--color-surface-series-3); }
.badge-guide { color: var(--color-text-success-on-tint); background: var(--color-surface-success); }
.badge-pending { color: var(--color-text-warning-on-tint); background: var(--color-surface-warning); }

.pill-tech { color: var(--color-text-secondary); background: var(--color-surface-disabled); }
.pill-geplant { color: var(--color-text-brand-on-tint); background: var(--color-surface-subtle); }
.pill-erledigt { color: var(--color-text-success-on-tint); background: var(--color-surface-success); }
.pill-abgesagt { color: var(--color-text-danger-on-tint); background: var(--color-surface-danger); }

/* ══ Login ════════════════════════════════════════════════════════════════
   The design system's brand block: the COMMODUS wordmark in Rajdhani over the
   product line, on the navy ground; the PIN itself in a white card; the submit
   button white — a navy primary on a navy ground would vanish. */

.pin-screen {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--dimension-space-24);
  gap: var(--dimension-space-32);
  background: var(--color-surface-brand);
  color: var(--color-text-inverse);
}
.pin-brand { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.pin-wordmark {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 28px;
  line-height: 32px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-inverse);
}
.pin-title {
  margin: 0;
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  line-height: 16px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.62);
}
.pin-form {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--dimension-space-16);
  width: 100%;
  max-width: 320px;
}
.pin-card {
  display: flex;
  flex-direction: column;
  gap: var(--dimension-space-12);
  padding: var(--dimension-space-20);
  background: var(--color-surface-default);
  border-radius: var(--dimension-radius-lg);
  box-shadow: var(--elevation-card);
}
.pin-subtitle {
  margin: 0;
  font-size: 13px;
  font-weight: 600;
  line-height: 20px;
  color: var(--color-text-secondary);
}
.pin-input {
  width: 100%;
  min-height: 52px;
  padding: var(--dimension-space-12);
  font-family: var(--font-display);
  font-size: 28px;
  font-weight: 700;
  letter-spacing: 10px;
  text-indent: 10px;             /* re-centres what letter-spacing pushes left */
  text-align: center;
  color: var(--color-text-primary);
  background: var(--color-surface-default);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--dimension-radius-md);
}
.pin-input:focus {
  outline: 2px solid var(--color-text-brand);
  outline-offset: 0;
  border-color: var(--color-text-brand);
}
.pin-submit {
  width: 100%;
  min-height: var(--dimension-size-control-md);
  padding: var(--dimension-space-8) var(--dimension-space-16);
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  color: var(--color-text-primary);
  background: var(--color-surface-default);
  border: 1px solid var(--color-surface-default);
  border-radius: var(--dimension-radius-md);
  cursor: pointer;
}
.pin-error {
  margin: 0;
  padding: var(--dimension-space-8) var(--dimension-space-12);
  font-size: 13px;
  font-weight: 600;
  color: var(--color-text-danger-on-tint);
  background: var(--color-surface-danger);
  border-radius: var(--dimension-radius-md);
}

/* ══ App shell ════════════════════════════════════════════════════════════ */

.home { min-height: 100vh; }

/* The top app bar keeps the brand ground on this phone app — it is the only
   place the navy appears once the technician is past the login screen. */
.home-header {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--dimension-space-8);
  row-gap: var(--dimension-space-8);
  padding: var(--dimension-space-12) var(--dimension-space-16);
  background: var(--color-surface-brand);
  color: var(--color-text-inverse);
}
/* The bar can carry four things (title, technician, Abmelden, Problem melden).
   On a 390 px phone that left the title ~30 px and it ellipsised to "A…" — so
   the bar WRAPS and the title keeps a readable floor instead. */
.home-header h1 {
  flex: 1 1 auto;
  min-width: 7em;
  margin: 0 auto 0 0;
  font-family: var(--font-display);
  font-size: 22px;
  line-height: 26px;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--color-text-inverse);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.home-header-actions { margin: 0; }

/* K1 (ruling 5): who is logged in — an inverse pill in the app bar. */
.tech-badge {
  flex: none;
  padding: 4px 10px;
  font-size: 11px;
  font-weight: 600;
  line-height: 16px;
  border-radius: var(--dimension-radius-full);
  background: rgba(255, 255, 255, 0.16);
  color: var(--color-text-inverse);
  white-space: nowrap;
}

/* Demo mode's one piece of chrome (spec 2026-09-10). Deliberately the loudest
   thing in the app bar: a technician who mistakes the demo for the real app
   would file an Antrag nobody receives. Red ground + white text carries the
   warning without relying on hue alone — the word DEMO says it too. */
.demo-badge {
  flex: none;
  padding: 4px 8px;
  font-size: 11px;
  font-weight: 700;
  line-height: 16px;
  letter-spacing: 0.08em;
  border-radius: var(--dimension-radius-sm, 4px);
  background: #c8102e;
  color: #fff;
  white-space: nowrap;
}

/* DE · PL — the navigation language, in the app bar and on the login screen
   (spec 2026-09-10, D2). Two small submit buttons that read as one control; the
   current language is the bright one and carries `aria-current`, so the state is
   not colour alone. Deliberately quiet: it is set once per device and then never
   touched again, and it must not compete with the technician's own name. */
.sprache {
  flex: none;
  display: flex;
  align-items: center;
  gap: 2px;
  margin: 0 0 0 auto;
}
.sprache-btn {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--color-text-inverse);
  opacity: 0.55;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  line-height: 16px;
  letter-spacing: 0.04em;
  padding: 4px 4px;
  min-height: 24px;
  cursor: pointer;
}
.sprache-btn.is-active { opacity: 1; text-decoration: underline; }
.sprache-sep { color: var(--color-text-inverse); opacity: 0.4; font-size: 12px; }

/* On the login screen the control sits on the navy brand block, under the
   wordmark, so it inherits the same inverse colours — nothing to override. */
.pin-brand .sprache { margin: 8px 0 0; justify-content: center; }

.home-body {
  padding: var(--dimension-space-16);
  max-width: 860px;
  margin: 0 auto;
}
.home-body h2 { margin: 0 0 var(--dimension-space-12); font-size: 28px; line-height: 32px; }

/* ══ Bottom tab bar ═══════════════════════════════════════════════════════
   White with a top border; the active tab is brand text over a subtle pill
   behind its icon — the design system's active navigation state, on a light
   ground because this bar is not on the navy. */

.tabbar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 40;
  display: flex;
  background: var(--color-surface-default);
  border-top: 1px solid var(--color-border-default);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
.tabbar .tab {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  min-height: 58px;
  padding: var(--dimension-space-8) var(--dimension-space-4) 6px;
  color: var(--color-text-secondary);
  text-decoration: none;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.01em;
}
.tabbar .tab svg {
  padding: 2px 14px;
  border-radius: var(--dimension-radius-full);
  box-sizing: content-box;
}
.tabbar .tab.is-active { color: var(--color-text-brand-on-tint); }
.tabbar .tab.is-active svg { background: var(--color-surface-subtle); }
.tabbar .tab:active { background: var(--color-surface-canvas); }

/* The red open-items badge — a count, so the filled danger red carries it
   (white on #dc2626 is 4.83:1). */
.tab-badge {
  position: absolute;
  top: 4px;
  left: calc(50% + 14px);
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: var(--dimension-radius-full);
  background: var(--color-text-danger);
  color: var(--color-text-inverse);
  font-size: 11px;
  font-weight: 600;
  line-height: 18px;
  text-align: center;
}
.has-tabbar { padding-bottom: calc(70px + env(safe-area-inset-bottom, 0px)); }

/* ══ Cards / panels ═══════════════════════════════════════════════════════
   White, radius 12, card elevation. The step cards, the Kasse cards and the
   note blocks further down are the same object at different densities. */

.step-card {
  background: var(--color-surface-default);
  border: 1px solid var(--color-border-default);
  border-radius: var(--dimension-radius-lg);
  box-shadow: var(--elevation-card);
  padding: var(--dimension-space-20);
  margin-bottom: var(--dimension-space-16);
}
.step-head {
  display: flex;
  align-items: center;
  gap: var(--dimension-space-8);
  margin-bottom: var(--dimension-space-16);
}
.step-num {
  flex: none;
  width: 28px; height: 28px;
  border-radius: var(--dimension-radius-full);
  background: var(--color-surface-subtle);
  color: var(--color-text-brand-on-tint);
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.step-head h2 { font-size: 22px; line-height: 26px; margin: 0; }
.step-tag { margin-left: auto; }

/* step 1 — the picked client, confirmed in the success tone */
.selected-wrap {
  border: 1px solid #bbf7d0;
  background: var(--color-surface-success);
  border-radius: var(--dimension-radius-md);
  padding: var(--dimension-space-12);
}
.selected-wrap h3 {
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  line-height: 20px;
  color: var(--color-text-success-on-tint);
  margin: 0 0 var(--dimension-space-8);
}
.person-chips { display: flex; flex-wrap: wrap; gap: var(--dimension-space-8); }
.person-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--dimension-space-8);
  background: var(--color-surface-default);
  border: 1px solid var(--color-border-default);
  border-radius: var(--dimension-radius-md);
  padding: 6px 6px 6px 12px;
  font-size: 13px;
  font-weight: 600;
  line-height: 18px;
}
.person-chip .sub { font-size: 11px; font-weight: 400; color: var(--color-text-secondary); }
.person-chip .x {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: var(--color-surface-danger);
  color: var(--color-text-danger-on-tint);
  width: 32px; height: 32px;
  border-radius: var(--dimension-radius-full);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}
/* The disc stays 32 px (a 44 px disc inside a chip is a blob); the TOUCH target
   is grown to 44x44 with an invisible extension. Same trick on the two other
   small round controls below. */
.person-chip .x::after,
.hint-dismiss::after,
.chip-undo::after {
  content: "";
  position: absolute;
  inset: -6px;
}
.selected-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--dimension-space-8);
  margin-top: var(--dimension-space-12);
}
.selected-actions .btn { flex: 1 1 auto; }
.selected-note { margin: var(--dimension-space-8) 0 0; font-size: 11px; color: var(--color-text-secondary); }

/* step 2 — kasse-for-person context banner */
.kasse-context {
  background: var(--color-surface-success);
  border-radius: var(--dimension-radius-md);
  padding: var(--dimension-space-8) var(--dimension-space-12);
  margin-bottom: var(--dimension-space-12);
  font-size: 13px;
  color: var(--color-text-success-on-tint);
}
.kasse-context strong { display: block; font-weight: 600; }
.kasse-context span { color: var(--color-text-secondary); font-size: 11px; }

/* ══ Kasse picker ═════════════════════════════════════════════════════════ */

.kasse-search { display: flex; gap: var(--dimension-space-8); margin: 0 0 var(--dimension-space-16); }
.kasse-search input[type="search"] {
  flex: 1;
  min-width: 0;
  min-height: var(--dimension-size-control-md);
  padding: var(--dimension-space-8) var(--dimension-space-12);
  font-size: 16px;          /* ≥16 px: below it mobile browsers zoom on focus */
  color: var(--color-text-primary);
  background: var(--color-surface-default);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--dimension-radius-md);
}
.kasse-results, .kasse-browse { display: flex; flex-direction: column; gap: var(--dimension-space-8); }
.kasse-card {
  background: var(--color-surface-default);
  border: 1px solid var(--color-border-default);
  border-radius: var(--dimension-radius-lg);
  padding: var(--dimension-space-12) var(--dimension-space-16);
  box-shadow: var(--elevation-card);
  display: flex;
  flex-direction: column;
  gap: var(--dimension-space-8);
}
.kasse-card.is-pending { background: var(--color-surface-disabled); box-shadow: none; }
.kasse-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--dimension-space-8);
}
.kasse-name { font-size: 15px; font-weight: 600; line-height: 20px; }
.kasse-start { margin: 0; }
.kasse-pending-note { margin: 0; font-size: 13px; }
.kasse-fuzzy, .kasse-nomatch { margin-top: var(--dimension-space-16); }
.kasse-confirm { margin-bottom: var(--dimension-space-8); width: 100%; }
.kasse-nomatch .kasse-browse { margin-top: var(--dimension-space-12); }

.kasse-browse-all { display: flex; flex-direction: column; gap: var(--dimension-space-20); }
.browse-hint { margin: 0 0 var(--dimension-space-12); font-size: 13px; color: var(--color-text-secondary); }
.kasse-group { display: flex; flex-direction: column; gap: var(--dimension-space-8); }

/* Column-label type from the design system: uppercase 10, .04 em tracking. */
.kasse-group-title, .aktion-title, .verbleib-label, .offen-tag {
  margin: 0;
  font-family: var(--font-body);
  font-size: 10px;
  font-weight: 600;
  line-height: 14px;
  color: var(--color-text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.kasse-nofilter-hit { margin: 0; }
.kasse-llm-suggest { margin-bottom: var(--dimension-space-12); }
.llm-suggestions { display: flex; flex-direction: column; gap: var(--dimension-space-8); }

/* ══ Client picker modal ══════════════════════════════════════════════════ */

body.modal-open { overflow: hidden; }

.client-modal {
  position: fixed;
  inset: 0;
  /* Above the tab bar (40): a full-screen picker that lets the bar show through
     at its foot reads as a half-open screen. Still below sheets (50) and the
     feedback chips (60). */
  z-index: 46;
  background: var(--color-surface-canvas);
  display: flex;
  flex-direction: column;
}
.client-modal-head {
  background: var(--color-surface-brand);
  color: var(--color-text-inverse);
  display: flex;
  align-items: center;
  gap: var(--dimension-space-12);
  padding: var(--dimension-space-12) var(--dimension-space-16);
}
.client-modal-head h2 {
  flex: 1;
  margin: 0;
  font-family: var(--font-display);
  font-size: 22px;
  line-height: 26px;
  font-weight: 700;
  color: var(--color-text-inverse);
}
.client-modal-head .close {
  background: none;
  border: none;
  border-radius: var(--dimension-radius-md);
  color: var(--color-text-inverse);
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
  width: var(--dimension-size-control-md);
  height: var(--dimension-size-control-md);
}
.client-modal-body {
  flex: 1;
  overflow-y: auto;
  padding: var(--dimension-space-16);
  max-width: 860px;
  width: 100%;
  margin: 0 auto;
}

/* Filter chips (technician scope): pill, 44 high, semibold 14; pressed = navy. */
.tech-row { display: flex; flex-wrap: wrap; gap: var(--dimension-space-8); margin-bottom: var(--dimension-space-16); }
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface-default);
  color: var(--color-text-primary);
  border-radius: var(--dimension-radius-full);
  padding: var(--dimension-space-8) var(--dimension-space-16);
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  line-height: 20px;
  cursor: pointer;
  min-height: var(--dimension-size-control-md);
  text-decoration: none;
}
.chip[aria-pressed="true"] {
  background: var(--color-surface-interactive);
  border-color: var(--color-surface-interactive);
  color: var(--color-text-inverse);
}
.chip .cnt {
  background: var(--color-surface-subtle);
  color: var(--color-text-brand-on-tint);
  border-radius: var(--dimension-radius-full);
  font-size: 11px;
  font-weight: 600;
  padding: 1px 7px;
}
.chip[aria-pressed="true"] .cnt { background: rgba(255, 255, 255, 0.22); color: var(--color-text-inverse); }
.tech-scope { margin: 0 0 var(--dimension-space-12); }
.tech-scope .chip { text-decoration: none; }

/* ══ Day pager + Upcoming Work Items ══════════════════════════════════════
   The design system's Upcoming Work Item: a 44×44 tinted box in Rajdhani brand
   text, then the title (semibold 13) over its meta line (11). Here the box
   carries the TIME of the visit — the day is the page, not the row. */

.day-pager { display: flex; align-items: center; gap: var(--dimension-space-8); margin-bottom: var(--dimension-space-12); }
.day-pager .nav {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--dimension-size-control-md);
  height: var(--dimension-size-control-md);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--dimension-radius-md);
  background: var(--color-surface-default);
  font-size: 18px;
  cursor: pointer;
  color: var(--color-text-brand-on-tint);
  text-decoration: none;
}
.day-pager .nav.is-disabled { opacity: 0.35; cursor: default; }
.day-label { flex: 1; text-align: center; }
.day-label strong {
  display: block;
  font-family: var(--font-display);
  font-size: 22px;
  line-height: 26px;
  font-weight: 700;
}
.day-label span { font-size: 11px; color: var(--color-text-secondary); }

.appt-list { display: flex; flex-direction: column; gap: var(--dimension-space-8); touch-action: pan-y; }
.appt {
  display: flex;
  align-items: center;
  gap: var(--dimension-space-12);
  border: 1px solid var(--color-border-default);
  border-radius: var(--dimension-radius-lg);
  background: var(--color-surface-default);
  padding: var(--dimension-space-8) var(--dimension-space-12);
  text-align: left;
  cursor: pointer;
  min-height: 64px;
  width: 100%;
}
.appt:active { background: var(--color-surface-canvas); }
.appt.is-abgesagt { opacity: 0.6; }
.appt time {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--dimension-size-control-md);
  height: var(--dimension-size-control-md);
  border-radius: var(--dimension-radius-md);
  background: var(--color-surface-subtle);
  color: var(--color-text-brand-on-tint);
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.01em;
}
.appt .who { flex: 1; min-width: 0; }
/* R12-03: the name column had no wrapping rule at all, so a long surname ran
   on past its box, under the pill and — while the call control still sat in
   this row — under an opaque button that hid its middle. One line, ellipsed at
   whatever width is left: a name may be shortened, it may not be hidden. */
.appt .who strong {
  display: block;
  font-size: 13px;
  font-weight: 600;
  line-height: 18px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* The meta line MAY wrap: KC's tap-to-call prints the phone number in it, and
   an ellipsis would hide the very thing the line exists to show. The name above
   it is the part that gets long, and it is the part that is ellipsed. */
.appt .who-sub {
  display: block;
  font-size: 11px;
  line-height: 16px;
  color: var(--color-text-secondary);
  overflow-wrap: anywhere;
}
/* R13: one inline-block per segment, each carrying the separator that opens
   it. A wrap can then only break BETWEEN segments, so the `·` always travels
   with the thing it introduces and never ends a line on its own. */
.appt .who-sub .seg { display: inline-block; }
.appt .who-sub .sep { padding: 0 0.35em; }
/* Tap-to-call (KC 2026-09-04): the number IS the control. Vertical padding on
   an inline link does not move the line it sits in, but it IS part of the hit
   region — the platform minimum for a gloved thumb, with no separate button to
   paint over the name beside it. 15 px each side rather than 14: the content
   box of an 11 px inline link is its FONT box (~15 px), not the 16 px
   line-height, so 14 measured 43 px in Chromium at 360 px and 15 measures 45.
   Verified with `getBoundingClientRect`, not derived from the numbers. */
.appt-tel {
  color: var(--color-text-brand);
  text-decoration: underline;
  padding: 15px 6px;
  white-space: nowrap;
}
.appt .tags { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: var(--dimension-space-4); }
.appt-static { cursor: default; }
.appt-static:active { background: var(--color-surface-default); }
.appt-form { margin: 0; }
.appt-form .appt { width: 100%; }

.empty-day {
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--dimension-radius-lg);
  padding: var(--dimension-space-24);
  text-align: center;
  color: var(--color-text-secondary);
  background: var(--color-surface-default);
  font-size: 13px;
}
.swipe-hint { text-align: center; font-size: 11px; color: var(--color-text-tertiary); margin: var(--dimension-space-12) 0 0; }

.name-search {
  margin-top: var(--dimension-space-16);
  border-top: 1px solid var(--color-border-default);
  padding-top: var(--dimension-space-16);
}
.name-search input[type="search"] {
  width: 100%;
  min-height: var(--dimension-size-control-md);
  padding: var(--dimension-space-8) var(--dimension-space-12);
  font-size: 16px;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--dimension-radius-md);
  background: var(--color-surface-default);
  color: var(--color-text-primary);
}
.name-hits { display: flex; flex-direction: column; gap: var(--dimension-space-8); margin-top: var(--dimension-space-8); }
.name-search .lead-search-form { display: flex; gap: var(--dimension-space-8); margin-top: var(--dimension-space-16); }
.name-search .lead-hits {
  list-style: none; padding: 0; margin: var(--dimension-space-8) 0 0;
  display: flex; flex-direction: column; gap: var(--dimension-space-8);
}
.name-search .lead-pick { justify-content: flex-start; }

/* ══ Termine: lead card, quick-action well, sheets ════════════════════════
   Ruling 15 — the quick actions sit in a RECESSED container under the lead's
   name, so the day still reads as a list of visits. The recess is the design
   system's tinted well (surface-subtle). */

.lead-card {
  border: 1px solid var(--color-border-default);
  border-radius: var(--dimension-radius-lg);
  background: var(--color-surface-default);
  box-shadow: var(--elevation-card);
  overflow: hidden;
  margin-bottom: var(--dimension-space-8);
}
.lead-card .appt { border: none; border-radius: 0; box-shadow: none; margin: 0; }
.lead-well {
  display: flex;
  gap: var(--dimension-space-8);
  padding: var(--dimension-space-8) var(--dimension-space-12) var(--dimension-space-12);
  background: var(--color-surface-subtle);
  border-top: 1px solid var(--color-border-default);
}

.aktion { flex: 1; min-width: 0; }
.aktion-btn {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
  min-height: 48px;
  padding: 6px var(--dimension-space-8);
  border: 1px solid var(--color-border-default);
  border-radius: var(--dimension-radius-md);
  background: var(--color-surface-default);
  cursor: pointer;
  list-style: none;
  text-align: center;
}
.aktion-btn::-webkit-details-marker { display: none; }
.aktion-value {
  font-size: 13px;
  font-weight: 600;
  line-height: 18px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.aktion-btn.is-offen { color: var(--color-text-tertiary); background: var(--color-surface-default); }
.aktion-btn.is-offen .aktion-value { font-weight: 600; }
.aktion-btn:active { background: var(--color-surface-canvas); }

/* Bottom sheets: white, top corners 12, overlay lift. An open <details> IS the
   sheet in both worlds (with and without JS). */
.sheet-panel {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 50;
  display: flex;
  flex-direction: column;
  gap: var(--dimension-space-8);
  background: var(--color-surface-default);
  border-radius: var(--dimension-radius-lg) var(--dimension-radius-lg) 0 0;
  box-shadow: var(--elevation-overlay);
  padding: var(--dimension-space-8) var(--dimension-space-16) calc(var(--dimension-space-24) + env(safe-area-inset-bottom, 0px));
  max-width: 560px;
  margin: 0 auto;
  max-height: 80vh;
  overflow-y: auto;
  text-align: left;
}
.sheet-grip {
  width: 36px; height: 4px;
  border-radius: var(--dimension-radius-full);
  background: var(--color-border-strong);
  margin: 0 auto var(--dimension-space-12);
}
.sheet-head {
  margin: 0 0 var(--dimension-space-8);
  font-family: var(--font-display);
  font-size: 20px;
  line-height: 24px;
  font-weight: 700;
}
.sheet-scrim, .verbleib-scrim, .section-preview-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(7, 22, 50, 0.55);
}
.sheet-scrim { z-index: 45; }

.aktion-options { display: flex; flex-direction: column; gap: var(--dimension-space-8); margin: 0; }
.aktion-opt {
  display: flex;
  align-items: center;
  gap: var(--dimension-space-8);
  /* The design system's option rows are 44 high; the field app keeps 48 —
     these are tapped with gloves on, in a customer's hallway. */
  min-height: 48px;
  padding: 0 var(--dimension-space-12);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--dimension-radius-md);
  background: var(--color-surface-default);
  color: var(--color-text-primary);
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  text-align: left;
}
.aktion-opt.is-current { outline: 2px solid var(--color-text-brand); outline-offset: -2px; }

.aktion-confirm-step { display: flex; flex-direction: column; gap: var(--dimension-space-8); }
.aktion-confirm-step p { margin: 0; font-size: 14px; font-weight: 600; }
.aktion-abbrechen {
  min-height: var(--dimension-size-control-md);
  background: none;
  border: none;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  color: var(--color-text-secondary);
  cursor: pointer;
  text-decoration: none;
  text-align: center;
}
.aktion-confirm { display: flex; flex-direction: column; gap: var(--dimension-space-16); }
.aktion-confirm-line { display: flex; align-items: center; gap: var(--dimension-space-8); margin: 0; }
.aktion-arrow { color: var(--color-text-tertiary); font-weight: 700; }
.aktion-confirm-actions { margin: 0; }

/* Ruling 10 — the lead name is the menu trigger, not a link to a screen. */
.lead-menu { flex: 1; min-width: 0; }
.lead-menu > summary { list-style: none; cursor: pointer; }
.lead-menu > summary::-webkit-details-marker { display: none; }
.menu-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--dimension-space-8);
  min-height: var(--dimension-size-control-md);
  padding: 0 var(--dimension-space-12);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--dimension-radius-md);
  background: var(--color-surface-default);
  font-size: 14px;
  font-weight: 600;
  color: var(--color-text-primary);
  text-decoration: none;
}
.menu-item.is-disabled {
  color: var(--color-text-tertiary);
  background: var(--color-surface-disabled);
  border-color: var(--color-border-default);
  cursor: default;
}
.menu-item em {
  font-style: normal;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-tertiary);
}

/* ══ Feedback chips (ruling 14) ═══════════════════════════════════════════
   The design system's dark chip: navy ground, white text, radius 8, lift.
   Top-anchored, above everything, because it reports what just happened. */

.chip-stack {
  position: fixed;
  top: calc(var(--dimension-space-8) + env(safe-area-inset-top, 0px));
  left: var(--dimension-space-12); right: var(--dimension-space-12);
  z-index: 60;
  display: flex;
  flex-direction: column;
  gap: var(--dimension-space-8);
  align-items: center;
  pointer-events: none;
}
/* KC 2026-09-04: the dark navy chip said a delivery, a warning and a refusal
   in one voice. Ruling 11 — colour AND glyph, never colour alone — now governs
   the chip itself. The three tints below carry the on-tint text tokens, which
   exist because they were measured against exactly these grounds (≥ 4.5:1, see
   DECISIONS 2026-08-30); the glyph comes from the tone in chips.js. */
.chip-toast {
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: var(--dimension-space-12);
  max-width: 560px;
  width: 100%;
  padding: var(--dimension-space-12) var(--dimension-space-16);
  border-radius: var(--dimension-radius-md);
  border: 1px solid currentColor;
  font-size: 13px;
  font-weight: 600;
  line-height: 18px;
  box-shadow: var(--elevation-float);
}
.chip-toast.chip-success {
  background: var(--color-surface-success);
  color: var(--color-text-success-on-tint);
}
.chip-toast.chip-warning {
  background: var(--color-surface-warning);
  color: var(--color-text-warning-on-tint);
}
.chip-toast.chip-danger {
  background: var(--color-surface-danger);
  color: var(--color-text-danger-on-tint);
}
.chip-text { flex: 1; min-width: 0; }
.chip-undo {
  position: relative;
  flex: none;
  min-height: 36px;
  padding: 0 var(--dimension-space-8);
  background: none;
  border: none;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  color: inherit;
  text-decoration: underline;
  cursor: pointer;
}
.chip-undo[disabled] { opacity: 0.5; cursor: default; }
a.chip-undo { text-decoration: underline; align-self: center; }
/* R13-01: every chip closes by hand. The lane used to have exactly one way out
   — the countdown — so a chip whose countdown had stopped sat over the header
   until the technician navigated away. The glyph stays small (a 44 px control
   inside a 44 px chip is a blob); the TOUCH target is the full platform
   minimum, grown around it and invisible. */
.chip-close {
  position: relative;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  min-height: 24px;
  padding: 0;
  background: none;
  border: none;
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1;
  color: inherit;
  opacity: 0.75;
  cursor: pointer;
}
.chip-close::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 44px;
  height: 44px;
  transform: translate(-50%, -50%);
}
/* A "written" chip reports a DELIVERY, not an action the technician can revise:
   its tone is success like any other completed thing, and the heavier edge is
   what says "this one is about the office, not about you".

   R20-09: the R8 chip (`kind='rekl_status'`, K5c) is the ONE chip the
   technician did not trigger at all — it is the office's own answer about her
   close — and it was the only chip with no rule here. Two of its seven labels
   are success-toned (Akzeptiert, Autoakzeptiert), which is exactly the case
   this edge disambiguates: without it a success-toned, undo-less chip is
   indistinguishable from the delivery chip. It gets the selector rather than
   the KIND: `chips.js` keys its seen-ledger on `kind|id`, and this chip names
   the same feld_status row as the close and delivery chips, so a shared kind
   would drop whichever arrived second (R16-03, and R20-04 next door). */
.chip-toast.chip-written,
.chip-toast.chip-rekl_status {
  border-left-width: 4px;
  padding-left: var(--dimension-space-12);
}
@keyframes chip-in {
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: none; }
}
/* One chip at a time (KC 2026-09-04): 200 ms in, 200 ms out, then the next. */
.chip-toast.chip-anim { animation: chip-in 200ms ease-out; }
.chip-toast.chip-out { opacity: 0; transition: opacity 200ms ease-in; }
@media (prefers-reduced-motion: reduce) {
  .chip-toast.chip-anim { animation: none; }
  .chip-toast.chip-out { transition: none; }
}

/* The reload-stash toast is the same dark chip, bottom-anchored. */
.stash-toast {
  position: fixed;
  left: 50%;
  bottom: var(--dimension-space-24);
  transform: translateX(-50%);
  max-width: 90%;
  padding: var(--dimension-space-12) var(--dimension-space-16);
  background: var(--color-surface-brand);
  color: var(--color-text-inverse);
  border-radius: var(--dimension-radius-md);
  box-shadow: var(--elevation-float);
  font-size: 13px;
  font-weight: 600;
  z-index: 1000;
  transition: opacity 0.4s ease;
}
.stash-toast--out { opacity: 0; }

/* ══ "Von gestern offen" batch (K3, ruling 6) ═════════════════════════════ */

.offen-sheet {
  margin: 0 0 var(--dimension-space-16);
  border: 1px solid var(--color-border-default);
  border-radius: var(--dimension-radius-lg);
  background: var(--color-surface-default);
  box-shadow: var(--elevation-card);
  overflow: hidden;
}
.offen-head {
  display: flex; flex-direction: column; gap: 2px;
  padding: var(--dimension-space-16);
  background: var(--color-surface-subtle);
  cursor: pointer;
  list-style: none;
}
.offen-head::-webkit-details-marker { display: none; }
.offen-head strong { font-family: var(--font-display); font-size: 20px; line-height: 24px; font-weight: 700; }
.offen-head .muted { font-weight: 400; font-size: 13px; }
.offen-panel { padding: 0 var(--dimension-space-16) var(--dimension-space-16); }
.offen-tag { margin: var(--dimension-space-16) 0 var(--dimension-space-4); }
.offen-row {
  display: flex; flex-direction: column; gap: var(--dimension-space-8);
  padding: var(--dimension-space-12) 0;
  border-top: 1px solid var(--color-border-default);
}
.offen-row.is-done { opacity: 0.45; }
.offen-who { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--dimension-space-8); }
.offen-who time {
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: 16px;
  font-weight: 700;
  color: var(--color-text-brand-on-tint);
}
.offen-who strong { font-size: 13px; font-weight: 600; }
.offen-who .muted { font-size: 11px; }
.offen-actions { display: flex; flex-wrap: wrap; gap: var(--dimension-space-8); }
.offen-actions .aktion-opt {
  flex: 1 1 30%;
  /* R2-05: wide enough for the longest label ("Überspringen") at this size.
     Setting `overflow-wrap` to *anywhere* had ALSO dropped each item's min-content
     width to a single character, which is how flexbox kept three buttons on one
     390 px row and then broke the words themselves: "Abgesa/gt",
     "Überspringe/n". With a real min-width the third button drops to its own
     row instead — a wrapped ROW is readable, a wrapped WORD is not. */
  min-width: 108px;
  justify-content: center;
  /* ADV-16: at 390 px "Überspringen" measured 115 px of text in a 95 px box and
     was clipped in every row. The label wraps rather than being cut off — a
     control whose name you cannot read is not a control. */
  white-space: normal;
  overflow-wrap: normal;
  hyphens: manual;
  text-align: center;
  padding: var(--dimension-space-8);
  line-height: 18px;
}
/* The two widths the technicians actually hold (390 px = iPhone 14/15,
   360 px = most Androids). One notch smaller so the label still fits its box
   when the row has to break into two lines. */
@media (max-width: 390px) {
  .offen-actions .aktion-opt { font-size: 13px; padding: var(--dimension-space-8) var(--dimension-space-4); }
}
.offen-form { display: contents; }
.offen-skip { background: var(--color-surface-default); }
.offen-spaeter { margin: 0; }
.offen-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--dimension-space-8);
  margin-top: var(--dimension-space-16);
}

/* ══ Guide page ═══════════════════════════════════════════════════════════ */

.guide-content h1, .guide-content h2 {
  color: var(--color-text-primary);
  font-size: 20px;
  line-height: 24px;
  margin: var(--dimension-space-16) 0 var(--dimension-space-8);
}
.guide-content h3 { font-size: 17px; line-height: 22px; }
.guide-content ul, .guide-content ol { padding-left: var(--dimension-space-20); }
.guide-content li { margin: var(--dimension-space-4) 0; }
.guide-content code {
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: 0.92em;
  background: var(--color-surface-disabled);
  color: var(--color-text-primary);
  padding: 1px 4px;
  border-radius: 4px;
  overflow-wrap: anywhere;
}
.guide-source { margin-top: var(--dimension-space-24); }

/* ══ Wizard: fields and sections ══════════════════════════════════════════ */

.wizard-progress {
  margin: 0 0 var(--dimension-space-4);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-secondary);
}
.wizard-form { display: flex; flex-direction: column; gap: var(--dimension-space-20); }
.section-intro { margin: 0 0 var(--dimension-space-16); font-size: 13px; }
.pflicht-legend { margin: 0 0 var(--dimension-space-16); font-size: 11px; }

.field { display: flex; flex-direction: column; gap: var(--dimension-space-8); }
.field > label { font-weight: 600; font-size: 13px; line-height: 18px; color: var(--color-text-primary); }
.field .req { color: var(--color-text-danger-on-tint); }
.field input[type="text"], .field input[type="tel"], .field input[type="email"],
.field select, .field textarea {
  width: 100%;
  min-height: var(--dimension-size-control-md);
  padding: var(--dimension-space-8) var(--dimension-space-12);
  /* 16 px, not the design system's 14: below 16 px mobile browsers zoom the
     page on focus, which throws a half-filled form off screen. */
  font-size: 16px;
  line-height: 22px;
  color: var(--color-text-primary);
  background: var(--color-surface-default);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--dimension-radius-md);
}
.field input:focus, .field select:focus, .field textarea:focus {
  outline: 2px solid var(--color-text-brand);
  outline-offset: 0;
  border-color: var(--color-text-brand);
}
.field textarea { resize: vertical; min-height: 96px; }
.field-hint { margin: 0; font-size: 11px; line-height: 16px; }
.radio-group, .check-group { display: flex; flex-direction: column; gap: var(--dimension-space-8); }
.opt {
  display: flex;
  align-items: center;
  gap: var(--dimension-space-12);
  min-height: var(--dimension-size-control-md);
  padding: 0 var(--dimension-space-12);
  font-size: 14px;
  font-weight: 400;
  background: var(--color-surface-default);
  border: 1px solid var(--color-border-default);
  border-radius: var(--dimension-radius-md);
  cursor: pointer;
}
.opt input { width: 20px; height: 20px; flex: none; accent-color: var(--color-surface-interactive); }
.opt-hint { margin: 0 0 var(--dimension-space-4) 40px; font-size: 11px; line-height: 16px; }
.field-finding { margin: 0; font-size: 13px; font-weight: 600; }
.field-finding.error { color: var(--color-text-danger-on-tint); }
.field-finding.warn { color: var(--color-text-warning-on-tint); }
.field-finding .fix { display: block; font-weight: 400; color: var(--color-text-secondary); }

.coresident-rows { display: flex; flex-direction: column; gap: var(--dimension-space-16); }
.coresident-row {
  display: flex; flex-direction: column; gap: var(--dimension-space-16);
  padding: var(--dimension-space-16);
  background: var(--color-surface-default);
  border: 1px solid var(--color-border-default);
  border-radius: var(--dimension-radius-lg);
  box-shadow: var(--elevation-card);
}
.coresident-row > legend {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 17px;
  padding: 0 var(--dimension-space-8);
}
.coresident-rows.household-muted { opacity: 0.55; }
.coresident-rows.household-active { opacity: 1; }
.btn-add-row, .btn-remove-row { align-self: flex-start; }
.btn-remove-row { font-size: 13px; }

.field.subordinate {
  margin-left: var(--dimension-space-12);
  padding-left: var(--dimension-space-12);
  border-left: 2px solid var(--color-border-strong);
}
.field.subordinate.gate-off { opacity: 0.55; }

.monday-chip {
  color: var(--color-text-brand-on-tint);
  background: var(--color-surface-subtle);
  margin-left: var(--dimension-space-4);
  vertical-align: middle;
}
/* Specific enough to beat `.field input[type="text"]` without !important. */
.monday-prefilled,
.field input.monday-prefilled,
.field select.monday-prefilled {
  border-color: var(--color-text-brand);
  background: var(--color-surface-brand-faint);
}
.field-note.not-printed {
  margin: var(--dimension-space-4) 0 0;
  font-size: 11px;
  font-style: italic;
}

/* Note blocks — one white card with a tone rail on the left. */
.prefill-checklist, .hand-ticks, .kassen-hinweis, .stacking-summary, .stacking-prompt {
  margin: var(--dimension-space-16) 0;
  padding: var(--dimension-space-16);
  background: var(--color-surface-default);
  border: 1px solid var(--color-border-default);
  border-left: 4px solid var(--color-text-brand);
  border-radius: var(--dimension-radius-lg);
  box-shadow: var(--elevation-card);
}
.prefill-checklist p, .hand-ticks > p, .stacking-summary p, .stacking-prompt p {
  margin: 0 0 var(--dimension-space-8);
}
.prefill-checklist ul, .hand-ticks ul { margin: 0; padding-left: var(--dimension-space-20); }
.prefill-checklist li, .hand-ticks li { margin: var(--dimension-space-4) 0; }
.cap-note.warn { color: var(--color-text-warning-on-tint); font-weight: 600; }

/* Demo mode only (ANTRAG_DEMO=1): the one line saying this wizard was seeded
   from a test fixture rather than typed for a client. Deliberately loud — a
   demo screen that looks exactly like a real intake is how synthetic data ends
   up believed. */
.demo-hinweis {
  margin: var(--dimension-space-16) 0;
  padding: var(--dimension-space-12) var(--dimension-space-16);
  border: 1px dashed var(--color-border-default);
  border-radius: var(--dimension-radius-lg);
  background: var(--color-surface-default);
  color: var(--color-text-secondary, inherit);
  font-weight: 600;
}

.findings-summary, .overflow-banner {
  padding: var(--dimension-space-16);
  margin: 0 0 var(--dimension-space-16);
  color: var(--color-text-danger-on-tint);
  background: var(--color-surface-danger);
  border: 1px solid #fecaca;
  border-radius: var(--dimension-radius-lg);
}
.overflow-banner { font-weight: 600; }
.findings-summary p { margin: 0 0 var(--dimension-space-8); font-weight: 600; }
.findings-summary ul { margin: 0; padding-left: var(--dimension-space-20); }
.findings-summary li { margin: var(--dimension-space-4) 0; }
.findings-summary a {
  display: inline-block;
  padding: var(--dimension-space-8) 0;
  color: var(--color-text-danger-on-tint);
}

.render-warnings {
  color: var(--color-text-warning-on-tint);
  background: var(--color-surface-warning);
  border: 1px solid #fde68a;
  border-radius: var(--dimension-radius-lg);
  padding: var(--dimension-space-12) var(--dimension-space-16);
  margin: var(--dimension-space-16) 0;
}
.render-warnings ul { margin: var(--dimension-space-4) 0 0; padding-left: var(--dimension-space-20); }
.render-warning.warn { color: var(--color-text-warning-on-tint); }
.fallback-note.warn {
  margin: 0 0 var(--dimension-space-12);
  font-size: 13px;
  font-weight: 600;
  color: var(--color-text-warning-on-tint);
}

.overflow-meter { font-size: 13px; font-weight: 600; padding: var(--dimension-space-8) 0; }
.overflow-meter.ok { color: var(--color-text-success-on-tint); }
.overflow-meter.over { color: var(--color-text-warning-on-tint); }

.wizard-nav { display: flex; justify-content: space-between; gap: var(--dimension-space-12); }
.wizard-nav .btn { flex: 1; }

.switch-kasse { margin-top: var(--dimension-space-32); }
.switch-kasse summary {
  cursor: pointer;
  color: var(--color-text-secondary);
  font-size: 13px;
  font-weight: 600;
  min-height: var(--dimension-size-control-md);
  display: flex;
  align-items: center;
}
.switch-form { display: flex; gap: var(--dimension-space-8); margin-top: var(--dimension-space-8); }
.switch-form select {
  flex: 1;
  min-height: var(--dimension-size-control-md);
  padding: var(--dimension-space-8) var(--dimension-space-12);
  font-size: 16px;
  color: var(--color-text-primary);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--dimension-radius-md);
  background: var(--color-surface-default);
}

/* Begründungs-Assistent — the checkmark card that writes the prose. */
.begruendung-assist {
  display: flex;
  flex-direction: column;
  gap: var(--dimension-space-16);
  padding: var(--dimension-space-16);
  background: var(--color-surface-subtle);
  border: 1px solid var(--color-border-default);
  border-radius: var(--dimension-radius-lg);
}
.begruendung-assist .opt { background: var(--color-surface-default); }
.compose-status { margin: 0; font-size: 13px; font-weight: 600; }
.compose-status.ok { color: var(--color-text-success-on-tint); }
.compose-status.warn { color: var(--color-text-warning-on-tint); }
.compose-status.error { color: var(--color-text-danger-on-tint); }
.draft-actions { display: flex; flex-wrap: wrap; gap: var(--dimension-space-8); }
.draft-actions .btn { flex: 1 1 auto; }
.draft-assist { display: flex; flex-direction: column; gap: var(--dimension-space-8); }
.draft-assist > label { font-weight: 600; font-size: 13px; line-height: 18px; }
.draft-assist textarea {
  width: 100%;
  min-height: 96px;
  padding: var(--dimension-space-8) var(--dimension-space-12);
  font-size: 16px;
  line-height: 22px;
  color: var(--color-text-primary);
  background: var(--color-surface-default);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--dimension-radius-md);
  resize: vertical;
}
.draft-status, .draft-hint { margin: 0; font-size: 11px; line-height: 16px; }
.voice-capture { display: flex; flex-wrap: wrap; align-items: center; gap: var(--dimension-space-8); }
.voice-status, .voice-hint { margin: 0; flex: 1 1 100%; font-size: 11px; line-height: 16px; }
.record-dot {
  width: 10px; height: 10px;
  border-radius: var(--dimension-radius-full);
  background: var(--color-text-danger);
  flex: none;
}

/* ══ Review, packets and print ════════════════════════════════════════════ */

.packet-tabs { display: flex; flex-wrap: wrap; gap: var(--dimension-space-8); margin: var(--dimension-space-16) 0; }
.packet-tab-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--dimension-space-8);
  min-height: var(--dimension-size-control-md);
  padding: var(--dimension-space-8) var(--dimension-space-16);
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  color: var(--color-text-primary);
  background: var(--color-surface-default);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--dimension-radius-full);
  cursor: pointer;
}
.packet-tab-btn.active {
  background: var(--color-surface-interactive);
  color: var(--color-text-inverse);
  border-color: var(--color-surface-interactive);
}
.packet-tab-btn.active .muted { color: rgba(255, 255, 255, 0.72); }
.packet-title { font-size: 22px; line-height: 26px; margin: var(--dimension-space-16) 0 var(--dimension-space-8); }

.print-flow { margin-top: var(--dimension-space-20); }
.print-status { margin: 0 0 var(--dimension-space-8); }
.tab-print-badge.printed, .print-badge.printed {
  color: var(--color-text-success-on-tint);
  background: var(--color-surface-success);
}
.tab-print-badge.unprinted, .print-badge.unprinted {
  color: var(--color-text-warning-on-tint);
  background: var(--color-surface-warning);
}
.print-banner { font-size: 13px; margin: var(--dimension-space-12) 0; }
.print-disabled-reason { margin-top: var(--dimension-space-4); font-size: 13px; }

.pdf-preview-pages { display: flex; flex-direction: column; gap: var(--dimension-space-16); }
.pdf-page {
  width: 100%;
  height: auto;
  border: 1px solid var(--color-border-default);
  border-radius: var(--dimension-radius-lg);
  box-shadow: var(--elevation-card);
  background: var(--color-surface-default);
}
.preview-pdf-link { margin: var(--dimension-space-8) 0; }
.preview-pdf-link a, .guide-source a {
  display: inline-flex;
  align-items: center;
  min-height: var(--dimension-size-control-md);
  font-weight: 600;
}

.review-findings {
  list-style: none; padding: 0; margin: 0;
  display: flex; flex-direction: column; gap: var(--dimension-space-8);
}
.review-finding {
  padding: var(--dimension-space-12);
  background: var(--color-surface-default);
  border: 1px solid var(--color-border-default);
  border-left: 4px solid var(--color-text-warning);
  border-radius: var(--dimension-radius-lg);
  box-shadow: var(--elevation-card);
  font-size: 13px;
}
.review-finding.error { border-left-color: var(--color-text-danger); }
.review-finding a {
  display: block;
  font-weight: 600;
  color: var(--color-text-primary);
  text-decoration: none;
  min-height: 28px;
  padding: 8px 0;
}
.review-finding .fix { display: block; font-size: 11px; margin-top: var(--dimension-space-4); }
.review-complete {
  color: var(--color-text-success-on-tint);
  background: var(--color-surface-success);
  border-radius: var(--dimension-radius-md);
  padding: var(--dimension-space-12);
  font-weight: 600;
}
.print-flow-placeholder { margin-top: var(--dimension-space-32); }

.completeness-hints {
  margin: var(--dimension-space-16) 0;
  padding: var(--dimension-space-16);
  background: var(--color-surface-brand-faint);
  border: 1px solid var(--color-border-default);
  border-radius: var(--dimension-radius-lg);
}
.completeness-hints h3 { margin: 0 0 var(--dimension-space-4); font-size: 20px; }
.hint-list { list-style: none; margin: var(--dimension-space-8) 0 0; padding: 0; }
.hint {
  display: flex; align-items: flex-start; gap: var(--dimension-space-8);
  padding: var(--dimension-space-8) 0;
  border-top: 1px solid var(--color-border-default);
  font-size: 13px;
}
.hint-text { flex: 1; }
.hint-dismiss {
  position: relative;
  flex: none;
  width: 32px; height: 32px;
  border: none;
  background: var(--color-surface-disabled);
  color: var(--color-text-secondary);
  border-radius: var(--dimension-radius-full);
  font-size: 16px;
  cursor: pointer;
}

.packet-prose { margin: var(--dimension-space-16) 0; }
.packet-prose .field {
  display: flex; flex-direction: column; gap: var(--dimension-space-4);
  margin: var(--dimension-space-16) 0;
}
.packet-prose .vorlage-btn, .packet-prose .packet-draft-btn { margin-top: var(--dimension-space-8); }
.packet-prose-form { display: flex; flex-direction: column; gap: var(--dimension-space-8); }

.draft-choice {
  display: flex;
  gap: var(--dimension-space-8);
  flex-wrap: wrap;
  margin-top: var(--dimension-space-8);
}

.close-flow { margin-top: var(--dimension-space-32); }
.close-disabled-reason { margin-top: var(--dimension-space-8); }
.close-disabled-reason p { margin: 0 0 var(--dimension-space-8); }
.close-hint.warn { color: var(--color-text-warning-on-tint); font-weight: 600; margin: 0 0 var(--dimension-space-8); }
.close-actions { display: flex; flex-wrap: wrap; gap: var(--dimension-space-8); margin-top: var(--dimension-space-16); }

.claim-refs {
  list-style: none; padding: 0; margin: var(--dimension-space-16) 0 0;
  display: flex; flex-direction: column; gap: var(--dimension-space-8);
}
.claim-ref {
  display: flex; flex-direction: column; gap: 2px;
  padding: var(--dimension-space-12);
  background: var(--color-surface-default);
  border: 1px solid var(--color-border-default);
  border-radius: var(--dimension-radius-lg);
  box-shadow: var(--elevation-card);
  font-size: 13px;
}
.claim-id { font-size: 11px; overflow-wrap: anywhere; }

.reprint-list {
  list-style: none; padding: 0; margin: var(--dimension-space-16) 0 0;
  display: flex; flex-direction: column; gap: var(--dimension-space-8);
}
.reprint-item {
  display: flex;
  align-items: center;
  gap: var(--dimension-space-12);
  padding: var(--dimension-space-12);
  background: var(--color-surface-default);
  border: 1px solid var(--color-border-default);
  border-radius: var(--dimension-radius-lg);
  box-shadow: var(--elevation-card);
}
.reprint-meta { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.reprint-person { overflow-wrap: anywhere; font-size: 13px; font-weight: 600; }
.reprint-date { font-size: 11px; }
.reprint-action { flex: none; margin-left: auto; white-space: nowrap; }

/* ══ In-wizard Vorschau sheet ═════════════════════════════════════════════ */

.section-preview-toggle { white-space: nowrap; }
.section-preview-toggle .icon-label { font-size: 13px; }

/* While the sheet is open the app bar stays ABOVE it — the same toggle opens
   and closes the preview, so it has to keep receiving taps. */
body.preview-open { overflow: hidden; }
body.preview-open .home-header { position: relative; z-index: 45; }

.section-preview-backdrop { z-index: 40; }
.section-preview-panel {
  position: fixed;
  z-index: 41;
  left: 0;
  right: 0;
  bottom: 0;
  top: var(--preview-top, 112px);
  display: flex;
  flex-direction: column;
  background: var(--color-surface-canvas);
  border-radius: var(--dimension-radius-lg) var(--dimension-radius-lg) 0 0;
  box-shadow: var(--elevation-overlay);
  overflow: hidden;
}
.section-preview-head {
  display: flex;
  align-items: center;
  gap: var(--dimension-space-12);
  padding: var(--dimension-space-12) var(--dimension-space-16);
  background: var(--color-surface-brand);
  color: var(--color-text-inverse);
  border-radius: var(--dimension-radius-lg) var(--dimension-radius-lg) 0 0;
}
.section-preview-head h2 {
  flex: 1; margin: 0;
  font-family: var(--font-display);
  font-size: 20px;
  line-height: 24px;
  font-weight: 700;
  color: var(--color-text-inverse);
}
.section-preview-close {
  display: inline-flex;
  align-items: center;
  gap: var(--dimension-space-4);
  min-height: var(--dimension-size-control-md);
  padding: 0 var(--dimension-space-8);
  font-size: 18px;
  line-height: 1;
  color: inherit;
  background: none;
  border: none;
  border-radius: var(--dimension-radius-md);
  cursor: pointer;
}
.section-preview-close .icon-label { font-size: 13px; font-weight: 600; }
.section-preview-body {
  flex: 1;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  display: flex;
  flex-direction: column;
  gap: var(--dimension-space-16);
  padding: var(--dimension-space-16);
  max-width: 860px;
  width: 100%;
  margin: 0 auto;
}
.section-preview-hint { margin: 0; font-size: 13px; }
.section-preview-pages { display: flex; flex-direction: column; gap: var(--dimension-space-16); }

/* The "Problem melden" control pwa.js mounts into the app bar. */
.report-btn { white-space: nowrap; }
.report-btn .icon-label { font-size: 13px; }

/* ══ Antrag-Verbleib ══════════════════════════════════════════════════════ */

.verbleib-flow { margin-top: var(--dimension-space-20); }
.verbleib-card {
  background: var(--color-surface-default);
  border: 1px solid var(--color-border-default);
  border-radius: var(--dimension-radius-lg);
  box-shadow: var(--elevation-card);
  padding: var(--dimension-space-20);
  display: flex;
  flex-direction: column;
  gap: var(--dimension-space-16);
  max-width: 560px;
}
.verbleib-block {
  display: flex;
  align-items: center;
  gap: var(--dimension-space-12);
  background: var(--color-surface-default);
  border: 1px solid var(--color-border-default);
  border-radius: var(--dimension-radius-lg);
  padding: var(--dimension-space-12);
  max-width: 560px;
}
.verbleib-text { flex: 1; display: flex; flex-direction: column; gap: var(--dimension-space-4); }
.verbleib-chip { align-self: flex-start; }
/* R7-01/R7-02: the sentence a refused Verbleib button answers with, right
   above the chip that shows what the row actually holds. */
.verbleib-hinweis.warn {
  margin: var(--dimension-space-12) 0 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--color-text-warning-on-tint);
}
.verbleib-chip.ok { color: var(--color-text-success-on-tint); background: var(--color-surface-success); }
.verbleib-chip.queued { color: var(--color-text-warning-on-tint); background: var(--color-surface-warning); }
.verbleib-chip.office { color: var(--color-text-brand-on-tint); background: var(--color-surface-subtle); }
.verbleib-chip.offen { color: var(--color-text-secondary); background: var(--color-surface-disabled); }
.verbleib-aendern {
  background: none;
  border: none;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  color: var(--color-text-brand);
  text-decoration: none;
  min-height: var(--dimension-size-control-md);
  display: inline-flex;
  align-items: center;
  cursor: pointer;
}

.verbleib-frage h3 { font-size: 22px; line-height: 26px; margin: 0 0 var(--dimension-space-4); }
.verbleib-options { display: flex; flex-direction: column; gap: var(--dimension-space-8); margin-top: var(--dimension-space-8); }
.verbleib-opt {
  display: flex;
  align-items: center;
  gap: var(--dimension-space-12);
  min-height: 64px;
  padding: var(--dimension-space-8) var(--dimension-space-12);
  background: var(--color-surface-default);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--dimension-radius-md);
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  color: var(--color-text-brand);
}
.verbleib-opt svg { flex: none; }
/* R5-03: the four answers carry the SAME glyph and semantic border as the
   day-list well (rulings 11/12), in the 24 px slot the two hand-drawn icons
   used to occupy. */
.verbleib-opt .sem-glyph {
  flex: none;
  width: 24px;
  margin-right: 0;
  font-size: 18px;
  line-height: 24px;
  text-align: center;
}
.verbleib-opt.sem-pos { border-color: #bbf7d0; }
.verbleib-opt.sem-neu { border-color: #c3d3ea; }
.verbleib-opt.sem-neg { border-color: #fecaca; }
.verbleib-opt.primary .sem-glyph { color: var(--color-text-inverse); }
.verbleib-opt-text { display: flex; flex-direction: column; gap: 2px; }
.verbleib-opt-text strong { font-size: 14px; font-weight: 600; color: var(--color-text-primary); }
.verbleib-opt-text span { font-size: 11px; line-height: 16px; color: var(--color-text-secondary); }
.verbleib-opt.primary {
  background: var(--color-surface-interactive);
  border-color: var(--color-surface-interactive);
  color: var(--color-text-inverse);
}
.verbleib-opt.primary .verbleib-opt-text strong { color: var(--color-text-inverse); }
.verbleib-opt.primary .verbleib-opt-text span { color: rgba(255, 255, 255, 0.75); }
.verbleib-spaeter {
  min-height: var(--dimension-size-control-md);
  background: none;
  border: none;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  color: var(--color-text-secondary);
  cursor: pointer;
}

.verbleib-scrim { z-index: 45; }
.verbleib-sheet {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 50;
  background: var(--color-surface-default);
  border-radius: var(--dimension-radius-lg) var(--dimension-radius-lg) 0 0;
  box-shadow: var(--elevation-overlay);
  padding: var(--dimension-space-8) var(--dimension-space-16) var(--dimension-space-32);
  max-width: 560px;
  margin: 0 auto;
}
.verbleib-grip {
  width: 36px; height: 4px;
  border-radius: var(--dimension-radius-full);
  background: var(--color-border-strong);
  margin: 0 auto var(--dimension-space-16);
}
.verbleib-inline {
  margin-top: var(--dimension-space-16);
  background: var(--color-surface-default);
  border: 1px solid var(--color-border-default);
  border-radius: var(--dimension-radius-lg);
  box-shadow: var(--elevation-card);
  padding: var(--dimension-space-20);
  max-width: 560px;
}

.verbleib-confirm { margin: 0; }
.verbleib-busy {
  display: flex;
  align-items: center;
  gap: var(--dimension-space-12);
  background: var(--color-surface-subtle);
  border: 1px solid var(--color-border-default);
  border-radius: var(--dimension-radius-lg);
  padding: var(--dimension-space-16);
}
.verbleib-spinner {
  width: 28px; height: 28px;
  flex: none;
  border: 3px solid var(--color-border-strong);
  border-top-color: var(--color-text-brand);
  border-radius: 50%;
  animation: verbleib-spin 0.8s linear infinite;
}
@keyframes verbleib-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .verbleib-spinner { animation: none; } }

.verbleib-cand {
  display: flex; flex-direction: column; gap: var(--dimension-space-4);
  background: var(--color-surface-canvas);
  border: 1px solid var(--color-border-default);
  border-radius: var(--dimension-radius-lg);
  padding: var(--dimension-space-16);
}
.verbleib-cand strong { font-size: 15px; font-weight: 600; }
.verbleib-board {
  align-self: flex-start;
  margin-top: var(--dimension-space-4);
  color: var(--color-text-brand-on-tint);
  background: var(--color-surface-subtle);
}
.verbleib-actions { display: flex; gap: var(--dimension-space-8); }
.verbleib-actions form { flex: 1; display: flex; }
.verbleib-actions .btn { flex: 1; }
.verbleib-office {
  display: flex; flex-direction: column; gap: var(--dimension-space-8);
  border-top: 1px solid var(--color-border-default);
  padding-top: var(--dimension-space-16);
}
.verbleib-office .btn { min-height: 48px; }

/* start-screen Verbleib row: a white row inside the green client box */
.verbleib-start { margin: var(--dimension-space-8) 0; }
.verbleib-start .verbleib-icon { flex: none; color: var(--color-text-brand); }

/* ══ Install page ═════════════════════════════════════════════════════════ */

.install {
  max-width: 560px;
  margin: 0 auto;
  padding: var(--dimension-space-24) var(--dimension-space-16);
}
.install h1 { font-size: 28px; line-height: 32px; margin: 0 0 var(--dimension-space-16); }
.install h2 { font-size: 22px; line-height: 26px; margin: 0 0 var(--dimension-space-8); }
.install .btn-primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--dimension-size-control-md);
  padding: var(--dimension-space-8) var(--dimension-space-16);
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  color: var(--color-text-inverse);
  background: var(--color-surface-interactive);
  border: 1px solid var(--color-surface-interactive);
  border-radius: var(--dimension-radius-md);
  cursor: pointer;
}
.install .card {
  background: var(--color-surface-default);
  border: 1px solid var(--color-border-default);
  border-radius: var(--dimension-radius-lg);
  padding: var(--dimension-space-20);
  margin: var(--dimension-space-16) 0;
  box-shadow: var(--elevation-card);
}

/* ══ Semantic outcome tones (spec ruling 11) ══════════════════════════════
   LAST on purpose: a tone class is an override that has to beat whatever
   ground its host component paints (.pill, .aktion-btn, .aktion-opt). Color
   alone never carries the meaning — every tagged element also prints its glyph
   as TEXT, so the status survives color blindness, a grayscale screenshot and
   a phone held in direct sun. An unrecognised board value renders neutral
   WITHOUT a glyph rather than claiming a meaning we do not know. */

.sem-pos { color: var(--color-text-success-on-tint); background: var(--color-surface-success); }
.sem-neu { color: var(--color-text-brand-on-tint); background: var(--color-surface-subtle); }
.sem-neg { color: var(--color-text-danger-on-tint); background: var(--color-surface-danger); }
.aktion-btn.sem-pos, .aktion-opt.sem-pos { border-color: #bbf7d0; }
.aktion-btn.sem-neu, .aktion-opt.sem-neu { border-color: #c3d3ea; }
.aktion-btn.sem-neg, .aktion-opt.sem-neg { border-color: #fecaca; }
.sem-glyph { font-weight: 700; margin-right: 5px; }

/* ══ Antrag abbrechen ═════════════════════════════════════════════════════
   The app-bar title is a link on every screen: inside the wizard it opens the
   cancel question, outside it goes home. It has to look EXACTLY like the title
   it replaced — a title that suddenly reads as a link would be a new control the
   technician has to learn, and this one is deliberately quiet. */
.app-title {
  color: inherit;
  text-decoration: none;
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.app-title:focus-visible {
  outline: 2px solid var(--color-text-inverse);
  outline-offset: 2px;
  border-radius: var(--dimension-radius-sm, 4px);
}
/* R10-N3: the app bar's own gap is 8 px, and at 360 px that put the control
   which DESTROYS the Antrag eight pixels from »Prüfung«, the forward action of
   the whole wizard — one thumb-width, on the row a technician taps all day. The
   extra 8 px make 16, the smallest gap this design system reads as a separation
   rather than a group. The confirmation still stands behind it; this is about
   not having to rely on the confirmation. */
.abbrechen-btn { white-space: nowrap; margin-left: var(--dimension-space-8); }
.abbrechen-sheet .abbrechen-buero,
.abbrechen-confirm .abbrechen-buero { margin-top: calc(-1 * var(--dimension-space-8)); }

/* The danger button. Ruling 11: the tone is never the only signal — every
   caller keeps the ✕ glyph in the label, so a sunlit screen or a colour-blind
   eye still reads "this destroys something". */
.btn-danger {
  color: var(--color-text-danger-on-tint);
  background: var(--color-surface-danger);
  border-color: #fecaca;
}

/* The sheet itself reuses .sheet-panel / .sheet-grip / .sheet-head verbatim —
   this is the same object the technician already knows from Termine. Only the
   host and its scrim are new, and both ship hidden: without JS the app-bar
   controls stay plain links to the confirm PAGE and this markup never appears. */
.abbrechen-sheet .sheet-panel { z-index: 50; }
.abbrechen-sheet .abbrechen-actions { margin: 0; }
.abbrechen-sheet .btn { width: 100%; }
.abbrechen-confirm { text-align: left; }
.abbrechen-confirm .btn { width: 100%; }
.abbrechen-confirm .abbrechen-kasse { margin-top: calc(-1 * var(--dimension-space-8)); }
.abbrechen-weiter-zeile { margin: var(--dimension-space-16) 0 var(--dimension-space-8); }

/* ══ Responsive ═══════════════════════════════════════════════════════════ */

/* The wizard app bar carries THREE actions (Vorschau, Prüfung, Problem
   melden). On a phone that leaves the Kasse name a sliver, so there the title
   takes its own row and the actions wrap underneath. */
@media (max-width: 560px) {
  .home-header--wizard { flex-wrap: wrap; row-gap: var(--dimension-space-8); }
  .home-header--wizard h1 { flex: 1 0 100%; font-size: 20px; line-height: 24px; }
}

@media (max-width: 820px) {
  .step-card { padding: var(--dimension-space-16); }
  .client-modal-body { padding: var(--dimension-space-12); }
}

@media (max-width: 480px) {
  .home-body h2 { font-size: 26px; line-height: 30px; }
}

/* Desktop gets the design system's full display scale — the phone shrinks the
   page title from 40/44 to 28/32, because a 40 px title eats a third of a
   390 px screen before the first control. */
@media (min-width: 861px) {
  .home-body h2 { font-size: 40px; line-height: 44px; }
  .install h1 { font-size: 40px; line-height: 44px; }
}

/* The keyboard/AT path to the chip's free Rückgängig (ADV-12): a quiet link
   under the Termin options, present only while the inference is still
   undoable. Deliberately not a fourth option button — it undoes, it does not
   set. */
.aktion-undo { margin: var(--dimension-space-8) 0 0; }
.aktion-undo-btn {
  min-height: 44px;
  padding: 0 var(--dimension-space-8);
  background: none;
  border: none;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  color: var(--color-text-brand);
  text-decoration: underline;
  cursor: pointer;
}

/* ── K5 »Kunde abschließen« ────────────────────────────────────────────────
   Two surfaces: the menu entry that opens the reason list (nested inside the
   lead menu's own panel), and the TERMINAL well that replaces the three quick
   actions once a customer is closed.

   Ruling 11 throughout: the red never carries the meaning alone — the entry
   keeps its word, the pill keeps its ✕. Ruling 15: the well stays the same
   recessed layer it was; only its contents stop being controls. */
.menu-item.is-danger {
  color: var(--color-text-danger-on-tint);
  border-color: #fecaca;
}
.abschluss-entry > summary { list-style: none; cursor: pointer; }
.abschluss-entry > summary::-webkit-details-marker { display: none; }
.abschluss-panel {
  display: flex;
  flex-direction: column;
  gap: var(--dimension-space-8);
  padding-top: var(--dimension-space-8);
}
.abschluss-panel .aktion-options {
  display: flex;
  flex-direction: column;
  gap: var(--dimension-space-8);
}
.abschluss-notiz-feld {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
  font-weight: 600;
  color: var(--color-text-secondary);
}
.abschluss-notiz-feld textarea {
  width: 100%;
  padding: var(--dimension-space-8);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--dimension-radius-md);
  font: inherit;
  font-weight: 400;
  color: var(--color-text-primary);
  background: var(--color-surface-default);
}

/* The terminal state. It is a statement, not a control — no min-height of a
   tap target, no hover, nothing that invites a finger. */
.lead-well.is-abgeschlossen { flex-direction: column; gap: 4px; }
.abschluss-pill {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  padding: 6px var(--dimension-space-8);
  border-radius: var(--dimension-radius-md);
  font-size: 13px;
  color: var(--color-text-danger-on-tint);
  background: var(--color-surface-danger);
}
.abschluss-grund { font-weight: 600; }

/* R14-04 — the one control the terminal well may carry, and only while the
   close has reached nobody (the server decides; the template only renders what
   `abschluss.view` says). Deliberately quiet: a text link at the end of the
   pill, not a button competing with the statement it sits in.

   R16-N1 — quiet is not the same as small. It stayed a 28 px tap target at
   both viewports, and it is the ONE control on a terminal well: the thing a
   technician reaches for under time pressure in a stairwell, forty seconds
   after a mis-tap, with the withdrawal window already running out. The LOOK is
   unchanged — a 12 px underlined text link, no button chrome — and only the hit
   area grows to 44 px. The wrapper's negative margins absorb the pill's own
   6 px padding instead of adding to it, so the statement it sits in goes from
   29 px to 44 px rather than to 56 px, and a pill with no control on it does
   not grow at all. */
.abschluss-zurueck {
  margin-left: auto;
  display: flex;
  align-items: center;
  margin-top: -6px;
  margin-bottom: -6px;
}
.abschluss-zurueck-btn {
  border: 0;
  background: none;
  padding: 4px var(--dimension-space-8, 8px);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  min-width: 44px;
  font: inherit;
  font-size: 12px;
  text-decoration: underline;
  color: var(--color-text-danger-on-tint);
  cursor: pointer;
}

/* R14-09 — a 485-character note rendered as 220 px of unbroken prose at
   360×780: about a quarter of the viewport, per closed customer, above every
   visit that follows. The note is clamped to three lines and opens on demand.
   The clamp is CSS on the ONE copy of the text (the <summary> itself), so the
   full note is always in the DOM for a screen reader and for Strg-F — nothing
   is truncated, only folded. */
.abschluss-notiz-box { margin: 0; }
/* The native marker is hidden and replaced by a caret AFTER the text: a
   disclosure triangle in front of a paragraph reads as a bullet.

   R15-05 — the caret used to be `summary::after` while the SUMMARY was itself
   the clamped -webkit-box, so the marker sat at the end of the clamped text,
   inside its own `overflow: hidden`. It was eaten exactly when there was
   something to expand: the two clipped notes showed no affordance and the short
   one that needed none showed it. The clamp moved onto an inner <span>; the
   caret stays on the summary as a BLOCK below it, where no overflow can reach
   it. Which shape a note gets is the server's call (`abschluss.notiz_lang`) —
   a note that fits renders as a plain <p> with no box and no caret at all. */
.abschluss-notiz-box > summary::-webkit-details-marker { display: none; }
.abschluss-notiz-box > summary { list-style: none; cursor: pointer; display: block; }
.abschluss-notiz-box > summary::after {
  content: "▾";
  display: block;
  padding: 0 var(--dimension-space-8);
  font-size: 12px;
  color: var(--color-text-secondary);
}
.abschluss-notiz-box[open] > summary::after { content: "▴"; }
.abschluss-notiz {
  margin: 0;
  padding: 0 var(--dimension-space-8);
  font-size: 13px;
  color: var(--color-text-secondary);
  overflow-wrap: anywhere;
}
.abschluss-notiz-box:not([open]) > summary > .abschluss-notiz {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
}

/* ── K5b (R3): the same-day nudge ─────────────────────────────────────────
   A visit whose time is an hour past with nobody having said how it went. The
   amber is the app's existing warning tint (never invented here) and it is
   never the only signal: the ⚠ and the sentence carry the meaning on a
   grayscale screenshot, in a sunlit windscreen and for a colour-blind reader
   (ruling 11). The card keeps its shape — the highlight is a left rule and a
   tinted question, not a different kind of row. */
.lead-card.is-offen-heute {
  border-color: var(--color-text-warning);
  box-shadow: inset 3px 0 0 var(--color-text-warning);
}
.lead-nudge {
  padding: var(--dimension-space-8) var(--dimension-space-12);
  background: var(--color-surface-warning);
  border-top: 1px solid var(--color-border-default);
}
.lead-nudge .nudge-frage {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0 0 var(--dimension-space-8);
  font-size: 14px;
  font-weight: 600;
  color: var(--color-text-warning-on-tint);
}
.nudge-actions { display: flex; gap: var(--dimension-space-8); }
.nudge-form { flex: 1; min-width: 0; margin: 0; }
/* 44 px targets, like every other one-tap answer in this app. */
.nudge-form .aktion-opt { width: 100%; min-height: 44px; }

/* ── K5b (R1): the »Abgesagt« follow-up page (no-JS half) ─────────────── */
.reschedule-frage { margin: var(--dimension-space-12) 0; font-size: 18px; }
.reschedule-kontext { display: block; margin-bottom: var(--dimension-space-12); }
.reschedule-kontext > span { display: block; margin-bottom: 4px; font-size: 14px; }
.reschedule-kontext textarea {
  width: 100%;
  min-height: 88px;
  padding: var(--dimension-space-8);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--dimension-radius-md);
  font: inherit;
}
.reschedule-ja .btn { width: 100%; min-height: 44px; }
/* R18-13: the character counter under the mandatory context text. Right
   under the box it counts, quiet until it matters. */
.kontext-zaehler { text-align: right; font-variant-numeric: tabular-nums; }
.reschedule-nein { margin-top: var(--dimension-space-16); }
.reschedule-nein > summary { min-height: 44px; display: flex; align-items: center; }

/* ── K5b (R4): »Besuch abgeschlossen« ─────────────────────────────────── */
.besuch-head { display: flex; align-items: center; gap: 6px; }
.besuch-sub {
  margin: var(--dimension-space-16) 0 var(--dimension-space-8);
  font-size: 14px;
  color: var(--color-text-secondary);
}
.besuch-summary { list-style: none; margin: 0; padding: 0; }
.besuch-zeile {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px;
  padding: var(--dimension-space-8) 0;
  border-bottom: 1px solid var(--color-border-default);
}
.besuch-titel { min-width: 120px; color: var(--color-text-secondary); font-size: 14px; }
.besuch-wert { display: inline-flex; align-items: baseline; gap: 4px; font-weight: 600; }
.besuch-naechster { display: flex; gap: 8px; align-items: baseline; }
.besuch-hinweis { margin-top: var(--dimension-space-16); font-size: 13px; }
/* The follow-up's own refusal sentence, said in the sheet before the round
   trip the server would refuse anyway (K5b, R1). */
.aktion-fehler {
  margin: 0 0 var(--dimension-space-8);
  font-size: 13px;
  color: var(--color-text-danger);
}

/* ══ K5c — die Reklamationsfrist (R6/R7/R11) ══════════════════════════════
   Two places, one sentence: the OPEN visit's row, and the head of the close
   sheet. The row line is deliberately quiet — it is a fact about a visit that
   is still ahead of her, and it must not compete with the name above it or the
   three quick actions below it. It borrows the semantic COLOUR and drops the
   tint, because a full red band under every expired lead would repaint the day
   list into a warning screen.

   The sheet's head is the opposite case and keeps its tint: at that moment the
   technician is one tap from an irreversible decision, and the box is what
   tells her which of the two decisions it is. */
.lead-frist {
  margin: 2px 0 0;
  font-size: 11px;
  line-height: 16px;
  font-weight: 600;
  background: none;                 /* the .sem-* tint is for boxes, not lines */
  overflow-wrap: anywhere;
}
.abschluss-frist {
  padding: var(--dimension-space-8);
  border-radius: var(--dimension-radius-md);
  font-size: 12px;
  line-height: 17px;
}
.abschluss-frist p { margin: 0; }
.abschluss-frist-zeile { font-weight: 700; }
.abschluss-frist-satz,
.abschluss-frist-hinweis { margin-top: 4px !important; font-weight: 400; }

/* K5c (R8) — the office's answer under a closed customer's pill.
   Quiet by construction: the pill is the statement the technician made, this
   is what came back, and it must not compete with it. Same left rail and the
   same glyph gap as the note below it, so the well reads as one block.

   R20-08: both of those promises were unmet. `.sem-pos/.sem-neu/.sem-neg` set a
   BACKGROUND as well as a foreground, and this rule reset neither it nor the
   rail — so a full-width tinted band stood directly under the red close pill
   (green, for Akzeptiert and Autoakzeptiert), and the text sat 8px left of both
   the pill and the note. `.lead-frist` two rules up makes the opposite decision
   with the reason written out; this now makes the same one. */
.abschluss-rekl {
  margin: .25rem 0 0;
  padding: 0 var(--dimension-space-8);   /* the same rail as .abschluss-notiz */
  font-size: .82rem;
  display: flex;
  align-items: baseline;
  gap: .3rem;
  background: none;                 /* the .sem-* tint is for boxes, not lines */
}
.abschluss-rekl .sem-glyph { flex: 0 0 auto; }
