/* ════════════════════════════════════════════════════════════════════════════
   VIDEO CONVERTER — THE TOOL-PAGE GRAMMAR (rebuilt 2026-09-07, wave 2).
   The hero band, its flow illustration and the old .panel padding are GONE:
   the page is now header card → step rail → workspace (dropzone / queue table /
   results | output settings) → quiet footer, all from core/shell.css's shared
   `.dl-*` components. What is left here is only what the grammar does not have.

   ⚠ COLOUR: this tool was violet before the rebuild (--vc-accent #7c3aed) and
   stays violet — the grammar's tokens are re-pointed at the tool's own values
   rather than the shared indigo. Every colour below comes from a --dl-* token.
   ⚠ SPECIFICITY: shell.css zeroes non-.panel section padding at (0,2,1) and
   strips .panel chrome per tool at (0,3,0), so every rule here is declared at
   `.tool .app .vc-…` (0,3,0) or higher and nothing uses the .panel class.
   ⚠ test-video-convert.php requires this file to keep ≥12 `html.dark` rules and
   a `.vc-card.is-off` rule.
   ════════════════════════════════════════════════════════════════════════════ */

/* ── the tool's own colour language, on the grammar's tokens ── */
.tool .app.vc-app.dl-page{
  --dl-acc:#7c3aed;--dl-acc-hover:#5b21b6;--dl-acc-ink:#fff;--dl-acc-soft:#f4f0ff;--dl-acc-line:#d8c9fb;
  --vc-accent:#7c3aed;--vc-accent-dark:#5b21b6}
html.dark .tool .app.vc-app.dl-page{
  --dl-acc:#c4b5fd;--dl-acc-hover:#ddd6fe;--dl-acc-ink:#15181d;--dl-acc-soft:rgba(196,181,253,.15);--dl-acc-line:rgba(196,181,253,.36);
  --vc-accent:#c4b5fd;--vc-accent-dark:#ddd6fe}
.tool .app.vc-app .vc-title-accent{color:var(--dl-acc)}

/* ── header + step rail ── */
.tool .app.vc-app .vc-steps{margin:0}
.tool .app.vc-app .dl-page-head .dl-btn{white-space:nowrap}

/* ── the dropzone: full card while empty, a strip once files exist ──
   ⚠ `is-slim` changes `display` on children, so it ships its own [hidden] rule
   at the same specificity — `.x[hidden]{display:none}` at (0,2,0) loses to a
   component rule that sets display, and the "hidden" node keeps painting. */
.tool .app.vc-app .vc-drop-card{padding:14px}
.tool .app.vc-app .vc-drop-card .dl-drop{min-height:280px}
.tool .app.vc-app .vc-drop-card.is-slim{padding:8px}
.tool .app.vc-app .vc-drop-card.is-slim .dl-drop{min-height:0;padding:11px 14px;flex-direction:row;flex-wrap:wrap;gap:10px;border-width:1.5px}
.tool .app.vc-app .vc-drop-card.is-slim .dl-drop-ic{width:30px;height:30px;font-size:14px;border-radius:9px;margin:0}
.tool .app.vc-app .vc-drop-card.is-slim .upload-title{font-size:13.5px}
.tool .app.vc-app .vc-drop-card.is-slim .upload-sub,
.tool .app.vc-app .vc-drop-card.is-slim .upload-mini{display:none}
.tool .app.vc-app .vc-drop-card.is-slim .dl-btn{margin-left:auto;height:32px;padding:0 12px;font-size:12.5px}
/* Video Converter is the ONE tool whose drop card survives the empty state: vc.js does
   `els.drop.classList.toggle('is-slim', !!state.files.length)` and never hides it, so
   .dl-fill-card is still matched while files are staged. A slim strip that grew would put
   ~500px of dashed nothing above the queue. */
.tool .app.vc-app .vc-drop-card.is-slim{flex:0 0 auto}
.tool .app.vc-app .vc-drop-card.is-slim .dl-drop{flex:0 0 auto}
.tool .app.vc-app [hidden]{display:none!important}

/* ── option cards. "Convert to" is the real decision and keeps full cards;
     SIZE is a modifier, so it stays a compact row of pills (kept from the
     pre-rebuild sheet — it is what stopped the panel reading as eight
     identical buttons). ── */
.tool .app.vc-app .vc-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(104px,1fr));gap:8px;width:100%}
.tool .app.vc-app .vc-card{min-width:0;text-align:left;cursor:pointer;font:inherit;
  border:1.5px solid var(--dl-line);border-radius:11px;background:var(--dl-panel);padding:9px 11px;transition:border-color var(--dl-t),background var(--dl-t)}
