  /* ---- colour tokens (RC7-008) ----
     Every colour the dashboard paints comes from here: ui.js inline styles
     name these, never a literal. The light set is the dashboard as it has
     always looked, except where RC7-022 darkened a token that failed WCAG AA
     (each marked RC7-022: the smallest change that passes on every surface it
     is painted on, hue kept); the dark set below redefines the same names.
     Theme choice: html[data-theme] is set by /static/theme.js before first
     paint ("light" / "dark"; absent = follow the OS), so the dark set applies
     under prefers-color-scheme unless the page is pinned light, and always
     when it is pinned dark. The two dark blocks are identical on purpose.
     rc.11 redesign (Lukas's direction 2, "Ink sidebar"): the handoff's light and
     dark values replace the old ones for the tokens it names (--bg, --bg-sunken,
     --bg-hover, --fill, --ink2, --muted, --faint, --line, --line2, --line-row,
     --field-edge, the status backgrounds, --dot-off) — warm greys instead of
     neutral ones — and add --card, --shadow and the --side-* set below. Every
     RC7-022 pair still passes; the one handoff value that did not (dark
     --field-edge on a dialog, 2.87:1) moved the smallest step that does. */
  :root{
    color-scheme:light;
    /* surfaces — Signal Slate & Alabaster */
    --bg:#f8fafc; --bg-raised:#ffffff; --bg-sunken:#f1f5f9; --bg-hover:#f4f7fb; --card:#ffffff;
    --fill-soft:rgb(241,245,249); --fill:#e8eef6;
    --control-bg:#ffffff; --field-bg:Field; --field-ink:FieldText;
    --field-edge:rgb(148,163,184);
    --preset-ink:var(--ink2); --preset-edge:var(--line2);
    --fill-banner:rgb(241,245,249); --fill-chip:rgb(238,242,248);
    --wash:rgba(15,23,42,.025); --wash2:rgba(15,23,42,.06);
    /* text */
    --ink:rgb(15,23,42); --ink2:rgb(51,65,85); --muted:rgb(90,104,126); --faint:rgb(108,122,143);
    --ink-disabled:rgb(110,120,136);
    --dim-opacity:.73; --count-dim-ink:rgb(60,72,90);
    --pick-count-a:.75; --pick-on-count-a:1;
    --inverse-ink:#fff; --inverse-wash:rgba(255,255,255,.22);
    /* lines */
    --line:#e2e8f0; --line2:#cbd5e1; --line3:rgb(218,226,236); --line-soft:rgb(236,241,247); --line-row:#edf2f7;
    /* accent — Signal Royal Indigo */
    --accent:rgb(67,97,238); --accent-hover:rgb(50,77,214); --accent-ink:#fff; --accent-text:rgb(55,81,210);
    --accent-tint:rgba(67,97,238,.10); --accent-line:rgba(67,97,238,.30); --accent-wash:rgba(67,97,238,.05);
    --accent-glow:rgba(67,97,238,.24); --accent-glow-soft:rgba(67,97,238,.18);
    --accent-line-soft:rgba(67,97,238,.26); --accent-line-strong:rgba(67,97,238,.36);
    /* status */
    --ok:rgb(5,150,105); --ok-bg:rgb(232,248,242); --ok-fg:rgb(6,115,80); --ok-ink:#fff;
    --ok-line:rgb(198,238,222); --ok-tint:rgba(5,150,105,.09); --ok-edge:rgba(5,150,105,.22); --ok-halo:rgba(5,150,105,.18);
    --ok-edge-strong:rgba(5,150,105,.3); --ok-note-a:.89;
    --warn:rgb(217,119,6); --warn-bg:rgb(254,243,220); --warn-fg:rgb(146,84,12);
    --warn-line:rgba(217,119,6,.4); --warn-line-soft:rgba(217,119,6,.28); --warn-tint:rgba(217,119,6,.12); --amber-fg:#b45309;
    --err:rgb(220,38,38); --err-bg:rgb(254,236,236); --err-fg:rgb(185,28,28); --err-ink:#fff;
    --err-strong:rgb(153,27,27); --err-line:rgb(244,206,206); --err-tint:rgba(220,38,38,.09); --err-edge:rgba(220,38,38,.24);
    --danger:rgb(220,38,38); --danger-ink:#fff;
    --alert-fg:rgb(195,40,48); --alert-bg:rgba(220,38,38,.09); --alert-line:rgba(220,38,38,.40);
    --notice-fg:#166534; --notice-bg:#f0fdf4; --notice-line:#bbf7d0;
    --dot-off:rgb(142,152,168); --dot-old:rgb(203,213,225); --dot-old-halo:rgba(203,213,225,.3);
    --warn-dot:rgb(184,136,40);
    --step-todo-line:rgb(226,232,240); --step-todo-ink:rgb(108,122,143);
    /* named hues */
    --violet:#7c3aed; --violet-fg:#6d28d9; --violet-bg:rgba(124,58,237,.09);
    --teal:rgb(13,116,144); --teal-bg:rgba(13,116,144,.08); --teal-line:rgba(13,116,144,.25); --teal-line-strong:rgba(13,116,144,.3);
    --cyan-fg:#0e7490; --cyan-bg:rgba(8,145,178,.09); --cyan-line:rgba(8,145,178,.35);
    --trig-auto:rgb(0,118,146); --trig-manual:#7c3aed; --trig-upload:rgb(5,130,75); --trig-other:rgb(90,104,126);
    /* user-coloured chips */
    --tint-ink-pct:100%; --tint-edge-pct:20%; --tagchip-a:10.2%; --tbadge-a:7.84%; --tag-dot-pct:100%;
    --pick-fill-pct:100%; --pick-edge-pct:100%; --pick-on-ink:#fff;
    --tag-aa-pct:100%;
    /* chart */
    --chart-bar:rgb(99,115,146); --chart-bar-sel:rgb(67,97,238); --chart-zero:var(--line); --chart-share:rgba(99,115,146,.55);
    /* overlays, shadows, focus */
    --scrim:rgba(15,23,42,.45);
    --scrim-dialog:rgba(15,23,42,.45);
    --scrim-source:rgba(15,23,42,.42);
    --scrim-sched:rgba(15,23,42,.48);
    --scrim-tags:rgba(15,23,42,.42);
    --shadow-1:rgba(15,23,42,.05); --shadow-2:rgba(15,23,42,.13); --shadow-3:rgba(15,23,42,.28);
    --shadow-upload:rgba(15,23,42,.06); --shadow-drawer:rgba(15,23,42,.18); --shadow-sched:rgba(15,23,42,.22);
    --spin-track:rgba(15,23,42,.14);
    --focus-ring:rgba(67,97,238,.20); --selection:rgba(67,97,238,.18);
    --shadow:rgba(15,23,42,.06);
    --accent-shadow:rgba(67,97,238,.25);
    --tag-bg-pct:10%; --tag-edge-pct:24%; --tag-dot-mix:80%;
    /* Signal Midnight Slate sidebar */
    --bg-side:#0b1120; --side-ink:rgb(238,242,248); --side-ink2:rgb(203,213,225); --side-muted:rgb(148,163,184); --side-faint:rgb(122,138,160);
    --side-accent:rgb(114,142,255); --side-accent-ink:rgb(11,17,32); --side-glow:rgba(114,142,255,.18); --side-active:rgba(114,142,255,.15);
    --side-hover:rgba(255,255,255,.055); --side-field:rgba(255,255,255,.055); --side-edge:rgba(255,255,255,.085); --side-kbd-edge:rgba(255,255,255,.15);
    --side-chip:rgba(255,255,255,.075); --side-card:rgba(255,255,255,.045); --side-card-edge:rgba(255,255,255,.075); --side-ring:rgba(255,255,255,.18);
    --side-spin:rgba(255,255,255,.18);
    /* log terminal */
    --term:rgb(15,21,35); --term-ink:#e8edf5; --term-text:rgb(198,208,224); --term-dim:rgb(124,138,160);
    --term-ok:rgb(74,201,135); --term-err:rgb(255,120,120); --term-strong:#fff; --term-thumb:rgba(255,255,255,.14);
    --mono:"JetBrains Mono",ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,monospace;
    --ease:cubic-bezier(0.16,1,0.3,1);
  }
  @media (prefers-color-scheme:dark){
    :root:not([data-theme="light"]){
      color-scheme:dark;
      /* surfaces */
      --bg:#0f1626; --bg-raised:rgb(24,33,52); --bg-sunken:#0a0f1c; --bg-hover:#162036; --card:#141d30;
      --fill-soft:rgb(30,41,62); --fill:#1b263d;
      --control-bg:rgb(26,36,56); --field-bg:rgb(20,28,46); --field-ink:rgb(238,242,248); --field-edge:rgb(94,108,132);
      --preset-ink:var(--ink2); --preset-edge:var(--line2);
      --fill-banner:rgb(28,39,60); --fill-chip:rgb(34,47,70);
      --wash:rgba(255,255,255,.03); --wash2:rgba(255,255,255,.08);
      /* text */
      --ink:rgb(238,242,248); --ink2:rgb(208,218,232); --muted:rgb(154,168,188); --faint:rgb(132,146,168);
      --ink-disabled:rgb(132,146,168); --dim-opacity:.62; --count-dim-ink:var(--ink); --pick-count-a:.7; --pick-on-count-a:1;
      --inverse-ink:rgb(15,22,38); --inverse-wash:rgba(0,0,0,.12);
      /* lines */
      --line:#212d45; --line2:#2e3d5c; --line3:rgb(52,66,94); --line-soft:rgb(34,46,70); --line-row:#192338;
      /* accent */
      --accent:rgb(114,142,255); --accent-hover:rgb(140,165,255); --accent-ink:rgb(11,17,32); --accent-text:rgb(150,175,255);
      --accent-tint:rgba(114,142,255,.15); --accent-line:rgba(114,142,255,.42); --accent-wash:rgba(114,142,255,.08);
      --accent-glow:rgba(114,142,255,.18); --accent-glow-soft:rgba(114,142,255,.15);
      --accent-line-soft:rgba(114,142,255,.38); --accent-line-strong:rgba(114,142,255,.46);
      /* status */
      --ok:rgb(52,211,153); --ok-bg:rgb(18,46,38); --ok-fg:rgb(134,228,184); --ok-ink:rgb(10,30,20);
      --ok-line:rgb(36,88,68); --ok-tint:rgba(52,211,153,.12); --ok-edge:rgba(52,211,153,.3); --ok-halo:rgba(52,211,153,.22);
      --ok-edge-strong:rgba(52,211,153,.36); --ok-note-a:.82;
      --warn:rgb(230,180,72); --warn-bg:rgb(50,40,19); --warn-fg:rgb(240,202,120);
      --warn-line:rgba(230,180,72,.45); --warn-line-soft:rgba(230,180,72,.32); --warn-tint:rgba(230,180,72,.14); --amber-fg:rgb(245,190,100);
      --err:rgb(244,98,104); --err-bg:rgb(56,24,32); --err-fg:rgb(255,156,160); --err-ink:rgb(28,18,18);
      --err-strong:rgb(255,176,176); --err-line:rgb(104,44,52); --err-tint:rgba(244,98,104,.14); --err-edge:rgba(244,98,104,.34);
      --danger:rgb(206,52,60); --danger-ink:#fff;
      --alert-fg:rgb(255,146,150); --alert-bg:rgba(244,98,104,.12); --alert-line:rgba(244,98,104,.45);
      --notice-fg:rgb(134,224,172); --notice-bg:rgb(20,50,40); --notice-line:rgb(38,88,66);
      --dot-off:rgb(102,116,138); --dot-old:rgb(84,96,118); --dot-old-halo:rgba(148,163,184,.18);
      --warn-dot:rgb(230,180,72);
      --step-todo-line:rgb(44,56,80); --step-todo-ink:rgb(136,150,172);
      /* named hues */
      --violet:rgb(167,139,250); --violet-fg:rgb(200,184,253); --violet-bg:rgba(167,139,250,.16);
      --teal:rgb(100,204,218); --teal-bg:rgba(100,204,218,.12); --teal-line:rgba(100,204,218,.35); --teal-line-strong:rgba(100,204,218,.4);
      --cyan-fg:rgb(103,212,236); --cyan-bg:rgba(34,184,220,.14); --cyan-line:rgba(34,184,220,.4);
      --trig-auto:#0891b2; --trig-upload:#16a34a; --trig-other:#6b7280;
      /* user-coloured chips */
      --tint-ink-pct:40%; --tint-edge-pct:45%; --tagchip-a:22%; --tbadge-a:18%; --tag-dot-pct:75%;
      --pick-fill-pct:30%; --pick-edge-pct:70%; --pick-on-ink:rgb(238,242,248); --tag-aa-pct:0%;
      --tag-bg-pct:20%; --tag-edge-pct:45%;
      /* chart */
      --chart-bar:rgb(126,144,176); --chart-bar-sel:rgb(114,142,255); --chart-share:rgba(126,144,176,.6);
      /* overlays, shadows, focus */
      --scrim:rgba(5,10,20,.65); --scrim-dialog:rgba(5,10,20,.65); --scrim-source:rgba(5,10,20,.65);
      --scrim-sched:rgba(5,10,20,.65); --scrim-tags:rgba(5,10,20,.60);
      --shadow-1:rgba(0,0,0,.32); --shadow-2:rgba(0,0,0,.52); --shadow-3:rgba(0,0,0,.64);
      --shadow-upload:rgba(0,0,0,.32); --shadow-drawer:rgba(0,0,0,.52); --shadow-sched:rgba(0,0,0,.62);
      --spin-track:rgba(255,255,255,.18);
      --focus-ring:rgba(114,142,255,.35); --selection:rgba(114,142,255,.32);
      --shadow:rgba(0,0,0,.35);
      --term:rgb(10,15,26); --term-dim:rgb(124,138,160);
    }
  }
  :root[data-theme="dark"]{
    color-scheme:dark;
    /* surfaces */
    --bg:#0f1626; --bg-raised:rgb(24,33,52); --bg-sunken:#0a0f1c; --bg-hover:#162036; --card:#141d30;
    --fill-soft:rgb(30,41,62); --fill:#1b263d;
    --control-bg:rgb(26,36,56); --field-bg:rgb(20,28,46); --field-ink:rgb(238,242,248); --field-edge:rgb(94,108,132);
    --preset-ink:var(--ink2); --preset-edge:var(--line2);
    --fill-banner:rgb(28,39,60); --fill-chip:rgb(34,47,70);
    --wash:rgba(255,255,255,.03); --wash2:rgba(255,255,255,.08);
    /* text */
    --ink:rgb(238,242,248); --ink2:rgb(208,218,232); --muted:rgb(154,168,188); --faint:rgb(132,146,168);
    --ink-disabled:rgb(132,146,168); --dim-opacity:.62; --count-dim-ink:var(--ink); --pick-count-a:.7; --pick-on-count-a:1;
    --inverse-ink:rgb(15,22,38); --inverse-wash:rgba(0,0,0,.12);
    /* lines */
    --line:#212d45; --line2:#2e3d5c; --line3:rgb(52,66,94); --line-soft:rgb(34,46,70); --line-row:#192338;
    /* accent */
    --accent:rgb(114,142,255); --accent-hover:rgb(140,165,255); --accent-ink:rgb(11,17,32); --accent-text:rgb(150,175,255);
    --accent-tint:rgba(114,142,255,.15); --accent-line:rgba(114,142,255,.42); --accent-wash:rgba(114,142,255,.08);
    --accent-glow:rgba(114,142,255,.18); --accent-glow-soft:rgba(114,142,255,.15);
    --accent-line-soft:rgba(114,142,255,.38); --accent-line-strong:rgba(114,142,255,.46);
    /* status */
    --ok:rgb(52,211,153); --ok-bg:rgb(18,46,38); --ok-fg:rgb(134,228,184); --ok-ink:rgb(10,30,20);
    --ok-line:rgb(36,88,68); --ok-tint:rgba(52,211,153,.12); --ok-edge:rgba(52,211,153,.3); --ok-halo:rgba(52,211,153,.22);
    --ok-edge-strong:rgba(52,211,153,.36); --ok-note-a:.82;
    --warn:rgb(230,180,72); --warn-bg:rgb(50,40,19); --warn-fg:rgb(240,202,120);
    --warn-line:rgba(230,180,72,.45); --warn-line-soft:rgba(230,180,72,.32); --warn-tint:rgba(230,180,72,.14); --amber-fg:rgb(245,190,100);
    --err:rgb(244,98,104); --err-bg:rgb(56,24,32); --err-fg:rgb(255,156,160); --err-ink:rgb(28,18,18);
    --err-strong:rgb(255,176,176); --err-line:rgb(104,44,52); --err-tint:rgba(244,98,104,.14); --err-edge:rgba(244,98,104,.34);
    --danger:rgb(206,52,60); --danger-ink:#fff;
    --alert-fg:rgb(255,146,150); --alert-bg:rgba(244,98,104,.12); --alert-line:rgba(244,98,104,.45);
    --notice-fg:rgb(134,224,172); --notice-bg:rgb(20,50,40); --notice-line:rgb(38,88,66);
    --dot-off:rgb(102,116,138); --dot-old:rgb(84,96,118); --dot-old-halo:rgba(148,163,184,.18);
    --warn-dot:rgb(230,180,72);
    --step-todo-line:rgb(44,56,80); --step-todo-ink:rgb(136,150,172);
    /* named hues */
    --violet:rgb(167,139,250); --violet-fg:rgb(200,184,253); --violet-bg:rgba(167,139,250,.16);
    --teal:rgb(100,204,218); --teal-bg:rgba(100,204,218,.12); --teal-line:rgba(100,204,218,.35); --teal-line-strong:rgba(100,204,218,.4);
    --cyan-fg:rgb(103,212,236); --cyan-bg:rgba(34,184,220,.14); --cyan-line:rgba(34,184,220,.4);
    --trig-auto:#0891b2; --trig-upload:#16a34a; --trig-other:#6b7280;
    /* user-coloured chips */
    --tint-ink-pct:40%; --tint-edge-pct:45%; --tagchip-a:22%; --tbadge-a:18%; --tag-dot-pct:75%;
    --pick-fill-pct:30%; --pick-edge-pct:70%; --pick-on-ink:rgb(238,242,248); --tag-aa-pct:0%;
    --tag-bg-pct:20%; --tag-edge-pct:45%;
    /* chart */
    --chart-bar:rgb(126,144,176); --chart-bar-sel:rgb(114,142,255); --chart-share:rgba(126,144,176,.6);
    /* overlays, shadows, focus */
    --scrim:rgba(5,10,20,.65); --scrim-dialog:rgba(5,10,20,.65); --scrim-source:rgba(5,10,20,.65);
    --scrim-sched:rgba(5,10,20,.65); --scrim-tags:rgba(5,10,20,.60);
    --shadow-1:rgba(0,0,0,.32); --shadow-2:rgba(0,0,0,.52); --shadow-3:rgba(0,0,0,.64);
    --shadow-upload:rgba(0,0,0,.32); --shadow-drawer:rgba(0,0,0,.52); --shadow-sched:rgba(0,0,0,.62);
    --spin-track:rgba(255,255,255,.18);
    --focus-ring:rgba(114,142,255,.35); --selection:rgba(114,142,255,.32);
    --shadow:rgba(0,0,0,.35);
    --term:rgb(10,15,26); --term-dim:rgb(124,138,160);
  }
  *{box-sizing:border-box}
  html,body{margin:0;padding:0}
  /* While Settings' save bar shows, the page scrolls a focused control clear
     of it (ui.js _sbPad sets the bar's height; DX-02, WCAG 2.4.11). */
  html{scroll-padding-bottom:var(--savebar-pad,0px)}
  body{font-family:"Plus Jakarta Sans","Inter",ui-sans-serif,system-ui,-apple-system,sans-serif;background:var(--bg);color:var(--ink);letter-spacing:-0.008em;-webkit-font-smoothing:antialiased}
  h1,h2,h3,.side-name{letter-spacing:-0.022em}
  button{font-family:inherit}
  /* A link-looking control that is a real button (UX-06: these were <a onclick>
     with no href, which the keyboard could not reach). */
  .linkbtn{appearance:none;background:none;border:none;padding:0;margin:0;font:inherit;color:var(--accent);cursor:pointer;text-align:inherit;line-height:inherit;border-radius:3px}
  .linkbtn:hover{text-decoration:underline}
  .linkbtn:focus-visible,.an-toggle:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
  /* Read by screen readers, not drawn (UX-21: inputs named by a placeholder alone). */
  /* A dialog's own box takes focus only as a fallback (nothing focusable in it
     yet); its controls draw the focus ring. */
  [aria-modal="true"]:focus{outline:none}
  /* A heading the app moves focus to (a new page's h1, a section's h2, an
     upload's outcome — tabindex="-1"): the accent ring when the keyboard
     brought it there, none after a click (DX-07; Chrome drew its own ring). */
  h1[tabindex="-1"]:focus,h2[tabindex="-1"]:focus,#u-fail-head:focus{outline:none}
  h1[tabindex="-1"]:focus-visible,h2[tabindex="-1"]:focus-visible,#u-fail-head:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:4px}
  .sr-only{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
  a{color:inherit}
  /* Form fields take the theme's field colours. Light keeps the browser's own
     (Field / FieldText), which is what they have always had. */
  input:not([type=checkbox]):not([type=radio]):not([type=color]):not([type=file]),select,textarea{background-color:var(--field-bg);color:var(--field-ink)}
  /* Placeholders: light keeps the browser's own (Chromium's #757575 is 4.6:1
     on white; other browsers differ, and none of them move). On the dark
     field that grey is 3.7:1, so wherever the dark set applies they take
     --faint instead (5.7:1 on --field-bg). Same two selectors as the dark
     token blocks. */
  @media (prefers-color-scheme:dark){:root:not([data-theme="light"]) ::placeholder{color:var(--faint);opacity:1}}
  :root[data-theme="dark"] ::placeholder{color:var(--faint);opacity:1}
  @keyframes dcspin{to{transform:rotate(360deg)}}
  @keyframes dcblink{0%,100%{opacity:1}50%{opacity:.3}}
  @keyframes dcline{from{opacity:0;transform:translateY(3px)}to{opacity:1;transform:none}}
  @keyframes dcscrim{from{opacity:0}to{opacity:1}}
  @keyframes dcslide{from{transform:translateX(100%)}to{transform:translateX(0)}}
  ::selection{background:var(--selection)}
  .scroll::-webkit-scrollbar{width:10px;height:10px}
  .scroll::-webkit-scrollbar-thumb{background:var(--term-thumb);border-radius:8px;border:2px solid transparent;background-clip:padding-box}
  /* .spin sits on filled buttons: it takes the button's own text colour. */
  .spin{display:inline-block;width:14px;height:14px;border:2px solid color-mix(in srgb,currentColor 40%,transparent);border-top-color:currentColor;border-radius:50%;animation:dcspin .7s linear infinite}
  .spin-ink{display:inline-block;width:14px;height:14px;border:2px solid var(--spin-track);border-top-color:var(--accent);border-radius:50%;animation:dcspin .7s linear infinite;vertical-align:middle}
  .main{max-width:1312px;margin:0 auto;padding:30px 36px 96px}
  /* A page that is one message — a report that isn't available, a refusal, a
     load error: centred, its heading the page's H1 (FC-04; the server's
     refusal pages use the same two classes). */
  .main.note-pg{max-width:560px;text-align:center;padding-top:72px}
  .note-h1{margin:0 0 8px;font-size:17px;font-weight:700;letter-spacing:-.01em;line-height:1.3;overflow-wrap:anywhere}
  .detail-title{margin:0;font-size:30px;font-weight:700;letter-spacing:-.03em;line-height:1.12;overflow-wrap:anywhere}
  .mono-wrap{font-family:var(--mono);overflow-wrap:anywhere}

  /* ---- shell: the ink sidebar (rc.11 redesign, Lukas's direction 2) ----
     240px, full height, near-black in both themes: .side (and the phone bar,
     .mbar) map the --side-* tokens onto the names everything inside them
     paints with, so a shared class (.spin-ink, a focus ring) comes out right
     on ink. Sizes are the handoff's "Shared shell". renderShell() (ui.js)
     fills #side-nav and #side-user. */
  .skip-link{position:absolute;left:12px;top:-64px;z-index:500;padding:10px 14px;border-radius:9px;background:var(--accent);color:var(--accent-ink);font-size:14px;font-weight:500;text-decoration:none}
  .skip-link:focus{top:12px;outline:2px solid var(--ink);outline-offset:2px}
  .shell{display:flex;align-items:stretch;min-height:100vh}
  .shell-main{flex:1;min-width:0}
  #app:focus{outline:none}
  .side,.mbar{--ink:var(--side-ink);--ink2:var(--side-ink2);--muted:var(--side-muted);--faint:var(--side-faint);
    --accent:var(--side-accent);--accent-ink:var(--side-accent-ink);--spin-track:var(--side-spin);color-scheme:dark;color:var(--ink)}
  .side{width:240px;flex:none;position:sticky;top:0;height:100vh;height:100dvh;z-index:30;display:flex;flex-direction:column;
    background-color:var(--bg-side);background-image:radial-gradient(260px 180px at 30px 0,var(--side-glow),transparent 70%)}
  /* The sidebar's contents. While the sidebar is the drawer (≤ 900px, open) this
     is its modal dialog — the <aside> stays the page's landmark (FC-02). */
  .side-dlg{flex:1;min-height:0;display:flex;flex-direction:column}
  .side-head{display:flex;align-items:center;gap:10px;padding:16px 14px 14px 16px}
  .side-brand{display:flex;align-items:center;gap:10px;min-width:0;color:inherit;text-decoration:none;border-radius:8px}
  .side-mark{width:28px;height:28px;display:block;flex:none;border-radius:7px;box-shadow:0 0 0 1px var(--side-ring)}
  .side-brand-txt{display:flex;flex-direction:column;gap:2px;min-width:0}
  .side-name{font-size:15px;font-weight:700;letter-spacing:-.02em;line-height:1}
  .side-by{font-size:10px;font-weight:500;letter-spacing:.06em;line-height:1;color:var(--faint);white-space:nowrap}
  .side-ws{margin-left:auto;min-width:0;max-width:96px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
    font-size:11.5px;font-weight:500;color:var(--ink2);padding:3px 8px;border-radius:6px;background:var(--side-chip);border:1px solid var(--side-edge)}
  .side-search-wrap{padding:0 12px}
  .side-search{appearance:none;cursor:pointer;width:100%;display:flex;align-items:center;gap:8px;height:36px;padding:0 10px;border-radius:8px;
    background:var(--side-field);border:1px solid var(--side-edge);color:var(--muted);font:inherit;font-size:13px;text-align:left;transition:border-color 120ms}
  .side-search:hover{border-color:var(--side-kbd-edge)}
  .side-search .lbl{flex:1;min-width:0}
  .kbd{font-family:inherit;font-size:11px;line-height:1.35;padding:0 5px;border-radius:4px;border:1px solid var(--side-kbd-edge);color:var(--muted);white-space:nowrap}
  .side-nav{flex:1;min-height:0;display:flex;flex-direction:column}
  .side-list{flex:1;min-height:0;overflow-y:auto;padding:14px 8px 8px;display:flex;flex-direction:column;gap:1px;scrollbar-width:thin;scrollbar-color:var(--side-edge) transparent}
  .side-grp{display:flex;flex-direction:column;gap:1px}
  .side-h{font-size:11px;font-weight:500;letter-spacing:.07em;text-transform:uppercase;color:var(--faint);padding:16px 10px 6px}
  .side-row{display:flex;align-items:center;gap:10px;flex:none;height:32px;padding:0 10px;border-radius:7px;color:var(--ink2);font-size:13.5px;
    text-decoration:none;cursor:pointer;transition:background 120ms}
  .side-row svg{flex:none}
  .side-row .lbl{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .side-row .n{font-size:12px;color:var(--faint);font-variant-numeric:tabular-nums}
  .side-row:hover{background:var(--side-hover)}
  .side-row[aria-current]{background:var(--side-active);color:var(--ink);font-weight:500}
  .side-row[aria-current] svg{color:var(--side-accent)}
  .side-row[aria-current] .n{color:var(--ink2)}
  .side-navfoot{padding:8px 8px 0;display:flex;flex-direction:column;gap:2px}
  .side-user{padding:0 8px 8px}
  .side-card{display:flex;align-items:center;gap:10px;padding:8px 10px;margin-top:4px;border-radius:10px;background:var(--side-card);border:1px solid var(--side-card-edge)}
  .side-av{width:30px;height:30px;flex:none;border-radius:8px;background:var(--side-accent);color:var(--side-accent-ink);
    display:inline-flex;align-items:center;justify-content:center;font-size:12px;font-weight:700;letter-spacing:.02em}
  /* The name and the role's line are each a 24px target (WCAG 2.5.8): Sign
     out sits right under the name. */
  .side-who{display:flex;flex-direction:column;gap:0;flex:1;min-width:0}
  .side-me{appearance:none;background:none;border:none;padding:0;margin:0;font:inherit;font-size:13px;font-weight:500;color:var(--ink);text-align:left;
    height:24px;line-height:24px;
    cursor:pointer;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border-radius:4px;max-width:100%}
  .side-me:disabled{cursor:default}
  .side-me:not(:disabled):hover{text-decoration:underline}
  /* A role that doesn't fit beside Sign out wraps rather than being cut
     (A11Y2-12: "Not regis…" with text spacing): Sign out takes the next line. */
  .side-role{font-size:11.5px;color:var(--muted);min-width:0;overflow-wrap:anywhere}
  /* The role's line: the role, then Sign out as a small link (DX-21). */
  .side-sub{display:flex;flex-wrap:wrap;align-items:center;gap:5px;min-height:24px;min-width:0;font-size:11.5px;color:var(--muted)}
  .side-sep{flex:none;color:var(--muted)}   /* --faint was 3.44–4.4:1 on the ink (A11Y2-13) */
  .side-out{flex:none;display:inline-flex;align-items:center;min-height:24px;color:var(--muted);text-decoration:none;white-space:nowrap;border-radius:3px}
  /* A button since rc.16 (the sign-out form posts): it keeps the link's look. */
  button.side-out{appearance:none;background:none;border:none;padding:0;margin:0;font:inherit;cursor:pointer}
  .side-out:hover{color:var(--ink);text-decoration:underline}
  .side .side-out:focus-visible{outline-offset:1px}
  .side-ib{appearance:none;cursor:pointer;flex:none;width:28px;height:28px;padding:0;display:inline-flex;align-items:center;justify-content:center;
    border-radius:7px;border:none;background:none;color:var(--muted);text-decoration:none;transition:background 120ms,color 120ms}
  .side-ib:hover{background:var(--side-hover);color:var(--ink)}
  /* Inset rings: a ring drawn outside a row would be cut by the scrolling list. */
  .side a:focus-visible,.side button:focus-visible,.mbar a:focus-visible,.mbar button:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
  .side-search[hidden],.side-ws[hidden],.side-ib[hidden]{display:none}
  .mbar .mbar-ws{margin-left:0;max-width:40vw;flex:0 1 auto}
  /* a touch screen offers no keyboard shortcut (UX2-19; the palette's footer is
     hidden after its own rule below, UX3-03) */
  @media (hover:none) and (pointer:coarse){ #side-kbd{display:none} }
  .side-close,.mbar,.side-scrim{display:none}
  /* The colour theme button cycles System → Light → Dark (cycleTheme). It
     shows the current choice; the icon follows html[data-theme], so it is
     right before ui.js runs. */
  .theme-btn svg{display:none}
  :root:not([data-theme]) .theme-btn .ic-system,
  :root[data-theme="light"] .theme-btn .ic-light,
  :root[data-theme="dark"] .theme-btn .ic-dark{display:block}
  /* ≤ 900px: the sidebar becomes a drawer behind the bar's menu button. Open,
     its #side-dlg is a modal dialog over a scrim (toggleSide): a tap on the
     scrim only closes it, never reaches the page under it (QA-060's rule, kept). */
  @media (max-width:900px){
    .shell{display:block}
    .mbar{display:flex;align-items:center;gap:8px;position:sticky;top:0;z-index:40;height:56px;padding:0 10px 0 8px;
      background-color:var(--bg-side);border-bottom:1px solid var(--side-edge)}
    .mbar .side-brand{padding:4px 6px;flex:none}   /* "Lens" never yields to a long workspace chip (UX3-07) */
    .mbar .side-name{font-size:16px}
    .mbar-fill{flex:1}
    .mbar-btn{width:40px;height:40px}
    .side{position:fixed;top:0;bottom:0;left:0;z-index:60;width:280px;max-width:86vw;height:auto;
      transform:translateX(-100%);visibility:hidden;transition:transform 200ms var(--ease),visibility 0s linear 200ms}
    .side.open{transform:none;visibility:visible;transition:transform 200ms var(--ease);box-shadow:0 0 60px var(--shadow-3)}
    .side-scrim.open{display:block;position:fixed;inset:0;z-index:59;background:var(--scrim)}
    .side-close{display:inline-flex;width:36px;height:36px;margin-left:auto}
    .side-ws+.side-close{margin-left:0}
    .side-row{height:40px}
    .side-ib{width:36px;height:36px}
  }
  /* Reduced motion (DX-08): the drawers don't slide, the scrim and the log's
     lines don't fade in, nothing scrolls smoothly (ui.js _still() for the
     Guide's chips and the Settings list). A spinner still turns: it says
     something is happening. */
  @media (prefers-reduced-motion:reduce){
    .side,.side.open{transition:none}
    .spin,.spin-ink{animation:none}   /* still rings; the words beside them say what runs (A11Y2-07) */
    #drawer-host>div,#d-log>div,#u-log>div{animation:none!important}
    html{scroll-behavior:auto!important}
  }

  /* ---- the ⌘K palette (openPalette): the sidebar's search ---- */
  .pal-ov{position:fixed;inset:0;z-index:300;background:var(--scrim-dialog);display:flex;justify-content:center;align-items:flex-start;padding:12vh 16px 16px}
  .pal{width:100%;max-width:560px;max-height:min(560px,76vh);display:flex;flex-direction:column;background:var(--bg-raised);border:1px solid var(--line2);
    border-radius:12px;box-shadow:0 24px 64px var(--shadow-3);overflow:hidden}
  .pal-head{display:flex;align-items:center;gap:10px;padding:0 14px;border-bottom:1px solid var(--line);color:var(--faint)}
  .pal-head:focus-within{box-shadow:inset 0 -2px 0 var(--accent)}
  .pal-q{flex:1;min-width:0;height:50px;border:none;outline:none;background:transparent!important;font:inherit;font-size:15px;color:var(--ink)!important}
  .pal-list{overflow-y:auto;padding:6px;min-height:0}
  .pal-group{font-size:11px;font-weight:500;letter-spacing:.07em;text-transform:uppercase;color:var(--faint);padding:10px 10px 4px}
  .pal-opt{display:flex;align-items:center;gap:10px;min-height:38px;padding:6px 10px;border-radius:8px;cursor:pointer;color:var(--ink2);font-size:14px}
  .pal-opt svg{flex:none;color:var(--muted)}
  .pal-opt .lbl{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .pal-opt .meta{margin-left:auto;padding-left:12px;flex:none;font-size:12px;color:var(--faint);white-space:nowrap}
  .pal-opt[aria-selected="true"]{background:var(--accent-tint);color:var(--ink)}
  .pal-opt[aria-selected="true"] svg{color:var(--accent-text)}
  .pal-opt[aria-selected="true"] .meta{color:var(--muted)}
  /* The chosen report's secondary way in: its page in Lens, "Details"
     (rc.14; Shift+Enter from the keyboard — Enter opens the report itself). */
  .pal-alt{display:none;flex:none;align-items:center;gap:4px;margin-left:auto;padding:2px 8px;border-radius:6px;font-size:12px;font-weight:500;
    color:var(--accent-text);border:1px solid var(--line2);background:var(--bg-raised)}
  .pal-opt[aria-selected="true"] .pal-alt{display:inline-flex}
  .pal-opt[aria-selected="true"] .meta+.pal-alt{margin-left:10px}
  .pal-alt:hover{border-color:var(--accent-text)}
  .pal-empty{padding:18px 18px 12px;color:var(--muted);font-size:13.5px;line-height:1.5}   /* outside the listbox (FC-03) */
  .pal-foot{display:flex;gap:16px;padding:9px 14px;border-top:1px solid var(--line);font-size:12px;color:var(--muted)}
  /* A touch screen offers no keyboard shortcut (UX2-19): after the rule above,
     which it overrode at the same specificity on a tablet over 640px (UX3-03).
     Nor the header's "Esc" chip (rc.12, FC4-07). */
  @media (hover:none) and (pointer:coarse){ .pal-foot,.pal-esc{display:none} }
  .pal .kbd{border-color:var(--line2);color:var(--muted)}
  @media (max-width:640px){
    .pal-ov{padding:8px}
    .pal{max-height:calc(100vh - 16px)}
    .pal-opt .meta{display:none}
    .pal-foot{display:none}
  }

  /* ---- the "New" button and its menu (title row of the reports list) ---- */
  .newmenu{position:relative;flex:none}
  /* .newmenu: over .primary's own 14px / 8px radius, which comes later (DX-15). */
  .newmenu .new-btn{height:36px;padding:0 12px 0 14px;gap:7px;border-radius:9px;font-size:13.5px;box-shadow:0 6px 16px var(--accent-shadow)}
  .new-btn svg:last-child{opacity:.85}
  .new-menu{display:none;position:absolute;right:0;top:calc(100% + 6px);z-index:45;min-width:200px;padding:6px;flex-direction:column;gap:2px;
    background:var(--bg-raised);border:1px solid var(--line2);border-radius:12px;box-shadow:0 12px 36px var(--shadow-2)}
  .newmenu.open .new-menu{display:flex}
  .new-opt{appearance:none;cursor:pointer;font:inherit;font-size:13.5px;font-weight:500;display:flex;align-items:center;gap:9px;height:38px;padding:0 11px;
    border:none;border-radius:8px;background:none;color:var(--ink);text-align:left;white-space:nowrap}
  .new-opt svg{flex:none;color:var(--muted)}
  .new-opt:hover{background:var(--bg-hover)}
  .new-opt:focus-visible,.new-btn:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
  .num{font-variant-numeric:tabular-nums}

  /* ---- the report index (rc.11 redesign, screen 2a "All files") ----
     renderDashboard (ui.js), at the handoff's sizes: the title row, the filter
     row (a radio-group switch, tag pills, the palette's search chip, Clear
     filters) and a full-bleed table of 50px rows. A row's name is its one
     button; its ::after covers the row, so the whole row opens the report's
     page, and the actions cell sits above it. ≤ 900px a row stacks (no
     sideways scroll at 375px) and the column headers stay for screen readers. */
  .ix{--ix-pad:36px;display:flex;flex-direction:column;gap:16px}
  .ix-title{display:flex;align-items:flex-end;gap:16px}
  .ix-head{flex:1 1 auto;min-width:0}
  .ix-eyebrow{font-size:12px;font-weight:500;letter-spacing:.09em;text-transform:uppercase;color:var(--muted)}
  .ix-h1row{display:flex;align-items:baseline;flex-wrap:wrap;gap:4px 22px;margin-top:6px}   /* the reference's 22px to the count (DX-15) */
  .ix-h1{margin:0;min-width:0;font-size:28px;font-weight:700;letter-spacing:-.03em;line-height:1.1;overflow-wrap:anywhere}
  .ix-count{font-size:14px;color:var(--muted)}
  .ix-filters{display:flex;flex-wrap:wrap;align-items:center;gap:6px;padding-top:6px}
  /* All / Reports / Insights. The chosen one is a card on the track with a
     --faint ring: the thumb alone is 1.1:1 on the track, the ring 4.3:1 or more. */
  .ix-seg{display:inline-flex;flex:none;padding:2px;border-radius:8px;background:var(--fill)}
  .ix-seg-opt{appearance:none;cursor:pointer;height:28px;padding:0 11px;border:none;border-radius:6px;background:none;
    font:inherit;font-size:13px;font-weight:500;color:var(--muted);transition:color 120ms}
  .ix-seg-opt:hover{color:var(--ink)}
  .ix-seg-opt[aria-checked="true"]{background:var(--card);color:var(--ink);box-shadow:0 0 0 1px var(--faint),0 1px 2px var(--shadow)}
  .ix-div{flex:none;width:1px;height:20px;margin:0 8px;background:var(--line2)}
  /* The pills, the palette's chip and the tags note: in the row's own flow
     (wrapping) on a wide screen; ≤ 900px one row that scrolls sideways (DX-5). */
  .ix-pillrow{display:contents}
  /* Tag filter pills (the handoff's "Tag colours"): a card with the tag's dot,
     tinted with the tag when chosen. The chosen edge is the AA shade tagVars()
     hands light, 70% toward --ink in dark (DX-17: kept for 3:1). */
  .tpick{appearance:none;cursor:pointer;display:inline-flex;align-items:center;gap:6px;height:26px;padding:0 10px;border-radius:9999px;
    font:inherit;font-size:12px;font-weight:500;white-space:nowrap;border:1px solid var(--line2);background:var(--card);color:var(--ink2);transition:border-color 120ms}
  .tpick:hover{border-color:var(--field-edge)}
  .tpick .dot{width:6px;height:6px;flex:none;border-radius:50%;background:color-mix(in srgb,var(--tag) var(--tag-dot-mix),var(--ink))}
  .tpick .n{font-size:11px;opacity:var(--pick-count-a);font-variant-numeric:tabular-nums}
  .tpick[aria-pressed="true"]{--pick-count-a:var(--pick-on-count-a);
    color:color-mix(in srgb,color-mix(in srgb,var(--tag-text,var(--tag)) var(--tag-aa-pct),var(--tag)) var(--tint-ink-pct),var(--ink));
    background:color-mix(in srgb,var(--tag) var(--tag-bg-pct),transparent);
    border-color:color-mix(in srgb,color-mix(in srgb,var(--tag-fill,var(--tag)) var(--tag-aa-pct),var(--tag)) var(--pick-edge-pct),var(--ink))}
  .ix-qchip{appearance:none;cursor:pointer;display:inline-flex;align-items:center;gap:6px;max-width:100%;height:26px;padding:0 8px 0 9px;border-radius:9999px;
    font:inherit;font-size:12px;font-weight:500;border:1px solid var(--line2);background:var(--fill);color:var(--ink2);transition:border-color 120ms}
  .ix-qchip svg{flex:none;color:var(--muted)}
  .ix-qchip:hover{border-color:var(--field-edge)}
  .ix-qchip:hover svg:last-child{color:var(--ink)}
  .ix-qtxt{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .ix-clear{appearance:none;cursor:pointer;height:26px;padding:0 6px;border:none;border-radius:6px;background:none;
    font:inherit;font-size:12.5px;font-weight:500;color:var(--accent-text)}
  .ix-clear:hover{text-decoration:underline}
  .ix-note{font-size:12.5px;color:var(--muted)}
  .ix-seg-opt:focus-visible,.tpick:focus-visible,.ix-qchip:focus-visible,.ix-clear:focus-visible,.ix-ib:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
  /* the table */
  .ix-table,.ix-empty{margin:3px calc(-1 * var(--ix-pad)) 0;border-top:1px solid var(--line)}
  .ix-row{position:relative;display:grid;grid-template-columns:minmax(0,1fr) 150px 170px 120px 80px;gap:16px;align-items:center;
    min-height:51px;padding:0 var(--ix-pad);border-bottom:1px solid var(--line-row)}   /* 50px and its rule */
  .ix-hrow{min-height:35px;font-size:11px;font-weight:500;letter-spacing:.07em;text-transform:uppercase;color:var(--faint)}
  .ix-body .ix-row{transition:background 120ms}
  .ix-body .ix-row:hover{background:var(--bg-hover)}
  .ix-c{min-width:0}
  .ix-rep{display:flex;align-items:center;gap:10px}
  .ix-tile{width:26px;height:26px;flex:none;border-radius:7px;background:var(--fill);color:var(--ink2);display:inline-flex;align-items:center;justify-content:center}
  .ix-open{appearance:none;cursor:pointer;flex:0 1 auto;min-width:0;margin:0;padding:0;border:none;background:none;font:inherit;font-size:14px;font-weight:500;
    color:var(--ink);text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-decoration:none}   /* a link since rc.13 */
  .ix-open::after{content:"";position:absolute;inset:0}
  .ix-open:focus-visible,.main .ix-open:focus-visible{outline:none}   /* the row draws it (.main a:focus-visible would ring the name too) */
  .ix-open:focus-visible::after{outline:2px solid var(--accent);outline-offset:-2px}
  .ix-pills{display:flex;gap:6px;flex:0 9999 auto;min-width:0;overflow:hidden}
  /* A report's tag (the handoff's 20px pill): the tag's text on its own tint, no edge. */
  .tpill{display:inline-flex;align-items:center;flex:none;height:20px;padding:0 8px;border-radius:9999px;font-size:11px;font-weight:500;white-space:nowrap;
    color:color-mix(in srgb,color-mix(in srgb,var(--tag-text,var(--tag)) var(--tag-aa-pct),var(--tag)) var(--tint-ink-pct),var(--ink));
    background:color-mix(in srgb,var(--tag) var(--tag-bg-pct),transparent)}
  .ix-health{display:flex;align-items:center;gap:8px;font-size:13px;font-weight:500;white-space:nowrap}
  .ix-dot{width:7px;height:7px;flex:none;border-radius:50%}
  .ix-fresh{font-size:13px;line-height:1.35;color:var(--ink2)}
  .ix-faint{color:var(--faint)}
  .ix-ver{font-size:13px;color:var(--faint);white-space:nowrap}
  .ix-v{font-weight:500;color:var(--ink)}
  .ix-act{position:relative;z-index:1;display:flex;align-items:center;justify-content:flex-end;gap:2px}
  .ix-hrow .ix-act{display:block;z-index:auto;text-align:right}
  .ix-row.menu-open .ix-act{z-index:3}
  .ix-ib{appearance:none;cursor:pointer;width:30px;height:30px;flex:none;padding:0;border:none;border-radius:7px;background:none;color:var(--muted);
    display:inline-flex;align-items:center;justify-content:center;transition:background 120ms,color 120ms}
  .ix-ib:hover,.ix-more.open>.ix-ib{background:var(--fill);color:var(--ink)}
  .ix-rf:hover{color:var(--accent-text)}
  .ix-more{position:relative;display:inline-flex}
  .ix-menu{display:none;position:absolute;right:0;top:calc(100% + 4px);z-index:5;min-width:212px;padding:6px;flex-direction:column;gap:2px;
    background:var(--bg-raised);border:1px solid var(--line2);border-radius:12px;box-shadow:0 12px 36px var(--shadow-2)}
  .ix-more.open .ix-menu{display:flex}
  .ix-more.up .ix-menu{top:auto;bottom:calc(100% + 4px)}   /* near the window's bottom it opens upward (DX-20) */
  .ix-scrim{position:fixed;inset:0;z-index:2}              /* ≤ 900px, under an open ⋯ (RG-11) */
  .ix-mi{appearance:none;cursor:pointer;display:flex;align-items:center;gap:9px;height:36px;padding:0 11px;border:none;border-radius:8px;background:none;
    font:inherit;font-size:13.5px;font-weight:500;color:var(--ink);text-align:left;white-space:nowrap}
  .ix-mi svg{flex:none;width:15px;height:15px;color:var(--muted)}
  .ix-mi:hover{background:var(--wash2)}
  .ix-mi:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
  .ix-mi.del,.ix-mi.del svg{color:var(--err-fg)}
  .ix-msep{height:1px;margin:4px;background:var(--line)}
  /* the empty states: none archived, nothing matches, nothing yet */
  .ix-empty{padding:42px var(--ix-pad);text-align:center;font-size:14px;color:var(--muted)}
  .ix-first{padding:48px var(--ix-pad)}
  .ix-first-h{font-size:17px;font-weight:700;color:var(--ink);margin-bottom:6px}
  .ix-first-p{max-width:460px;margin:0 auto;font-size:14px;line-height:1.55}
  .ix-first-btns{display:flex;gap:10px;justify-content:center;flex-wrap:wrap;margin-top:18px}
  /* 901–1240px (DX-01): the five columns would leave the name a sliver beside
     the sidebar, so the table keeps three — Report, Health, Actions — and
     Freshness and Latest version become the Report cell's second line, under
     the name. Their column heads stay for screen readers, visually hidden.
     One rule for both layouts (fix round 2, FC-06): the name never has less
     than about 300px. The three columns give it 323px at 901; the five give
     it 309px from 1241 — at 1181 they gave 249, a visible jump from 602. */
  @media (min-width:901px) and (max-width:1240px){
    .ix-row{grid-template-columns:36px minmax(0,max-content) minmax(0,1fr) 150px 80px;column-gap:0;row-gap:2px;padding-top:8px;padding-bottom:8px}
    .ix-hrow{padding-top:0;padding-bottom:0}
    .ix-rep,.ix-h-rep{grid-column:1/4;grid-row:1}
    .ix-health,.ix-h-health{grid-column:4;grid-row:1/3;margin-left:16px}
    .ix-act{grid-column:5;grid-row:1/3;margin-left:16px}
    .ix-fresh{grid-column:2;grid-row:2;font-size:12.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
    .ix-ver{grid-column:3;grid-row:2;font-size:12.5px;overflow:hidden;text-overflow:ellipsis}
    .ix-ver::before{content:"·" / "";margin:0 6px;color:var(--faint)}
    .ix-h-fresh,.ix-h-ver{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
    .ix-hrow .ix-h-health,.ix-hrow .ix-act{grid-row:1}
  }
  @media (max-width:900px){
    .ix-thead{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
    .ix-row{display:flex;flex-wrap:wrap;align-items:center;column-gap:14px;row-gap:0;min-height:0;
      padding:11px var(--ix-pad) 12px calc(var(--ix-pad) + 36px)}
    .ix-row::after{content:"";order:2;flex-basis:100%;height:0}   /* the name and actions, then the rest */
    .ix-rep{order:0;flex:1 1 calc(100% - 100px);margin-left:-36px;display:grid;grid-template-columns:26px minmax(0,1fr);column-gap:10px;row-gap:6px;align-items:center}
    .ix-tile{grid-row:1;align-self:start}
    .ix-open{white-space:normal;overflow-wrap:anywhere;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;line-height:1.35}
    .ix-pills{grid-column:2;flex-wrap:wrap;overflow:visible}
    .ix-act{order:1;flex:none;align-self:flex-start}
    .ix-health,.ix-fresh,.ix-ver{order:3;flex:0 1 auto;margin-top:5px;font-size:12.5px}
    .ix-ib{width:36px;height:36px}
  }
  @media (max-width:900px){
    .ix-div{display:none}
    .ix-clear{margin-left:auto}
    .ix-pillrow{position:relative;display:flex;align-items:center;gap:6px;order:3;flex:1 1 100%;min-width:0;overflow-x:auto;scrollbar-width:none;
      padding:3px 2px;margin:-3px -2px}   /* relative: a pill's .sr-only count stays inside the scroller */
    .ix-pillrow::-webkit-scrollbar{display:none}
    .ix-pillrow>*{flex:none}
    .ix-pillrow.more:focus-within,.g-chips.more:focus-within,.set-nav-in.more:focus-within{-webkit-mask-image:none!important;mask-image:none!important}
    .ix-pillrow,.g-chips,.set-nav-in{scroll-padding-inline:44px}   /* a focused item is scrolled clear of the edge */
    .ix-pillrow.more{-webkit-mask-image:linear-gradient(90deg,var(--bg) calc(100% - 36px),transparent);
      mask-image:linear-gradient(90deg,var(--bg) calc(100% - 36px),transparent)}
  }
  @media (max-width:780px){
    .ix{--ix-pad:20px}
  }

  /* ---- the pages the design didn't draw: 2a's pattern (DX-06, ui.js pageHead) ----
     Users, Spend, Analytics, Tags, the Guide, New report / New insight /
     Update: the list's padding and left edge, the eyebrow (.ix-eyebrow) and a
     28px H1, the page's buttons at the right of that row, cards with the
     report page's 12px radius on --card. A page's reading width is --pg-max. */
  .main.pg>*{max-width:var(--pg-max,none)}
  .pg-title{display:flex;align-items:flex-end;gap:16px;flex-wrap:wrap;margin-bottom:14px}
  .pg-head{flex:1 1 auto;min-width:0}
  .pg-h1{margin:6px 0 0;font-size:28px;font-weight:700;letter-spacing:-.03em;line-height:1.1;overflow-wrap:anywhere}
  .pg-acts{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
  .pg-lead{margin:0 0 20px;font-size:14px;color:var(--muted);line-height:1.6;max-width:760px}
  .pg-card{border:1px solid var(--line);border-radius:12px;background:var(--card);overflow:hidden}
  .pg-stat{border:1px solid var(--line);border-radius:10px;background:var(--card);padding:14px 18px;min-width:140px}
  /* An Update's way back to its report (RG-09): the breadcrumb's look. */
  .pg-back{appearance:none;cursor:pointer;display:inline-flex;align-items:center;gap:6px;margin:0 0 12px;padding:0;border:none;background:none;
    font:inherit;font-size:13px;color:var(--muted);border-radius:4px}
  .pg-back:hover{color:var(--ink);text-decoration:underline}
  .pg-back:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
  /* The Guide's section chips: wrapping rows; ≤ 900px one row that scrolls
     sideways, faded at the edge while more lies past it (FC-06: ten chips took
     five rows of a phone's first screen). */
  .g-chips{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:22px}
  @media (max-width:900px){
    .g-chips{position:relative;flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;padding:4px;margin:-4px -4px 18px}
    .g-chips::-webkit-scrollbar{display:none}
    .g-chips>*{flex:none;white-space:nowrap}
    .g-chips.more{-webkit-mask-image:linear-gradient(90deg,var(--bg) calc(100% - 40px),transparent);
      mask-image:linear-gradient(90deg,var(--bg) calc(100% - 40px),transparent)}
  }
  .g-chip{appearance:none;cursor:pointer;display:inline-flex;align-items:center;gap:5px;font:inherit;font-size:12.5px;color:var(--ink2);
    background:var(--card);border:1px solid var(--line2);border-radius:9999px;padding:5px 12px}
  .g-chip:hover{border-color:var(--field-edge)}
  .g-chip:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
  /* Checkboxes and radios in the theme's accent (DX-24: the viewer-access
     chooser drew the browser's blue). */
  input[type=checkbox],input[type=radio]{accent-color:var(--accent)}

  /* ---- users (renderUsers; rc.11 fix round 2: 2a's table) ----
     The reports list's table pattern: full bleed under a top rule, a 34px head
     of small capitals, 50px rows on --line-row rules that light on hover; one
     line per person — the email with its organisation pill, the name, the
     role, the reports a viewer sees (two lines at most, "change" beside them),
     Remove as a quiet icon button. ≤ 640px a row restacks; the heads stay for
     screen readers. */
  .u-add{display:flex;align-items:center;gap:10px;margin-bottom:22px;flex-wrap:wrap}
  .u-add .field{flex:1;min-width:220px;max-width:360px}
  .main.pg>.u-table{max-width:none}
  .u-table{--u-pad:36px;margin:0 calc(-1 * var(--u-pad));border-top:1px solid var(--line)}
  .u-row{display:grid;grid-template-columns:minmax(0,1.5fr) minmax(0,1fr) 150px minmax(0,1.4fr) 40px;gap:16px;align-items:center;
    min-height:51px;padding:8px var(--u-pad);border-bottom:1px solid var(--line-row)}
  .u-hrow{min-height:35px;padding-top:0;padding-bottom:0;font-size:11px;font-weight:500;letter-spacing:.07em;text-transform:uppercase;color:var(--faint)}
  .u-body .u-row{transition:background 120ms}
  .u-body .u-row:hover{background:var(--bg-hover)}
  .u-email{display:flex;align-items:center;gap:8px;min-width:0}
  /* An address too long for its column wraps, never cut (A11Y2-12): an email
     has no shorter form to fall back on. */
  .u-email-txt{flex:0 1 auto;min-width:0;font-size:14px;font-weight:500;color:var(--ink);overflow-wrap:anywhere}
  .u-chip{display:inline-flex;align-items:center;flex:none;height:20px;padding:0 8px;border-radius:9999px;font-size:11px;font-weight:500;white-space:nowrap}
  .u-chip.ext{color:var(--amber-fg);background:var(--warn-tint)}
  .u-chip.dc{color:var(--muted);background:var(--fill)}
  .u-chip.org{color:var(--cyan-fg);background:var(--cyan-bg)}
  .u-note{flex:none;font-size:11.5px;color:var(--faint);white-space:nowrap}
  .u-name{min-width:0;font-size:13px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .u-role{min-width:0}
  .u-role-fixed{font-size:13px;font-weight:600;padding-left:2px}
  .u-sees{display:flex;align-items:center;gap:8px;min-width:0;font-size:12.5px}
  .u-sees-txt{flex:0 1 auto;min-width:0;line-height:1.35;overflow-wrap:anywhere;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
  .u-sees-txt.none{color:var(--muted);font-style:italic}
  .u-sees .linkbtn{flex:none}
  /* rc.12 (FC4-06): a cut list's names are a disclosure — a button laid over
     them (no width of its own), so the clamp and the column stay as fix round
     3 set them; open, every name shows and the row grows. */
  .u-sees-w{display:block;position:relative;flex:0 1 auto;min-width:0}
  .u-sees-tog{position:absolute;inset:-2px -4px;margin:0;padding:0;border:0;border-radius:5px;background:none;color:inherit;font:inherit;cursor:pointer}
  .u-sees-tog:hover+.u-sees-txt,.u-sees-tog:focus-visible+.u-sees-txt{text-decoration:underline;text-decoration-color:var(--faint)}
  .u-sees-tog:focus-visible{outline:2px solid var(--accent);outline-offset:0}
  .u-sees-w.open .u-sees-txt{display:block;-webkit-line-clamp:unset;overflow:visible}
  .u-sees-all{color:var(--faint)}
  .u-del{display:flex;justify-content:flex-end;min-width:0}
  .u-rm:hover{color:var(--err-fg)}
  .u-empty{padding:30px var(--u-pad);text-align:center;color:var(--faint);font-size:14px}
  /* 641–1280px: the email keeps a line of its own, its pill and "you" /
     "built-in admin" go under it, and its column is the widest (UX2-02: an
     email had 0–40px left beside them up to ~1280, and "built-in admin" ran
     into Name). */
  @media (min-width:641px) and (max-width:1280px){
    /* Sees keeps 128px — its link and a whole long word ("Unsubscribes") — or
       a report name broke mid-word at ~641–739 and ~901–999px (UX3-02). */
    .u-row{grid-template-columns:minmax(0,2fr) minmax(0,.9fr) 150px minmax(128px,1.2fr) 40px}
    .u-email{flex-wrap:wrap;row-gap:3px}
    .u-email-txt{flex:1 1 100%}
  }
  @media (max-width:780px){
    .u-table{--u-pad:20px}
  }
  /* ---- analytics tables (restack at phone width) ---- */
  .tbl-head{padding:10px 18px;background:var(--bg-sunken);border-bottom:1px solid var(--line);font-size:11.5px;font-weight:500;letter-spacing:.07em;text-transform:uppercase;color:var(--faint)}
  .an-row{display:grid;grid-template-columns:22px minmax(0,1.6fr) 90px 110px 150px;gap:10px;align-items:center}
  .an-last{text-align:right}
  .an-sub-last{color:var(--faint);width:130px;text-align:right;flex:none}
  .an-recent{display:flex;align-items:center;gap:10px;padding:9px 18px;border-bottom:1px solid var(--line-soft);font-size:13.5px}
  .an-who{font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:220px;min-width:0;flex:0 1 auto}
  .an-verb,.an-when{color:var(--faint);white-space:nowrap;flex:none}
  .an-what{color:var(--accent);cursor:pointer;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;flex:1}
  .an-what.an-gone{color:var(--muted);cursor:default;font-weight:400}   /* a deleted report: no page to open (QA-089) */
  .an-old{color:var(--faint);font-size:11.5px;white-space:nowrap;flex:none}
  @media (max-width:640px){
    .tbl-head{display:none}
    .cell-lbl[data-label]::before{content:attr(data-label);content:attr(data-label) / "";display:block;font-size:10.5px;font-weight:500;letter-spacing:.07em;text-transform:uppercase;color:var(--faint);margin-bottom:3px}
    /* Users: the add field takes its own line (its placeholder whole, FC-06),
       the role and the button the next. A row restacks: the email (and its
       pill) and Remove, the name, then the role and what a viewer sees.
       align-items:start keeps the ROLE and SEES labels on one line (centring
       dropped SEES beside the taller dropdown); a row with no name drops the
       name line, and its gap, altogether. The heads stay for screen readers. */
    .u-add .field{flex:1 1 100%;min-width:0;max-width:none}
    .u-thead{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
    .u-row{grid-template-columns:minmax(0,1fr) minmax(0,1fr) 36px;grid-template-areas:"email email del" "name name name" "role sees sees";
      column-gap:12px;row-gap:8px;align-items:start;padding:12px var(--u-pad) 14px}
    .u-row.no-name{grid-template-areas:"email email del" "role sees sees"}
    .u-email{grid-area:email;flex-wrap:wrap;row-gap:4px;min-height:36px} .u-name{grid-area:name} .u-role{grid-area:role} .u-sees{grid-area:sees;display:block} .u-del{grid-area:del}
    .u-email-txt{white-space:normal;overflow-wrap:anywhere}
    .u-row.no-name .u-name{display:none}
    .an-row{grid-template-columns:22px repeat(3,minmax(0,1fr));grid-template-areas:"chev name name name" ". views aud last";row-gap:8px}
    .an-chev{grid-area:chev} .an-name{grid-area:name} .an-views{grid-area:views} .an-aud{grid-area:aud} .an-last{grid-area:last;text-align:left}
    .an-sub{padding-left:22px!important}
    .an-sub-last{width:auto}
    .an-recent{display:grid;grid-template-columns:minmax(0,max-content) auto minmax(0,1fr) auto;grid-template-areas:"who verb . when" "what what what old";column-gap:6px;row-gap:2px}
    .an-who{grid-area:who;max-width:none} .an-verb{grid-area:verb} .an-when{grid-area:when} .an-what{grid-area:what} .an-old{grid-area:old;justify-self:end;align-self:center}
  }

  /* ---- the report's page (rc.11 redesign, screen 2b) ----
     .dmain draws its own gutters: the header (.dhead) and its tabs run the
     width of the page, the panels below keep 36px sides. Settings (.sbody) is
     the handoff's grid: a sticky section list, then the sections; the save bar
     sits at the bottom of the window while General has unsaved changes. */
  .main.dmain{max-width:none;padding:0}
  .dmain [hidden]{display:none!important}   /* a class's display (.ghost's inline-flex) must not show what is hidden */
  .dhead{padding:26px 36px 0;border-bottom:1px solid var(--line);display:flex;flex-direction:column;gap:14px}
  /* One line, never wrapped (DX-19): a long name never leaves a "/" at the end
     of a line. The category gives way first, then the name, each cut with an
     ellipsis (its title has it whole). The padding keeps a focus ring inside
     the line's clip. */
  .crumbs ol{list-style:none;margin:-3px;padding:3px;display:flex;flex-wrap:nowrap;align-items:center;gap:6px;font-size:13px;color:var(--muted);min-width:0;overflow:hidden}
  .crumbs li{display:inline-flex;align-items:center;gap:6px;min-width:0;flex:none}
  .crumbs li.crumb-mid{flex:0 1000 auto;min-width:4.5em}
  .crumbs li.crumb-last{flex:0 1 auto}
  .crumbs li>a,.crumbs li>span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .crumbs li+li::before{content:"/";color:var(--faint)}
  .crumbs a{color:inherit;text-decoration:none;border-radius:4px}
  .crumbs a:hover{color:var(--ink);text-decoration:underline}
  .crumbs a:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
  .crumbs [aria-current]{color:var(--ink2);font-weight:500}
  /* The tile, the name with its badge, the buttons (DX-19): a long name wraps
     in its own column beside the tile and the badge follows its last word, so
     the row never breaks into a column. */
  .dtitle-row{display:grid;grid-template-columns:40px minmax(0,1fr) auto;align-items:center;column-gap:14px;row-gap:12px;min-width:0}
  .dtitle{min-width:0;line-height:1.2}
  .dtile{width:40px;height:40px;flex:none;border-radius:10px;background:var(--fill);color:var(--ink2);display:inline-flex;align-items:center;justify-content:center}
  .dhead .detail-title{display:inline;font-size:26px;letter-spacing:-.03em;line-height:1.2}
  .dbadge{display:inline-flex;vertical-align:middle;position:relative;top:-2px;margin-left:12px;white-space:nowrap}
  .dhead-actions{display:flex;align-items:center;justify-content:flex-end;gap:10px;flex-wrap:wrap}
  /* A long name (.long, over 48 characters) gives the buttons its line, so
     the name keeps the width it needs. */
  .dtitle-row.long{grid-template-columns:40px minmax(0,1fr)}
  .dtitle-row.long .dhead-actions{grid-column:2;justify-content:flex-start}
  /* The redesign's button, on every page (DX-06): 36px, radius 9, 13.5px —
     .primary or .ghost (secondary: --card on a --line2 edge). Doubled with
     them so their own 14px / radius 8 (further down) never wins. */
  .dbtn,.primary.dbtn,.ghost.dbtn{height:36px;padding:0 12px;border-radius:9px;font-size:13.5px;font-weight:500;gap:7px;white-space:nowrap}
  .ghost.dbtn{background:var(--card)}
  .dbtn svg{flex:none}
  .dbtn:focus-visible,.dtab:focus-visible,.set-nav-a:focus-visible,.tok-x:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
  /* A11Y2-10: icon buttons, Spend's report links, the Guide's links, a details summary and a colour swatch */
  .iconbtn:focus-visible,.sp-link:focus-visible,.main a:focus-visible,.main summary:focus-visible,.main input[type="color"]:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}
  .vs-pre:focus-visible{outline:2px solid var(--accent);outline-offset:2px}   /* F10: View source's file, scrolled by keyboard */
  /* rc.14: a .dbtn or .linkbtn that is a link (it opens a report: "View
     report" after a publish, Analytics' report names) looks as the button
     did — no underline at rest, and its own corners when focused, not
     .main a's 4px. rc.15 (RC14-OPENBTN): the report page's Open latest and
     Open (.dbtn), a version's Open (.iconbtn, whose focus ring is .main a's
     already) and ⋯ Open latest (.ix-mi: its ring inside, on its 8px corners). */
  a.dbtn,a.linkbtn,a.iconbtn,a.ix-mi{text-decoration:none}
  a.dbtn{text-align:center}
  a.iconbtn{text-align:center}
  .main a.dbtn:focus-visible{border-radius:9px}
  .main a.linkbtn:focus-visible{border-radius:3px}
  .main a.ix-mi:focus-visible{outline-offset:-2px;border-radius:8px}
  .dbtn:disabled,.dbtn[aria-disabled="true"]{cursor:default;opacity:.55}
  /* A primary with nothing to do (Save schedule before a change, DX-18) is a
     neutral, quiet button, not a dimmed red one (FC-06); a busy one (disabled
     while it saves) keeps its colour. */
  .dbtn[aria-busy="true"]{cursor:progress}
  .primary.dbtn[aria-disabled="true"]:not([aria-busy="true"]),.primary.dbtn[aria-disabled="true"]:not([aria-busy="true"]):hover{background:var(--fill)!important;border-color:var(--line2);
    color:var(--muted);box-shadow:none;opacity:1;cursor:not-allowed}
  .dbtn.danger{appearance:none;cursor:pointer;font-family:inherit;display:inline-flex;align-items:center;background:transparent;border:1px solid var(--err);color:var(--err-fg)}
  .dbtn.danger:not(:disabled):hover{background:var(--err-tint)}
  .dbtn.danger:disabled{cursor:not-allowed}
  /* F6 (rc.16): the tabs wrap onto a second row when they don't fit — at
     320 px Settings was cut at the edge of a strip with no scrollbar; where
     they fit (390 px and up) nothing moves. */
  .dtabs{display:flex;flex-wrap:wrap;gap:2px;min-width:0;overflow-x:auto;scrollbar-width:none;margin-top:4px}   /* 18px under the title row, the reference's (DX-15) */
  .dtabs::-webkit-scrollbar{display:none}
  .dtab{appearance:none;cursor:pointer;flex:none;display:inline-flex;align-items:center;height:40px;padding:0 12px;border:none;background:none;
    font-family:inherit;font-size:13.5px;color:var(--muted);white-space:nowrap;border-radius:6px 6px 0 0}
  .dtab:hover{color:var(--ink)}
  .dtab[aria-selected="true"]{color:var(--ink);font-weight:500;box-shadow:inset 0 -2px 0 var(--accent)}
  .dtab:focus-visible{outline-offset:-2px}
  .dtab-n{margin-left:6px;font-size:12.5px;color:var(--faint);font-weight:400}
  /* Overview, Versions, Activity */
  .dbody{padding:28px 36px 72px;display:flex;flex-direction:column;gap:20px}
  .ov-grid{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:20px;align-items:start}
  .ov-col{display:flex;flex-direction:column;gap:20px;min-width:0}
  .ov-card{border:1px solid var(--line);border-radius:12px;background:var(--card);padding:18px 20px;min-width:0}
  .ov-card.ov-flush{padding:0;overflow:hidden}
  .ov-flush-head{padding:16px 20px;border-bottom:1px solid var(--line);display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:4px 12px}
  .ov-card-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-bottom:12px}
  .ov-h{margin:0 0 12px;font-size:15px;font-weight:700;letter-spacing:-.01em}
  .ov-card-head .ov-h{margin:0}
  .ov-edit{font-size:13px;flex:none}
  .ov-desc{font-size:14px;color:var(--ink2);line-height:1.6}
  .ov-empty{margin:0;font-size:13.5px;color:var(--muted);line-height:1.55}
  .ov-chips{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-top:14px}
  .ov-cat{display:inline-flex;align-items:center;gap:6px;height:22px;padding:0 9px;border-radius:7px;font-size:11.5px;font-weight:500;color:var(--ink2);background:var(--fill)}
  /* F6 (rc.16): a long query name in the version line breaks rather than
     pushing the page sideways at 320 px with text spacing. */
  .ov-meta{font-size:12.5px;color:var(--faint);margin-top:3px;overflow-wrap:anywhere}
  /* rc.16 (A9, QA R16F-02): rows outside the period, said so it can be read */
  .ov-note{margin:10px 0 0;padding:9px 12px;border-radius:8px;background:var(--wash);border:1px solid var(--line2);font-size:13px;line-height:1.55;color:var(--ink2);overflow-wrap:anywhere}
  .ov-cron{font-size:12px;color:var(--faint);margin-top:4px}   /* a writer's cron under the schedule's words (DX-09) */
  /* A cron expression as code, its fields set close (FC-06: in a monospace font
     "0 6 * * *" read as spaced-out asterisks); the text itself is unchanged. */
  .cron{font-family:var(--mono);font-size:.95em;word-spacing:-.3em}
  .ov-acts{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}
  /* Settings */
  .sbody{display:grid;grid-template-columns:180px minmax(0,720px);gap:48px;padding:32px 36px 100px;align-items:start}
  .set-nav{position:sticky;top:24px;display:flex;flex-direction:column;gap:2px;min-width:0}
  .set-nav-in{display:contents}
  .set-nav-a{display:flex;align-items:center;flex:none;height:32px;padding:0 10px;border-radius:7px;font-size:13.5px;color:var(--ink2);text-decoration:none;white-space:nowrap}
  .set-nav-a:hover{background:var(--bg-hover)}
  .set-nav-a[aria-current]{background:var(--fill);color:var(--ink);font-weight:500}
  .set-nav-a.danger{color:var(--err-fg)}
  .set-col{display:flex;flex-direction:column;gap:36px;min-width:0}
  .set-sec{scroll-margin-top:24px;min-width:0}
  .set-sec+.set-sec{border-top:1px solid var(--line);padding-top:36px}
  .set-sec h2{margin:0;font-size:17px;font-weight:700;letter-spacing:-.01em}
  .set-help{margin:4px 0 0;font-size:13px;color:var(--muted);line-height:1.5}
  .set-fields{display:flex;flex-direction:column;gap:20px;margin-top:20px}
  .set-2{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:16px}
  .set-lbl{display:block;font-size:13px;font-weight:500;color:var(--ink2);margin-bottom:6px}
  /* !important: the base field rule (input:not(…) ×4) outranks a class. */
  .set-input{display:block;width:100%;height:38px;padding:0 12px;border-radius:9px;border:1px solid var(--field-edge);background-color:var(--card)!important;color:var(--ink)!important;
    font-family:inherit;font-size:14px;outline:none}
  .set-input:focus,.tokens:focus-within{border-color:var(--accent);box-shadow:inset 0 0 0 1px var(--accent),0 0 0 3px var(--accent-tint)}
  .set-input:disabled{opacity:.6;cursor:not-allowed}
  /* 108px as the reference renders it; no resize grip — it grows with what is
     typed (_growTa), to a point, then scrolls (DX-14/15). */
  .set-ta{height:auto;min-height:108px;max-height:320px;padding:9px 12px;line-height:1.5;resize:none;overflow-y:auto}
  .set-input.mono{font-family:var(--mono);font-size:13px}
  .set-hint{font-size:12px;color:var(--faint);margin-top:6px;line-height:1.45}
  .set-selwrap{position:relative}
  .set-sel-ic{position:absolute;left:12px;top:50%;transform:translateY(-50%);display:inline-flex;color:var(--muted);pointer-events:none}
  .set-selwrap.has-ic .set-input{padding-left:36px}
  /* A select draws the redesign's chevron, not the browser's arrow (DX-14). */
  .set-selwrap select.set-input,.selwrap select{appearance:none;-webkit-appearance:none;padding-right:36px}
  .selwrap{position:relative;display:inline-block}
  .sel-chev{position:absolute;right:12px;top:50%;transform:translateY(-50%);display:inline-flex;color:var(--muted);pointer-events:none}
  /* The time field without the browser's clock; the tag field without the
     datalist's arrow (typing and the suggestions still work). */
  .set-input[type=time]::-webkit-calendar-picker-indicator{display:none}
  .tok-in::-webkit-calendar-picker-indicator{display:none!important}
  .set-note{margin:14px 0 0;font-size:13.5px;color:var(--ink2);line-height:1.55;padding:12px 14px;border-radius:10px;background:var(--bg-sunken);border:1px solid var(--line)}
  .set-foot{margin:12px 0 0;font-size:12px;color:var(--faint);line-height:1.5}
  .set-err{margin-top:10px;font-size:13px;color:var(--err-fg);font-family:var(--mono);overflow-wrap:anywhere}
  .set-btns{display:flex;flex-wrap:wrap;gap:8px;margin-top:16px}
  /* tags: a token input */
  .tokens{display:flex;flex-wrap:wrap;align-items:center;gap:6px;min-height:38px;padding:4px 6px;border-radius:9px;border:1px solid var(--field-edge);
    background:var(--card);cursor:text}
  .tok-list{display:contents}
  .tok{display:inline-flex;align-items:center;gap:5px;height:28px;padding:0 3px 0 9px;border-radius:9999px;font-size:12px;font-weight:500;white-space:nowrap;max-width:100%;
    color:color-mix(in srgb,color-mix(in srgb,var(--tag-text,var(--tag)) var(--tag-aa-pct),var(--tag)) var(--tint-ink-pct),var(--ink));
    background:color-mix(in srgb,var(--tag) var(--tag-bg-pct),transparent);border:1px solid color-mix(in srgb,var(--tag) var(--tag-edge-pct),transparent)}
  .tok-dot{width:6px;height:6px;flex:none;border-radius:50%;background:color-mix(in srgb,var(--tag) var(--tag-dot-mix),var(--ink))}
  .tok-x{appearance:none;cursor:pointer;flex:none;width:20px;height:20px;padding:0;border:none;border-radius:50%;background:none;color:inherit;
    display:inline-flex;align-items:center;justify-content:center}
  .tok-x:hover{background:color-mix(in srgb,var(--tag) var(--tag-edge-pct),transparent)}
  .tok-in{flex:1;min-width:72px;height:28px;padding:0 4px;border:none;outline:none;background:transparent!important;font-family:inherit;font-size:14px;color:var(--ink)!important}
  /* the schedule: a segmented frequency control (native radios), its fields, the estimate */
  .set-fs{border:none;margin:16px 0 0;padding:0;min-width:0}
  .seg{display:inline-flex;max-width:100%;overflow-x:auto;scrollbar-width:none;padding:3px;gap:2px;border-radius:9px;background:var(--fill)}
  .seg::-webkit-scrollbar{display:none}
  .seg-i{position:relative;display:inline-flex;flex:none}
  .seg-i input{position:absolute;opacity:0;width:1px;height:1px;margin:0;pointer-events:none}
  .seg-i span{display:inline-flex;align-items:center;height:32px;padding:0 14px;border-radius:7px;font-size:13.5px;font-weight:500;color:var(--muted);cursor:pointer;white-space:nowrap}
  .seg-i span:hover{color:var(--ink)}
  /* the chosen frequency is ringed like the list's switch (A11Y2-06: its fill alone was 1.15:1) */
  .seg-i input:checked+span{background:var(--card);color:var(--ink);box-shadow:0 0 0 1px var(--faint),0 1px 2px var(--shadow)}
  .seg-i input:focus-visible+span{outline:2px solid var(--accent);outline-offset:-2px}
  .seg-i input:disabled+span{cursor:not-allowed}
  .set-fs:disabled .seg{opacity:.6}
  .sp-fields{display:flex;flex-wrap:wrap;gap:16px;margin-top:16px}
  .sp-fields:not(:has(.sp-g:not([hidden]))){display:none}
  .sp-g-time,.sp-g-dow{flex:0 0 160px}
  .sp-g-day{flex:0 0 140px}
  .sp-g-hmin{flex:0 0 180px}
  .sp-g-tz{flex:1 1 220px;min-width:0}
  .sp-g-cron{flex:1 1 100%}
  .est{display:flex;align-items:stretch;margin:16px 0 0;padding:14px 16px;border-radius:10px;background:var(--bg-sunken);border:1px solid var(--line)}
  .est-stat{padding:0 24px;border-left:1px solid var(--line);min-width:0}
  .est-stat:first-child{padding-left:0;border-left:0}
  .est dt{font-size:11px;font-weight:500;letter-spacing:.07em;text-transform:uppercase;color:var(--faint)}
  .est dd{margin:4px 0 0;font-size:18px;font-weight:700;color:var(--ink);white-space:nowrap}
  .est dd small{font-size:13px;font-weight:400;color:var(--muted)}
  .est dd.sm{font-size:14px;font-weight:500;line-height:26px;white-space:normal;overflow-wrap:anywhere}
  .est-words{margin-top:10px;font-size:12.5px;color:var(--muted);line-height:1.5}
  .sched-save{display:flex;align-items:center;flex-wrap:wrap;gap:10px;margin-top:16px}
  .sched-dirty{font-size:12.5px;color:var(--muted)}
  /* archive or delete */
  .set-list{margin-top:16px;border:1px solid var(--line);border-radius:10px}
  .set-row{display:flex;align-items:center;gap:16px;padding:14px 16px}
  .set-row+.set-row{border-top:1px solid var(--line)}
  .set-row-txt{flex:1;min-width:0}
  .set-row-t{font-size:14px;font-weight:500;color:var(--ink)}
  .set-row-h{font-size:13px;color:var(--muted);margin-top:2px;line-height:1.5}
  /* The list's buttons are the compact ones: 34px, radius 8, 13px (DX-15). */
  .dmain .set-row>.dbtn{height:34px;border-radius:8px;font-size:13px}
  .set-row>button{flex:none}
  /* the unsaved-changes bar */
  .savebar{position:fixed;left:240px;right:0;bottom:0;z-index:25;display:flex;align-items:center;gap:12px;min-height:64px;padding:0 36px;
    background:var(--card);border-top:1px solid var(--line);box-shadow:0 -6px 20px var(--shadow)}
  .savebar[hidden]{display:none}
  .savebar-dot{width:8px;height:8px;flex:none;border-radius:50%;background:var(--warn)}
  .savebar-txt{font-size:13.5px;color:var(--ink2);min-width:0}
  .savebar-fill{flex:1}
  .savebar-save{box-shadow:0 6px 16px var(--accent-shadow)}
  .set-sec h2:focus{outline:none}
  .set-sec h2:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:4px}
  @media (max-width:1100px){
    .ov-grid{grid-template-columns:minmax(0,1fr)}
  }
  /* 901–1040px: beside its section list, Settings' column is under ~450px —
     the frequency switch is a 3×2 grid and the strip's next run takes its own
     line, as at ≤ 640px (UX2-01: Custom cron was cut at 901–985, and a long
     zone ran past the strip and scrolled the page sideways at 901). */
  @media (min-width:901px) and (max-width:1040px){
    .seg{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));width:100%}
    .seg-i span{justify-content:center;width:100%;padding:0 8px}
    .est{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);row-gap:12px}
    .est-stat:nth-child(3){grid-column:1/-1;padding:12px 0 0;border-left:0;border-top:1px solid var(--line)}
  }
  @media (max-width:900px){
    .dhead{padding:20px 20px 0}
    .dtabs{margin:0 -20px;padding:0 8px}
    .dbody{padding:20px 20px 64px}
    /* The section list turns into a row that scrolls sideways, held under the bar. */
    .sbody{grid-template-columns:minmax(0,1fr);gap:20px;padding:0 20px 120px}
    .set-nav{top:56px;z-index:5;display:block;margin:0 -20px;background:var(--bg);border-bottom:1px solid var(--line)}
    /* the row itself scrolls, and fades at the edge while more lies past it
       (FC-06: "Archive or de…" was cut hard); the nav keeps the bar's ground */
    .set-nav-in{position:relative;display:flex;flex-direction:row;gap:4px;overflow-x:auto;scrollbar-width:none;padding:10px 20px}
    .set-nav-in::-webkit-scrollbar{display:none}
    .set-nav-in.more{-webkit-mask-image:linear-gradient(90deg,var(--bg) calc(100% - 44px),transparent);
      mask-image:linear-gradient(90deg,var(--bg) calc(100% - 44px),transparent)}
    .set-sec{scroll-margin-top:124px}
    .savebar{left:0;padding:10px 20px}
  }
  @media (max-width:640px){
    .dhead .detail-title{font-size:22px}
    .dtitle-row{grid-template-columns:40px minmax(0,1fr)}
    .dhead-actions{grid-column:1/-1;justify-content:flex-start}
    .set-2{grid-template-columns:minmax(0,1fr)}
    .sp-g-time,.sp-g-dow,.sp-g-day,.sp-g-hmin{flex:1 1 140px}
    .est{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);row-gap:12px}
    .est-stat:nth-child(3){grid-column:1/-1;padding:12px 0 0;border-left:0;border-top:1px solid var(--line)}
    .set-row{flex-wrap:wrap;row-gap:10px}
    .savebar{flex-wrap:wrap;row-gap:8px}
    .savebar-txt{flex:1 1 calc(100% - 20px)}
    .savebar-fill{display:none}
    .savebar .dbtn{flex:1 1 0;justify-content:center}
    .seg{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));width:100%}
    .seg-i span{justify-content:center;width:100%;padding:0 8px}
    .tok-x{width:24px;height:24px}
  }

  /* ---- spend ---- */
  .sp-card-head{padding:16px 20px 4px;display:flex;justify-content:space-between;align-items:baseline;gap:10px;flex-wrap:wrap}
  .sp-card-title{margin:0;font-size:15px;font-weight:700}
  .sp-hint{font-size:12px;color:var(--faint);white-space:nowrap}
  .sp-hint[hidden]{display:none}
  .sp-scroll{overflow-x:auto}
  /* UX2-05: the schedules table needs ~1,050px; its card may run past the
     page's 1,000px reading width, so it fits beside the sidebar from ~1,430px. */
  .main.pg>.sp-wide{max-width:1120px}
  .sp-table{width:100%;border-collapse:collapse}
  /* The report (or start time) stays put while the numbers scroll under it. */
  .sp-table .sp-stick{position:sticky;left:0;z-index:1;background:var(--card)}
  .sp-scroll.is-scrolled .sp-stick{box-shadow:1px 0 0 var(--line2)}
  /* pan-y: a finger dragging sideways along the chart reads the days
     (spendBarAt) while an up-down swipe still scrolls the page. */
  .sp-bars{display:flex;gap:2px;align-items:flex-end;touch-action:pan-y pinch-zoom;border-radius:4px}
  .sp-bars:focus-visible{outline:2px solid var(--chart-bar);outline-offset:4px}
  .sp-bar{flex:1;display:flex;flex-direction:column;justify-content:flex-end;height:88px;cursor:pointer}
  .sp-bar.mstart{border-left:1px solid var(--line2)}
  .sp-bar-fill{border-radius:2px 2px 0 0;background:var(--chart-bar);opacity:.75}
  .sp-bar-fill.zero{background:var(--chart-zero);opacity:1}
  .sp-bar.sel .sp-bar-fill{opacity:1;background:var(--chart-bar-sel)}
  .sp-bar.sel .sp-bar-fill.zero{background:var(--faint)}
  .sp-axis{display:flex;gap:2px;margin-top:2px;overflow:hidden}
  .sp-tick{flex:1;position:relative;height:18px}
  .sp-tick-mark{position:absolute;left:50%;top:0;width:1px;height:4px;background:var(--line2)}
  .sp-tick-lbl{position:absolute;left:50%;top:5px;transform:translateX(-50%);font-size:10.5px;color:var(--faint);white-space:nowrap}
  /* The newest date always shows, so it hangs left of its bar instead of
     being cut in half by the card edge. */
  .sp-tick-lbl.end{left:auto;right:0;transform:none}
  .sp-read{font-size:12px;color:var(--muted);margin-top:8px;min-height:18px;font-variant-numeric:tabular-nums}
  .sp-kpis{display:flex;gap:12px;margin:18px 0 22px;flex-wrap:wrap}
  /* Old spend data: the windows end on the day it was read, not today. */
  .sp-stale{margin:14px 0 0;padding:11px 16px;border-radius:10px;background:var(--warn-bg);border:1px solid var(--warn-line);
    color:var(--warn-fg);font-size:13px;font-weight:500;line-height:1.5}
  .sp-stat{flex:1 1 140px;min-width:140px;border:1px solid var(--line);border-radius:10px;padding:14px 16px;background:var(--card)}
  .sp-card{border:1px solid var(--line);border-radius:12px;background:var(--card);overflow:hidden;margin-bottom:16px}
  .sp-foot{padding:12px 20px 16px;font-size:12.5px;color:var(--muted);line-height:1.6}
  .sp-sub{font-size:11.5px;color:var(--faint);margin-top:2px;font-weight:400;white-space:normal}
  /* A schedule in Spend's table: its words on one line, the cron under them
     (FC-06: three lines a row before). */
  .sp-sched{white-space:nowrap}
  .sp-sub.sp-cron{white-space:nowrap}
  /* A report name that opens the report: reads as text, underlines as a link.
     A real link since rc.14, laid out as the button it was (inline-block). */
  .sp-link{appearance:none;border:none;background:none;padding:0;font:inherit;color:inherit;cursor:pointer;text-align:left;
    text-decoration:underline;text-decoration-color:var(--line2);text-underline-offset:3px}
  a.sp-link{display:inline-block}
  .sp-link:hover,.sp-link:focus-visible{color:var(--accent-text);text-decoration-color:currentColor}
  .sp-arch{display:inline-block;font-size:10.5px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--muted);
    background:var(--fill-chip);border-radius:9999px;padding:1px 7px;margin-left:4px;vertical-align:1px}
  .sp-badge{display:inline-block;font-size:10.5px;font-weight:600;border-radius:9999px;padding:1px 7px;white-space:nowrap}
  .sp-badge.warn{color:var(--warn-fg);background:var(--warn-bg);border:1px solid var(--warn-line-soft)}
  /* Largest query against its cap: a small bar, warn from 80 %, err after a
     cost-gate refusal in the last 30 days. */
  .sp-cap{display:inline-flex;align-items:center;gap:8px}
  .sp-cap-track{display:inline-block;width:52px;height:7px;border-radius:4px;background:var(--fill);overflow:hidden;flex:none}
  .sp-cap-fill{display:block;height:100%;border-radius:4px;background:var(--teal)}
  .sp-cap.warn .sp-cap-fill{background:var(--warn)}
  .sp-cap.err .sp-cap-fill{background:var(--err)}
  .sp-cap-txt{font-size:12.5px;color:var(--ink2)}
  .sp-cap.warn .sp-cap-txt{color:var(--warn-fg);font-weight:600}
  .sp-cap.err .sp-cap-txt{color:var(--err-fg);font-weight:600}
  /* Spend by report: each report opens to its queries and triggers. */
  .sp-fold>summary{cursor:pointer}
  .sp-fold-body{white-space:normal;min-width:220px;max-width:360px;margin-top:6px;font-size:12px;font-weight:400;color:var(--muted);line-height:1.55}
  /* Report detail: cost per version, oldest left (the Spend strip, small). */
  .cost-spark{display:flex;gap:2px;align-items:flex-end;height:30px;margin-top:8px;max-width:220px}
  .cost-spark-bar{flex:1;min-width:3px;border-radius:2px 2px 0 0;background:var(--chart-bar);opacity:.75}
  .cost-spark-bar.zero{background:var(--chart-zero);opacity:1}
  .cost-spark-bar.latest{opacity:1}
  .desc-clamp{display:-webkit-box;-webkit-line-clamp:4;-webkit-box-orient:vertical;overflow:hidden}   /* UX-31: a long description folds to four lines */
  .cap-line{font-size:12px;color:var(--faint);margin-top:6px;line-height:1.5;overflow-wrap:anywhere}   /* F6: a long query name breaks */
  .cap-line.warn{color:var(--warn-fg)}
  @media (max-width:480px){
    .sp-tick.minor .sp-tick-lbl,.sp-tick.minor .sp-tick-mark{display:none}
    .sp-tick-lbl.start{left:0;transform:none}
  }
  @media (max-width:640px){
    .sp-table .sp-stick{white-space:normal!important;min-width:112px}
    /* Phone tap targets at least 32px: the small icon buttons, the back link,
       and the chips and text buttons marked .tap (tag filters, category and
       tag buttons, Add description, the Guide's section chips, tag colours).
       min-* wins over their inline sizes, so the desktop look is unchanged. */
    .iconbtn,.tap{min-width:32px;min-height:32px}
    .pg-back{min-height:32px}
  }

  /* Upload pages: the publish button keeps its label on one line; the note
     beside it drops underneath when there's no room. */
  .submit-row{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
  .submit-row>button{flex:none;white-space:nowrap}

  /* ---- the refresh drawer (openDrawer; rc.11 fix round 2) ----
     The redesign's tokens, type and radii: the pages' eyebrow and an H2, a
     stepper, the log as a sunken card (10px, like the schedule's strip) whose
     lines keep their ok / error colours through the --term-* names re-pointed
     at the theme's own, and the outcome as the report page's banner (12px) and
     buttons (.dbtn). Its box is a <div role="dialog">, never an <aside>. */
  .rd-scrim{animation:dcscrim 200ms ease-out}
  .rd{position:fixed;top:0;right:0;bottom:0;z-index:61;width:480px;max-width:94vw;display:flex;flex-direction:column;
    background:var(--bg-raised);border-left:1px solid var(--line);box-shadow:-24px 0 60px var(--shadow-drawer);animation:dcslide 320ms var(--ease)}
  .rd-head{display:flex;align-items:flex-start;gap:14px;padding:22px 20px 16px 24px;border-bottom:1px solid var(--line)}
  .rd-hd{flex:1;min-width:0}
  .rd-title{margin:6px 0 0;font-size:17px;font-weight:700;letter-spacing:-.01em;line-height:1.3;overflow-wrap:anywhere}
  .rd-x{appearance:none;cursor:pointer;flex:none;width:32px;height:32px;margin-top:-4px;padding:0;border:none;border-radius:8px;background:none;color:var(--muted);
    display:inline-flex;align-items:center;justify-content:center;transition:background 120ms,color 120ms}
  .rd-x:hover{background:var(--fill);color:var(--ink)}
  .rd-x:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
  /* the steps: Check — Query BigQuery — Publish */
  .rd-steps{display:flex;align-items:center;gap:8px;margin:0;padding:14px 24px;list-style:none;border-bottom:1px solid var(--line)}
  .rd-step{display:flex;align-items:center;gap:8px;flex:none;min-width:0;font-size:13px;font-weight:500;color:var(--faint);white-space:nowrap}
  .rd-step+.rd-step{flex:1 1 auto;min-width:min-content}
  .rd-step+.rd-step::before{content:"";flex:1 1 12px;min-width:12px;height:1px;background:var(--line2)}
  /* A label too long for its step wraps between words, never cut (A11Y2-12:
     "Query BigQ…" with text spacing at 375px); a step is never narrower than
     its longest word. Where the steps fit, nothing changes. */
  .rd-lb{min-width:0;white-space:normal}
  .rd-mk{flex:none;width:20px;height:20px;border-radius:9999px;display:inline-flex;align-items:center;justify-content:center;
    font-size:11px;font-weight:700;font-variant-numeric:tabular-nums;color:var(--faint);background:var(--bg-raised);border:1px solid var(--line2)}
  .rd-mk svg{width:11px;height:11px}
  .rd-step[data-st="done"]{color:var(--ink2)}
  .rd-step[data-st="done"] .rd-mk{background:var(--ok);border-color:var(--ok);color:var(--ok-ink)}
  .rd-step[data-st="active"]{color:var(--ink)}
  .rd-step[data-st="active"] .rd-mk{border-color:var(--accent);color:var(--accent-text);box-shadow:0 0 0 3px var(--accent-tint)}
  .rd-step[data-st="error"]{color:var(--err-fg)}
  .rd-step[data-st="error"] .rd-mk{background:var(--err);border-color:var(--err);color:var(--err-ink)}
  .rd-run{display:flex;align-items:center;gap:9px;padding:10px 24px;border-bottom:1px solid var(--line);font-size:13px;color:var(--muted)}
  /* the log: a sunken card; its lines' colours are the theme's (logAppend
     paints them with the --term-* names, re-pointed here) */
  .rd-log{--term-text:var(--ink2);--term-dim:var(--faint);--term-ok:var(--ok-fg);--term-err:var(--err-fg);--term-strong:var(--ink);--term-thumb:var(--line2);
    flex:1;min-height:0;overflow:auto;margin:16px 24px;padding:12px 14px;border:1px solid var(--line);border-radius:10px;
    background:var(--bg-sunken);font-family:var(--mono);font-size:12px;line-height:1.75}
  .rd-log:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
  .rd-log.folded{flex:none;margin:8px 0 0;max-height:45vh;background:var(--card)}
  /* the outcome */
  .rd-foot{flex:none}
  .rd-foot.rd-scroll{flex:1;min-height:0;overflow:auto}
  .rd-out{display:flex;align-items:center;gap:12px;padding:16px 24px;border-top:1px solid var(--line)}
  .rd-out-txt{flex:1;min-width:0}
  .rd-out-h{font-size:14px;font-weight:500;color:var(--ink)}
  .rd-out-s{font-size:12.5px;color:var(--muted);margin-top:2px}
  .rd-note-out{padding:18px 24px;border-top:1px solid var(--line)}
  .rd-out-p{font-size:13.5px;color:var(--ink2);margin-top:6px;line-height:1.55}
  .rd-out-acts{display:flex;justify-content:flex-end;margin-top:14px}
  .rd-badge{flex:none;width:28px;height:28px;border-radius:9999px;display:inline-flex;align-items:center;justify-content:center}
  .rd-badge.ok{background:var(--ok-bg);color:var(--ok-fg)}
  .rd-badge.err{width:24px;height:24px;margin-top:1px;background:var(--err);color:var(--err-ink)}
  .rd-badge.sm{width:18px;height:18px}
  .rd-badge.sm svg{width:11px;height:11px}
  .rd-fail{display:flex;align-items:flex-start;gap:12px;margin:16px 24px 20px;padding:16px 18px;border-radius:12px;background:var(--err-bg);border:1px solid var(--err-line)}
  .rd-fail-body{flex:1;min-width:0}
  .rd-fail-h{font-size:14px;font-weight:500;color:var(--err-strong)}
  .rd-fail-p{font-size:13.5px;color:var(--err-strong);margin-top:4px;line-height:1.5}
  .rd-live{display:flex;align-items:center;gap:9px;margin-top:13px;padding:10px 12px;border-radius:9px;background:var(--card);border:1px solid var(--line);
    font-size:12.5px;color:var(--ink2)}
  .rd-tech{margin-top:12px}
  .rd-tech>summary{cursor:pointer;font-size:12.5px;color:var(--err-strong)}
  .rd-tech>summary:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:3px}
  /* "Copy for Claude Code" sits under the sentence rather than squeezing it
     into a narrow column beside the button. */
  .drawer-fail-head{display:flex;flex-direction:column;align-items:flex-start;gap:12px}
  .drawer-fail-text{min-width:0}
  @media (max-width:560px){
    .rd-head{padding:18px 14px 14px 18px}
    .rd-steps{padding:12px 18px;gap:6px}
    .rd-step{gap:6px;font-size:12.5px}
    .rd-run{padding:10px 18px}
    .rd-log{margin:14px 18px}
    .rd-out,.rd-note-out{padding:14px 18px}
    .rd-fail{margin:14px 18px 18px;padding:14px 16px}
  }
  /* ≤ 350px a label wraps rather than being cut (UX2-08: "Read Bloo…", "Pu…" at 320). */
  @media (max-width:350px){
    .rd-steps{gap:4px;padding:12px 14px}
    .rd-step{white-space:normal;line-height:1.2}
    .rd-step+.rd-step{flex:1 1 0;min-width:min-content}
    .rd-lb{overflow:visible}
    .rd-step+.rd-step::before{flex-basis:6px;min-width:6px}
  }

  @media (max-width:780px){
    .main{padding-left:20px;padding-right:20px}
  }
  /* Component base classes. These carry the shared look; per-instance values that
     genuinely differ (height, padding, box-shadow, width, flex) stay inline and
     override. Class names match what the markup already references, so the :hover
     rules below (which predate these) keep working. */
  .primary{appearance:none;cursor:pointer;font-family:inherit;font-size:14px;font-weight:500;color:var(--accent-ink);background:var(--accent);border:1px solid var(--accent);border-radius:8px;display:inline-flex;align-items:center;gap:7px;transition:background 140ms}
  .ghost{appearance:none;cursor:pointer;font-family:inherit;font-size:14px;font-weight:500;color:var(--ink);background:var(--control-bg);border:1px solid var(--line2);border-radius:8px;display:inline-flex;align-items:center;gap:8px;transition:border-color 140ms}
  .iconbtn{appearance:none;cursor:pointer;font-family:inherit;border:1px solid var(--line3);background:var(--control-bg);color:var(--ink2);border-radius:8px;display:inline-flex;align-items:center;justify-content:center;transition:all 140ms}
  .iconbtn.del{color:var(--faint)}
  .field{height:38px;border:1px solid var(--field-edge);border-radius:9px;padding:0 12px;font-family:inherit;font-size:14px;outline:none}
  .field:focus{border-color:var(--accent);box-shadow:inset 0 0 0 1px var(--accent),0 0 0 3px var(--focus-ring)}   /* 2px edge, not only a hue (A11Y2-09) */
  /* Controls that draw their own edge inline and drop the browser's focus ring
     (outline:none): the same focus look as .field, which their inline border
     would otherwise win over, and an outline round a drop zone. Without these
     a keyboard user could not see where focus was (WCAG 2.4.7). */
  .field-focus:focus-visible{border-color:var(--accent)!important;box-shadow:inset 0 0 0 1px var(--accent),0 0 0 3px var(--focus-ring)}
  .drop-focus:focus-visible{outline:2px solid var(--accent)!important;outline-offset:2px}
  .iconbtn:hover{border-color:var(--faint)!important;color:var(--ink)!important}
  .iconbtn.rf:hover{border-color:var(--accent)!important;color:var(--accent)!important}
  .iconbtn.del:hover{border-color:var(--err)!important;color:var(--err)!important}
  .primary:hover{background:var(--accent-hover)!important}
  .ghost:hover{border-color:var(--ink)!important}

  /* ---- user-coloured chips (RC7-008) ----
     The colour is data (a tag's #rrggbb, or a refresh-trigger hue), set per
     element as --tag. Light paints it as chosen: text in the colour on a faint
     tint of it, unless that colour fails AA there; then ui.js tagVars() hands a
     darker shade of it as --tag-text / --tag-fill (RC7-022; --tag-aa-pct picks
     them). Dark lightens the text toward --ink and deepens the tint, so a navy
     or black tag stays readable on a dark page (tokens above). */
  .tint{color:color-mix(in srgb,color-mix(in srgb,var(--tag-text,var(--tag)) var(--tag-aa-pct),var(--tag)) var(--tint-ink-pct),var(--ink));
    background:color-mix(in srgb,var(--tag) var(--tint-a),transparent);
    border:1px solid color-mix(in srgb,var(--tag) var(--tint-edge-pct),transparent)}
  .tagchip{--tint-a:var(--tagchip-a);display:inline-flex;align-items:center;gap:5px;height:22px;padding:0 9px;border-radius:9999px;font-size:11.5px;font-weight:500;white-space:nowrap}
  .tagchip-dot{width:6px;height:6px;border-radius:50%;background:color-mix(in srgb,var(--tag) var(--tag-dot-pct),var(--ink))}
  .tagchip-x{cursor:pointer;opacity:.7;font-size:13px;line-height:1;margin-left:1px}
  .tbadge{--tint-a:var(--tbadge-a);display:inline-flex;align-items:center;height:18px;padding:0 7px;border-radius:9999px;font-size:10.5px;font-weight:600;letter-spacing:.02em;white-space:nowrap}

  /* ---- admin Settings (FR-SETTINGS release A) ----
     /?view=settings: the report Settings' grammar (.sbody's section list,
     .set-sec / .set-fields / .set-lbl / .set-input, .seg, the save bar) on an
     admin page's frame (.main.pg + pageHead), so it reads as the same form.
     Each field closes with where its value comes from (.ws-src). */
  .ws-sbody{padding:8px 0 100px}
  .ws-src{margin-top:8px;font-size:12.5px;color:var(--muted);line-height:1.5}
  .ws-src>svg{vertical-align:-2px;margin-right:6px}
  .ws-src.locked{color:var(--ink2)}
  .ws-src.bad{color:var(--err-fg)}
  .ws-sep{color:var(--faint);margin:0 7px}
  .ws-reset{font-size:12.5px;font-weight:500}
  .ws-banner{display:flex;align-items:flex-start;gap:8px;margin:0 0 14px;padding:10px 14px;border:1px solid var(--notice-line);background:var(--notice-bg);border-radius:10px;font-size:13.5px;color:var(--notice-fg);line-height:1.5}
  .ws-banner.bad{border-color:var(--err-line);background:var(--err-bg);color:var(--err-fg)}
  .ws-banner>svg{flex:none;margin-top:2px}
  .ws-fs{border:none;margin:0;padding:0;min-width:0}
  .ws-fs:disabled .seg{opacity:.6}
  /* Two choices: always one row that fits (the report form's ≤ 640 / 901–1040
     three-column grid is for its six frequencies). */
  .ws-fs .seg{display:inline-flex;width:auto;max-width:100%;margin-bottom:10px}
  .ws-fs .seg-i span{width:auto;padding:0 14px}
  .ws-num{max-width:120px}
  .ws-ids{min-height:96px}
  .ws-conn{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr) minmax(0,.8fr);gap:16px;padding:14px 16px;border:1px solid var(--line);border-radius:10px;background:var(--bg-sunken)}
  .ws-ro{min-width:0}
  .ws-ro .set-lbl{margin-bottom:4px}
  .ws-ro-v{font-size:13.5px;color:var(--ink);overflow-wrap:anywhere}
  .ws-ro-v.mono{font-family:var(--mono);font-size:12.5px}
  .ws-ro .ws-src{margin-top:6px}
  .ws-warn{display:flex;align-items:flex-start;gap:8px;margin-top:10px;border-color:var(--warn-line);background:var(--warn-bg);color:var(--warn-fg)}
  .ws-warn>svg{flex:none;margin-top:3px}
  .ws-warn[hidden]{display:none}
  .ws-log{list-style:none;margin:16px 0 0;padding:0;border-top:1px solid var(--line)}
  .ws-log-i{display:grid;grid-template-columns:150px minmax(0,1fr) auto;gap:12px;align-items:baseline;padding:10px 2px;border-bottom:1px solid var(--line-row);font-size:13px;line-height:1.5}
  .ws-log-when{color:var(--muted);white-space:nowrap}
  .ws-log-what{color:var(--ink2);overflow-wrap:anywhere}
  .ws-log-what b{font-weight:600;color:var(--ink)}
  .ws-log-rev{color:var(--faint);font-size:12px}
  @media (max-width:900px){
    .ws-sbody{padding:0 0 120px}
    .ws-pg .set-nav{margin:0 -36px}
    .ws-pg .set-nav-in{padding:10px 36px}
    .ws-conn{grid-template-columns:minmax(0,1fr)}
  }
  @media (max-width:780px){
    .ws-pg .set-nav{margin:0 -20px}
    .ws-pg .set-nav-in{padding:10px 20px}
  }
  @media (max-width:640px){
    .ws-log-i{grid-template-columns:minmax(0,1fr) auto;row-gap:2px}
    .ws-log-when{grid-column:1/-1}
  }
  /* fix round (M-1 / SA-1): the extra_env lines a rollback older than rc.16 needs */
  .ws-rollback{padding:12px 14px;border:1px solid var(--warn-line);background:var(--warn-bg);border-radius:10px;color:var(--warn-fg);font-size:13px;line-height:1.5}
  .ws-rollback-h{display:flex;align-items:center;gap:8px;font-weight:600}
  .ws-rollback-h>svg{flex:none}
  .ws-rollback-p{margin:6px 0 10px}
  .ws-rollback code{font-family:var(--mono);font-size:12px}
  .ws-copy-row{display:flex;align-items:flex-start;gap:10px}
  .ws-copy{flex:1;min-width:0;margin:0;padding:8px 10px;border-radius:8px;border:1px solid var(--line);background:var(--card);color:var(--ink);font-family:var(--mono);font-size:12px;line-height:1.5;white-space:pre-wrap;overflow-wrap:anywhere;user-select:all}
  .ws-copy:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
  .ws-copy-btn{flex:none;height:34px}
  @media (max-width:640px){ .ws-copy-row{flex-direction:column} }
