/* ============================================================================
   TOOL DESIGN KIT - components.css
   Baut auf tokens.css auf. Nur Semantic-/Component-Tokens, keine Rohwerte.
   Liefert: Reset, Basis, Utilities, App-Shell, Sidebar/Nav, Topbar, Buttons,
   KPI-Karten, Panel/Tabelle, Chips, Legende.
   ============================================================================ */

*{box-sizing:border-box}
html,body{margin:0;height:100%}
body{
  background:var(--bg); color:var(--text);
  font-family:var(--font-sans); font-size:var(--text-base); line-height:1.5;
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
}

/* Utilities */
.num{font-family:var(--font-label); font-weight:500; font-variant-numeric:tabular-nums; font-feature-settings:'tnum' 1}
.eyebrow{font-family:var(--font-label);font-weight:600; font-size:var(--text-xs); letter-spacing:.1em; text-transform:uppercase; color:var(--subtle)}
.muted{color:var(--muted)}
svg.ic{width:18px;height:18px;stroke:currentColor;stroke-width:1.7;fill:none;stroke-linecap:round;stroke-linejoin:round;flex:none}

/* Text-Konventionen - die EINE Quelle für Headings/Body/Labels über alle Tools.
   Schriften nie inline (STANDARDS). Headings = Display-Grotesk, Labels/Meta = Mono.
   Tools laden diese Datei und definieren sie NICHT mehr lokal (single source). */
.heading-xl{font-family:var(--font-display);font-size:var(--text-2xl);font-weight:700;letter-spacing:-.035em;line-height:1.15;margin:0}
.heading-lg{font-family:var(--font-display);font-size:var(--text-xl);font-weight:700;letter-spacing:-.03em;line-height:1.2;margin:0}
.heading-md{font-family:var(--font-display);font-size:var(--text-lg);font-weight:600;letter-spacing:-.025em;line-height:1.3;margin:0}
.body-text{font-size:var(--text-md);line-height:1.55}
.body-small{font-size:var(--text-sm);line-height:1.5}
.hint-text{font-size:var(--text-xs);color:var(--muted)}
.label-text{font-family:var(--font-label);font-size:var(--text-xs);font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--subtle)}

/* Accessibility */
a,button,input,[tabindex]{outline:none}
a:focus-visible,button:focus-visible,input:focus-visible,[tabindex]:focus-visible{box-shadow:var(--ring);border-radius:var(--radius-sm)}
@media (prefers-reduced-motion:reduce){*{animation-duration:.01ms!important;transition-duration:.01ms!important}}

/* ---------- APP SHELL ---------------------------------------------------- */
/* Hoehe: 100dvh, nicht 100vh. Am Handy ist 100vh die Hoehe OHNE Browserleiste -
   die unterste Reihe der App laege sonst dauerhaft hinter der Adressleiste und
   waere auf Seiten ohne Scroll gar nicht erreichbar. 100vh bleibt als Rueckfall. */
.app{display:grid;grid-template-columns:236px 1fr;height:100vh;height:100dvh}
.main{display:flex;flex-direction:column;min-width:0;min-height:0;overflow:auto}
.content{padding:24px 26px;max-width:1180px}

/* ---------- SIDEBAR ------------------------------------------------------ */
.side{background:var(--surface);border-right:1px solid var(--border);display:flex;flex-direction:column}
.brand{display:flex;align-items:center;gap:11px;padding:18px 18px 16px}
.brand .logo{width:34px;height:34px;border-radius:var(--radius-sm);background:var(--accent-strong);color:var(--on-accent);display:grid;place-items:center;box-shadow:var(--shadow-sm)}
.brand .logo svg{width:20px;height:20px;stroke:currentColor;stroke-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}
.brand b{font-family:var(--font-display);font-weight:700;font-size:var(--text-lg);letter-spacing:-.03em}
.brand .ver{font-family:var(--font-label);font-weight:500;font-variant-numeric:tabular-nums;font-size:10px;color:var(--subtle);margin-left:auto;background:var(--sunken);padding:2px 7px;border-radius:var(--radius-pill)}