.tool .app.vc-app .vc-card strong{display:block;font-size:12.5px;font-weight:800;color:var(--dl-ink)}
.tool .app.vc-app .vc-card small{display:block;font-size:11px;line-height:1.35;color:var(--dl-mut);margin-top:2px}
.tool .app.vc-app .vc-card small.vc-rec{color:var(--dl-ok);font-weight:700}
.tool .app.vc-app .vc-card:hover:not(:disabled){border-color:var(--dl-acc)}
.tool .app.vc-app .vc-card.on{border-color:var(--dl-acc);background:var(--dl-acc-soft)}
.tool .app.vc-app .vc-card.on strong{color:var(--dl-acc)}
/* a target this browser cannot write says so on the card and cannot be picked.
   ⚠ GIF is NEVER in this state — supported() returns true for it unconditionally
   because gif.js encodes it, and "no audio" is a property, not a reason. */
.tool .app.vc-app .vc-card.is-off{opacity:.5;cursor:not-allowed}
.tool .app.vc-app .vc-card.is-off:hover{border-color:var(--dl-line)}
.tool .app.vc-app .vc-card:focus-visible{outline:2px solid var(--dl-acc);outline-offset:2px}
.tool .app.vc-app #vcScales{display:flex;flex-wrap:wrap;gap:6px}
.tool .app.vc-app #vcScales .vc-card{flex:0 1 auto;padding:6px 12px;border-radius:999px;text-align:center}
.tool .app.vc-app #vcScales .vc-card strong{display:inline;font-size:12px}
.tool .app.vc-app #vcScales .vc-card small{display:inline;margin:0 0 0 6px;font-size:11px;font-weight:700;font-variant-numeric:tabular-nums}

/* ── the settings panel ── */
.tool .app.vc-app .vc-set-sub{font-size:11.5px;font-weight:600;color:var(--dl-mut)}
.tool .app.vc-app .dl-set.vc-set-col{display:block;padding:13px 18px}
.tool .app.vc-app .dl-set.vc-set-col .dl-set-lbl{display:flex;align-items:center;gap:7px;margin-bottom:8px}
.tool .app.vc-app .vc-size-flag{height:19px;padding:0 7px;font-size:10.5px}
.tool .app.vc-app .vc-hint{font-size:11.5px;line-height:1.55;color:var(--dl-mut);margin-top:8px}
.tool .app.vc-app .vc-hint strong{color:var(--dl-ink-2)}
.tool .app.vc-app .vc-set-out .dl-set-val{display:block;font-size:17px;font-weight:800;color:var(--dl-ink);font-variant-numeric:tabular-nums;margin-bottom:4px}
.tool .app.vc-app .vc-set-note{display:block;font-size:11.5px;line-height:1.5;color:var(--dl-mut)}
/* the padding rides on the NOTE, not the wrapper: PRO hides the note with
   [hidden], and a padded wrapper would leave a 28px empty block behind it */
.tool .app.vc-app .vc-side-acts{padding:0}
.tool .app.vc-app .vc-side-acts .bj-plan-note{margin:14px 18px;font-size:11.5px}

/* ── the per-file queue ── */
.tool .app.vc-app .vc-queue-note{font-size:11.5px;color:var(--dl-mut)}
.tool .app.vc-app .vc-table td{vertical-align:middle}
.tool .app.vc-app .vc-td-name{max-width:230px}
.tool .app.vc-app .vc-file-ic{color:var(--dl-acc);margin-right:8px;font-size:12px}
.tool .app.vc-app .vc-file-nm{display:inline-block;max-width:190px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:middle;font-weight:700;color:var(--dl-ink)}
.tool .app.vc-app .vc-file-meta{display:block;font-size:11px;color:var(--dl-mut);white-space:nowrap}
.tool .app.vc-app .vc-td-out .vc-out-dim{font-weight:700;color:var(--dl-ink)}
.tool .app.vc-app .vc-half{height:17px;padding:0 5px;font-size:10px;margin-left:5px;vertical-align:1px}
/* status = TEXT + an ICON, never colour alone (the README's rule). The
   grammar's ::before dot would then be a THIRD copy of the same signal, so it
   steps aside and the icon carries the colour. */
