/* ══ DESIGNSYSTEM ═══════════════════════════════════════════════════════════
   Tre lag, og kun det første må bandet ændre:

   1. TEMA-VÆRDIER (--ink*, --cream*, --accent*, --panel*, --field-bg).
      Navnene er gamle og siger en farve, ikke en rolle — men de SÆTTES af
      _applyThemeVars/_applyAppearanceOverrides (01-core.js) og applyBranding
      (09-boot.js), og ~1.100 inline-stilarter læser dem. De bliver.
   2. ROLLER (--surface, --text, --border …). Peger på lag 1. Ny kode bruger
      DISSE — så et fremtidigt lyst tema er et spørgsmål om lag 1 alene.
   3. SKALAER (afstand, type, radius, skygge, lag, bevægelse). Faste.

   Reglen for ny kode: ingen px-værdi eller farve i markup, der ikke findes
   her. Hvis den mangler, hører den til her — ikke inline. */
:root{
  /* 1 · tema-værdier (standard = "kul"; overskrives ved boot) */
  --ink-deep:#0A0A0A; --ink:#141414; --ink-soft:#1E1E1E; --ink-line:#2C2C2C;
  --ink-line-soft:rgba(255,255,255,.06); --ink-line-strong:rgba(255,255,255,.16);
  --panel:rgba(255,255,255,.045); --panel-2:rgba(255,255,255,.02); --field-bg:rgba(0,0,0,.28);
  --accent:#8A8A8A; --accent-soft:#A8A8A8; --accent-deep:#5C5C5C;
  /* Tekst PÅ accentfarven. Regnes af _saetAccent (01-core.js) ud fra
     accentens lyshed — en fast mørk tekst var ulæselig på et mørkt brand. */
  --on-accent:#0A0A0A;
  --cream:#F2F2F2; --cream-dim:#C9C9C9; --cream-mute:#8A8A8A;
  --ok:#7FB985; --warn:#E8A867; --danger:#D97A6C;
  --font-display:"Instrument Serif","Times New Roman",serif;
  --font-ui:"Inter",-apple-system,BlinkMacSystemFont,sans-serif;
  --font-mono:"JetBrains Mono",ui-monospace,monospace;

  /* 2 · roller */
  --surface:var(--ink-deep);            /* siden */
  --surface-1:var(--ink);               /* kort, sidemenu */
  --surface-2:var(--ink-soft);          /* hævet: menuer, dialoger */
  --surface-hover:color-mix(in srgb, var(--cream) 5%, transparent);
  --surface-sunken:var(--field-bg);     /* felter */
  --border:var(--ink-line);
  --border-soft:var(--ink-line-soft);
  --border-strong:var(--ink-line-strong);
  --text:var(--cream); --text-dim:var(--cream-dim); --text-muted:var(--cream-mute);
  --success:var(--ok); --warning:var(--warn);
  --success-soft:color-mix(in srgb, var(--ok) 14%, transparent);
  --warning-soft:color-mix(in srgb, var(--warn) 14%, transparent);
  --danger-soft:color-mix(in srgb, var(--danger) 14%, transparent);
  --accent-tint:color-mix(in srgb, var(--accent) 14%, transparent);
  --focus-ring:0 0 0 3px color-mix(in srgb, var(--accent) 45%, transparent);

  /* 3 · skalaer */
  --s-1:4px; --s-2:8px; --s-3:12px; --s-4:16px; --s-5:20px; --s-6:24px;
  --s-8:32px; --s-10:40px; --s-12:48px;
  --fs-xs:12px; --fs-sm:13px; --fs-base:15px; --fs-md:16px; --fs-lg:20px;
  --fs-xl:24px; --fs-2xl:32px; --fs-3xl:40px;
  --radius-sm:6px; --radius:8px; --radius-lg:12px; --radius-xl:16px; --radius-pill:999px;
  --shadow-1:0 1px 2px rgba(0,0,0,.25);
  --shadow-2:0 4px 16px rgba(0,0,0,.28), 0 1px 3px rgba(0,0,0,.2);
  --shadow-3:0 24px 64px rgba(0,0,0,.5), 0 2px 8px rgba(0,0,0,.3);
  --shadow-card:0 1px 0 rgba(245,237,224,.04) inset, 0 8px 24px rgba(0,0,0,.3);
  --z-nav:100; --z-drawer:300; --z-modal:10000; --z-toast:10100;
  --ease:cubic-bezier(.2,.8,.2,1); --dur:160ms;
}
*{box-sizing:border-box}
html,body{margin:0;padding:0;background:var(--surface);color:var(--text);font-family:var(--font-ui);font-size:var(--fs-base);line-height:1.5;-webkit-font-smoothing:antialiased;font-feature-settings:"cv11","ss01"}
/* Ét stille lys øverst i stedet for tre farvede tåger. */
/* To stille lys, så glasset har noget at ligge over: accenten øverst til
   venstre, tekstfarven svagt nederst til højre. Fast, så de ikke ruller med. */
body{min-height:100vh;background:radial-gradient(900px 500px at 15% -10%,color-mix(in srgb, var(--accent) 11%, transparent),transparent 70%),radial-gradient(800px 600px at 110% 110%,color-mix(in srgb, var(--cream) 5%, transparent),transparent 70%),var(--surface);background-attachment:fixed}
button{font-family:inherit;cursor:pointer;color:inherit}
input,textarea,select{font-family:inherit}
a{color:inherit;text-decoration:none}
::selection{background:color-mix(in srgb, var(--accent) 35%, transparent)}
/* Synlig tastaturfokus OVERALT. Musen får den ikke (:focus-visible). */
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:var(--radius-sm)}
.serif{font-family:var(--font-display);font-weight:400}
.mono{font-family:var(--font-mono);font-variant-numeric:tabular-nums}
.num{font-variant-numeric:tabular-nums}
/* Etiketter: små, rolige og i almindelig skrift. De var 10-11 px mono med
   versaler og spærret skrift — karakterfuldt, men svært at læse, og det
   gjorde at ALT så ens ud. */
.eyebrow{font-size:var(--fs-xs);font-weight:500;letter-spacing:.01em;color:var(--text-muted)}
.eyebrow.warm{color:var(--accent)}
.muted{color:var(--text-muted)}
.icon{width:16px;height:16px;flex:none;stroke:currentColor;fill:none;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round;vertical-align:-3px}
.icon-lg{width:20px;height:20px}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}

/* Buttons */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--s-2);min-height:36px;padding:0 var(--s-4);border-radius:var(--radius);font-size:var(--fs-sm);font-weight:500;line-height:1.2;border:1px solid transparent;background:transparent;color:var(--text);transition:background var(--dur) var(--ease),border-color var(--dur) var(--ease),color var(--dur) var(--ease),box-shadow var(--dur) var(--ease);white-space:nowrap;text-decoration:none}
.btn{-webkit-tap-highlight-color:transparent}
/* Tryk: knappen giver en anelse efter — mærkbart på en telefon, hvor der
   ikke findes hover (24/9). */
.btn:active:not(:disabled){transform:scale(.98)}
.btn-primary{background:var(--accent);color:var(--on-accent);font-weight:600;box-shadow:var(--shadow-1)}
.btn-primary:hover{background:var(--accent-soft)}
.btn-primary:disabled{opacity:.55;cursor:not-allowed}
.btn-ghost{background:var(--surface-hover);border-color:var(--border-strong);color:var(--text)}
.btn-ghost:hover{background:color-mix(in srgb, var(--cream) 9%, transparent);border-color:color-mix(in srgb, var(--cream) 26%, transparent)}
.btn-text{min-height:0;padding:var(--s-1) var(--s-1);background:transparent;color:var(--text-dim)}
.btn-text:hover{color:var(--accent)}
.btn-danger{background:transparent;border-color:color-mix(in srgb, var(--danger) 45%, transparent);color:var(--danger)}
.btn-danger:hover{background:var(--danger-soft)}
.btn-danger.solid{background:var(--danger);border-color:var(--danger);color:#fff}
.btn-sm{min-height:30px;padding:0 var(--s-3);font-size:var(--fs-xs)}
.btn-lg{min-height:44px;padding:0 var(--s-6);font-size:var(--fs-base)}
.btn-icon{min-height:32px;width:32px;padding:0}
.btn:focus-visible{outline:none;box-shadow:var(--focus-ring)}
.btn{transition:background var(--dur) var(--ease),border-color var(--dur) var(--ease),color var(--dur) var(--ease),box-shadow var(--dur) var(--ease),transform var(--dur) var(--ease)}
/* Hover med liv — kun hvor der ER en mus. På en touchskærm "hænger" hover
   efter et tryk, og knappen ville blive stående løftet (24/9). */
@media (hover:hover){
  .btn-primary:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 8px 22px -8px color-mix(in srgb, var(--accent) 70%, transparent),var(--shadow-1)}
  .btn-ghost:hover:not(:disabled),.btn-danger:hover:not(:disabled){transform:translateY(-1px)}
  .btn:active:not(:disabled){transform:translateY(0) scale(.98)}
}
/* "✓ Gemt" i selve knappen — se knapGemt i 01-core.js. */
.btn.btn-gemt,.btn.btn-gemt:hover{background:var(--success);border-color:var(--success);color:#fff;box-shadow:none;transform:none}
.btn-gemt .icon{animation:gemtPop .35s var(--ease)}
@keyframes gemtPop{0%{transform:scale(.4);opacity:0}70%{transform:scale(1.15)}100%{transform:scale(1);opacity:1}}
@media (prefers-reduced-motion: reduce){
  .btn,.btn:hover,.btn:active{transform:none !important;transition:none}
  .btn-gemt .icon{animation:none}
}

/* Cards */
/* ── Glas (23/9) ─────────────────────────────────────────────────────────
   ALLE bokse — kort, nøgletal, musikerens jobkort, booker- og operatør-
   panelets kort — og sidemenuen er samme halvgennemsigtige flade med let
   sløring og en hårfin lyskant foroven. Ét udtryk overalt; ingen boks har
   sin egen farve. Dialoger og menuer (.ui-modal) forbliver solide: de ligger
   OVER indholdet og skal kunne læses uanset hvad der er bag dem. */
/* Glasset skal SES, også når bandet har egne HEX-farver. Ren gennemsigtighed
   gjorde intet på dmdt: kortets #0F213C ligger så tæt på sidens #08111F, at
   62 % af det ene over det andet er samme farve. Derfor en gradient, som kun
   er afledt af tema-rollerne (--surface-1, --cream, --accent) og altså følger
   med, uanset om farverne kommer fra et tema eller fra bandets egne koder:
   lyst hjørne øverst til venstre, et svagt accent-skær nederst til højre, og
   mere gennemsigtigt mod bunden. */
.card,.stat-tile{background:
  radial-gradient(140% 100% at 0% 0%, color-mix(in srgb, var(--cream) 9%, transparent), transparent 55%),
  radial-gradient(90% 90% at 100% 100%, color-mix(in srgb, var(--accent) 7%, transparent), transparent 60%),
  linear-gradient(160deg, color-mix(in srgb, var(--surface-1) 92%, transparent) 0%, color-mix(in srgb, var(--surface-1) 38%, transparent) 100%);
  -webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);
  border:1px solid color-mix(in srgb, var(--cream) 10%, transparent);
  box-shadow:inset 0 1px 0 color-mix(in srgb, var(--cream) 12%, transparent), 0 10px 30px rgba(0,0,0,.25)}