.side nav{padding:10px 12px;display:flex;flex-direction:column;gap:3px;flex:1}  /* gescopet: bare `nav` würde sonst in Tools mit eigenem <nav> (z.B. edgelab Bottom-Nav) leaken */
.navlbl{font-family:var(--font-label);font-weight:600;font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--subtle);padding:14px 10px 6px}
.ni{display:flex;align-items:center;gap:12px;padding:9px 11px;border-radius:var(--radius-sm);color:var(--muted);text-decoration:none;font-weight:500;cursor:pointer;transition:background var(--dur-fast),color var(--dur-fast)}
.ni:hover{background:var(--sunken);color:var(--text)}
.ni.on{background:var(--accent-soft);color:var(--accent-strong);font-weight:600}
.ni .badge{margin-left:auto;font-family:var(--font-label);font-weight:500;font-variant-numeric:tabular-nums;font-size:11px;background:var(--sunken);color:var(--muted);padding:1px 7px;border-radius:var(--radius-pill)}
.ni.on .badge{background:var(--accent-strong);color:var(--on-accent)}

.acct{margin:12px;padding:11px;display:flex;align-items:center;gap:10px;background:var(--sunken);border-radius:var(--radius)}
.acct .ava{width:32px;height:32px;border-radius:var(--radius-sm);background:var(--accent-strong);color:var(--on-accent);display:grid;place-items:center;font-family:var(--font-label);font-weight:600;font-size:12px}
.acct .who{min-width:0}
.acct .who b{font-size:var(--text-sm);display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.acct .who span{font-size:11px;color:var(--subtle);display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.acct .out{margin-left:auto;color:var(--muted);background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-sm);width:32px;height:32px;display:grid;place-items:center;cursor:pointer;transition:color var(--dur-fast),border-color var(--dur-fast)}
.acct .out:hover{color:var(--bad);border-color:var(--bad)}
/* Hell/Dunkel in der Schublade: am Handy kann die Kopfzeile wegfallen, der Schalter
   darf es nicht. Gleicher Knopf wie das Abmelden, nur ohne die rote Warnfarbe. */
.acct .thema{margin-left:auto;color:var(--muted);background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-sm);width:32px;height:32px;display:grid;place-items:center;cursor:pointer;transition:color var(--dur-fast),border-color var(--dur-fast)}
.acct .thema:hover{color:var(--text);border-color:var(--border-strong)}
.acct .thema+.out{margin-left:0}

/* ---------- TOPBAR ------------------------------------------------------- */
/* Der Einzug der Statusleiste gehoert IN die Leiste: als Web-App laeuft die Seite
   unter der Uhr durch (viewport-fit=cover), ohne den Einzug sitzt die Brotkrume
   hinter der Uhrzeit. Die Hoehe bleibt trotzdem fest und steht als --top-h bereit:
   klebende Kopfzeilen im Inhalt klemmen sich unter die Leiste und muessen deren
   Hoehe kennen. Mit min-height ist die Leiste schmaler als 58+Einzug, dann rutscht
   alles Angeklemmte um die Differenz zu weit nach unten. Im Browser ist der Einzug 0.
   flex:none gehoert dazu: als Flex-Kind einer Spalte wuerde der Kopf sonst mitschrumpfen,
   sobald der Inhalt darunter laenger ist als die Flaeche - min-height hatte das verdeckt. */
