/* Web app: plain and quick. Reuses the site's tokens. */
body.app main.wrap{padding:28px 20px 72px;min-height:60vh}
body.app .top .wrap{height:64px}
body.app .brand img{height:26px;width:auto}
.form{max-width:520px}
/* Login: one centred column; the e-mail field turns into the six code boxes. */
.login{max-width:440px;margin:6vh auto 0;text-align:center}
.login h1{font-size:40px;margin:0 0 28px}
.login .morph{position:relative;min-height:64px}
.login .morph>*{transition:opacity .25s ease,transform .25s ease}
.login .morph .out{opacity:0;transform:scale(.96);pointer-events:none;position:absolute;inset:0}
.login input#email,.login input#email:focus{width:100%;box-sizing:border-box;height:64px;font-size:20px;text-align:center !important;border-radius:16px;background:var(--bg2)}
.login .code{margin-top:0}
.login .btn.app{display:inline-block;margin-top:22px;background:var(--blue);border:none;color:#fff;font-weight:600;padding:14px 28px;border-radius:999px;font-size:16px}
.login .btn.app:disabled{opacity:.5}
.login .newacc{text-align:left;margin-top:14px}
.login .newacc input[type=text]{width:100%;box-sizing:border-box}
.login .hint{margin-top:14px;min-height:20px}
/* TV sign-in hand-off (/tv/): the user code to compare with the TV, and the install/update help below it. */
.login .tvcode{font-size:34px;font-weight:700;letter-spacing:.12em;margin:4px 0;font-variant-numeric:tabular-nums}
.login .tvhelp{margin-top:28px;text-align:left}
.form input,.form select,.form textarea{width:100%;box-sizing:border-box}
.form .actions{margin-top:18px;display:flex;gap:12px;align-items:center}
.form label{margin-top:16px}
body.app .top nav a.active{color:var(--ink)}
body.app h1{font-size:26px;margin:0 0 12px}
body.app h2{font-size:18px;margin:24px 0 10px}
.card{background:var(--surface);border:1px solid var(--line);border-radius:16px;padding:16px;margin:0 0 12px}
.card>h2:first-child{margin-top:0}
/* Replacements for the inline style="" attributes removed by SEC-06/D-26 (no font-size or font-weight in any of
   these): the login consent checkbox, the editor's title/description inputs, its "Block hinzufügen" row and save
   row spacing, the preview gap, the admin ride-code input width and the account "Store-Abo" paragraph margin. */
.check{width:auto}
.full{width:100%}
.mt-8{margin-top:8px}
.mt-12{margin-top:12px}
.note{margin:8px 0 0}
.ridecode{max-width:12em}
.prewrap{white-space:pre-wrap}
/* "Konto löschen" danger card at the bottom of #/settings (D-27, UI-SPEC): separated from "Speichern" above it,
   never looks like the page's main action. */
.card.danger{margin-top:32px;border-color:rgba(248,113,113,.4);overflow-wrap:anywhere}
.card.danger ul{margin:8px 0;padding-left:20px}
.card.danger .code{max-width:360px}
.card.danger .actions{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-top:16px}
.row{display:flex;gap:12px;align-items:center;flex-wrap:wrap}
.grow{flex:1 1 auto}
.muted{color:var(--muted)}
.small{font-size:13px}
.list a.item{display:flex;gap:14px;align-items:center;padding:12px 14px;border:1px solid var(--line);border-radius:14px;background:var(--surface);color:var(--ink);text-decoration:none;margin-bottom:8px}
.list a.item:hover{border-color:var(--blue)}
.list div.item{display:flex;gap:14px;align-items:center;padding:12px 14px;border:1px solid var(--line);border-radius:14px;background:var(--surface);color:var(--ink);margin-bottom:8px}
.list div.item a.plain{color:var(--ink);text-decoration:none}
.list .title{font-weight:600}
.thumb{width:72px;height:40px;flex:0 0 72px}
.profile{width:100%;height:160px;display:block}
input,select,textarea{background:var(--bg2);color:var(--ink);border:1px solid var(--line);border-radius:10px;padding:9px 12px;font:inherit}
input[type=number]{width:110px}
label{display:block;font-size:13px;color:var(--muted);margin:10px 0 4px}
.btn{cursor:pointer}
/* Disabled buttons must look disabled (Review C-WR-02): .btn/.btn.danger set colour, background and border as author
   styles, which override the browser's own greying, so e.g. "Konto endgültig löschen" looked clickable before six
   digits were typed. No font-size or font-weight here (UI-SPEC typography gate); filter:none cancels the hover glow. */
.btn:disabled{opacity:.5;cursor:not-allowed;filter:none}
.btn.small{padding:8px 14px;font-size:14px}
.btn.danger{color:#f87171;border-color:rgba(248,113,113,.5)}
/* The hidden attribute always wins: any class rule that sets display (.btn, .login .btn.app, .upgrade ...) would
   otherwise override it (admin "Mehr laden", reload banner, new-account fields). */
[hidden]{display:none !important}
table{width:100%;border-collapse:collapse;font-size:14px}
th,td{text-align:left;padding:8px 10px;border-bottom:1px solid var(--line);vertical-align:top}
th{color:var(--muted);font-weight:600;font-size:12px;letter-spacing:.06em;text-transform:uppercase}
tr.click{cursor:pointer}
tr.click:hover td{background:rgba(59,130,246,.08)}
.tag{display:inline-block;padding:2px 9px;border-radius:999px;font-size:12px;border:1px solid var(--line);color:var(--muted)}
.tag.ok{color:var(--lime);border-color:rgba(139,210,74,.4)}
.tag.warn{color:var(--amber);border-color:rgba(245,179,47,.4)}
.tag.bad{color:#f87171;border-color:rgba(248,113,113,.4)}
.err{color:#f87171;margin:8px 0}
.code{display:flex;gap:10px;margin-top:6px}
.code input{flex:1 1 0;min-width:0;width:auto;height:64px;text-align:center;font-size:28px;font-weight:700;padding:0;border-radius:16px;background:var(--bg2)}
.code input:focus{outline:none;border-color:var(--cyan);border-width:2px}
.blocks .blk{display:grid;grid-template-columns:110px 90px 110px 1fr 90px 1fr 40px;gap:8px;align-items:center;margin-bottom:8px}
.blocks .blk input,.blocks .blk select{width:100%;box-sizing:border-box}
pre{background:var(--bg2);border:1px solid var(--line);border-radius:10px;padding:10px;font-size:12px;overflow:auto;max-height:320px}
details summary{cursor:pointer;color:var(--muted);margin:10px 0}
.kpi{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:10px}
.kpi div{background:var(--bg2);border:1px solid var(--line);border-radius:12px;padding:12px}
.kpi b{display:block;font-size:22px}
/* Phase 23 (STAT-08): ride-time strip above #/activities; figures tabular, tile lines stack at 140px, 8px between the text lines */
.stats-kpi b{font-variant-numeric:tabular-nums}
.stats-kpi span{display:block;line-height:1.4}
.stats p{margin:8px 0 0}
/* #/admin/jobs (JOB-07, D-19): the 9-column table scrolls inside its wrapper instead of squeezing at narrow widths;
   the linked jobsFailed KPI tile below reuses the plain-tile box. */
.tablewrap{overflow-x:auto;margin:0 0 16px}
table.jobs{min-width:880px}
table.jobs td.errcell{min-width:240px;overflow-wrap:anywhere}
table.jobs .sub{display:block;margin-top:4px}
.kpi a{background:var(--bg2);border:1px solid var(--line);border-radius:12px;padding:12px;color:var(--ink);text-decoration:none;display:block}
.kpi a:hover{border-color:var(--blue)}
.kpi b.bad{color:#f87171}
@media (max-width:720px){.blocks .blk{grid-template-columns:1fr 1fr;}}
/* Reload banner on 426 (UI-SPEC F): static in index.html, app.js only toggles hidden; sticky under the 64px header. */
.upgrade{position:sticky;top:64px;z-index:9;background:rgba(245,179,47,.10);border-bottom:1px solid rgba(245,179,47,.4);backdrop-filter:blur(12px)}
.upgrade .wrap{display:flex;gap:16px;align-items:center;flex-wrap:wrap;padding-top:16px;padding-bottom:16px}
.upgrade b{display:block;color:var(--amber);font-weight:600}
.upgrade span{display:block;font-size:14px;line-height:1.5}
/* Admin diagnostics (wattout-tv 7.5): wide tables scroll inside .tablewrap so a phone never scrolls the page sideways;
   code chips, outbox item lines, the per-client report card and a block-level second line in a cell. No font-size or
   font-weight here. */
table.wide{min-width:880px}
table.wide .tag,table.accounts .tag{white-space:nowrap}
table.stuck{min-width:1240px}
table.wide a,table.wide td:first-child{white-space:nowrap}
td .cf{display:inline-block;min-width:170px}
table.accounts{min-width:1100px}
.dline{display:block;margin-top:2px}
.chips{display:flex;flex-wrap:wrap;gap:6px;margin:6px 0 10px}
ul.outbox{list-style:none;margin:0;padding:0;min-width:260px}
ul.outbox li{margin:0 0 4px}
/* A report ride the server already holds ("inzwischen hochgeladen", 261012-dgx): its outdated lifecycle and outbox stay
   readable but muted. */
ul.outbox.stale,.tag.stale{opacity:.55}
.card.report>p{overflow-wrap:anywhere}
.card.report h3{margin:0 0 6px}
.card.report h4{margin:14px 0 6px;color:var(--muted)}
.card.report b.bad{color:#f87171}
.card.report b.warn{color:var(--amber)}
/* Admin polish (wattout-tv 7.5 follow-up): admin routes widen every .wrap to 1400px so the tables fit a laptop
   (render() sets .wide-admin; phones are unchanged, wide tables still scroll in .tablewrap); KPI tiles in titled
   groups; the client cell's two lines never wrap; the web-request toggle above the account log. No font-size or
   font-weight here. */
.wrap.wide-admin{max-width:1400px}
.kpigroup{margin:0 0 14px}
.kpigroup h3{margin:0 0 6px;letter-spacing:.04em}
.kpigroup .kpi{grid-template-columns:repeat(auto-fill,minmax(150px,1fr))}
.cf .cl,.cf .dline{white-space:nowrap}
/* The account detail's "Letzter Client" line keeps the client on one line: model · OS · seen follow after a dot. */
#latestclient .cf .dline{display:inline;margin:0}
#latestclient .cf .dline::before{content:" · "}
table.accounts td:nth-child(4),table.accounts td:nth-child(12){white-space:nowrap}
label.toggle{display:flex;gap:8px;align-items:center;margin:4px 0 8px;cursor:pointer}
.coach-feedback .coach-headline{font-size:18px;font-weight:700;margin:4px 0 10px}
.coach-feedback h3{font-size:12px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);margin:14px 0 4px}
.coach-feedback .coach-highlight{border-left:3px solid var(--amber);padding-left:10px;font-weight:600}
.coach-feedback .coach-signal{border-left:3px solid var(--cyan);padding-left:10px}
.coach-feedback .coach-signal.warn{border-left-color:var(--amber)}
/* File upload on #/activities: the input stays focusable for keyboard users (never the hidden attribute, which is display:none !important); the label is the visible, named control. */
.vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
label.btn{position:relative}
label.btn:focus-within{outline:2px solid var(--cyan);outline-offset:2px}
.title .tag{margin:0 0 0 8px;vertical-align:middle}
/* Curve of an uploaded FIT: classes only (style-src 'self'), strokes stay 2 px under preserveAspectRatio="none". */
.curve{width:100%;height:160px;display:block;margin:0 0 12px}
.curve-bg{fill:var(--bg2)}
.curve-power{fill:none;stroke:var(--blue);stroke-width:2;vector-effect:non-scaling-stroke}
.curve-hr{fill:none;stroke:var(--amber);stroke-width:2;vector-effect:non-scaling-stroke}
/* Admin tabs ("Nutzung" | "Betrieb") and the usage view: tiles reuse .kpi (lines stack inside a tile); the 12-week chart is
   inline SVG drawn by app.js, styled by classes only (style-src 'self'); it scrolls sideways on a phone instead of shrinking. */
.subtabs{display:flex;gap:6px;margin:0 0 16px;border-bottom:1px solid var(--line)}
.subtabs a{padding:8px 14px;color:var(--muted);text-decoration:none;font-weight:600;border-bottom:2px solid transparent;margin-bottom:-1px}
.subtabs a:hover{color:var(--ink)}
.subtabs a.active{color:var(--ink);border-bottom-color:var(--blue)}
.usage-kpi{grid-template-columns:repeat(auto-fill,minmax(160px,1fr))}
.usage-kpi b{font-variant-numeric:tabular-nums}
.usage-kpi span{display:block;line-height:1.4}
.usage-kpi .ut a{display:inline;background:none;border:0;padding:0;border-radius:0;color:var(--blue)}
.usage-meta{margin:0 0 12px}
.uc{display:block;width:100%;height:auto;background:var(--bg2);border:1px solid var(--line);border-radius:12px}
.uc-grid{stroke:var(--line);stroke-width:1}
.uc-bar{fill:var(--blue)}
.uc-line{fill:none;stroke:var(--lime);stroke-width:2;stroke-linejoin:round}
.uc-dot{fill:var(--lime)}
.uc-t{fill:var(--muted);font-size:13px}
.uc-l{fill:var(--blue)}
.uc-r{fill:var(--lime)}
.uc-key{display:inline-block;vertical-align:middle;margin-right:2px}
.uc-key-bar{width:12px;height:12px;border-radius:2px;background:var(--blue)}
.uc-key-line{width:14px;height:3px;background:var(--lime)}
.uc-key-blue{width:14px;height:3px;background:var(--blue)}
.uc-key-cyan{width:12px;height:12px;border-radius:2px;background:var(--cyan)}
.uc-key-ma{width:14px;height:0;border-top:3px dashed var(--amber)}
.uc-line-b{stroke:var(--blue)}
.uc-area{fill:rgba(59,130,246,.18);stroke:none}
.uc-ma{fill:none;stroke:var(--amber);stroke-width:2;stroke-dasharray:5 3;stroke-linejoin:round}
.uc-bar-c{fill:var(--cyan)}
.uc-hit{fill:transparent}
.uc-hit:hover{fill:rgba(255,255,255,.07)}
.uc-legend{margin:6px 0 0}
/* Usage dashboard: KPI tiles with trend + sparkline, ring gauges, charts in a responsive grid (one column on a phone). */
.ut-trend{font-weight:600;font-size:12px}
.ut-trend.up{color:var(--lime)}
.ut-trend.down{color:#f87171}
.ut-trend.warn{color:var(--amber)}
.ut-trend.flat{color:var(--muted)}
.ut-spark{display:block;width:100%;height:28px;margin-top:6px}
.ut-spark-line{fill:none;stroke:var(--blue);stroke-width:1.5;stroke-linejoin:round;vector-effect:non-scaling-stroke}
.rings{display:grid;grid-template-columns:repeat(auto-fit,minmax(100px,1fr));gap:12px;margin:0 0 8px}
.ring{background:var(--bg2);border:1px solid var(--line);border-radius:12px;padding:12px;text-align:center}
.ring span{display:block;line-height:1.4}
.ring svg{display:block;width:120px;max-width:100%;height:auto;margin:0 auto 6px}
.ring-bg{fill:none;stroke:var(--line);stroke-width:12}
.ring-fg{fill:none;stroke:var(--blue);stroke-width:12;stroke-linecap:round}
.ring-b .ring-fg{stroke:var(--cyan)}
.ring-c .ring-fg{stroke:var(--lime)}
.ring-t{fill:var(--ink);font-size:24px;font-weight:700}
.usage-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,420px),1fr));gap:16px;margin:0 0 8px}
.ufig{min-width:0}
.ufig h3{margin:12px 0 8px;font-size:15px}
/* KI-Kosten: bar per account relative to the limit; the secondary columns drop out on a phone. */
.ai-table td.num{font-variant-numeric:tabular-nums;white-space:nowrap;text-align:right}
.ai-table th:nth-child(3){text-align:right}
.ai-table td.aicell{min-width:90px;width:35%}
.aibar{display:block;width:100%;height:10px}
.aibar-bg{fill:var(--line)}
.aibar-fg{fill:var(--blue)}
.aibar-fg.bad{fill:#f87171}
.ai-table .ai-name{display:block}
.ai-table tr.atlimit td:first-child{border-left:3px solid #f87171}
@media (max-width:640px){.hide-sm{display:none}}
/* Account deletion block on the admin account page. */
.card.danger-zone{border-color:rgba(248,113,113,.4)}
.danger-zone h2{margin-top:0}
.danger-zone input{flex:1 1 220px;min-width:0}
.danger-zone .ok-msg{color:var(--lime);margin:8px 0}