.tool .app.vc-app .vc-td-st .dl-status{font-size:12.5px;gap:6px;color:var(--dl-ink)}
.tool .app.vc-app .vc-td-st .dl-status::before{display:none}
.tool .app.vc-app .vc-td-st .dl-status i{font-size:11.5px;width:12px;text-align:center;color:var(--dl-ok)}
.tool .app.vc-app .vc-td-st .dl-status.is-warn i{color:var(--dl-warn)}
.tool .app.vc-app .vc-td-st .dl-status.is-bad i{color:var(--dl-bad)}
.tool .app.vc-app .vc-td-st .dl-status.is-busy i{color:var(--dl-acc)}
.tool .app.vc-app .vc-td-x{width:40px;text-align:right}
.tool .app.vc-app .vc-row.is-bad .vc-file-nm{color:var(--dl-bad)}
.tool .app.vc-app .vc-row.is-bad .vc-file-ic{color:var(--dl-bad)}
.tool .app.vc-app .dl-row-btn:disabled{opacity:.35;cursor:not-allowed}
/* 🔴 QA-02 (2026-09-16): this was position:absolute with NO left/top. A span with no
   offset lays out at its STATIC position — inside a horizontally scrolling table cell,
   far to the right — and because no ancestor here is positioned it resolves against
   <body>, so it escapes the scroll container's clip and EXTENDS THE DOCUMENT. At a 390px
   phone the page measured 576 (Leave Manager) and 477 (To-Dos) and scrolled sideways.
   Proved by hiding just this span: 576 -> 390, restore -> 576, while hiding the navbar,
   the container and four in-bounds blocks changed nothing.
   left:-9999px;top:auto is this codebase's own pattern (core/shell.css .su-hp). clip
   alone does not contain it: clip only paints, it does not remove the box from layout. */
