@import url('https://fonts.googleapis.com/css2?family=Archivo:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500;600&display=swap');
:root{
  /* Consto visual refresh — warm paper surfaces, fir-green sidebar/actions,
     green="good/automated", amber="attention", red strictly for errors/blocked.
     Variable NAMES are kept stable across the refresh (only values change)
     so every view module's existing var(--x) references retheme for free —
     see design_handoff_consto_refresh/README.md for the source token table. */
  --paper:#F5F2EA; --panel:#FFFDF8; --field:#EFEADC; --row-highlight:#FBF7EE;
  --ink:#12201A; --ink-2:#3C4A43; --slate:#4C5A52; --faint:#6E7A72; --hair:#EFEADC; --hair-strong:#E3DDCE; --field-border:#DCD5C4; --disabled:#9AA69F; --panel-alt:#EFEADC;
  --accent:#1F7A52;
  --sidebar:#14392B; --sidebar-raised:#1B4634; --sidebar-active:#1F5140;
  --sidebar-text:#CFE0D6; --sidebar-muted:#A9C8B7; --sidebar-faint:#7FA692; --sidebar-label:#6E9484;
  --sidebar-border:#1F5140; --sidebar-border-2:#1B4634; --accent-dot:#8FD8AE;
  --mint:#8FD8AE; --mint-ink:#0C2A1F;
  --green:#1F7A52; --green-wash:#E6F2EA; --green-ink:#14392B;
  --amber:#A9722B; --amber-wash:#F7EEDF; --amber-ink:#8A5E1C;
  --red:#B0472F; --red-wash:#FBE9E2; --red-border:#EBD3CC;
  --red-panel-bg:#FBE9E2; --red-panel-border:#EBD3CC; --red-panel-hair:#F3DDD5;
  --blue:oklch(0.45 0.07 235); --blue-wash:oklch(0.94 0.02 230);
  --teal:oklch(0.50 0.08 180); --teal-wash:oklch(0.94 0.03 180);
  --violet:oklch(0.45 0.09 300); --violet-wash:oklch(0.94 0.03 300);
  --chart-in:#1F7A52; --chart-out:#A9722B; --chart-balance:#12201A;
  --aging-1:#12201A; --aging-2:#A9722B; --aging-3:#C7663F; --aging-4:#B0472F;
  /* Fixed categorical order for a donut()/aging_chart()-style breakdown by
     category/lender/position (see app/charts.py's categorical_series) —
     validated with the dataviz skill's validate_palette.js against this
     app's light chart surface (lightness band, 0.10 chroma floor, CVD and
     normal-vision adjacent-pair separation all pass); confined to a hue
     range clear of --green/--amber/--red so a category never reads as a
     status color by accident. This exact order is the CVD-safety
     mechanism — re-ordering needs re-validating, not just relabeling. */
  --cat-1:#008a9b; --cat-2:#6e65c2; --cat-3:#b54b69; --cat-4:#037ac0; --cat-5:#9c54a1;
  --shadow:0 1px 2px rgba(16,24,21,.06);
  --shadow-tab:0 1px 2px rgba(16,24,21,.06);
  --r-sm:8px; --r-md:10px; --r-lg:6px; --r-pill:99px;
}
*{box-sizing:border-box}
html,body{margin:0;height:100%}
body{background:var(--paper);color:var(--ink);font-family:"Archivo",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.5;-webkit-font-smoothing:antialiased}
.mono{font-family:"IBM Plex Mono",ui-monospace,Menlo,monospace;font-feature-settings:"tnum" 1;font-variant-numeric:tabular-nums}
button{font-family:inherit;cursor:pointer;border:none;background:none}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:2px}

.shell{display:grid;grid-template-columns:248px 1fr;min-height:100vh}

