/* ===========================================================================
   DESIDUS · Client register
   ---------------------------------------------------------------------------
   Built from the DESIDUS brand guidelines (July 2023):

     Colour     Navy #28334a · Copper #bb6747 / #e08d58 · Warm grey #f2f0ee /
                #d7d1ca · Blue #6aabe4. One accent at a time — copper for
                DESIDUS, blue for TM Marinas — set via [data-accent].
     Type       Montserrat for the interface, letter-spaced uppercase for
                eyebrows and buttons exactly as page 15 shows. Lora for
                headings and prose. Nothing else.
     Rules      Thin vertical hairlines as separators, pill buttons, generous
                whitespace. Boxes are the exception, not the default.

   Contrast: every text token was measured against its ground before it was
   allowed in. Muted text is 4.9:1 or better in both themes — that is the usual
   failure point in minimal interfaces, so it is checked rather than eyeballed.

   Spacing is a 4 px scale. There are no arbitrary pixel values below.
   =========================================================================== */

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

:root {
  /* Light is the default. Every colour is declared here first, so no value
     exists only inside a media query. */
  --bg:          #f2f0ee;   /* Warm Gray 1 C, 30% tint */
  --surface:     #ffffff;
  --surface-2:   #faf9f8;
  --text:        #28334a;   /* Pantone 2380 C */
  --muted:       #4f5a72;   /* 6.1:1 on --bg */
  --faint:       #5c6885;   /* 4.9:1 on --bg — the floor */
  --empty:       #5c6885;   /* the “no value” dash: 5.6:1 on --surface */
  --line:        #e2ddd7;
  --line-strong: #cfc8c0;

  --accent:      #a8543a;   /* copper, darkened for 4.6:1 as text */
  --accent-ink:  #ffffff;   /* on an --accent fill */
  --accent-soft: rgba(187, 103, 71, 0.10);
  --accent-line: rgba(187, 103, 71, 0.34);

  --danger:      #a33b32;
  --danger-soft: rgba(163, 59, 50, 0.10);

  --shadow:      0 1px 2px rgba(40, 51, 74, .05), 0 8px 28px rgba(40, 51, 74, .08);
  --shadow-lift: 0 2px 6px rgba(40, 51, 74, .07), 0 22px 60px rgba(40, 51, 74, .16);

  --sans: 'Montserrat', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --serif: 'Lora', Georgia, 'Times New Roman', serif;

  --r-sm: 4px;
  --r:    8px;
  --r-lg: 14px;
  --r-pill: 999px;

  --tap: 44px;              /* minimum comfortable target */
  --ease: cubic-bezier(.32, .72, 0, 1);
}

/* TM Marinas swaps the single accent. Nothing else about the design changes. */
[data-accent="blue"] {
  --accent:      #2f6ea8;
  --accent-soft: rgba(106, 171, 228, 0.16);
  --accent-line: rgba(47, 110, 168, 0.34);
}

/* Dark: only the tokens are redefined. Guarded so an explicit light choice
   still wins on a system set to dark. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg:          #1d2637;
    --surface:     #28334a;   /* the brand navy carries the surfaces here */
    --surface-2:   #222c40;
    --text:        #eceae7;
    --muted:       #9aa5bd;
    --faint:       #8e99b3;
    --empty:       #9aa5bd;   /* 5.1:1 on the navy --surface */
    --line:        rgba(255, 255, 255, .10);
    --line-strong: rgba(255, 255, 255, .20);
    --accent:      #e08d58;
    --accent-ink:  #21283a;
    --accent-soft: rgba(224, 141, 88, .14);
    --accent-line: rgba(224, 141, 88, .40);
    --danger:      #e08a80;
    --danger-soft: rgba(224, 138, 128, .13);
    --shadow:      0 1px 2px rgba(0, 0, 0, .3), 0 8px 28px rgba(0, 0, 0, .32);
    --shadow-lift: 0 2px 6px rgba(0, 0, 0, .34), 0 22px 60px rgba(0, 0, 0, .5);
  }
  :root:not([data-theme="light"])[data-accent="blue"] {
    --accent:      #8cc0ee;
    --accent-ink:  #17283a;
    --accent-soft: rgba(140, 192, 238, .14);
    --accent-line: rgba(140, 192, 238, .40);
  }
}

/* The toggle must win in both directions, so the same block is repeated
   under an explicit dark choice. */
:root[data-theme="dark"] {
  --bg:          #1d2637;
  --surface:     #28334a;
  --surface-2:   #222c40;
  --text:        #eceae7;
  --muted:       #9aa5bd;
  --faint:       #8e99b3;
  --empty:       #9aa5bd;   /* 5.1:1 on the navy --surface */
  --line:        rgba(255, 255, 255, .10);
  --line-strong: rgba(255, 255, 255, .20);
  --accent:      #e08d58;
  --accent-ink:  #21283a;
  --accent-soft: rgba(224, 141, 88, .14);
  --accent-line: rgba(224, 141, 88, .40);
  --danger:      #e08a80;
  --danger-soft: rgba(224, 138, 128, .13);
  --shadow:      0 1px 2px rgba(0, 0, 0, .3), 0 8px 28px rgba(0, 0, 0, .32);
  --shadow-lift: 0 2px 6px rgba(0, 0, 0, .34), 0 22px 60px rgba(0, 0, 0, .5);
}
:root[data-theme="dark"][data-accent="blue"] {
  --accent:      #8cc0ee;
  --accent-ink:  #17283a;
  --accent-soft: rgba(140, 192, 238, .14);
  --accent-line: rgba(140, 192, 238, .40);
}