:root{--top-h:calc(58px + env(safe-area-inset-top,0px))}
.top{height:var(--top-h);flex:none;border-bottom:1px solid var(--border);background:var(--surface);display:flex;align-items:center;gap:14px;padding:0 22px;padding-top:env(safe-area-inset-top,0px);position:sticky;top:0;z-index:5}
.crumb{font-size:var(--text-base);color:var(--muted)}
.crumb b{color:var(--text);font-weight:600;letter-spacing:-.02em;font-family:var(--font-display)}
.search{margin-left:6px;flex:1;max-width:360px;display:flex;align-items:center;gap:9px;background:var(--sunken);border:1px solid transparent;border-radius:var(--radius-pill);padding:8px 14px;color:var(--subtle)}
.search input{border:none;background:none;outline:none;color:var(--text);font-family:var(--font-sans);font-size:var(--text-sm);width:100%}
.tbtn{margin-left:auto;display:flex;gap:7px}
.iconbtn{width:36px;height:36px;border:1px solid var(--border);background:var(--surface);border-radius:var(--radius-sm);display:grid;place-items:center;color:var(--muted);cursor:pointer;transition:color var(--dur-fast),border-color var(--dur-fast)}
.iconbtn:hover{color:var(--text);border-color:var(--border-strong)}
/* Hamburger (öffnet die Sidebar-Drawer auf Mobil) + Scrim - nur mobil sichtbar */
.iconbtn.navtoggle{display:none}
.scrim{display:none;position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:20}

/* ---------- HEADINGS / BUTTONS ------------------------------------------ */
.h1row{display:flex;align-items:center;gap:16px;margin-bottom:22px}
h1{font-family:var(--font-display);font-size:var(--text-2xl);font-weight:700;letter-spacing:-.035em;margin:0}
.h1row .sub{color:var(--muted);font-size:var(--text-sm)}
.h1row .actions{margin-left:auto;display:flex;gap:9px}
.btn{font-family:var(--font-sans);font-weight:600;font-size:var(--text-sm);padding:9px 15px;border-radius:var(--radius-sm);cursor:pointer;display:inline-flex;align-items:center;gap:7px;border:1px solid var(--border);background:var(--surface);color:var(--text);transition:border-color var(--dur-fast),background var(--dur-fast)}
.btn:hover{border-color:var(--border-strong)}
.btn.pri{background:var(--accent-strong);border-color:var(--accent-strong);color:var(--on-accent);box-shadow:var(--shadow-sm)}
.btn.pri:hover{filter:brightness(1.05)}

/* ---------- KPI CARDS --------------------------------------------------- */
.kpis{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-bottom:22px}
.kpi{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:16px 18px;box-shadow:var(--shadow-sm)}
.kpi.lead{border-top:2px solid var(--accent)}
.kpi .k{font-family:var(--font-mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--subtle);display:flex;align-items:center;gap:7px}
.kpi .k svg{width:14px;height:14px;color:var(--accent);stroke-width:1.8}
.kpi .v{font-family:var(--font-display);font-weight:700;font-size:var(--text-3xl);letter-spacing:-.035em;font-variant-numeric:tabular-nums;margin-top:12px}
.kpi .v small{font-size:var(--text-lg);color:var(--muted);font-weight:500}
.kpi .d{font-family:var(--font-label);font-size:11px;font-weight:500;font-variant-numeric:tabular-nums;margin-top:6px}
.up{color:var(--ok)}.dn{color:var(--bad)}.flat{color:var(--subtle)}
/* Anklickbare Kachel: dieselbe Karte, nur als <button>. Sie setzt den Filter der
   Liste darunter - wer eine Zahl sieht, will sie aufmachen, und tippt sie an.
   Als Knopf gebaut, damit Tastatur und Vorleser sie finden; der gesetzte Zustand
   steht in aria-pressed und nicht in einer Extraklasse. */
.kpi.klick{width:100%;text-align:left;font:inherit;color:inherit;cursor:pointer;
  -webkit-tap-highlight-color:transparent;
  transition:border-color var(--dur-fast),box-shadow var(--dur-fast),background var(--dur-fast)}
.kpi.klick:hover{border-color:var(--border-strong);box-shadow:var(--shadow)}
.kpi.klick[aria-pressed="true"]{border-color:var(--accent);background:var(--accent-soft)}
.kpi.klick[aria-pressed="true"] .k{color:var(--accent-strong)}
.kpi.klick[disabled]{cursor:default;opacity:.65}
.kpi.klick[disabled]:hover{border-color:var(--border);box-shadow:var(--shadow-sm)}