.tool .app.vc-app .vc-sr{position:absolute;left:-9999px;top:auto;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* ── progress ── */
.tool .app.vc-app .vc-prog-card{padding:14px 18px}
.tool .app.vc-app .vc-prog-head{display:flex;align-items:center;gap:9px;font-size:12.5px;font-weight:700;color:var(--dl-ink);margin-bottom:8px}
.tool .app.vc-app .vc-prog-pct{margin-left:auto;color:var(--dl-acc);font-weight:800;font-variant-numeric:tabular-nums}
.tool .app.vc-app .vc-prog-bar{height:7px;border-radius:99px;background:var(--dl-hair);overflow:hidden}
.tool .app.vc-app .vc-prog-fill{height:100%;width:0;border-radius:99px;background:var(--dl-acc);transition:width .25s}
.tool .app.vc-app .vc-spin{width:13px;height:13px;border-radius:50%;border:2px solid var(--dl-acc-line);border-top-color:var(--dl-acc);animation:vcspin .7s linear infinite}
@keyframes vcspin{to{transform:rotate(360deg)}}

/* ── results ── */
/* the "lands here" placeholder is a signpost, not a stage: measured at 220px tall
   with the grammar's default empty body, which is a lot of nothing between the
   queue and the fold. It reads as one quiet row instead. */
.tool .app.vc-app #vcResultsEmpty .dl-empty-body{display:flex;align-items:center;justify-content:flex-start;gap:10px;padding:4px 0 6px;text-align:left}
.tool .app.vc-app #vcResultsEmpty .dl-empty-body i{font-size:17px;color:var(--dl-acc)}
.tool .app.vc-app #vcResultsEmpty .dl-empty-body p{margin:0;max-width:none;color:var(--dl-mut)}
.tool .app.vc-app .vc-results-head{display:flex;align-items:center;gap:10px;min-width:0}
.tool .app.vc-app .vc-results-head h3{margin:0;font-size:15px;font-weight:700;color:var(--dl-ink)}
/* align-items:start — a portrait clip beside a landscape one otherwise stretches the
   shorter card to the taller row and leaves a blank slab under its Download button */
.tool .app.vc-app .vc-result-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:12px;align-items:start}
.tool .app.vc-app .vc-rcard{border:1px solid var(--dl-line);border-radius:12px;overflow:hidden;background:var(--dl-panel)}
.tool .app.vc-app .vc-rcard-thumb{display:grid;place-items:center;min-height:132px;padding:9px;background:var(--dl-raised)}
.tool .app.vc-app .vc-rcard-thumb video,
.tool .app.vc-app .vc-rcard-thumb img{max-width:100%;max-height:200px;display:block;border-radius:6px}
.tool .app.vc-app .vc-rcard-body{padding:10px 12px 12px}
.tool .app.vc-app .vc-rcard-name{font-size:12.5px;font-weight:800;color:var(--dl-ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tool .app.vc-app .vc-rcard-meta{font-size:11.5px;color:var(--dl-mut);margin:3px 0 9px;font-variant-numeric:tabular-nums}
.tool .app.vc-app .vc-rcard-fail{padding:14px}
.tool .app.vc-app .vc-rcard-msg{font-size:12px;color:var(--dl-bad);margin-top:5px}
.tool .app.vc-app .vc-dl{width:100%;border:0;border-radius:9px;padding:8px 12px;cursor:pointer;
  font:inherit;font-size:12.5px;font-weight:800;color:var(--dl-acc-ink);background:var(--dl-acc);transition:background var(--dl-t)}
.tool .app.vc-app .vc-dl:hover:not(:disabled){background:var(--dl-acc-hover)}
.tool .app.vc-app .vc-dl:disabled{opacity:.6;cursor:default}

/* ── dark twins. shell.css's grammar already re-points every --dl-* token above,
     so these are only the places where an OLDER (0,2,1) literal in dark-tools.css
     or the tool's own history would otherwise win. ── */
html.dark .tool .app.vc-app .vc-card{background:var(--dl-panel);border-color:var(--dl-line)}
html.dark .tool .app.vc-app .vc-card strong{color:var(--dl-ink)}
html.dark .tool .app.vc-app .vc-card small{color:var(--dl-mut)}
html.dark .tool .app.vc-app .vc-card.on{background:var(--dl-acc-soft);border-color:var(--dl-acc)}
html.dark .tool .app.vc-app .vc-card.on strong{color:var(--dl-acc)}
html.dark .tool .app.vc-app .vc-hint{color:var(--dl-mut)}
html.dark .tool .app.vc-app .vc-hint strong{color:var(--dl-ink-2)}
html.dark .tool .app.vc-app .vc-file-nm{color:var(--dl-ink)}
html.dark .tool .app.vc-app .vc-file-meta{color:var(--dl-mut)}
html.dark .tool .app.vc-app .vc-prog-head{color:var(--dl-ink)}
html.dark .tool .app.vc-app .vc-prog-bar{background:var(--dl-hair)}
html.dark .tool .app.vc-app .vc-rcard{background:var(--dl-panel);border-color:var(--dl-line)}
html.dark .tool .app.vc-app .vc-rcard-thumb{background:var(--dl-raised)}
html.dark .tool .app.vc-app .vc-rcard-name{color:var(--dl-ink)}
html.dark .tool .app.vc-app .vc-rcard-meta{color:var(--dl-mut)}
html.dark .tool .app.vc-app .vc-rcard-msg{color:var(--dl-bad)}
html.dark .tool .app.vc-app .vc-set-out .dl-set-val{color:var(--dl-ink)}
html.dark .tool .app.vc-app .vc-set-note{color:var(--dl-mut)}
/* the step rail's own dark surface is shell.css's; only the numerals need the
   tool's accent so the rail is not indigo on a violet page */
html.dark .tool .app.vc-app .dl-step.is-on .dl-step-n,
.tool .app.vc-app .dl-step.is-on .dl-step-n{background:var(--dl-acc);color:var(--dl-acc-ink);border-color:var(--dl-acc)}
html.dark .tool .app.vc-app .dl-step.is-done .dl-step-n,
.tool .app.vc-app .dl-step.is-done .dl-step-n{background:var(--dl-acc-soft);color:var(--dl-acc);border-color:var(--dl-acc-line)}

/* ── narrow: the settings column drops under the workspace (shell.css does the
     grid), so the cards only need to stop being four-across ── */
@container dlpage (max-width:520px){
  .tool .app.vc-app .vc-cards{grid-template-columns:1fr 1fr}
  .tool .app.vc-app .vc-td-name{max-width:150px}
  .tool .app.vc-app .vc-file-nm{max-width:120px}
}

/* ── WHY THIS ONE (added 2026-09-13) ─────────────────────────────────────────────
   This pane may not use the older card class — its test asserts none survives here —
   so the block is a .dl-card and only re-points the shared .dl-cmp tokens to the
   tool's own violet. The padding/margin that the shared sheet keys on that older
   class is restated here for the same reason. Dark twin below, as the house rule
   requires for anything that names a colour. */
.tool .app.vc-app .dl-cmp.vc-cmp{margin-top:22px;padding:clamp(20px,3vw,34px);
  --cmp-a:#6d28d9;--cmp-a2:#8b5cf6;--cmp-soft:#f4f0ff;--cmp-line:#ddd2fb}
html.dark .tool .app.vc-app .dl-cmp.vc-cmp{--cmp-a:#c4b5fd;--cmp-a2:#ddd6fe;
  --cmp-soft:rgba(196,181,253,.12);--cmp-line:rgba(196,181,253,.30)}