/* --- Base --------------------------------------------------------------- */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3 { margin: 0; font-weight: 500; line-height: 1.2; }
p { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }
a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 2px; }

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

.spacer { flex: 1; }

/* Present for screen readers and the accessibility tree, painted nowhere.
   The sign-in page uses it so the page still has a heading without showing
   any text beyond the brandmark and the two fields. */
.sr-only {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden; white-space: nowrap;
  clip: rect(0 0 0 0); clip-path: inset(50%);
}
.skip {
  position: absolute; left: 8px; top: -60px; z-index: 100;
  background: var(--surface); color: var(--text);
  padding: 12px 16px; border-radius: var(--r); box-shadow: var(--shadow);
  transition: top .15s var(--ease);
}
.skip:focus { top: 8px; }

/* The one recurring brand device: letter-spaced uppercase Montserrat. */
.eyebrow {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--faint);
}

/* The brandmark is a raster asset in the guidelines' navy. Because the artwork
   is one flat colour with the shape held in the alpha channel, the same file
   reverses cleanly to white for dark grounds — which is exactly how the
   guidelines show it used on navy. height:auto keeps the aspect ratio while the
   declared width/height attributes reserve the space. */
.logo { display: block; width: auto; height: auto; }
.logo--gate    { width: 210px; }
.logo--chooser { width: 152px; }
.logo--mark    { width: 148px; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .logo { filter: brightness(0) invert(1); }
}
:root[data-theme="dark"] .logo { filter: brightness(0) invert(1); }

/* --- Buttons ------------------------------------------------------------ */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 36px; padding: 0 16px;
  font: inherit; font-size: 11px; font-weight: 500;
  letter-spacing: .1em; text-transform: uppercase;
  border-radius: var(--r-pill);            /* pill, per the guidelines */
  border: 1px solid transparent;
  background: transparent; color: var(--text);
  cursor: pointer; white-space: nowrap;
  transition: background .16s var(--ease), border-color .16s var(--ease), color .16s var(--ease);
}
.btn--primary { background: var(--accent); color: var(--accent-ink); }
.btn--primary:hover { filter: brightness(1.08); }
.btn--quiet { border-color: var(--line-strong); color: var(--muted); }
.btn--quiet:hover { border-color: var(--accent-line); color: var(--accent); }
.btn--block { width: 100%; min-height: 44px; }
.btn--danger-quiet { color: var(--danger); border-color: transparent; }
.btn--danger-quiet:hover { background: var(--danger-soft); }
.btn--icon {
  min-height: 34px; width: 34px; padding: 0;
  /* Overrides the 11px uppercase of .btn: these hold a glyph, not a word. */
  font-size: 19px; line-height: 1; letter-spacing: 0;
  border-color: var(--line-strong); color: var(--muted);
}
.btn--icon:hover { border-color: var(--accent-line); color: var(--accent); }
.btn--icon svg { width: 12px; height: 12px; }
.btn[disabled] { opacity: .4; cursor: not-allowed; }

/* --- Inputs ------------------------------------------------------------- */

.input, .select, .textarea {
  width: 100%;
  min-height: 40px;
  padding: 8px 12px;
  font: inherit; font-size: 14px;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r);
  transition: border-color .16s var(--ease), box-shadow .16s var(--ease);
}
.textarea { min-height: 108px; resize: vertical; line-height: 1.6; }
.input:focus, .select:focus, .textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.select {
  appearance: none;
  padding-right: 32px;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 16px) 17px, calc(100% - 11px) 17px;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
.field { display: block; margin-bottom: 16px; }

/* Mehrfachauswahl: zwei Spalten, damit acht Punkte nicht acht Zeilen kosten. */
.checks {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 2px 12px;
  padding: 8px 10px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r);
  background: var(--surface);
}
.check {
  display: flex; align-items: center; gap: 9px;
  padding: 6px 4px;
  font-size: 13.5px;
  border-radius: var(--r-sm);
  cursor: pointer;
}
.check:hover { background: var(--accent-soft); }
.check input { accent-color: var(--accent); width: 15px; height: 15px; margin: 0; flex: none; }
@media (max-width: 560px) { .checks { grid-template-columns: 1fr; } }
.field__label {
  display: block; margin-bottom: 6px;
  font-size: 10px; font-weight: 500; letter-spacing: .14em;
  text-transform: uppercase; color: var(--faint);
}
.field__help { margin-top: 6px; font-size: 12px; color: var(--muted); line-height: 1.5; }

.alert { padding: 10px 14px; border-radius: var(--r); font-size: 13px; margin-bottom: 4px; }
.alert--error { background: var(--danger-soft); color: var(--danger); }

/* =========================================================================
   Sign-in
   ========================================================================= */