/* ---------- PANEL + TABLE ----------------------------------------------- */
.panel{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow-sm);overflow:hidden}
.panelhd{display:flex;align-items:center;gap:10px;padding:15px 18px;border-bottom:1px solid var(--border)}
.panelhd b{font-family:var(--font-display);font-weight:600;letter-spacing:-.02em;font-size:var(--text-md)}
.panelhd .eyebrow{margin-left:auto}
table{width:100%;border-collapse:collapse}
th{text-align:left;font-family:var(--font-label);font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--subtle);font-weight:600;padding:11px 18px;background:var(--sunken)}
td{padding:13px 18px;border-bottom:1px solid var(--border);font-size:var(--text-sm)}
tr:last-child td{border-bottom:none}
tbody tr:hover td{background:var(--sunken)}
td.r,th.r{text-align:right}
td.r{font-family:var(--font-label);font-weight:500;font-variant-numeric:tabular-nums}
.rowname{font-weight:600}
/* Eine Tabelle, die man am Handy seitwaerts schieben muss, ist keine Tabelle mehr:
   man sieht die erste Spalte und ahnt den Rest. .stapelt loest jede Zeile in eine
   Karte auf - der Kopf faellt weg, und jede Zelle traegt ihre Beschriftung selbst
   in data-label. Die fuehrende Zelle laesst man ohne Label, sie ist die Ueberschrift
   der Karte. Am Rechner bleibt alles eine gewoehnliche Tabelle. */
@media (max-width:720px){
  table.stapelt thead{display:none}
  table.stapelt,table.stapelt tbody,table.stapelt tr,table.stapelt td{display:block;width:auto}
  table.stapelt tr{padding:14px 16px;border-bottom:1px solid var(--border)}
  table.stapelt tr:last-child{border-bottom:none}
  table.stapelt tbody tr:hover td{background:none}
  table.stapelt td{padding:0;border:none}
  table.stapelt td+td{margin-top:7px;display:flex;gap:10px;align-items:baseline}
  table.stapelt td+td::before{content:attr(data-label);flex:none;min-width:6.5rem;
    font-family:var(--font-label);font-size:10px;letter-spacing:.08em;text-transform:uppercase;
    color:var(--subtle);font-weight:600;line-height:1.7}
  table.stapelt td.r,table.stapelt th.r{text-align:left}
}

/* ---------- CHIPS ------------------------------------------------------- */
.chip{display:inline-flex;align-items:center;gap:6px;font-size:var(--text-xs);font-weight:600;padding:3px 10px;border-radius:var(--radius-pill)}
.chip.ok{background:var(--ok-bg);color:var(--ok)}
.chip.warn{background:var(--warn-bg);color:var(--warn)}
.chip.bad{background:var(--bad-bg);color:var(--bad)}
.chip.neutral{background:var(--neutral-bg);color:var(--neutral);font-family:var(--font-label);font-weight:600;font-variant-numeric:tabular-nums;font-size:11px}
.dot{width:6px;height:6px;border-radius:99px;background:currentColor}

/* ---------- LEGEND (Demo/Doku) ----------------------------------------- */
.legend{grid-column:1/-1;border-top:1px solid var(--border);padding:15px 22px;display:flex;align-items:center;gap:22px;flex-wrap:wrap;background:var(--surface)}
.legend .lt{font-family:var(--font-mono);font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--subtle)}
.legend .sw{display:flex;align-items:center;gap:8px;font-size:var(--text-sm)}
.legend .sw i{width:14px;height:14px;border-radius:5px;display:inline-block;box-shadow:var(--shadow-sm)}
.legend .tag{margin-left:auto;font-family:var(--font-label);font-weight:500;font-variant-numeric:tabular-nums;font-size:11px;color:var(--subtle)}