/* Lyse temaer: tekstfarven er mørk, så "lyset" er hvidt, og skyggen let. */
/* Lyse temaer er IKKE mørkt glas med omvendte farver. Gennemsigtigheden lod
   den mørkere side skinne op gennem kortets bund (gråt "snavs"), og accent-
   skæret blev en brun plet. Her er kortene næsten uigennemsigtige og hvide
   foroven med et blødt fald, hvidt lys i hjørnet og en let skygge. */
:where(:root[data-tema="lys"]) .card,:where(:root[data-tema="lys"]) .stat-tile{background:
  radial-gradient(120% 80% at 0% 0%, rgba(255,255,255,.9), transparent 60%),
  linear-gradient(180deg, color-mix(in srgb, var(--surface-1) 97%, transparent) 0%, color-mix(in srgb, var(--surface-1) 84%, transparent) 100%);
  border-color:color-mix(in srgb, var(--cream) 9%, transparent);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.9), 0 1px 2px rgba(0,0,0,.04), 0 8px 24px rgba(0,0,0,.05)}
/* Sidens lys: tekstfarven er mørk, så hjørnet nederst til højre lysnes med
   hvidt i stedet for at blive gråt. */
:where(:root[data-tema="lys"]) body{background:radial-gradient(900px 500px at 15% -10%,color-mix(in srgb, var(--accent) 7%, transparent),transparent 70%),radial-gradient(800px 600px at 110% 110%,rgba(255,255,255,.55),transparent 70%),var(--surface);background-attachment:fixed}
.card{border-radius:var(--radius-lg);padding:var(--s-6)}
/* Mange kort med sløring er tungt på en telefon, og over en jævn baggrund
   ses sløringen alligevel ikke. Gennemsigtigheden bliver. */
@media (max-width:720px){.card,.stat-tile,.sidebar{-webkit-backdrop-filter:none;backdrop-filter:none}}
.card-head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--s-3);margin-bottom:var(--s-4)}
.card-title{font-family:var(--font-display);font-size:var(--fs-xl);font-weight:400;margin:2px 0 0;line-height:1.15}

/* Form */
.field{display:flex;flex-direction:column;gap:6px;min-width:0}
.field label{font-size:var(--fs-xs);font-weight:500;letter-spacing:.01em;color:var(--text-dim)}
.field .hint{font-size:var(--fs-xs);color:var(--text-muted)}
/* Feltfejl: rammen, teksten under og aria-invalid sættes af markFelt
   (01-core.js). Én fejl ved feltet slår en banner øverst, man skal lede efter. */
.field-fejl{display:none;font-size:var(--fs-xs);color:var(--danger)}
.field.has-error .field-fejl{display:block}
.field.has-error .input,.field.has-error .textarea,.field.has-error .select{border-color:var(--danger)}
.req::after{content:" *";color:var(--danger)}
.input,.textarea,.select{background:var(--surface-sunken);border:1px solid var(--border);border-radius:var(--radius);padding:9px 12px;min-height:38px;color:var(--text);font-size:14px;outline:none;transition:border-color var(--dur),box-shadow var(--dur);width:100%}
.input::placeholder,.textarea::placeholder{color:color-mix(in srgb, var(--cream-mute) 80%, transparent)}
.input[type=number]{-moz-appearance:textfield}
.input[type=number]::-webkit-inner-spin-button,
.input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}
.member-pill-row{display:flex;flex-wrap:wrap;gap:14px 18px;align-items:flex-start}
.member-pill{display:flex;flex-direction:column;align-items:center;gap:4px;min-width:64px;text-align:center}
.member-pill .avatar{width:42px;height:42px;border-radius:50%;background:var(--surface-2);border:1px solid var(--border);display:flex;align-items:center;justify-content:center;color:var(--accent);font-size:13px;font-weight:600}
button:disabled{opacity:.55;cursor:not-allowed}
/* Øjet i kodefelterne (01-core.js, _kodeOejne). */
.kode-kasse{position:relative;display:block;width:100%}
.kode-kasse>.input{padding-right:42px}
.kode-oeje{position:absolute;top:50%;right:4px;transform:translateY(-50%);width:34px;height:34px;display:flex;align-items:center;justify-content:center;background:none;border:0;border-radius:var(--radius);color:var(--text-mute,var(--cream-mute));cursor:pointer}
.kode-oeje:hover{color:var(--text)}
.kode-oeje:focus-visible{outline:none;box-shadow:var(--focus-ring)}
.input:focus,.textarea:focus,.select:focus{border-color:var(--accent);box-shadow:var(--focus-ring)}
.textarea{min-height:70px;resize:vertical;font-family:inherit}

/* ── Mærkater — ÉT system ──────────────────────────────────────────────────
   Der var fem (.badge, .count-badge, .job-status-tag, .job-archived-tag,
   .job-note-tag), hver med sin størrelse og kant. De gamle klassenavne
   bruges stadig i markup'en, så de er samlet her under ét udseende. */
.badge,.count-badge,.job-status-tag,.job-archived-tag,.job-note-tag{display:inline-flex;align-items:center;gap:6px;padding:2px 9px;min-height:22px;border-radius:var(--radius-pill);font-size:var(--fs-xs);font-weight:500;line-height:1.3;letter-spacing:0;text-transform:none;font-family:var(--font-ui);white-space:nowrap;vertical-align:middle;border:1px solid transparent;background:color-mix(in srgb, var(--cream) 7%, transparent);color:var(--text-dim)}
.badge.amber,.count-badge,.job-note-tag{background:var(--accent-tint);color:var(--accent)}
.badge.ok,.job-status-tag.ok{background:var(--success-soft);color:var(--success)}
.badge.warn,.job-status-tag.warn{background:var(--warning-soft);color:var(--warning)}
.badge.danger{background:var(--danger-soft);color:var(--danger)}
.badge.mute,.job-status-tag.mute,.job-archived-tag{background:color-mix(in srgb, var(--cream) 6%, transparent);color:var(--text-muted)}
.badge-dot{width:6px;height:6px;border-radius:50%;background:currentColor;flex:none}

/* ── Segmenterede kontroller — ÉT udseende ─────────────────────────────────
   Fire implementeringer (.mode-pill, .filter-pill, .seg, .bk-seg) plus
   .job-filter-pill. JS sætter stadig .on/.active på de gamle navne. */
.mode-pill,.filter-pill,.seg,.bk-seg{display:inline-flex;gap:2px;padding:3px;border-radius:var(--radius);background:var(--surface-sunken);border:1px solid var(--border-soft)}
.mode-pill button,.filter-pill button,.seg button,.bk-seg-knap{padding:6px 12px;min-height:30px;border:0;background:transparent;color:var(--text-muted);font-family:var(--font-ui);font-size:var(--fs-sm);font-weight:500;letter-spacing:0;text-transform:none;border-radius:calc(var(--radius) - 3px);cursor:pointer;transition:background var(--dur),color var(--dur)}
.mode-pill button:hover,.filter-pill button:hover,.seg button:hover,.bk-seg-knap:hover{color:var(--text)}
.mode-pill button.on,.filter-pill button.on,.seg button.on,.bk-seg-knap.on{background:var(--surface-2);color:var(--text);box-shadow:var(--shadow-1),inset 0 0 0 1px var(--border)}

/* Stat tile — et nøgletal. Kan være en knap (klikbar genvej). */
/* flex-kolonne, ikke block: en <button> centrerer sit indhold lodret, saa et
   tal uden .sub fik etiketten laengere nede end naboerne i samme raekke. */
/* Nøgletal: samme glas som .card (se "Glas" nedenfor), ens og dæmpede. */
.stat-tile{position:relative;overflow:hidden;display:flex;flex-direction:column;justify-content:flex-start;width:100%;text-align:left;padding:var(--s-5);border:1px solid var(--border-soft);border-radius:var(--radius-lg);color:var(--text);font:inherit}
button.stat-tile{cursor:pointer;transition:border-color var(--dur),background var(--dur),transform var(--dur) var(--ease)}
button.stat-tile:hover{border-color:var(--border-strong);transform:translateY(-1px)}
.stat-tile .label{font-size:var(--fs-xs);font-weight:500;color:var(--text-muted);margin-bottom:var(--s-2);display:flex;align-items:center;gap:8px}
.dash-stats .stat-tile{min-height:132px}
.stat-ikon{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;border-radius:50%;background:var(--surface-hover);color:var(--text-dim);flex:none}
.stat-ikon .icon{width:14px;height:14px;vertical-align:0}
.stat-tile .value{font-family:var(--font-display);font-size:clamp(26px,2.2vw,36px);color:var(--text);line-height:1;font-variant-numeric:tabular-nums}
.dash-stats .stat-tile .value{margin-top:var(--s-4)}
.stat-tile .value.warm{color:var(--accent)}
.stat-tile .sub{font-size:var(--fs-xs);color:var(--text-muted);margin-top:6px}

/* Avatar */
.avatar{width:40px;height:40px;border-radius:50%;background:var(--surface-2);color:var(--text);display:inline-flex;align-items:center;justify-content:center;font-size:14px;font-weight:600;flex-shrink:0;border:1px solid var(--border)}

/* Table */
/* Dashboardets nøgletal og de to kort under dem deler ÉT gitter: fire lige
   spalter med samme mellemrum, hvor jobs-kortet spænder over tre. Den højre
   spalte var før fast 320 px med 16 px gap, mens tallene var auto-fit med
   12 px — arrangør-kortet flugtede derfor ikke med "Aktive medlemmer".
   stretch, ikke start: med tomme lister var de to kort forskelligt hoeje
   (jobs-kortets tomtilstand har en knap, arrangoer-kortets ikke). */
.dash-stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px}
/* Fire i rækken kræver ~210 px pr. nøgletal. Under 1200 px skærmbredde
   ombrød etiketter og undertekster (målt 24/9: "Din andel af de kommende"
   på to linjer ved 1100, etiketterne ved 1000, og 109 px brede felter ved
   800). 2x2 derunder — mobilblokken gør det samme. */
@media (max-width:1199px){.dash-stats{grid-template-columns:repeat(2,minmax(0,1fr))}}
.dash-split{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;align-items:stretch;min-width:0}
.dash-split>*{min-width:0}
.dash-split>:first-child{grid-column:span 3}
/* Under 1100 px bliver en fjerdedel for smal til arrangør-rækkerne; så
   ligger kortet under jobs-kortet i fuld bredde. */
@media (max-width:1100px){
  .dash-split{grid-template-columns:1fr}
  .dash-split>:first-child{grid-column:auto}
}
/* Rullefladen om enhver tabel, ved ALLE bredder — ikke kun paa mobil.
   En tabel er bredere end sin spalte laenge foer man naar en telefon:
   "Kommende jobs" er 574 px, og dashboardets venstre spalte er 452 px paa en
   1100 px skaerm. Uden det her voksede tabellen ud af kortet og blev tegnet
   OVEN PAA nabokortet — tegnene stod bogstavelig talt oven i hinanden.
   `display:block` paa selve tabellen duer ikke som loesning: saa holder den
   op med at fylde spalten ud naar indholdet er smallere. */