/* ---------- Sidebar ---------- */
aside.side{background:var(--sidebar);color:var(--sidebar-muted);display:flex;flex-direction:column;position:sticky;top:0;height:100vh}
.brand{display:flex;align-items:center;gap:10px;padding:20px 18px 16px}
/* ---- Eckmarken: corner-bracket mark, from the Swiss QR-bill's unfilled field ---- */
.mark{position:relative;display:inline-block;width:var(--sz,26px);height:var(--sz,26px);flex:none}
.mark::before,.mark::after{content:'';position:absolute;width:38%;height:38%;border:2px solid var(--mc,#fff)}
.mark::before{top:0;left:0;border-right:0;border-bottom:0}
.mark::after{bottom:0;right:0;border-left:0;border-top:0}
.mark.zu::before,.mark.zu::after{width:100%;height:100%}
.mark.zu::after{display:none}
.mark.zu::before{border:2px solid var(--mc,#fff);background:var(--mc,#fff);opacity:1}
.brand b{color:#fff;font-size:16px;font-weight:600;letter-spacing:-.03em;line-height:1}

.tenantbar{padding:0 14px 16px}
.tenantbtn{display:flex;align-items:center;gap:9px;width:100%;padding:10px 12px;border:1px solid var(--sidebar-border);border-radius:var(--r-lg);background:var(--sidebar-raised);font-family:"IBM Plex Mono",monospace;font-size:11.5px;font-weight:500;color:var(--sidebar-muted);text-align:left;text-transform:uppercase;letter-spacing:.02em}
.tenantbtn .dot{width:6px;height:6px;border-radius:50%;background:var(--accent-dot);flex:none}
.tenantbtn .lbl{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.5}
.tenantbtn .lbl small{display:block;color:var(--sidebar-faint);font-size:10.5px;letter-spacing:.04em}
.tenantbtn select{position:absolute;inset:0;opacity:0;cursor:pointer;width:100%}
.tenantbtn{position:relative}
.tenantbtn .car{color:var(--sidebar-faint);font-size:11px}

nav.modules{padding:2px 12px 12px;flex:1;overflow-y:auto;display:flex;flex-direction:column;gap:2px}
.navsec{font-family:"IBM Plex Mono",monospace;font-size:9.5px;text-transform:uppercase;letter-spacing:.14em;color:var(--sidebar-label);padding:16px 12px 7px;font-weight:600}
.navitem{display:flex;align-items:center;gap:10px;width:100%;text-align:left;padding:9px 12px;color:var(--sidebar-text);font-size:13.5px;font-weight:500;border-radius:var(--r-lg);transition:background .12s,color .12s}
.navitem:hover{background:rgba(255,255,255,.06);color:var(--sidebar-text)}
.navitem.active{background:var(--mint);color:var(--mint-ink);font-weight:600}
.navitem svg{flex:none;width:16px;height:16px}
.navitem .tag{margin-left:auto;font-family:"IBM Plex Mono",monospace;font-size:11.5px;font-weight:600;font-variant-numeric:tabular-nums;letter-spacing:.01em;line-height:1.5;border-radius:var(--r-lg);padding:1px 6px;white-space:nowrap}
.navitem .tag.neutral{color:var(--sidebar-faint);background:transparent}
.navitem .tag.alert{color:var(--red);background:transparent;font-weight:600}
.navitem .tag.progress{color:var(--mint);background:transparent}
.navitem.active .tag.neutral,.navitem.active .tag.progress{color:var(--mint-ink)}
.navitem.active .tag.alert{color:var(--red)}

.side-user{margin-top:auto;padding:14px 20px 0;border-top:1px solid var(--sidebar-border);display:flex;align-items:center;gap:10px}
.side-user .avatar{width:30px;height:30px;border-radius:var(--r-lg);background:var(--sidebar-active);color:var(--mint);display:grid;place-items:center;font-weight:600;font-size:11.5px;flex:none}
.side-user .m{line-height:1.25;min-width:0;flex:1}
.side-user .m b{color:var(--sidebar-muted);font-size:12px;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-weight:600}
.side-user .m small{color:var(--sidebar-faint);font-size:11px}

/* ---------- Main ---------- */
main{min-width:0}
header.top{display:flex;align-items:center;gap:14px;padding:20px 34px;border-bottom:1px solid var(--hair-strong);background:rgba(245,242,234,.94);backdrop-filter:blur(6px);position:sticky;top:0;z-index:30;flex-wrap:wrap}
.hamburger{display:none;font-size:22px;padding:2px 8px}
.crumb{font-weight:600;font-size:15px;letter-spacing:-.02em;margin-right:auto}
.periodchip{display:flex;align-items:center;gap:8px;font-family:"IBM Plex Mono",monospace;font-size:11.5px;font-weight:500;letter-spacing:.08em;text-transform:uppercase;color:var(--faint)}
select{border:none;background:none;font:inherit;font-weight:600;color:var(--ink);cursor:pointer}
.jobsdot{display:inline-block;min-width:15px;padding:0 4px;margin-left:5px;border-radius:999px;background:var(--red);color:#fff;font-size:10.5px;font-weight:700;line-height:15px;text-align:center}
.jobspanel{display:none;position:absolute;top:calc(100% + 6px);right:0;min-width:260px;max-width:320px;background:var(--panel);border:1px solid var(--hair-strong);border-radius:var(--r-md);box-shadow:0 8px 24px rgba(0,0,0,.14);z-index:40;overflow:hidden}
.jobspanel.show{display:block}
.chatfab{position:fixed;bottom:24px;right:24px;z-index:50;width:52px;height:52px;border-radius:999px;border:none;background:var(--sidebar);color:var(--panel);font-size:22px;line-height:52px;text-align:center;padding:0;cursor:pointer;box-shadow:0 6px 18px rgba(0,0,0,.2)}
.chatfab:hover{filter:brightness(1.3)}
.chatpanel{display:none;position:fixed;bottom:88px;right:24px;width:380px;max-width:calc(100vw - 32px);max-height:min(560px,70vh);overflow:auto;background:var(--panel);border:1px solid var(--hair-strong);border-radius:var(--r-md);box-shadow:0 8px 24px rgba(0,0,0,.18);z-index:50}
.chatpanel.show{display:block}
.chatscope{padding:4px 10px;border-radius:999px;border:1px solid var(--hair-strong);background:none;color:var(--faint);font-size:11.5px;font-weight:600;cursor:pointer}
.chatscope-active{background:var(--sidebar);color:var(--panel);border-color:var(--sidebar)}

.view{padding:28px 34px 42px}
.view.htmx-request{opacity:.45;pointer-events:none;transition:opacity 120ms ease-out}
.view.htmx-request::after{content:"";position:fixed;top:50%;left:50%;width:30px;height:30px;margin:-15px 0 0 -15px;border:3px solid var(--hair-strong);border-top-color:var(--accent);border-radius:50%;animation:view-spin .7s linear infinite;pointer-events:none;z-index:5}
@keyframes view-spin{to{transform:rotate(360deg)}}

/* A background job's own self-polling status line (banking/inbox/portfolio/
   settings/reports upload-status widgets, the header jobsbar) sets
   hx-indicator="this" specifically so its periodic re-fetch does NOT dim
   the whole #view via the rule above — that produced a jarring dim+spin
   flash on every poll for the entire duration of a long-running job. This
   gentle continuous pulse on the status text is the "still working"
   feedback instead — restarts on each poll's re-render, but a slow loop
   like this reads as continuous, not as a flicker. */
@keyframes polling-pulse{0%,100%{opacity:1}50%{opacity:.5}}
.polling-status{animation:polling-pulse 1.6s ease-in-out infinite}
.vhead{margin-bottom:26px}
.vhead h2{font-size:24px;font-weight:600;letter-spacing:-.02em;margin:0 0 4px;text-wrap:balance}
.vhead p{margin:0;color:var(--faint);font-size:14px}

/* KPI grid — one bordered panel with 1px dividers between cells (the 1px
   grid-gap over a hair-strong background shows through as the divider),
   not N separate cards. Works whether a view's inline style sets an exact
   repeat(N,1fr) or leaves the auto-fit default, and however it wraps. */
.kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:1px;background:var(--hair-strong);border:1px solid var(--hair-strong);border-radius:var(--r-md);overflow:hidden;margin-bottom:24px}
.kpi{background:var(--panel);border-radius:0;padding:18px 20px}
.kpi .k{font-family:"IBM Plex Mono",monospace;font-size:10px;color:var(--faint);text-transform:uppercase;letter-spacing:.12em;font-weight:500;margin-bottom:12px}
.kpi .v{font-family:"IBM Plex Mono",monospace;font-variant-numeric:tabular-nums;font-size:22px;font-weight:500;letter-spacing:-.01em}
.kpi .v .ccy{font-family:"Archivo",sans-serif;font-size:12px;color:var(--faint);margin-right:5px;font-weight:500}
.kpi .d{font-size:12px;margin-top:8px;display:flex;align-items:center;gap:5px;color:var(--faint)}
.d.up{color:var(--green)} .d.down{color:var(--red)} .d.flat{color:var(--faint)}

/* Larger variant — Übersicht's own KPI row only (kpis() without "lg" keeps
   every other module's KPI tiles at their existing size). */
.kpis.lg .kpi .v{font-size:30px}
.kpis.lg .kpi .k{font-size:10.5px}
/* min-height reserves room for 2 lines (line-height 1.5 * 2 = 3em) whether
   this specific tile's own value wraps or not — a long formatted amount
   ("228'913.34 USD") wraps at the currency suffix while a short one
   ("0.00 USD") doesn't, so without this every tile's caption/sparkline
   below .v started at a different height depending on which sibling in the
   row happened to wrap, breaking row alignment. Scoped to .lg only — this
   is Übersicht's own row; every other module's (shorter, rarely-wrapping)
   kpi() tiles keep their current tighter spacing. */
.kpis.lg .kpi .v{min-height:3em}

/* feature cards (close card, panels, blocker panel) */
.card{background:var(--panel);border:1px solid var(--hair-strong);border-radius:var(--r-md);padding:22px 24px;box-shadow:var(--shadow)}

/* chart panels */
.panels{display:grid;grid-template-columns:1.5fr 1fr;gap:16px;margin-bottom:16px}
.panel{background:var(--panel);border:1px solid var(--hair-strong);border-radius:var(--r-md);padding:20px 24px}
.panel h3{margin:0 0 2px;font-size:14.5px;font-weight:600;letter-spacing:-.01em}
.panel .sub{color:var(--faint);font-size:12px;margin-bottom:16px}
.legend{display:flex;gap:18px;flex-wrap:wrap;margin-top:14px;font-size:12px;color:var(--slate)}
.legend span{display:inline-flex;align-items:center;gap:7px}
.legend i{width:8px;height:8px;border-radius:2px;display:inline-block}

/* chart hover tooltips — see chart-mark/data-tip-* in app/charts.py, wired up
   in base.html's shared event-delegated listener (works across htmx swaps
   with no re-binding). Every value a tooltip shows is also already visible
   as a direct label or an axis tick — hover only adds precision, never gates
   access to the number. */
.chart-mark{cursor:pointer;transition:opacity .1s}
.chart-mark:hover,.chart-mark:focus-visible{opacity:.75}
.chart-tooltip{position:fixed;pointer-events:none;z-index:1000;background:var(--ink);color:#fff;font-size:12px;line-height:1.5;padding:7px 10px;border-radius:var(--r-sm);box-shadow:var(--shadow);opacity:0;transform:translateY(2px);transition:opacity .08s,transform .08s;max-width:260px}
.chart-tooltip.show{opacity:1;transform:translateY(0)}
.chart-tooltip .tt-row{display:flex;align-items:center;gap:7px;white-space:nowrap}
.chart-tooltip .tt-row+.tt-row{margin-top:3px}
.chart-tooltip .tt-key{width:10px;height:2px;border-radius:1px;flex-shrink:0}
.chart-tooltip .tt-label{color:#fff;opacity:.75;overflow:hidden;text-overflow:ellipsis}
.chart-tooltip .tt-val{font-family:"IBM Plex Mono",monospace;font-weight:700;margin-left:auto;padding-left:10px}

/* tables */
.tablewrap{background:var(--panel);border:1px solid var(--hair-strong);border-radius:var(--r-md);overflow:hidden;overflow-x:auto}
.tablewrap .th{display:flex;align-items:center;justify-content:space-between;padding:15px 22px;border-bottom:1px solid var(--hair-strong);gap:10px;flex-wrap:wrap}
.tablewrap .th h3{margin:0;font-size:14.5px;font-weight:600}
table{width:100%;min-width:max-content;border-collapse:collapse;font-size:13.5px}
th{text-align:left;font-family:"IBM Plex Mono",monospace;font-size:10px;text-transform:uppercase;letter-spacing:.1em;color:var(--faint);font-weight:600;padding:11px 22px;border-bottom:1px solid var(--hair-strong)}
td{padding:13px 22px;border-bottom:1px solid var(--hair)}
tr:last-child td{border-bottom:none}
/* Table rows deliberately do not change background on hover — the highlight
   is reserved for the one row that needs attention (see .row-highlight). */
tr.row-highlight{background:var(--row-highlight)}
td.r,th.r{text-align:right}
.badge{font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;padding:2px 8px;border-radius:5px}
.b-qrr{background:var(--blue-wash);color:var(--blue)}.b-scor{background:var(--violet-wash);color:var(--violet)}.b-non{background:var(--hair);color:var(--slate)}

/* ---- Status pills: Consto's state-color system (bill_status is the state machine) ---- */
.pill{display:inline-flex;align-items:center;gap:6px;font:600 12px "Archivo",sans-serif;padding:4px 10px;border-radius:var(--r-pill)}
.pill i{width:6px;height:6px;background:currentColor;border-radius:50%}
.p-open{color:var(--ink-2);background:var(--panel-alt)}                  /* draft/parsed/not started — unverbindlich, bewusst zurückhaltend */
.p-sent{color:var(--amber-ink);background:var(--amber-wash)}             /* scheduled/submitted/in progress — Geld unterwegs */
.p-ok{color:var(--green-ink);background:var(--green-wash)}               /* approved/done */
.p-over{color:var(--red);background:var(--red-wash)}                     /* rejected/returned/overdue/blocked */

.btn{font:600 12.5px "Archivo",sans-serif;padding:8px 16px;border:none;border-radius:var(--r-pill);transition:filter .12s}
.btn:active{filter:brightness(.94)}
.btn-p{background:var(--sidebar);color:var(--panel)}.btn-p:hover{filter:brightness(1.3)}     /* primary dark — submit-for-approval style actions, header CTA */
.btn-g{background:var(--green);color:#fff}.btn-g:hover{filter:brightness(1.15)}              /* primary green — the main call to action */
.btn-o{border:1px solid var(--field-border);background:var(--panel);color:var(--ink-2)}
.btn-o:hover{background:var(--field)}
.btn-d{background:#fff;border:1px solid var(--red-border);color:var(--red)}                  /* destructive secondary */
.btn-d:hover{background:var(--red-wash)}
.btn-sm{padding:6px 12px;font-size:11.5px}
.btn:disabled{opacity:.4;cursor:not-allowed}

/* filter chips */
.chip{padding:7px 14px;border-radius:var(--r-pill);border:1px solid var(--hair-strong);background:var(--panel);color:var(--slate);font-size:12.5px;font-weight:600}
.chip.on{background:var(--ink);color:#fff;border-color:var(--ink)}

/* row-card pattern (Freigabe-Inbox / Posteingang / Ausnahmen) */
.rowcards{display:flex;flex-direction:column;gap:10px}
.rowcard{background:var(--panel);border:1px solid var(--hair-strong);border-radius:var(--r-md);padding:18px 20px;display:flex;gap:18px;align-items:center;flex-wrap:wrap}
.rowcard.sev-high{border-left:3px solid var(--red)}
.rowcard.sev-medium{border-left:3px solid var(--aging-2)}
.rowcard.sev-low{border-left:3px solid var(--slate)}

/* decision card (Übersicht + Freigabe-Inbox — see common.py's decision_card()) */
.decision-card{background:var(--panel);border:1px solid var(--hair-strong);border-radius:var(--r-md);padding:18px 20px;margin-bottom:10px}
.decision-card:last-child{margin-bottom:0}
.decision-card.status-red{border-left:2px solid var(--red)}
.decision-card.status-amber{border-left:2px solid var(--amber)}
.decision-card.status-green{border-left:2px solid var(--green)}
.dc-meta{display:flex;align-items:center;gap:10px;margin-bottom:12px;flex-wrap:wrap}
.dc-chip{font:600 10px "IBM Plex Mono",monospace;letter-spacing:.1em;background:var(--green-wash);color:var(--green-ink);padding:4px 8px;border-radius:5px;text-transform:uppercase}
.dc-meta .time{font-size:12px;color:var(--faint)}
.dc-meta .reason{margin-left:auto;font:600 11.5px "IBM Plex Mono",monospace}
.dc-subject{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;margin-bottom:4px}
.dc-subject .who{font:600 16px "Archivo",sans-serif;letter-spacing:-.02em;color:var(--ink)}
.dc-subject .amt{font:500 19px "IBM Plex Mono",monospace}
.dc-context{color:var(--slate);font-size:12.5px;margin-bottom:12px}
.dc-chips{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:14px}
.dc-chips span{font-size:11.5px;background:#F0F3F1;color:var(--slate);padding:4px 8px;border-radius:5px}
.dc-chips span.ok{background:var(--green-wash);color:var(--green-ink)}
.dc-chips span.warn{background:var(--amber-wash);color:var(--amber-ink)}
.dc-candidates{margin-bottom:14px}
.dc-candidate{display:flex;justify-content:space-between;align-items:center;gap:12px;padding:10px 0;border-bottom:1px solid var(--hair)}
.dc-candidate:last-child{border-bottom:none}
.dc-candidate .desc{font-size:13px;color:var(--ink)}
.dc-candidate .note{font:600 11px "IBM Plex Mono",monospace}
.dc-candidate .note.ok{color:var(--green)}
.dc-candidate .note.warn{color:var(--amber)}
.dc-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.dc-actions .more{margin-left:auto;font-size:12px;color:var(--faint);text-decoration:none}

/* automation banner (dark, single-line "what the system did" strip — see
   common.py's automation_banner()). Same dark accent-panel texture as the
   sidebar, per design_handoff_consto_refresh/README.md. */
.automation-banner{
  display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  background-color:var(--sidebar);color:var(--sidebar-text);
  background-image:linear-gradient(45deg,rgba(255,255,255,.045) 25%,transparent 25%,transparent 75%,rgba(255,255,255,.045) 75%),linear-gradient(45deg,rgba(255,255,255,.045) 25%,transparent 25%,transparent 75%,rgba(255,255,255,.045) 75%);
  background-size:18px 18px;background-position:0 0,9px 9px;
  border-radius:var(--r-md);padding:14px 18px;margin-bottom:16px;
}
.automation-banner .tag{font:600 10px "IBM Plex Mono",monospace;letter-spacing:.1em;text-transform:uppercase;background:var(--mint);color:var(--mint-ink);border-radius:var(--r-pill);padding:4px 9px;flex-shrink:0}
.automation-banner .txt{font-size:13px;flex:1;min-width:200px}
.automation-banner .cta{margin-left:auto;font-size:12.5px;color:var(--mint);font-weight:600;white-space:nowrap;text-decoration:none}

/* segmented control (close period tabs) */
.segmented{display:inline-flex;background:var(--panel-alt);border-radius:var(--r-pill);padding:3px;gap:2px;margin-bottom:22px}
.segtab{padding:8px 16px;border-radius:var(--r-pill);color:var(--faint);font-size:13px;font-weight:600}
.segtab.on{background:var(--panel);color:var(--ink);box-shadow:var(--shadow-tab)}

/* blocker panel */
.blocker-panel{background:var(--red-panel-bg);border:1px solid var(--red-panel-border);border-radius:var(--r-md);padding:18px 22px;margin-bottom:20px}
.blocker-panel h3{margin:0 0 12px;font-size:14px;font-weight:600;color:var(--red)}
.blocker-row{display:flex;justify-content:space-between;align-items:center;gap:16px;padding:10px 0;border-bottom:1px solid var(--red-panel-hair)}
.blocker-row:last-child{border-bottom:none}
.blocker-btn{display:flex;align-items:center;gap:8px;padding:7px 12px;border:1px solid var(--red-panel-border);border-radius:var(--r-sm);background:var(--red-panel-bg);font-size:12.5px;font-weight:600;color:var(--red)}
.blocker-btn .dot{width:6px;height:6px;border-radius:50%;background:var(--red)}

/* close stat strip */
.statstrip{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));background:var(--panel);border:1px solid var(--hair-strong);border-radius:var(--r-md);overflow:hidden}
.statcell{padding:16px 18px;border-left:1px solid var(--hair-strong)}
.statcell:first-child{border-left:none}
.statcell .k{font-size:12px;color:var(--faint);font-weight:600;margin-bottom:8px}
.statcell .v{font-family:ui-monospace,Menlo,monospace;font-size:20px;font-weight:500}

.locked{padding:50px 26px;text-align:center;color:var(--faint)}
.locked b{display:block;color:var(--slate);font-size:16px;margin-bottom:5px}
.locked .lockicon{width:44px;height:44px;margin:0 auto 14px;background:var(--field);border:1px solid var(--hair-strong);border-radius:var(--r-lg);display:grid;place-items:center;color:var(--slate)}

.toast{position:fixed;bottom:22px;left:50%;transform:translate(-50%,20px);background:var(--ink);color:#fff;padding:12px 18px;border-radius:var(--r-sm);font-size:13px;font-weight:500;display:flex;gap:10px;align-items:center;box-shadow:0 12px 30px -8px rgba(0,0,0,.4);opacity:0;pointer-events:none;transition:all .25s;z-index:80}
.toast.show{opacity:1;transform:translate(-50%,0)}
.toast i{width:7px;height:7px;border-radius:50%;background:var(--green)}
.toast.warn i{background:var(--red)}

.rolegrid{display:grid;grid-template-columns:1fr;gap:0}
.permrow td:first-child{font-weight:600}
.yes{color:var(--green);font-weight:700}.no{color:var(--hair-strong);font-weight:700}

.subtabs{display:flex;background:var(--panel-alt);border-radius:var(--r-pill);padding:3px;margin-bottom:18px;gap:2px;max-width:100%;overflow-x:auto}
.subtab{padding:8px 16px;border-radius:var(--r-pill);font-weight:600;font-size:13px;color:var(--faint);flex:none;white-space:nowrap}
.subtab.on{background:var(--panel);color:var(--ink);box-shadow:var(--shadow-tab)}
.subtab-groups{display:flex;gap:22px;flex-wrap:wrap;margin-bottom:18px}
.subtab-group{display:flex;flex-direction:column;gap:6px}
.subtab-group-label{font-family:"IBM Plex Mono",monospace;font-size:10px;color:var(--faint);text-transform:uppercase;letter-spacing:.1em;font-weight:500;padding-left:4px}
.subtab-group .subtabs{margin-bottom:0}
.attn-strip{display:flex;flex-direction:column;gap:8px;margin-bottom:18px}
.attn-card{display:flex;justify-content:space-between;align-items:center;gap:16px;padding:12px 16px;border-radius:var(--r-md);border:1px solid var(--hair-strong);background:var(--panel)}
.attn-card b{font-size:13px}
.attn-detail{font-size:12px;color:var(--faint);margin-top:2px}
.attn-card.sev-amber{background:var(--amber-wash);border-color:var(--amber)}
.attn-card.sev-amber b{color:var(--amber-ink)}
.attn-card.sev-red{background:var(--red-wash);border-color:var(--red-border)}
.attn-card.sev-red b{color:var(--red)}
.attn-btn{flex:none;padding:6px 14px;border-radius:var(--r-sm);border:1px solid currentColor;background:transparent;font-size:12px;font-weight:600}
.numin{width:104px;border:1px solid var(--field-border);border-radius:var(--r-lg);padding:6px 10px;font-size:12.5px;text-align:right;background:var(--panel);font-family:"IBM Plex Mono",ui-monospace,Menlo,monospace;font-weight:500}
.numin:focus{border-color:var(--accent);outline:none;background:#fff}
.methsel{border:1px solid var(--field-border);border-radius:var(--r-lg);padding:4px 7px;font-size:11.5px;background:var(--panel);font-family:inherit}
.methsel.ks-empty{border-color:var(--amber);background:var(--amber-wash);color:var(--amber);font-weight:600}
.excrow{display:flex;gap:14px;align-items:flex-start;background:var(--panel);border:1px solid var(--hair-strong);border-radius:var(--r-md);padding:14px 16px;margin-bottom:10px}
.excrow.res{opacity:.62}
.sevdot{width:9px;height:9px;border-radius:50%;margin-top:6px;flex:none}
.sevdot.high{background:var(--red)}.sevdot.medium{background:var(--aging-2)}.sevdot.low{background:var(--slate)}
.conngrid{display:grid;grid-template-columns:repeat(2,1fr);gap:14px;margin-bottom:16px}
.conncard{background:var(--panel);border:1px solid var(--hair-strong);border-radius:var(--r-md);padding:15px 16px;display:flex;gap:12px;align-items:flex-start}
.conncard .lg{width:36px;height:36px;border-radius:var(--r-lg);display:grid;place-items:center;font-weight:700;color:#fff;flex:none;font-size:13px}
.mscrim{position:fixed;inset:0;background:rgba(18,32,26,.4);opacity:0;pointer-events:none;transition:opacity .2s;z-index:70}
.mscrim.show{opacity:1;pointer-events:auto}
.modal{position:fixed;left:50%;top:50%;transform:translate(-50%,-46%);width:min(420px,92vw);max-height:86vh;overflow-y:auto;background:var(--panel);border:1px solid var(--hair-strong);border-radius:var(--r-md);box-shadow:0 20px 60px -20px rgba(0,0,0,.4);z-index:75;opacity:0;pointer-events:none;transition:all .2s}
.modal.show{opacity:1;pointer-events:auto;transform:translate(-50%,-50%)}
.modal .mhead{padding:16px 18px;border-bottom:1px solid var(--hair-strong);font-weight:600;font-size:16px}
.modal .mbody{padding:16px 18px}
.modal .mrow{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;gap:12px}
.modal label{font-size:12px;color:var(--faint);font-weight:600}
.modal .mfoot{padding:14px 18px;border-top:1px solid var(--hair-strong);display:flex;gap:10px}
.mpreview{background:var(--field);border:1px solid var(--hair-strong);border-radius:var(--r-sm);padding:12px;font-size:13px}
.mpreview .pl{display:flex;justify-content:space-between;padding:3px 0}
tr.sub td{border-top:1px solid var(--hair-strong);font-weight:600}
tr.total td{border-top:2px solid var(--ink);font-weight:700;font-size:14px;background:var(--field)}
.closebar{background:var(--panel);border:1px solid var(--hair-strong);border-radius:var(--r-md);padding:14px 16px;margin-bottom:18px}
.closebar .top{display:flex;justify-content:space-between;align-items:center;font-size:13px;margin-bottom:9px;flex-wrap:wrap;gap:6px}
.closebar b{font-weight:600}
.progress{height:8px;background:var(--panel-alt);border-radius:var(--r-pill);overflow:hidden}
.progress i{display:block;height:100%;background:var(--green);border-radius:var(--r-pill)}

/* task grid (Übersicht close card) — one block per close task, colored by
   its own status, instead of one blended progress bar */
.taskgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(20px,1fr));gap:4px}
.taskgrid i{display:block;height:10px;border-radius:3px;background:var(--panel-alt)}
.taskgrid i.done{background:var(--green)}
.taskgrid i.blocked{background:var(--red)}
.taskgrid i.progress{background:var(--amber)}

/* segmented ratio bar (Übersicht KPI — automated vs. needs-decision split) */
.segbar{display:flex;gap:2px;height:6px;margin-top:10px}
.segbar i{flex:1;display:block;border-radius:2px;background:var(--panel-alt)}
.segbar i.done{background:var(--green)}
.segbar i.pending{background:var(--amber)}

/* proportional aging bar (Übersicht "Offene Posten" card) — one continuous
   bar whose segment widths are the real bucket amounts, not discrete blocks */
.aging-bar{display:flex;gap:2px;height:8px;border-radius:3px;overflow:hidden}
.aging-bar i{display:block;height:100%}
.banner-or{background:var(--green-wash);border:1px solid oklch(0.88 0.03 195);border-radius:var(--r-md);padding:11px 14px;margin-bottom:18px;font-size:12.5px;color:var(--green);line-height:1.5}
ul.anhang{margin:0;padding:14px 18px 14px 34px;font-size:12.5px;color:var(--slate);line-height:1.7}
ul.anhang li{margin-bottom:5px}

.dropzone{border:1px dashed var(--hair-strong);border-radius:var(--r-md);background:var(--field);padding:28px;text-align:center;margin-bottom:22px}
.dropzone .t{font-size:14px;font-weight:600;margin-bottom:4px}
.dropzone .s{color:var(--faint);font-size:12.5px;margin-bottom:14px}

@media (max-width:900px){
  .shell{grid-template-columns:1fr}
  aside.side{position:fixed;left:0;top:0;z-index:60;width:248px;transform:translateX(-100%);transition:transform .22s}
  aside.side.open{transform:translateX(0);box-shadow:0 0 40px rgba(0,0,0,.4)}
  .hamburger{display:block}
  /* many views set an inline style="grid-template-columns:..." (e.g. repeat(3,1fr)) —
     !important is needed here so the mobile collapse actually wins over that */
  .kpis{grid-template-columns:repeat(2,1fr)!important}
  .panels{grid-template-columns:1fr!important}
  .conngrid{grid-template-columns:1fr!important}
  .scrim-m{position:fixed;inset:0;background:rgba(0,0,0,.4);z-index:55;display:none}
  .scrim-m.show{display:block}
  .view{padding:18px 16px 60px}
  header.top{padding:12px 16px}
  .kpi .v{font-size:19px}
  table{font-size:12px}
  th,td{padding:9px 12px}
}
@media (max-width:480px){
  .kpis{grid-template-columns:1fr!important}
  .brand b{font-size:14px}
  .periodchip{font-size:12px;padding:5px 9px}
  .toast{width:calc(100% - 32px);max-width:340px;text-align:left}
}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