/* ---------- LAYOUT-VARIANTEN (die Shell ist OPTIONAL, kein Zwang) -------- */
/* Ohne Sidebar: Main füllt die Breite. Navigation wandert in die Topbar (.topnav) oder
   über den Inhalt (.tabs). Alle übrigen Komponenten (KPI, Tabelle, Button …) bleiben gleich. */
.app.solo{grid-template-columns:1fr}

/* Horizontale Navigation - für „kein Sidebar"-Tools und In-Page-Umschaltung (z.B. argus-in-Website) */
.topnav{display:flex;flex-direction:row;flex:none;padding:0;align-items:center;gap:2px;flex-wrap:nowrap;min-width:0}
.tabs{display:flex;align-items:center;gap:4px;flex-wrap:wrap}
.tabs.underline{gap:18px;border-bottom:1px solid var(--border)}
.topnav a,.tabs a{display:inline-flex;align-items:center;gap:8px;padding:8px 12px;border-radius:var(--radius-sm);color:var(--muted);font-weight:500;font-size:var(--text-sm);text-decoration:none;cursor:pointer;white-space:nowrap;transition:background var(--dur-fast),color var(--dur-fast)}
.topnav a:hover,.tabs a:hover{color:var(--text);background:var(--sunken)}
.topnav a.on,.tabs a.on{color:var(--accent-strong);background:var(--accent-soft);font-weight:600}
.tabs.underline a{border-radius:0;padding:10px 0;background:none}
.tabs.underline a.on{background:none;box-shadow:inset 0 -2px 0 var(--accent-strong)}

/* Embed (z.B. argus eingebettet in eine Website): keine App-Chrome, Komponenten inline auf
   transparentem Grund. Der Host setzt data-theme/data-tool auf den Wrapper. */
.embed{background:transparent}
.embed .panel{box-shadow:none}

/* ---------- UNTERE LEISTE (nur Handy) ----------------------------------- */
/* Zweite Navigation fuer kleine Schirme: die Ziele, die man unterwegs anfasst, in
   Daumenreichweite; alles Weitere ueber "Mehr" in der Schublade. Am Rechner traegt
   die Seitenleiste, dort ist die Leiste aus. Ein Tool bindet sie ein, indem es
   <nav class="botnav"> als letztes Kind von .app legt - sie wird dann zur zweiten
   Gitterreihe, liegt also neben dem Inhalt und nicht darueber. */
.botnav{display:none}
.bn{flex:1;min-width:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
    padding:8px 2px 6px;border:0;background:none;color:var(--subtle);text-decoration:none;cursor:pointer;
    font-family:var(--font-label);font-weight:600;font-size:10px;
    -webkit-tap-highlight-color:transparent;transition:color var(--dur-fast)}
