/* Dashboard — on top of the shared style.css (the container is .dashboard, not .dash: the
   latter is the dashboard link in the web app's nav bar): a sidebar that becomes a top bar
   below 768px, and tables inside a scrollable frame */
.dashboard{display:grid;grid-template-columns:220px 1fr;min-height:100vh}
.side{background:var(--surface-2);border-inline-end:1px solid var(--line);padding:18px 14px;display:flex;flex-direction:column;gap:14px;position:sticky;top:0;height:100vh}
.side .brand{font-size:1.3rem;display:block}
.sidenav{display:flex;flex-direction:column;gap:4px}
.sidenav a{padding:9px 12px;border-radius:10px;color:inherit;text-decoration:none}
.sidenav a.on{background:var(--accent);color:#fff}
.sidefoot{margin-top:auto;display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.sidefoot .who{max-width:100%}
.dashmain{min-width:0}
.dashwrap{padding:22px clamp(14px,3vw,36px);max-width:1200px}
.ovgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:12px}
.two{display:grid;grid-template-columns:1fr 1fr;gap:14px;align-items:start}
.tblwrap{overflow:auto;max-width:100%;border:1px solid var(--line);border-radius:12px}
.tbl{width:100%;border-collapse:collapse;font-size:.95rem}
.tbl th,.tbl td{padding:9px 12px;text-align:start;border-bottom:1px solid var(--line);white-space:nowrap}
.tbl th{font-weight:600;background:var(--surface-2);position:sticky;top:0}
.tbl tr:last-child td{border-bottom:0}
.ltr{direction:ltr;unicode-bidi:isolate;text-align:start}
.kv{display:grid;grid-template-columns:auto 1fr;gap:6px 14px;margin:0}
.kv dt{color:var(--text-2)} .kv dd{margin:0}
.actions{display:flex;flex-direction:column;gap:10px}
.actions form{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.actions .hint{margin:-4px 0 0;font-size:.85rem;color:var(--text-2)}
.actions .danger button{background:transparent;border:1px solid var(--accent);color:var(--accent)}
.searchf{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin:10px 0 14px}
.searchf input{flex:1 1 220px;min-width:0}
.pager{display:flex;justify-content:space-between;align-items:center;margin:12px 0}
.pill.role-owner{background:var(--accent);color:#fff}
.pill.st-disabled{opacity:.6;text-decoration:line-through}
.msg.ok{border-color:#2e9e6a}
.tempw{font-family:'IBM Plex Mono',monospace;font-size:1.2rem;user-select:all}
@media (max-width:767px){
  .dashboard{grid-template-columns:1fr;grid-template-rows:auto 1fr}   /* bar sized to fit; content takes the rest */
  .side{position:static;height:auto;flex-direction:row;flex-wrap:wrap;align-items:center;border-inline-end:0;border-bottom:1px solid var(--line)}
  .sidenav{flex-direction:row;flex-wrap:wrap}
  .sidefoot{margin-top:0;width:100%;justify-content:flex-start}
  .two{grid-template-columns:1fr}
}
.editf{display:flex;flex-direction:column;gap:10px}
.editf label{display:flex;flex-direction:column;gap:4px;font-size:.9rem}
.pairf{border:1px solid var(--line);border-radius:10px;padding:8px 12px 12px;display:grid;grid-template-columns:1fr 1fr;gap:8px;margin:0}
.pairf legend{padding:0 6px;color:var(--text-2)}
.inl{display:inline-flex;gap:4px;align-items:center}
.inl button{padding:4px 8px;font-size:.85rem}
.vlista{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:6px}
.vrowa{display:flex;flex-wrap:wrap;gap:8px;align-items:center;padding:8px 10px;border:1px solid var(--line);border-radius:10px}
.pill.ok{background:#1f6f4a;color:#fff} .pill.warn{background:#8a6d1f;color:#fff} .pill.bad,.num.bad{color:var(--accent);font-weight:700}
button.danger{background:transparent;border:1px solid var(--accent);color:var(--accent)}
@media (max-width:767px){.pairf{grid-template-columns:1fr}}
.csv{display:inline-block;margin:8px 0 16px;font-size:.9rem}

/* 023 US1 — the clip player on the exercise page.
   The box takes a full row (flex-basis:100%) inside .vrowa, so the details sit above and the
   video below, with nothing crowding it at 360px. aspect-ratio reserves the height before the
   image loads so the layout does not jump, and max-width keeps a wide image from pushing the
   page into horizontal scrolling. */
.vplay{flex-basis:100%;max-width:520px}
.vid{position:relative;aspect-ratio:16/9;width:100%;border-radius:10px;overflow:hidden;background:#000;cursor:pointer;display:block;border:1px solid var(--line)}
.vid img,.vid iframe,.vid video{width:100%;height:100%;object-fit:cover;border:0;display:block}
.vid video{object-fit:contain;background:#000}
.vid .play{position:absolute;inset:0;display:grid;place-items:center;pointer-events:none}
.vid .play span{background:rgba(0,0,0,.62);color:#fff;padding:6px 14px;border-radius:999px;font-size:.9rem}
.vid:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.vfoot{display:flex;gap:10px;align-items:center;margin:6px 0 0;font-size:.85rem}
.vfoot .localbtn{padding:4px 10px;font-size:.85rem}
/* Row buttons never break mid-word: the "Hide" label used to render as "Hi/de" at 360px. */
.inl button{white-space:nowrap}

/* 023 US2 — the library page. The filter bar flows onto one or more lines depending on the
   width, so it works at 360 with no horizontal scrolling. Hidden clips are visually dimmed so
   they stand out at a glance without reading the tag. */
.filterbar{display:flex;flex-wrap:wrap;gap:10px;align-items:flex-end;margin:12px 0}
.filterbar label{display:flex;flex-direction:column;gap:4px;font-size:.85rem;min-width:0}
.filterbar input,.filterbar select{min-width:0;max-width:100%}
.clipList{list-style:none;padding:0;margin:12px 0;display:flex;flex-direction:column;gap:8px}
.clipRow{border:1px solid var(--line);border-radius:10px;padding:10px 12px;display:flex;flex-direction:column;gap:6px}
.clipRow.isHidden{opacity:.55}
.clipHead{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
/* The inner form wraps too: without wrap, inline-flex squeezed its children at 360 — the
   classification select down to 54px and the muscles field down to **zero**, i.e. a field that
   exists but cannot be used. */
.clipActs{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.clipActs .inl{flex-wrap:wrap;gap:6px;flex:1 1 auto;min-width:0}
.clipActs select,.clipActs input{font-size:.85rem;padding:4px 6px;min-width:0}
.clipActs select{flex:1 1 9rem;min-width:9rem}
.clipActs input{flex:1 1 7rem;min-width:7rem}
.clipActs label{display:flex;align-items:center;gap:6px;flex:1 1 12rem;min-width:0}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.clipActs .sr{position:static;width:auto;height:auto;clip:auto}

/* 023 US3 — charts. 100% width with a viewBox: they shrink at 360 and are not clipped.
   Colors come from the theme variables, so they follow light and dark without extra code. */
.chart{width:100%;height:auto;max-width:100%;display:block;margin:8px 0 4px;overflow:hidden}
.chart .cbar{fill:var(--accent);opacity:.85}
.chart .cbar.bad{fill:#c2384c}
.chart .ctrack{fill:var(--line)}
.chart .caxis{stroke:var(--line);stroke-width:1}
.chart .cval{fill:var(--text);font-size:11px;text-anchor:middle;font-variant-numeric:tabular-nums}
.chart .ctick{fill:var(--text-2);font-size:10px;text-anchor:middle}
.chart .clabel{fill:var(--text);font-size:14px;text-anchor:end}
/* Horizontal bars: the label is HTML (native RTL and truncation); only the bar is SVG. */
.hbars{margin:8px 0 4px}
.chtitle{margin:0 0 6px;font-size:.9rem;color:var(--text-2)}
.hrow{display:grid;grid-template-columns:minmax(0,1fr) minmax(80px,2fr) auto;gap:8px;align-items:center;margin:3px 0}
.hlabel{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.85rem;min-width:0}
.hval{font-size:.85rem;color:var(--text-2);min-width:2ch;text-align:start}
.chart.hbar{height:14px;margin:0}
@media (max-width:520px){.hrow{grid-template-columns:minmax(0,1.2fr) minmax(60px,1fr) auto}.hlabel{font-size:.8rem}}
.chart.ratio{height:26px}
.chart.ratio .cval{text-anchor:start;font-size:11px}
.covlist{display:flex;flex-direction:column;gap:2px;margin:8px 0}
.covrow{display:grid;grid-template-columns:minmax(90px,1fr) 2fr;gap:8px;align-items:center}
@media (max-width:520px){.covrow{grid-template-columns:1fr}.chart .clabel{font-size:10px}}

/* 026 — the visitors page: its two tables are narrow (2 and 4 columns), so they drop the shared
   420px minimum and a long country name wraps — both fit at 360px without sideways scrolling */
.vstats table{min-width:0}
.tbl td.wrap{white-space:normal}