.gate {
  min-height: 100dvh;
  display: grid;
  place-items: center;
  padding: 32px 24px;
  background:
    radial-gradient(120% 90% at 50% -20%, var(--accent-soft), transparent 62%),
    var(--bg);
}
.gate__panel {
  width: 100%; max-width: 380px;
  padding: 40px 32px 32px;
  background: var(--surface);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
}
/* The sign-in screen carries no copy at all: brandmark, two fields, button.
   With nothing between the logo and the first label the panel needs a little
   less vertical padding to stay optically centred. */
.gate__panel--bare { padding: 36px 32px 30px; }
.gate__panel--bare .gate__brand { margin-bottom: 30px; }

.gate__brand { margin-bottom: 32px; }
.gate__brand .logo { margin: 0 auto; }
.gate .eyebrow { text-align: center; }
.gate__title {
  margin: 4px 0 8px;
  font-family: var(--serif);
  font-size: 30px;
  text-align: center;
}
.gate__note {
  margin-bottom: 28px;
  font-size: 13px; color: var(--muted); text-align: center; line-height: 1.6;
}
.form .field:last-of-type { margin-bottom: 20px; }
.form .alert { margin-bottom: 16px; }

/* =========================================================================
   Workspace chooser
   ========================================================================= */

.chooser { min-height: 100dvh; display: flex; flex-direction: column; }
.chooser__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 24px 32px;
}
.chooser__body {
  flex: 1;
  display: flex; flex-direction: column; justify-content: center;
  /* Breit genug, dass die drei Kacheln auf dem Desktop in einer Reihe stehen;
     darunter fällt das Raster von selbst auf zwei und dann auf eine Spalte. */
  max-width: 1080px; width: 100%; margin: 0 auto; padding: 24px 32px 64px;
}
.chooser__title { margin: 4px 0 40px; font-family: var(--serif); font-size: 38px; }

.cards { display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(264px, 1fr)); }
.card__link {
  display: flex; flex-direction: column; gap: 8px;
  height: 100%; padding: 28px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  color: inherit; text-decoration: none;
  transition: border-color .18s var(--ease), transform .18s var(--ease), box-shadow .18s var(--ease);
}
.card__link:hover { border-color: var(--accent-line); transform: translateY(-2px); box-shadow: var(--shadow); }
.card[data-accent="blue"] .card__link:hover { border-color: rgba(47, 110, 168, .4); }
.card__name { font-family: var(--serif); font-size: 26px; }
.card__blurb { font-size: 13.5px; color: var(--muted); line-height: 1.6; margin-bottom: 12px; }
.card__go {
  margin-top: auto;
  display: inline-flex; align-items: center; gap: 10px;
  font-size: 10px; font-weight: 500; letter-spacing: .14em; text-transform: uppercase;
  color: var(--accent);
}
.card[data-accent="blue"] .card__go { color: #2f6ea8; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .card[data-accent="blue"] .card__go { color: #8cc0ee; }
}
:root[data-theme="dark"] .card[data-accent="blue"] .card__go { color: #8cc0ee; }
.arrow { width: 32px; height: 8px; }

/* Konfigurator-Rahmen: Kopfzeile oben, darunter füllt der iframe den Rest des
   Fensters. 100dvh statt 100vh, damit die Adressleiste mobiler Browser den
   Konfigurator nicht unten abschneidet. */
body.hat-rahmen {
  height: 100dvh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
body.hat-rahmen .top { position: static; flex: none; }
.rahmen {
  flex: 1 1 auto;
  width: 100%;
  min-height: 0;
  border: 0;
  display: block;
  background: var(--surface);
}

/* =========================================================================
   Application chrome
   ========================================================================= */

.top {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px;
  padding: 12px 24px;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: saturate(1.6) blur(12px);
  border-bottom: 1px solid var(--line);
}
@supports not (backdrop-filter: blur(1px)) { .top { background: var(--bg); } }

.top__left { display: flex; align-items: center; gap: 16px; min-width: 0; }
.top__home { display: block; line-height: 0; }
.top__id {
  padding-left: 16px;
  border-left: 1px solid var(--line-strong);   /* the guidelines' thin rule */
  min-width: 0;
}
.top__name {
  font-family: var(--serif); font-size: 19px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.top__right { display: flex; align-items: center; gap: 8px; }

.who {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 0 12px 0 10px; height: 30px;
  font-size: 12px; color: var(--muted);
  border: 1px solid var(--line); border-radius: var(--r-pill);
}
.who__dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }

.menu { position: relative; }
.menu > summary { list-style: none; }
.menu > summary::-webkit-details-marker { display: none; }
.menu__panel {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 40;
  min-width: 216px; padding: 6px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--shadow-lift);
}
.menu__item {
  display: block; width: 100%;
  padding: 9px 12px;
  font: inherit; font-size: 13px; text-align: left; text-decoration: none;
  color: var(--text); background: none; border: 0; border-radius: var(--r-sm);
  cursor: pointer;
}
.menu__item:hover { background: var(--accent-soft); color: var(--accent); }
.menu__item--warn { color: var(--danger); }
.menu__item--warn:hover { background: var(--danger-soft); color: var(--danger); }

.wrap { max-width: 1400px; margin: 0 auto; padding: 24px 24px 96px; }

/* --- Controls ----------------------------------------------------------- */

.controls { margin-bottom: 20px; }
.controls__row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }

.search { position: relative; flex: 1 1 300px; min-width: 220px; }
.search__icon {
  position: absolute; left: 14px; top: 50%; transform: translateY(-50%);
  width: 15px; height: 15px; color: var(--faint); pointer-events: none;
}
.search__input {
  width: 100%; min-height: 42px;
  padding: 8px 40px 8px 40px;
  font: inherit; font-size: 14px;
  color: var(--text); background: var(--surface);
  border: 1px solid var(--line-strong); border-radius: var(--r-pill);
  transition: border-color .16s var(--ease), box-shadow .16s var(--ease);
}
.search__input::-webkit-search-cancel-button { display: none; }
.search__input:focus {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
.search__clear {
  position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
  width: 28px; height: 28px;
  font-size: 20px; line-height: 1; color: var(--muted);
  background: none; border: 0; border-radius: 50%; cursor: pointer;
}
.search__clear:hover { background: var(--accent-soft); color: var(--accent); }

.sortpick { display: flex; align-items: center; gap: 8px; }
.sortpick__label {
  font-size: 10px; font-weight: 500; letter-spacing: .14em;
  text-transform: uppercase; color: var(--faint);
}
.sortpick .select { width: auto; min-width: 168px; min-height: 36px; border-radius: var(--r-pill); }
#dirBtn[data-dir="desc"] svg { transform: rotate(180deg); }
.filters-toggle { display: none; }

/* Facets: one quiet row, not a control panel. */
.facets {
  display: flex; flex-wrap: wrap; gap: 8px;
  margin-top: 12px;
}
.facet { position: relative; }
.facet__btn {
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 32px; padding: 0 12px;
  font: inherit; font-size: 12px; color: var(--muted);
  background: transparent;
  border: 1px solid var(--line-strong); border-radius: var(--r-pill);
  cursor: pointer;
  transition: border-color .16s var(--ease), color .16s var(--ease);
}
.facet__btn:hover { border-color: var(--accent-line); color: var(--accent); }
.facet__btn[aria-expanded="true"] { border-color: var(--accent); color: var(--accent); }
.facet__btn--on { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
.facet__caret { width: 7px; height: 5px; opacity: .7; }
.facet__count {
  min-width: 17px; height: 17px; padding: 0 5px;
  display: inline-grid; place-items: center;
  font-size: 10px; font-weight: 600;
  color: var(--accent-ink); background: var(--accent); border-radius: var(--r-pill);
}
.facet__pop {
  position: absolute; left: 0; top: calc(100% + 6px); z-index: 25;
  min-width: 220px; max-height: 320px; overflow-y: auto;
  padding: 6px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r); box-shadow: var(--shadow-lift);
}
.facet__opt {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 10px; border-radius: var(--r-sm);
  font-size: 13px; cursor: pointer;
}
.facet__opt:hover { background: var(--accent-soft); }
.facet__opt input { accent-color: var(--accent); width: 15px; height: 15px; margin: 0; flex: none; }
.facet__opt span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.facet__opt em { font-style: normal; color: var(--faint); font-size: 11px; font-variant-numeric: tabular-nums; }
.facet__dates { display: flex; align-items: center; gap: 8px; padding: 8px; }
.facet__dates .input { min-height: 34px; font-size: 13px; }
.facet__arrow { color: var(--faint); }

/* Active filters, as removable chips. */
.chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.chips:empty { display: none; }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  height: 26px; padding: 0 6px 0 11px;
  font-size: 12px; color: var(--accent);
  background: var(--accent-soft); border: 1px solid var(--accent-line);
  border-radius: var(--r-pill);
}
.chip__x {
  width: 18px; height: 18px;
  display: grid; place-items: center;
  font-size: 15px; line-height: 1; color: inherit;
  background: none; border: 0; border-radius: 50%; cursor: pointer; opacity: .7;
}
.chip__x:hover { opacity: 1; background: var(--accent-line); }
.chip--clear {
  padding: 0 11px; color: var(--muted);
  background: none; border-color: var(--line-strong); cursor: pointer;
  font: inherit; font-size: 12px; height: 26px;
}
.chip--clear:hover { color: var(--accent); border-color: var(--accent-line); }

.meta {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; margin-bottom: 8px; padding-bottom: 8px;
}
.count { font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.count b { color: var(--text); font-weight: 500; }

.viewpick { display: flex; gap: 2px; padding: 2px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-pill); }
.viewpick__btn {
  min-height: 26px; padding: 0 13px;
  font: inherit; font-size: 10px; font-weight: 500; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); background: none; border: 0; border-radius: var(--r-pill); cursor: pointer;
}
.viewpick__btn[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); }

/* --- Table -------------------------------------------------------------- */

/* No `overflow` here on purpose. Any overflow value other than `visible` turns
   this element into the scroll container for its descendants, which stops the
   sticky <th> from sticking to the viewport and pushes it down by its own
   offset instead. The corners are rounded on the corner cells below. */
.tablewrap {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
}
table.reg { width: 100%; border-collapse: collapse; font-size: 13.5px; }