.bn span{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bn .ic{flex:none}
.bn.on{color:var(--accent-strong)}

/* ---------- RESPONSIVE (Desktop-first, mobil funktional) ---------------- */
@media (max-width:880px){
  /* Am Handy scrollt wieder die SEITE, nicht nur ein Kasten darin. Nur so faehrt die
     Adressleiste des Browsers beim Scrollen ein - sie reagiert ausschliesslich auf
     Dokument-Scroll. Kopf- und Fussleiste bleiben per sticky stehen.
     Seiten, die selbst die volle Hoehe fuellen (Chart, Karte, Editor), setzen
     zusaetzlich .fest - dort scrollt nichts und die Adressleiste bleibt. */
  /* Flex statt Gitter: im Gitter ist die Zeile der unteren Leiste genau so hoch wie die
     Leiste, und position:sticky kommt aus seinem Gitterfeld nicht heraus - die Leiste
     verschwand beim Scrollen nach unten. Als Flex-Spalte ist .app der Bezugsrahmen, und
     sticky haelt die Leiste am unteren Rand. */
  .app{display:flex;flex-direction:column;height:auto;min-height:100dvh}
  .app.fest{height:100dvh;min-height:0}
  .main{flex:1;min-height:0;overflow:visible}
  .app.fest .main{overflow:hidden}
  .side{padding-top:env(safe-area-inset-top,0px)}
  /* Der Home-Indikator des iPhones braucht Luft, aber nicht die vollen 34 px: sonst
     steht unter den Beschriftungen ein toter Streifen und die Leiste wird 85 px hoch.
     12 px abgezogen laesst gut 20 px frei - genug Abstand, halb so viel Moebel.

     position:fixed, nicht sticky. Mit sticky haengt die Leiste an ihrem Elternteil und
     bleibt nur, solange der einen Klebebereich hergibt. Auf einer Seite, die das Dokument
     scrollt, hat Safari genau das nicht durchgehalten: auf der festen Chartflaeche stand
     die Leiste, auf der scrollenden Listenseite fehlte sie ganz (Marcels Bilder vom
     20.09., 22:04 und 22:05). Chromium zeigte in beiden Faellen 801-852 - der Fehler war
     im Testbrowser unsichtbar. fixed haengt am Sichtfenster selbst und braucht keinen
     Klebebereich, also traegt es in beiden Maschinen.

     Weil eine feste Leiste keinen Platz mehr im Fluss belegt, haelt --botnav-h ihn frei:
     unten am .app (dort zieht box-sizing:border-box den Wert auch von den 100dvh der
     festen Flaechen ab). Ohne das liegt die letzte Zeile unter der Leiste. */
  :root{--botnav-h:calc(51px + max(0px,calc(env(safe-area-inset-bottom,0px) - 12px)))}
  .botnav{display:flex;align-items:stretch;background:var(--surface);border-top:1px solid var(--border);
    padding-bottom:max(0px,calc(env(safe-area-inset-bottom,0px) - 12px));
    position:fixed;left:0;right:0;bottom:0;z-index:15}
  .app:has(>.botnav){padding-bottom:var(--botnav-h)}
  /* Die Schublade am Handy ist keine geschrumpfte Schreibtisch-Leiste. Zwei Dinge
     aendern sich gegenueber dem Rechner: sie wird breiter, weil neben ihr nur der
     Abdunkler liegt und kein Inhalt, und jeder Eintrag bekommt ein Tippziel von
     48 px. Am Rechner zielt eine Maus auf 34 px, ein Daumen nicht. */
  .side{position:fixed;left:0;top:0;bottom:0;width:min(320px,86vw);transform:translateX(-100%);transition:transform var(--dur) var(--ease-out);z-index:30;box-shadow:var(--shadow-pop)}
  .side nav{padding:8px 14px;gap:2px;overflow-y:auto}
  .ni{min-height:48px;padding:0 12px;border-radius:var(--radius);font-size:var(--text-md)}
  .navlbl{padding:16px 12px 6px}
  .app.nav-open .side{transform:none}
  .app.nav-open .scrim{display:block}
  .iconbtn.navtoggle{display:grid}
  /* Wo eine untere Leiste haengt, traegt deren "Mehr" die Schublade - der Griff
     oben waere derselbe Knopf ein zweites Mal. */
  .app:has(>.botnav) .iconbtn.navtoggle{display:none}
  .kpis{grid-template-columns:repeat(2,1fr)}
  .content{padding:18px 16px}
  .panel{overflow-x:auto}
}
@media (max-width:520px){
  /* Zwei Spalten, nicht eine: vier Kacheln untereinander schieben die eigentliche
     Liste unter die Falz, und genau wegen der Liste ist man hier. Die Zahl bleibt
     auch auf halber Breite gross genug, nur die Zeile darunter wird enger. */
  .kpis{grid-template-columns:repeat(2,1fr);gap:10px}
  .kpi{padding:13px 14px}
  .kpi .v{margin-top:8px;font-size:var(--text-2xl)}
  .kpi .d{font-size:10px}
  /* Auf dem Handy passen Titel, Beisatz und Knoepfe nicht in eine Zeile.
     Ohne Umbruch quetscht der Beisatz den Titel in drei Zeilen. */
  .h1row{flex-wrap:wrap;gap:10px}
}