.table-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch;max-width:100%}
.table{width:100%;border-collapse:collapse}
.table th{text-align:left;font-size:var(--fs-xs);font-weight:500;letter-spacing:0;text-transform:none;color:var(--text-muted);padding:10px 12px;border-bottom:1px solid var(--border-soft);white-space:nowrap}
.table td{padding:12px;border-bottom:1px solid var(--border-soft);font-size:14px;vertical-align:middle}
.table tbody tr:last-child td{border-bottom:0}
.table tr:hover td{background:var(--surface-hover)}
.table tr.clickable{cursor:pointer}
.table tr.clickable:focus-visible{outline:none}
.table tr.clickable:focus-visible td{background:var(--accent-tint)}
.table td.num,.table th.num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}

/* ─── LOGIN ────────────────────────────────── */
.login-wrap{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:20px}
.login-card{position:relative;width:100%;max-width:420px;padding:40px 36px;border-radius:var(--radius-xl);box-shadow:var(--shadow-3)}
.login-brand{text-align:center;margin-bottom:24px}
.login-card h1{font-family:var(--font-display);font-size:var(--fs-3xl);font-weight:400;margin:0 0 6px;line-height:1.05;text-align:center;letter-spacing:-.01em}
.login-card .lede{color:var(--text-muted);text-align:center;font-size:14px;margin-bottom:24px}
.login-form .field{margin-bottom:14px}
/* "Vælg visning" — beholdt med vilje (Jonas, 23/9); kun udseendet er nyt. */
.visning-valg{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.visning-kort{display:flex;flex-direction:column;align-items:center;gap:6px;padding:22px 14px;background:var(--surface-sunken);border:1px solid var(--border);border-radius:var(--radius-lg);color:var(--text);font:inherit;cursor:pointer;transition:border-color var(--dur),background var(--dur)}
.visning-kort:hover{border-color:var(--accent);background:var(--accent-tint)}
.visning-kort strong{font-size:15px;font-weight:600}
.visning-kort span:last-child{font-size:var(--fs-xs);color:var(--text-muted)}
.visning-ikon{display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;border-radius:50%;background:var(--accent-tint);color:var(--accent);margin-bottom:4px}
.login-err{display:none;background:var(--danger-soft);border:1px solid color-mix(in srgb, var(--danger) 35%, transparent);color:var(--danger);padding:10px 12px;border-radius:var(--radius);font-size:13px;margin-bottom:14px}
.login-err.show{display:block}
.login-status{display:none;color:var(--cream-mute);font-size:12px;margin-top:10px;text-align:center}
.login-status.show{display:block}
.spinner{display:inline-block;width:12px;height:12px;border:2px solid color-mix(in srgb, var(--cream) 20%, transparent);border-top-color:var(--accent);border-radius:50%;animation:sp .8s linear infinite;vertical-align:middle;margin-right:6px}
@keyframes sp{to{transform:rotate(360deg)}}
.load-error{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:16px 18px;margin:8px 0;border:1px solid rgba(217,122,108,.4);background:rgba(217,122,108,.08);border-radius:var(--radius);color:var(--cream-dim);font-size:13px}
.load-error .load-error-icn{color:var(--danger);font-size:16px}

/* ─── ADMIN SHELL ──────────────────────────── */
.admin-shell{display:grid;grid-template-columns:248px minmax(0,1fr);min-height:100vh}
/* Her stod en regel der gjorde skallen til én kolonne ved <=900 px. Men
   sidemenuen skjules først ved <=768 px, så i mellemrummet — fx en telefon
   på langs (844x390) eller en iPad Air på højkant (820) — lå den fulde
   sidemenu (100vh, sticky) OVEN PÅ indholdet. Fjernet 24/9: menu + indhold
   side om side ned til 768, derefter bundbjælken. */
/* ── Mobile navigation ── */
.mobile-nav{display:none}
.sidebar{position:sticky;top:0;height:100vh;overflow-y:auto;background:color-mix(in srgb, var(--surface-1) 45%, transparent);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);border-right:1px solid var(--border-soft);padding:20px 12px;display:flex;flex-direction:column}
.sidebar-brand{display:flex;align-items:center;gap:10px;margin-bottom:24px;padding:4px 10px}
.nav-group{display:flex;flex-direction:column;gap:2px;margin-bottom:18px}
/* Knapper, ikke div'er: de skal kunne nås med tastaturet. */
.nav-item{display:flex;align-items:center;gap:10px;width:100%;min-height:36px;padding:0 10px;border-radius:var(--radius);color:var(--text-dim);font-size:14px;font-weight:500;cursor:pointer;transition:background var(--dur),color var(--dur);border:0;background:transparent;text-align:left;font-family:inherit}
.nav-item:hover{background:var(--surface-hover);color:var(--text)}
.nav-item.on{background:var(--accent-tint);color:var(--text);box-shadow:inset 2px 0 0 var(--accent)}
.nav-item .icn{display:inline-flex;width:18px;justify-content:center;color:var(--text-muted);flex:none}
.nav-item.on .icn{color:var(--accent)}
.nav-item .nav-badge{margin-left:auto;min-width:20px;height:20px;padding:0 6px;border-radius:var(--radius-pill);background:var(--danger);color:#fff;font-size:11px;font-weight:600;display:none;align-items:center;justify-content:center;font-family:var(--font-ui)}
.nav-label{padding:0 10px;margin:6px 0 6px;font-size:var(--fs-xs);color:var(--text-muted);font-weight:500}
.sidebar-foot{margin-top:auto;padding-top:12px;border-top:1px solid var(--border-soft);display:flex;flex-direction:column;gap:2px}
/* Ingen fast maksbredde: på en stor skærm stod der ellers en bred tom stribe
   til højre, mens arrangørlinjerne blev klippet af (23/9). */
.main{padding:32px 40px 48px;overflow-x:hidden;overflow-x:clip;width:100%}
@media (max-width:720px){.main{padding:20px}}
.page-head{display:flex;justify-content:space-between;align-items:flex-end;flex-wrap:wrap;gap:14px;margin-bottom:var(--s-6)}
.page-head h1{font-family:var(--font-display);font-size:var(--fs-3xl);font-weight:400;margin:0;line-height:1.05;letter-spacing:-.01em}
.page-head .lede{color:var(--text-muted);font-size:14px;margin-top:6px}
.page-head .eyebrow{margin-bottom:4px}
.section-title{font-family:var(--font-display);font-size:var(--fs-xl);font-weight:400;margin:0;line-height:1.15}

/* Filter bar */
.filter-bar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:16px}

/* Members grid */
.member-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:12px}
.member-card{padding:18px;display:flex;gap:14px;align-items:flex-start;cursor:pointer;transition:border-color var(--dur),background var(--dur)}
.member-card:hover{border-color:var(--border-strong)}
.member-card .info{flex:1;min-width:0}
.member-card .name{font-family:var(--font-display);font-size:19px;line-height:1.15;margin:0 0 2px}
.member-card .role-line{font-size:var(--fs-xs);font-weight:500;color:var(--accent);margin-bottom:8px}
.member-card .meta{font-size:var(--fs-xs);color:var(--text-muted);line-height:1.6;word-break:break-all}

/* Drawer */
.drawer-backdrop{position:fixed;inset:0;background:color-mix(in srgb, var(--ink-deep) 65%, transparent);backdrop-filter:blur(3px);z-index:var(--z-drawer);display:none}
.drawer-backdrop.show{display:block;animation:fadeIn var(--dur) ease}
@keyframes fadeIn{from{opacity:0}to{opacity:1}}
.drawer{position:fixed;top:0;right:0;bottom:0;width:460px;max-width:100vw;background:var(--surface-1);border-left:1px solid var(--border);box-shadow:var(--shadow-3);z-index:calc(var(--z-drawer) + 1);display:none;flex-direction:column;overflow-y:auto}
.drawer.show{display:flex;animation:slideIn .22s var(--ease)}
@keyframes slideIn{from{transform:translateX(24px);opacity:0}to{transform:translateX(0);opacity:1}}
.drawer-head{position:sticky;top:0;z-index:1;background:var(--surface-1);padding:18px 24px;border-bottom:1px solid var(--border-soft);display:flex;justify-content:space-between;align-items:center;gap:12px}
.drawer-head h2{font-family:var(--font-display);font-size:var(--fs-xl);margin:0;font-weight:400}
.drawer-body{padding:24px;flex:1;display:flex;flex-direction:column;gap:14px}
.drawer-foot{position:sticky;bottom:0;background:var(--surface-1);padding:16px 24px;border-top:1px solid var(--border-soft);display:flex;gap:10px;justify-content:space-between}
.row-2{display:grid;grid-template-columns:1fr 1fr;gap:12px}

/* Contract editor */
.contract-split{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:0;min-height:calc(100vh - 140px);border:1px solid var(--border-soft);border-radius:var(--radius-lg);overflow:hidden;background:var(--surface-1)}
@media (max-width:1100px){.contract-split{grid-template-columns:1fr}}
.contract-form{padding:8px 32px 60px;border-right:1px solid var(--border-soft);overflow-y:auto;max-height:calc(100vh - 140px)}
@media (max-width:1100px){.contract-form{border-right:none;border-bottom:1px solid var(--border-soft);max-height:none}}
.form-section{padding:24px 0;border-bottom:1px solid var(--border-soft)}
.form-section:last-child{border-bottom:none}
.form-section-head{display:flex;align-items:center;gap:12px;margin-bottom:16px}
/* Nummeret er en lille rund markør, ikke en mono-kode. */
.form-section-num{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:50%;background:var(--accent-tint);color:var(--accent);font-family:var(--font-ui);font-size:12px;font-weight:600;letter-spacing:0;flex:none}
.form-section-title{font-family:var(--font-display);font-size:var(--fs-lg);margin:0;color:var(--text);font-weight:400}
.form-section-body{display:flex;flex-direction:column;gap:14px}
/* Sammenfoldelig sektion (<details>) — de sjældne dele af editoren. */
details.form-section > summary{list-style:none;cursor:pointer}
details.form-section > summary::-webkit-details-marker{display:none}
details.form-section > summary .form-section-head{margin-bottom:0}
details.form-section[open] > summary .form-section-head{margin-bottom:16px}
details.form-section > summary .fold{margin-left:auto;color:var(--text-muted);transition:transform var(--dur)}
details.form-section[open] > summary .fold{transform:rotate(180deg)}
details.form-section > summary .fold-sum{font-size:var(--fs-xs);color:var(--text-muted);font-weight:400}
.row-3{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
@media (max-width:540px){.row-3{grid-template-columns:1fr}}
.rider-note{font-size:var(--fs-sm);color:var(--text-dim);padding:10px 12px;background:var(--accent-tint);border-radius:var(--radius);line-height:1.5}

/* Attendees grid */
.attendees-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:8px}
.attend-chip{position:relative;display:flex;align-items:center;gap:10px;padding:10px 12px;border:1px solid var(--border);border-radius:var(--radius);cursor:pointer;transition:border-color var(--dur),background var(--dur);background:var(--surface-sunken)}
.attend-chip.on{border-color:var(--accent);background:var(--accent-tint)}
.attend-chip:hover{border-color:var(--border-strong)}
.chip-name{font-size:13px;color:var(--text);font-weight:500}
.chip-role{font-size:var(--fs-xs);color:var(--text-muted)}
.chip-share{margin-left:auto;width:80px}
.chip-share .input{padding:4px 6px;font-size:12px;text-align:right}
.attend-tick{width:20px;height:20px;border-radius:50%;border:1px solid var(--border-strong);display:flex;align-items:center;justify-content:center;font-size:11px;color:transparent;flex-shrink:0}
.attend-chip.on .attend-tick{background:var(--accent);color:var(--on-accent);border-color:var(--accent)}