.reg thead th {
  /* Sticks just below the page header. --top-h is measured by app.js because
     the header's height changes across breakpoints. */
  position: sticky; top: var(--top-h, 71px); z-index: 10;
  padding: 0;
  background: var(--surface-2);
  /* An inset shadow rather than border-bottom: with border-collapse the
     border is owned by the row and does not travel with a sticky cell. */
  box-shadow: inset 0 -1px 0 var(--line-strong);
  text-align: left;
  white-space: nowrap;
}
.reg thead th:first-child { border-top-left-radius: var(--r-lg); }
.reg thead th:last-child  { border-top-right-radius: var(--r-lg); }
.reg tbody tr:last-child td:first-child { border-bottom-left-radius: var(--r-lg); }
.reg tbody tr:last-child td:last-child  { border-bottom-right-radius: var(--r-lg); }
.sortbtn {
  display: flex; align-items: center; gap: 6px;
  width: 100%; min-height: 42px; padding: 0 16px;
  font: inherit; font-size: 10px; font-weight: 500;
  letter-spacing: .13em; text-transform: uppercase;
  color: var(--faint); background: none; border: 0; cursor: pointer;
  transition: color .16s var(--ease);
}
.sortbtn:hover { color: var(--accent); }
.reg th[aria-sort] .sortbtn { color: var(--accent); }
.sortbtn__i { width: 9px; height: 9px; opacity: 0; flex: none; transition: opacity .16s var(--ease); }
.sortbtn:hover .sortbtn__i { opacity: .45; }
.reg th[aria-sort] .sortbtn__i { opacity: 1; }
.reg th[aria-sort="descending"] .sortbtn__i { transform: rotate(180deg); }
.reg th.num .sortbtn { justify-content: flex-end; }

.reg tbody tr {
  border-bottom: 1px solid var(--line);
  cursor: pointer;
  transition: background .12s var(--ease);
}
.reg tbody tr:last-child { border-bottom: 0; }
.reg tbody tr:hover { background: var(--accent-soft); }
.reg tbody tr:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.reg td { padding: 11px 16px; vertical-align: middle; }
@media (max-width: 1200px) {
  .reg td { padding: 11px 12px; }
  .sortbtn { padding: 0 12px; }
}
.reg td.num { text-align: right; font-variant-numeric: tabular-nums; }
.reg td.date { font-variant-numeric: tabular-nums; white-space: nowrap; }

.cell-name { font-weight: 500; }
.cell-sub { display: block; font-size: 12px; color: var(--muted); margin-top: 1px; }
/* The em-dash means "no value recorded", so it is content, not decoration, and
   has to clear AA. Opacity was taking it to ~1.8:1 — it recedes by being small
   and light instead. */
.empty-val { color: var(--empty); font-size: 12px; }

/* Status: a dot plus a word. No coloured pill blocks — they shout, and with
   eight statuses the table would turn into confetti. */
/* Kein `nowrap`: „Warten auf Kundenrückmeldung“ machte die Statusspalte 265 px
   breit und die Tabelle damit unschrumpfbar — die Seite scrollte seitlich,
   statt dass der Status zweizeilig wird. Der Punkt bleibt auf der ersten Zeile. */
.status { display: inline-flex; align-items: flex-start; gap: 8px; }
.status__dot {
  width: 7px; height: 7px; border-radius: 50%; flex: none;
  margin-top: 7px; background: var(--s-col, var(--faint));
}
/* Keyed on the value stored in the record, so these strings must match
   STATUS_OPTIONS in lib/schema.php exactly. Rename a status there and its
   colour has to be renamed here too. Die Reihenfolge folgt dem Ablauf:
   kühl bei neuen Anfragen, warm sobald ein Angebot draußen ist, grün beim
   gewonnenen Kunden, gedeckt bei ruhenden und rot bei verlorenen. */