/* PDF preview */
.contract-preview{padding:28px 32px 60px;background:#E8E4DF;overflow-y:auto;max-height:calc(100vh - 100px)}
@media (max-width:1100px){.contract-preview{max-height:none}}
.preview-toolbar{display:flex;justify-content:space-between;align-items:center;margin-bottom:18px}
.pdf-page{background:#ffffff;color:#1A1A1A;padding:36px 40px;border-radius:2px;box-shadow:0 4px 16px rgba(0,0,0,.18),0 1px 4px rgba(0,0,0,.12);font-family:'Inter',sans-serif;font-size:12px;line-height:1.5;max-width:540px;margin:0 auto;position:relative}
.pdf-eyebrow{font-family:var(--font-mono);font-size:9px;letter-spacing:.16em;text-transform:uppercase;color:#8A6F4D}
.pdf-big{font-family:var(--font-display);font-size:32px;color:#0F213C;margin-top:2px;line-height:1}
.pdf-strong{color:#0F213C;font-weight:600;font-size:13px;margin-top:2px}
.pdf-text{color:#2A2A2A;font-size:12px}
.pdf-divider{border-top:1px solid #E5DAC4;margin:18px 0}
.pdf-grid{display:grid;grid-template-columns:1fr 1fr;gap:24px}
.pdf-grid-3{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
.pdf-attendees{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px}
.pdf-attendee{background:#EFE3CC;padding:3px 8px;border-radius:3px;font-size:11px;color:#0F213C}
.pdf-foot{margin-top:24px;padding-top:14px;border-top:1px solid #E5DAC4;font-size:10px;color:#6A5A40}

/* Segmented type picker — udseendet er fælles (se "Segmenterede kontroller");
   her kun at den fylder bredden i editoren. */
.seg{width:100%;max-width:340px}
.seg button{flex:1}

/* ─── MEMBER APP ─────────────────────────── */
.member-app{min-height:100vh;display:flex;flex-direction:column}
.member-topbar{position:sticky;top:0;z-index:var(--z-nav);padding:12px 28px;border-bottom:1px solid var(--border-soft);display:flex;justify-content:space-between;align-items:center;gap:14px;flex-wrap:wrap;background:color-mix(in srgb, var(--surface) 82%, transparent);backdrop-filter:blur(10px)}
.member-topbar .me{display:flex;align-items:center;gap:12px}
.member-topbar .me .name{font-family:var(--font-display);font-size:19px;line-height:1.1}
.member-main{padding:32px 28px;flex:1;max-width:920px;margin:0 auto;width:100%}
@media (max-width:540px){.member-main{padding:20px}}
.job-card{display:grid;grid-template-columns:84px 1fr auto;gap:18px;padding:18px;align-items:center;cursor:pointer;transition:border-color var(--dur);margin-bottom:10px}
.job-card:hover{border-color:var(--border-strong)}
.job-date{text-align:center;border-right:1px solid var(--border-soft);padding-right:14px}
.job-date .month{font-size:var(--fs-xs);font-weight:600;color:var(--accent);text-transform:uppercase;letter-spacing:.04em}
.job-date .day{font-family:var(--font-display);font-size:38px;line-height:1;color:var(--text)}
.job-date .year{font-size:var(--fs-xs);color:var(--text-muted);margin-top:2px}
.job-info{min-width:0}
.job-venue{font-family:var(--font-display);font-size:22px;line-height:1.15;margin:0 0 4px}
.job-meta{font-size:var(--fs-sm);color:var(--text-muted)}
.job-share{font-size:15px;font-weight:600;color:var(--accent);margin-top:6px;font-variant-numeric:tabular-nums}
.job-km{font-size:var(--fs-xs);color:var(--text-muted);margin-top:2px}
.job-side{display:flex;flex-direction:column;align-items:flex-end;justify-content:space-between;gap:10px;border-left:1px solid var(--border-soft);padding-left:18px;min-width:130px;text-align:right}
.job-countdown-line{font-family:var(--font-display);font-size:18px;color:var(--accent);line-height:1.1;white-space:nowrap}
.job-addr-link{font-size:var(--fs-xs);color:var(--text-muted);text-decoration:none;text-align:right;line-height:1.3;max-width:180px;overflow:hidden;text-overflow:ellipsis;display:block}
.job-addr-link:hover{color:var(--accent)}
@media (max-width:640px){
  .job-card{grid-template-columns:70px 1fr;gap:10px;padding:14px}
  .job-side{grid-column:1/-1;border-left:none;border-top:1px solid var(--ink-line-soft);padding-left:0;padding-top:10px;flex-direction:row;align-items:center;justify-content:space-between;min-width:0;text-align:left}
  .job-addr-link{text-align:left;max-width:none}
}
/* Reserveret: "hold datoen", ikke et job med detaljer — lettere og stiplet. */
.card.job-card-reserveret{background:color-mix(in srgb, var(--surface-1) 28%, transparent);border-style:dashed;border-color:var(--border);box-shadow:none}
.job-card-archived{opacity:.55}
.job-card-archived:hover{opacity:.85}
/* Mærkaterne på jobkortet har fælles udseende (se "Mærkater"); her kun
   placeringen. Aftalens status på kortet findes fordi et job der IKKE var
   underskrevet så præcis ud som et der var — musikeren kunne ikke se om
   datoen var en aftale eller en reservation. */
.job-archived-tag,.job-status-tag{margin-left:8px}
.job-note-tag{margin-top:6px}
.job-filter-row{display:flex;gap:6px;margin-bottom:12px;flex-wrap:wrap}
.job-filter-pill{font-family:var(--font-ui);font-size:var(--fs-sm);font-weight:500;padding:6px 12px;min-height:32px;border-radius:var(--radius-pill);border:1px solid var(--border);background:transparent;color:var(--text-muted);cursor:pointer;transition:background var(--dur),color var(--dur),border-color var(--dur)}
.job-filter-pill:hover{color:var(--text);border-color:var(--border-strong)}
.job-filter-pill.active{background:var(--accent);color:var(--on-accent);border-color:var(--accent)}
.job-filter-pill{white-space:nowrap}
.job-opdater{margin-left:auto}
/* Telefon på højkant: de tre filtre + "Opdater" var 440 px i en 343 px
   række, så Opdater knækkede ned på sin egen linje ude til højre (24/9).
   Nu én linje: Opdater bliver en rund ikonknap, pillerne lidt smallere, og
   rækken kan rulles sidelæns hvis tallene bliver lange. */
@media (max-width:720px){
  .job-filter-row{flex-wrap:nowrap;gap:5px;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}
  .job-filter-row::-webkit-scrollbar{display:none}
  .job-filter-row .job-filter-pill{padding:6px 8px;font-size:13px;flex:none}
  .job-opdater{width:34px;padding:0 !important;justify-content:center;display:inline-flex;align-items:center}
  .job-opdater .opd-tekst{display:none}
}
.kv-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:14px;margin-top:6px}
@media (max-width:540px){.kv-grid{grid-template-columns:1fr}}
.kv .label{font-size:var(--fs-xs);font-weight:500;color:var(--text-muted);margin-bottom:2px}
.kv .value{font-family:var(--font-display);font-size:20px;color:var(--text)}

/* ── Tom tilstand ─────────────────────────────────────────────────────────
   .empty alene er den gamle, tekst-only. Med .empty-ikon/.empty-titel/
   .empty-handling (se tomTilstand i 01-core.js) får den et ikon og en knap
   videre — en tom liste skal sige hvad man gør nu, ikke bare at den er tom. */
.empty{text-align:center;padding:48px 20px;color:var(--text-muted);font-size:14px}
.empty-ikon{display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;border-radius:50%;background:var(--surface-hover);color:var(--text-dim);margin-bottom:12px}
.empty-ikon .icon{width:20px;height:20px}
.empty-titel{color:var(--text);font-weight:600;font-size:15px;margin-bottom:4px}
.empty-handling{margin-top:16px}
.flex{display:flex;align-items:center;gap:12px}
.grid-4{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px}

/* ── Skelet (indlæsning) ── */
.skel{position:relative;overflow:hidden;background:color-mix(in srgb, var(--cream) 6%, transparent);border-radius:var(--radius-sm);min-height:12px}
.skel::after{content:"";position:absolute;inset:0;transform:translateX(-100%);background:linear-gradient(90deg,transparent,color-mix(in srgb, var(--cream) 7%, transparent),transparent);animation:skel 1.4s infinite}
@keyframes skel{to{transform:translateX(100%)}}

/* ── Toast ── */
.toast{position:fixed;bottom:24px;left:50%;transform:translateX(-50%);display:flex;align-items:center;gap:10px;max-width:min(520px,calc(100vw - 32px));background:var(--surface-2);border:1px solid var(--border-strong);padding:10px 14px 10px 16px;border-radius:var(--radius-lg);font-size:14px;z-index:var(--z-toast);animation:toastInd .22s var(--ease);box-shadow:var(--shadow-2);transition:opacity .3s}
.toast .icon{color:var(--success)}
.toast.err{border-color:color-mix(in srgb, var(--danger) 45%, transparent)}
.toast.err .icon{color:var(--danger)}
.toast .toast-luk{margin-left:6px;min-height:28px;width:28px;padding:0;color:var(--text-muted)}
@keyframes toastInd{from{opacity:0;transform:translate(-50%,8px)}to{opacity:1;transform:translate(-50%,0)}}
@media (max-width:768px){.toast{bottom:76px}}
/* Sticky toast: bliver staaende til brugeren lukker den. Bruges til vaerdier
   der kun vises EN gang — startkoder — hvor to sekunder ikke raekker. */
.toast.sticky{padding:16px 18px;flex-direction:column;align-items:stretch;gap:10px}
.toast.sticky .toast-msg{line-height:1.5}
.toast.sticky .toast-val{background:var(--surface);border:1px solid var(--border-strong);border-radius:var(--radius-sm);padding:10px 12px;font-size:15px;letter-spacing:.06em;color:var(--text);user-select:all;word-break:break-all}
.toast.sticky .toast-actions{display:flex;gap:8px;justify-content:flex-end}

/* ── Dialog (uiConfirm / uiPrompt i 01-core.js) ──────────────────────────
   Erstatter browserens confirm()/prompt(): de kan ikke styles, låser hele
   fanen og ser ud som en advarsel fra browseren — ikke fra appen. */
.ui-modal-bag{position:fixed;inset:0;z-index:var(--z-modal);background:color-mix(in srgb, var(--ink-deep) 70%, transparent);backdrop-filter:blur(4px);display:flex;align-items:center;justify-content:center;padding:16px;animation:fadeIn var(--dur) ease}
.ui-modal{width:100%;max-width:460px;max-height:calc(100dvh - 32px);overflow:auto;background:var(--surface-2);border:1px solid var(--border);border-radius:var(--radius-xl);box-shadow:var(--shadow-3);animation:modalInd .2s var(--ease)}
.ui-modal.bred{max-width:600px}
@keyframes modalInd{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
.ui-modal-krop{padding:24px 24px 8px}
.ui-modal-ikon{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:50%;background:var(--accent-tint);color:var(--accent);margin-bottom:14px}
.ui-modal-ikon.fare{background:var(--danger-soft);color:var(--danger)}
.ui-modal-ikon .icon{width:20px;height:20px}
.ui-modal h2{font-family:var(--font-display);font-weight:400;font-size:var(--fs-xl);line-height:1.2;margin:0 0 8px}
.ui-modal-tekst{color:var(--text-dim);font-size:14px;line-height:1.6;white-space:pre-line}
.ui-modal-tekst p{margin:0 0 10px}
.ui-modal-felter{display:flex;flex-direction:column;gap:12px;margin-top:16px}
.ui-modal-liste{margin:12px 0 0;padding:12px 14px;border-radius:var(--radius);background:var(--surface-sunken);display:grid;grid-template-columns:auto 1fr;gap:6px 14px;font-size:13px}
.ui-modal-liste dt{color:var(--text-muted)}
.ui-modal-liste dd{margin:0;color:var(--text);word-break:break-word}
.ui-modal-fod{display:flex;justify-content:flex-end;gap:10px;padding:16px 24px 20px;flex-wrap:wrap}
@media (max-width:480px){.ui-modal-fod .btn{flex:1}}

/* ── Databehandleraftalens dialog ──────────────────────────────────────────
   Paa en bred skaerm er kortet en fast hoejde med aftaleteksten rullende
   indeni. Paa en telefon duer det ikke: de faste dele — overskrift, ramme-
   boks, kontoboks, kryds, to knapper og fodnote — fylder naesten hele
   skaermen, saa tekstfeltet blev presset ned paa 30 px, og fodnoten
   overflowede kortet med 26 px og blev skaaret af. Maalt 21/9 paa 375x812.
   Under 768 px ruller HELE kortet i stedet, og teksten faar sin naturlige
   hoejde — en rulleflade inden i en rulleflade er alligevel elendig med
   fingeren. */
/* overflow:auto ogsaa paa bred skaerm. `.dpa-tekst` kan ikke krympe under sin
   min-height, saa i et lavt vindue (fx 1100x800) summede de faste dele til
   mere end 88vh, og fodnoten hang neden for kortets kant. Nu ruller kortet i
   stedet. Ved rigelig hoejde ses ingen forskel. */
.dpa-card{max-width:680px;max-height:88vh;display:flex;flex-direction:column;padding:24px;overflow:auto}
.dpa-tekst{flex:1;min-height:140px;overflow:auto;font-size:13px;color:var(--cream-dim);line-height:1.6;border:1px solid var(--ink-line-soft);border-radius:8px;padding:14px;margin-bottom:14px}
.dpa-handling{margin-top:auto}
@media (max-width:768px){
  /* dvh foelger browserens adressefelt; vh goer ikke, og de sidste linjer
     havner under kanten paa iOS. vh staar foerst som fallback. */
  .dpa-card{max-height:calc(100vh - 24px);max-height:calc(100dvh - 24px);overflow:auto;padding:18px}
  .dpa-tekst{flex:none;min-height:0;overflow:visible}
  /* Kryds og knapper KLAEBER til bunden af det rullende kort. Uden det ville
     man skulle rulle forbi ~2.700 px aftaletekst for at naa "Accepter" —
     teksten skal kunne laeses, men handlingen skal kunne naas. */
  .dpa-handling{position:sticky;bottom:-18px;z-index:1;
    margin:0 -18px -18px;padding:12px 18px 18px;
    /* UGENNEMSIGTIG. --panel-2 er rgba(255,255,255,.02) — praktisk talt
       gennemsigtig — saa aftaleteksten rullede synligt bag krydset og
       knapperne og gjorde begge dele ulaeselige. --ink er temaets faste
       flade og foelger med naar bandet skifter tema. */
    background:var(--ink);border-top:1px solid var(--ink-line)}
}

/* ── Mobil-overstyringerne ligger til SIDST med vilje ─────────────────────
   De stod foer her oppe, foer basisreglerne de skulle overstyre. Med samme
   specificitet vinder den SENESTE regel, saa `.sidebar{display:none}` blev
   slaaet ihjel af `.sidebar{...display:flex}` 20 linjer laengere nede: hele
   sidemenuen blev stablet oven paa indholdet paa en telefon, samtidig med
   bundbjaelken. Opdaget 21/9 ved at kigge paa 375x812. Flyttes blokken op
   igen, kommer fejlen tilbage. */
@media (max-width:768px){
  .sidebar{display:none}
  /* ÉN kolonne. `display:block` alene virker ikke: enterApp sætter
     style.display='grid' inline, og inline slår denne regel. Det var den
     fjernede 900 px-regel (grid-template-columns:1fr) der reelt holdt
     mobilen på én kolonne — uden den stod skallen i 248px + 127px (24/9). */
  .admin-shell{display:block;grid-template-columns:minmax(0,1fr)}
  .main{padding:16px 16px 76px}
  .mobile-nav{display:flex;position:fixed;bottom:0;left:0;right:0;background:color-mix(in srgb, var(--ink) 92%, transparent);backdrop-filter:blur(10px);border-top:1px solid var(--border-soft);z-index:var(--z-nav);height:calc(60px + env(safe-area-inset-bottom));padding-bottom:env(safe-area-inset-bottom)}
  /* min-width:0 er ikke kosmetik. Uden den kan et flex-element ikke krympe
     under sin egen tekstbredde, saa "Honorarafregninger" holdt bjaelken
     bredere end skaermen og skubbede "Indstillinger" 5 px ud over kanten paa
     375 px — og vaerre naar booking-fanen er slaaet til. Maalt 21/9.
     Siden 23/9 er der højst fem faner (fire + "Mere"), så teksten kan være
     11 px i almindelig skrift og ikke 8-9 px mono. */
  .mn-item{flex:1 1 0;min-width:0;display:flex;flex-direction:column;align-items:center;justify-content:center;font-size:11px;font-weight:500;color:var(--text-muted);cursor:pointer;padding:6px 2px;gap:3px;text-align:center;user-select:none;transition:color var(--dur);overflow:hidden;white-space:nowrap;border:0;background:transparent;font-family:inherit}
  .mn-item.on{color:var(--accent)}
  .mn-item .mn-icn{display:inline-flex;line-height:1}
  .mn-item .mn-icn .icon{width:22px;height:22px}
  .mn-item{position:relative}
  .mn-item .nav-badge{position:absolute;top:4px;left:calc(50% + 6px);min-width:18px;height:18px;padding:0 5px;border-radius:var(--radius-pill);background:var(--danger);color:#fff;font-size:10px;font-weight:600;display:none;align-items:center;justify-content:center}
  .page-head{flex-direction:column;align-items:flex-start;gap:8px;margin-bottom:16px}
  .page-head h1{font-size:28px}
  .page-head .flex{flex-wrap:wrap;gap:6px}
  .page-head .flex .btn{font-size:11px;padding:6px 10px}
  .contract-preview{display:none}
  .contract-form{max-height:none;border-right:none}
  .contract-split{grid-template-columns:1fr}
  .job-card{grid-template-columns:70px 1fr;gap:10px;padding:14px}
  .grid-4,.dash-stats{grid-template-columns:repeat(2,1fr)}
  .row-2{grid-template-columns:1fr}
  /* Tabellerne er bredere end en telefon — "Kommende jobs" maalte 574 px paa
     en 375 px skaerm — og `.main{overflow-x:hidden}` KLIPPEDE resten væk i
     stedet for at lade den rulle. Honorar-kolonnen kunne bogstavelig talt
     ikke naas. `display:block` goer tabellen til en rulleflade; raekkerne
     beholder deres egen visning, saa den ser ud som en tabel endnu. */
  /* Dashboardets to spalter. Den hoejre var fast 320 px, og paa en telefon
     tvang den + tabellen gitteret op paa 945 px inde i en 343 px kasse. Den
     blev saa klippet af `.main{overflow-x:hidden}`, saa hverken honorar-
     kolonnen eller hoejrespalten kunne naas. Den ligger nu UNDER i stedet. */
  .dash-split{grid-template-columns:1fr}
  /* Filterbjaelken ombryder mellem pille-GRUPPERNE, men en enkelt gruppe
     ("Alle statuser / Udkast / Afventer / Godkendt") var selv 381 px bred i
     en 343 px kasse og stak 38 px ud over kanten. Grupperne maa ombryde
     indeni, og knapperne bliver lidt mindre. */
  .filter-bar{gap:8px}
  .filter-pill{flex-wrap:wrap}
  .filter-pill button{padding:6px 10px;font-size:12px}
  .table th,.table td{padding:10px 8px;font-size:13px}
  .table th{white-space:nowrap}
}

/* Booker-portalen: den primaere handling faar fuld bredde paa telefon.
   Paa 375 px sad "+ Nyt tilbud" som en lille knap i hoejre hjoerne over en
   liste i fuld bredde — den vigtigste knap paa skaermen saa ud som en
   eftertanke, og den er samtidig den sværeste at ramme med en tommel. */
@media (max-width:540px){
  .bk-ny-rk{display:block}
  .bk-ny-rk .btn{width:100%}
  /* De tre totaler braekkede 1+2 paa 375 px, hvilket laeses som om det
     foerste tal hoerer til noget andet end de to naeste. Mindre tal og en
     lavere min-width holder dem paa ÉN linje, saa de laeses som det saet de
     er — og sparer samtidig en halv skaerm lodret plads. */
  .bk-total-rk{gap:10px !important}
  .bk-total-felt{min-width:0 !important;flex:1 1 0 !important}
  .bk-total-felt .serif{font-size:19px !important}
  .bk-total-felt .muted{font-size:11px !important}
}

/* ── Booker-portalens graf (11-booker.js, _bkTegnGraf) ─────────────────────
   Søjlerne bærer farven; al tekst bruger teksttokens. Gitter er hårlinjer
   ét trin fra fladen, gulvet et trin stærkere. "Afventer" er SKRAVERET i
   samme farve som "Godkendt" — samme slags ting i to tilstande, ikke to
   forskellige ting, og striberne bærer forskellen uden at bero på lyshed. */
.bk-graf-kort{margin-top:22px;padding-top:16px;border-top:1px solid var(--ink-line-soft)}
.bk-graf{position:relative;margin-top:6px}
.bk-graf-rul{overflow-x:auto;-webkit-overflow-scrolling:touch}
.bk-graf svg{display:block;overflow:visible}
.bk-graf-linje{stroke:var(--ink-line);stroke-width:1;opacity:.45}
.bk-graf-gulv{stroke:var(--ink-line-strong, var(--ink-line));stroke-width:1}
.bk-graf-akse,.bk-graf-x{font-family:var(--font-mono);font-size:10px;fill:var(--cream-mute);font-variant-numeric:tabular-nums}
.bk-graf-top{font-family:var(--font-ui);font-size:11px;font-weight:600;fill:var(--cream-dim)}
.bk-graf-afventer{fill:url(#bkStreg);background:repeating-linear-gradient(45deg,var(--accent) 0 2px,color-mix(in srgb, var(--accent) 16%, transparent) 2px 4.2px)}
.bk-graf-noegle{display:inline-block;width:10px;height:10px;border-radius:3px;flex:none}
.bk-graf-soejle{transform-box:fill-box;transform-origin:50% 100%;animation:bkVokser .45s cubic-bezier(.2,.8,.2,1) both;transition:opacity .15s}
.bk-kol{transition:opacity .15s}
.bk-graf svg.fokus .bk-kol:not(.on){opacity:.4}
.bk-graf svg:not(.fokus) .bk-kol.valgt .bk-graf-x{fill:var(--accent)}
.bk-graf svg:not(.fokus):has(.bk-kol.valgt) .bk-kol:not(.valgt){opacity:.4}
.bk-kol.on .bk-graf-x{fill:var(--cream)}
.bk-graf-hit{fill:transparent;cursor:pointer;outline:none}
.bk-kol.tom .bk-graf-hit{cursor:default}
.bk-graf-hit:focus-visible{stroke:var(--accent);stroke-width:1.5;rx:6}
.bk-graf-tip{position:absolute;z-index:5;pointer-events:none;min-width:150px;padding:10px 12px;border-radius:10px;
  background:var(--ink-deep);border:1px solid var(--ink-line);box-shadow:0 10px 28px rgba(0,0,0,.45);font-size:12px}
.bk-graf-tip-titel{font-weight:600;color:var(--cream);margin-bottom:6px;text-transform:capitalize}
.bk-graf-tip-rk{display:flex;align-items:center;gap:7px;color:var(--cream-dim);padding:2px 0}
.bk-graf-tip-rk strong{margin-left:auto;color:var(--cream);font-weight:600;font-variant-numeric:tabular-nums;padding-left:12px}
.bk-graf-tip-sum{border-top:1px solid var(--ink-line-soft);margin-top:4px;padding-top:6px}
@keyframes bkVokser{from{transform:scaleY(0)}to{transform:scaleY(1)}}
@media (prefers-reduced-motion: reduce){.bk-graf-soejle{animation:none}}

/* Skifter med to lige værdige valg (Kr. / Antal): udseendet er det fælles
   for segmenterede kontroller — se "Segmenterede kontroller" øverst. */

/* (Her stod en OVERGANGS-regel, der gav inline-etiketter i den gamle stil —
   mono, versaler — det nye udseende. Den blev fjernet 23/9, da skabelonerne
   var skrevet om: "text-transform:uppercase" findes nu kun i dokument-
   skabelonerne i 07-calendar-pdf.js, som SKAL se ud som det der printes.) */

/* ── Bevægelse slås fra for dem der har bedt om det ── */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation-duration:.01ms !important;animation-iteration-count:1 !important;transition-duration:.01ms !important;scroll-behavior:auto !important}
}

/* ── "Kræver handling" på dashboardet (03-dashboard.js) ── */
.handling-liste{display:flex;flex-direction:column}
.handling{display:flex;align-items:center;gap:14px;padding:12px 0;border-bottom:1px solid var(--border-soft)}
.handling:last-child{border-bottom:0}
.handling-ikon{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;border-radius:50%;flex:none;background:var(--surface-hover);color:var(--text-dim)}
.handling-ikon.haster{background:var(--danger-soft);color:var(--danger)}
.handling-ikon.vent{background:var(--warning-soft);color:var(--warning)}
.handling-ikon.info{background:var(--accent-tint);color:var(--accent)}
.handling-tekst{flex:1;min-width:0}
.handling-titel{font-size:14px;font-weight:500;color:var(--text)}
.handling-sub{font-size:var(--fs-xs);color:var(--text-muted);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Arrangør-kortet klipper ikke: der er intet der skal gemmes væk. */
#dashArrangoere .handling-sub{white-space:normal;overflow:visible}
.handling-ok{display:flex;align-items:center;gap:10px;color:var(--text-muted);font-size:14px;padding:6px 0}
.handling-ok .icon{color:var(--success)}

/* ── Forløbsbanner i kontrakteditoren ── */
.forloeb-banner{display:flex;align-items:center;gap:14px;flex-wrap:wrap;padding:14px 16px;margin-bottom:16px;border-radius:var(--radius-lg);border:1px solid color-mix(in srgb, var(--accent) 30%, transparent);background:var(--accent-tint)}
.forloeb-banner.done{border-color:color-mix(in srgb, var(--ok) 35%, transparent);background:var(--success-soft)}
.forloeb-trin{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:13px;color:var(--text-dim)}
.forloeb-trin .prik{display:inline-flex;align-items:center;gap:6px}
.forloeb-trin .prik::before{content:"";width:8px;height:8px;border-radius:50%;background:var(--border-strong)}
.forloeb-trin .prik.ja::before{background:var(--ok)}
.forloeb-banner .handlinger{margin-left:auto;display:flex;gap:8px;flex-wrap:wrap}

/* ── Rullemenu (<details class="menu">) ── */
details.menu{position:relative}
details.menu > summary{list-style:none}
details.menu > summary::-webkit-details-marker{display:none}
details.menu .icon-ned{display:inline-flex;transition:transform var(--dur)}
details.menu[open] .icon-ned{transform:rotate(180deg)}
.menu-liste{position:absolute;right:0;top:calc(100% + 6px);z-index:50;min-width:240px;padding:6px;background:var(--surface-2);border:1px solid var(--border);border-radius:var(--radius-lg);box-shadow:var(--shadow-2);animation:fadeIn var(--dur) ease}
.menu-liste.venstre{right:auto;left:0}
.menu-liste{max-width:calc(100vw - 32px)}
.menu-liste button{display:flex;align-items:center;gap:10px;width:100%;min-height:36px;padding:0 10px;border:0;border-radius:var(--radius-sm);background:transparent;color:var(--text);font:inherit;font-size:14px;text-align:left;cursor:pointer}
.menu-liste button:hover{background:var(--surface-hover)}
.menu-liste button .icon{color:var(--text-muted)}
.menu-liste button.fare,.menu-liste button.fare .icon{color:var(--danger)}
.menu-liste hr{border:0;border-top:1px solid var(--border-soft);margin:6px 0}
/* Underfold i en formular-sektion. */
details.underfold > summary{list-style:none;cursor:pointer;display:inline-flex;align-items:center;gap:6px;font-size:var(--fs-sm);font-weight:500;color:var(--text-dim);margin-top:4px}
details.underfold > summary::-webkit-details-marker{display:none}
details.underfold > summary .icon{transition:transform var(--dur)}
details.underfold[open] > summary .icon{transform:rotate(180deg)}

/* ── "Mere" på mobil ── */
.mere-ark{position:fixed;left:0;right:0;bottom:0;z-index:calc(var(--z-nav) + 50);background:var(--surface-2);border-top:1px solid var(--border);border-radius:var(--radius-xl) var(--radius-xl) 0 0;box-shadow:var(--shadow-3);padding:8px 12px calc(16px + env(safe-area-inset-bottom));animation:arkOp .22s var(--ease)}
@keyframes arkOp{from{transform:translateY(100%)}to{transform:none}}
.mere-ark .nav-item{min-height:48px;font-size:15px}
.mere-ark-greb{width:36px;height:4px;border-radius:2px;background:var(--border-strong);margin:4px auto 10px}
.mere-bag{position:fixed;inset:0;z-index:calc(var(--z-nav) + 40);background:color-mix(in srgb, var(--ink-deep) 55%, transparent)}

/* ── Hjælpeklasser ─────────────────────────────────────────────────────────
   Til det der før stod inline: små tekster, grå tekst, rækker og afstande.
   Står SIDST i filen med vilje: en hjælpeklasse skal vinde over en komponent
   med samme vægt (.t-xs på en .table td, .p-0 på et .card). Stod de øverst,
   tabte de, og stilen blev skrevet inline igen.
   KUN værdier fra skalaerne ovenfor — findes et trin ikke, bruges det
   nærmeste. Opfind ikke nye her uden at tilføje dem til skalaen.
   IKKE til display:none: JS skifter synlighed med style.display, og en klasse
   ville ikke blive fjernet af style.display = ''. */
/* En lille etiket over en værdi (erstatter de inline mono-versal-etiketter). */
.label-sm{display:block;font-size:var(--fs-xs);font-weight:500;color:var(--text-muted);margin-bottom:2px}
.d-block{display:block} .ml-auto{margin-left:auto}
.avatar-sm{width:32px;height:32px;font-size:12px}
.select-sm{min-height:30px;padding:4px 8px;font-size:var(--fs-xs);width:auto}
/* En række i en lodret liste med en hårlinje under (historik, besætning …). */
.liste-rk{display:flex;align-items:center;gap:var(--s-3);padding:10px 0;border-bottom:1px solid var(--border-soft)}
.liste-rk:last-child{border-bottom:0}
/* Kort-varianter der gik igen inline. Skrevet som .card.card-x, så de vinder
   over .card, der står længere nede i filen med samme vægt. */
.card.p-0{padding:0}
.card.card-sm{padding:var(--s-4)} .card.card-flat{background:transparent;box-shadow:none}
.card.card-note{padding:var(--s-3) var(--s-4);background:var(--surface-hover);border-color:transparent;box-shadow:none;font-size:var(--fs-sm);color:var(--text-dim);line-height:1.55}
.card.card-varsel{padding:var(--s-3) var(--s-4);background:var(--warning-soft);border-color:color-mix(in srgb, var(--warn) 35%, transparent);box-shadow:none;font-size:var(--fs-sm);line-height:1.55}
.card.card-fare{padding:var(--s-3) var(--s-4);background:var(--danger-soft);border-color:color-mix(in srgb, var(--danger) 35%, transparent);box-shadow:none;font-size:var(--fs-sm);line-height:1.55}
.hint{font-size:var(--fs-xs);color:var(--text-muted)} .mt-auto{margin-top:auto}
.t-left{text-align:left} .mt-8{margin-top:var(--s-8)} .items-end{align-items:flex-end}
.border-t{border-top:1px solid var(--border-soft)} .border-b{border-bottom:1px solid var(--border-soft)}
.t-xs{font-size:var(--fs-xs)} .t-sm{font-size:var(--fs-sm)} .t-base{font-size:var(--fs-base)}
.t-md{font-size:var(--fs-md)} .t-lg{font-size:18px} .t-xl{font-size:var(--fs-lg)}
.t-muted{color:var(--text-muted)} .t-dim{color:var(--text-dim)} .t-text{color:var(--text)}
.t-danger{color:var(--danger)} .t-ok{color:var(--ok)} .t-warn{color:var(--warn)} .t-accent{color:var(--accent)}
.t-strong{font-weight:600} .t-medium{font-weight:500} .t-right{text-align:right} .t-center{text-align:center}
.nowrap{white-space:nowrap} .lh-tight{line-height:1.3} .lh-loose{line-height:1.6} .break{word-break:break-word}
.row{display:flex;align-items:center;gap:var(--s-2)} .row-start{align-items:flex-start}
.row-between{justify-content:space-between} .row-end{justify-content:flex-end} .row-center{justify-content:center}
.wrap{flex-wrap:wrap} .grow{flex:1;min-width:0} .shrink-0{flex-shrink:0}
.stack{display:flex;flex-direction:column;gap:var(--s-2)}
.gap-1{gap:var(--s-1)} .gap-2{gap:var(--s-2)} .gap-3{gap:var(--s-3)} .gap-4{gap:var(--s-4)} .gap-6{gap:var(--s-6)}
.w-full{width:100%}
.m-0{margin:0}
.mt-1{margin-top:var(--s-1)} .mt-2{margin-top:var(--s-2)} .mt-3{margin-top:var(--s-3)} .mt-4{margin-top:var(--s-4)} .mt-6{margin-top:var(--s-6)}
.mb-1{margin-bottom:var(--s-1)} .mb-2{margin-bottom:var(--s-2)} .mb-3{margin-bottom:var(--s-3)} .mb-4{margin-bottom:var(--s-4)} .mb-6{margin-bottom:var(--s-6)}
.p-0{padding:0} .p-3{padding:var(--s-3)} .p-4{padding:var(--s-4)} .p-6{padding:var(--s-6)}

/* Lyse temaer (data-tema="lys", sat af _applyThemeVars): baggrunden bag en
   dialog DÆMPES i stedet for at blive lysnet. Siden farvet med 70 % af sin
   egen lyse farve gav en hvid dialog på næsten hvidt — ingen adskillelse. */
:root[data-tema="lys"] .ui-modal-bag,
:root[data-tema="lys"] .drawer-backdrop,
:root[data-tema="lys"] .mere-bag{background:rgba(24,20,16,.32)}

/* Uden uploadet logo stod der et tomt billede på 36-72 px — et hul øverst i
   login-kortet og sidemenuen. Så skjules billedet, og bandnavnet vises som
   ordmærke i stedet (applyBranding fylder [data-band-name]). */
img.band-logo[src=""],img.band-logo:not([src]){display:none!important}
.band-navn-mark{display:none;font-family:var(--font-display);font-size:var(--fs-xl);line-height:1.1;color:var(--text);text-align:center;margin-bottom:12px}
img.band-logo[src=""]+.band-navn-mark,img.band-logo:not([src])+.band-navn-mark{display:block}
.band-navn-mark.sidebar-navn{text-align:left;font-size:var(--fs-lg);margin:0}

/* ══ Mobil-gennemgang 23/9 ══════════════════════════════════════════════════
   Målt på 375 px. Ligger sidst, så den vinder over basisreglerne. */
.mp-icn{display:none}
.member-knapper{display:flex;gap:8px;align-items:center}
.filter-toggle{display:none}
.filter-mere{display:contents}
@media (max-width:720px){
  /* Musikerens top: navn og ikon-knapper på én linje (~56 px i stedet for
     ~160), fanerne som bundbjælke — samme mønster som admin-panelet. */
  /* Ingen backdrop-filter her: den gør topbjælken til ankerpunkt for
     position:fixed, så fane-bjælken endte i toppen i stedet for i bunden. */
  .member-topbar{padding:10px 16px;flex-wrap:nowrap;-webkit-backdrop-filter:none;backdrop-filter:none;background:color-mix(in srgb, var(--surface) 96%, transparent)}
  .member-topbar .me .name{font-size:17px}
  /* Én linje hver: tagline + et langt navn fyldte fire linjer (~90 px) af
     en telefonskærm (24/9). Resten klippes med … — det fulde navn står i
     "Min profil". */
  .member-topbar .me{min-width:0;flex:1 1 auto}
  .member-topbar .me > div:last-child{min-width:0}
  .member-topbar .me [data-band-tagline],
  .member-topbar .me .name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .member-topbar .knap-tekst{display:none}
  .member-knapper .btn{padding:0;width:38px;height:38px;justify-content:center}
  .member-topbar .mode-pill{position:fixed;left:0;right:0;bottom:0;z-index:var(--z-nav);display:flex;gap:0;padding:0 0 env(safe-area-inset-bottom);height:calc(60px + env(safe-area-inset-bottom));border-radius:0;border:0;border-top:1px solid var(--border-soft);background:color-mix(in srgb, var(--ink) 92%, transparent);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}
  .member-topbar .mode-pill button{flex:1 1 0;min-width:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;font-size:11px;border-radius:0;background:transparent;box-shadow:none}
  .member-topbar .mode-pill button.on{background:transparent;box-shadow:none;color:var(--accent)}
  .member-topbar .mode-pill .mp-icn{display:inline-block;width:22px;height:22px}
  .member-main{padding:20px 16px 88px}

  /* Visningsvalget: to rækker i stedet for to smalle kolonner, hvor
     "Admin-panel" knækkede midt i ordet. */
  .visning-valg{grid-template-columns:1fr}
  .visning-kort{display:grid;grid-template-columns:auto 1fr;column-gap:14px;row-gap:2px;align-items:center;justify-items:start;text-align:left;padding:14px 16px}
  .visning-kort .visning-ikon{grid-row:1 / 3;flex:none}
  .login-card{padding:28px 20px}

  /* Nøgletal: to kolonner er for smalle til ikon + etiket — ikonet går. */
  .dash-stats .stat-ikon{display:none}
  .dash-stats .stat-tile{min-height:0;padding:var(--s-4)}
  .dash-stats .stat-tile .value{margin-top:var(--s-2)}

  /* Kontraktformularen havde 32 px indrykning OVEN i sidens 16 px. */
  .contract-form{padding:4px 16px 40px}

  /* Filtre: søgning fremme, resten bag knappen. */
  .filter-toggle{display:inline-flex}
  .filter-mere{display:none;width:100%;flex-wrap:wrap;gap:10px}
  .filter-mere.aaben{display:flex}
  .filter-bar .input{max-width:none!important;min-width:0!important;flex:1 1 140px}

  /* Tabeller som stablede rækker — ingen sidelæns rulning. */
  #dashUpcoming .table-wrap,#contractsTable .table-wrap{overflow:visible}
  #dashUpcoming .table,#contractsTable .table,#dashUpcoming tbody,#contractsTable tbody{display:block;width:100%}
  #dashUpcoming thead,#contractsTable thead{display:none}
  #dashUpcoming tr,#contractsTable tr{display:grid;gap:4px 12px;align-items:center;padding:12px 0;border-bottom:1px solid var(--border-soft)}
  #dashUpcoming tr:last-child,#contractsTable tr:last-child{border-bottom:0}
  #dashUpcoming td,#contractsTable td{padding:0;border:0;min-width:0}
  /* Dashboard: dato · spillested · honorar · status · besætning */
  #dashUpcoming tr{grid-template-columns:1fr auto auto;grid-template-areas:"sted sted belob" "dato status besat"}
  #dashUpcoming td:nth-child(1){grid-area:dato;font-size:var(--fs-sm)}
  #dashUpcoming td:nth-child(2){grid-area:sted}
  #dashUpcoming td:nth-child(3){grid-area:belob;text-align:right}
  #dashUpcoming td:nth-child(4){grid-area:status}
  #dashUpcoming td:nth-child(5){grid-area:besat}
  /* Kontraktlisten: nr · spillested · arrangør · dato · honorar · status · pil */
  #contractsTable{padding:4px 16px!important}
  #contractsTable tr{grid-template-columns:auto 1fr auto;grid-template-areas:"sted sted belob" "dato arr status" "nr nr nr"}
  #contractsTable td:nth-child(1){grid-area:nr;font-size:var(--fs-xs)}
  #contractsTable td:nth-child(2){grid-area:sted}
  #contractsTable td:nth-child(3){grid-area:arr;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  #contractsTable td:nth-child(4){grid-area:dato;font-size:var(--fs-sm)}
  #contractsTable td:nth-child(5){grid-area:belob;text-align:right}
  #contractsTable td:nth-child(6){grid-area:status}
  #contractsTable td:nth-child(7){display:none}
}

/* Operatørpanelets "Funktioner": foldet sammen, så man kun ser hvor mange der
   er til og fra. Folden åbnes med pilen. */
details.op-funk > summary{display:flex;align-items:center;gap:8px;cursor:pointer;list-style:none;padding:6px 0}
details.op-funk > summary::-webkit-details-marker{display:none}
details.op-funk > summary .fold{margin-left:auto;display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:50%;background:var(--surface-hover);color:var(--text-muted);transition:transform var(--dur)}
details.op-funk[open] > summary .fold{transform:rotate(180deg)}
details.op-funk > .handling-liste{margin-top:6px}

/* Operatørens statistik: tre tal og en kumulativ trappelinje pr. gruppe. */
.op-stat-tal{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px}
.op-graf{position:relative;width:100%}
.op-graf svg{display:block;overflow:visible}
.op-graf-gitter{stroke:var(--border-soft);stroke-width:1}
.op-graf-gulv{stroke:var(--border);stroke-width:1}
.op-graf-akse{font-family:var(--font-ui);font-size:11px;fill:var(--text-muted);font-variant-numeric:tabular-nums}
.op-graf-slut{font-family:var(--font-ui);font-size:12px;font-weight:600;fill:var(--text)}
.op-graf-linje{fill:none;stroke:var(--accent);stroke-width:2;stroke-linejoin:round}
.op-graf-flade{fill:color-mix(in srgb, var(--accent) 12%, transparent)}
.op-graf-prik{fill:var(--accent);stroke:var(--surface-1);stroke-width:2}
.op-graf-kryds{stroke:var(--text-muted);stroke-width:1;stroke-dasharray:3 3}
.op-graf-tip{position:absolute;pointer-events:none;min-width:130px;padding:8px 10px;border-radius:var(--radius);background:var(--surface-2);border:1px solid var(--border);box-shadow:var(--shadow-2);font-size:12px;line-height:1.4}
@media (max-width:720px){.op-stat-tal{grid-template-columns:1fr 1fr 1fr;gap:8px}.op-stat-tal .stat-tile{padding:12px}}

/* Accentforslag: små farveprøver med navn; den valgte har en ring. */
/* Seks forslag pr. tema → 3x2. Som flex-række blev det 5+1 med "Lavendel"
   alene på næste linje (24/9). */
.accent-forslag{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;max-width:480px}
.accent-prove{display:flex;min-width:0;white-space:nowrap;align-items:center;gap:8px;padding:5px 10px 5px 5px;border-radius:var(--radius-pill);border:1px solid var(--border);background:var(--surface-sunken);color:var(--text-dim);font:inherit;font-size:var(--fs-xs);cursor:pointer;transition:border-color var(--dur)}
.accent-prove:hover{border-color:var(--border-strong);color:var(--text)}
.accent-prove.on{border-color:var(--text);color:var(--text)}
.accent-prik{width:20px;height:20px;border-radius:50%;flex:none;box-shadow:inset 0 0 0 1px rgba(0,0,0,.15)}

/* Forløbets tidslinje: vandret på desktop, lodret på telefon. */
.tidslinje{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:0}
.tidslinje li{position:relative;display:flex;flex-direction:column;gap:6px;padding-right:12px}
.tidslinje li::before{content:"";position:absolute;top:10px;left:22px;right:0;height:2px;background:var(--border)}
.tidslinje li:last-child::before{display:none}
.tidslinje li.ja::before{background:var(--ok)}
.tl-prik{position:relative;z-index:1;display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:50%;border:2px solid var(--border-strong);background:var(--surface-1);color:var(--on-accent)}
.tidslinje li.ja .tl-prik{background:var(--ok);border-color:var(--ok);color:#fff}
.tl-prik .icon{width:12px;height:12px;stroke-width:3}
.tl-tekst{display:flex;flex-direction:column;gap:2px;min-width:0}
.tl-navn{font-size:13px;font-weight:500;color:var(--text)}
.tidslinje li:not(.ja) .tl-navn{color:var(--text-muted)}
.tl-tid{font-size:var(--fs-xs);color:var(--text-muted)}
@media (max-width:720px){
  .tidslinje{grid-template-columns:1fr;gap:10px}
  .tidslinje li{flex-direction:row;align-items:flex-start;gap:10px;padding-right:0}
  .tidslinje li::before{top:22px;bottom:-10px;left:10px;right:auto;width:2px;height:auto}
}
.forloeb-banner > div:nth-child(2){flex:1 1 320px;min-width:0}

/* Musikerens top: bandets logo (eller navn) forrest — det er bandets app.
   Initialerne står kun, når der hverken er logo eller navn. */
.member-logo{height:34px;max-width:140px;object-fit:contain;flex:none}
.member-navn-mark{font-size:18px;margin:0;text-align:left;padding-right:12px;border-right:1px solid var(--border-soft)}
.member-topbar .me .member-logo:not([src=""]) ~ .avatar,
.member-topbar .me .member-logo[src=""] + .member-navn-mark:not(:empty) ~ .avatar{display:none}
.member-logo:not([src=""]){padding-right:12px;border-right:1px solid var(--border-soft);box-sizing:content-box}

/* Bandmærket på jobkortene. */
.job-band-badge{display:flex;align-items:center;gap:6px;font-size:var(--fs-xs);color:var(--text-muted);margin-bottom:4px}
.job-band-logo{width:20px;height:20px;border-radius:4px;object-fit:contain;flex:none}
.job-band-chip{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:4px;font-size:9px;font-weight:700;color:#fff;flex:none}

/* Næste job-kortet. */
.naeste-job{cursor:pointer}
.naeste-top{display:flex;align-items:baseline;justify-content:space-between;gap:12px}
.naeste-nedtaelling{font-family:var(--font-display);font-size:var(--fs-xl);color:var(--accent);line-height:1;white-space:nowrap}
.naeste-titel{font-family:var(--font-display);font-weight:400;font-size:clamp(28px,4vw,40px);line-height:1.05;margin:6px 0 4px}
.naeste-meta{color:var(--text-muted);font-size:var(--fs-sm)}
.naeste-felter{display:grid;grid-template-columns:repeat(auto-fit,minmax(110px,1fr));gap:12px;margin-top:16px}
.naeste-felt .label{font-size:var(--fs-xs);color:var(--text-muted)}
.naeste-felt .value{font-family:var(--font-display);font-size:20px;color:var(--text);font-variant-numeric:tabular-nums}
.card.naeste-reserveret{background:color-mix(in srgb, var(--surface-1) 28%, transparent);border-style:dashed;border-color:var(--border);box-shadow:none}

/* Tjeklisten for nye bands. */
.tjek-bar{height:6px;border-radius:var(--radius-pill);background:var(--surface-hover);overflow:hidden}
.tjek-bar span{display:block;height:100%;background:var(--accent);border-radius:inherit;transition:width .3s var(--ease)}
.tjek-punkt.ok .handling-titel{color:var(--text-muted);text-decoration:line-through;text-decoration-color:var(--border-strong)}
.tjek-punkt.ok .handling-ikon{background:var(--success-soft);color:var(--success)}
/* Sammenfoldet: én linje — etiket, tal, bjælke, "Vis". */
.tjek-foldet{display:flex;align-items:center;gap:14px;padding-top:12px;padding-bottom:12px}
.tjek-foldet .eyebrow{margin:0;white-space:nowrap}
.tjek-foldet-tal{font-size:var(--fs-sm);color:var(--text);white-space:nowrap}
.tjek-foldet .tjek-bar{flex:1;min-width:60px}
@media (max-width:720px){
  .tjek-foldet{flex-wrap:wrap;gap:8px 12px}
  .tjek-foldet .tjek-bar{order:3;flex-basis:100%}
  .tjek-foldet .btn{margin-left:auto}
}
.forloeb-banner{align-items:flex-start}

/* Arrangørens læsestatus under bookingens status. */
.laesestatus{font-size:var(--fs-xs);color:var(--text-muted);margin-top:4px}
.laesestatus.laest{color:var(--success)}
/* Bookinger på mobil: stablede rækker som kontraktlisten.
   spillested · arrangør · dato · status · sidst opdateret · pil */
@media (max-width:720px){
  #bookingsTable{padding:4px 16px!important}
  #bookingsTable .table-wrap{overflow:visible}
  #bookingsTable .table,#bookingsTable tbody{display:block;width:100%}
  #bookingsTable thead{display:none}
  #bookingsTable tr{display:grid;gap:4px 12px;align-items:start;padding:12px 0;border-bottom:1px solid var(--border-soft);grid-template-columns:1fr auto;grid-template-areas:"sted dato" "arr arr" "status status"}
  #bookingsTable tr:last-child{border-bottom:0}
  #bookingsTable td{padding:0;border:0;min-width:0}
  #bookingsTable td:nth-child(1){grid-area:sted}
  #bookingsTable td:nth-child(2){grid-area:arr;font-size:var(--fs-xs)}
  #bookingsTable td:nth-child(3){grid-area:dato;font-size:var(--fs-sm);text-align:right}
  #bookingsTable td:nth-child(4){grid-area:status}
  #bookingsTable td:nth-child(5),#bookingsTable td:nth-child(6){display:none}
}

/* Handlingsrækker på telefon (24/9): knapperne fylder rækken. Før brød den
   sidste knap ("Skriv under", "Godkend og underskriv", "Gensend kontrakt",
   "Nulstil nuancer") ned på sin egen linje og hang alene i venstre side —
   det så ud som en fejl. Nu får den linjen for sig i fuld bredde. */
@media (max-width:720px){
  .forloeb-banner .handlinger > .btn,
  .card .row.wrap > .btn{flex:1 1 auto;justify-content:center;min-height:36px}
}
/* Skuffen er smal ved ALLE bredder (også på en telefon på langs), så dens
   handlingsrække fylder altid ud — ellers hang "Godkend og underskriv" alene. */
.drawer .row-end > .btn{flex:1 1 auto;justify-content:center}
/* Musikerens topbjælke på en telefon på langs (721–1000 px): "Admin" og
   "Log ud" brød ned på en linje for sig under navnet, og den klæbende bjælke
   tog ~75 px af en 390 px høj skærm (24/9). Én linje: ikonknapper, og navn/
   tagline klippes med … som på højkant. */
@media (min-width:721px) and (max-width:1000px){
  .member-topbar{flex-wrap:nowrap}
  .member-topbar .knap-tekst{display:none}
  .member-knapper{display:flex;gap:6px;flex:none}
  .member-knapper .btn{padding:0;width:38px;height:38px;justify-content:center}
  .member-topbar .mode-pill{flex:none}
  .member-topbar .me{min-width:0;flex:1 1 auto}
  .member-topbar .me > div:last-child{min-width:0}
  .member-topbar .me [data-band-tagline],
  .member-topbar .me .name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
}

/* Editorens hoved klæber (24/9) — se _klaebEditorHoved i 04-contracts.js.
   `.main` bruger overflow-x:clip og ikke hidden: hidden gør den til en
   rullecontainer, og så klæber intet indeni. */
.editor-head{position:sticky;top:0;z-index:30}
.editor-head.fast{margin:0 -40px 16px;padding:10px 40px;align-items:center;
  background:color-mix(in srgb, var(--surface) 88%, transparent);
  -webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);
  border-bottom:1px solid var(--border-soft);box-shadow:0 10px 24px -18px rgba(0,0,0,.6)}
.editor-head.fast .editor-tilbage,.editor-head.fast .eyebrow{display:none}
.editor-head.fast h1{font-size:20px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.editor-head .editor-head-titel{min-width:0}
.editor-head.fast{flex-direction:row;flex-wrap:nowrap;justify-content:space-between;gap:16px}
.editor-head.fast .editor-head-titel{flex:1 1 auto}
.editor-head.fast > .row{flex:none;flex-wrap:nowrap}
@media (max-width:768px){
  .editor-head.fast{margin:0 -16px 12px;padding:8px 16px;flex-direction:row;justify-content:flex-end}
  .editor-head.fast .editor-head-titel{display:none}
  .editor-head.fast > .row{flex-wrap:nowrap}
}

/* ── Kun med mus (24/9): genvejsmærkater og rækkehandlinger ────────────────
   Samme knapper på telefon; der vises bare hverken mærkater (der er intet
   tastatur) eller skjules handlinger (der er intet hover). */
@media (hover:hover) and (pointer:fine){
  /* Mærkatet på knapper med data-genvej — se tastaturgenvejene i 01-core.js. */
  .btn[data-genvej]::after{font-family:var(--font-ui);font-size:10px;font-weight:600;letter-spacing:.02em;
    padding:1px 5px;margin-left:4px;border-radius:4px;opacity:.7;
    border:1px solid color-mix(in srgb, currentColor 35%, transparent)}
  .btn[data-genvej="mod+s"]::after{content:"Ctrl S"}
  html.mac .btn[data-genvej="mod+s"]::after{content:"⌘S"}
  .btn[data-genvej="n"]::after{content:"N"}
  .btn.btn-gemt[data-genvej]::after{display:none}

  /* Rækkens sekundære handlinger vises når man peger på rækken (eller
     tabber ind i den). Den primære ("Markér betalt", "Arkivér") står altid. */
  .table .raekke-handling .btn:not(.btn-primary){opacity:0;transition:opacity var(--dur) var(--ease)}
  .table tr:hover .raekke-handling .btn,
  .table tr:focus-within .raekke-handling .btn{opacity:1}

  /* Klikbare rækker: en accentstreg i venstre side viser at hele rækken er
     et link. */
  .table tr.clickable td:first-child{transition:box-shadow var(--dur) var(--ease)}
  .table tr.clickable:hover td:first-child{box-shadow:inset 3px 0 0 var(--accent)}
}

/* Bookerens bands i operatørpanelet: noten under navnet, ikke i en smal
   højrespalte (tre linjer på 375 px ved siden af et langt bandnavn, 24/9). */
.op-bk-band-navn{display:flex;flex-direction:column;min-width:0}
/* Operatørens værktøjslinje på telefon: seks knapper brød skævt med "Nyt
   band" alene nederst. Et jævnt gitter, "Nyt band" øverst i fuld bredde. */
@media (max-width:720px){
  .op-vaerktoej{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));width:100%}
  .op-vaerktoej .btn{width:100%;justify-content:center}
  .op-vaerktoej .btn-primary{grid-column:1 / -1;order:-1}
  .op-vaerktoej [data-act="opSystemHealth"]{grid-column:1 / -1}
}
/* Bandets medlemmer i operatørens editor, på telefon: navn og e-mail over
   hele bredden, mærket og knappen på linjen under. Før brød navnet over fire
   linjer og en lang e-mail løb ind under mærket (24/9). */
@media (max-width:720px){
  .op-medlem{flex-wrap:wrap;row-gap:8px}
  .op-medlem .handling-tekst{flex:1 1 100%}
  .op-medlem .op-medlem-mail{display:block;overflow-wrap:anywhere}
  .op-medlem > .btn,.op-medlem > span.t-xs{margin-left:auto}
}
/* Et langt statusmærke (fx en timeout-besked i Systemtjek) må ombryde i
   stedet for at skubbe siden bredere end skærmen (24/9). */
.handling .grow{min-width:0}
.handling .grow .badge{white-space:normal;max-width:100%;text-align:left}
/* Kundens spillesteder i kartoteket: et langt navn løb ud af kortet og ind
   i nabokortet (24/9). Klippes med … — hele navnet står i title. */
.badge.kunde-sted{display:inline-block;max-width:100%;overflow:hidden;text-overflow:ellipsis;vertical-align:middle}