.status[data-s="Neue Anfrage"]                 { --s-col: #6aabe4; }
.status[data-s="In Bearbeitung"]               { --s-col: #4c6895; }
.status[data-s="Angebot gesendet"]             { --s-col: #e08d58; }
.status[data-s="Warten auf Kundenrückmeldung"] { --s-col: #a9906f; }
.status[data-s="In Verhandlung"]               { --s-col: #bb6747; }
.status[data-s="Aktiver Kunde"]                { --s-col: #2f8f6b; }
.status[data-s="Ehemaliger Kunde"]             { --s-col: #bfb7af; }
.status[data-s="Zurückgestellt"]               { --s-col: #9a8f84; }
.status[data-s="Verloren"]                     { --s-col: #a33b32; }

/* --- Aufgeklappte Zeile ---------------------------------------------------
   Ein Klick auf die Zeile zeigt darunter alles, was nicht in die sieben
   Spalten passt. Die Zeile bleibt dabei sichtbar hervorgehoben, damit klar
   ist, wozu der Bereich gehört. */
.reg tbody tr.auf { background: var(--accent-soft); }
.reg tbody tr.auf td { border-bottom: 0; }
.reg tbody tr.detailrow { cursor: default; }
.reg tbody tr.detailrow:hover { background: transparent; }
.reg tbody tr.detailrow > td { padding: 0 16px 18px; }

.detail { border-left: 2px solid var(--accent-line); padding: 4px 0 0 16px; }
.ddlist {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 10px 24px; margin: 8px 0 0;
}
.ddlist--lang { grid-template-columns: 1fr; }
.dd, .langtext { min-width: 0; }
.dd dt, .langtext dt {
  font-size: 10px; font-weight: 500; letter-spacing: .13em;
  /* --faint fiel im dunklen Design auf der Detail-Fläche auf 4.43:1 — knapp
     unter AA. --empty ist auf genau diese Fläche geprüft (mind. 5.1:1) und
     dient hier demselben Zweck: zurückgenommenes, aber lesbares Label. */
  text-transform: uppercase; color: var(--empty); margin-bottom: 2px;
}
.dd dd, .langtext dd {
  margin: 0; font-size: 13.5px; line-height: 1.5;
  /* Anfragetexte enthalten URLs und E-Mail-Adressen. Ohne diese Regel setzt
     eine einzige lange Zeichenkette die Mindestbreite der Tabelle und schiebt
     die ganze Seite seitlich aus dem Bild. */
  overflow-wrap: anywhere;
}
.langtext dd {
  white-space: pre-wrap;          /* Anfragetexte behalten ihre Absätze */
  max-height: 15em; overflow-y: auto;
  padding: 8px 12px; background: var(--surface-2);
  border-radius: var(--r); color: var(--muted);
}
.detail__leer { font-size: 13px; color: var(--muted); margin: 6px 0; }
.detail__foot {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--line);
}
.detail__stamp { font-size: 11px; color: var(--faint); }

/* --- Bereich für verlorene Anfragen --------------------------------------
   Zugeklappt und optisch zurückgenommen: sie sollen greifbar bleiben, aber
   die tägliche Arbeit nicht mehr belasten. */
.archiv { margin-top: 28px; }
.archiv__kopf {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 4px; cursor: pointer; list-style: none;
  border-top: 1px solid var(--line-strong);
}
.archiv__kopf::-webkit-details-marker { display: none; }
.archiv__kopf::before {
  content: ""; width: 0; height: 0; flex: none;
  border-left: 5px solid var(--faint);
  border-top: 4px solid transparent; border-bottom: 4px solid transparent;
  transition: transform .15s var(--ease);
}
.archiv[open] .archiv__kopf::before { transform: rotate(90deg); }
.archiv__titel {
  font-size: 10px; font-weight: 500; letter-spacing: .16em;
  text-transform: uppercase; color: var(--muted);
}
.archiv__zahl {
  min-width: 20px; padding: 0 6px; height: 18px;
  display: inline-grid; place-items: center;
  font-size: 11px; font-variant-numeric: tabular-nums;
  color: var(--muted); background: var(--surface-2);
  border: 1px solid var(--line); border-radius: var(--r-pill);
}
.archiv__kopf:hover .archiv__titel, .archiv__kopf:hover .archiv__zahl { color: var(--accent); }
.archiv__body { opacity: .82; padding-top: 4px; }
/* Die Kopfzeile bleibt stehen: ohne sie hätte die Tabelle im Archiv keine
   Spaltenbeschriftungen — für Screenreader wäre sie damit unlesbar. Sie wird
   nur zurückgenommen, weil sie die der Hauptliste wiederholt. */
.archiv__body .reg thead th { background: transparent; box-shadow: none; }
.archiv__body .sortbtn { min-height: 32px; }

/* Vom Server vergebene Werte werden gezeigt, nicht eingegeben. */
.input--fest { background: var(--surface-2); color: var(--muted); cursor: default; }

/* Zuständige: voller Name in einer festen, aus dem Namen abgeleiteten Farbe.
   Acht Töne, in beiden Designs gegen alle drei Untergründe auf mindestens
   4,5:1 geprüft — die hellen Werte sind dafür gegenüber den Markentönen
   abgedunkelt, die dunklen aufgehellt. */
.owner {
  color: var(--owner-c, var(--text));
  font-weight: 500;
  white-space: nowrap;
}
:root {
  --owner-0: #9d4e36; --owner-1: #2f6ea8; --owner-2: #296b50; --owner-3: #7b5ea7;
  --owner-4: #7a5d1a; --owner-5: #a33b6e; --owner-6: #37707a; --owner-7: #6b6f2e;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --owner-0: #f0a074; --owner-1: #8cc0ee; --owner-2: #6fd3a5; --owner-3: #c3aae8;
    --owner-4: #e2c463; --owner-5: #f0a0c4; --owner-6: #79cfdb; --owner-7: #c4cc7a;
  }
}
:root[data-theme="dark"] {
  --owner-0: #f0a074; --owner-1: #8cc0ee; --owner-2: #6fd3a5; --owner-3: #c3aae8;
  --owner-4: #e2c463; --owner-5: #f0a0c4; --owner-6: #79cfdb; --owner-7: #c4cc7a;
}
.owner[data-c="0"] { --owner-c: var(--owner-0); }
.owner[data-c="1"] { --owner-c: var(--owner-1); }
.owner[data-c="2"] { --owner-c: var(--owner-2); }
.owner[data-c="3"] { --owner-c: var(--owner-3); }
.owner[data-c="4"] { --owner-c: var(--owner-4); }
.owner[data-c="5"] { --owner-c: var(--owner-5); }
.owner[data-c="6"] { --owner-c: var(--owner-6); }
.owner[data-c="7"] { --owner-c: var(--owner-7); }

/* Mehrfachauswahl in der Liste: mehrere kleine Marken statt einer langen Zeile. */
.tag {
  display: inline-block;
  margin: 1px 4px 1px 0;
  padding: 1px 8px;
  font-size: 11.5px;
  color: var(--muted);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
}

/* Die Wunsch-Spalte trägt den längsten Text der Zeile und darf umbrechen,
   damit sie die übrigen Spalten nicht zusammendrückt. */
.reg td.wunsch { white-space: normal; line-height: 1.45; }

.overdue { color: var(--danger); font-weight: 500; }
.overdue::before { content: "▲"; font-size: 8px; vertical-align: 2px; margin-right: 5px; }

/* --- Cards -------------------------------------------------------------- */

.grid { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(268px, 1fr)); }
.rec {
  display: flex; flex-direction: column; gap: 6px;
  padding: 18px;
  text-align: left; font: inherit; color: inherit;
  background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-lg);
  cursor: pointer;
  transition: border-color .16s var(--ease), transform .16s var(--ease);
}
.rec:hover { border-color: var(--accent-line); transform: translateY(-1px); }
.rec__name { font-size: 15px; font-weight: 500; }
.rec__sub { font-size: 12.5px; color: var(--muted); }
.rec__row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-top: 8px; padding-top: 10px;
  border-top: 1px solid var(--line);
  font-size: 12px; color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* --- States ------------------------------------------------------------- */

.state { padding: 72px 24px; text-align: center; }
.state__title { font-family: var(--serif); font-size: 21px; margin-bottom: 8px; }
.state__text { font-size: 13.5px; color: var(--muted); max-width: 38ch; margin: 0 auto 20px; line-height: 1.7; }
.state--error .state__title { color: var(--danger); }

.skeleton { padding: 8px 0; }
.skeleton__row {
  height: 44px; margin: 0 0 1px;
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface) 50%, var(--surface-2) 75%);
  background-size: 400% 100%;
  animation: shimmer 1.3s linear infinite;
  border-radius: var(--r-sm);
}
@keyframes shimmer { to { background-position: -100% 0; } }

.pager {
  display: flex; align-items: center; justify-content: center; gap: 12px;
  margin-top: 20px;
}
.pager__info { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }

/* --- Drawer ------------------------------------------------------------- */

.drawer { position: fixed; inset: 0; z-index: 60; }
.drawer__scrim {
  position: absolute; inset: 0;
  background: rgba(29, 38, 55, .42);
  backdrop-filter: blur(2px);
  animation: fade .18s var(--ease);
}
@keyframes fade { from { opacity: 0; } }
.drawer__panel {
  position: absolute; right: 0; top: 0; bottom: 0;
  width: min(560px, 100%);
  display: flex; flex-direction: column;
  background: var(--surface);
  box-shadow: var(--shadow-lift);
  animation: slide .22s var(--ease);
}
.drawer__panel--narrow { width: min(460px, 100%); }
@keyframes slide { from { transform: translateX(20px); opacity: .4; } }
@media (prefers-reduced-motion: reduce) {
  .drawer__panel, .drawer__scrim { animation: none; }
  * { transition-duration: .01ms !important; }
}
.drawer__head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 16px;
  padding: 22px 24px 18px;
  border-bottom: 1px solid var(--line);
}
.drawer__title { font-family: var(--serif); font-size: 22px; margin-top: 2px; }
.drawer__body { flex: 1; overflow-y: auto; padding: 24px; }
.drawer__foot {
  display: flex; align-items: center; gap: 10px;
  padding: 16px 24px;
  border-top: 1px solid var(--line);
  background: var(--surface-2);
}
.drawer__stamp { font-size: 11px; color: var(--faint); }
.pair { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; }
.prose { font-size: 13.5px; color: var(--muted); line-height: 1.7; margin-bottom: 20px; }
.prose strong { color: var(--text); font-weight: 500; }

.drop {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  min-height: 116px; padding: 24px;
  text-align: center; font-size: 13px; color: var(--muted);
  border: 1px dashed var(--line-strong); border-radius: var(--r-lg);
  cursor: pointer;
  transition: border-color .16s var(--ease), background .16s var(--ease);
}
.drop:hover, .drop--over { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
.drop__name { font-size: 12px; color: var(--accent); font-weight: 500; }
.hint { margin-top: 16px; font-size: 12.5px; color: var(--muted); }
.hint summary { cursor: pointer; color: var(--accent); }
.hint__cols { margin-top: 8px; line-height: 1.8; }
.result-list { margin-top: 16px; font-size: 13px; }
.result-list li { padding: 3px 0; color: var(--muted); }
.result-ok { color: var(--text); font-weight: 500; }

/* --- Toasts ------------------------------------------------------------- */

.toasts {
  position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%);
  z-index: 80; display: flex; flex-direction: column; gap: 8px; align-items: center;
  pointer-events: none;
}
.toast {
  padding: 10px 18px;
  font-size: 13px; color: var(--bg); background: var(--text);
  border-radius: var(--r-pill); box-shadow: var(--shadow-lift);
  animation: rise .2s var(--ease);
}
.toast--bad { background: var(--danger); color: #fff; }
@keyframes rise { from { transform: translateY(8px); opacity: 0; } }

/* =========================================================================
   Narrow screens
   -------------------------------------------------------------------------
   Below 1080px the table becomes cards. Der Schwellwert ist gemessen, nicht
   geraten: sieben Spalten echter Kundendaten brauchen mit der Wunsch-Spalte
   rund 1050 px, darunter kommt die Zeile nicht mehr unter,
   and the alternative — letting the table overflow — would scroll the whole
   page sideways, which is the one thing the layout must never do. Sorting is
   not dropped with the table: the sort <select> in the control row is always
   present, which is why the column headers are not the only way to reorder.
   ========================================================================= */

@media (max-width: 1080px) {
  .viewpick { display: none; }
  .tablewrap { border: 0; background: none; }
  .reg, .reg tbody, .reg tr, .reg td { display: block; width: 100%; }
  .reg thead { display: none; }
  .reg tbody tr {
    margin-bottom: 10px; padding: 16px;
    background: var(--surface);
    border: 1px solid var(--line); border-radius: var(--r-lg);
  }
  .reg td {
    display: grid; grid-template-columns: 118px 1fr; gap: 4px 14px;
    align-items: baseline;
    padding: 3px 0; text-align: left !important;
  }
  .reg td::before {
    content: attr(data-label);
    font-size: 10px; font-weight: 500; letter-spacing: .12em; line-height: 1.7;
    text-transform: uppercase; color: var(--faint);
  }
  .reg td.first { display: block; margin-bottom: 10px; }
  .reg td.first::before { display: none; }
  .reg td.empty-row { display: none; }

  /* Die aufgeklappte Zeile ist in der gestapelten Ansicht keine Zelle mit
     Beschriftung, sondern ein Block unter der Karte. */
  .reg tbody tr.detailrow { padding: 0; margin: -10px 0 10px; border: 0; background: none; }
  .reg tbody tr.detailrow > td { display: block; padding: 0; }
  .reg tbody tr.detailrow > td::before { display: none; }
  .reg tbody tr.auf { margin-bottom: 0; }
  .detail {
    padding: 14px 16px;
    background: var(--surface);
    border: 1px solid var(--line); border-top: 0;
    border-radius: 0 0 var(--r-lg) var(--r-lg);
    border-left-width: 2px; border-left-color: var(--accent-line);
  }
  .ddlist { grid-template-columns: 1fr; gap: 10px; }

}

/* Sehr schmale Geräte (iPhone SE der ersten Generation und ähnlich): neben
   einer 118-px-Beschriftungsspalte bleibt für einen langen Wert wie „Warten auf
   Kundenrückmeldung“ zu wenig übrig. Dort steht die Beschriftung über dem Wert
   statt daneben. */
@media (max-width: 420px) {
  .reg td { grid-template-columns: 1fr; gap: 0; }
  .reg tbody tr { padding: 14px; }
}

@media (max-width: 720px) {
  .wrap { padding: 16px 16px 96px; }
  .top { padding: 10px 16px; }
  .top__name { font-size: 16px; }
  .chooser__head, .chooser__body { padding-left: 20px; padding-right: 20px; }
  .chooser__title { font-size: 30px; }
  .filters-toggle { display: inline-flex; }
  .facets { display: none; }
  .facets--open { display: flex; }
  .sortpick__label { display: none; }
  .sortpick .select { min-width: 140px; }
  .pair { grid-template-columns: 1fr; }
  .drawer__foot { flex-wrap: wrap; }
}

/* Der Konfigurator-Kopf trägt drei Schaltflächen. Auf schmalen Geräten passen
   die zusammen mit dem Logo nicht in eine Zeile, deshalb entfällt dort die
   Bequemlichkeitsfunktion und die Bereichsbezeichnung — der Konfigurator
   benennt sich in seiner eigenen Kopfzeile ohnehin selbst. */
@media (max-width: 720px) {
  .nur-breit { display: none; }
}
@media (max-width: 560px) {
  body.hat-rahmen .top__id { display: none; }
  body.hat-rahmen .top__left { border-right: 0; }
}

@media (max-width: 560px) {
  /* The eyebrow wraps to two lines at this width and shoulders the buttons out
     of the bar. The workspace name alone is enough identification here. */
  .top__id .eyebrow { display: none; }
  .top__id { padding-left: 12px; }
  .top__left { gap: 12px; }
  .logo--mark { width: 112px; }
  .top__right { gap: 6px; }
  .btn { padding: 0 12px; letter-spacing: .06em; }
}

@media (max-width: 460px) {
  .top__right .btn--quiet#themeBtn { display: none; }   /* lives in the menu instead */
  .who { display: none !important; }
  .top__name { font-size: 15px; }
}

@media print {
  .top, .controls, .meta, .pager, .drawer, .toasts, .skip { display: none !important; }
  .tablewrap { border: 0; }
  .reg { font-size: 10pt; }
}
