
    *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

    :root {
      /* Stitch "Ethereal Editor" palette */

      /* Surfaces — cool canvas, layered paper */
      --bg:           #F7F9FB;
      --bg-base:      #F7F9FB;
      --bg-surface:   #F2F4F6;
      --bg-elevated:  #FFFFFF;
      --bg-subtle:    #ECEEF0;
      --bg-inverse:   #191C1E;
      --surface:      #F2F4F6;
      --nav-bg:       #F2F4F6;

      /* Brand — Digital Ink blue */
      --brand-primary:  #0051D5;
      --brand-container: #316BF3;
      --brand-hover:    #1B63E0;
      --brand-accent:   #003EA8;
      --brand-dim:      #DBE1FF;
      --brand-text:     #0051D5;
      --brand-border:   rgba(0, 81, 213, 0.25);
      --brand-glow:     rgba(0, 81, 213, 0.15);
      --indigo:       #0051D5;
      --indigo-light: rgba(0,81,213,.1);
      --indigo-dark:  #003EA8;
      --blue:         #0051D5;
      --blue-hover:   #003EA8;

      /* Gradients + glass — kept as aliases but flattened; real fills are solid */
      --gradient-primary: var(--ink);
      --gradient-page: #FFFFFF;
      --glass-bg: rgba(255, 255, 255, 0.95);
      --glass-border: var(--border);
      --glass-blur: blur(0);

      /* Ink — used as primary button / active underline (pro, not brand-y) */
      --ink: #09090B;
      --ink-hover: #27272A;

      /* Text — premium near-black, never pure */
      --text:         #191C1E;
      --text2:        #505F76;
      --text3:        #717783;
      --text4:        #717783;
      --text-primary:   #191C1E;
      --text-secondary: #505F76;
      --text-muted:     #717783;
      --text-on-dark:   #EFF1F3;
      --text-on-brand:  #FFFFFF;

      /* Ghost borders (outline-variant at low opacity) */
      --border:       rgba(193, 199, 211, 0.60);
      --border2:      rgba(193, 199, 211, 0.90);
      --border-subtle:  rgba(193, 199, 211, 0.30);
      --border-default: rgba(193, 199, 211, 0.60);
      --border-strong:  rgba(193, 199, 211, 0.90);

      /* Semantic */
      --green:        #1A7F5A;
      --green-bg:     #EDFAF4;
      --green-border: rgba(26, 127, 90, 0.20);
      --amber:        #A05E00;
      --amber-bg:     #FDF5E6;
      --red:          #C0392B;
      --red-bg:       #FDEEEC;
      --red-border:   rgba(192, 57, 43, 0.20);
      /* Teal was the only one of its hue in the palette and had a single
         consumer. Aliased to the brand blue rather than deleted, because the
         names are public surface and something may reach for them later. */
      --info:         var(--brand-primary);
      --info-bg:      var(--brand-dim);
      --info-border:  var(--brand-border);
      --success:      #1A7F5A;
      --success-bg:   #EDFAF4;
      --success-border: rgba(26, 127, 90, 0.20);
      --warning:      #A05E00;
      --warning-bg:   #FDF5E6;
      --warning-border: rgba(160, 94, 0, 0.20);
      --error:        #C0392B;
      --error-bg:     #FDEEEC;
      --error-border: rgba(192, 57, 43, 0.20);

      /* Column colors */
      --col-draft:    #0051D5;
      --col-todo:     #1A7F5A;
      --col-review:   #A05E00;
      --col-writing:  var(--brand-primary);
      --col-done:     #1A7F5A;

      /* Flat, quiet shadows — enterprise tools do not glow */
      --shadow-xs:      0 1px 2px  rgba(15, 23, 42, 0.04);
      --shadow-sm:      0 1px 2px  rgba(15, 23, 42, 0.06);
      --shadow-md:      0 4px 12px rgba(15, 23, 42, 0.06);
      --shadow-lg:      0 8px 24px rgba(15, 23, 42, 0.08);
      --shadow-brand:   0 1px 2px  rgba(15, 23, 42, 0.08);

      /* ── Typography — ONE typeface: DM Sans ────────────────────────────────
         The dashboard and the article editor run entirely on DM Sans. It was
         already the app's UI face; what changed is that Fraunces (display),
         JetBrains Mono (--font-code) and eight stray `arial` fallbacks are gone,
         so there is now exactly one family on the screen instead of four.

         --font-ui is the canonical definition and the other three are aliases,
         which is what let ~370 call sites keep resolving without being edited.
         Point them somewhere else and the whole dashboard follows.

         DM Sans ships 300/400/500/600/700 (static/css/fonts.css), so weight is
         a real hierarchy tool here — unlike a two-weight face, where it is not.
         Prefer the .t-* roles below over inventing a size/weight pair.

         Numeric columns get font-variant-numeric: tabular-nums rather than a
         monospace face, so scores and counts still align in a column. */
      --font-ui:      'DM Sans', system-ui, sans-serif;
      --font-display: var(--font-ui);
      --font-body:    var(--font-ui);
      --font-code:    var(--font-ui);
      /* Referenced at :2899 and by anything expecting a mono alias. Kept
         pointing at the one family — this app has no second face. */
      --font-mono:    var(--font-ui);

      /* Type scale */
      --text-xs:   0.625rem;    /* 10 — eyebrow */
      --text-sm:   0.75rem;     /* 12 — secondary */
      --text-base: 0.8575rem;   /* 13.7 — UI default */
      --text-lg:   0.9375rem;   /* 15 — row primary */
      --text-xl:   1.125rem;    /* 18 — view title */
      --text-2xl:  1.35rem;     /* 21.6 — metric */
      --text-3xl:  1.75rem;

      /* Spacing */
      --space-1: 0.25rem;
      --space-2: 0.5rem;
      --space-3: 0.75rem;
      --space-4: 1rem;
      --space-5: 1.25rem;
      --space-6: 1.5rem;
      --space-8: 2rem;

      /* Radius — the four steps that cover ~490 of the app's ~554
         border-radius declarations (6px ×135, 8px ×127, 10px ×91, 4px ×57,
         999px ×31). Derived from what the code already does. */
      --radius-xs:   4px;
      --radius-sm:   6px;
      --radius-md:   10px;
      --radius-pill: 999px;

      /* Layout — the shell's fixed widths, named so a component that has to
         dodge the drawer (see .al-floatbar) does not hardcode them again.
         These are declarations only: the sidebar's own !important width blocks
         are load-bearing and are deliberately left alone. */
      --nav-w:         220px;
      --nav-w-icon:    48px;
      --drawer-w:      380px;
      --drawer-w-wide: 600px;
      --band-inset:    20px;

      /* Easing */
      --ease-sharp: cubic-bezier(0.4, 0, 0.2, 1);
    }

    html, body { height: 100%; }
    body {
      font-family: var(--font-body);
      background: var(--gradient-page); color: var(--text);
      display: flex; -webkit-font-smoothing: antialiased;
      font-size: 13px; line-height: 1.5; letter-spacing: -0.002em;
    }

    /* ── Type roles ────────────────────────────────────────────────────────
       One typeface across the whole dashboard, so these six roles are the
       sanctioned way to express hierarchy. Reach for a role rather than
       inventing another font-size + font-weight pair — that habit is how the
       file ended up with four faces and ~700 font declarations in 25 spellings.
       DM Sans has real 300-700, so weight does real work here. */
    .t-title   { font-size: 18px;   font-weight: 600; color: var(--text);  letter-spacing: -0.02em; }
    .t-eyebrow { font-size: 10px;   font-weight: 600; color: var(--text3); letter-spacing:  0.06em; text-transform: uppercase; }
    .t-primary { font-size: 13px;   font-weight: 600; color: var(--text);  letter-spacing: -0.01em; }
    .t-ui      { font-size: 13px;   font-weight: 400; color: var(--text);  letter-spacing: -0.002em; }
    .t-second  { font-size: 11.5px; font-weight: 400; color: var(--text3); letter-spacing: 0; }
    .t-metric  { font-size: 21px;   font-weight: 700; color: var(--text);  letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
    body::before { display: none; }

    /* ══ NAV (Variant 2 — 220px, workspace switcher, grouped) ══ */
    .nav {
      width: 220px; flex-shrink: 0;
      background: var(--canvas, #FAFAFA);
      border-right: 1px solid var(--border-subtle);
      display: flex; flex-direction: column;
      position: fixed; top: 0; left: 0; bottom: 0; z-index: 200;
      transition: width 0.25s var(--ease-sharp);
      overflow-y: auto;
      padding: 10px 8px 0;
    }
    .nav.collapsed { width: 64px; }

    /* Workspace switcher */
    .workspace-switcher {
      display: flex; align-items: center; gap: 9px;
      padding: 8px 9px;
      border-radius: 7px;
      cursor: pointer;
      margin-bottom: 12px;
      border: 1px solid transparent;
      transition: background 0.15s, border-color 0.15s;
    }
    .workspace-switcher:hover { background: var(--bg-surface); border-color: var(--border-subtle); }
    .ws-logo {
      width: 28px; height: 28px; border-radius: 7px;
      object-fit: contain;
      flex-shrink: 0;
      display: block;
    }
    .ws-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
    .ws-name {
      font-family: var(--font-ui); font-size: 13px; font-weight: 600;
      color: var(--text-primary);
      white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
      line-height: 1.2;
    }
    .ws-sub {
      font-family: var(--font-ui); font-size: 10.5px; font-weight: 500;
      color: var(--text-muted);
      white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
      line-height: 1.2;
    }
    .ws-chev { color: var(--text-muted); flex-shrink: 0; }

    /* Command-palette-style search */
    .quick-search {
      display: flex; align-items: center; gap: 8px;
      padding: 5px 9px;
      background: var(--bg-elevated);
      border: 1px solid var(--border-subtle);
      border-radius: 6px;
      color: var(--text-muted);
      font-family: var(--font-ui); font-size: 12px;
      cursor: pointer;
      margin-bottom: 14px;
      width: 100%; text-align: left;
    }
    .quick-search:hover { border-color: var(--border-strong); }
    .quick-search svg { color: var(--text-muted); flex-shrink: 0; }
    .quick-search > span:nth-of-type(1) { flex: 1; }
    .kbd {
      display: inline-flex; align-items: center;
      padding: 1px 5px; font-size: 10.5px;
      font-family: var(--font-code);
      background: var(--bg-surface); color: var(--text-muted);
      border-radius: 3px;
      border: 1px solid var(--border-subtle);
    }
    .nav-brand {
      display: flex; align-items: center; gap: 0.7rem;
      padding: 1.25rem 1.25rem 1.1rem; border-bottom: 1px solid var(--border-subtle);
      overflow: hidden; white-space: nowrap; position: relative;
    }
    .nav.collapsed .nav-brand { padding: 1.25rem 0 1.1rem; justify-content: center; }
    .brand-icon {
      width: 38px; height: 38px; border-radius: 10px;
      display: block; flex-shrink: 0;
      object-fit: contain;
      box-shadow: var(--shadow-sm);
    }
    .nav-brand-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; transition: opacity .2s; }
    .nav.collapsed .nav-brand-text { opacity: 0; width: 0; overflow: hidden; }
    .brand-name { font-family: var(--font-display); font-size: 1.05rem; font-weight: 600; color: var(--text-primary); letter-spacing: -0.015em; line-height: 1.1; }
    .brand-tagline {
      font-family: var(--font-ui); font-size: 0.56rem; font-weight: 700;
      color: var(--text-muted); letter-spacing: 0.14em; text-transform: uppercase;
      line-height: 1.1;
    }
    .brand-tag {
      font-family: var(--font-ui); font-size: 0.58rem; font-weight: 600;
      background: var(--brand-dim); color: var(--brand-text);
      border-radius: 3px; padding: 2px 5px; border: 1px solid var(--brand-border);
      text-transform: uppercase; letter-spacing: 0.04em; transition: opacity .2s;
    }
    .nav.collapsed .brand-name,
    .nav.collapsed .brand-tag { opacity: 0; width: 0; overflow: hidden; }
    .nav-section-label {
      font-family: var(--font-ui); font-size: 10.5px; font-weight: 600;
      text-transform: uppercase; letter-spacing: 0.05em;
      color: var(--text-muted); padding: 0 8px;
      margin: 12px 0 6px;
      transition: opacity .2s;
    }
    .nav.collapsed .nav-section-label { opacity: 0; height: 0; padding: 0; margin: 0; overflow: hidden; }
    .nav-section-label.sep {
      border-top: 1px solid var(--border);
      margin-top: 0.25rem;
    }
    .nav.collapsed .nav-section-label.sep { border-top: none; }
    .nav-separator { border-top: 1px solid var(--border); margin: 0.35rem 0.75rem; }
    .nav.collapsed .nav-separator { margin: 0.35rem 0.25rem; }
    .nav-items { padding: 0; flex: 1; display: flex; flex-direction: column; }
    .nav.collapsed .nav-items { padding: 0.5rem 0.25rem; }
    .nav-item {
      display: flex; align-items: center; gap: 9px;
      width: 100%; padding: 5px 8px;
      border: 1px solid transparent; background: none; cursor: pointer;
      border-radius: 6px; color: var(--text-secondary);
      font-family: var(--font-ui); font-size: 13px; font-weight: 500;
      text-align: left;
      transition: background 0.15s, color 0.15s; margin-bottom: 1px;
      overflow: hidden; white-space: nowrap;
    }
    .nav.collapsed .nav-item { justify-content: center; padding: 0.65rem 0; }
    .nav-item-label { transition: opacity .2s; flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    .nav.collapsed .nav-item-label { opacity: 0; width: 0; overflow: hidden; }
    .nav-item:hover { background: var(--bg-surface); color: var(--text-primary); }
    .nav-item.active {
      background: var(--brand-dim); color: var(--text-primary); font-weight: 600;
      border: 1px solid transparent; box-shadow: none; border-radius: 8px;
    }
    .nav-item svg { flex-shrink: 0; opacity: 0.75; width: 14px; height: 14px; color: var(--text-muted); }
    .nav-item.active svg { opacity: 1; color: var(--text-primary); }

    /* Small count badge on the right of a nav item (e.g. Planner 32) */
    .nav-badge {
      margin-left: auto;
      font-family: var(--font-code); font-size: 10.5px; font-weight: 600;
      color: var(--text-muted); padding-left: 4px;
    }
    .nav-badge:empty { display: none; }
    .nav-footer {
      padding: 8px 6px 10px; border-top: 1px solid var(--border-subtle);
      overflow: hidden; transition: padding 0.25s var(--ease-sharp);
      margin-top: 8px;
    }
    #nav-lang-toggle { transition: opacity 0.2s, height 0.2s; display: inline; }
    .nav.collapsed .nav-footer { padding: 0.75rem 0; display: flex; flex-direction: column; align-items: center; overflow: hidden; }
    .nav-profile-mini {
      display: flex; align-items: center; gap: 9px;
      overflow: hidden; white-space: nowrap;
      padding: 8px 8px;
      border-radius: 7px;
      cursor: pointer;
      transition: background 0.15s;
    }
    .nav-profile-mini:hover { background: var(--bg-surface); }
    .nav-profile-info { min-width: 0; flex: 1; }
    .nav-profile-chev { color: var(--text-muted); flex-shrink: 0; opacity: 0.7; }
    .nav.collapsed .nav-profile-mini { justify-content: center; }
    .nav.collapsed .nav-profile-mini > div:last-child,
    .nav.collapsed .nav-profile-mini > .nav-profile-chev { opacity: 0; width: 0; overflow: hidden; }
    .nav.collapsed .nav-footer a { opacity: 0; width: 0; height: 0; padding: 0; margin: 0; overflow: hidden; }
    .nav.collapsed #nav-lang-toggle { opacity: 0; width: 0; height: 0; overflow: hidden; margin: 0; }
    .avatar {
      width: 28px; height: 28px; border-radius: 50%;
      background: linear-gradient(135deg, #FFB36B, #E94F37);
      color: #fff;
      display: flex; align-items: center; justify-content: center;
      font-family: var(--font-ui); font-size: 11px; font-weight: 700;
      flex-shrink: 0;
    }
    .nav-profile-name { font-family: var(--font-ui); font-size: 12.5px; font-weight: 600; color: var(--text-primary); line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    .nav-profile-plan { font-family: var(--font-ui); font-size: 10.5px; color: var(--text-muted); line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    .nav-footer-links {
      display: flex; align-items: center; gap: 10px;
      padding: 6px 8px 0; margin-top: 4px;
      font-family: var(--font-ui); font-size: 11px;
    }
    .nav-foot-link {
      color: var(--text-muted); text-decoration: none;
      transition: color 0.15s;
    }
    .nav-foot-link:hover { color: var(--text-primary); }
    /* Collapse toggle — sits as last nav-item */
    .nav-collapse-btn { margin-top: auto; }
    .nav-collapse-btn svg { transition: transform .25s; }
    .nav.collapsed .nav-collapse-btn svg { transform: rotate(180deg); }

    /* Help center + bottom CTA button */
    .nav-help-item {
      display: flex; align-items: center; gap: 0.7rem;
      padding: 0.65rem 0.85rem;
      color: var(--text-muted); text-decoration: none;
      border-radius: 10px; font-family: var(--font-ui);
      font-size: var(--text-sm); font-weight: 500;
      transition: background 0.15s, color 0.15s;
      overflow: hidden; white-space: nowrap;
    }
    .nav-help-item:hover { background: var(--bg-surface); color: var(--text-secondary); }
    .nav-help-item svg { flex-shrink: 0; opacity: 0.8; width: 17px; height: 17px; }
    .nav.collapsed .nav-help-item { justify-content: center; padding: 0.65rem 0; }
    .nav.collapsed .nav-help-item .nav-item-label { opacity: 0; width: 0; overflow: hidden; }

    .nav-cta-wrap { padding: 0.75rem 0.85rem 1rem; transition: padding 0.25s var(--ease-sharp); }
    .nav.collapsed .nav-cta-wrap { padding: 0.75rem 0.25rem 1rem; }
    .nav-cta-btn {
      display: flex; align-items: center; justify-content: center; gap: 0.5rem;
      width: 100%; padding: 0.7rem 1rem;
      background: var(--ink); color: #fff;
      border: 1px solid var(--ink); border-radius: 8px; cursor: pointer;
      font-family: var(--font-ui); font-size: 0.8rem; font-weight: 600;
      letter-spacing: 0;
      transition: background 0.15s var(--ease-sharp);
      white-space: nowrap; overflow: hidden;
    }
    .nav-cta-btn:hover { background: var(--ink-hover); border-color: var(--ink-hover); }
    .nav-cta-btn svg { flex-shrink: 0; }
    .nav.collapsed .nav-cta-btn { padding: 0.85rem 0; }
    .nav.collapsed .nav-cta-btn .nav-cta-label { opacity: 0; width: 0; overflow: hidden; }

    /* ══ DASHBOARD TOPBAR (title + global search + actions + icons) ══ */
    .dashboard-topbar {
      display: flex; align-items: center; gap: 14px;
      height: 52px; padding: 0 18px;
      border-bottom: 1px solid var(--border-subtle);
      background: var(--bg-elevated); flex-shrink: 0;
    }
    .topbar-title {
      font-family: var(--font-display); font-size: 18px; font-weight: 600;
      letter-spacing: -0.02em; color: var(--text-primary);
      white-space: nowrap; flex-shrink: 0;
    }
    .dash-breadcrumb { display: none; }
    /* First-run empty state — the pane must never be a silent void */
    .al-empty-hero {
      display: flex; flex-direction: column; align-items: center; justify-content: center;
      gap: 10px; text-align: center; padding: 72px 24px; min-height: 320px;
    }
    .al-empty-hero h3 { font-family: var(--font-display, var(--font-ui)); font-size: 1.35rem; font-weight: 600; color: var(--text-primary); margin: 6px 0 0; }
    .al-empty-hero p { font-size: 0.92rem; color: var(--text-secondary); max-width: 46ch; margin: 0 0 10px; line-height: 1.55; }
    .al-empty-cta { font-size: 0.9rem !important; padding: 0.65rem 1.4rem !important; }
    .al-empty-import { background: none; border: 0; color: var(--brand-primary, #0051D5); font-size: 0.82rem; cursor: pointer; font-family: var(--font-ui); padding: 4px 8px; }
    .al-empty-import:hover { text-decoration: underline; }
    .al-empty-slim { min-height: 140px; padding: 36px 24px; }
    /* Non-planner views: search / export / import act on the article list only */
    .dashboard-topbar.tb-nonplanner .topbar-search,
    .dashboard-topbar.tb-nonplanner .dash-topbar-right .btn-ghost { display: none !important; }

    /* Global search field in topbar — centered */
    .topbar-search {
      display: flex; align-items: center; gap: 8px;
      /* min-width matters more than max-width here. This is the only flexible
         item in a row with seven fixed items to its right (generation pill,
         quota, Export, Import, New article, bell, help), so without a floor it
         absorbs the entire shortfall and collapses until the placeholder clips
         mid-word — "Search articles, pro". 240px is the width at which the
         full placeholder still fits. */
      max-width: 420px; min-width: 240px; flex: 1 1 240px;
      background: var(--bg-surface);
      border: 1px solid var(--border-subtle);
      border-radius: 7px;
      padding: 6px 10px;
      cursor: text;
      color: var(--text-muted);
      font-family: var(--font-ui); font-size: 12.5px;
      transition: border-color 0.15s, background 0.15s;
      margin: 0 auto;
    }
    .topbar-search:hover { border-color: var(--border-strong); }
    .topbar-search:focus-within { border-color: var(--text-secondary); background: var(--bg-elevated); }
    .topbar-search svg { color: var(--text-muted); flex-shrink: 0; }
    .topbar-search input {
      border: 0; background: transparent; outline: 0; flex: 1;
      font-family: inherit; font-size: 12.5px; color: var(--text-primary);
    }
    .topbar-search input::placeholder { color: var(--text-muted); }
    .topbar-search .kbd { flex-shrink: 0; }

    /* Right-side cluster: +New article CTA + icons */
    .dash-topbar-right { display: flex; align-items: center; gap: 0.35rem; flex: 0 0 auto; }
    /* Giving the search a floor only works if something else yields. Export and
       Import are the two items whose icons carry the meaning on their own, so
       their labels are what go when the row runs out of room — before the
       search is allowed to clip. */
    @media (max-width: 1560px) {
      .dash-topbar-right .btn-ghost span[data-i18n] { display: none; }
      .dash-topbar-right .btn-ghost { padding: 6px 9px; }
    }
    .topbar-cta {
      display: inline-flex; align-items: center; gap: 6px;
      background: var(--ink); color: #fff; border: 0;
      font-family: var(--font-ui); font-size: 12.5px; font-weight: 600;
      padding: 7px 12px; border-radius: 7px; cursor: pointer;
      transition: background 0.15s;
      margin-right: 6px;
    }
    .topbar-cta:hover { background: var(--ink-hover); }
    .topbar-cta svg { flex-shrink: 0; }

    /* Hide sidebar CTA — primary "New article" now lives in the topbar */
    .nav-cta-wrap { display: none !important; }

    /* Mobile: hide global search + topbar CTA, keep breadcrumb compact */
    @media (max-width: 720px) {
      .topbar-search { display: none; }
      .topbar-cta .topbar-cta-label { display: none; }
      .topbar-cta { padding: 7px 9px; }
    }

    /* ══ MAIN ════════════════════════════════════════════ */
    .main { margin-left: 220px; flex: 1; min-height: 100vh; display: flex; flex-direction: column; overflow: hidden; transition: margin-left 0.25s cubic-bezier(.4,0,.2,1), padding-right 0.25s cubic-bezier(0.4,0,0.2,1); }
    .main.nav-collapsed { margin-left: 64px; }
    .view { display: none; flex: 1; flex-direction: column; overflow: hidden; }
    .analytics-scroll { flex: 1; min-height: 0; overflow-y: auto; }
    .view.active { display: flex; }
    .view-header {
      display: flex; align-items: stretch; justify-content: flex-start;
      padding: 0; min-height: 0;
      border-bottom: 1px solid var(--border-subtle); background: var(--bg-base); flex-shrink: 0;
      gap: 0;
    }
    .view-title { display: none; }
    .view-subtitle { display: none; }

    /* Available to assistive tech and to crawlers, absent from the layout.
       Not `display:none` — that would hide it from both, which is the whole
       point of not using it here. Carries the shell's single <h1>. */
    .sr-only {
      position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
      overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
    }

    /* Top header search + bell + avatar cluster */
    .header-right { display: flex; align-items: center; gap: 0.5rem; flex-shrink: 0; }
    .header-search-wrap {
      display: flex; align-items: center; gap: 0.45rem;
      background: #fff; border: 1px solid var(--border-strong);
      border-radius: 6px; padding: 0.42rem 0.75rem;
      min-width: 240px; transition: border-color .15s;
    }
    .header-search-wrap:focus-within { border-color: var(--text-muted); }
    .header-search-wrap svg { color: var(--text-muted); flex-shrink: 0; }
    .header-search-input {
      flex: 1; background: none; border: none; outline: none;
      font-family: var(--font-ui); font-size: 0.78rem; color: var(--text-primary);
    }
    .header-search-input::placeholder { color: var(--text-muted); }
    .header-icon-btn {
      width: 28px; height: 28px; border-radius: 6px;
      background: transparent; border: 1px solid transparent;
      display: flex; align-items: center; justify-content: center;
      cursor: pointer; color: var(--text-secondary);
      transition: background .15s, color .15s;
      position: relative;
    }
    .header-icon-btn:hover { background: var(--bg-surface); color: var(--text-primary); }
    .header-icon-btn .dot-indicator {
      position: absolute; top: 6px; right: 7px; width: 7px; height: 7px;
      background: var(--brand-primary); border: 2px solid var(--bg-base); border-radius: 50%;
    }
    /* Phase 4c — popover for notification bell + help button (previously dead controls) */
    .topbar-icon-wrap { position: relative; display: inline-flex; }
    .topbar-popover {
      position: absolute; top: calc(100% + 8px); right: 0;
      min-width: 260px; max-width: 320px;
      background: var(--bg-elevated, #fff);
      border: 1px solid var(--border, #E5E7EB);
      border-radius: 10px;
      box-shadow: 0 12px 28px rgba(0,0,0,0.10);
      padding: 10px 0;
      z-index: 1000;
      display: none;
    }
    .topbar-popover.open { display: block; }
    .topbar-popover-title {
      padding: 4px 14px 8px;
      font-family: var(--font-ui);
      font-size: 11px;
      font-weight: 700;
      text-transform: uppercase;
      letter-spacing: 0.06em;
      color: var(--text-muted);
    }
    .topbar-popover-empty {
      padding: 10px 14px 14px;
      font-family: var(--font-ui);
      font-size: 13px;
      color: var(--text-muted);
      line-height: 1.4;
    }
    .topbar-popover-item {
      display: flex; align-items: center; gap: 10px;
      padding: 9px 14px;
      text-decoration: none;
      color: var(--text-primary, #111);
      transition: background .12s;
    }
    .topbar-popover-item:hover { background: var(--bg-surface, #F3F4F6); }
    .topbar-popover-item .tpi-icon {
      width: 28px; height: 28px; flex-shrink: 0;
      border-radius: 6px;
      background: var(--bg-surface, #F3F4F6);
      display: flex; align-items: center; justify-content: center;
      font-size: 14px;
    }
    .topbar-popover-item .tpi-text { display: flex; flex-direction: column; min-width: 0; }
    .topbar-popover-item .tpi-label {
      font-family: var(--font-ui);
      font-size: 13px; font-weight: 600; line-height: 1.2;
      color: var(--text-primary, #111);
    }
    .topbar-popover-item .tpi-sub {
      font-family: var(--font-ui);
      font-size: 11.5px;
      color: var(--text-muted);
      margin-top: 1px;
    }
    .header-avatar-btn {
      width: 32px; height: 32px; border-radius: 50%;
      background: var(--bg-subtle);
      display: flex; align-items: center; justify-content: center;
      cursor: pointer; color: var(--text-muted);
      transition: background .15s;
      border: 1px solid transparent;
      overflow: hidden;
    }
    .header-avatar-btn:hover { background: var(--bg-surface); }

    /* Phase 4d — one-button system. Audit: "kill the black buttons" — the
       --ink-coloured .btn-primary clashed with the brand-blue .topbar-cta
       and broke the primary/secondary hierarchy. Standardising on the
       brand blue (#0051D5) so every primary CTA reads as the same action. */
    .btn-primary {
      display: inline-flex; align-items: center; gap: 6px;
      padding: 6px 12px; background: var(--brand-primary); color: #fff;
      border: 1px solid var(--brand-primary); border-radius: 6px;
      font-family: var(--font-ui); font-size: 12.5px; font-weight: 600;
      letter-spacing: 0;
      cursor: pointer; transition: background 0.15s var(--ease-sharp);
      box-shadow: none;
    }
    .btn-primary:hover { background: #003FA8; border-color: #003FA8; }
    .btn-primary:active { background: #003FA8; }
    .btn-primary:focus-visible { outline: 2px solid var(--brand-primary); outline-offset: 2px; }
    .btn-ghost {
      display: inline-flex; align-items: center; gap: 6px;
      padding: 6px 12px; background: #fff;
      border: 1px solid var(--border-strong); border-radius: 6px;
      font-family: var(--font-ui); font-size: 12.5px; font-weight: 500;
      color: var(--text-secondary); cursor: pointer;
      transition: background 0.15s var(--ease-sharp), border-color 0.15s var(--ease-sharp);
    }
    .btn-ghost:hover { background: var(--bg-surface); color: var(--text-primary); border-color: var(--text-muted); }

    /* ══ KPI STRIP ═════════════════════════════════════════
       Four metrics, left-grouped on the page rather than boxed and stretched.
       The card chrome is deliberately gone: the strip used to be a bordered
       panel whose 22px inner padding pushed its labels to x=51 while the
       topbar and status chips sat at x=20, so the top of the screen had three
       different left edges. With no border and no cell padding, the labels
       start at the pane's own 20px inset — the same edge as everything above
       and as the table below.

       max-content columns keep the four metrics as a readable cluster instead
       of smearing them across an ultra-wide monitor. */
    /* One row: metrics on the left, filters on the right. Replaces two stacked
       rows that each filled about a quarter of their width and leaned opposite
       ways. Top breathing room lives here rather than on .article-list-pane,
       whose padding-top must stay 0 or rows bleed through the sticky header
       during scroll. */
    .al-toolbar {
      display: flex; align-items: center; justify-content: space-between;
      gap: 16px; flex-wrap: wrap;
      padding: 12px 0;
    }
    .kpi-strip {
      display: flex; align-items: baseline; gap: 0 22px;
      background: transparent; padding: 0; min-width: 0;
    }
    .kpi-cell { padding: 0; display: flex; align-items: baseline; gap: 7px; }
    /* The status chips one row up already print these three numbers. Keeping a
       second, larger copy of them here is what made the header read as noise.
       The nodes stay so renderArticleList() keeps writing to their ids. */
    .kpi-cell.kpi-dup { display: none; }
    /* Client inventory cells. Clickable, so they read as controls: the label
       carries the affordance rather than a button chrome that would out-shout
       the score beside them. */
    .kpi-cell.kpi-client { cursor: pointer; border-radius: 6px; padding: 2px 6px;
                           margin: -2px -6px; }
    .kpi-cell.kpi-client:hover { background: var(--bg-surface); }
    .kpi-cell.kpi-client:focus-visible { outline: 2px solid var(--brand-primary);
                                         outline-offset: 1px; }
    /* Dimmed at zero, never hidden: these sit in a fixed strip, and a cell that
       disappears shifts the three beside it on every render. */
    .kpi-cell.kpi-client.kpi-zero { opacity: .45; }
    .kpi-cell.kpi-client.kpi-zero:hover { opacity: .7; }
    .kpi-label {
      font-family: var(--font-ui); font-size: 10px; font-weight: 600;
      color: var(--text3);
      text-transform: uppercase; letter-spacing: 0.06em;
      margin-bottom: 0;
    }
    .kpi-val-row { display: flex; align-items: baseline; gap: 8px; }
    .kpi-val {
      font-family: var(--font-ui); font-size: 14px; font-weight: 700;
      color: var(--text-primary); letter-spacing: -0.01em; line-height: 1;
      /* tabular-nums, not a monospace face: the digits need to hold a column
         without introducing a second typeface. */
      font-variant-numeric: tabular-nums;
    }
    .kpi-delta {
      font-family: var(--font-ui); font-size: 11px; font-weight: 600;
      color: var(--text-muted); margin-top: 6px; min-height: 14px;
      display: inline-flex; align-items: center; gap: 3px;
      font-variant-numeric: tabular-nums;
    }
    .kpi-delta:empty { min-height: 0; margin-top: 0; }
    .kpi-delta.up { color: var(--green); }
    .kpi-delta.down { color: var(--red); }
    .kpi-delta.flat { color: var(--text-muted); }
    .kpi-sub {
      font-size: 11.5px; color: var(--text-muted); margin-top: 4px;
      font-family: var(--font-ui);
    }

    /* ══ PIPELINE STRIP ════════════════════════════════════ */
    .pipeline-strip {
      display: flex; align-items: center; gap: 0;
      padding: 10px 28px;
      background: var(--bg-base);
      border-bottom: 1px solid var(--border-subtle);
      overflow-x: auto;
    }
    .pipeline-strip .pipe-step {
      display: inline-flex; align-items: center; gap: 8px;
      padding: 4px 14px;
      border-radius: 6px;
      cursor: pointer;
      transition: background 0.12s;
      white-space: nowrap;
    }
    .pipeline-strip .pipe-step:hover { background: var(--bg-surface); }
    .pipeline-strip .pipe-dot {
      width: 6px; height: 6px; border-radius: 50%;
      background: var(--text-muted); flex-shrink: 0;
    }
    .pipeline-strip .pipe-step[data-status="draft"] .pipe-dot { background: var(--col-draft); }
    .pipeline-strip .pipe-step[data-status="writing"] .pipe-dot { background: var(--amber); }
        /* --col-review, not --info: the review status chip is amber everywhere
       else in the app, so a teal dot for the same state meant one state had
       two colours. */
    .pipeline-strip .pipe-step[data-status="review"] .pipe-dot { background: var(--col-review); }
    .pipeline-strip .pipe-step[data-status="done"] .pipe-dot { background: var(--green); }
    .pipeline-strip .pipe-step.empty .pipe-dot { background: var(--border-strong); opacity: 0.5; }
    .pipeline-strip .pipe-label {
      font-family: var(--font-ui); font-size: 12px; font-weight: 500;
      color: var(--text-secondary);
    }
    .pipeline-strip .pipe-step.empty .pipe-label { color: var(--text-muted); }
    .pipeline-strip .pipe-count {
      font-family: var(--font-code); font-size: 11px; font-weight: 700;
      background: var(--bg-elevated);
      border: 1px solid var(--border-subtle);
      border-radius: 4px;
      padding: 1px 6px;
      color: var(--text-primary);
      min-width: 22px; text-align: center;
    }
    .pipeline-strip .pipe-step.empty .pipe-count { color: var(--text-muted); }
    .pipeline-strip .pipe-arrow {
      color: var(--text-muted); opacity: 0.5;
      font-size: 14px; padding: 0 4px;
      flex-shrink: 0;
    }

    /* ══ ARTICLE LIST LAYOUT ═══════════════════════════════ */
    .article-list-wrap {
      flex: 1; display: flex; overflow: hidden;
    }
    .article-list-pane {
      /* padding-top dropped: it was a transparent gap above the sticky header
         that let rows visibly bleed through during scroll. The visual top
         spacing now lives on .al-filter-bar via margin-top so the sticky
         header pins flush with the scroll container's top edge. */
      /* 20px, not 28: the topbar and the status strip both inset their content
         by 20px, so a 28px pane put the whole content area on a second left
         edge 8px to the right of the chrome above it. That jog is the thing
         the eye reads as "nothing lines up". */
      flex: 1; overflow-y: auto; overflow-x: auto; padding: 0 20px 20px;
    }
    /* .al-filter-bar's old margin-top:12px is gone — it is a flex child of
   .al-toolbar now, which owns the vertical rhythm. */
    .article-list-pane::-webkit-scrollbar { width: 6px; }
    .article-list-pane::-webkit-scrollbar-thumb { background: var(--border2); border-radius: 3px; }

    /* Always-visible planner header (sits above onboarding state and article list) */
    .planner-header-wrap { padding: 1.5rem 2rem 1rem; flex-shrink: 0; }

    /* Recent topics section header */
    .recent-section-header {
      display: flex; align-items: center; justify-content: space-between;
    }
    .recent-section-title {
      font-family: var(--font-display); font-size: 1.1rem; font-weight: 600;
      letter-spacing: -0.015em; color: var(--text-primary);
    }
    .btn-add-topic {
      display: inline-flex; align-items: center; gap: 0.35rem;
      padding: 0.5rem 0.95rem; background: var(--ink);
      color: #fff; border: 1px solid var(--ink); border-radius: 8px;
      font-family: var(--font-ui); font-size: 0.78rem; font-weight: 600;
      letter-spacing: 0; text-transform: none; cursor: pointer;
      box-shadow: none;
      transition: background .15s var(--ease-sharp);
    }
    .btn-add-topic:hover { background: var(--ink-hover); border-color: var(--ink-hover); }
    .btn-add-topic svg { flex-shrink: 0; }

    /* Status strip — clean underline tabs */
    .status-strip {
      display: flex; gap: 28px; border-bottom: 1px solid var(--border-subtle);
      background: var(--bg-base); padding: 0 28px;
    }
    .status-chip {
      display: inline-flex; align-items: center; gap: 7px;
      padding: 10px 0 11px; font-family: var(--font-ui);
      font-size: 13px; font-weight: 500; color: var(--text-muted);
      cursor: pointer; border-bottom: 2px solid transparent;
      transition: color 0.15s, border-color 0.15s;
      background: none; border-radius: 0;
      margin-bottom: -1px;
    }
    .status-chip:hover { color: var(--text-secondary); background: none; }
    .status-chip.active {
      color: var(--text-primary); border-bottom-color: var(--ink);
      font-weight: 600; background: none;
    }
    .status-chip-dot { display: none; }
    .status-chip-count {
      font-weight: 600; font-size: 10.5px;
      font-family: var(--font-code);
      color: var(--text-muted); padding: 1px 6px;
      background: var(--bg-surface); border-radius: 3px; letter-spacing: 0;
    }
    .status-chip.active .status-chip-count {
      background: var(--ink); color: #fff;
    }

    /* Status strip inside view-header — full width underline tab strip */
    .view-header .status-strip {
      border-bottom: none; background: transparent; padding: 0 28px;
      flex: 1; align-self: stretch; align-items: stretch;
    }
    .view-header .status-chip { padding-top: 0; padding-bottom: 0; margin-bottom: 0; align-items: center; }
    /* Header-right hidden — Export + New article moved to topbar */
    .view-header .header-right { display: none; }

    /* Filter bar — compact chips sitting above the data table */
    .al-filter-bar {
      display: flex; gap: 8px; margin-bottom: 12px; align-items: center;
    }
    /* Search wrapper: icon on the left, input on the right, shared border */
    .al-search-wrap {
      position: relative; display: inline-flex; align-items: center;
      flex: 0 0 260px; height: 30px;
      background: var(--bg-elevated);
      border: 1px solid var(--border-strong); border-radius: 6px;
      transition: border-color 0.15s;
    }
    .al-search-wrap:focus-within { border-color: var(--text-muted); }
    .al-search-wrap > svg {
      position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
      color: var(--text-muted); pointer-events: none;
    }
    /* Higher specificity (wrap > input.class) so we beat the global
       input[type="text"] rule defined later in this stylesheet. */
    .al-search-wrap > input.al-search {
      width: 100%; height: 100%;
      padding: 0 10px 0 30px;
      border: none; background: transparent; outline: none;
      border-radius: 0; box-shadow: none;
      font-size: 12.5px; font-family: var(--font-ui);
      font-style: normal; font-weight: 400;
      color: var(--text-primary);
      line-height: 1;
      flex: 1 1 auto;
    }
    .al-search-wrap > input.al-search:focus { box-shadow: none; border-color: transparent; }
    .al-search-wrap > input.al-search::placeholder { color: var(--text-muted); font-style: normal; opacity: 1; }
    /* Select: flat chip with custom chevron.
       The global `select { width: 100% }` rule (used by modal forms)
       would stretch these; override with width:auto + !important. */
    .al-select {
      -webkit-appearance: none; -moz-appearance: none; appearance: none;
      width: auto !important;
      box-sizing: border-box;
      height: 30px;
      padding: 0 28px 0 10px !important;
      border: 1px solid var(--border-strong); border-radius: 6px;
      font-size: 12.5px; font-family: var(--font-ui);
      font-weight: 500;
      background-color: var(--bg-elevated);
      background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='%236B7280' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>") !important;
      background-repeat: no-repeat !important;
      background-position: right 10px center !important;
      color: var(--text-primary); outline: none; cursor: pointer;
      transition: border-color 0.15s;
      flex: 0 0 auto;
      min-width: 120px;
    }
    .al-select::-ms-expand { display: none; }
    .al-select:focus { border-color: var(--text-muted); }
    .al-select:hover { border-color: var(--text-muted); }
    .al-select option { font-weight: 500; color: var(--text-primary); background: var(--bg-elevated); }

    /* ══ CUSTOM BRAND COMBOBOX ══════════════════════════════
       Replaces native <select> so we can render favicon + name rows.
       Uses the same visual footprint as .al-select (30px, 6px radius, hairline border). */
    .brand-combo {
      position: relative; display: inline-flex; align-items: center;
      height: 30px; min-width: 150px;
      padding: 0 28px 0 10px;
      border: 1px solid var(--border-strong); border-radius: 6px;
      background-color: var(--bg-elevated);
      background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='%236B7280' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
      background-repeat: no-repeat;
      background-position: right 10px center;
      font-family: var(--font-ui); font-size: 12.5px; font-weight: 500;
      color: var(--text-primary);
      cursor: pointer;
      user-select: none;
      gap: 8px;
    }
    .brand-combo:hover, .brand-combo.open { border-color: var(--text-muted); }
    .brand-combo-fav {
      width: 16px; height: 16px; border-radius: 3px;
      object-fit: contain; background: #fff;
      flex-shrink: 0;
    }
    .brand-combo-fav-empty {
      width: 16px; height: 16px; border-radius: 3px;
      background: var(--bg-surface); flex-shrink: 0;
    }
    .brand-combo-label {
      flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    }
    .brand-combo-menu {
      display: none;
      position: absolute; top: calc(100% + 4px); left: 0;
      min-width: 220px; max-width: 320px; max-height: 280px; overflow-y: auto;
      background: var(--bg-elevated);
      border: 1px solid var(--border-strong); border-radius: 8px;
      box-shadow: 0 8px 28px rgba(15,23,42,0.12);
      padding: 4px;
      z-index: 500;
    }
    .brand-combo.open .brand-combo-menu { display: block; }
    .brand-combo-item {
      display: flex; align-items: center; gap: 8px;
      padding: 6px 8px; border-radius: 5px;
      font-family: var(--font-ui); font-size: 12.5px; font-weight: 500;
      color: var(--text-primary);
      cursor: pointer;
      background: transparent; border: none; width: 100%;
      text-align: left;
    }
    .brand-combo-item:hover, .brand-combo-item.active {
      background: var(--bg-surface);
    }
    .brand-combo-item.selected {
      color: var(--brand-primary);
    }
    .brand-combo-item-check {
      margin-left: auto; opacity: 0; color: var(--brand-primary); flex-shrink: 0;
    }
    .brand-combo-item.selected .brand-combo-item-check { opacity: 1; }
    .brand-combo-item-name {
      flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    }
    .brand-combo-item-fav {
      width: 18px; height: 18px; border-radius: 4px;
      object-fit: contain; background: #fff; flex-shrink: 0;
      border: 1px solid var(--border-subtle);
    }
    .brand-combo-item-fav-empty {
      width: 18px; height: 18px; border-radius: 4px;
      background: var(--bg-surface); flex-shrink: 0;
      display: grid; place-items: center;
      font-family: var(--font-ui); font-size: 9.5px; font-weight: 700;
      color: var(--text-muted);
      text-transform: uppercase;
    }

    /* Article rows — real data table with column header.
       Cols (11 total): title | persona | serp | brief | facts | interview |
                        writer | audit | article | score | kebab.
       Persona/Brief/Interview restored so the grid mirrors the full
       human-in-the-loop pipeline; each cell is a reviewable checkpoint. */
    .al-row, .al-row-header {
      display: grid;
      /* MOT-CLÉ | PIPELINE | ARTICLE | SCORE | kebab. Was eleven tracks with
         eight equal 0.72fr step columns until 2026-08-23; those eight took 70%
         of the table to carry one bit each. The "À FAIRE" column this comment
         used to name went in that same pass — its button and the Article status
         pill were two controls for one meaning, so they merged and Article now
         carries the row's one pill. */
      grid-template-columns: minmax(280px,2.3fr) minmax(230px,1.4fr) minmax(150px,1fr) 96px 28px;
      align-items: center; gap: 0;
      padding: 0; min-width: 1180px;
    }
    /* Six tracks: a CLIENT column between ARTICLE and SCORE, for accounts that
       have somebody invited to review. Set on the LIST container, never per row —
       rows whose track count disagreed with the header would each start their
       columns at a different x.
       The width comes out of MOT-CLÉ, which has the most to give: it was
       carrying the state badge as a chip, so it is handing back space it only
       needed while it was doing this column's job. Measured at 1174px total in
       a 1440 window, which is the real render area — no horizontal scroll.
       1.9fr, not the 1.35 the mockup used: the widest cell is "Lu · il y a 6 j"
       PLUS "Modifié depuis lecture", and at 1.35 the qualifier ellipsised to
       "Modifié depuis lectu…" — which is the exact imprecision this column was
       built to remove. Sized from the widest real pairing, not from the average
       row. */
    .al-has-client .al-row, .al-has-client .al-row-header {
      grid-template-columns: minmax(280px,2.1fr) minmax(200px,1.2fr) minmax(140px,0.9fr) minmax(290px,1.9fr) 96px 28px;
    }
    /* Structural only — the visual skin lives in the Attio grid block (search
       "Attio grid skin"). */
    .al-row-header {
      display: grid !important;
      border-bottom: 1px solid var(--border-subtle);
      /* No vertical padding on the CONTAINER. The header is a fixed 40px and
         its cells are stretched to it (see the grid-lines block), but stretch
         fills the content box -- container padding would hold every column
         rule 8px short of the header's own edges, leaving a visible gap
         between the header's rule and the first row's. The cells keep their
         own 8px, which is what insets the labels. */
      padding-top: 0; padding-bottom: 0;
    }
    .al-row {
      border: none; border-bottom: 1px solid var(--border-subtle); border-radius: 0;
      margin-bottom: 0;
      cursor: default;
    }
    .al-row:focus { outline: none; }
    .al-row:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }
    /* Cell padding. ONE keyline: every column's content starts 12px from its
       divider, header included, so the header label sits directly above the
       cell content it names. Before 2026-08-24 this was 12 on the title and
       score columns, 10 on the rail, 8 on the step cells and 6 on every
       header — five different keylines in one table, which is the "consistent
       margins and padding" step of the 4-point system, skipped. Vertical is
       8px, a 4-multiple; it was 7. */
    .al-row > *, .al-row-header > * { padding: 8px 12px; }
    .al-row-header > * { padding-top: 8px; padding-bottom: 8px; }
    .al-row > .al-kebab-btn { padding: 0; display: flex; align-items: center; justify-content: center; }
    /* Step cells fill the full row height; horizontal keyline matches every
       other column (see above). */
    .al-row > .al-step-cell { padding: 0 12px; }

    /* Col 1: icon + keyword + sub (inside a single flex cell) */
    .al-title-col { display: flex; align-items: center; gap: 12px; min-width: 0; }
    .al-title-text { min-width: 0; flex: 1; overflow: hidden; }
    .al-kw { font-family: var(--font-ui); font-size: 13px; font-weight: 600; color: var(--text-primary); line-height: 16px; letter-spacing: -0.005em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    /* nowrap + overflow:hidden: the chips live on this line, and anything that
       wraps here becomes a third line that overlaps the next row's title. */
    .al-chip-opt { background:#EEF4FF; color:#3B5B8C; }
    .al-kw-sub { font-size: 11.5px; line-height: 16px; color: var(--text-muted); margin-top: 0; display: flex; align-items: center; gap: 4px; font-weight: 400; flex-wrap: nowrap; overflow: hidden; }

    /* Column cells */
    .al-cell-seo { display: flex; align-items: center; min-width: 0; }
    /* Interim SOSEO number while Plume Stage-2 is still computing */
    .score-pending { display: inline-flex; animation: score-pending-pulse 1.6s ease-in-out infinite; }
    @keyframes score-pending-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.45; } }
    @media (prefers-reduced-motion: reduce) { .score-pending { animation: none; opacity: 0.7; } }
    .al-cell-dash { color: var(--text4); font-size: 12px; }

    /* ── Pipeline step cells — plain text, centered, colored by state ── */
    .al-step-cell {
      display: flex; align-items: center; justify-content: center;
      min-width: 0; cursor: pointer;
      font-family: var(--font-ui); font-size: 11.5px; font-weight: 500;
      color: var(--text-muted); transition: background 0.1s;
      padding: 0 12px; text-align: center;
      overflow: hidden;
      position: relative;
      box-sizing: border-box;
      /* CRITICAL: the row has align-items:center, which overrides grid's
         default stretch behavior — cells size to their CONTENT instead of
         the row height, then overflow:visible on the row lets the cell box
         (and its hover bg) extend past the row's bottom border into the row
         below. align-self:stretch + height:100% locks the cell to the row
         height so the bg can never bleed past the row separator. */
      align-self: stretch !important;
      height: 100% !important;
    }
    .al-step-text {
      overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
      max-width: 100%;
    }
    .al-step-cell.empty { cursor: default; color: var(--border-strong); }
    .al-step-cell.empty:hover, .al-step-cell.queued:hover { background: transparent; }
    .al-step-cell.queued { color: var(--text-muted); opacity: 0.55; cursor: default; }

    /* Legacy keyframe kept for any non-step components that still reference it */
    @keyframes al-shimmer { 0%{background-position:-200% 0} 100%{background-position:200% 0} }
    /* Active cell — see authoritative blue/white shimmer rule near line 7966.
       The legacy amber + italic active rule that previously lived here was
       leaking residual properties (font-style, animation) through the cascade
       and producing the visual "bleed" the owner reported. Removed. */
    .al-step-cell.needs-input { color: #B45309; cursor: pointer; }

    /* Done — per-step accent colors */
    .al-step-cell[data-step="persona"].done  { color: #5B21B6; }
    .al-step-cell[data-step="brief"].done    { color: #1D4ED8; }
    .al-step-cell[data-step="interview"].done{ color: #92400E; }
    .al-step-cell[data-step="article"].done  { color: #065F46; }

    /* Hover tints per step (done only) */
    .al-step-cell[data-step="persona"].done:hover  { background: rgba(124,58,237,0.06); }
    .al-step-cell[data-step="brief"].done:hover    { background: rgba(37,99,235,0.06); }
    .al-step-cell[data-step="interview"].done:hover{ background: rgba(217,119,6,0.06); }
    .al-step-cell[data-step="article"].done:hover  { background: rgba(5,150,105,0.06); }
    .al-step-cell.needs-input:hover { background: rgba(180,83,9,0.06); }
    /* Phase 1 — failed-step indicator (a real pipeline failure, surfaced from step_states) */
    .al-step-cell.failed { color: #B91C1C; cursor: pointer; font-weight: 600; }
    .al-step-cell.failed:hover { background: rgba(185,28,28,0.07); }

    /* Run button */
    .al-step-run {
      font-size: 11px; font-weight: 600; font-family: var(--font-ui);
      background: none; color: var(--text-muted); border: 1px solid var(--border-strong);
      border-radius: 4px; padding: 6px 12px; cursor: pointer;
      white-space: nowrap; transition: background 0.1s, color 0.1s;
      min-height: 32px; min-width: 52px;
    }
    .al-step-run:hover { background: var(--ink); color: #fff; border-color: var(--ink); }

    /* Answer button.
       The label MUST be wrapped in its own <span> (see buildStepCell): a bare
       text node inside an inline-flex cannot be ellipsized, which is how
       "Réponse requise" rendered as "Réponse re" — 114px of text hard-clipped
       into a 65px cell with no ellipsis, bleeding over the column border. Same
       trap reviewPill() already documents. The overflow rules live here, not
       only in a media query, because the cell is ~88px at 1280 and the clip was
       never width-gated. */
    .al-step-answer {
      font-size: 11px; font-weight: 600; font-family: var(--font-ui);
      background: none; color: #B45309; border: 1px solid #FDE68A;
      border-radius: 4px; padding: 2px 8px; cursor: pointer;
      max-width: 100%; min-width: 0; overflow: hidden;
      white-space: nowrap; transition: background 0.1s, color 0.1s;
    }
    .al-step-answer > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .al-step-answer:hover { background: #D97706; color: #fff; border-color: #D97706; }

    /* Keyword inline edit */
    .al-kw-wrap { cursor: text; min-width: 0; flex: 1; }
    .al-kw-input {
      width: 100%; font-family: var(--font-ui); font-size: 13px; font-weight: 600;
      color: var(--text-primary); background: transparent; border: none;
      outline: none; padding: 0; line-height: 1.25; letter-spacing: -0.005em;
    }

    /* AEO citation column — three engine pips per row */
    .al-cell-aeo { display: flex; align-items: center; gap: 3px; min-width: 0; }
    .aeo-pip {
      width: 18px; height: 18px; border-radius: 4px;
      font-family: var(--font-code); font-size: 9px; font-weight: 700;
      display: inline-flex; align-items: center; justify-content: center;
      background: var(--bg-subtle); color: var(--text-muted);
      flex-shrink: 0;
    }
    .aeo-pip.hit { background: var(--green-bg); color: var(--green); }
    .aeo-pip.miss { background: var(--bg-subtle); color: var(--text-muted); opacity: 0.55; }
    .aeo-pip.pending { background: transparent; border: 1px dashed var(--border-strong); color: var(--text-muted); opacity: 0.5; }

    /* Wrap rows in a bordered container so all rows read as one table.
       overflow:visible is required so the sticky column header can anchor to
       the scrolling .article-list-pane (overflow:hidden here would clip it). */
    #article-rows {
      background: var(--bg-elevated);
    }
    /* Attio-flat: sharp corners, hairline frame, no card chrome */
    .al-table-wrap {
      border: 1px solid var(--border-subtle);
      border-radius: 0;
      overflow: visible;
      background: var(--bg-elevated);
      margin-bottom: 0;
    }

    /* Bulk-import group header — a collapsible box grouping one import's cards.
       Owner feedback: consecutive imports were hard to tell apart in the flat
       grid. Top+bottom borders, a brand-colored left rail, and a gap before
       each header (reset on the first one) mark where one import ends and
       the next begins; the rail continues at low opacity down the group's
       own rows (.al-row-grouped below) so the banding reads as one unit. */
    .al-group {
      display: flex; align-items: center; gap: 10px;
      padding: 9px 14px;
      background: var(--bg-surface, #f7f6f3);
      border-top: 1px solid var(--border-subtle);
      border-bottom: 1px solid var(--border-subtle);
      border-left: 3px solid var(--brand-primary, #0051D5);
      cursor: pointer; user-select: none;
      font-size: 0.82rem;
      margin-top: 12px;
    }
    .al-group:first-child { margin-top: 0; }
    .al-group:hover { background: var(--bg-elevated); }
    .al-group:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }
    .al-group.collapsed { border-radius: 0; }
    .al-group-chevron, .al-group-folder { display: inline-flex; align-items: center; color: var(--text-muted); flex-shrink: 0; }
    .al-group-folder { color: var(--brand-primary, #0051D5); }
    .al-group-label { font-weight: 600; color: var(--ink, #1a1a1a); white-space: nowrap; }
    .al-group-summary { color: var(--text-muted); font-size: 0.76rem; flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    .al-group-gen {
      display: inline-flex; align-items: center; gap: 5px; flex-shrink: 0;
      padding: 4px 11px; border: none; border-radius: 999px;
      background: var(--brand-primary, #0051D5); color: #fff;
      font-size: 0.74rem; font-weight: 600; cursor: pointer;
    }
    .al-group-gen:hover { filter: brightness(1.08); }
    .al-group-genrunning { display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0; color: var(--text-muted); font-size: 0.76rem; }
    .al-group-stop, .al-group-del {
      display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
      width: 24px; height: 24px; border-radius: 6px; cursor: pointer;
      background: transparent; border: 1px solid var(--border-subtle);
    }
    .al-group-stop { color: var(--amber, #A05E00); }
    .al-group-del  { color: var(--red, #C0392B); }
    .al-group-stop:hover { background: var(--amber-bg, #FDF5E6); border-color: var(--amber, #A05E00); }
    .al-group-del:hover  { background: var(--red-bg, #FDEEEC); border-color: var(--red, #C0392B); }

    /* Icon box on left of row */
    .al-icon-box {
      width: 24px; height: 24px; border-radius: 5px;
      background: var(--brand-dim);
      display: flex; align-items: center; justify-content: center;
      color: var(--brand-primary); flex-shrink: 0;
      position: relative; overflow: hidden;
    }
    .al-icon-box svg { width: 12px; height: 12px; }
    /* Favicon variant: image sits on top of the fallback SVG. When it loads
       it fully covers the heuristic icon; when it errors, onerror hides the
       <img> and the SVG underneath remains visible. */
    .al-icon-box.al-icon-has-fav { background: #fff; border: 1px solid var(--border-subtle); }
    .al-icon-box .al-fav {
      position: absolute; inset: 1px;
      width: calc(100% - 2px); height: calc(100% - 2px);
      object-fit: contain;
      background: #fff;
      border-radius: 4px;
      display: block;
    }

    /* Count footer — Attio-style strip attached under the grid ("N articles") */
    .al-pager-row {
      display: flex; align-items: center;
      padding: 9px 14px;
      background: var(--bg-elevated);
      border: 1px solid var(--border-subtle);
      border-top: none;
      margin-bottom: 20px;
      font-family: var(--font-ui); font-size: 12px; color: var(--text-muted);
    }
    .al-pager-row #al-pager { font-family: var(--font-ui); }

    /* Kebab 3-dot menu button */
    .al-kebab-btn {
      width: 32px; height: 32px; border-radius: 8px;
      background: none; border: none; cursor: pointer;
      color: var(--text-muted);
      display: flex; align-items: center; justify-content: center;
      transition: background .15s, color .15s;
    }
    .al-kebab-btn:hover { background: var(--bg-surface); color: var(--text-primary); }
    /* Kebab dropdown menu */
    .al-kebab-menu {
      display: none; position: absolute; z-index: 100;
      background: var(--bg-card, #fff); border: 1px solid var(--border-strong, #ddd);
      border-radius: 10px; padding: 4px; min-width: 180px;
      box-shadow: 0 8px 28px rgba(36,32,26,0.12);
    }
    .al-kebab-menu.open { display: block; }
    .al-km-item {
      display: flex; align-items: center; gap: 8px; width: 100%;
      padding: 9px 12px; border: none; background: none; color: var(--text-secondary, #444);
      font-size: 0.8rem; font-family: var(--font-ui); cursor: pointer;
      border-radius: 8px; transition: background 0.12s;
    }
    .al-km-item:hover { background: var(--brand-dim, #eef); }
    .al-km-item.danger { color: var(--red, #C0392B); }
    .al-km-item.danger:hover { background: var(--red-bg, #fee2e2); }
    .al-km-sep { height: 1px; background: var(--border, #eee); margin: 3px 4px; }
    /* Status+scores wrapper: on desktop, act as grid pass-through */
    .al-status-scores-wrap { display: contents; }
    .al-scores-row { display: contents; }
    /* Mobile actions: hidden on desktop */
    .al-mobile-actions { display: none; }

    /* Step artifact panel header */
    .dp-step-header {
      display: flex; align-items: center; justify-content: space-between; gap: 10px;
      padding: 1rem 1.25rem 0.75rem;
      border-bottom: 1px solid var(--border-subtle);
      flex-shrink: 0;
    }
    .dp-step-back {
      background: none; border: none; cursor: pointer; padding: 4px;
      color: var(--text-muted); border-radius: 4px; display: flex;
      align-items: center; transition: color 0.1s, background 0.1s;
    }
    .dp-step-back:hover { color: var(--text-primary); background: var(--bg-subtle); }
    .dp-step-label {
      font-family: var(--font-ui); font-size: 11px; font-weight: 600;
      text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-muted);
    }
    .dp-step-title {
      font-family: var(--font-display); font-size: 1rem; font-weight: 700;
      color: var(--text-primary); flex: 1; letter-spacing: -0.01em;
    }
    .dp-step-body { padding: 1.25rem; overflow-y: auto; flex: 1; display: flex; flex-direction: column; gap: 1rem; }
    /* Artifact field rows */
    .dp-artifact-section { display: flex; flex-direction: column; gap: 0.4rem; }
    .dp-artifact-label {
      font-family: var(--font-ui); font-size: 10px; font-weight: 700;
      text-transform: uppercase; letter-spacing: 0.1em; color: var(--text-muted);
    }
    .dp-artifact-value { font-size: 13px; color: var(--text-primary); line-height: 1.65; }
    .dp-artifact-list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 0.35rem; }
    .dp-artifact-list li { font-size: 13px; color: var(--text-primary); line-height: 1.55; }
    .dp-artifact-tag {
      display: inline-block; font-size: 11px; padding: 2px 8px; border-radius: 4px;
      background: var(--red-bg); color: var(--red); border: 1px solid var(--red-border);
      margin: 2px; font-family: var(--font-ui);
    }
    /* ── Expert Interview panel ───────────────────────────────────────────
       The interview is the one pipeline step that ASKS the writer for
       something instead of showing them a result, and it was the last step
       still wearing the flat dp-step-header chrome every sibling left behind.
       It now reads as a short conversation: numbered prompts, the hint
       promoted out of grey italic into a real callout (it is the most useful
       line in the card and it was the least visible), a progress rail so the
       finish line is visible before you start typing, and per-card state so
       "have I done this one" never needs re-reading. */
    .iv-rail {
      position: sticky; top: 0; z-index: 3;
      display: flex; align-items: center; gap: 10px;
      padding: 0.6rem 1.2rem;
      background: rgba(255,255,255,0.94);
      -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
      border-bottom: 1px solid var(--border-subtle);
    }
    .iv-rail-count {
      font-family: var(--font-code); font-size: 10px; font-weight: 700;
      letter-spacing: 0.09em; text-transform: uppercase;
      color: var(--text-muted); white-space: nowrap;
    }
    .iv-rail-count b { color: var(--brand-primary); }
    .iv-rail-pips { display: flex; gap: 4px; flex: 1; }
    .iv-pip {
      flex: 1; height: 4px; border-radius: var(--radius-pill);
      background: var(--surface); transition: background 0.25s ease;
    }
    .iv-pip.filled { background: var(--brand-primary); }

    /* The drawer scrolls on .dr-body and .drawer-panel is display:block, so the
       rail and footer pin with sticky against that scrollport — a flex:1 body
       here would be inert. */
    .iv-list {
      padding: 1.05rem 1.2rem 1.35rem;
      display: flex; flex-direction: column; gap: 0.8rem;
    }
    .iv-intro {
      font-size: 12.5px; line-height: 1.6; color: var(--text-secondary);
      padding: 0.7rem 0.85rem; border-radius: 11px;
      background: var(--brand-dim); border: 1px solid var(--brand-border);
    }

    .iv-q {
      border: 1px solid var(--border-subtle); border-radius: 14px;
      background: var(--bg-elevated); padding: 0.9rem 1rem;
      transition: border-color 0.16s, box-shadow 0.16s, background 0.16s;
    }
    .iv-q:focus-within { border-color: var(--brand-border); box-shadow: 0 4px 16px rgba(0,81,213,0.09); }
    .iv-q.answered { border-color: var(--green-border); background: linear-gradient(180deg, var(--green-bg) 0%, var(--bg-elevated) 46%); }
    .iv-q-head { display: flex; align-items: flex-start; gap: 9px; }
    .iv-q-num {
      flex-shrink: 0; width: 24px; height: 24px; border-radius: 8px;
      display: flex; align-items: center; justify-content: center;
      font-family: var(--font-code); font-size: 10.5px; font-weight: 700;
      background: var(--brand-dim); color: var(--brand-primary);
      transition: background 0.18s, color 0.18s;
    }
    .iv-q.answered .iv-q-num { background: var(--green); color: #FFFFFF; }
    .iv-q-text {
      flex: 1; min-width: 0; padding-top: 3px;
      font-family: var(--font-display); font-size: 13.5px; font-weight: 600;
      color: var(--text-primary); line-height: 1.4; letter-spacing: -0.005em;
    }
    .iv-q-hint {
      display: flex; align-items: flex-start; gap: 7px;
      margin: 0.6rem 0 0 33px; padding: 0.45rem 0.6rem;
      background: rgba(0,81,213,0.045);
      border-left: 2px solid var(--brand-border); border-radius: 0 8px 8px 0;
      font-size: 11.5px; line-height: 1.5; color: var(--text-secondary);
    }
    .iv-q-hint svg { flex-shrink: 0; margin-top: 1px; color: var(--brand-primary); opacity: 0.7; }
    .iv-q-input { margin: 0.6rem 0 0 33px; }
    .iv-textarea {
      width: 100%; box-sizing: border-box; display: block;
      min-height: 60px; max-height: 300px; overflow-y: auto; resize: none;
      border: 1px solid var(--border); border-radius: 9px;
      padding: 0.55rem 0.7rem;
      font-family: var(--font-ui); font-size: 12.5px; line-height: 1.55;
      color: var(--text-primary); background: var(--bg-base);
      transition: border-color 0.14s, background 0.14s;
    }
    .iv-textarea::placeholder { color: var(--text-muted); opacity: 0.8; }
    .iv-textarea:focus { outline: none; border-color: var(--brand-primary); background: var(--bg-elevated); }
    .iv-q-meta {
      display: flex; justify-content: flex-end; align-items: center; gap: 5px;
      margin-top: 4px; min-height: 13px;
      font-family: var(--font-code); font-size: 10px; color: var(--text-muted);
      opacity: 0; transition: opacity 0.18s;
    }
    .iv-q-meta.show { opacity: 1; }
    .iv-q-meta .iv-ok { display: inline-flex; align-items: center; gap: 3px; color: var(--green); font-weight: 700; }

    .iv-foot {
      position: sticky; bottom: 0; z-index: 3;
      padding: 0.8rem 1.2rem 0.95rem;
      border-top: 1px solid var(--border-subtle); background: var(--bg-elevated);
      box-shadow: 0 -6px 18px rgba(9,9,11,0.05);
      display: flex; flex-direction: column; gap: 0.5rem;
    }
    .iv-foot-row { display: flex; gap: 0.5rem; align-items: stretch; }
    .iv-submit {
      flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 7px;
      padding: 0.68rem 1rem; border: none; border-radius: 10px;
      background: var(--brand-primary); color: #FFFFFF;
      font-family: var(--font-ui); font-size: 13px; font-weight: 600;
      cursor: pointer; box-shadow: 0 2px 10px rgba(0,81,213,0.22);
      transition: background 0.14s, box-shadow 0.14s, transform 0.1s;
    }
    .iv-submit:hover { background: #003FA8; box-shadow: 0 4px 16px rgba(0,81,213,0.28); }
    .iv-submit:active { transform: translateY(1px); }
    .iv-submit kbd {
      font-family: var(--font-code); font-size: 9.5px; font-weight: 700;
      padding: 2px 5px; border-radius: 5px;
      background: rgba(255,255,255,0.2); color: rgba(255,255,255,0.92);
    }
    .iv-skip {
      padding: 0.68rem 0.95rem; border: 1px solid var(--border); border-radius: 10px;
      background: transparent; color: var(--text-muted); white-space: nowrap;
      font-family: var(--font-ui); font-size: 12.5px; font-weight: 500;
      cursor: pointer; transition: color 0.14s, border-color 0.14s, background 0.14s;
    }
    .iv-skip:hover { color: var(--text-primary); border-color: var(--text-muted); background: var(--bg-subtle); }
    .iv-foot-note { font-size: 11px; line-height: 1.45; color: var(--text-muted); text-align: center; }

    /* Recap — the same cards once the gate is closed, answers shown inline */
    .iv-badge {
      display: inline-flex; align-items: center; gap: 6px; align-self: flex-start;
      padding: 4px 10px; border-radius: var(--radius-pill);
      background: var(--green-bg); border: 1px solid var(--green-border); color: var(--green);
      font-family: var(--font-code); font-size: 10px; font-weight: 700;
      letter-spacing: 0.08em; text-transform: uppercase;
    }
    .iv-badge.skipped { background: var(--surface); border-color: var(--border); color: var(--text-muted); }
    .iv-answer {
      margin: 0.6rem 0 0 33px; padding: 0.55rem 0.75rem;
      background: var(--bg-base); border-left: 2px solid var(--green-border);
      border-radius: 0 8px 8px 0; white-space: pre-wrap;
      font-size: 12.5px; line-height: 1.6; color: var(--text-secondary);
    }
    .iv-answer.empty { border-left-color: var(--border); color: var(--text-muted); font-style: italic; }

    /* GSC Overview & Performance — Google Search Console style */
    .gsc-range-btn { font-size:0.7rem; font-weight:600; padding:0.3rem 0.6rem; border:none; background:transparent; color:var(--text-secondary); cursor:pointer; border-radius:6px; transition:all 0.15s; font-family:var(--font-ui); }
    .gsc-range-btn.active { background:var(--bg-elevated); color:var(--text-primary); box-shadow:0 1px 3px rgba(0,0,0,0.08); }
    .gsc-range-btn:hover { color:var(--text-primary); }
    .gsc-stat-card { padding:0.75rem; border-radius:10px; border:2px solid transparent; transition:all 0.15s; }
    .gsc-stat-card.active { border-color:currentColor; }
    .gsc-stat-label { font-size:0.72rem; font-weight:500; margin:0 0 0.25rem; }
    .gsc-stat-value { font-size:1.15rem; font-weight:700; font-family:var(--font-code); margin:0; }
    .gsc-stat-delta { font-size:0.72rem; font-weight:600; margin:0.2rem 0 0; min-height:1em; }
    .gsc-delta-up { color:#16a34a; }
    .gsc-delta-down { color:#dc2626; }
    .gsc-delta-flat { color:var(--text-muted); }
    .gsc-article-row { display:grid; grid-template-columns:1fr 72px 80px 56px 56px 72px; gap:0; align-items:center; padding:0.65rem 1.25rem; border-bottom:1px solid var(--border); font-size:0.82rem; }
    .gsc-article-row:last-child { border-bottom:none; }
    .gsc-article-row:hover { background:rgba(0,81,213,0.03); }
    .gsc-articles-header { display:grid; grid-template-columns:1fr 72px 80px 56px 56px 72px; gap:0; padding:0.5rem 1.25rem; font-size:0.72rem; font-weight:600; color:var(--text-muted); text-transform:uppercase; letter-spacing:0.04em; border-bottom:1px solid var(--border); cursor:default; }
    .gsc-articles-header span { cursor:pointer; user-select:none; }
    .gsc-articles-header span:hover { color:var(--text-primary); }
    .gsc-sort-active { color:var(--brand-primary) !important; }
    .gsc-track-card-item { padding:0.55rem 0.75rem; cursor:pointer; border-bottom:1px solid var(--border); font-size:0.85rem; }
    .gsc-track-card-item:last-child { border-bottom:none; }
    .gsc-track-card-item:hover { background:rgba(0,81,213,0.05); }
    .gsc-track-card-item.selected { background:rgba(0,81,213,0.08); color:var(--brand-primary); }
    /* Analytics, not connected. One card, one action - the four-step
       checklist that used to live here duplicated the topbar « Prise en
       main », which derives the same steps from real account state. */
    .gsc-connect-card { border:1px solid var(--border); border-radius:14px; background:var(--bg-elevated);
      padding:34px 30px 30px; text-align:center; }
    .gsc-connect-icon { width:46px; height:46px; border-radius:50%; background:var(--bg-surface);
      display:flex; align-items:center; justify-content:center; margin:0 auto 16px; }
    .gsc-connect-title { font-family:var(--font-display); font-size:1.22rem; font-weight:640;
      letter-spacing:-.01em; margin:0 0 7px; }
    .gsc-connect-sub { font-size:0.87rem; color:var(--text-secondary); line-height:1.5;
      margin:0 auto 20px; max-width:34ch; }
    .gsc-connect-cta { display:inline-flex; align-items:center; justify-content:center;
      padding:0.62rem 1.35rem; font-size:0.88rem; text-decoration:none; }
    .gsc-connect-alt { display:block; margin:14px auto 0; background:none; border:0; padding:0;
      font-size:0.79rem; font-weight:600; color:var(--brand-primary); cursor:pointer; }
    .gsc-connect-alt:hover { text-decoration:underline; }
    /* One hue for all four. The old set was #0051D5 / #7C3AED / #059669 /
       #D97706: violet and emerald are prohibited outright by BRAND.md §4, and
       the violet also failed accessibility against the brand blue (ΔE 3.9
       protanopia, 14.1 normal vision, floor 15). Since each metric now has its
       own plot, no colour needs to carry identity at all. */
    .gsc-stat-clicks,
    .gsc-stat-impressions,
    .gsc-stat-ctr,
    .gsc-stat-position { color:#0051D5; }
    .gsc-stat-hint { font-weight:400; color:var(--text-muted); text-transform:none; letter-spacing:0; }
    /* The sparkline box. Fixed height so four tiles stay the same size even
       when one has a delta line and another does not. */
    .gsc-spark { height:34px; margin-top:0.5rem; position:relative; }
    .gsc-spark canvas { position:absolute; inset:0; }
    /* DESIGN_SYSTEM.md §11: two-column max at tablet, never three at any
       breakpoint, single column on a phone. */
    /* -- Analytics visual system -------------------------------------------
       Light, airy SaaS analytics: grey page, white cards, hairline borders,
       navy text, one purple accent. Chart series use Google Search Console's
       own four colours so the data reads the way an SEO already expects.

       BRAND.md section 4 prohibits purple / teal / green / orange and section 5
       prohibits Inter. Both are waived HERE ONLY, on owner instruction
       (2026-07-28), and recorded as an exception at the top of BRAND.md.
       The app now runs on a single typeface (DM Sans, 2026-08), so this
       block inherits it like everything else — no separate webfont request
       and no second face to keep in sync. */
    #view-analytics { --an-bg:#F6F7F9; --an-card:#FFFFFF; --an-line:#ECEDF1;
                      --an-ink:#1A1B33; --an-mut:#6B7280; --an-accent:#5B5BD6;
                      background:#F6F7F9; }
    #view-analytics .view-title { color:#1A1B33; font-size:24px; font-weight:600; }

    .gsc-verdict { background:#FFFFFF; border:1px solid var(--an-line);
                   border-radius:14px; padding:14px 20px; margin-bottom:14px;
                   box-shadow:0 1px 2px rgba(26,27,51,0.03); }
    .gsc-verdict-eyebrow, .gsc-verdict-quiet { display:none; }
    .gsc-verdict p { font-family:var(--font-ui); font-weight:500; font-size:14px;
                   line-height:1.5; margin:0; color:var(--an-ink); }
    .gsc-verdict a { color:var(--an-accent); text-decoration:none;
                   border-bottom:1px solid rgba(91,91,214,0.35); cursor:pointer; }

    .gsc-scope-band { display:flex; align-items:center; gap:8px; margin-bottom:10px; }
    .gsc-scope-tag { font-size:11px; font-weight:500; padding:2px 9px; border-radius:8px;
                   background:#FFF; color:var(--an-mut); border:1px solid var(--an-line); }
    .gsc-scope-note { font-size:12px; color:var(--an-mut); }

    .gsc-mini-btn { font-size:12px; font-weight:500; color:#374151; background:#FFF;
                   border:1px solid var(--an-line); border-radius:8px; padding:4px 11px;
                   cursor:pointer; font-family:var(--font-ui); }
    .gsc-mini-btn:hover { border-color:#D8DAE0; }
    .gsc-mini-btn.open { color:var(--an-accent); border-color:rgba(91,91,214,0.4); }

    /* -- Metric row + chart, one card -------------------------------------- */
    .gsc-chart-card { background:var(--an-card); border:1px solid var(--an-line);
                   border-radius:14px; box-shadow:0 1px 2px rgba(26,27,51,0.03);
                   padding:24px 26px 16px; margin-bottom:14px; }
    .gsc-tile-row { display:grid; grid-template-columns:repeat(4,1fr); gap:0;
                   margin-bottom:18px; }
    .gsc-stat-card { background:none; border:none; text-align:left; padding:0 20px 0 0;
                   cursor:pointer; display:block; font-family:var(--font-ui);
                   position:relative; opacity:0.42; transition:opacity .15s; }
    .gsc-stat-card.active { opacity:1; }
    .gsc-stat-card::before { content:""; position:absolute; left:0; top:4px;
                   width:9px; height:9px; border-radius:50%; border:2px solid currentColor;
                   background:transparent; box-sizing:border-box; }
    .gsc-stat-card.active::before { background:currentColor; }
    .gsc-stat-label { display:block; font-size:13px; font-weight:400; color:var(--an-mut);
                   margin:0 0 6px 20px; }
    .gsc-stat-value { display:block; font-family:var(--font-ui); font-weight:600;
                   font-size:29px; line-height:1.1; letter-spacing:-0.02em;
                   color:var(--an-ink); margin-left:20px; }
    .gsc-stat-delta { display:block; font-size:12px; font-weight:500; color:var(--an-mut);
                   margin:3px 0 0 20px; }
    .gsc-stat-hint { display:none; }
    /* Search Console's own series colours. The dot on each card IS the line. */
    .gsc-stat-clicks      { color:#4285F4; }
    .gsc-stat-impressions { color:#5E35B1; }
    .gsc-stat-ctr         { color:#00897B; }
    .gsc-stat-position    { color:#E8710A; }
    .gsc-chart-wrap { height:230px; position:relative; }

    /* -- Cards -------------------------------------------------------------- */
    .gsc-sec { background:var(--an-card); border:1px solid var(--an-line);
                   border-radius:14px; padding:24px 26px; margin-bottom:14px;
                   box-shadow:0 1px 2px rgba(26,27,51,0.03); }
    .gsc-sec-head { display:flex; justify-content:space-between; align-items:baseline;
                   gap:12px; margin-bottom:14px; min-height:24px; }
    /* The title was wrapping to two lines and shoving the filter out of
       alignment with the one in the neighbouring card. */
    .gsc-sec-title { white-space:nowrap; }
    .gsc-pager { display:flex; align-items:center; justify-content:flex-end;
                 gap:8px; padding-top:10px; }
    .gsc-pg { background:#FFF; border:1px solid var(--an-line); border-radius:6px;
              width:24px; height:24px; line-height:1; cursor:pointer; color:#374151;
              font-size:14px; font-family:var(--font-ui); padding:0; }
    .gsc-pg:disabled { opacity:0.35; cursor:default; }
    .gsc-pg:not(:disabled):hover { border-color:#D8DAE0; }
    .gsc-pg-n { font-size:11px; color:var(--an-mut); font-family:var(--font-ui); }
    .gsc-sec-eyebrow { display:none; }
    .gsc-sec-title { font-family:var(--font-ui); font-weight:500; font-size:17px;
                   letter-spacing:-0.01em; margin:0; color:var(--an-ink); }
    .gsc-two-col { display:grid; grid-template-columns:repeat(2,1fr); gap:14px;
                   align-items:start; }
    /* Higher specificity than the app's global input rule, which sets a grey
       fill, a border and width:100% and made this overflow the card. */
    .gsc-sec-head input.gsc-filter,
    input.gsc-filter {
      border:0 !important; outline:none; background:transparent !important;
      box-shadow:none !important; font-size:12px; color:var(--an-mut);
      font-family:var(--font-ui); padding:0 !important; margin:0;
      width:140px !important; max-width:40%; flex:0 0 auto;
      text-align:right; height:auto; border-radius:0;
    }
    input.gsc-filter::placeholder { color:#9CA3AF; }

    /* The five-column data tables read across, not beside each other: at half
       width the metric columns collapse onto each other and the numbers stop
       being scannable. The movers/striking pair below is short lists and stays
       two-up. */
    .gsc-two-col.gsc-stack { grid-template-columns:1fr; }

    .gsc-thead { display:flex; align-items:center; gap:0; padding:0 0 10px;
                   border-bottom:1px solid var(--an-line); }
    /* NB: the keyword column modifier is .col-kw, never .main - `.main` is the
       app's page-layout container, and a header cell carrying it inherited a
       900px-tall layout box that pushed every row off screen. */
    .gsc-th { font-family:var(--font-ui); font-size:11px; font-weight:500;
                   color:var(--an-mut); flex-shrink:0; width:126px;
                   text-align:right; padding-right:18px; }
    .gsc-th.col-kw { flex:1; min-width:0; text-align:left; padding-right:12px; }
    .gsc-row { display:flex; align-items:center; gap:0; padding:14px 0;
                   border-bottom:1px solid var(--an-line); font-size:13px;
                   color:var(--an-ink); }
    .gsc-row:last-child { border-bottom:none; }
    .gsc-row-main { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis;
                   white-space:nowrap; }
    .gsc-row-num { font-family:var(--font-ui); font-size:13px; color:var(--an-ink);
                   flex-shrink:0; min-width:52px; text-align:right; }
    .gsc-cell { display:inline-flex; align-items:baseline; justify-content:flex-end;
                   gap:5px; flex-shrink:0; width:126px; padding-right:18px; }
    .gsc-cell .v { font-family:var(--font-ui); font-size:13px; color:var(--an-ink);
                   font-variant-numeric:tabular-nums; }
    /* Direction, not just colour: the triangle survives a colourblind reader
       and a greyscale screenshot.
       order:-1 puts it BEFORE the number, as in the reference dashboards, with
       no change to the markup the builder emits. */
    .gsc-d { order:-1; font-family:var(--font-ui); font-size:10px; font-weight:500;
                   line-height:1; position:relative; top:-1px; }
    /* Hairline column rules, as in the reference dashboards. They do the work
       the gap used to: four right-aligned numbers in a row read as one blur
       without a boundary between them. Left edge only, so the row never ends
       in a dangling line. */
    .gsc-th.col-clicks, .gsc-th.col-impr, .gsc-th.col-ctr, .gsc-th.col-pos,
    .gsc-cell.col-clicks, .gsc-cell.col-impr, .gsc-cell.col-ctr, .gsc-cell.col-pos {
      border-left:1px solid var(--an-line);
    }
    .gsc-thead .gsc-th { align-self:stretch; display:flex; align-items:flex-end;
                   justify-content:flex-end; }
    .gsc-thead .gsc-th.col-kw { justify-content:flex-start; }
    .gsc-row .gsc-cell { align-self:stretch; align-items:center; }
    .gsc-d.up   { color:#1A7F5A; }
    .gsc-d.down { color:#C0392B; }
    .gsc-d.flat { color:var(--an-mut); }
    .gsc-state { font-size:11px; font-weight:500; padding:1px 8px; border-radius:8px;
                   flex-shrink:0; background:#F6F7F9; color:var(--an-mut);
                   border:1px solid var(--an-line); }
    .gsc-state.good { background:rgba(91,91,214,0.07); color:var(--an-accent);
                   border-color:rgba(91,91,214,0.2); }
    .gsc-state.warn { background:#F6F7F9; color:var(--an-mut); }
    .gsc-flag { font-size:11px; font-weight:500; color:#C0392B;
                   background:rgba(192,57,43,0.06); border:1px solid rgba(192,57,43,0.15);
                   border-radius:8px; padding:1px 8px; flex-shrink:0; }
    .gsc-empty { border:1px dashed var(--an-line); border-radius:12px; background:#FAFBFC;
                   padding:20px 22px; }
    .gsc-empty h4 { font-family:var(--font-ui); font-weight:500; font-size:14px;
                   color:var(--an-ink); margin:0 0 4px; }
    .gsc-empty p { color:var(--an-mut); font-size:13px; margin:0; line-height:1.5; }

    @media (max-width:1000px) { .gsc-two-col { grid-template-columns:1fr; } }
    @media (max-width:1200px) {
      .gsc-th.col-impr, .gsc-th.col-ctr,
      .gsc-cell.col-impr, .gsc-cell.col-ctr { display:none; }
    }
    @media (max-width:700px) { .gsc-tile-row { grid-template-columns:repeat(2,1fr); row-gap:16px; } }
    .dp-btn {
      padding: 0.45rem 0.75rem; background: var(--bg-surface);
      border: 1px solid var(--border2); border-radius: 6px;
      font-family: var(--font-ui); font-size: 0.72rem; font-weight: 600;
      color: var(--text2); cursor: pointer; transition: border-color 0.15s, color 0.15s;
    }
    .dp-btn:hover { border-color: var(--brand-accent); color: var(--brand-accent); }

    .card-section { }
    .card-section.empty { display: none; }
    .section-header {
      display: flex; align-items: center; gap: 0.6rem;
      margin-bottom: 0.5rem; padding: 0 0.25rem;
    }
    .section-dot {
      width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
    }
    .section-title {
      font-family: var(--font-ui); font-size: 0.78rem; font-weight: 700; color: var(--text);
      text-transform: uppercase; letter-spacing: 0.05em;
    }
    .section-count {
      font-size: 0.65rem; font-weight: 700;
      background: var(--bg-elevated); color: var(--text3);
      padding: 2px 8px; border-radius: 6px;
      min-width: 22px; text-align: center;
    }
    .section-line {
      flex: 1; height: 1px;
      background: linear-gradient(90deg, var(--border2), transparent);
    }

    /* ══ CARDS ═══════════════════════════════════════════ */
    .card {
      position: relative;
      background: var(--bg-surface); border: 1px solid var(--border-subtle);
      border-radius: 6px; padding: var(--space-6);
      cursor: default; transition: border-color 0.15s, box-shadow 0.15s;
    }
    .card::before { display: none; }
    .card:hover { border-color: var(--border-default); }
    .card.card-generating {
      border-color: var(--brand-border);
    }
    @keyframes cardPulse {
      0%,100% { box-shadow: 0 0 8px var(--brand-glow); }
      50%      { box-shadow: 0 0 20px rgba(184, 41, 61, 0.25); }
    }
    .card.card-done { cursor: pointer; }

    /* Per-section top accent stripe (subtle, not left-border) */
    .section-draft .card   { border-top: 2px solid var(--brand-primary); }
    .section-todo .card    { border-top: 2px solid var(--green); }
    .section-review .card  { border-top: 2px solid var(--amber); }
    .section-writing .card { border-top: 2px solid var(--red); }
    .section-done .card    { border-top: 2px solid var(--green); }

    /* Card inner elements */
    .card-top { display: flex; align-items: flex-start; flex-wrap: wrap; gap: 0.35rem 0.5rem; margin-bottom: 0.25rem; }
    .card-keyword { font-family: var(--font-display); font-size: 0.92rem; font-weight: 700; color: var(--text); line-height: 1.3; letter-spacing: -0.02em; flex: 1 1 60%; min-width: 60%; }
    .card-del { background: none; border: none; color: var(--text4); cursor: pointer; font-size: 1.1rem; line-height: 1; padding: 0 2px; transition: color 0.15s; opacity: 0; }
    .card:hover .card-del { opacity: 1; }
    .card-del:hover { color: var(--red); }
    .card-sub { font-size: 0.74rem; color: var(--text3); line-height: 1.4; margin-bottom: 0.5rem; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
    .card-meta-row {
      display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap;
      margin-bottom: 0.6rem;
    }
    .card-tag {
      font-size: 0.65rem; font-weight: 600; padding: 2px 8px;
      border-radius: 6px; border: 1px solid var(--border2);
      color: var(--text3); background: var(--bg-base);
    }
    .card-tag.accent { border-color: var(--brand-border); color: var(--brand-primary); background: var(--brand-dim); }
    .card-foot { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; margin-top: 0.65rem; }
    .card-foot-actions { display: flex; gap: 0.4rem; }
    .card-meta { font-size: 0.7rem; color: var(--text4); }
    .card-btn {
      font-size: 0.72rem; font-weight: 600; padding: 5px 12px;
      border-radius: 3px; border: 1px solid var(--border2);
      background: none; color: var(--text3); cursor: pointer;
      font-family: var(--font-ui); transition: border-color 0.15s, color 0.15s, background 0.15s;
      white-space: nowrap;
    }
    .card-btn:hover { border-color: var(--brand-accent); color: var(--brand-accent); }
    .card-btn.primary { background: var(--brand-primary); border-color: var(--brand-primary); color: var(--text-on-brand); }
    .card-btn.primary:hover { background: var(--indigo-dark); }
    .card-btn.green { background: var(--green-bg); border-color: var(--green-border); color: var(--green); }
    .card-btn.green:hover { background: rgba(26, 127, 90, 0.22); border-color: var(--green); }
    .card-btn.analyzed { background: var(--green-bg); border-color: var(--green-border); color: var(--green); pointer-events: auto; }
    .card-btn.analyzed:hover { background: rgba(26, 127, 90, 0.20); border-color: var(--green); }
    .card-btn.amber { background: var(--amber-bg); border-color: rgba(160, 94, 0, 0.40); color: var(--amber); }
    .card-btn.amber:hover { background: rgba(160, 94, 0, 0.20); border-color: var(--amber); }
    .card-btn.red { background: var(--red-bg); border-color: var(--red-border); color: var(--red); }
    .card-btn.red:hover { background: var(--red-bg); border-color: var(--red); }
    .card-btn.queuing { pointer-events: none; opacity: 0.5; cursor: default; }
    .fc-pill {
      display: inline-flex; align-items: center;
      font-size: 0.65rem; font-weight: 700; padding: 2px 7px; border-radius: 6px;
    }
    .fc-pill.ok  { background: var(--green-bg); color: var(--green); border: 1px solid var(--green-border); }
    .fc-pill.warn { background: var(--amber-bg); color: var(--amber); border: 1px solid var(--amber); }
    .card-preview {
      font-size: 0.75rem; color: var(--text3); line-height: 1.55;
      display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
      overflow: hidden; margin-bottom: 0.5rem;
    }

    /* ══ CARD ACTION MENU ═════════════════════════════════ */
    .card-actions-btn {
      background: none; border: none; color: var(--text4); cursor: pointer;
      font-size: 1.1rem; line-height: 1; padding: 2px 4px; border-radius: 4px;
      transition: color 0.15s, background 0.15s; opacity: 0; position: relative;
    }
    .card:hover .card-actions-btn { opacity: 1; }
    .card-actions-btn:hover { color: var(--text); background: var(--bg-elevated); }
    .card-actions-menu {
      display: none; position: absolute; top: 100%; right: 0; z-index: 50;
      background: var(--surface); border: 1px solid var(--border2);
      border-radius: 6px; padding: 4px; min-width: 170px;
      box-shadow: 0 8px 28px rgba(36, 32, 26, 0.10); margin-top: 4px;
    }
    .card-actions-menu.open { display: block; }
    .cam-item {
      display: flex; align-items: center; gap: 8px; width: 100%;
      padding: 7px 10px; border: none; background: none; color: var(--text2);
      font-size: 0.78rem; font-family: var(--font-ui); cursor: pointer;
      border-radius: 6px; transition: background 0.12s;
    }
    .cam-item:hover { background: var(--brand-dim); }
    .cam-item.danger { color: var(--red); }
    .cam-item.danger:hover { background: var(--red-bg); }
    .cam-sep { height: 1px; background: var(--border); margin: 3px 4px; }

    /* ══ CATEGORY TAG ═════════════════════════════════════ */
    .card-cat-tag {
      font-size: 0.62rem; font-weight: 700; padding: 2px 7px;
      border-radius: 5px; background: var(--brand-dim);
      color: var(--brand-primary); border: 1px solid var(--brand-border);
      max-width: 100px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }

    /* ══ CATEGORY FILTER ══════════════════════════════════ */
    .cat-filter-select {
      flex: 0 0 200px;
      background: var(--bg-base); border: 1px solid var(--border2);
      border-radius: 6px; padding: 0.38rem 0.7rem; font-size: 0.82rem;
      color: var(--text); font-family: var(--font-ui); outline: none; cursor: pointer;
      transition: border-color 0.15s;
    }
    .cat-filter-select:focus { border-color: var(--brand-accent); }

    /* ══ ARCHIVE SECTION ══════════════════════════════════ */
    .section-archived { opacity: 0.7; }
    .section-archived .card { opacity: 0.65; }
    .section-archived .card:hover { opacity: 1; }
    .archive-toggle {
      background: none; border: 1px solid var(--border2); border-radius: 6px;
      color: var(--text3); font-size: 0.68rem; font-weight: 600;
      padding: 3px 10px; cursor: pointer; font-family: var(--font-ui);
      transition: border-color 0.15s, color 0.15s;
    }
    .archive-toggle:hover { border-color: var(--brand-accent); color: var(--brand-accent); }
    .spinner { width: 14px; height: 14px; border: 2px solid var(--brand-border); border-top-color: var(--brand-primary); border-radius: 50%; animation: spin 0.8s linear infinite; flex-shrink: 0; }
    .gen-progress-bar { height: 3px; background: var(--border); border-radius: 2px; overflow: hidden; margin-bottom: 0.35rem; }
    .gen-progress-fill { height: 100%; background: linear-gradient(90deg, var(--brand-primary), var(--brand-accent)); border-radius: 2px; transition: width 0.8s cubic-bezier(0.4, 0, 0.2, 1); width: 0%; position: relative; }
    .gen-progress-fill::after { content:''; position:absolute; top:0; left:0; right:0; bottom:0; background:linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent); animation: progress-shine 1.5s ease-in-out infinite; }
    @keyframes progress-shine { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } }
    /* The bar's WIDTH is data on a 1s cadence and must keep moving — it is the
       only thing telling the user the run is alive. The sheen sliding across it
       is pure decoration, so that is what stops. */
    @media (prefers-reduced-motion: reduce) {
      .gen-progress-fill::after { animation: none; }
      .gen-progress-fill { transition: none; }
    }
    @keyframes spin { to { transform: rotate(360deg); } }
    @keyframes text-shimmer { 0% { background-position: 200% center; } 100% { background-position: -200% center; } }
    .text-shimmer {
      color: var(--brand-primary);
    }
    .card-revision-notes {
      font-size: 0.72rem; color: var(--text3);
      background: var(--amber-bg); border-left: 2px solid var(--amber);
      padding: 0.4rem 0.5rem; border-radius: 4px;
      margin-bottom: 0.5rem; line-height: 1.4; font-style: italic;
    }
    .card-error { font-size: 0.7rem; color: var(--red); margin-top: 0.4rem; line-height: 1.4; }
    .card-dl { font-size: 0.72rem; font-weight: 600; color: var(--green); text-decoration: none; display: inline-flex; align-items: center; gap: 0.3rem; }
    .card-dl:hover { opacity: 0.8; }

    /* ══ TLDR BOX ════════════════════════════════════════ */
    .tldr-box {
      background: var(--brand-dim);
      border-left: 3px solid var(--brand-primary);
      border-radius: 0 8px 8px 0;
      padding: 0.875rem 1.25rem;
      margin: 0.5rem 0 1.5rem;
    }
    .tldr-label {
      font-size: 0.65rem; font-weight: 700;
      text-transform: uppercase; letter-spacing: 0.1em;
      color: var(--brand-accent); margin-bottom: 0.5rem;
    }
    .tldr-list { margin: 0; padding-left: 1.25rem; }
    .tldr-list li { font-size: 0.875rem; color: var(--text2); line-height: 1.65; margin-bottom: 0.2rem; }

    /* ══ COMMENT SYSTEM ══════════════════════════════════ */
    .comment-highlight {
      background: var(--amber-bg, #FDF5E6);
      border-bottom: 2px solid var(--amber);
      border-radius: 2px; padding: 0 1px;
      cursor: pointer;
    }

    .comment-item {
      background: var(--amber-bg); border: 1px solid rgba(160, 94, 0, 0.20);
      border-radius: 6px; padding: 0.6rem 0.75rem;
      margin-bottom: 0.5rem; position: relative;
    }
    .comment-excerpt {
      font-size: 0.7rem; color: var(--text4); font-style: italic;
      margin-bottom: 0.2rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }
    .comment-body { font-size: 0.78rem; color: var(--text2); line-height: 1.4; padding-right: 1.2rem; }
    .comment-del {
      position: absolute; top: 0.3rem; right: 0.4rem;
      background: none; border: none; color: var(--text4);
      cursor: pointer; font-size: 1rem; line-height: 1; transition: color 0.15s;
    }
    .comment-del:hover { color: var(--red); }
    .no-comments-hint { font-size: 0.75rem; color: var(--text4); text-align: center; padding: 0.75rem 0; line-height: 1.5; }

    /* ══ MODAL OVERLAY ═══════════════════════════════════ */
    .modal-overlay {
      position: fixed; inset: 0; background: rgba(36, 32, 26, 0.50);
      backdrop-filter: blur(4px); z-index: 500;
      display: none; align-items: center; justify-content: center;
    }
    .modal-overlay.open { display: flex; }
    .modal-box {
      background: var(--bg-base); border: 1px solid var(--border-default); border-radius: 6px;
      width: 100%; max-width: 460px; padding: var(--space-8);
      box-shadow: var(--shadow-lg);
      animation: slideUp 0.2s ease;
    }
    @keyframes slideUp {
      from { opacity: 0; transform: translateY(12px); }
      to   { opacity: 1; transform: translateY(0); }
    }
    .modal-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 1.25rem; }
    .modal-title { font-family: var(--font-display); font-size: 1rem; font-weight: 700; }
    .modal-close { background: none; border: none; color: var(--text4); cursor: pointer; font-size: 1.25rem; padding: 2px; line-height: 1; transition: color 0.15s; }
    .modal-close:hover { color: var(--text); }
    .field { margin-bottom: 1rem; }
    .field:last-of-type { margin-bottom: 0; }
    label { display: block; font-family: var(--font-ui); font-size: 0.75rem; font-weight: 600; color: var(--text2); margin-bottom: 0.35rem; }
    /* password/email included so fields like "Changer le mot de passe" don't
       render as bare native inputs next to their styled text siblings.
       url included 2026-08-18: the onboarding wizard's website field rendered
       as a bare native input on the very first screen a client sees. */
    input[type="text"], input[type="number"], input[type="password"], input[type="email"], input[type="url"], textarea {
      width: 100%; background: var(--bg-base); border: 1px solid var(--border-default);
      border-radius: 4px; padding: 0.5rem 0.75rem;
      font-size: var(--text-base); color: var(--text-primary); font-family: var(--font-body); outline: none;
      transition: border-color 0.15s, box-shadow 0.15s; line-height: 1.5;
    }
    /* GDPR delete confirm input sits inline in a flex row — keep it compact */
    #gdpr-delete-pw { width: auto; }
    input::placeholder, textarea::placeholder { color: var(--text-muted); font-style: italic; }
    input:focus, textarea:focus { border-color: var(--brand-primary); box-shadow: 0 0 0 3px var(--brand-glow); }
    textarea { resize: vertical; min-height: 60px; }
    select {
      width: 100%; background: var(--bg-base); border: 1px solid var(--border-default);
      border-radius: 4px; padding: 0.5rem 2rem 0.5rem 0.75rem;
      font-size: var(--text-base); color: var(--text-primary); font-family: var(--font-ui); outline: none;
      appearance: none; -webkit-appearance: none;
      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%230051D5' stroke-width='1.8' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
      background-repeat: no-repeat; background-position: right 0.75rem center;
      cursor: pointer; transition: border-color 0.15s, box-shadow 0.15s;
    }
    select:focus { border-color: var(--brand-primary); box-shadow: 0 0 0 3px var(--brand-glow); }
    select option { background: var(--bg-base); color: var(--text); }
    .field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem; }
    .hint { font-size: 0.7rem; color: var(--text4); margin-top: 0.3rem; }
    .modal-actions { display: flex; gap: 0.75rem; justify-content: flex-end; margin-top: 1.5rem; }

    /* ══ ADD TOPIC MODAL — Enhanced styling ══════════════ */
    /* ══ ADD MODAL — two-pane: the article left, Génération rail right
       (design: add-topic-modal-20260826 variant C). No overflow on the
       box — panes carry their own corner radii (see CLAUDE.md CSS rules). */
    #modal-add .modal-box {
      background: #FFFFFF;
      border-radius: 16px;
      border: 1px solid rgba(15,23,42,0.06);
      box-shadow: 0 0 0 1px rgba(0,81,213,0.06), 0 32px 80px rgba(15,23,42,0.28), 0 4px 16px rgba(15,23,42,0.08);
      padding: 0; max-width: 780px; width: min(780px, calc(100vw - 2rem));
      display: grid; grid-template-columns: minmax(0,1fr) 288px;
      animation: addModalIn 0.28s cubic-bezier(0.34, 1.56, 0.64, 1);
    }
    @keyframes addModalIn {
      from { opacity: 0; transform: translateY(12px) scale(0.96); }
      to   { opacity: 1; transform: translateY(0) scale(1); }
    }
    .am-pane-left { padding: 20px 24px 22px; min-width: 0; }
    .am-title-row { display: flex; align-items: center; margin-bottom: 14px; }
    #modal-add .modal-title { font-size: 1.05rem; letter-spacing: -0.01em; }
    .am-rail {
      background: #F4F7FC; border-left: 1px solid #E8EEF6;
      border-radius: 0 15px 15px 0;
      padding: 18px 18px 20px; display: flex; flex-direction: column; min-width: 0;
    }
    .am-rail-head { display: flex; align-items: center; margin-bottom: 12px; flex-shrink: 0; }
    .am-rail-title {
      font-size: 0.66rem; font-weight: 700; text-transform: uppercase;
      letter-spacing: 0.09em; color: #64748B; font-family: var(--font-ui);
    }
    .am-rail-body { display: flex; flex-direction: column; gap: 8px; }
    #modal-add .modal-close {
      margin-left: auto; width: 28px; height: 28px; display: flex; align-items: center; justify-content: center;
      border-radius: 7px; font-size: 0; transition: background 0.15s, color 0.15s;
    }
    #modal-add .modal-close:hover { background: #E6ECF5; }
    .am-rail-cta { margin-top: auto; padding-top: 12px; flex-shrink: 0; }
    .am-rail-cta .btn-primary { width: 100%; height: 42px; justify-content: center; font-size: 0.88rem; }
    .am-rail-cost { text-align: center; font-size: 0.68rem; color: var(--text4); margin-top: 8px; font-family: var(--font-ui); }
    .am-rail-cancel {
      width: 100%; text-align: center; font-size: 0.78rem; font-weight: 500; color: #64748B;
      margin-top: 4px; padding: 8px; background: none; border: none; cursor: pointer; font-family: var(--font-ui);
      border-radius: 7px;
    }
    .am-rail-cancel:hover { color: var(--text1, #16233B); background: #E6ECF5; }

    /* Body — left pane stack */
    .add-modal-body { display: flex; flex-direction: column; gap: 0.8rem; }

    /* Keyword — larger, SEO-prominent */
    .am-keyword-wrap { position: relative; }
    .am-keyword-wrap svg { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); color: #0051D5; pointer-events: none; }
    #add-keyword { padding-left: 38px; height: 42px; font-size: 0.9rem; border-radius: 10px; border: 1.5px solid rgba(0,81,213,0.25); background: #FBFCFE; }
    #add-keyword:focus { border-color: #0051D5; box-shadow: 0 0 0 3px rgba(0,81,213,0.09); }
    .am-keyword-hint { font-size: 0.67rem; color: #94A3B8; margin-top: 4px; display: flex; align-items: center; gap: 4px; }

    /* Uniform field heights — all inputs/selects 36px in the grid rows */
    #modal-add .field-row select,
    #modal-add .field-row input[type="number"],
    #modal-add .field-row input[type="text"] { height: 36px; padding-top: 0; padding-bottom: 0; }
    #modal-add .field-row .card-btn { height: 36px; padding: 0 9px; font-size: 15px; flex-shrink: 0; }
    #add-wc::-webkit-inner-spin-button, #add-wc::-webkit-outer-spin-button { opacity: 0; width: 0; }
    #add-wc { -moz-appearance: textfield; }
    .field-row .am-label-with-icon { display: flex; align-items: center; gap: 4px; margin-bottom: 0.28rem; font-size: 0.73rem; font-weight: 600; color: var(--text2); }
    .field-row .am-label-with-icon svg { color: #94A3B8; flex-shrink: 0; }

    /* Generation mode cards — stacked white cards in the rail */
    .am-mode-group { display: flex; flex-direction: column; gap: 8px; }
    .am-mode-card {
      position: relative; display: flex; flex-direction: column; gap: 3px;
      padding: 11px 12px; border: 1.5px solid transparent; border-radius: 11px;
      cursor: pointer; transition: border-color 0.18s, box-shadow 0.18s;
      user-select: none; background: #FFFFFF; box-shadow: 0 1px 2px rgba(15,23,42,0.05);
    }
    .am-mode-card:hover { border-color: rgba(0,81,213,0.3); }
    .am-mode-card input { position: absolute; opacity: 0; pointer-events: none; }
    .am-mode-card.selected { border-color: #0051D5; box-shadow: 0 0 0 3px rgba(0,81,213,0.08); }
    .am-card-head { display: flex; align-items: center; gap: 7px; }
    .am-card-icon {
      width: 22px; height: 22px; border-radius: 6px; display: flex; align-items: center; justify-content: center;
      background: #F1F5F9; color: #64748B; transition: all 0.18s; flex-shrink: 0;
    }
    .am-mode-card.selected .am-card-icon { background: rgba(0,81,213,0.1); color: #0051D5; }
    .am-card-radio { width: 14px; height: 14px; border-radius: 50%; border: 1.5px solid #CBD5E1; margin-left: auto; flex-shrink: 0; transition: border 0.15s; box-sizing: border-box; }
    .am-mode-card.selected .am-card-radio { border: 4.5px solid #0051D5; }
    .am-card-title { font-size: 0.8rem; font-weight: 700; color: var(--text1); font-family: var(--font-ui); }
    .am-mode-card.selected .am-card-title { color: #0051D5; }
    .am-card-sub { font-size: 0.68rem; color: #64748B; line-height: 1.45; font-family: var(--font-ui); }

    /* Interview row — white card in the rail */
    .am-interview-row {
      display: flex; align-items: center; gap: 10px; padding: 10px 12px;
      border: 1.5px solid transparent; border-radius: 11px; cursor: pointer;
      transition: border-color 0.18s;
      background: #FFFFFF; box-shadow: 0 1px 2px rgba(15,23,42,0.05); position: relative;
    }
    .am-interview-row:hover { border-color: rgba(0,81,213,0.25); }
    .am-interview-row input[type=checkbox] { position: absolute; opacity: 0; pointer-events: none; }
    .am-interview-icon { width: 22px; height: 22px; border-radius: 6px; display: flex; align-items: center; justify-content: center; background: #F1F5F9; color: #64748B; transition: all 0.18s; flex-shrink: 0; }
    .am-interview-row.am-checked { border-color: #0051D5; }
    .am-interview-row.am-checked .am-interview-icon { background: rgba(0,81,213,0.1); color: #0051D5; }
    .am-interview-text { flex: 1; display: flex; flex-direction: column; gap: 1px; }
    .am-interview-title { font-size: 0.78rem; font-weight: 600; color: var(--text1); font-family: var(--font-ui); }
    .am-interview-sub { font-size: 0.66rem; color: #64748B; font-family: var(--font-ui); }
    .am-check-indicator { width: 16px; height: 16px; border-radius: 4px; border: 1.5px solid #CBD5E1; flex-shrink: 0; display: flex; align-items: center; justify-content: center; transition: all 0.18s; }
    .am-interview-row.am-checked .am-check-indicator { background: #0051D5; border-color: #0051D5; }

    /* Instructions accordion */
    .adv-settings { border: 1.5px solid #E2E8F0; border-radius: 10px; background: rgba(255,255,255,0.55); }
    .adv-settings-toggle { display: flex; align-items: center; gap: 0.5rem; padding: 0.65rem 0.875rem; font-size: 0.79rem; font-weight: 600; color: var(--text2); cursor: pointer; list-style: none; user-select: none; }
    .adv-settings-toggle::-webkit-details-marker { display: none; }
    .adv-settings[open] .adv-chevron { transform: rotate(180deg); }
    .adv-chevron { transition: transform 0.15s ease; flex-shrink: 0; color: #94A3B8; }
    .adv-settings-summary { margin-left: auto; font-size: 0.7rem; color: var(--text4); font-weight: 400; }
    .adv-settings[open] .adv-settings-summary { display: none; }
    .adv-settings-body { padding: 0 0.875rem 0.875rem; display: flex; flex-direction: column; gap: 0.75rem; }

    /* Section label */
    .add-section-label {
      display: flex; align-items: center; gap: 0.5rem;
      font-size: 0.6rem; font-weight: 700; text-transform: uppercase;
      letter-spacing: 0.1em; color: var(--text-muted);
      margin-top: 0.15rem; margin-bottom: -0.25rem;
    }
    .add-section-label::after { content: ''; flex: 1; height: 1px; background: rgba(193,199,211,0.5); }
    .add-optional-tag { font-weight: 400; font-size: 0.65rem; text-transform: none; letter-spacing: 0; color: var(--text4); }

    /* ID-scoped hide utility — wins over .btn-ghost { display:flex !important } */
    #modal-add .am-hidden { display: none !important; }

    /* Glass action bar */
    /* Mode switch at the top of the add-article modal. Two buttons rather than
       a <select>: the choice changes what the rest of the form means, and a
       collapsed dropdown hides that there is a second way to work at all. */
    .am-mode-opts { display:grid; grid-template-columns:1fr 1fr; gap:8px; }
    .am-mode-opt {
      display:flex; align-items:center; justify-content:center; gap:8px;
      padding:10px 12px; border:1.5px solid #E2E8F0; border-radius:10px;
      background:#FBFCFE; cursor:pointer; font-family:var(--font-ui);
      font-size:0.82rem; font-weight:600; color:var(--text2, #505F76);
      transition:border-color .15s, color .15s, background .15s;
    }
    .am-mode-opt:hover { color:var(--text1, #16233B); border-color:rgba(0,81,213,0.3); }
    .am-mode-opt.is-on {
      background:rgba(219,225,255,0.3); border-color:#0051D5; color:#0051D5;
    }
    .am-mode-opt svg { flex-shrink:0; }
    .review-meta-pill {
      display: inline-flex; align-items: center; gap: 0.2rem;
      font-family: var(--font-ui); font-size: 0.62rem; font-weight: 500;
      color: var(--text3); white-space: nowrap;
    }
    .review-meta-pill svg { opacity: 0.5; }
    .review-meta-sep {
      width: 2px; height: 2px; border-radius: 50%;
      background: var(--border2); flex-shrink: 0;
    }
    .tt-btn { font-family: var(--font-ui); font-size: 0.78rem; font-weight: 700; width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center; border-radius: 5px; border: none; background: none; color: var(--text-secondary, #505F76); cursor: pointer; transition: background 0.1s, color 0.1s; flex-shrink: 0; }
    .tt-btn:hover { background: var(--bg-elevated, #FFF); color: var(--text-primary, #191C1E); }
    .tt-btn.is-active { background: var(--brand-dim, #DBE1FF); color: var(--brand-accent, #003EA8); }
    .tt-btn:disabled { opacity: 0.4; cursor: default; }
    .tt-sep { width: 1px; height: 16px; background: var(--border, rgba(193,199,211,0.4)); margin: 0 3px; flex-shrink: 0; align-self: center; }
    /* ── Link editor popup ──────────────────────────────────────────────────── */
    #tt-link-popup { position: fixed; z-index: 1100; display: none; }
    .tt-link-popup-inner { display: flex; align-items: center; gap: 6px; padding: 8px 10px; background: var(--bg-elevated, #FFFFFF); border: 1px solid var(--brand-border, rgba(0,81,213,0.25)); border-radius: 10px; box-shadow: 0 4px 20px rgba(0,81,213,0.14); }
    .tt-link-popup-label { font-family: var(--font-ui); font-size: 0.72rem; font-weight: 700; color: var(--text-muted, #717783); white-space: nowrap; }
    #tt-link-input { font-family: var(--font-ui); font-size: 0.82rem; padding: 5px 9px; min-width: 220px; border: 1px solid var(--border-subtle, rgba(193,199,211,0.5)); border-radius: 6px; background: var(--bg-surface, #F2F4F6); color: var(--text-primary, #191C1E); outline: none; transition: border-color 0.15s, box-shadow 0.15s; }
    #tt-link-input:focus { border-color: var(--brand-primary, #0051D5); box-shadow: 0 0 0 3px rgba(0,81,213,0.10); background: #FFF; }
    .tt-link-btn { width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center; border-radius: 6px; border: 1px solid var(--border-subtle); background: none; cursor: pointer; flex-shrink: 0; transition: all 0.12s; }
    .tt-link-ok { border-color: var(--brand-primary, #0051D5); color: var(--brand-primary, #0051D5); }
    .tt-link-ok:hover { background: var(--brand-primary, #0051D5); color: #FFF; }
    .tt-link-cancel { color: var(--text-muted, #717783); }
    .tt-link-cancel:hover { border-color: #DC2626; color: #DC2626; }
    /* ── Link hover tooltip ─────────────────────────────────────────────────── */
    #tt-link-tooltip { position: fixed; z-index: 1100; display: none; }
    .tt-link-tooltip-inner { display: flex; align-items: center; gap: 4px; padding: 6px 10px; background: var(--bg-elevated, #FFFFFF); border: 1px solid var(--border-subtle, rgba(193,199,211,0.5)); border-radius: 8px; box-shadow: 0 4px 16px rgba(0,81,213,0.12); max-width: 380px; }
    .tt-link-tooltip-url { font-family: var(--font-ui); font-size: 0.78rem; color: var(--brand-primary, #0051D5); text-decoration: none; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 240px; }
    .tt-link-tooltip-url:hover { text-decoration: underline; }
    .tt-link-tooltip-sep { width: 1px; height: 14px; background: var(--border-subtle); flex-shrink: 0; margin: 0 2px; }
    .tt-link-tooltip-btn { display: inline-flex; align-items: center; gap: 4px; font-family: var(--font-ui); font-size: 0.75rem; font-weight: 600; padding: 3px 7px; border-radius: 5px; border: 1px solid var(--border-subtle); background: none; cursor: pointer; color: var(--text-secondary, #505F76); white-space: nowrap; flex-shrink: 0; transition: all 0.1s; }
    .tt-link-tooltip-btn:hover { background: var(--bg-surface, #F2F4F6); color: var(--text-primary); }
    .tt-link-tooltip-unlink:hover { border-color: #DC2626; color: #DC2626; }
    mark.internal-link { background: var(--indigo-light); color: var(--brand-accent); padding: 0.1em 0.35em; border-radius: 3px; font-size: 0.85em; font-style: normal; border: 1px solid var(--brand-border); }
    mark.needs-evidence { background: var(--amber-bg, #FDF5E6); color: var(--amber); padding: 0.1em 0.35em; border-radius: 3px; font-size: 0.85em; font-style: normal; border: 1px solid rgba(160, 94, 0, 0.25); }
    mark.needs-human-input { background: #FEE2E2; color: #991B1B; padding: 0.1em 0.4em; border-radius: 3px; font-size: 0.82em; font-style: normal; font-weight: 600; border: 1px solid rgba(153, 27, 27, 0.25); cursor: help; }
    mark.needs-human-input.ev-flag-focus { outline: 2px solid #DC2626; outline-offset: 2px; transition: outline-color 0.3s; }
    /* "À vérifier" checklist banner (editor, owner only) */
    #ev-flags-banner { display: none; flex-direction: column; gap: 2px; margin: 10px 24px 0; padding: 10px 14px; background: #FEF2F2; border: 1px solid rgba(153, 27, 27, 0.22); border-radius: 8px; font-family: var(--font-ui); }
    .ev-flags-title { font-size: 12px; font-weight: 700; color: #991B1B; margin-bottom: 4px; }
    .ev-flag-row { display: flex; align-items: center; gap: 8px; padding: 3px 0; font-size: 12px; color: #7F1D1D; min-width: 0; }
    .ev-flag-desc { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
    .ev-flag-btn { flex-shrink: 0; font-family: var(--font-ui); font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: 5px; border: 1px solid rgba(153, 27, 27, 0.3); background: #FFFFFF; color: #991B1B; cursor: pointer; }
    .ev-flag-btn:hover { background: #FEE2E2; }
    .table-wrap { overflow-x: auto; margin: 1rem 0; }
    .article-table { width: 100%; border-collapse: collapse; font-size: 0.875rem; max-width: 72ch; background: #FFFFFF; border-radius: 8px; overflow: hidden; box-shadow: 0 1px 3px rgba(0, 81, 213, 0.06); }
    .article-table th { background: var(--brand-dim); font-weight: 700; text-align: left; padding: 0.6rem 0.85rem; border: 1px solid var(--brand-border); color: var(--brand-accent); font-size: 0.82rem; }
    .article-table td { padding: 0.6rem 0.85rem; border: 1px solid var(--border-subtle); color: var(--text-primary); line-height: 1.5; background: #FFFFFF; }
    .article-table tr:nth-child(even) td { background: rgba(0, 81, 213, 0.06); }

    /* Review tab bar controls — keyword hidden (shown in article header instead) */
    .review-kw { display: none; }
    @keyframes sheetUp {
      from { transform: translateY(100%); }
      to { transform: translateY(0); }
    }
    .review-close-fixed { display: none; }

    .review-section { margin-bottom: 1.25rem; }
    .review-section-title { font-size: 0.65rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em; color: var(--text4); margin-bottom: 0.5rem; }
    .review-meta-text { font-size: 0.8rem; color: var(--text2); line-height: 1.55; font-style: italic; }
    .review-meta-chars { font-size: 0.68rem; color: var(--text4); margin-top: 0.35rem; }
    .seo-meta-field { margin-bottom: 0.75rem; }
    .seo-meta-field:last-child { margin-bottom: 0; }
    .seo-meta-label { font-size: 0.65rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text4); margin-bottom: 0.2rem; }
    .seo-meta-value { font-size: 0.8rem; color: var(--text2); line-height: 1.5; }
    .seo-meta-value.slug { font-family: var(--font-ui); font-size: 0.78rem; color: var(--brand-accent); background: var(--indigo-light); padding: 2px 6px; border-radius: 4px; display: inline-block; cursor: pointer; }
    .seo-meta-chars { font-size: 0.65rem; margin-top: 0.15rem; }
    .seo-chars-ok  { color: var(--green); }
    .seo-chars-warn { color: var(--amber); }
    .review-fc-badge { display: inline-flex; align-items: center; gap: 0.3rem; font-size: 0.75rem; font-weight: 600; padding: 3px 9px; border-radius: 6px; }
    .review-fc-badge.ok   { background: var(--green-bg); color: var(--green); }
    .review-fc-badge.warn { background: var(--amber-bg); color: var(--amber); }
    .review-fc-issues summary { font-size: 0.73rem; color: var(--text3); cursor: pointer; list-style: none; display: flex; align-items: center; gap: 0.3rem; margin-top: 0.4rem; }
    .review-fc-issues summary::before { content: "▶"; font-size: 0.55rem; }
    .vf-claim { padding: 8px 10px; margin-bottom: 6px; border-radius: 6px; border: 1px solid var(--border); cursor: pointer; transition: background 0.15s; font-size: 0.78rem; line-height: 1.45; }
    .vf-claim:hover { background: var(--bg-hover); }
    .vf-claim.active { border-color: var(--brand-primary); background: rgba(37,99,235,0.06); }
    .vf-claim-text { font-style: italic; color: var(--text-secondary); margin-bottom: 4px; }
    .vf-claim-finding { margin-top: 4px; }
    .vf-claim-correction { margin-top: 4px; padding: 4px 8px; background: #fef3c7; border-radius: 4px; font-size: 0.75rem; }
    .vf-badge { display: inline-block; font-size: 0.6rem; font-weight: 700; padding: 1px 6px; border-radius: 3px; text-transform: uppercase; letter-spacing: 0.5px; }
    .vf-badge.current { background: #d1fae5; color: #065f46; }
    .vf-badge.outdated { background: #fef3c7; color: #92400e; }
    .vf-badge.incorrect { background: #fee2e2; color: #991b1b; }
    .vf-badge.unverifiable { background: #e5e7eb; color: #4b5563; }
    .vf-check { float: right; cursor: pointer; font-size: 0.7rem; padding: 2px 8px; border: 1px solid var(--border); border-radius: 4px; background: var(--bg); }
    .vf-check:hover { background: #d1fae5; border-color: #065f46; }
    .vf-claim.checked { opacity: 0.5; border-style: dashed; }
    .vf-claim.checked .vf-check { background: #d1fae5; color: #065f46; }
    .vf-summary { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; padding: 8px; background: var(--bg-hover); border-radius: 6px; font-size: 0.72rem; }
    .vf-summary span { font-weight: 600; }
    mark.vf-highlight { background: #fef08a; padding: 1px 2px; border-radius: 2px; scroll-margin-top: 60px; }

    /* Category-tagged insight findings (CONTENT: ..., STRATEGIC: ..., etc.) */
    .ag-finding {
      display: flex; align-items: flex-start; gap: 0.65rem;
      padding: 0.7rem 0.8rem;
      margin-bottom: 0.45rem;
      background: var(--bg-elevated);
      border: 1px solid var(--border-subtle);
      border-radius: 10px;
      line-height: 1.6;
      transition: border-color 0.18s, box-shadow 0.18s;
    }
    .ag-finding:first-child { margin-top: 0; }
    .ag-finding:hover {
      border-color: var(--brand-border);
      box-shadow: 0 2px 10px rgba(0, 81, 213, 0.07);
    }
    .ag-finding-tag {
      flex-shrink: 0;
      font-family: var(--font-ui);
      font-size: 0.52rem; font-weight: 700;
      letter-spacing: 0.09em; text-transform: uppercase;
      padding: 0.22rem 0.5rem;
      border-radius: 5px;
      white-space: nowrap;
      margin-top: 0.12rem;
    }
    .ag-finding-text {
      font-family: var(--font-ui);
      font-size: 0.78rem; font-weight: 400;
      color: var(--text-primary);
      line-height: 1.65;
      min-width: 0;
    }
    .ag-finding-text strong { font-weight: 700; }

    /* Category pill colors */
    .ag-tag-content    { background: rgba(0, 81, 213, 0.10); color: #003EA8; }
    .ag-tag-strategic  { background: rgba(39, 174, 96, 0.12); color: #1B7E48; }
    .ag-tag-editorial  { background: rgba(243, 156, 18, 0.12); color: #926200; }
    .ag-tag-practical  { background: rgba(142, 124, 195, 0.14); color: #5B4A8C; }
    .ag-tag-factual    { background: rgba(231, 76, 60, 0.10); color: #B83224; }
    .ag-tag-structural { background: rgba(80, 95, 118, 0.12); color: #3C4A5C; }
    .ag-tag-technical  { background: rgba(0, 81, 213, 0.08); color: #0051D5; }
    .ag-tag-default    { background: var(--bg-surface); color: var(--text2); }

    /* ── Intel cards (Competitive Intel panel) ── */
    .intel-card { border: 1px solid var(--border); border-radius: 6px; margin-bottom: 0.6rem; background: var(--surface); overflow: hidden; border-left: 3px solid var(--intel-accent, var(--brand-primary)); }
    .intel-card-head { display: flex; align-items: center; gap: 0.6rem; padding: 0.7rem 0.9rem; cursor: pointer; user-select: none; transition: background 0.1s; }
    .intel-card-head:hover { background: var(--surface2, var(--bg-surface)); }
    .intel-card-icon { width: 28px; height: 28px; display: flex; align-items: center; justify-content: center; border-radius: 6px; background: color-mix(in srgb, var(--intel-accent) 12%, transparent); color: var(--intel-accent); flex-shrink: 0; }
    .intel-card-title-wrap { flex: 1; min-width: 0; }
    .intel-card-num { font-size: 0.62rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--intel-accent); display: block; line-height: 1; margin-bottom: 0.15rem; }
    .intel-card-title { font-size: 0.8rem; font-weight: 600; color: var(--text); line-height: 1.3; display: block; }
    .intel-card-chevron { flex-shrink: 0; color: var(--text4); transition: transform 0.2s; }
    .intel-card.collapsed .intel-card-chevron { transform: rotate(-90deg); }
    .intel-card-body { padding: 0 0.9rem 0.75rem; font-size: 0.78rem; line-height: 1.65; color: var(--text2); }
    .intel-card-body:not(.open) { display: none; }
    .intel-card-body p { margin-bottom: 0.5rem; }
    .intel-card-body ul { padding-left: 1.2rem; margin-bottom: 0.5rem; }
    .intel-card-body li { margin-bottom: 0.2rem; }
    .intel-preamble { font-size: 0.78rem; color: var(--text3); line-height: 1.6; margin-bottom: 0.75rem; padding: 0.6rem 0.8rem; background: var(--surface2, var(--bg-surface)); border-radius: 8px; }
    .intel-preamble p { margin-bottom: 0.3rem; }
    .intel-sub-label { font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; color: var(--intel-accent, var(--text2)); margin: 0.7rem 0 0.25rem; padding-bottom: 0.2rem; border-bottom: 1px solid var(--border); }

    /* ── SERP-style intel cards (Google-like per-website cards) ── */
    .intel-serp-section-label { font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text4); margin: 1.2rem 0 0.5rem; display: flex; align-items: center; gap: 0.5rem; }
    .intel-serp-section-label::after { content: ''; flex: 1; height: 1px; background: var(--border); }
    .intel-serp-item { border: 1px solid var(--border); border-radius: 6px; margin-bottom: 0.6rem; background: var(--surface); overflow: hidden; transition: box-shadow 0.15s; }
    .intel-serp-item:hover { box-shadow: var(--shadow-xs); }
    .intel-serp-item-head { padding: 0.75rem 0.9rem 0.5rem; }
    .intel-serp-item-brand { font-family: var(--font-ui); font-size: 0.68rem; font-weight: 600; color: var(--text3); display: flex; align-items: center; gap: 0.4rem; margin-bottom: 0.2rem; }
    .intel-serp-item-brand img { width: 16px; height: 16px; border-radius: 3px; }
    .intel-serp-item-title { font-family: var(--font-ui); font-size: 0.85rem; font-weight: 600; color: var(--brand-accent); line-height: 1.35; margin-bottom: 0.15rem; }
    .intel-serp-item-title a { color: inherit; text-decoration: none; }
    .intel-serp-item-title a:hover { text-decoration: underline; }
    .intel-serp-item-url { font-size: 0.68rem; color: var(--emerald, var(--green)); margin-bottom: 0.3rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .intel-serp-item-url a { color: inherit; text-decoration: none; }
    .intel-serp-item-url a:hover { text-decoration: underline; }
    .intel-serp-item-desc { font-family: var(--font-ui); font-size: 0.75rem; color: var(--text2); line-height: 1.5; padding: 0 0.9rem 0.6rem; }
    .intel-serp-item .serp-badge { font-size: 0.65rem; color: var(--text4); background: var(--surface2, var(--bg-surface)); padding: 0.15rem 0.45rem; border-radius: 4px; white-space: nowrap; }
    .intel-serp-item .serp-card-expand { display: none; margin-top: 0.5rem; padding: 0.5rem 0.9rem 0.6rem; border-top: 1px solid var(--border); }
    .intel-serp-item .serp-card-expand.open { display: block; }
    .intel-serp-item .serp-card-summary { font-size: 0.72rem; color: var(--text3); line-height: 1.5; margin-bottom: 0.5rem; }
    .intel-serp-item .serp-card-section-label { font-size: 0.65rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text4); margin-bottom: 0.3rem; }
    .intel-serp-item .serp-card-outline { list-style: none; padding: 0; margin: 0; }
    .intel-serp-item .serp-card-outline li { font-size: 0.72rem; color: var(--text3); padding: 0.15rem 0; padding-left: 0.5rem; border-left: 2px solid var(--border); line-height: 1.4; }
    .intel-serp-item .serp-card-outline li + li { margin-top: 0.1rem; }
    .intel-serp-item .serp-card-toggle { background: none; border: none; color: var(--brand-accent); font-size: 0.7rem; font-weight: 600; cursor: pointer; padding: 0.25rem 0.9rem 0.5rem; margin: 0; }
    .intel-serp-item .serp-card-toggle:hover { text-decoration: underline; }
    .intel-serp-item .serp-card-rank { font-size: 0.82rem; font-weight: 800; color: var(--brand-accent); background: var(--brand-dim); padding: 0.2rem 0; border-radius: 6px; min-width: 30px; text-align: center; display: inline-block; }
    /* ── Content Gaps section header ── */
    .content-gaps-header {
      display: flex; align-items: center; gap: 0.65rem;
      margin-bottom: 0.85rem; padding-bottom: 0.65rem;
      border-bottom: 1px solid var(--border-subtle);
    }
    .content-gaps-icon {
      width: 32px; height: 32px; border-radius: 9px;
      background: linear-gradient(135deg, rgba(0,81,213,0.12), rgba(49,107,243,0.06));
      display: flex; align-items: center; justify-content: center;
      color: var(--brand-primary); flex-shrink: 0;
    }
    .content-gaps-title-wrap { flex: 1; min-width: 0; }
    .content-gaps-title {
      font-family: var(--font-ui); font-size: 0.82rem; font-weight: 700;
      color: var(--text-primary); line-height: 1.2; margin: 0;
    }
    .content-gaps-subtitle {
      font-family: var(--font-ui); font-size: 0.62rem; font-weight: 400;
      color: var(--text4); line-height: 1.3; margin-top: 0.15rem;
    }
    .content-gaps-count {
      font-family: var(--font-ui); font-size: 0.62rem; font-weight: 700;
      color: var(--brand-primary); background: var(--brand-dim);
      padding: 0.2rem 0.55rem; border-radius: 999px;
      border: 1px solid var(--brand-border); flex-shrink: 0;
    }

    /* ── Gap cards ── */
    .intel-gap-card {
      border: 1px solid var(--border-subtle); border-radius: 12px;
      margin-bottom: 0.55rem; background: var(--bg-elevated);
      overflow: hidden;
      transition: border-color 0.2s, box-shadow 0.2s, transform 0.2s;
    }
    .intel-gap-card:hover {
      border-color: var(--brand-border);
      box-shadow: 0 3px 14px rgba(0, 81, 213, 0.08);
      transform: translateY(-1px);
    }
    .intel-gap-head {
      display: flex; align-items: center; gap: 0.55rem;
      padding: 0.75rem 0.9rem;
      cursor: pointer; user-select: none;
      transition: background 0.12s;
    }
    .intel-gap-head:hover { background: rgba(0, 81, 213, 0.025); }
    .intel-gap-num {
      width: 22px; height: 22px; border-radius: 7px;
      background: var(--intel-accent, var(--brand-primary));
      color: #fff; font-family: var(--font-ui);
      font-size: 0.58rem; font-weight: 800;
      display: flex; align-items: center; justify-content: center;
      flex-shrink: 0; letter-spacing: -0.02em;
      box-shadow: 0 1px 3px rgba(0,0,0,0.1);
    }
    .intel-gap-tag {
      font-family: var(--font-ui); font-size: 0.52rem; font-weight: 700;
      text-transform: uppercase; letter-spacing: 0.08em;
      padding: 0.18rem 0.45rem; border-radius: 5px; flex-shrink: 0;
    }
    .intel-gap-tag[data-type="factual"]      { background: rgba(231,76,60,0.10); color: #C0392B; }
    .intel-gap-tag[data-type="experiential"]  { background: rgba(243,156,18,0.12); color: #926200; }
    .intel-gap-tag[data-type="structural"]    { background: rgba(0,81,213,0.10); color: #003EA8; }
    .intel-gap-tag[data-type="opinion"]       { background: rgba(142,124,195,0.14); color: #5B4A8C; }
    .intel-gap-tag[data-type="coverage"]      { background: rgba(39,174,96,0.12); color: #1B7E48; }
    .intel-gap-tag[data-type="explanation"]   { background: rgba(26,95,160,0.10); color: #1A5FA0; }
    .intel-gap-tag[data-type="edge-case"]     { background: rgba(0,81,213,0.08); color: #0051D5; }
    .intel-gap-title {
      font-family: var(--font-ui); font-size: 0.8rem; font-weight: 600;
      color: var(--text-primary); flex: 1; line-height: 1.35; min-width: 0;
    }
    .intel-gap-chevron {
      flex-shrink: 0; color: var(--text4);
      transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
    }
    .intel-gap-card.collapsed .intel-gap-chevron { transform: rotate(-90deg); }
    .intel-gap-body {
      padding: 0 0.9rem 0.85rem 0.9rem;
      padding-left: calc(0.9rem + 22px + 0.55rem); /* align with title text */
      font-size: 0.76rem; color: var(--text2); line-height: 1.65;
      display: grid; grid-template-rows: 1fr;
      transition: grid-template-rows 0.3s ease, padding 0.3s ease, opacity 0.25s ease;
      opacity: 1;
    }
    .intel-gap-body:not(.open) {
      grid-template-rows: 0fr; padding-top: 0; padding-bottom: 0; opacity: 0;
      overflow: hidden;
    }
    .intel-gap-body > * { overflow: hidden; }
    .intel-gap-body p { margin-bottom: 0.45rem; }
    .intel-gap-why {
      font-size: 0.72rem; color: var(--brand-accent); line-height: 1.55;
      margin-top: 0.5rem; padding: 0.55rem 0.7rem;
      background:
        radial-gradient(circle at 100% 0%, rgba(0,81,213,0.05) 0%, transparent 50%),
        linear-gradient(180deg, rgba(0,81,213,0.035) 0%, rgba(0,81,213,0.015) 100%);
      border: 1px solid rgba(0, 81, 213, 0.1);
      border-radius: 8px;
      font-style: normal; font-weight: 500;
    }
    .intel-gap-why::before {
      content: 'Why it matters';
      display: block; font-size: 0.52rem; font-weight: 700;
      text-transform: uppercase; letter-spacing: 0.1em;
      color: var(--brand-primary); margin-bottom: 0.3rem;
      opacity: 0.7;
    }
    /* SERP visual cards */
    .serp-card { border: 1px solid var(--border); border-radius: 6px; padding: 1rem 1.1rem; margin-bottom: 0.75rem; background: var(--surface); transition: box-shadow 0.15s; }
    .serp-card:hover { box-shadow: var(--shadow-xs); }
    .serp-card-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.75rem; margin-bottom: 0.4rem; }
    .serp-card-rank { font-size: 0.82rem; font-weight: 800; color: var(--brand-accent); background: var(--brand-dim); padding: 0.2rem 0; border-radius: 6px; flex-shrink: 0; min-width: 30px; text-align: center; }
    .serp-card-title { font-size: 0.82rem; font-weight: 600; color: var(--text); line-height: 1.35; margin-bottom: 0.1rem; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
    .serp-card-url { font-size: 0.7rem; color: var(--brand-accent); text-decoration: none; display: inline-flex; align-items: center; gap: 0.2rem; }
    .serp-card-url:hover { text-decoration: underline; color: var(--brand-hover); }
    .serp-card-badges { display: flex; gap: 0.35rem; flex-shrink: 0; }
    .serp-badge { font-size: 0.65rem; color: var(--text4); background: var(--surface2, var(--bg-surface)); padding: 0.15rem 0.45rem; border-radius: 4px; white-space: nowrap; }
    .serp-card-meta { font-size: 0.72rem; color: var(--text4); margin-bottom: 0.35rem; line-height: 1.45; border-left: 2px solid var(--border); padding-left: 0.5rem; font-style: italic; }
    .serp-card-expand { display: none; margin-top: 0.5rem; padding-top: 0.5rem; border-top: 1px solid var(--border); }
    .serp-card-expand.open { display: block; }
    .serp-card-summary { font-size: 0.72rem; color: var(--text3); line-height: 1.5; margin-bottom: 0.5rem; }
    .serp-card-section-label { font-size: 0.65rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text4); margin-bottom: 0.3rem; }
    .serp-card-outline { list-style: none; padding: 0; margin: 0; }
    .serp-card-outline li { font-size: 0.72rem; color: var(--text3); padding: 0.15rem 0; padding-left: 0.5rem; border-left: 2px solid var(--border); line-height: 1.4; }
    .serp-card-outline li + li { margin-top: 0.1rem; }
    .serp-card-toggle { background: none; border: none; color: var(--brand-accent); font-size: 0.7rem; font-weight: 600; cursor: pointer; padding: 0.25rem 0; margin-top: 0.25rem; }
    .serp-card-toggle:hover { text-decoration: underline; }
    /* Fact-check stat cards */
    .fact-check-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; }
    @media (max-width: 600px) { .fact-check-grid { grid-template-columns: 1fr; } }
    .fact-check-card { border: 1px solid var(--border); border-radius: 6px; padding: 0.75rem 0.85rem; background: var(--surface); display: flex; flex-direction: column; gap: 0.3rem; }
    .fact-check-card-stat { font-family: var(--font-ui); font-size: 0.8rem; font-weight: 600; color: var(--text); line-height: 1.4; }
    .fact-check-card-ctx { font-family: var(--font-ui); font-size: 0.7rem; color: var(--text4); line-height: 1.4; }
    .fact-check-card-foot { display: flex; align-items: center; gap: 0.5rem; margin-top: auto; padding-top: 0.3rem; border-top: 1px solid var(--border); }
    .fact-check-card-src { font-size: 0.65rem; color: var(--text4); }
    .fact-check-card-link { font-size: 0.65rem; color: var(--brand-accent); text-decoration: none; display: inline-flex; align-items: center; gap: 0.2rem; margin-left: auto; }
    .fact-check-card-link:hover { text-decoration: underline; }
    /* Confidence badges */
    .ag-badge { font-family: var(--font-ui); font-size: 0.6rem; font-weight: 700; padding: 1px 6px; border-radius: 3px; text-transform: uppercase; letter-spacing: 0.05em; display: inline-flex; align-items: center; line-height: 1.4; vertical-align: middle; margin-left: 0.3rem; }
    .ag-badge-ok { background: var(--green-bg); color: var(--green); }
    .ag-badge-mid { background: var(--amber-bg); color: var(--amber); }
    .ag-badge-warn { background: var(--red-bg); color: var(--red); }

    /* ==================== AEO (AI Visibility) ==================== */
    /* Ported from Plume AEO design bundle 2026-04-23. Scoped under #view-aeo
       so the rest of the dashboard keeps its existing tokens. Article-list
       row annotations (.eng-badge-cluster) keep their own treatment. */

    #view-aeo {
      /* Plume palette (aligned with --brand-primary, --text-*, etc.) */
      --aeo-accent:      #0051D5;  /* Plume brand primary */
      --aeo-accent-2:    #003EA8;  /* Plume brand accent */
      --aeo-accent-soft: #DBE1FF;  /* Plume brand-dim */
      --aeo-ink:         #191C1E;  /* Plume text-primary */
      --aeo-ink-2:       #191C1E;
      --aeo-ink-3:       #505F76;  /* Plume text-secondary */
      --aeo-ink-4:       #717783;  /* Plume text-muted */
      --aeo-rule:        rgba(193, 199, 211, 0.30);  /* Plume border-subtle */
      --aeo-rule-2:      rgba(193, 199, 211, 0.60);  /* Plume border-default */
      --aeo-paper:       #FFFFFF;  /* bg-elevated */
      --aeo-paper-2:     #F7F9FB;  /* bg-base */
      --aeo-card:        #FFFFFF;
      --aeo-sage:        #1A7F5A;  /* Plume --green (darker, matches .ag-badge-ok) */
      --aeo-sage-soft:   rgba(26, 127, 90, 0.12);
      --aeo-gold:        #A05E00;  /* Plume --amber */
      --aeo-gold-soft:   rgba(160, 94, 0, 0.12);
      --aeo-red:         #C0392B;  /* Plume --red */
      --aeo-red-soft:    rgba(192, 57, 43, 0.10);
      --aeo-shadow:      rgba(0, 81, 213, 0.04);
      --aeo-shadow-hover: rgba(0, 81, 213, 0.10);
      --aeo-mono: var(--font-code);

      background: var(--aeo-paper-2);
      color: var(--aeo-ink);
      font-family: var(--font-ui);
      font-size: 13px;
      line-height: 1.45;
      /* Override .view { overflow: hidden; flex: 1 } so this page can scroll */
      overflow-y: auto;
      overflow-x: hidden;
    }
    #view-aeo button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; padding: 0; }
    #view-aeo .aeo-caps {
      text-transform: uppercase; letter-spacing: 0.12em;
      font-size: 10.5px; font-weight: 500; color: var(--aeo-ink-3);
    }
    #view-aeo .aeo-mono { font-family: var(--aeo-mono); font-variant-numeric: tabular-nums; }

    /* Hero */
    #view-aeo .aeo-hero {
      padding: 32px 32px 20px; background: var(--aeo-paper);
    }
    #view-aeo .aeo-hero-row { display:flex; align-items:flex-end; gap:24px; }
    #view-aeo .aeo-hero-brand-picker-wrap {
      display:inline-flex; align-items:center; margin-bottom: 14px;
    }
    #view-aeo .aeo-brand-select {
      display:inline-flex; align-items:center;
      appearance: none; -webkit-appearance: none;
      background: var(--aeo-paper);
      border: 1px solid var(--aeo-rule-2);
      border-radius: 8px;
      padding: 6px 32px 6px 12px;
      font-family: var(--font-ui);
      font-size: 12.5px; font-weight: 500;
      color: var(--aeo-ink);
      cursor: pointer;
      background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6' fill='none'><path d='M1 1l4 4 4-4' stroke='%23505F76' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/></svg>");
      background-repeat: no-repeat;
      background-position: right 10px center;
      background-size: 10px;
      transition: border-color 120ms ease;
    }
    #view-aeo .aeo-brand-select:hover { border-color: var(--aeo-ink-3); }
    #view-aeo .aeo-brand-select:focus { outline: none; border-color: var(--aeo-accent); }
    #view-aeo .aeo-brand-select option { font-family: var(--font-ui); font-size: 13px; color: var(--aeo-ink); background: var(--aeo-paper); }
    #view-aeo .aeo-hero h2 {
      margin: 0; font-size: 38px; font-weight: 700;
      letter-spacing: -1.2px; line-height: 1.05; color: var(--aeo-ink);
      font-family: var(--font-ui);
    }
    #view-aeo .aeo-hero h2 .accent {
      /* Plume's primary gradient (same as .btn-primary) */
      background: linear-gradient(135deg, #0051D5 0%, #316BF3 100%);
      -webkit-background-clip: text; -webkit-text-fill-color: transparent;
      background-clip: text;
    }
    #view-aeo .aeo-hero-sub {
      margin-top: 12px; font-size: 14px; color: var(--aeo-ink-3);
      max-width: 640px; line-height: 1.55;
    }
    #view-aeo .aeo-hero-sub .delta { color: var(--aeo-sage); font-weight: 600; }
    #view-aeo .aeo-hero-actions { display:flex; gap:8px; }

    /* Ghost + primary buttons (scoped) */
    #view-aeo .aeo-ghost-btn {
      display:inline-flex; align-items:center; gap:6px;
      padding: 7px 12px; border: 1px solid var(--aeo-rule-2); border-radius: 8px;
      background: var(--aeo-paper); color: var(--aeo-ink-2);
      font-size: 12.5px; font-weight: 500;
    }
    #view-aeo .aeo-ghost-btn:hover { border-color: var(--aeo-ink-3); }
    #view-aeo .aeo-primary-btn {
      padding: 8px 16px;
      background: linear-gradient(135deg, #0051D5 0%, #316BF3 100%);
      color: #fff;
      border-radius: 10px; font-size: 12.5px; font-weight: 600;
      box-shadow: 0 2px 6px rgba(0,81,213,0.18);
      transition: transform 120ms ease, box-shadow 120ms ease;
    }
    #view-aeo .aeo-primary-btn:hover { transform: translateY(-1px); box-shadow: 0 4px 10px rgba(0,81,213,0.28); }
    #view-aeo .aeo-primary-btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }

    /* Fact strip */
    #view-aeo .aeo-facts {
      margin: 0 32px; padding: 14px 20px;
      background: var(--aeo-paper-2);
      border: 1px solid var(--aeo-rule); border-radius: 10px;
      display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px;
    }
    #view-aeo .aeo-fact { display:flex; align-items:baseline; gap:10px; }
    #view-aeo .aeo-fact .label { min-width: 112px; }
    #view-aeo .aeo-fact .value {
      font-size: 16px; font-weight: 700; color: var(--aeo-ink);
      font-variant-numeric: tabular-nums;
    }
    #view-aeo .aeo-fact .sub { font-size: 11.5px; color: var(--aeo-ink-4); }

    /* Panel grid container */
    #view-aeo .aeo-body { padding: 24px 32px; display: grid; gap: 20px; }
    #view-aeo .aeo-two-col { display:grid; grid-template-columns: 1fr 320px; gap: 20px; }
    #view-aeo .aeo-half-col { display:grid; grid-template-columns: 1fr 1fr; gap: 20px; }
    #view-aeo .aeo-card {
      background: var(--aeo-card);
      border: 1px solid var(--aeo-rule);
      border-radius: 10px;
      padding: 22px;
    }
    #view-aeo .aeo-section-head {
      display:flex; align-items:baseline; gap:16px; margin-bottom: 16px;
    }
    #view-aeo .aeo-section-head .title {
      font-size: 20px; font-weight: 600; letter-spacing: -0.3px; color: var(--aeo-ink);
      flex: 1;
    }
    #view-aeo .aeo-section-head .title .muted {
      color: var(--aeo-ink-4); font-weight: 400; font-size: 18px;
    }
    #view-aeo .aeo-section-head .eyebrow { margin-bottom: 6px; }

    /* KPI strip */
    #view-aeo .aeo-kpi-strip {
      display: grid; grid-template-columns: repeat(4, 1fr);
      border: 1px solid var(--aeo-rule); border-radius: 6px;
      background: var(--aeo-card); overflow: hidden;
    }
    #view-aeo .aeo-kpi {
      padding: 18px 22px; position: relative;
      border-right: 1px solid var(--aeo-rule);
    }
    #view-aeo .aeo-kpi:last-child { border-right: none; }
    #view-aeo .aeo-kpi-label { margin-bottom: 10px; }
    #view-aeo .aeo-kpi-row { display:flex; align-items:baseline; gap:8px; }
    #view-aeo .aeo-kpi-val {
      font-size: 34px; font-weight: 600; line-height: 1;
      letter-spacing: -1px; color: var(--aeo-ink);
      font-variant-numeric: tabular-nums;
    }
    #view-aeo .aeo-kpi-val .unit {
      font-size: 18px; color: var(--aeo-ink-3); margin-left: 2px; font-weight: 500;
    }
    #view-aeo .aeo-kpi-hint { font-size: 11.5px; color: var(--aeo-ink-3); margin-top: 8px; }
    #view-aeo .aeo-delta { font-family: var(--aeo-mono); font-size: 11.5px; }
    #view-aeo .aeo-delta.up { color: var(--aeo-sage); }
    #view-aeo .aeo-delta.down { color: var(--aeo-red); }
    #view-aeo .aeo-delta.zero { color: var(--aeo-ink-4); }

    /* Pills */
    #view-aeo .aeo-pill {
      display:inline-flex; align-items:center; gap:5px;
      padding: 2px 8px 3px;
      border: 1px solid var(--aeo-rule); background: #f2f4f6; color: var(--aeo-ink-2);
      border-radius: 999px; font-size: 10.5px; font-weight: 500;
      letter-spacing: 0.3px; line-height: 1.2; white-space: nowrap;
    }
    #view-aeo .aeo-pill-accent { background: var(--aeo-accent-soft); color: var(--aeo-accent-2); border-color: var(--aeo-accent-soft); }
    #view-aeo .aeo-pill-sage { background: var(--aeo-sage-soft); color: #0f5132; border-color: var(--aeo-sage-soft); }
    #view-aeo .aeo-pill-gold { background: var(--aeo-gold-soft); color: #8a6500; border-color: var(--aeo-gold-soft); }
    #view-aeo .aeo-pill-red { background: var(--aeo-red-soft); color: #a23a31; border-color: var(--aeo-red-soft); }

    /* Visibility chart container */
    #view-aeo .aeo-vis-panel-grid { display:grid; grid-template-columns: 1fr 180px; gap: 28px; align-items:center; }
    #view-aeo .aeo-range-tabs { display:flex; gap: 6px; }
    #view-aeo .aeo-range-tabs button {
      padding: 4px 10px; font-size: 11px; color: var(--aeo-ink-3);
      border-bottom: 1px solid transparent; font-family: var(--aeo-mono);
    }
    #view-aeo .aeo-range-tabs button.active { color: var(--aeo-ink); border-bottom-color: var(--aeo-accent); }
    #view-aeo .aeo-legend button {
      display:grid; width:100%;
      grid-template-columns: 10px 1fr auto; gap:8px; align-items:center;
      padding: 6px 0; border-bottom: 1px solid var(--aeo-rule);
      text-align: left;
      transition: opacity 0.15s;
    }
    #view-aeo .aeo-legend button .dot {
      display:inline-block; width:8px; height:8px; border-radius:999px;
    }
    #view-aeo .aeo-legend button .aeo-legend-fav {
      display:inline-block; width: 14px; height: 14px;
      border-radius: 3px; object-fit: contain;
      grid-column: 1 / 2;
    }
    #view-aeo .aeo-legend button { grid-template-columns: 14px 1fr auto; }
    #view-aeo .aeo-legend button .name { font-size:12px; color: var(--aeo-ink); }
    #view-aeo .aeo-legend button .val { font-family: var(--aeo-mono); font-size:11px; color: var(--aeo-ink-2); }
    #view-aeo .aeo-legend.highlight-active button { opacity: 0.45; }
    #view-aeo .aeo-legend.highlight-active button.on { opacity: 1; }

    /* Competitor share bars */
    #view-aeo .aeo-share-row {
      display:grid; grid-template-columns: 120px 1fr 52px 48px;
      gap: 12px; align-items:center; padding: 9px 0;
      border-bottom: 1px solid var(--aeo-rule);
    }
    #view-aeo .aeo-share-row:last-child { border-bottom: none; }
    #view-aeo .aeo-share-name {
      font-size: 12.5px; color: var(--aeo-ink); font-weight: 450;
      display: inline-flex; align-items: center; gap: 8px; min-width: 0;
    }
    #view-aeo .aeo-share-name .aeo-fav {
      flex-shrink: 0; width: 16px; height: 16px;
      border-radius: 3px; background: var(--aeo-paper-2);
      object-fit: contain;
    }
    #view-aeo .aeo-share-name .aeo-fav-fb {
      flex-shrink: 0; width: 16px; height: 16px;
      border-radius: 3px; background: var(--aeo-rule-2);
      display: inline-block;
    }
    #view-aeo .aeo-share-name .label {
      overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }
    #view-aeo .aeo-share-name.brand .label {
      color: var(--aeo-accent-2); font-weight: 500;
      font-family: var(--font-display); font-style: italic;
    }
    #view-aeo .aeo-share-bar { position: relative; height: 14px; }
    #view-aeo .aeo-share-bar .fill {
      position: absolute; left: 0; top: 4px; height: 6px;
      opacity: 0.35; border-radius: 1px;
    }
    #view-aeo .aeo-share-bar .fill.brand { opacity: 1; }
    #view-aeo .aeo-share-val { font-family: var(--aeo-mono); font-size: 11.5px; color: var(--aeo-ink-2); text-align: right; font-variant-numeric: tabular-nums; }
    #view-aeo .aeo-share-foot {
      margin-top: 16px; font-size: 11px; color: var(--aeo-ink-3);
      border-top: 1px dashed var(--aeo-rule); padding-top: 12px;
    }

    /* Opportunities list */
    #view-aeo .aeo-opp-row {
      display: grid; grid-template-columns: 28px 1fr 110px;
      gap: 14px; padding: 14px 0;
      border-bottom: 1px solid var(--aeo-rule);
      align-items: start;
    }
    #view-aeo .aeo-opp-row:last-child { border-bottom: none; }
    #view-aeo .aeo-opp-num {
      font-size: 13px; color: var(--aeo-accent); font-weight: 600;
      font-family: var(--aeo-mono); margin-top: 2px;
    }
    #view-aeo .aeo-opp-title { font-size: 13.5px; color: var(--aeo-ink); margin-bottom: 4px; line-height: 1.4; }
    #view-aeo .aeo-opp-reason { font-size: 11.5px; color: var(--aeo-ink-3); }
    #view-aeo .aeo-opp-meta { display:flex; flex-direction: column; gap: 4px; align-items: flex-end; }
    #view-aeo .aeo-opp-meta .effort { font-size: 10.5px; color: var(--aeo-ink-4); }

    /* Coverage matrix */
    #view-aeo .aeo-cov-header, #view-aeo .aeo-cov-row {
      display: grid;
      grid-template-columns: 1fr 70px 60px repeat(3, 30px) 50px 60px;
      gap: 0; padding: 10px 0;
      align-items: center;
    }
    #view-aeo .aeo-cov-header {
      padding: 0 0 10px;
      border-bottom: 1px solid var(--aeo-rule-2);
      font-size: 10px; color: var(--aeo-ink-3);
      letter-spacing: 1px; text-transform: uppercase; font-weight: 500;
    }
    #view-aeo .aeo-cov-row { border-bottom: 1px solid var(--aeo-rule); font-size: 12.5px; }
    #view-aeo .aeo-cov-row:last-child { border-bottom: none; }
    #view-aeo .aeo-cov-row .q { padding-right: 12px; color: var(--aeo-ink); font-weight: 450; line-height: 1.35; }
    #view-aeo .aeo-cov-row .vol { font-family: var(--aeo-mono); text-align: right; color: var(--aeo-ink-2); font-size: 11.5px; font-variant-numeric: tabular-nums; }
    #view-aeo .aeo-cov-row .intent { text-align: center; font-size: 10.5px; color: var(--aeo-ink-3); font-style: italic; }
    #view-aeo .aeo-cov-row .eng { display:flex; justify-content: center; }
    #view-aeo .aeo-cov-row .pos-col {
      text-align: right; display:flex; align-items:center; justify-content: flex-end; gap: 6px;
      font-family: var(--aeo-mono); color: var(--aeo-ink); font-size: 12px;
    }
    #view-aeo .aeo-cov-row .action-col { text-align: right; }
    #view-aeo .aeo-cov-gen-btn {
      padding: 4px 10px; border-radius: 6px;
      background: linear-gradient(135deg, #0051D5 0%, #316BF3 100%);
      color: #fff;
      font-size: 11px; font-weight: 600; white-space: nowrap;
      box-shadow: 0 1px 2px rgba(0,81,213,0.15);
    }
    #view-aeo .aeo-cov-gen-btn:hover { box-shadow: 0 2px 6px rgba(0,81,213,0.25); }
    #view-aeo .aeo-cov-filter-strip {
      display:flex; gap: 14px; margin-bottom: 14px; align-items: center;
    }
    #view-aeo .aeo-cov-filter-strip button {
      font-size: 11px; color: var(--aeo-ink-3);
      border-bottom: 1px solid transparent; padding-bottom: 2px;
      letter-spacing: 0.2px;
    }
    #view-aeo .aeo-cov-filter-strip button.active {
      color: var(--aeo-ink); border-bottom-color: var(--aeo-accent); font-weight: 600;
    }
    #view-aeo .aeo-cov-legend {
      display:flex; gap: 14px; font-size: 11px; color: var(--aeo-ink-3); margin-left: auto;
    }
    #view-aeo .aeo-cov-legend span { display:inline-flex; align-items:center; gap: 5px; }

    /* Coverage-matrix status dot (cited / absent) */
    #view-aeo .aeo-status-dot {
      display:inline-block; width: 9px; height: 9px; border-radius: 999px;
    }
    #view-aeo .aeo-status-dot.cited { background: var(--aeo-accent); }
    #view-aeo .aeo-status-dot.mentioned { background: var(--aeo-gold); }
    #view-aeo .aeo-status-dot.absent { background: transparent; border: 1px solid var(--aeo-rule-2); }

    /* Activity rail */
    #view-aeo .aeo-rail { position:relative; padding-left: 14px; }
    #view-aeo .aeo-rail::before {
      content:""; position:absolute; left: 3px; top: 6px; bottom: 6px;
      width: 1px; background: var(--aeo-rule);
    }
    #view-aeo .aeo-rail-item { position:relative; padding: 6px 0 10px; }
    #view-aeo .aeo-rail-item::before {
      content:""; position:absolute; left: -14px; top: 9px;
      width: 7px; height: 7px; border-radius: 999px;
      background: var(--aeo-ink-3); border: 2px solid var(--aeo-card);
      box-shadow: 0 0 0 1px var(--aeo-rule);
    }
    #view-aeo .aeo-rail-item.event-cited::before { background: var(--aeo-sage); }
    #view-aeo .aeo-rail-item.event-mentioned::before { background: var(--aeo-gold); }
    #view-aeo .aeo-rail-item.event-lost::before { background: var(--aeo-red); }
    #view-aeo .aeo-rail-head { display:flex; align-items:baseline; gap:8px; }
    #view-aeo .aeo-rail-when { font-family: var(--aeo-mono); font-size: 10.5px; color: var(--aeo-ink-4); width: 26px; }
    #view-aeo .aeo-rail-engine { font-size: 11px; color: var(--aeo-ink-3); }
    #view-aeo .aeo-rail-detail { font-size: 12px; color: var(--aeo-ink-2); margin-top: 3px; margin-left: 34px; line-height: 1.4; }

    /* Citations feed */
    #view-aeo .aeo-cite {
      padding: 12px 0; border-bottom: 1px solid var(--aeo-rule);
    }
    #view-aeo .aeo-cite:last-child { border-bottom: none; }
    #view-aeo .aeo-cite-head { display:flex; align-items:center; gap: 8px; margin-bottom: 4px; }
    #view-aeo .aeo-cite-head .dot { width:6px; height:6px; border-radius:999px; display:inline-block; }
    #view-aeo .aeo-cite-eng-fav {
      width: 14px; height: 14px; border-radius: 3px;
      object-fit: contain; flex-shrink: 0;
    }
    #view-aeo .aeo-cite-engine { font-size: 11px; color: var(--aeo-ink-3); }
    #view-aeo .aeo-cite-date { margin-left: auto; font-family: var(--aeo-mono); font-size: 10.5px; color: var(--aeo-ink-4); }
    #view-aeo .aeo-cite-title { font-size: 12.5px; color: var(--aeo-ink); line-height: 1.4; margin-bottom: 4px; }
    #view-aeo .aeo-cite-foot { display:flex; justify-content: space-between; align-items: center; gap: 8px; }
    #view-aeo .aeo-cite-url-wrap {
      display:inline-flex; align-items:center; gap: 6px;
      min-width: 0; flex: 1;
    }
    #view-aeo .aeo-cite-dom-fav {
      width: 12px; height: 12px; border-radius: 2px;
      object-fit: contain; flex-shrink: 0;
    }
    #view-aeo .aeo-cite-url { font-family: var(--aeo-mono); font-size: 10.5px; color: var(--aeo-ink-4); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    #view-aeo .aeo-cite-count { font-family: var(--aeo-mono); font-size: 10.5px; color: var(--aeo-ink-3); flex-shrink: 0; }

    /* Empty state (no data yet) */
    #view-aeo .aeo-empty-dashboard {
      padding: 56px 32px; text-align: center; color: var(--aeo-ink-3);
    }
    #view-aeo .aeo-empty-dashboard h3 {
      font-family: var(--font-display); font-size: 1.4rem; font-weight: 600; color: var(--aeo-ink);
      margin: 0 0 10px;
    }

    /* Responsive collapse */
    @media (max-width: 1100px) {
      #view-aeo .aeo-two-col,
      #view-aeo .aeo-half-col { grid-template-columns: 1fr; }
      #view-aeo .aeo-kpi-strip { grid-template-columns: 1fr 1fr; }
      #view-aeo .aeo-kpi:nth-child(2n) { border-right: none; }
      #view-aeo .aeo-facts { grid-template-columns: 1fr 1fr; }
    }

    /* === Article-list column micro-badges (unchanged from V1) === */
    .eng-badge-cluster { display:inline-flex; gap:4px; align-items:center; }
    .eng-badge {
      display:inline-flex; width:24px; height:24px; border-radius:4px;
      font-family: var(--font-code); font-size:11px; font-weight:600;
      align-items:center; justify-content:center;
      line-height:1; user-select:none; cursor:help;
      position:relative;
    }
    .eng-badge-cited    { background: var(--green-bg); color: var(--green); }
    .eng-badge-miss     { background: transparent; color: var(--text-muted); border: 1px solid var(--border-default); }
    .eng-badge-pending  { background: transparent; color: var(--text-muted); opacity: 0.6; border: 1px solid var(--border-subtle); }
    .eng-badge-skipped  { background: transparent; color: var(--amber); border: 1px solid var(--amber); }
    .eng-badge-skipped::after {
      content:""; position:absolute; top:2px; right:2px; width:4px; height:4px;
      border-radius:50%; background: var(--amber);
    }
    /* Mobile aggregate pill (shown under 768px in place of the 3-badge cluster) */
    .eng-badge-aggregate {
      display:inline-flex; gap:4px; align-items:center;
      padding: 2px 8px; border-radius: 999px;
      background: var(--bg-surface); color: var(--text-secondary);
      font-family: var(--font-ui); font-size: 11px; font-weight: 600;
    }
    @media (max-width: 768px) {
      .eng-badge-cluster { display:none; }
      .eng-badge-aggregate.eng-badge-aggregate--mobile { display:inline-flex; }
    }
    .eng-badge-aggregate--mobile { display:none; }

    /* Win pulse — applied when a ✗→✓ flip happened this week (Pass 3). */
    @keyframes eng-win-pulse {
      0%   { box-shadow: 0 0 0 0 rgba(26, 127, 90, 0.35); }
      70%  { box-shadow: 0 0 0 6px rgba(26, 127, 90, 0); }
      100% { box-shadow: 0 0 0 0 rgba(26, 127, 90, 0); }
    }
    .eng-badge--new-this-week { animation: eng-win-pulse 1.8s ease-out 3; }
    @media (prefers-reduced-motion: reduce) { .eng-badge--new-this-week { animation: none; } }

    /* AEO prompt row card (AI Visibility page). Matches .al-row aesthetic. */
    .aeo-prompt-row {
      background: var(--bg-elevated);
      border: 1px solid var(--border-subtle);
      border-radius: 16px;
      padding: var(--space-4) var(--space-6);
      margin-bottom: var(--space-3);
      box-shadow: 0 1px 2px rgba(0,81,213,0.04);
      transition: transform 120ms ease, box-shadow 120ms ease;
    }
    .aeo-prompt-row:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(0,81,213,0.08); }
    .aeo-prompt-row.aeo-paused { opacity: 0.6; }
    .aeo-prompt-row-head { display:flex; align-items:flex-start; justify-content:space-between; gap: var(--space-3); }
    .aeo-prompt-text { font-family: var(--font-body); font-size: var(--text-lg); font-weight: 600; color: var(--text-primary); line-height: 1.35; word-break: break-word; flex:1; }
    .aeo-prompt-meta { font-family: var(--font-body); font-size: var(--text-sm); color: var(--text-muted); margin-top: 4px; }
    .aeo-prompt-engines { margin-top: var(--space-3); display:flex; gap: var(--space-6); align-items:center; flex-wrap: wrap; }
    .aeo-prompt-competitors {
      font-family: var(--font-code); font-size: var(--text-sm);
      color: var(--text-secondary); margin-top: var(--space-3);
      display:flex; align-items:center; gap:6px; flex-wrap:wrap;
    }
    .aeo-comp-fav { width:14px; height:14px; border-radius: 3px; flex-shrink:0; }
    .aeo-comp-fav-fallback {
      width:14px; height:14px; border-radius:3px;
      background: var(--border-subtle);
      display:inline-block;
    }
    .aeo-all-cited-chip {
      font-family: var(--font-body); font-size: 13px;
      color: var(--green); font-weight: 600;
      display:inline-flex; align-items:center; gap: 6px; margin-top: var(--space-3);
    }
    .aeo-prompt-footer { margin-top: var(--space-3); display:flex; align-items:center; justify-content:space-between; gap: var(--space-3); }
    .aeo-sparkline { display:inline-flex; align-items:flex-end; gap: 2px; height: 24px; }
    .aeo-sparkline-bar { width: 6px; background: var(--border-strong); border-radius: 1px; min-height: 2px; }
    .aeo-sparkline-bar.cited { background: var(--brand-primary); }
    .aeo-sparkline-label { font-family: var(--font-body); font-size: var(--text-xs); color: var(--text-muted); margin-left: 8px; }
    .aeo-generate-btn {
      font-family: var(--font-ui); font-size: 13px; font-weight: 600;
      padding: 8px 16px; border-radius: 12px; border: none;
      background: linear-gradient(135deg, #0051D5, #316BF3); color: #FFFFFF;
      cursor: pointer; box-shadow: 0 2px 6px rgba(0,81,213,0.18);
      transition: transform 120ms ease, box-shadow 120ms ease;
      white-space: nowrap;
    }
    .aeo-generate-btn:hover { transform: translateY(-1px); box-shadow: 0 4px 10px rgba(0,81,213,0.28); }
    .aeo-generate-btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none; box-shadow: none; }

    /* Starter banner (dismissible) */
    .aeo-starter-banner {
      background: var(--brand-dim, #DBE1FF);
      border: 1px solid var(--border-subtle);
      border-radius: 12px;
      padding: 12px 16px;
      margin-bottom: var(--space-4);
      display:flex; align-items:flex-start; gap: var(--space-3);
      font-family: var(--font-body); font-size: var(--text-base);
      color: var(--text-primary);
    }
    .aeo-starter-banner-close {
      background: transparent; border: none; cursor: pointer; color: var(--text-muted); font-size: 20px; line-height: 1; padding: 0 4px;
    }

    /* Empty state */
    .aeo-empty { text-align: center; padding: 48px 24px; color: var(--text-muted); }
    .aeo-empty h3 { font-family: var(--font-display); font-size: 1.2rem; font-weight: 600; color: var(--text-primary); margin: 0 0 8px; }

    /* Amber-skipped icon (tooltip marker on prompt row) */
    .aeo-skip-icon {
      display:inline-flex; align-items:center; justify-content:center;
      width:18px; height:18px; border-radius: 50%; background: var(--amber-bg); color: var(--amber);
      font-size: 11px; font-weight: 700; font-family: var(--font-code);
      margin-left: 8px; cursor: help;
    }

    /* === Setup wizard === */
    #view-aeo .aeo-setup-card {
      background: var(--aeo-card);
      border: 1px solid var(--aeo-rule);
      border-radius: 16px;
      padding: 40px 32px;
      margin: 32px;
      text-align: center;
      box-shadow: 0 1px 2px var(--aeo-shadow);
    }
    #view-aeo .aeo-setup-card h2 {
      font-family: var(--font-display);
      font-size: 1.6rem; font-weight: 600;
      letter-spacing: -0.02em;
      color: var(--aeo-ink);
      margin: 0 0 12px;
    }
    #view-aeo .aeo-setup-card p {
      font-size: 14px; color: var(--aeo-ink-3);
      max-width: 500px; margin: 0 auto 28px; line-height: 1.55;
    }
    #view-aeo .aeo-setup-card-actions {
      display:inline-flex; gap: 12px; align-items: center;
    }
    #view-aeo .aeo-setup-step-list {
      display:grid; grid-template-columns: repeat(3, 1fr);
      gap: 16px; max-width: 720px; margin: 28px auto 0;
      text-align: left;
    }
    #view-aeo .aeo-setup-step {
      padding: 16px;
      background: var(--aeo-paper-2);
      border: 1px solid var(--aeo-rule);
      border-radius: 10px;
    }
    #view-aeo .aeo-setup-step-num {
      font-family: var(--aeo-mono); font-size: 11px; font-weight: 600;
      color: var(--aeo-accent); margin-bottom: 6px;
    }
    #view-aeo .aeo-setup-step-title {
      font-size: 13px; font-weight: 600; color: var(--aeo-ink); margin-bottom: 4px;
    }
    #view-aeo .aeo-setup-step-desc {
      font-size: 12px; color: var(--aeo-ink-3); line-height: 1.45;
    }
    @media (max-width: 720px) {
      #view-aeo .aeo-setup-step-list { grid-template-columns: 1fr; }
    }

    /* Setup modal */
    #aeo-setup-modal {
      position: fixed; inset: 0;
      background: rgba(15, 22, 32, 0.45);
      display: none; align-items: center; justify-content: center;
      z-index: 10000;
      padding: 24px;
    }
    #aeo-setup-modal.show { display: flex; }
    #aeo-setup-modal .aeo-setup-modal-inner {
      background: #FFFFFF;
      border-radius: 16px;
      max-width: 640px;
      width: 100%;
      max-height: 90vh;
      overflow-y: auto;
      padding: 28px 32px;
      box-shadow: 0 20px 60px rgba(0,81,213,0.18);
      font-family: var(--font-ui);
    }
    #aeo-setup-modal h2 {
      font-family: var(--font-display);
      font-size: 1.4rem; font-weight: 600;
      color: #191C1E; margin: 0 0 6px;
      letter-spacing: -0.02em;
    }
    #aeo-setup-modal .aeo-setup-sub {
      color: #505F76; font-size: 13px; margin-bottom: 20px; line-height: 1.5;
    }
    #aeo-setup-modal label {
      display: block; font-size: 11px; font-weight: 600;
      text-transform: uppercase; letter-spacing: 0.06em;
      color: #505F76; margin: 14px 0 6px;
    }
    #aeo-setup-modal input,
    #aeo-setup-modal textarea,
    #aeo-setup-modal select {
      width: 100%; padding: 9px 12px;
      border: 1px solid rgba(193,199,211,0.6);
      border-radius: 8px;
      font-family: var(--font-ui); font-size: 13.5px;
      color: #191C1E; background: #FFFFFF;
      transition: border-color 120ms ease, box-shadow 120ms ease;
      box-sizing: border-box;
    }
    #aeo-setup-modal input:focus,
    #aeo-setup-modal textarea:focus,
    #aeo-setup-modal select:focus {
      outline: none; border-color: #0051D5;
      box-shadow: 0 0 0 3px rgba(0,81,213,0.12);
    }
    #aeo-setup-modal textarea { resize: vertical; min-height: 64px; }
    #aeo-setup-modal .aeo-setup-help {
      font-size: 11px; color: #717783; margin-top: 4px;
    }
    #aeo-setup-modal .aeo-setup-actions {
      display: flex; gap: 8px; justify-content: flex-end;
      margin-top: 24px; padding-top: 16px;
      border-top: 1px solid rgba(193,199,211,0.30);
    }
    #aeo-setup-modal .aeo-setup-prompt-row {
      display: flex; gap: 8px; align-items: flex-start;
      padding: 6px 0;
    }
    #aeo-setup-modal .aeo-setup-prompt-num {
      flex-shrink: 0;
      width: 24px; padding-top: 10px;
      font-family: var(--font-code); font-size: 11px;
      color: #0051D5; font-weight: 600;
    }
    #aeo-setup-modal .aeo-setup-prompt-row textarea {
      flex: 1; min-height: 38px; padding: 8px 10px; font-size: 13px; line-height: 1.4;
    }
    #aeo-setup-modal .aeo-setup-prompt-rm {
      flex-shrink: 0;
      width: 32px; height: 36px;
      border: 1px solid rgba(193,199,211,0.6);
      border-radius: 8px; background: #FFFFFF;
      color: #717783; font-size: 16px; cursor: pointer;
      display: inline-flex; align-items: center; justify-content: center;
    }
    #aeo-setup-modal .aeo-setup-prompt-rm:hover { color: #C0392B; border-color: #C0392B; }
    #aeo-setup-modal .aeo-setup-loading {
      text-align: center; padding: 32px;
      color: #505F76; font-size: 13px;
    }
    #aeo-setup-modal .aeo-setup-loading .spinner {
      display: block; width: 28px; height: 28px;
      border: 2px solid rgba(0,81,213,0.18);
      border-top-color: #0051D5;
      border-radius: 50%;
      animation: aeo-spin 0.8s linear infinite;
      margin: 0 auto 12px;
    }
    @keyframes aeo-spin { to { transform: rotate(360deg); } }
    #aeo-setup-modal .aeo-setup-error {
      background: rgba(192,57,43,0.08); color: #C0392B;
      border: 1px solid rgba(192,57,43,0.20);
      padding: 10px 14px; border-radius: 8px;
      font-size: 12.5px; margin: 12px 0;
    }
    #aeo-setup-modal .aeo-setup-add-btn {
      margin-top: 8px; padding: 6px 12px;
      border: 1px dashed rgba(193,199,211,0.8); border-radius: 8px;
      background: transparent; color: #505F76;
      font-size: 12px; font-weight: 500; cursor: pointer;
    }
    #aeo-setup-modal .aeo-setup-add-btn:hover { border-color: #0051D5; color: #0051D5; }
    #aeo-setup-modal .aeo-setup-lang-toggle {
      display:inline-flex; gap: 0;
      border: 1px solid rgba(193,199,211,0.6); border-radius: 8px;
      overflow: hidden;
    }
    #aeo-setup-modal .aeo-setup-lang-toggle button {
      padding: 7px 14px; background: #FFFFFF; color: #505F76;
      font-family: var(--font-ui); font-size: 12.5px; font-weight: 500;
      border: 0; border-right: 1px solid rgba(193,199,211,0.6);
      cursor: pointer;
    }
    #aeo-setup-modal .aeo-setup-lang-toggle button:last-child { border-right: 0; }
    #aeo-setup-modal .aeo-setup-lang-toggle button.active {
      background: #DBE1FF; color: #003EA8; font-weight: 600;
    }
    #aeo-setup-modal .aeo-setup-lang-toggle button:hover:not(.active) { background: #F7F9FB; }

    /* Cap-hit modal */
    .aeo-cap-modal {
      position: fixed; inset: 0; background: rgba(0,0,0,0.35);
      display: none; align-items:center; justify-content:center;
      z-index: 9999;
    }
    .aeo-cap-modal.show { display: flex; }
    .aeo-cap-modal-inner {
      background: var(--bg-elevated); border-radius: 16px; padding: 24px 28px;
      max-width: 460px; width: calc(100% - 32px);
      box-shadow: 0 20px 50px rgba(0,81,213,0.18);
      font-family: var(--font-body);
    }
    .aeo-cap-modal-title { font-family: var(--font-display); font-size: 1.25rem; font-weight: 600; color: var(--text-primary); margin: 0 0 10px; }
    .aeo-cap-modal-body { color: var(--text-secondary); font-size: var(--text-base); line-height: 1.5; margin-bottom: 16px; }
    .aeo-cap-modal-actions { display:flex; gap: 8px; justify-content:flex-end; }
    /* ==================== /AEO ==================== */

    /* Research evidence cards */
    .ev-section-label { font-family: var(--font-ui); font-size: 0.68rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text4); margin: 0.75rem 0 0.4rem; }
    .ev-section-label:first-child { margin-top: 0; }
    .ev-card { border: 1px solid var(--border-subtle); border-radius: 6px; padding: 0.7rem 0.85rem; margin-bottom: 0.5rem; background: var(--bg-surface); }
    .ev-card-misconception { font-family: var(--font-ui); border: 1px solid var(--warning-border); border-radius: 6px; padding: 0.7rem 0.85rem; margin-bottom: 0.5rem; background: var(--warning-bg); border-left: 3px solid var(--warning); }
    .ev-card-misconception .ev-card-claim { color: var(--warning); }
    .ev-card-misconception .ev-mc-why { font-size: 0.72rem; color: var(--text-secondary); line-height: 1.5; margin-bottom: 0.35rem; font-style: italic; }
    .ev-card-misconception .ev-mc-correction { font-size: 0.78rem; color: var(--text-primary); line-height: 1.5; margin-bottom: 0.35rem; }
    .ev-card-misconception .ev-mc-source { font-size: 0.68rem; color: var(--text-muted); margin-top: 0.3rem; padding-top: 0.3rem; border-top: 1px solid var(--warning-border); }
    .ev-card-claim { font-family: var(--font-ui); font-size: 0.8rem; font-weight: 600; color: var(--text); line-height: 1.45; margin-bottom: 0.35rem; }
    .ev-card-meta { font-family: var(--font-ui); display: flex; flex-wrap: wrap; gap: 0.3rem 0.75rem; font-size: 0.68rem; color: var(--text4); line-height: 1.6; }
    .ev-card-meta span { display: inline-flex; align-items: center; gap: 0.25rem; }
    .ev-card-note { font-family: var(--font-ui); font-size: 0.68rem; color: var(--text3); margin-top: 0.35rem; padding-top: 0.3rem; border-top: 1px solid var(--border); line-height: 1.5; font-style: italic; }
    .ev-expert-card { border: 1px solid var(--border-subtle); border-radius: 6px; padding: 0.6rem 0.85rem; margin-bottom: 0.4rem; background: var(--bg-surface); }
    .ev-expert-name { font-family: var(--font-ui); font-size: 0.78rem; font-weight: 600; color: var(--text); }
    .ev-expert-why { font-family: var(--font-ui); font-size: 0.72rem; color: var(--text3); margin-top: 0.2rem; line-height: 1.45; }
    .ev-gap-item { font-size: 0.75rem; color: var(--text-secondary); line-height: 1.5; padding: 0.4rem 0; border-bottom: 1px solid var(--border-subtle); }
    .ev-gap-item:last-child { border-bottom: none; }
    .ev-note-heading { font-family: var(--font-ui); font-size: 0.75rem; font-weight: 700; color: var(--text2); margin: 0.75rem 0 0.3rem; text-transform: none; }
    .ev-note-warn { font-family: var(--font-ui); font-size: 0.72rem; color: var(--amber, #b45309); background: var(--amber-bg, #fef3cd); border-left: 3px solid var(--amber, #e5a000); border-radius: 4px; padding: 0.45rem 0.7rem; margin: 0.35rem 0; line-height: 1.5; }
    .ev-note-info { font-family: var(--font-ui); font-size: 0.72rem; color: var(--text3); background: var(--bg-surface); border-left: 3px solid var(--border); border-radius: 4px; padding: 0.45rem 0.7rem; margin: 0.35rem 0; line-height: 1.5; }
    .ev-note-text { font-family: var(--font-ui); font-size: 0.72rem; color: var(--text3); line-height: 1.5; margin: 0.2rem 0; }
    /* Fact integration stat bar */
    .fi-stat-bar { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 0.75rem; }
    .fi-stat-badge { display: inline-flex; align-items: center; gap: 0.3rem; font-family: var(--font-ui); font-size: var(--text-xs); font-weight: 600; padding: 0.2em 0.6em; border-radius: 3px; letter-spacing: 0.03em; }
    .fi-stat-badge .fi-stat-num { font-family: var(--font-display); font-weight: 700; }
    .fi-stat-badge.fi-green { background: var(--green-bg); color: var(--green); border: 1px solid var(--green-border); }
    .fi-stat-badge.fi-amber { background: var(--amber-bg); color: var(--amber); border: 1px solid var(--warning-border); }
    .fi-stat-badge.fi-red { background: var(--red-bg); color: var(--red); border: 1px solid var(--red-border); }
    .fi-stat-badge.fi-brand { background: var(--brand-dim); color: var(--brand-text); border: 1px solid var(--brand-border); }
    /* Fact diff card */
    .fi-diff-card { font-family: var(--font-ui); border: 1px solid var(--border-subtle); border-radius: 6px; padding: 0.7rem 0.85rem; margin-bottom: 0.5rem; background: var(--bg-surface); }
    .fi-diff-label { font-size: var(--text-xs); font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-muted); margin-bottom: 0.2rem; font-family: var(--font-ui); }
    .fi-diff-text { font-size: 0.78rem; color: var(--text-secondary); line-height: 1.5; margin-bottom: 0.35rem; }
    .fi-diff-before { border-left: 3px solid var(--red); padding-left: 0.5rem; }
    .fi-diff-after { border-left: 3px solid var(--green); padding-left: 0.5rem; }
    .fi-warn-card { font-family: var(--font-ui); border: 1px solid var(--red-border); border-radius: 6px; padding: 0.7rem 0.85rem; margin-bottom: 0.5rem; background: var(--red-bg); border-left: 3px solid var(--red); }
    .fi-warn-card .ev-card-claim { color: var(--red); }

    /* ══ Inline fact-check flags — anchor flagged claims to article text ═══════ */
    /* Open flags: colored squiggle underline. Verified/dismissed: faded. */
    .flag-mark { cursor: pointer; padding: 0 2px; border-radius: 2px; transition: background-color 120ms ease, opacity 120ms ease; position: relative; }
    .flag-mark:hover { background-color: rgba(0, 81, 213, 0.06); }
    .flag-mark.flag-unverified { text-decoration: underline wavy var(--amber, #CA8A04); text-decoration-thickness: 2px; text-underline-offset: 3px; }
    .flag-mark.flag-misconception { text-decoration: underline wavy var(--red, #DC2626); text-decoration-thickness: 2px; text-underline-offset: 3px; }
    .flag-mark.flag-verified { text-decoration: none; opacity: 0.78; }
    .flag-mark.flag-verified::after { content: " ✓"; color: var(--green, #16A34A); font-weight: 700; font-size: 0.8em; }
    .flag-mark.flag-dismissed { text-decoration: none; opacity: 0.55; }
    .flag-mark.flag-active { background-color: rgba(202, 138, 4, 0.18); outline: 2px solid var(--amber, #CA8A04); outline-offset: 1px; }

    /* HUD counter floating top-right of article body */
    .flags-hud { font-family: var(--font-ui); position: absolute; top: 0.85rem; right: 0.85rem; z-index: 30; display: inline-flex; align-items: center; gap: 0.5rem; padding: 0.4rem 0.7rem 0.4rem 0.55rem; background: rgba(254, 243, 199, 0.95); border: 1px solid rgba(202, 138, 4, 0.35); border-radius: 999px; font-size: 0.78rem; font-weight: 600; color: #92400E; cursor: pointer; box-shadow: 0 2px 8px rgba(146, 64, 14, 0.10); transition: background 120ms ease, transform 120ms ease; user-select: none; }
    .flags-hud:hover { background: #FEF3C7; transform: translateY(-1px); }
    .flags-hud.all-clear { background: rgba(220, 252, 231, 0.95); border-color: rgba(22, 163, 74, 0.35); color: #166534; }
    .flags-hud .fh-count { font-family: var(--font-mono, var(--font-ui)); font-weight: 700; }
    .flags-hud[hidden] { display: none; }

    /* Pro-review banner above the article body (top-level, not anchored to any sentence) */
    .pro-review-banner { font-family: var(--font-ui); display: flex; align-items: flex-start; gap: 0.65rem; padding: 0.7rem 0.85rem; margin: 0 0 1rem 0; background: var(--red-bg, #FEF2F2); border: 1px solid var(--red-border, rgba(220, 38, 38, 0.25)); border-left: 3px solid var(--red, #DC2626); border-radius: 8px; }
    .pro-review-banner.is-resolved { opacity: 0.55; }
    /* ══ End inline fact-check flags ══════════════════════════════════════════ */

    /* [NEEDS HUMAN INPUT: ...] placeholder tags emitted by the Writer agent */
    .human-input-flag { display: inline-flex; align-items: baseline; gap: 0.3rem; background: #FEF3C7; border: 1px solid #F59E0B; border-radius: 4px; padding: 1px 7px; font-size: 0.82rem; font-family: var(--font-ui); color: #92400E; cursor: default; vertical-align: middle; }
    .human-input-flag .hif-badge { font-weight: 700; white-space: nowrap; }
    .human-input-flag .hif-text { font-style: italic; }
    /* Research summary stat bar */
    .research-stat-bar { font-family: var(--font-ui); display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 0.75rem; padding: 0.5rem 0.65rem; background: var(--bg-elevated); border-radius: 6px; }
    .research-stat-pill { font-family: var(--font-ui); font-size: var(--text-xs); font-weight: 600; color: var(--text-secondary); display: inline-flex; align-items: center; gap: 0.25rem; }
    .research-stat-pill .rs-num { font-family: var(--font-display); font-weight: 700; color: var(--text-primary); }
    /* Blueprint panel */
    .bp-thesis-card { border-left: 3px solid var(--brand-primary); background: var(--surface); border-radius: 0 6px 6px 0; padding: 0.7rem 0.85rem; margin-bottom: 0.5rem; }
    .bp-thesis-text { font-size: 0.82rem; font-weight: 600; color: var(--text); line-height: 1.5; }
    .bp-section-num { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; border-radius: 50%; background: var(--brand-dim); color: var(--brand-accent); font-size: 0.6rem; font-weight: 700; flex-shrink: 0; margin-right: 0.4rem; }
    .bp-opening-label { font-size: 0.6rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; color: var(--text4); margin-bottom: 0.2rem; }
    .bp-trap-item { font-size: 0.75rem; color: var(--text3); line-height: 1.5; padding: 0.4rem 0; border-bottom: 1px solid var(--border); display: flex; align-items: flex-start; gap: 0.4rem; }
    .bp-trap-item:last-child { border-bottom: none; }
    .bp-trap-icon { color: var(--amber); flex-shrink: 0; font-size: 0.7rem; margin-top: 0.1rem; }
    /* Actions panel */
    .act-card { border: 1px solid var(--border); border-radius: 6px; padding: 0.7rem 0.85rem; margin-bottom: 0.5rem; background: var(--surface); border-left: 3px solid var(--amber); }
    .act-card-quote { font-family: var(--font-ui); font-size: 0.75rem; color: var(--text3); line-height: 1.45; font-style: italic; margin-bottom: 0.3rem; padding-left: 0.5rem; border-left: 2px solid var(--border); }
    .act-card-issue { font-family: var(--font-ui); font-size: 0.78rem; color: var(--text); line-height: 1.45; }
    .review-fc-issues[open] summary::before { content: "▼"; }
    .review-fc-issues-list { margin-top: 0.4rem; font-size: 0.7rem; color: var(--text3); line-height: 1.6; white-space: pre-wrap; border-left: 2px solid var(--amber); padding-left: 0.5rem; }
    .review-hint { font-size: 0.75rem; color: var(--text3); line-height: 1.5; }
    .review-actions-divider {
      display: flex; align-items: center; gap: 0.5rem;
      margin: 1rem 0 0.65rem; font-size: 0.62rem; font-weight: 600;
      text-transform: uppercase; letter-spacing: 0.08em; color: var(--text4);
    }
    .review-actions-divider::after { content: ''; flex: 1; height: 1px; background: var(--border); }
    .reject-label { font-size: 0.72rem; font-weight: 600; color: var(--text3); margin: 0.875rem 0 0.35rem; display: block; }
    .reject-textarea {
      width: 100%; border: 1px solid var(--border); border-radius: 8px;
      padding: 0.55rem 0.7rem; font-size: 0.8rem; color: var(--text);
      background: var(--bg-base);
      font-family: var(--font-ui); resize: vertical; min-height: 60px; outline: none;
      margin-bottom: 0.5rem; transition: border-color 0.15s, box-shadow 0.15s;
    }
    .reject-textarea:focus { border-color: var(--red); box-shadow: 0 0 0 3px rgba(192, 57, 43, 0.07); }
    .reject-textarea::placeholder { color: var(--text4); }
    .btn-reject {
      width: 100%; display: flex; align-items: center; justify-content: center; gap: 0.35rem;
      padding: 0.6rem; background: none; border: 1px solid var(--red-border);
      border-radius: 6px; font-size: 0.82rem; font-weight: 600;
      color: var(--red); cursor: pointer; font-family: var(--font-ui); transition: background 0.15s, border-color 0.15s;
    }
    .btn-reject:hover { background: var(--red-bg); border-color: var(--red); }

    /* Done mode foot */
    #done-mode-foot { display: none; }
    .done-hint { font-size: 0.75rem; color: var(--text3); line-height: 1.55; padding: 0.25rem 0; }
    #btn-rewrite-comments {
      display: none; width: 100%; justify-content: center;
      margin-top: 0.75rem; background: var(--brand-primary);
    }
    .done-request-rewrite { margin-top: 0.875rem; padding-top: 0.875rem; border-top: 1px solid var(--border); }
    .done-request-rewrite-label { font-size: 0.72rem; font-weight: 600; color: var(--text3); margin-bottom: 0.35rem; display: block; }

    /* ═══════════════════════════════════════════════════════════
       Plume Score — compact side-by-side scorecard
       Hero composite on the left, 3×2 radial dial grid on the right.
       Single typeface (DM Sans via --font-ui) — as is the whole dashboard.
       ═══════════════════════════════════════════════════════════ */
    .plume-card {
      margin: 1rem 1.5rem 1.25rem;
      background:
        radial-gradient(circle at 100% 0%, rgba(0,81,213,0.055) 0%, transparent 42%),
        linear-gradient(180deg, #FBFCFE 0%, var(--bg-base) 100%);
      border: 1px solid var(--border);
      border-radius: 14px;
      position: relative;
      overflow: hidden;
      isolation: isolate;
      font-family: var(--font-ui);
    }
    .plume-card-grain {
      position: absolute; inset: 0; pointer-events: none; z-index: 0;
      opacity: 0.3; mix-blend-mode: multiply;
      background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' seed='7'/%3E%3CfeColorMatrix values='0 0 0 0 0.18 0 0 0 0 0.21 0 0 0 0 0.29 0 0 0 0.04 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
    }
    .plume-card > * { position: relative; z-index: 1; }

    /* ── Body: hero left, dial grid right ── */
    .plume-body {
      display: grid;
      grid-template-columns: minmax(220px, 0.78fr) 1.22fr;
      align-items: stretch;
      gap: 0;
    }

    /* ── Hero column ── */
    .plume-hero {
      padding: 1.15rem 1.35rem 1.1rem;
      border-right: 1px solid var(--border-subtle);
      display: flex;
      flex-direction: column;
      min-width: 0;
    }
    .plume-eyebrow {
      font-family: var(--font-ui);
      font-size: 0.54rem;
      font-weight: 700;
      letter-spacing: 0.2em;
      text-transform: uppercase;
      color: var(--text4);
      display: flex; align-items: center; gap: 0.5rem;
      margin: 0 0 0.55rem;
    }
    .plume-eyebrow-rule {
      display: inline-block; width: 20px; height: 1px;
      background: var(--text4); opacity: 0.55;
    }
    .plume-hero-figure {
      display: flex; align-items: baseline; gap: 0.4rem;
      line-height: 0.85;
    }
    .plume-hero-num {
      font-family: var(--font-ui);
      font-size: clamp(2.5rem, 4.2vw, 3.35rem);
      font-weight: 800;
      letter-spacing: -0.045em;
      color: var(--text-primary);
      font-variant-numeric: tabular-nums;
      display: inline-block;
      transition: color 0.35s ease;
    }
    .plume-hero-num.is-low  { color: var(--red); }
    .plume-hero-num.is-mid  { color: var(--amber); }
    .plume-hero-num.is-high { color: var(--green); }
    .plume-hero-denom {
      font-family: var(--font-ui);
      font-weight: 500;
      font-size: 1rem;
      color: var(--text4);
      letter-spacing: -0.01em;
      align-self: flex-end;
      transform: translateY(-0.25rem);
    }
    .plume-hero-verdict {
      font-family: var(--font-ui);
      font-size: 0.72rem;
      font-weight: 400;
      color: var(--text3);
      margin: 0.5rem 0 0.85rem;
      letter-spacing: -0.005em;
      max-width: 24ch;
      line-height: 1.4;
    }
    /* E2 — revision delta chip ("68 → 81 · après amélioration automatique") */
    .plume-delta-chip {
      display: inline-block;
      font-family: var(--font-ui);
      font-size: 0.68rem;
      font-weight: 500;
      color: var(--green);
      background: rgba(26, 127, 90, 0.08);
      border-radius: 999px;
      padding: 0.2rem 0.6rem;
      margin: 0 0 0.85rem;
      font-variant-numeric: tabular-nums;
      letter-spacing: -0.005em;
    }
    /* D9 — generation health panel (what the writer actually worked with) */
    .gen-health-panel {
      margin-top: 0.9rem;
      padding: 0.85rem 1rem;
      border: 1px solid var(--border, #E5E7EB);
      border-radius: 10px;
      background: var(--surface, #FFFFFF);
    }
    .gen-health-title {
      font-family: var(--font-ui);
      font-size: 0.72rem;
      font-weight: 700;
      text-transform: uppercase;
      letter-spacing: 0.04em;
      color: var(--text-muted, #505F76);
      margin-bottom: 0.55rem;
    }
    .gen-health-grid {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
      gap: 0.35rem 1rem;
    }
    .gen-health-row {
      display: flex;
      justify-content: space-between;
      gap: 0.5rem;
      font-family: var(--font-ui);
      font-size: 0.74rem;
      min-width: 0;
    }
    .gen-health-label { color: var(--text-muted, #505F76); white-space: nowrap; }
    .gen-health-val {
      font-weight: 600;
      color: var(--text, #1E2A3B);
      text-align: right;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      font-variant-numeric: tabular-nums;
    }
    .gen-health-val.is-ok { color: var(--green, #1A7F5A); }
    .gen-health-val.is-warn { color: #B45309; }
    /* E1 — illustrative evidence quotes inside dimension tiles */
    .plume-tile-evidence {
      display: flex;
      flex-direction: column;
      gap: 0.2rem;
      margin-top: 0.45rem;
      padding-top: 0.45rem;
      border-top: 1px dashed var(--border, #E5E7EB);
    }
    .plume-tile-evidence-label {
      font-family: var(--font-ui);
      font-size: 0.6rem;
      font-weight: 500;
      text-transform: uppercase;
      letter-spacing: 0.04em;
      color: var(--text4);
    }
    .plume-tile-evidence-item {
      font-family: var(--font-ui);
      font-size: 0.68rem;
      line-height: 1.4;
      color: var(--text3);
      font-style: italic;
      overflow: hidden;
      text-overflow: ellipsis;
      display: -webkit-box;
      -webkit-line-clamp: 2;
      -webkit-box-orient: vertical;
    }

    /* ── Color-graded score scale (inside hero column) ── */
    .plume-scale {
      position: relative;
      margin-top: auto;
      padding-top: 0.3rem;
    }
    .plume-scale-bar {
      display: flex;
      height: 3px;
      border-radius: 1.5px;
      overflow: hidden;
      opacity: 0.85;
    }
    .plume-scale-segment { height: 100%; }
    .plume-scale-low  { flex: 40; background: var(--red);   opacity: 0.78; }
    .plume-scale-mid  { flex: 30; background: var(--amber); opacity: 0.78; }
    .plume-scale-high { flex: 30; background: var(--green); opacity: 0.78; }
    .plume-scale-marker {
      position: absolute;
      top: calc(0.3rem - 4px);
      width: 2px; height: 11px;
      background: var(--text-primary);
      transform: translateX(-50%);
      transition: left 0.6s cubic-bezier(0.22, 1, 0.36, 1);
      border-radius: 1px;
      box-shadow: 0 0 0 2px var(--bg-base);
    }
    .plume-scale-marker::after {
      content: ''; position: absolute;
      top: -3px; left: 50%; transform: translateX(-50%);
      width: 0; height: 0;
      border-left: 3px solid transparent;
      border-right: 3px solid transparent;
      border-bottom: 3px solid var(--text-primary);
    }
    .plume-scale-ticks {
      position: relative;
      height: 0.75rem;
      margin-top: 0.35rem;
      font-family: var(--font-ui);
      font-size: 0.5rem;
      font-weight: 600;
      color: var(--text4);
      letter-spacing: 0.08em;
    }
    .plume-scale-ticks span {
      position: absolute;
      top: 0;
      transform: translateX(-50%);
    }
    .plume-scale-ticks span:nth-child(1) { left: 0; transform: translateX(0); }
    .plume-scale-ticks span:nth-child(2) { left: 40%; }
    .plume-scale-ticks span:nth-child(3) { left: 70%; }
    .plume-scale-ticks span:nth-child(4) { left: 100%; transform: translateX(-100%); }

    /* ── Dimension tile grid (right column) ── */
    .plume-grid {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 0;
    }
    @media (max-width: 900px) {
      .plume-body { grid-template-columns: 1fr; }
      .plume-hero { border-right: none; border-bottom: 1px solid var(--border-subtle); }
    }
    @media (max-width: 640px) {
      .plume-grid { grid-template-columns: repeat(2, 1fr); }
      .plume-grid .plume-tile:nth-child(3n) { border-right: 1px solid var(--border-subtle); }
      .plume-grid .plume-tile:nth-child(2n) { border-right: none; }
    }

    .plume-tile {
      padding: 0.85rem 0.9rem 0.9rem;
      border-right: 1px solid var(--border-subtle);
      border-bottom: 1px solid var(--border-subtle);
      display: flex; flex-direction: column; gap: 0.4rem;
      position: relative;
      transition: background 0.25s ease;
      min-width: 0;
    }
    .plume-grid .plume-tile:nth-child(3n) { border-right: none; }
    .plume-grid .plume-tile:nth-last-child(-n+3) { border-bottom: none; }
    .plume-tile:hover { background: rgba(0,81,213,0.025); }
    .plume-tile::before {
      content: ''; position: absolute;
      left: 0; top: 0.7rem; bottom: 0.7rem;
      width: 2px; background: var(--brand-primary);
      opacity: 0; transform: translateX(-2px);
      transition: opacity 0.25s ease, transform 0.25s ease;
    }
    .plume-tile:hover::before { opacity: 1; transform: translateX(0); }

    .plume-tile-head {
      display: flex; align-items: center; gap: 0.65rem;
    }
    .plume-dial {
      width: 40px; height: 40px; flex-shrink: 0;
      display: block;
    }
    .plume-dial-track { stroke: var(--border2); opacity: 0.55; }
    .plume-dial-arc {
      stroke-linecap: round;
      transition: stroke-dashoffset 0.9s cubic-bezier(0.22, 1, 0.36, 1),
                  stroke 0.25s ease;
    }
    .plume-dial-val {
      font-family: var(--font-ui);
      font-size: 13px;
      font-weight: 700;
      letter-spacing: -0.02em;
      dominant-baseline: central;
      text-anchor: middle;
    }

    .plume-tile-meta { flex: 1; min-width: 0; }
    .plume-tile-index {
      font-family: var(--font-ui);
      font-size: 0.5rem;
      font-weight: 600;
      color: var(--text4);
      letter-spacing: 0.1em;
      text-transform: uppercase;
      display: block;
      margin-bottom: 0.1rem;
    }
    .plume-tile-name {
      font-family: var(--font-ui);
      font-size: 0.78rem;
      font-weight: 700;
      color: var(--text-primary);
      letter-spacing: -0.01em;
      line-height: 1.2;
    }
    .plume-tile-detail {
      font-family: var(--font-ui);
      font-size: 0.64rem;
      color: var(--text3);
      line-height: 1.5;
      margin: 0;
    }
    .plume-tile-detail strong {
      color: var(--text-primary);
      font-weight: 700;
      font-variant-numeric: tabular-nums;
    }
    .plume-tile-detail .plume-tile-sep {
      display: inline-block;
      margin: 0 0.3rem;
      color: var(--text4);
      opacity: 0.5;
    }
    .plume-tile-penalty {
      margin-top: 0.1rem;
      display: inline-flex; align-items: center; gap: 0.3rem;
      font-family: var(--font-ui);
      font-size: 0.52rem;
      font-weight: 600;
      color: var(--red);
      letter-spacing: 0.08em;
      text-transform: uppercase;
    }
    .plume-tile-penalty::before {
      content: ''; width: 4px; height: 4px; border-radius: 50%;
      background: var(--red);
    }

    /* Staggered reveal on first render */
    .plume-card.is-revealing .plume-hero-num { animation: plume-num-in 0.65s cubic-bezier(0.22,1,0.36,1) both; }
    .plume-card.is-revealing .plume-tile { animation: plume-tile-in 0.5s cubic-bezier(0.22,1,0.36,1) both; }
    .plume-card.is-revealing .plume-tile:nth-child(1) { animation-delay: 0.05s; }
    .plume-card.is-revealing .plume-tile:nth-child(2) { animation-delay: 0.11s; }
    .plume-card.is-revealing .plume-tile:nth-child(3) { animation-delay: 0.17s; }
    .plume-card.is-revealing .plume-tile:nth-child(4) { animation-delay: 0.23s; }
    .plume-card.is-revealing .plume-tile:nth-child(5) { animation-delay: 0.29s; }
    .plume-card.is-revealing .plume-tile:nth-child(6) { animation-delay: 0.35s; }
    @keyframes plume-num-in {
      from { opacity: 0; transform: translateY(0.35rem); }
      to   { opacity: 1; transform: translateY(0); }
    }
    @keyframes plume-tile-in {
      from { opacity: 0; transform: translateY(0.4rem); }
      to   { opacity: 1; transform: translateY(0); }
    }
    @media (prefers-reduced-motion: reduce) {
      .plume-card.is-revealing * { animation: none !important; }
      .plume-dial-arc { transition: none !important; }
    }

    /* ── Keyword list with mini bars ── */
    .seo-kw-count { font-weight: 500; color: var(--text4); text-transform: none; letter-spacing: 0; font-size: 0.55rem; }

    /* Competitor toggle */
    .seo-comp-toggle {
      font-size: 0.55rem; font-weight: 600; color: var(--text4);
      cursor: pointer; user-select: none; margin-left: auto;
      position: relative;
    }
    .seo-comp-toggle summary { list-style: none; display: flex; align-items: center; gap: 0.25rem; cursor: pointer; }
    .seo-comp-toggle summary::-webkit-details-marker { display: none; }
    .seo-comp-list {
      display: flex; flex-direction: column; gap: 0.25rem;
      position: absolute; right: 0; top: 100%; margin-top: 0.2rem;
      background: var(--bg-base);
      border: 1px solid var(--border); border-radius: 6px; padding: 0.4rem;
      box-shadow: 0 4px 12px rgba(30,47,77,0.1); z-index: 10;
    }
    .seo-comp-label {
      display: inline-flex; align-items: center; gap: 0.25rem;
      font-size: 0.6rem; color: var(--text2); cursor: pointer; white-space: nowrap;
    }
    .seo-comp-label input { width: 12px; height: 12px; accent-color: var(--brand-primary); }
    .seo-comp-dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
    .seo-meta-chars { font-size: 0.55rem; color: var(--text4); margin-top: 0.1rem; }
    .seo-meta-chars.warn { color: var(--amber); }
    .seo-meta-chars.ok { color: var(--green); }
    .seo-spinner {
      width: 28px; height: 28px; border: 3px solid var(--border);
      border-top-color: var(--brand-primary); border-radius: 50%;
      animation: spin 0.7s linear infinite;
    }
    @keyframes spin { to { transform: rotate(360deg); } }

    /* Mobile responsive for inline SEO view */
    @media (max-width: 768px) {
      .seo-scores-row { flex-wrap: wrap; padding: 0.6rem; gap: 0.4rem; }
      .seo-score-card { flex: 1 1 calc(33% - 0.4rem); min-width: 80px; padding: 0.5rem; }
      .seo-score-value { font-size: 1.2rem; }
      .seo-meta-body { grid-template-columns: 1fr; }
    }
    .stat-card { background: var(--surface); border: 1px solid var(--border); border-radius: 6px; padding: 1.25rem 1.5rem; transition: box-shadow 0.2s, border-color 0.2s; }
    .stat-card:hover { box-shadow: var(--shadow-md); border-color: var(--border-default); }
    .stat-icon { width: 36px; height: 36px; border-radius: 6px; display: flex; align-items: center; justify-content: center; margin-bottom: 0.75rem; }
    .stat-icon.purple { background: var(--brand-dim); color: var(--brand-primary); }
    .stat-icon.green { background: var(--green-bg); color: var(--green); }
    .stat-icon.blue { background: var(--brand-dim); color: var(--brand-primary); }
    .stat-icon.amber { background: var(--amber-bg); color: var(--amber); }
    .stat-icon.gray { background: var(--bg-elevated); color: var(--text-muted); }
    .stat-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.75rem; }
    .stat-trend { font-size: 0.7rem; font-weight: 600; display: inline-flex; align-items: center; gap: 2px; padding: 2px 6px; border-radius: 4px; }
    .stat-trend.up { color: var(--green); background: var(--green-bg); }
    .stat-trend.neutral { color: var(--text4); background: var(--bg-elevated); }
    .stat-label { font-family: var(--font-ui); font-size: 0.72rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text4); margin-bottom: 0.5rem; }
    .stat-value { font-family: var(--font-display); font-size: 2rem; font-weight: 800; color: var(--text); letter-spacing: -0.04em; line-height: 1; }
    .stat-sub { font-size: 0.75rem; color: var(--text4); margin-top: 0.3rem; }
    .stat-bar-wrap { padding: 0 2rem 2rem; }
    .stat-bar-title { font-size: 0.85rem; font-weight: 700; color: var(--text2); margin-bottom: 1.25rem; }
    .stat-bar-row { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 0.875rem; padding: 0.5rem 0.75rem; background: var(--surface); border: 1px solid var(--border); border-radius: 6px; transition: border-color 0.15s; }
    .stat-bar-row:hover { border-color: var(--border2); }
    .stat-bar-label { font-size: 0.78rem; font-weight: 500; color: var(--text3); width: 120px; flex-shrink: 0; }
    .stat-bar-track { flex: 1; height: 6px; background: var(--bg-elevated); border-radius: 3px; overflow: hidden; }
    .stat-bar-fill { height: 100%; border-radius: 3px; transition: width 0.5s ease; }
    .stat-bar-num { font-size: 0.75rem; font-weight: 700; color: var(--text2); width: 24px; text-align: right; }

    /* ══ DASHBOARD V2 ════════════════════════════════════ */
    /* ══ PROFILE ═════════════════════════════════════════ */
    .profile-wrap { padding: 1.5rem 2rem; max-width: 640px; flex: 1; overflow-y: auto; }
    .profile-card { background: var(--surface); border: 1px solid var(--border); border-radius: 6px; padding: 1.75rem; margin-bottom: 1rem; }
    .profile-avatar-row { display: flex; align-items: center; gap: 1.25rem; margin-bottom: 1.5rem; }
    .avatar-lg { width: 64px; height: 64px; border-radius: 50%; background: var(--brand-primary); display: flex; align-items: center; justify-content: center; font-size: 1.4rem; font-weight: 700; color: var(--text-on-brand); }
    .profile-name-block h2 { font-size: 1.1rem; font-weight: 700; margin-bottom: 0.2rem; }
    .profile-name-block p { font-size: 0.82rem; color: var(--text3); }
    .profile-section-title { font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text4); margin-bottom: 0.875rem; }
    .profile-fields { display: flex; flex-direction: column; gap: 0.875rem; }

    /* ══ CLIENTS ═════════════════════════════════════════ */
    .client-card {
      background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
      padding: 1.25rem 1.5rem; margin-bottom: 0.625rem;
      transition: border-color 0.2s, box-shadow 0.2s;
    }
    .client-card:hover { border-color: var(--border2); box-shadow: var(--shadow-sm); }
    .client-card-header { display: flex; align-items: center; gap: 0.875rem; position: relative; }
    .client-avatar {
      width: 40px; height: 40px; border-radius: 10px;
      display: flex; align-items: center; justify-content: center;
      font-family: var(--font-display); font-size: 1rem; font-weight: 700;
      color: #fff; flex-shrink: 0;
    }
    /* Favicon variant: white card with hairline border, image fills the box.
       If the favicon fails to load, .fallback class flips to the colored
       letter circle that lives behind it. */
    .client-avatar-fav {
      background: #fff;
      border: 1px solid var(--border-subtle);
      position: relative; overflow: hidden;
    }
    .client-avatar-fav img {
      width: 28px; height: 28px; object-fit: contain;
      display: block;
    }
    .client-avatar-fav .client-avatar-fallback {
      position: absolute; inset: 0;
      display: none; align-items: center; justify-content: center;
      color: #fff; font-family: var(--font-display); font-weight: 700; font-size: 1rem;
      border-radius: 10px;
    }
    .client-avatar-fav.fallback .client-avatar-fallback { display: flex; }
    .client-avatar-fav.fallback { background: transparent; border: none; }
    .client-info { flex: 1; min-width: 0; }
    .client-name {
      font-family: var(--font-ui); font-size: 0.95rem; font-weight: 700;
      color: var(--text); margin-bottom: 0.1rem; line-height: 1.2;
      white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    }
    .client-meta {
      font-family: var(--font-ui); font-size: 0.78rem; color: var(--text3);
      white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    }
    /* Hover-revealed, but must NOT reserve layout width — the invisible 140px
       cluster was crushing the brand name to ~66px ("Acme …"). Overlay on
       hover instead; a gradient masks the text it covers. */
    .client-actions {
      display: flex; gap: 0.25rem; flex-shrink: 0; opacity: 0; transition: opacity 0.15s;
      position: absolute; right: 0; top: 50%; transform: translateY(-50%);
      padding-left: 26px; pointer-events: none;
      background: linear-gradient(90deg, transparent, var(--surface) 20%);
    }
    .client-card:hover .client-actions { opacity: 1; pointer-events: auto; }
    .client-action-btn {
      width: 32px; height: 32px; border: 1px solid var(--border); background: var(--bg-base);
      border-radius: 6px; display: flex; align-items: center; justify-content: center;
      cursor: pointer; color: var(--text3); transition: all 0.15s;
    }
    .client-action-btn:hover { background: var(--bg-elevated); color: var(--text); border-color: var(--border2); }
    .client-action-delete:hover { background: var(--red-bg); color: var(--red); border-color: var(--red-border); }
    .client-tags {
      display: flex; flex-wrap: wrap; gap: 0.375rem;
      margin-top: 0.75rem; padding-top: 0.75rem; border-top: 1px solid var(--border-subtle);
    }
    .client-tag {
      display: inline-flex; align-items: center; gap: 0.3rem;
      font-family: var(--font-ui); font-size: 0.7rem; font-weight: 500;
      color: var(--text3); background: var(--bg-elevated); border-radius: 5px; padding: 0.25rem 0.5rem;
    }
    .client-tag svg { opacity: 0.5; flex-shrink: 0; }

    /* ── Brands grid view ─────────────────────────────────────── */
    .brands-grid-wrap { padding: 1.5rem 2rem; flex: 1; overflow-y: auto; min-height: 0; }

    /* Add-brand card — lives in the grid, same cell as client cards */
    .brand-add-card {
      border: none;
      border-radius: 10px;
      background: var(--brand-primary);
      min-height: 148px;
      display: flex; align-items: center; justify-content: center;
      cursor: pointer;
      transition: background 0.18s;
    }
    .brand-add-card:hover { background: #003FA8; }
    .brand-add-card:focus-visible { outline: 2px solid var(--brand-primary); outline-offset: 3px; }
    .brand-add-card-inner {
      display: flex; flex-direction: column; align-items: center; gap: 0.6rem;
      color: #fff; pointer-events: none;
    }
    .brand-add-card-plus {
      width: 36px; height: 36px;
      border: 1.5px solid rgba(255,255,255,0.55); border-radius: 8px;
      display: flex; align-items: center; justify-content: center;
      font-size: 22px; font-weight: 300; line-height: 1;
      transition: border-color 0.18s;
    }
    .brand-add-card:hover .brand-add-card-plus { border-color: rgba(255,255,255,0.9); }
    .brand-add-card-label {
      font-family: var(--font-ui); font-size: 0.75rem; font-weight: 600;
      opacity: 0.8; letter-spacing: 0.01em;
    }
    .brand-add-card:hover .brand-add-card-label { opacity: 1; }
    #client-list {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
      gap: 0.75rem;
      align-items: stretch;
    }
    #client-list .client-card { margin-bottom: 0; }

    .client-empty-state { text-align: center; padding: 4rem 2rem; }
    .client-empty-icon {
      width: 80px; height: 80px; margin: 0 auto 1.25rem;
      background: var(--bg-elevated); border-radius: 20px;
      display: flex; align-items: center; justify-content: center; color: var(--text3);
    }
    .client-empty-title {
      font-family: var(--font-ui); font-size: 0.95rem; font-weight: 700;
      color: var(--text2); margin-bottom: 0.375rem;
    }
    .client-empty-desc {
      font-family: var(--font-ui); font-size: 0.8rem; color: var(--text3);
      max-width: 320px; margin: 0 auto; line-height: 1.5;
    }

    /* ══ SUBSCRIPTION ════════════════════════════════════ */
    .sub-wrap { padding: 1.5rem 2rem; }
    .sub-grid { display: grid; grid-template-columns: repeat(3,1fr); gap: 1rem; max-width: 900px; }
    .plan-card { background: var(--surface); border: 1px solid var(--border); border-radius: 6px; padding: 1.5rem; display: flex; flex-direction: column; position: relative; }
    .plan-card.featured { border-color: var(--brand-primary); box-shadow: 0 0 0 1px var(--brand-primary); }
    .plan-badge { position: absolute; top: -10px; left: 50%; transform: translateX(-50%); font-family: var(--font-ui); font-size: 0.65rem; font-weight: 700; background: var(--brand-primary); color: var(--text-on-brand); padding: 2px 10px; border-radius: 3px; text-transform: uppercase; letter-spacing: 0.06em; }
    .plan-name { font-family: var(--font-ui); font-size: 0.8rem; font-weight: 700; color: var(--text-muted); margin-bottom: 0.5rem; }
    .plan-price { font-family: var(--font-display); font-size: 2rem; font-weight: 800; color: var(--text); letter-spacing: -0.04em; line-height: 1; margin-bottom: 0.25rem; }
    .plan-price span { font-size: 0.85rem; font-weight: 500; color: var(--text3); }
    .plan-period { font-size: 0.72rem; color: var(--text4); margin-bottom: 1.25rem; }
    .plan-features { flex: 1; margin-bottom: 1.25rem; }
    .plan-feature { display: flex; align-items: center; gap: 0.5rem; font-size: 0.8rem; color: var(--text2); margin-bottom: 0.5rem; }
    .plan-feature svg { color: var(--green); flex-shrink: 0; }
    .plan-btn { display: block; width: 100%; padding: 0.65rem; border-radius: 3px; font-size: 0.85rem; font-weight: 600; cursor: pointer; font-family: var(--font-ui); text-align: center; transition: background 0.15s, border-color 0.15s; }
    .plan-btn.outline { background: none; border: 1px solid var(--border2); color: var(--text2); }
    .plan-btn.outline:hover { border-color: var(--brand-accent); color: var(--brand-accent); }
    .plan-btn.filled { background: var(--brand-primary); border: 1px solid var(--brand-primary); color: var(--text-on-brand); }
    .plan-btn.filled:hover { background: var(--indigo-dark); }
    .plan-current { display: block; width: 100%; padding: 0.65rem; text-align: center; font-size: 0.8rem; font-weight: 600; color: var(--green); background: var(--green-bg); border: 1px solid var(--green-border); border-radius: 3px; }
    .serp-head {
      padding: 1.1rem 1.5rem; border-bottom: 1px solid var(--border);
      display: flex; align-items: center; justify-content: space-between; flex-shrink: 0;
    }
    .serp-head-left { flex: 1; }
    .serp-title    { font-family: var(--font-display); font-size: 1rem; font-weight: 700; color: var(--text); }
    .serp-subtitle { font-size: 0.78rem; color: var(--text3); margin-top: 0.15rem; }

    .serp-body { display: flex; flex: 1; overflow: hidden; min-height: 0; }

    .serp-pages {
      width: 52%; border-right: 1px solid var(--border);
      overflow-y: auto; padding: 1rem 1.25rem; flex-shrink: 0;
    }
    .serp-pages::-webkit-scrollbar { width: 4px; }
    .serp-pages::-webkit-scrollbar-thumb { background: var(--border2); border-radius: 2px; }

    .serp-analysis-pane { flex: 1; overflow-y: auto; padding: 1rem 1.25rem; }
    .serp-analysis-pane::-webkit-scrollbar { width: 4px; }
    .serp-analysis-pane::-webkit-scrollbar-thumb { background: var(--border2); border-radius: 2px; }

    .serp-col-label {
      font-size: 0.65rem; font-weight: 700; text-transform: uppercase;
      letter-spacing: 0.1em; color: var(--text4); margin-bottom: 0.875rem;
    }

    .serp-page-card {
      background: var(--bg-surface); border: 1px solid var(--border);
      border-radius: 6px; padding: 0.875rem 1rem; margin-bottom: 0.75rem;
    }
    .serp-rank { font-size: 0.62rem; font-weight: 700; color: var(--brand-accent); letter-spacing: 0.06em; margin-bottom: 0.3rem; }
    .serp-page-title { font-size: 0.84rem; font-weight: 600; color: var(--text); margin-bottom: 0.15rem; line-height: 1.3; }
    .serp-page-url { font-size: 0.67rem; color: var(--brand-accent); margin-bottom: 0.5rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-decoration: none; display: block; }
    .serp-page-url:hover { text-decoration: underline; }
    .serp-page-snippet { font-size: 0.72rem; color: var(--text3); line-height: 1.5; margin-top: 0.4rem; }
    .serp-wc { display: inline-flex; align-items: center; font-size: 0.68rem; font-weight: 600; background: var(--indigo-light); color: var(--brand-accent); padding: 2px 7px; border-radius: 8px; margin-bottom: 0.5rem; }
    .serp-h2s { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-top: 0.4rem; }
    .serp-h2-chip { font-size: 0.66rem; color: var(--text3); background: var(--bg); border: 1px solid var(--border); border-radius: 4px; padding: 2px 6px; max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .serp-h3-chip { font-size: 0.61rem; color: var(--text4); background: transparent; border: 1px solid var(--brand-dim); border-radius: 4px; padding: 1px 5px; max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .serp-page-error { font-size: 0.72rem; color: var(--red); }

    .serp-section { margin-bottom: 1.25rem; }
    .serp-section-title { font-size: 0.65rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em; color: var(--text4); margin-bottom: 0.45rem; }
    .serp-section-text { font-size: 0.82rem; color: var(--text2); line-height: 1.65; }
    .serp-list { padding-left: 1.1rem; margin: 0; }
    .serp-list li { font-size: 0.8rem; color: var(--text2); line-height: 1.65; margin-bottom: 0.2rem; }

    .serp-loading {
      display: flex; flex-direction: column; align-items: center;
      justify-content: center; flex: 1; padding: 3rem; text-align: center; gap: 1rem;
    }
    .serp-spinner { width: 36px; height: 36px; border: 3px solid var(--brand-glow); border-top-color: var(--brand-primary); border-radius: 50%; animation: spin 0.8s linear infinite; }
    .serp-load-msg { font-size: 0.9rem; color: var(--text2); font-weight: 500; }
    .serp-progress-bar { width: 180px; height: 3px; background: var(--border); border-radius: 2px; overflow: hidden; }
    .serp-progress-fill { height: 100%; background: var(--brand-primary); border-radius: 2px; transition: width 0.6s ease; width: 0%; }
    .serp-kpi-bar { display: flex; flex-wrap: wrap; gap: 0.5rem 1.25rem; padding: 0.75rem 1rem; background: var(--indigo-light); border-radius: 6px; margin-bottom: 1rem; }
    .serp-kpi { display: flex; flex-direction: column; gap: 0.1rem; }
    .serp-kpi-val { font-size: 1rem; font-weight: 700; color: var(--brand-accent); line-height: 1; }
    .serp-kpi-lbl { font-size: 0.63rem; color: var(--text4); text-transform: uppercase; letter-spacing: 0.06em; }
    .serp-page-meta { font-size: 0.72rem; color: var(--text3); line-height: 1.5; margin: 0.2rem 0 0.4rem; font-style: italic; }
    .serp-page-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.2rem; gap: 0.5rem; }
    .serp-status-ok  { font-size: 0.62rem; font-weight: 700; color: var(--brand-primary); background: var(--green-bg); border-radius: 4px; padding: 1px 6px; white-space: nowrap; }
    .serp-status-blocked { font-size: 0.62rem; font-weight: 700; color: var(--amber); background: var(--amber-bg, #FDF5E6); border-radius: 4px; padding: 1px 6px; white-space: nowrap; }
    .serp-wc-green { background: var(--green-bg); color: var(--brand-primary); }
    .serp-wc-amber  { background: var(--amber-bg, #FDF5E6); color: var(--amber); }
    .serp-wc-red    { background: var(--red-bg); color: var(--red); }
    .serp-kw-hit    { font-weight: 700; color: var(--text); }

    .serp-foot {
      padding: 1rem 1.5rem; border-top: 1px solid var(--border);
      display: flex; align-items: center; justify-content: space-between; flex-shrink: 0;
    }
    .serp-foot-left { font-size: 0.75rem; color: var(--text4); }
    .serp-foot-right { display: flex; gap: 0.75rem; }

    .serp-analyzed-tag {
      display: inline-flex; align-items: center; gap: 0.25rem;
      font-size: 0.63rem; font-weight: 700; background: var(--indigo-light);
      color: var(--brand-accent); padding: 2px 6px; border-radius: 4px; margin-left: 0.4rem;
      vertical-align: middle;
    }

    /* ══ TOAST ══════════════════════════════════════════ */
    #toast-container {
      position: fixed; bottom: 1.5rem; right: 1.5rem;
      z-index: 9999; display: flex; flex-direction: column; gap: 0.5rem;
      pointer-events: none;
    }
    .toast {
      display: flex; align-items: center; gap: 0.65rem;
      padding: 0.7rem 1rem; border-radius: 6px;
      font-family: var(--font-ui); font-size: 0.83rem; font-weight: 600;
      box-shadow: var(--shadow-lg);
      pointer-events: auto; max-width: 340px;
      animation: toastIn 0.2s ease;
      backdrop-filter: blur(12px);
      position: relative; overflow: hidden;
    }
    @keyframes toastIn {
      from { opacity: 0; transform: translateY(8px) scale(0.97); }
      to   { opacity: 1; transform: translateY(0) scale(1); }
    }
    .toast.success { background: var(--green-bg); border: 1px solid var(--green-border); color: var(--green); }
    .toast.error   { background: var(--red-bg);  border: 1px solid var(--red-border);  color: var(--red); }
    .toast.info    { background: var(--brand-dim); border: 1px solid var(--brand-border); color: var(--brand-primary); }
    .toast-icon { flex-shrink: 0; font-size: 1rem; }
    .toast-progress {
      position: absolute; bottom: 0; left: 0; height: 2px;
      border-radius: 0 0 10px 10px;
      background: currentColor; opacity: 0.35;
      animation: toastProgress var(--toast-duration, 3.2s) linear forwards;
    }
    @keyframes toastProgress {
      from { width: 100%; }
      to   { width: 0%; }
    }

    /* ══ COMING SOON MODAL ══════════════════════════════ */
    .cs-modal {
      position: fixed; inset: 0; z-index: 10000;
      display: none; align-items: center; justify-content: center;
      padding: 24px;
    }
    .cs-modal.open { display: flex; animation: csFadeIn 0.15s ease; }
    .cs-modal-backdrop {
      position: absolute; inset: 0;
      background: rgba(15, 23, 42, 0.45);
      backdrop-filter: blur(2px);
      -webkit-backdrop-filter: blur(2px);
    }
    .cs-modal-card {
      position: relative; z-index: 1;
      width: 100%; max-width: 400px;
      background: var(--bg-elevated, #fff);
      border: 1px solid var(--border-subtle);
      border-radius: 12px;
      padding: 28px 28px 24px;
      box-shadow: 0 20px 60px rgba(15, 23, 42, 0.18);
      text-align: center;
      animation: csPop 0.18s cubic-bezier(0.2, 0.9, 0.3, 1.2);
    }
    .cs-modal-close {
      position: absolute; top: 10px; right: 10px;
      width: 28px; height: 28px; border-radius: 6px;
      background: transparent; border: 1px solid transparent;
      color: var(--text-muted); cursor: pointer;
      display: flex; align-items: center; justify-content: center;
      transition: background 0.12s, color 0.12s;
    }
    .cs-modal-close:hover { background: var(--bg-surface); color: var(--text-primary); }
    .cs-modal-icon {
      width: 48px; height: 48px; margin: 4px auto 14px;
      border-radius: 12px;
      background: var(--brand-dim);
      display: flex; align-items: center; justify-content: center;
      color: var(--brand-primary);
    }
    .cs-modal-icon svg { width: 24px; height: 24px; }
    .cs-modal-tag {
      display: inline-block;
      font-family: var(--font-ui); font-size: 10.5px; font-weight: 700;
      letter-spacing: 0.12em; color: var(--brand-primary);
      background: var(--brand-dim); padding: 3px 9px; border-radius: 4px;
      margin-bottom: 10px;
    }
    .cs-modal-title {
      font-family: var(--font-display); font-size: 20px; font-weight: 600;
      color: var(--text-primary); letter-spacing: -0.015em;
      line-height: 1.2; margin-bottom: 8px;
    }
    .cs-modal-body {
      font-family: var(--font-ui); font-size: 13px; font-weight: 400;
      color: var(--text-secondary); line-height: 1.55;
      margin-bottom: 22px;
    }
    .cs-modal-actions { display: flex; justify-content: center; gap: 8px; }
    .cs-modal-actions .btn-primary { min-width: 96px; justify-content: center; }
    @keyframes csFadeIn {
      from { opacity: 0; } to { opacity: 1; }
    }
    @keyframes csPop {
      from { opacity: 0; transform: translateY(6px) scale(0.98); }
      to   { opacity: 1; transform: translateY(0) scale(1); }
    }
    @media (prefers-reduced-motion: reduce) {
      .cs-modal.open, .cs-modal-card { animation: none !important; }
    }

    /* The credit meter used to live in the topbar. It is the token wallet now
       and it lives in the SIDEBAR (.nav-wallet) — one place, always visible,
       next to the plan it depends on. */

    /* Phase 2 — generation "finish moment" celebration (bottom-right card) */
    .finish-celebration {
      position: fixed; right: 24px; bottom: 24px; z-index: 10000;
      min-width: 280px; max-width: 380px;
      background: linear-gradient(135deg, #FFFFFF 0%, #F8FAFC 100%);
      border: 1px solid #D1FAE5; border-left: 4px solid #10B981;
      border-radius: 12px; padding: 14px 16px;
      box-shadow: 0 12px 32px rgba(16,185,129,0.18), 0 4px 12px rgba(0,0,0,0.08);
      font-family: var(--font-ui, inherit);
      animation: fc-in 0.45s cubic-bezier(.16,1,.3,1);
    }
    .finish-celebration.closing { animation: fc-out 0.3s ease forwards; }
    @keyframes fc-in  { from { transform: translateY(20px) scale(0.95); opacity: 0; } to { transform: none; opacity: 1; } }
    @keyframes fc-out { to   { transform: translateY(20px) scale(0.95); opacity: 0; } }
    .fc-head { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; }
    .fc-check {
      width: 26px; height: 26px; border-radius: 50%;
      background: #10B981; color: #fff; display: flex; align-items: center; justify-content: center;
      font-size: 16px; font-weight: 700; flex-shrink: 0;
      animation: fc-pop 0.5s cubic-bezier(.34,1.56,.64,1);
    }
    @keyframes fc-pop { 0% { transform: scale(0); } 70% { transform: scale(1.2); } 100% { transform: scale(1); } }
    .fc-title { font-weight: 700; font-size: 14px; color: #065F46; }
    .fc-keyword { font-size: 13px; color: #111827; margin-bottom: 8px; line-height: 1.3; word-break: break-word; }
    .fc-scores { display: flex; gap: 8px; margin-bottom: 10px; flex-wrap: wrap; }
    .fc-score-pill {
      display: inline-flex; align-items: baseline; gap: 4px;
      padding: 3px 9px; border-radius: 999px;
      background: rgba(16,185,129,0.1); color: #065F46;
      font-size: 11px; font-weight: 600;
    }
    .fc-score-pill .fc-score-val { font-size: 13px; font-weight: 700; }
    .fc-actions { display: flex; gap: 8px; }
    .fc-cta-primary {
      flex: 1; padding: 7px 12px; background: #10B981; color: #fff;
      border: 0; border-radius: 6px; font-size: 13px; font-weight: 600; cursor: pointer;
    }
    .fc-cta-primary:hover { background: #059669; }
    .fc-cta-dismiss {
      padding: 7px 10px; background: transparent; color: var(--text-muted);
      border: 1px solid var(--border, #E5E7EB); border-radius: 6px; font-size: 13px; cursor: pointer;
    }
    .fc-cta-dismiss:hover { background: var(--bg-surface, #F3F4F6); }

    /* Reduced motion: the running rail segment keeps its ring and stops
       sweeping. (This block also used to silence the topbar generation pill,
       which was removed 2026-08-26 — the percentage now lives per-card in the
       Article cell.) */
    @media (prefers-reduced-motion: reduce) {
      .al-rail-seg.is-active::before { animation: none !important; }
    }

    /* ══ ONBOARDING ══════════════════════════════════════ */
    #onboarding-state {
      display: none; flex: 1; flex-direction: column;
      align-items: center; justify-content: center;
      text-align: center; padding: 3rem;
    }

    /* ── First-paint skeleton ──────────────────────────────────────────────
       Visible by default (unlike its two siblings) because it is what stands
       in for the list until the first render. Mirrors the real .al-row
       anatomy — same column tracks, 44px height, 20px inset — so the data
       lands exactly where the bones were. Bones are static grey shapes; the
       motion is one translucent sweep per row (the ::after overlay), so
       every cell in a row shimmers in phase. */
    #al-skeleton { padding: 14px 20px 0; overflow: hidden; }
    .alsk-row {
      display: grid;
      grid-template-columns: minmax(280px,2.3fr) minmax(230px,1.4fr) minmax(150px,1fr) 96px 28px;
      align-items: center; gap: 0;
      height: 64px;   /* must match .al-row or the list jumps on first paint */
      border-bottom: 1px solid var(--border-subtle);
      position: relative; overflow: hidden;
    }
    .alsk-row::after {
      content: ""; position: absolute; inset: 0;
      transform: translateX(-100%);
      background: linear-gradient(90deg,
        transparent 0%, rgba(255,255,255,0.85) 50%, transparent 100%);
      animation: alsk-sweep 1.6s ease-in-out infinite;
    }
    /* Cascade: each row's sweep starts a beat after the one above it. */
    .alsk-row:nth-child(2)::after { animation-delay: 0.08s; }
    .alsk-row:nth-child(3)::after { animation-delay: 0.16s; }
    .alsk-row:nth-child(4)::after { animation-delay: 0.24s; }
    .alsk-row:nth-child(5)::after { animation-delay: 0.32s; }
    .alsk-row:nth-child(6)::after { animation-delay: 0.40s; }
    .alsk-row:nth-child(7)::after { animation-delay: 0.48s; }
    .alsk-row:nth-child(8)::after { animation-delay: 0.56s; }
    @keyframes alsk-sweep { to { transform: translateX(100%); } }
    .alsk-cell {
      display: flex; align-items: center; justify-content: center;
      min-width: 0; padding: 0 10px;
    }
    .alsk-cell.alsk-title { justify-content: flex-start; gap: 10px; padding: 0 12px; }
    .alsk-bone { background: var(--bg-subtle); border-radius: 4px; }
    .alsk-icon { width: 24px; height: 24px; border-radius: 5px; flex-shrink: 0; }
    .alsk-lines { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
    .alsk-kw  { height: 9px; width: var(--kw-w, 60%); }
    .alsk-sub { height: 7px; width: calc(var(--kw-w, 60%) * 0.55); border-radius: 3px; }
    /* Title widths vary per row so the column reads as real text, not bars. */
    .alsk-row:nth-child(1) { --kw-w: 72%; }
    .alsk-row:nth-child(2) { --kw-w: 46%; }
    .alsk-row:nth-child(3) { --kw-w: 63%; }
    .alsk-row:nth-child(4) { --kw-w: 81%; }
    .alsk-row:nth-child(5) { --kw-w: 52%; }
    .alsk-row:nth-child(6) { --kw-w: 68%; }
    .alsk-row:nth-child(7) { --kw-w: 40%; }
    .alsk-row:nth-child(8) { --kw-w: 58%; }
    .alsk-pill  { width: 54px; max-width: 85%; height: 16px; border-radius: 999px; }
    .alsk-score { width: 46px; max-width: 85%; height: 8px; }
    /* ≤1024px the real list becomes stacked cards (header hidden, no step
       grid) — collapse the skeleton the same way: icon + text lines only. */
    @media (max-width: 1024px) {
      #al-skeleton { padding: 10px 12px 0; }
      .alsk-row { display: flex; height: 58px; }
      .alsk-cell:not(.alsk-title) { display: none; }
      .alsk-cell.alsk-title { flex: 1; }
    }
    @media (prefers-reduced-motion: reduce) {
      .alsk-row::after { animation: none; display: none; }
    }
    /* .onboard-icon / -title / -sub: the old empty-state card, removed with
       its markup - the empty state is the getting-started list now. */
    .onboard-steps {
      display: flex; gap: 1.5rem; margin-bottom: 2rem; flex-wrap: wrap; justify-content: center;
    }
    .onboard-step {
      display: flex; flex-direction: column; align-items: center; gap: 0.4rem;
      max-width: 120px;
    }
    .onboard-step-num {
      width: 28px; height: 28px; border-radius: 50%;
      background: var(--brand-primary);
      color: var(--text-on-brand); font-family: var(--font-ui); font-size: 0.75rem; font-weight: 700;
      display: flex; align-items: center; justify-content: center;
      box-shadow: var(--shadow-brand);
    }
    .onboard-step-label { font-family: var(--font-ui); font-size: 0.72rem; color: var(--text-muted); text-align: center; line-height: 1.4; }

    /* ══ SEARCH / FILTER BAR ════════════════════════════ */
    .filter-pills { display: flex; gap: 0.3rem; flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; width: 100%; padding-top: 0.15rem; padding-bottom: 0.15rem; }
    .filter-pills::-webkit-scrollbar { display: none; }
    .filter-pill {
      font-size: 0.68rem; font-weight: 600; padding: 3px 9px;
      border-radius: 3px; border: 1px solid var(--border2);
      background: none; color: var(--text4); cursor: pointer;
      font-family: var(--font-ui); transition: border-color 0.15s, color 0.15s, background 0.15s;
    }
    .filter-pill:hover { border-color: var(--brand-accent); color: var(--brand-accent); }
    .filter-pill.active { background: var(--indigo-light); border-color: var(--brand-accent); color: var(--brand-accent); }

    /* ══ GENERATION PROGRESS ════════════════════════════ */
    .gen-step { font-size: 0.72rem; color: var(--brand-accent); font-weight: 500; }

    /* ══ MOBILE NAV ══════════════════════════════════════ */
    .mobile-header {
      display: none; align-items: center; justify-content: space-between;
      padding: 0 1rem; height: 56px; background: var(--nav-bg);
      border-bottom: 1px solid var(--border);
      position: fixed; top: 0; left: 0; right: 0; z-index: 300;
    }
    .mobile-header .brand-name { font-size: 0.9rem; font-weight: 700; color: var(--text-primary); }
    .mobile-burger {
      display: flex; flex-direction: column; justify-content: center; gap: 5px;
      background: none; border: none; cursor: pointer; padding: 6px;
      border-radius: 6px; width: 36px; height: 36px;
    }
    .mobile-burger span {
      display: block; width: 22px; height: 2px;
      background: var(--text-secondary); border-radius: 2px; transition: transform .25s, opacity .25s;
    }
    .mobile-burger.open span:nth-child(1) { transform: rotate(45deg) translate(5px,5px); }
    .mobile-burger.open span:nth-child(2) { opacity: 0; }
    .mobile-burger.open span:nth-child(3) { transform: rotate(-45deg) translate(5px,-5px); }
    .nav-overlay {
      display: none; position: fixed; inset: 0; background: rgba(36, 32, 26, 0.50);
      z-index: 250; backdrop-filter: blur(2px);
    }
    .nav-overlay.open { display: block; }

    @media (max-width: 768px) {
      .mobile-header { display: flex; }
      .nav-collapse-btn { display: none; }
      /* z-index must out-rank the desktop override's `z-index:200 !important`
         AND the .nav-overlay (250) + .mobile-header (300), or the drawer
         slides in BEHIND its own backdrop and stays invisible. */
      .nav { transform: translateX(-100%); transition: transform .25s ease !important; z-index: 400 !important; overflow-y: auto !important; -webkit-overflow-scrolling: touch; width: 220px !important; }
      .nav.collapsed { width: 220px !important; }
      .nav.collapsed .brand-name, .nav.collapsed .brand-tag { opacity: 1; width: auto; }
      .nav.collapsed .nav-section-label { opacity: 1; height: auto; padding: 1rem 1.25rem 0.4rem; }
      .nav.collapsed .nav-item-label { opacity: 1; width: auto; }
      .nav.collapsed .nav-item { justify-content: flex-start; padding: 0.6rem 0.75rem; }
      .nav.collapsed .nav-footer { padding: 1rem 1.25rem; display: block; }
      .nav.collapsed .nav-profile-mini { justify-content: flex-start; }
      .nav.collapsed .nav-profile-mini > div:last-child { opacity: 1; width: auto; display: block; }
      .nav.collapsed .nav-footer a { opacity: 1; width: auto; height: auto; padding: 6px; margin-top: 10px; display: block !important; }
      .nav.collapsed #nav-lang-toggle { opacity: 1; width: auto; height: auto; margin-bottom: 8px; }
      .nav.open { transform: translateX(0) !important; }
      body.nav-open { overflow: hidden; }
      html.nav-open { overflow: hidden; }
      .main, .main.nav-collapsed { margin-left: 0; padding-top: 56px; }

      /* View header */
      .view-header { flex-wrap: wrap; gap: 0.625rem; padding: 0.875rem 1rem; }
      .view-title { font-size: 1.1rem; }
      .view-subtitle { font-size: 0.75rem; }

      /* KPI strip: hidden on mobile */
      .kpi-strip { display: none; }
      .card-actions-btn { opacity: 1; }
      .card-del { opacity: 1; }
      .card-actions-menu { right: -8px; }
      .stat-bar-wrap { padding: 0 0.875rem 1.25rem; }
      .stat-bar-label { width: 90px; font-size: 0.7rem; }

      /* Profile */
      .profile-wrap { padding: 0.875rem; }
      .profile-card { padding: 1.1rem; }
      .profile-avatar-row { gap: 0.875rem; }

      /* Subscription */
      .sub-wrap { padding: 0.875rem; }
      .sub-grid { grid-template-columns: 1fr; max-width: 100%; }

      /* View header: status strip scrolls horizontally on mobile */
      .view-header .status-strip { overflow-x: auto; flex-wrap: nowrap; gap: 16px; }
      .topbar-title { font-size: 15px; }

      /* Modals */
      .modal-box { width: calc(100% - 2rem); padding: 1.25rem; max-width: none; max-height: 92vh; overflow-y: auto; }
#modal-add .modal-box { overflow-y: auto !important; }
      .field-row { grid-template-columns: 1fr; }
      .modal-actions { gap: 0.5rem; justify-content: stretch; }
      .modal-actions > * { flex: 1; justify-content: center; text-align: center; }
      .review-kw { max-width: 120px; font-size: 0.72rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
      /* Close block: solid, in the flow, nothing behind it */
      .review-close-fixed {
        display: flex; width: 44px; flex-shrink: 0; align-self: stretch;
        background: var(--red, #C0392B); color: #fff;
        align-items: center; justify-content: center;
        border: none; cursor: pointer; font-size: 1.4rem; font-weight: 700;
        border-left: 1px solid rgba(0,0,0,0.1);
        position: static; border-radius: 0;
      }
      .review-close-fixed:active { opacity: 0.8; }
      @keyframes scrollPulse {
        0%, 100% { opacity: 0.3; transform: translateX(-50%) translateY(0); }
        50% { opacity: 0.7; transform: translateX(-50%) translateY(3px); }
      }
/* ── Right panel: HIDDEN on mobile { display:flex !important }
`
         has the same specificity (0, 2, 0), so we have to scope by parent ID
         (0, 3 { display: none !important; }
      /* Mobile body typography — at 420px the 32px H1 + 72ch measure was
         forcing 2 characters per line. Cap H1 and remove the measure. */
      #ev-content { padding: 24px 20px; }
      #ev-content h1 { font-size: 22px; }
      #ev-content h2 { font-size: 18px; }
      #ev-content h3 { font-size: 16px; }
      #ev-content p,
      #ev-content ul,
      #ev-content ol,
      #ev-content blockquote { font-size: 16px; max-width: none; }
      .serp-body { flex-direction: column; overflow-y: auto; }
      .serp-pages { width: 100%; border-right: none; border-bottom: 1px solid var(--border); overflow-y: visible; max-height: none; padding: 0.875rem; }
      .serp-analysis-pane { overflow-y: visible; padding: 0.875rem; }
      .serp-head { padding: 0.875rem 1rem; }
      .serp-foot { flex-wrap: wrap; gap: 0.5rem; padding: 0.75rem 1rem; }
      .serp-foot-right { display: flex; gap: 0.5rem; flex: 1; justify-content: flex-end; }

      /* Toast */
      #toast-container { right: 0.75rem; left: 0.75rem; bottom: 1rem; }
      .toast { max-width: 100%; }
    }

    /* Article list responsive */
    @media (max-width: 1024px) {
      /* Tablet stacked-card layout — no horizontal scroll.
         Audit launch blocker: the 1020px-min-width grid forced horizontal
         overflow at 769–1024px ("unreadable mess"). Switch to stacked card.
         Selector elevated with .article-list-pane prefix to win over the
         later `.al-row { height: 52px !important }` global rule. */
      .article-list-pane { overflow-x: hidden; }
      .al-table-wrap { overflow-x: hidden; }
      .article-list-pane .al-row-header { display: none !important; }
      .article-list-pane .al-row {
        display: flex !important;
        flex-wrap: wrap;
        row-gap: 0.55rem;
        column-gap: 0;
        padding: 0.9rem 1.1rem !important;
        align-items: center;
        min-width: 0 !important;
        height: auto !important;
      }
      /* flex-basis must claim the full first line — with basis 0 the title packs
         onto one line with every step cell (all basis 0) and gets crushed to
         ~14px while the cells hold their min-width floor. */
      .article-list-pane .al-row .al-title-col { order: 1; flex: 1 1 calc(100% - 52px); min-width: 0; display: flex; align-items: center; gap: 10px; padding: 0 !important; border-right: 0 !important; }
      /* No column rules once the row wraps into a stack — a vertical line
         between two cells that sit on different lines marks nothing. And with
         no rules to run full-height, the stretch that closes them on desktop
         only distorts the wrapped cells here. */
      .article-list-pane .al-row .al-rail-cell { border-right: 0 !important; }
      .article-list-pane .al-row > .al-title-col,
      .article-list-pane .al-row > .al-rail-cell,
      .article-list-pane .al-row > .al-step-cell { align-self: center !important; }
      .article-list-pane .al-row .al-title-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
      .article-list-pane .al-row .al-kw { font-size: 0.92rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
      .article-list-pane .al-row .al-kw-sub { margin-top: 0; white-space: nowrap; }
      .article-list-pane .al-row .al-kebab-btn { order: 2; flex-shrink: 0; width: 36px; height: 36px; border-radius: 8px; display: flex; align-items: center; justify-content: center; padding: 0 !important; }
      /* Row 2: step cells share full width as equal pills */
      .article-list-pane .al-row .al-step-cell {
        order: 3; flex: 1 1 96px; min-width: 64px;
        font-size: 11.5px !important; padding: 6px 8px !important;
        justify-content: center;
        border-left: 1px solid var(--border-subtle) !important;
        height: 30px;
      }
      /* Row 3: SEO score full-width below */
      .article-list-pane .al-row .al-cell-seo { order: 4; width: 100%; padding: 0 !important; }
      /* Scoreless cards: the stacked layout otherwise shows an orphaned "—"
         alone on its own line — pure noise. Hide the whole score row. */
      .article-list-pane .al-row .al-cell-seo:has(.al-cell-dash) { display: none; }
    }
    @media (max-width: 768px) {
      .status-strip { display: none; }
      .article-list-pane .al-row-header { display: none !important; }

      /* Filter bar: wrap to 2 rows — search full-width on top, selects share bottom row */
      .al-filter-bar { flex-wrap: wrap; gap: 6px; }
      .al-search-wrap { flex: 1 1 100%; }
      .al-select { flex: 1 1 0; min-width: 0; width: auto !important; }

      /* Article row: flex-wrap layout for the 7-column pipeline grid.
         Row 1: title (flex:1) + kebab (36px)
         Row 2: the 4 step cells (persona/brief/interview/article) at equal share
         Row 3: SEO score
         Selector elevated to .article-list-pane .al-row to win over the
         later global .al-row{height:52px!important} rule. */
      .article-list-pane .al-row {
        display: flex !important;
        flex-wrap: wrap;
        row-gap: 0.4rem;
        column-gap: 0;
        padding: 0.75rem 1rem !important;
        align-items: center;
        min-width: 0 !important;
        height: auto !important;
      }
      /* Row 1: title + kebab */
      .article-list-pane .al-row .al-title-col { order: 1; flex: 1 1 calc(100% - 48px); min-width: 0; display: flex; align-items: center; }
      .article-list-pane .al-row .al-icon-box { display: none; }
      .article-list-pane .al-row .al-title-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
      .article-list-pane .al-row .al-kw { font-size: 0.82rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
      .article-list-pane .al-row .al-kw-sub { margin-top: 0; white-space: nowrap; }
      .article-list-pane .al-row .al-kebab-btn { order: 2; flex-shrink: 0; width: 36px; height: 36px; border-radius: 8px; display: flex; align-items: center; justify-content: center; }
      /* Row 2: step cells (persona / brief / interview / article) */
      .article-list-pane .al-row .al-step-cell { order: 3; flex: 1 1 80px; min-width: 55px; font-size: 11px !important; padding: 4px 6px !important; justify-content: center; height: 28px; }
      /* Row 3: SEO score */
      .article-list-pane .al-row .al-cell-seo { order: 4; width: 100%; }
      .article-list-pane .al-row .al-cell-seo:has(.al-cell-dash) { display: none; }

      .article-list-pane { padding: 0.5rem 0.75rem; overflow-x: hidden; }
      .al-table-wrap { overflow-x: hidden; }
      .planner-header-wrap { padding: 0.875rem 0.75rem 0.5rem; }
      /* Touch targets ≥ ~38px on phones (were 24-26px) */
      .al-group-stop, .al-group-del { width: 36px !important; height: 36px !important; }

      /* Add Topic modal: bottom sheet — panes stack, whole sheet scrolls */
      #modal-add { align-items: flex-end !important; }
      #modal-add .modal-box {
        display: flex !important; flex-direction: column !important;
        border-radius: 16px 16px 0 0 !important;
        width: 100% !important; max-width: 100% !important; margin: 0 !important;
        max-height: 92vh; max-height: 92dvh;
        overflow-y: auto; -webkit-overflow-scrolling: touch;
        /* no overflow:hidden here — max-height + flex + overflow:hidden clips
           native <select> dropdowns in Chrome (see CLAUDE.md CSS rules) */
      }
      #modal-add .am-pane-left { padding: 0.875rem 1rem 0.75rem; }
      #modal-add .am-rail { border-left: none; border-top: 1px solid #E8EEF6; border-radius: 0; padding: 0.875rem 1rem 1rem; }
      #modal-add .am-rail-cta { padding-top: 0.75rem; }
      #modal-add .add-modal-body { gap: 0.5rem; }
      #modal-add .field-row { grid-template-columns: 1fr 1fr !important; gap: 0.35rem !important; }
      #modal-add input[type="text"], #modal-add input[type="number"] { padding: 0.375rem 0.6rem; font-size: 0.82rem; }
      /* Keep the left padding that clears the inline search icon — the generic
         rule above was flattening it and the icon sat on the first letter */
      #modal-add #add-keyword { padding-left: 36px; }
      #modal-add select { padding: 0.375rem 1.75rem 0.375rem 0.6rem; font-size: 0.82rem; }
      #modal-add textarea { height: 52px; min-height: 52px; overflow-y: auto; resize: none; font-size: 0.82rem; }
      #modal-add .hint { display: none; }
    }
    @media (max-width: 480px) {
      .profile-card { padding: 0.875rem; }
      .view-header { padding: 0.75rem 0.875rem; }
      .modal-box { width: 100%; margin: 0; border-radius: 8px 16px 0 0; align-self: flex-end; max-width: 100% !important; padding: 1.25rem; max-height: 90vh; overflow-y: auto; }
/* override per-modal overflow:hidden so tall modals scroll on small phones */
#modal-seo .modal-box, #modal-audit .modal-box { overflow-y: auto !important; }
      /* add modal uses flex-column bottom sheet — keep hidden on box, body scrolls */
      /* overflow:hidden removed — clips native <select> popups (CLAUDE.md CSS rules) */
      #modal-add .field-row { grid-template-columns: 1fr 1fr !important; gap: 0.35rem !important; }
      .field-row { grid-template-columns: 1fr !important; gap: 0.6rem !important; }
      .modal-overlay.open { align-items: flex-end; }
      /* Client cards mobile: actions always visible — back in flow so they
         never cover the name (cards are full-width here, space is fine) */
      .client-card { padding: 1rem; }
      .client-actions { opacity: 1; position: static; transform: none; padding-left: 0; pointer-events: auto; background: none; }
      .client-meta { white-space: normal; }
      .client-empty-state { padding: 2.5rem 1rem; }
    }
  /* Lang toggle */
  .lang-toggle{display:flex;gap:4px;align-items:center}
  .lang-btn{font-family:var(--font-ui);background:none;border:1px solid var(--border);color:var(--text4);font-size:.68rem;font-weight:700;padding:6px 10px;border-radius:3px;cursor:pointer;transition:.15s;line-height:1;min-height:32px}
  .lang-btn.active{background:var(--brand-primary);border-color:var(--brand-primary);color:var(--text-on-brand)}
  .lang-btn:hover:not(.active){border-color:var(--brand-border);color:var(--brand-text)}

  /* ══ ONBOARDING WIZARD ════════════════════════════════ */
  .wizard-progress {
    display: flex; align-items: center; justify-content: center;
    gap: 0; margin-bottom: 2rem;
  }
  .wizard-step-node {
    display: flex; flex-direction: column; align-items: center; gap: 0.35rem;
    position: relative;
  }
  .wizard-step-circle {
    width: 28px; height: 28px; border-radius: 50%;
    font-family: var(--font-ui); font-size: 0.72rem; font-weight: 700;
    display: flex; align-items: center; justify-content: center;
    border: 2px solid var(--border-strong);
    color: var(--text4);
    background: transparent;
    transition: background 0.2s, border-color 0.2s, color 0.2s;
    flex-shrink: 0;
  }
  .wizard-step-circle.active {
    background: var(--brand-primary); border-color: var(--brand-primary);
    color: var(--text-on-brand);
  }
  .wizard-step-circle.done {
    background: var(--brand-primary); border-color: var(--brand-primary);
    color: var(--text-on-brand);
    position: relative;
  }
  /* CSS-only checkmark for completed steps — avoids innerHTML */
  .wizard-step-circle.done::after {
    content: '';
    display: block;
    width: 10px; height: 6px;
    border-left: 2px solid var(--text-on-brand);
    border-bottom: 2px solid var(--text-on-brand);
    transform: rotate(-45deg) translate(1px, -1px);
  }
  .wizard-step-label {
    font-family: var(--font-ui); font-size: 0.66rem; font-weight: 500;
    color: var(--text4); white-space: nowrap; text-align: center;
    transition: color 0.2s;
  }
  .wizard-step-label.active { color: var(--brand-primary); font-weight: 600; }
  .wizard-connector {
    width: 40px; height: 2px;
    background: var(--border-default);
    margin: 0 4px;
    margin-bottom: 18px; /* offset to align with circles, not labels */
    flex-shrink: 0;
    transition: background 0.2s;
  }
  .wizard-connector.done { background: var(--brand-primary); }

  .wizard-body { min-height: 160px; }
  .wizard-pane { display: none; flex-direction: column; gap: 0.75rem; }
  .wizard-pane.active { display: flex; }

  .wizard-question {
    font-family: var(--font-display); font-size: 1rem; font-weight: 700;
    color: var(--text); margin-bottom: 0.75rem; line-height: 1.3;
  }
  .wizard-skip {
    font-family: var(--font-ui); font-size: 0.75rem; color: var(--text4);
    background: none; border: none; cursor: pointer; padding: 0;
    text-decoration: underline; text-underline-offset: 2px;
    margin-top: 0.25rem; text-align: left; display: inline-block;
    transition: color 0.15s;
  }
  .wizard-skip:hover { color: var(--text2); }

  .wizard-summary {
    background: var(--bg-surface); border: 1px solid var(--border-default);
    border-radius: 6px; padding: 1rem 1.125rem;
    display: flex; flex-direction: column; gap: 0.5rem;
  }
  .wizard-summary-row {
    display: flex; align-items: baseline; gap: 0.5rem;
    font-family: var(--font-body); font-size: 0.825rem;
  }
  .wizard-summary-label {
    font-weight: 600; color: var(--text2); min-width: 96px; flex-shrink: 0;
    font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.04em;
  }
  .wizard-summary-val {
    color: var(--text); font-weight: 500;
  }
  .wizard-generate-btn {
    justify-content: center; padding: 0.75rem 1.5rem;
    font-size: 0.9rem;
  }

  .wizard-nav {
    display: flex; gap: 0.75rem; justify-content: space-between;
    align-items: center; margin-top: 1.5rem;
  }
  /* On step 3, wizard-nav-right holds only the generate button; let it grow */
  .wizard-nav-right { display: flex; gap: 0.75rem; flex: 1; justify-content: flex-end; }

  @media (max-width: 480px) {
    .wizard-connector { width: 24px; }
    #modal-wizard.modal-overlay.open { align-items: flex-end; }
  }

  /* ── DEMO MODE ──────────────────────────────────── */
  .demo-banner {
    display: none;
    background: linear-gradient(135deg, #0051D5 0%, #316BF3 100%);
    padding: 0.85rem 1.5rem;
    font-family: var(--font-ui);
    z-index: 10;
    position: relative;
  }
  .demo-banner-inner {
    max-width: 960px;
    margin: 0 auto;
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
  }
  .demo-banner-badge {
    background: rgba(255,255,255,0.18);
    color: #fff;
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    padding: 0.18rem 0.55rem;
    border-radius: 20px;
    border: 1px solid rgba(255,255,255,0.3);
    white-space: nowrap;
    flex-shrink: 0;
  }
  .demo-banner-text {
    color: rgba(255,255,255,0.92);
    font-size: 0.83rem;
    flex: 1;
    min-width: 160px;
  }
  .demo-banner-text strong { color: #fff; }
  .demo-banner-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-shrink: 0;
  }
  .demo-banner .btn-demo-cta {
    background: #fff;
    color: #0051D5;
    border: none;
    padding: 0.35rem 1.1rem;
    font-size: 0.79rem;
    font-weight: 600;
    border-radius: 6px;
    cursor: pointer;
    text-decoration: none;
    display: inline-block;
    white-space: nowrap;
    pointer-events: auto !important;
    opacity: 1 !important;
    transition: background 0.15s, box-shadow 0.15s;
  }
  .demo-banner .btn-demo-cta:hover { background: #EEF2FF; box-shadow: 0 2px 8px rgba(0,0,0,0.12); }
  .demo-banner .btn-demo-plans {
    color: rgba(255,255,255,0.85);
    font-size: 0.79rem;
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
    pointer-events: auto !important;
    opacity: 1 !important;
    padding: 0.35rem 0.5rem;
    border-radius: 6px;
    transition: color 0.15s;
  }
  .demo-banner .btn-demo-plans:hover { color: #fff; }

  /* Feature spotlight strip */
  .demo-spotlight {
    display: none;
    background: var(--bg-elevated);
    border-bottom: 1px solid var(--border);
    padding: 0.7rem 1.5rem;
  }
  .demo-spotlight-inner {
    max-width: 960px;
    margin: 0 auto;
    display: flex;
    align-items: center;
    gap: 0.5rem 1.5rem;
    flex-wrap: wrap;
  }
  .demo-spotlight-label {
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--text3);
    white-space: nowrap;
    flex-shrink: 0;
  }
  .demo-spotlight-items {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
  }
  .demo-spot-chip {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: 20px;
    padding: 0.22rem 0.65rem 0.22rem 0.5rem;
    font-size: 0.75rem;
    color: var(--text2);
    white-space: nowrap;
  }
  .demo-spot-chip svg { flex-shrink: 0; color: var(--brand-primary); }

  body.demo-mode .demo-spotlight { display: block; }
  body.demo-mode .demo-banner { display: block; }

  body.demo-mode .btn-primary,
  body.demo-mode .btn-ghost,
  /* The destructive confirm button. This class was assigned by showConfirm
     but never defined outside demo mode, so "Supprimer" rendered as a bare
     native button - the one control in the app where looking unfinished
     actively costs trust. Declared before the demo-mode override so that
     override still wins. */
  .btn-danger {
    background: var(--red); color: #fff; border: 1px solid var(--red);
    border-radius: 6px; padding: 0.5rem 1rem;
    font-family: var(--font-ui); font-size: 0.875rem; font-weight: 600;
    cursor: pointer; transition: background .15s, border-color .15s;
  }
  .btn-danger:hover { background: #A83226; border-color: #A83226; }

  body.demo-mode .btn-danger {
    pointer-events: none;
    opacity: 0.4;
  }
  /* Re-enable the demo banner CTAs */
  body.demo-mode .demo-banner .btn-demo-cta,
  body.demo-mode .demo-banner .btn-demo-plans { pointer-events: auto; opacity: 1; }
  @media (max-width: 640px) {
    .demo-banner-inner { gap: 0.6rem; }
    .demo-spotlight-items { gap: 0.35rem; }
    .demo-spot-chip { font-size: 0.7rem; }
  }

  /* ─────────────────────────────────────────────────────────
     Writer streaming drawer — Digital Ink palette, typed loader states.
     UX rules (Nielsen): under 1s no indicator, 1-10s indeterminate loader,
     over 10s show progress + step context + path to recovery.
     ───────────────────────────────────────────────────────── */
  #dp-wsd { display: none; flex-direction: column; width: 100%; }

  .wsd-header {
    display: flex; align-items: flex-start; justify-content: space-between;
    padding: 0.25rem 0 0.85rem 0;
    border-bottom: 1px solid var(--border-subtle);
    margin-bottom: 0.9rem;
  }
  .wsd-title {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 1.05rem;
    letter-spacing: -0.015em;
    color: var(--text-primary);
    margin: 0;
    line-height: 1.2;
  }
  .wsd-subtitle {
    font-family: var(--font-ui);
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--text-muted);
    margin: 0.2rem 0 0 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .wsd-subtitle-label {
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-size: 0.62rem;
    font-weight: 600;
    margin-right: 0.35rem;
  }

  .wsd-body { display: flex; flex-direction: column; gap: 0.6rem; }

  /* Step card — base */
  .wsd-card {
    position: relative;
    border: 1px solid var(--border-subtle);
    border-radius: 12px;
    padding: 0.85rem 1rem;
    background: var(--bg-elevated);
    transition: border-color 0.25s ease, background 0.25s ease,
                box-shadow 0.25s ease, opacity 0.25s ease;
    overflow: hidden;
  }

  /* Pending — quiet, not drawing attention */
  .wsd-card.pending { opacity: 0.55; }
  .wsd-card.pending .wsd-state {
    color: var(--text-muted);
    border-color: var(--border-strong);
    background: var(--bg-elevated);
  }

  /* Active — primary focus. Top-edge gradient sweep signals "work flowing". */
  .wsd-card.active {
    border-color: var(--brand-border);
    background: var(--bg-elevated);
    box-shadow: 0 1px 0 var(--brand-border),
                0 4px 14px rgba(0, 81, 213, 0.08);
  }
  .wsd-card.active::before {
    content: '';
    position: absolute;
    inset: 0 0 auto 0;
    height: 2px;
    background: linear-gradient(
      90deg,
      transparent 0%,
      var(--brand-primary) 40%,
      var(--brand-container) 60%,
      transparent 100%);
    background-size: 220% 100%;
    animation: wsd-sweep 1.6s linear infinite;
  }

  /* Done — resolved, subtle success hue */
  .wsd-card.done {
    border-color: var(--success-border);
    background: var(--bg-elevated);
  }

  /* Error — failed step, matches banner color language */
  .wsd-card.error {
    border-color: var(--error-border);
    background: var(--error-bg);
  }

  /* Paused — interview gate waiting for writer input */
  .wsd-card.paused {
    border-color: var(--brand-primary);
    background: color-mix(in srgb, var(--brand-primary) 5%, var(--bg-base));
  }
  .wsd-card.paused .wsd-state {
    background: var(--brand-primary);
    border-color: var(--brand-primary);
  }
  .wsd-card.paused .wsd-state::after { content: "⏸"; color: #fff; font-size: 0.6rem; }
  .wsd-interview-cta {
    display: none;
    margin-top: 0.5rem;
    padding: 0.35rem 0.75rem;
    background: var(--brand-primary);
    color: #fff;
    border: none;
    border-radius: 6px;
    font-size: 0.75rem;
    font-weight: 600;
    cursor: pointer;
    font-family: var(--font-ui);
    transition: opacity 0.15s;
  }
  .wsd-interview-cta:hover { opacity: 0.85; }
  .wsd-card.paused .wsd-interview-cta { display: inline-block; }

  .wsd-card-head {
    display: flex; align-items: center; gap: 0.65rem;
    font-family: var(--font-ui);
    font-size: 0.9rem;
    color: var(--text-primary);
  }

  /* Step indicator — numbered in pending, conic spinner in active,
     check in done, x in error. Single 22px slot for all states. */
  .wsd-state {
    width: 22px; height: 22px;
    border-radius: 50%;
    flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    font-family: var(--font-ui);
    font-size: 0.72rem;
    font-weight: 600;
    line-height: 1;
    border: 1.5px solid currentColor;
    color: var(--text-muted);
    background: var(--bg-elevated);
    position: relative;
  }
  .wsd-state::after {
    content: attr(data-step);
    color: var(--text-muted);
  }

  /* Active step: gradient-filled circle + rotating conic arc ring */
  .wsd-card.active .wsd-state {
    border-color: transparent;
    background: linear-gradient(135deg, var(--brand-primary), var(--brand-container));
    color: #fff;
  }
  .wsd-card.active .wsd-state::after {
    color: #fff;
    z-index: 1;
  }
  .wsd-card.active .wsd-state::before {
    content: '';
    position: absolute;
    inset: -3px;
    border-radius: 50%;
    background: conic-gradient(
      from 0deg,
      var(--brand-container) 0deg,
      var(--brand-primary) 90deg,
      transparent 180deg,
      transparent 360deg);
    -webkit-mask: radial-gradient(circle, transparent 55%, #000 58%);
            mask: radial-gradient(circle, transparent 55%, #000 58%);
    animation: wsd-spin 1.1s linear infinite;
  }

  /* Done step: success green with check */
  .wsd-card.done .wsd-state {
    border-color: transparent;
    background: var(--success);
    color: #fff;
  }
  .wsd-card.done .wsd-state::after { content: "✓"; color: #fff; }

  /* Error step: red with × */
  .wsd-card.error .wsd-state {
    border-color: transparent;
    background: var(--error);
    color: #fff;
  }
  .wsd-card.error .wsd-state::after { content: "×"; color: #fff; font-size: 0.95rem; }

  @keyframes wsd-sweep {
    0%   { background-position: 120% 0; }
    100% { background-position: -120% 0; }
  }
  @keyframes wsd-spin {
    to { transform: rotate(360deg); }
  }
  @keyframes wsd-slide-in {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
  }
  @media (prefers-reduced-motion: reduce) {
    .wsd-card.active::before,
    .wsd-card.active .wsd-state::before,
    .wsd-skeleton-line { animation: none; }
  }

  .wsd-card-title {
    font-family: var(--font-ui);
    font-weight: 600;
    letter-spacing: -0.005em;
  }
  .wsd-card-summary {
    margin: 0.45rem 0 0 2.3rem;
    font-family: var(--font-ui);
    font-size: 0.78rem;
    color: var(--text-muted);
    line-height: 1.45;
  }

  /* Writer stream body — only rendered when parent card is active */
  .wsd-writer-body {
    display: none;
    margin: 0.65rem 0 0 0;
    padding: 0.75rem 0.85rem;
    background: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: 8px;
    font-family: var(--font-ui);
    font-size: 0.82rem;
    line-height: 1.55;
    color: var(--text-primary);
    max-height: 48vh;
    overflow-y: auto;
    white-space: pre-wrap;
    word-wrap: break-word;
    min-height: 2.6em;
  }
  .wsd-card.active .wsd-writer-body,
  .wsd-card.done .wsd-writer-body,
  .wsd-card.error .wsd-writer-body {
    display: block;
  }
  /* Skeleton only shimmers while the card is actively streaming — once it errors
     we don't want a false "working" signal over dead content. */
  .wsd-card.error .wsd-writer-body:empty::before,
  .wsd-card.error .wsd-writer-body:empty::after,
  .wsd-card.done  .wsd-writer-body:empty::before,
  .wsd-card.done  .wsd-writer-body:empty::after {
    display: none;
  }

  /* Skeleton lines (shown while writer is active + empty) */
  .wsd-writer-body:empty::before {
    content: '';
    display: block;
    height: 0.7em;
    border-radius: 4px;
    background: linear-gradient(
      90deg,
      var(--bg-subtle) 0%,
      rgba(219, 225, 255, 0.55) 50%,
      var(--bg-subtle) 100%);
    background-size: 220% 100%;
    animation: wsd-sweep 1.6s linear infinite;
    margin-bottom: 0.55em;
    width: 92%;
  }
  .wsd-writer-body:empty::after {
    content: '';
    display: block;
    height: 0.7em;
    border-radius: 4px;
    background: linear-gradient(
      90deg,
      var(--bg-subtle) 0%,
      rgba(219, 225, 255, 0.55) 50%,
      var(--bg-subtle) 100%);
    background-size: 220% 100%;
    animation: wsd-sweep 1.6s linear infinite;
    animation-delay: -0.4s;
    width: 70%;
  }

  /* Footer — step counter left, (retry lives in banner, not here) */
  .wsd-footer {
    padding: 0.85rem 0 0 0;
    border-top: 1px solid var(--border-subtle);
    margin-top: 0.9rem;
    font-family: var(--font-ui);
    font-size: 0.72rem;
    color: var(--text-muted);
    display: flex; justify-content: space-between; align-items: center;
    letter-spacing: 0.01em;
  }
  .wsd-step-counter { font-weight: 500; }
  .wsd-step-counter strong {
    color: var(--text-primary);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
  }

  /* Error banner — contextual, contains retry inline */
  .wsd-error-banner {
    display: none;
    align-items: center; justify-content: space-between; gap: 0.75rem;
    background: var(--error-bg);
    border: 1px solid var(--error-border);
    color: var(--error);
    padding: 0.65rem 0.75rem 0.65rem 0.85rem;
    border-radius: 8px;
    margin-bottom: 0.75rem;
    font-family: var(--font-ui);
    font-size: 0.8rem;
    animation: wsd-slide-in 0.25s ease-out;
  }
  .wsd-error-banner[data-visible="1"] { display: flex; }
  .wsd-error-text { flex: 1; min-width: 0; line-height: 1.4; }
  .wsd-error-title { font-weight: 600; color: var(--error); }
  .wsd-error-hint {
    display: block;
    color: var(--text-secondary);
    font-size: 0.72rem;
    margin-top: 0.15rem;
    font-weight: 500;
  }

  /* Retry button — lives inside the error banner, gradient primary */
  .wsd-retry-btn {
    background: linear-gradient(135deg, var(--brand-primary), var(--brand-container));
    color: var(--text-on-brand);
    border: 0;
    padding: 0.4rem 0.85rem;
    border-radius: 8px;
    cursor: pointer;
    font-family: var(--font-ui);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    white-space: nowrap;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
    box-shadow: 0 1px 2px rgba(0, 81, 213, 0.20);
    flex-shrink: 0;
  }
  .wsd-retry-btn:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 10px rgba(0, 81, 213, 0.22);
  }
  .wsd-retry-btn:active { transform: translateY(0); }
  .wsd-retry-btn:focus-visible {
    outline: 2px solid var(--brand-primary);
    outline-offset: 2px;
  }
    /* [nav-hover-fly-out] REMOVED — dead 64px rail + hover-expand block.
       Replaced by the NEW SIDEBAR OVERRIDE (48px obsidian) below.
       The hover rules were firing and shifting icon alignment from center
       to flex-start on every nav hover, causing the visible icon jump. */

    /* ══ PANEL HEADER: stronger visual treatment ════════════════════════ */
    .dp-step-header {
      background: var(--bg-elevated, #f8f9fa);
      border-bottom: 1.5px solid var(--border-subtle);
      padding: 1.25rem 1.5rem 1rem;
    }
    .dp-step-icon {
      display: flex; align-items: center; justify-content: center;
      width: 30px; height: 30px; border-radius: 7px;
      background: var(--bg-base); border: 1px solid var(--border-subtle);
      color: var(--text-secondary); flex-shrink: 0;
    }
    .dp-step-title { font-size: 1rem; font-weight: 700; letter-spacing: -0.01em; }
    .dp-step-body { padding: 1.5rem; gap: 1.5rem; }
    /* ── Persona numbered-section layout ───────────────────────────────── */
    .dp-persona-body { gap: 0; padding: 0; }
    .dp-persona-section {
      padding: 1.25rem 1.5rem 1.35rem;
      border-bottom: 1px solid var(--border-subtle);
    }
    .dp-persona-section:last-child { border-bottom: none; }
    .dp-persona-section-head {
      display: flex; align-items: center; gap: 0.55rem;
      margin-bottom: 0.85rem;
    }
    .dp-persona-num {
      font-family: var(--font-code); font-size: 10px; font-weight: 800;
      color: var(--brand-primary); background: var(--brand-dim);
      border: 1px solid var(--brand-border);
      width: 18px; height: 18px; border-radius: 4px; flex-shrink: 0;
      display: flex; align-items: center; justify-content: center; line-height: 1;
    }
    .dp-persona-label {
      font-family: var(--font-ui); font-size: 10.5px; font-weight: 700;
      text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-muted);
    }
    .dp-persona-list {
      list-style: none; margin: 0; padding: 0;
      display: flex; flex-direction: column; gap: 0.5rem;
    }
    .dp-persona-list li {
      font-family: var(--font-ui); font-size: 13px; color: var(--text-primary);
      line-height: 1.6; padding: 0.55rem 0.75rem 0.55rem 0.9rem;
      background: var(--bg-base); border-radius: 7px;
      border: 1px solid var(--border-subtle);
      position: relative;
    }
    .dp-persona-list li::before {
      content: ''; position: absolute; left: 0;
      top: 0; bottom: 0; width: 3px; border-radius: 7px 0 0 7px;
      background: var(--brand-primary); opacity: 0.35;
    }
    /* ── Artifact list (brief, interview) ──────────────────────────────── */
    .dp-artifact-list { list-style: none; padding: 0; gap: 0.3rem; }
    .dp-artifact-list li {
      font-size: 13px; padding: 0.45rem 0.75rem 0.45rem 0.9rem;
      background: var(--bg-elevated); border-radius: 6px;
      border: 1px solid var(--border-subtle);
      position: relative; line-height: 1.55;
    }
    .dp-artifact-list li::before {
      content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
      border-radius: 6px 0 0 6px; background: var(--text-muted); opacity: 0.3;
    }
    /* ── Brief panel ──────────────────────────────────────────────────────
       Renders the brief DOCUMENT: the angle, the thesis, the outline with the
       planner's placements filed under each section, the traps and the
       openings.

       Read order is deliberate and it is not the order the data arrives in:

         1. the STRIP  — what this brief is, in numbers, before any prose.
         2. the DECISION — angle + thesis. The only part a human actually
            judges, so it is the only block that gets brand weight.
         3. the OUTLINE — the mechanics. Proportional budget bars, because
            "450 words" means nothing next to "300" until you can see it.
         4. the CONSTRAINTS — traps and openings, quietest of the four.

       Earlier every block was the same white card with the same eyebrow, so
       the thesis and a bullet about openings carried identical visual weight.
       When everything shouts, nothing is heard. */
    .dp-brief-strip {
      flex-shrink: 0;
      display: flex; flex-wrap: wrap; align-items: center; gap: 0 0.85rem;
      padding: 0.6rem 1rem; background: var(--bg-surface);
      border-bottom: 1px solid var(--border-subtle);
    }
    .dp-brief-stat {
      font-family: var(--font-ui); font-size: 11px; color: var(--text-muted);
      display: inline-flex; align-items: baseline; gap: 0.28rem;
    }
    .dp-brief-stat b {
      font-size: 13px; font-weight: 700; color: var(--text-primary);
      font-variant-numeric: tabular-nums;
    }
    .dp-brief-scroll {
      padding: 0.85rem 1rem 1.1rem;
      overflow-y: auto; flex: 1; min-height: 0;
      display: flex; flex-direction: column; gap: 0.6rem;
    }
    .dp-brief-card {
      background: var(--bg-elevated);
      border: 1px solid var(--border-subtle);
      border-radius: 10px; padding: 0.85rem 1rem;
      display: flex; flex-direction: column; gap: 0.5rem;
    }
    .dp-brief-card.dp-brief-warn {
      border-color: var(--warning-border); background: var(--amber-bg);
    }
    /* 4.2 — coverage-only is a STATEMENT, not a warning. Neutral surface on
       purpose: an article with no first-hand knowledge is a legitimate output,
       it just must not be indistinguishable from one that has it. */
    .dp-brief-card.dp-brief-note {
      background: var(--bg-surface); border-style: dashed;
    }
    /* The decision. The one block allowed to carry brand colour. */
    .dp-brief-card.dp-brief-decision {
      border-color: var(--brand-border);
      box-shadow: inset 3px 0 0 var(--brand-primary);
      padding-left: 1.15rem;
    }
    .dp-brief-eyebrow {
      font-family: var(--font-ui); font-size: 10px; font-weight: 700;
      text-transform: uppercase; letter-spacing: 0.1em; color: var(--text-muted);
      display: flex; align-items: center; gap: 0.4rem;
    }
    .dp-brief-count, .dp-brief-budget {
      font-weight: 600; letter-spacing: 0.02em; text-transform: none;
      background: var(--brand-dim); color: var(--brand-primary);
      border-radius: 20px; padding: 1px 7px; font-size: 10px;
      font-variant-numeric: tabular-nums;
    }
    .dp-brief-letter {
      font-weight: 700; letter-spacing: 0.02em;
      background: var(--brand-primary); color: var(--text-on-brand);
      border-radius: 4px; padding: 1px 6px; font-size: 10px;
    }
    .dp-brief-angle {
      font-family: var(--font-ui); font-size: 13.5px; color: var(--text-primary);
      line-height: 1.6;
    }
    .dp-brief-thesis {
      font-family: var(--font-ui); font-size: 13px; color: var(--text-primary);
      line-height: 1.6; font-style: italic;
      padding: 0.55rem 0.8rem; border-left: 3px solid var(--brand-primary);
      background: var(--brand-dim); border-radius: 0 6px 6px 0;
    }
    /* One outline section. NOTE: no overflow:hidden here — a details/select
       inside a flex scroll container gets clipped by it (see CLAUDE.md). */
    .dp-brief-sec {
      border-top: 1px solid var(--border-subtle);
      padding-top: 0.6rem; margin-top: 0.15rem;
      display: flex; flex-direction: column; gap: 0.3rem;
    }
    .dp-brief-sec:first-of-type { border-top: none; padding-top: 0; margin-top: 0; }
    .dp-brief-sec-head { display: flex; align-items: baseline; gap: 0.5rem; }
    .dp-brief-sec-n {
      flex-shrink: 0; font-family: var(--font-ui); font-size: 10px; font-weight: 700;
      color: var(--brand-primary); background: var(--brand-dim);
      border-radius: 5px; padding: 1px 6px; font-variant-numeric: tabular-nums;
    }
    .dp-brief-sec-title {
      font-family: var(--font-ui); font-size: 13px; font-weight: 600;
      color: var(--text-primary); line-height: 1.4; flex: 1; min-width: 0;
    }
    .dp-brief-sec-w {
      flex-shrink: 0; font-family: var(--font-ui); font-size: 10.5px;
      color: var(--text-muted); font-variant-numeric: tabular-nums;
    }
    /* Share of the article this section is budgeted. A number the Writer is
       held to is worth seeing as a proportion — a 700-word section next to
       three 150s is a plan problem you can spot in one glance and cannot spot
       in a column of digits. */
    .dp-brief-bar {
      height: 3px; border-radius: 2px; background: var(--bg-subtle);
      overflow: hidden; margin: 0.1rem 0 0.05rem;
    }
    .dp-brief-bar > span {
      display: block; height: 100%; border-radius: 2px;
      background: var(--brand-primary); opacity: 0.55;
    }
    .dp-brief-sec-job {
      font-family: var(--font-ui); font-size: 12px; color: var(--text-muted);
      line-height: 1.5;
    }
    .dp-brief-items { display: flex; flex-direction: column; gap: 0.3rem; margin-top: 0.2rem; }
    /* A planner placement. The bucket it came from ([fact] / [trust] / …) used
       to be printed as literal bracket text; it is a type, so it reads as one. */
    .dp-brief-item {
      font-family: var(--font-ui); font-size: 11.5px; color: var(--text-secondary);
      line-height: 1.5; display: flex; align-items: baseline; gap: 0.4rem;
    }
    .dp-brief-tag {
      flex-shrink: 0; font-size: 9.5px; font-weight: 700; letter-spacing: 0.05em;
      text-transform: uppercase; border-radius: 4px; padding: 1px 5px;
      background: var(--bg-subtle); color: var(--text-muted);
    }
    .dp-brief-tag.t-fact     { background: var(--brand-dim);  color: var(--brand-primary); }
    .dp-brief-tag.t-trust    { background: var(--green-bg);   color: var(--green); }
    .dp-brief-tag.t-position { background: var(--amber-bg);   color: var(--amber); }
    .dp-brief-tag.t-depth    { background: var(--bg-subtle);  color: var(--text-primary); }
    .dp-brief-tag.t-subheads { background: var(--bg-subtle);  color: var(--text-secondary); }
    /* Traps are instructions, not errors. A red left rule says "constraint";
       five saturated red boxes said "five things went wrong". */
    .dp-brief-trap, .dp-brief-open {
      font-family: var(--font-ui); font-size: 12.5px; line-height: 1.5;
      padding: 0.35rem 0 0.35rem 0.7rem;
      display: flex; align-items: baseline; gap: 0.45rem;
    }
    .dp-brief-trap { border-left: 2px solid var(--red-border); color: var(--text-secondary); }
    .dp-brief-open { border-left: 2px solid var(--border-default); color: var(--text-primary); }
    .dp-brief-open-k {
      flex-shrink: 0; font-size: 10px; font-weight: 700; color: var(--text-muted);
      text-transform: uppercase;
    }
    .dp-brief-raw {
      font-family: var(--font-ui); font-size: 12.5px; color: var(--text-primary);
      line-height: 1.6;
    }
    /* Zero silent failures, on screen and not only in the log: a brief the
       parser could not read must never look like a topic that simply had no
       traps and no opening. */
    .dp-brief-diag {
      font-family: var(--font-ui); font-size: 10.5px; color: var(--text-muted);
      line-height: 1.5; padding: 0.15rem 0.15rem 0;
    }

    /* ══ PIPELINE STEP PANELS — visual redesign (pp-*) ════════════════ */
    /* The drawer IS the step panel (its old tab bar/header were removed);
       the step's hero card (icon, eyebrow, title, ✕ close) carries context. */

    /* Cancels the .drawer-panel 20px padding so the hero is full-bleed */
    .pp-panel { margin: -20px; }

    /* Hero header — illustrated, replaces the cramped dp-step-header */
    .pp-hero {
      position: relative; overflow: hidden; flex-shrink: 0;
      padding: 1.35rem 1.4rem 1.25rem;
      background: linear-gradient(157deg, var(--brand-dim) 0%, #FFFFFF 78%);
      border-bottom: 1px solid var(--border-subtle);
    }
    .pp-hero-art {
      position: absolute; right: -18px; top: -16px;
      width: 116px; height: 116px; opacity: 0.55; pointer-events: none;
    }
    .pp-hero-row { position: relative; display: flex; align-items: center; gap: 0.8rem; }
    .pp-hero-tile {
      width: 46px; height: 46px; border-radius: 13px; flex-shrink: 0;
      display: flex; align-items: center; justify-content: center;
      background: #FFFFFF; border: 1px solid var(--brand-border);
      color: var(--brand-primary); box-shadow: 0 3px 10px rgba(0,81,213,0.12);
    }
    .pp-hero-text { flex: 1; min-width: 0; }
    .pp-hero-eyebrow {
      font-family: var(--font-code); font-size: 9px; font-weight: 700;
      letter-spacing: 0.14em; text-transform: uppercase;
      color: var(--brand-primary); opacity: 0.75; margin-bottom: 3px;
    }
    .pp-hero-title {
      font-family: var(--font-display); font-size: 17px; font-weight: 700;
      color: var(--text-primary); letter-spacing: -0.012em; line-height: 1.2;
    }
    .pp-hero-sub { font-size: 11.5px; color: var(--text-muted); margin-top: 3px; line-height: 1.45; }
    .pp-hero-back {
      width: 30px; height: 30px; border-radius: 9px; flex-shrink: 0;
      display: flex; align-items: center; justify-content: center;
      background: #FFFFFF; border: 1px solid var(--border);
      color: var(--text-muted); cursor: pointer; transition: 0.12s;
    }
    .pp-hero-back:hover { color: var(--text-primary); border-color: var(--text-muted); }

    /* Body */
    .pp-body { padding: 1.2rem 1.2rem 2.2rem; display: flex; flex-direction: column; gap: 1.5rem; }

    /* Phase 3 — persona identity card (replaces the bullet list of archetypes
       at the top of the persona panel, per the owner's "fake profile photo +
       name + profession" redesign request). Avatar is a stylized silhouette
       in a brand-gradient circle so we don't fabricate fake names yet. */
    .pp-identity-hero {
      display: flex; gap: 14px; align-items: flex-start;
      padding: 16px; border: 1px solid var(--border, #E5E7EB);
      border-radius: 12px; background: linear-gradient(135deg, #FFFFFF 0%, #F8FAFC 100%);
      box-shadow: 0 1px 3px rgba(0,0,0,0.04);
    }
    .pp-identity-avatar {
      width: 64px; height: 64px; flex-shrink: 0;
      border-radius: 50%; background: linear-gradient(135deg, #3B82F6 0%, #1D4ED8 100%);
      color: #fff; display: flex; align-items: center; justify-content: center;
      box-shadow: 0 4px 12px rgba(29,78,216,0.25);
    }
    .pp-identity-avatar svg { width: 34px; height: 34px; }
    .pp-identity-meta { min-width: 0; flex: 1; padding-top: 4px; }
    .pp-identity-role {
      font-family: var(--font-display, var(--font-ui, inherit));
      font-size: 16px; font-weight: 600; color: var(--text1, #111);
      line-height: 1.35; margin-bottom: 6px;
    }
    .pp-identity-label {
      display: inline-block; font-size: 10px; font-weight: 700;
      color: #1D4ED8; background: rgba(29,78,216,0.08);
      padding: 3px 9px; border-radius: 999px;
      text-transform: uppercase; letter-spacing: 0.08em;
    }
    .pp-identity-others {
      margin-top: 14px; padding: 12px;
      border: 1px solid var(--border, #E5E7EB); border-radius: 10px;
      background: var(--bg-surface, #F9FAFB);
    }
    .pp-identity-others-label {
      font-size: 11px; font-weight: 700; color: var(--text-muted, #6B7280);
      text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 8px;
    }
    .pp-identity-others-list { display: flex; flex-direction: column; gap: 6px; }
    .pp-identity-other {
      display: flex; align-items: center; gap: 8px;
      font-size: 12px; color: var(--text-secondary, #4B5563); line-height: 1.4;
    }
    .pp-identity-other svg { width: 18px; height: 18px; color: var(--text-muted, #6B7280); flex-shrink: 0; }

    /* ── Persona bento (v3 schema only) ──────────────────────────────────
       The v3 persona used to be seven full-width cards with the same border,
       the same 12px radius and the same 24px gap — 1466px of scroll at 600px
       and no second focal point after the avatar. This is the same content as
       tiles of deliberately different weight.

       Columns are driven by a CONTAINER query, not a media query, because the
       viewport width says nothing about how wide this panel actually is: it is
       600px as a drawer (#editor-view.ev-panel-mode) but only ~371-427px as
       the 35% #ev-intel-pane in full editor mode. Below 520px every tile goes
       full width, which keeps line measure readable on the prose lists.

       Scoped to .pp-body.pp-bento so the SERP / Brief / Faits panels, which
       share the plain .pp-body flex column, are untouched. */
    .pp-body.pp-bento { display: block; container-type: inline-size; padding: 14px 14px 30px; }
    .pb-grid { display: grid; grid-template-columns: 1fr; gap: 10px; }
    .pb-grid > * { min-width: 0; }
    @container (min-width: 520px) {
      .pb-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
      .pb-grid > .pb-full { grid-column: 1 / -1; }
    }

    /* Generic tile + one header system. The old panel had three: bar+label+count,
       bare uppercase label, and no header at all. */
    .pb-tile {
      padding: 14px 15px; background: #FFFFFF;
      border: 1px solid var(--border-subtle); border-radius: 12px;
    }
    .pb-head { display: flex; align-items: center; gap: 8px; margin-bottom: 11px; }
    .pb-head-bar { width: 14px; height: 2px; border-radius: 2px; background: var(--brand-primary); flex-shrink: 0; }
    .pb-head-bar.is-warn { background: #C62B44; }
    .pb-head-bar.is-good { background: #12833C; }
    .pb-head-title {
      font-family: var(--font-ui); font-size: 11px; font-weight: 700;
      letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-primary);
    }
    .pb-head-count {
      margin-left: auto; font-size: 10.5px; font-weight: 700; color: #5F6779;
      background: var(--surface); border-radius: 20px; padding: 2px 8px; line-height: 1.45;
    }

    /* Anchor tile — who + goal + traits fused. The only tile with a shadow and
       a brand-strength border, so the eye gets one landing point. */
    .pb-anchor {
      padding: 16px; border: 1px solid var(--brand-border); border-radius: 14px;
      background: linear-gradient(158deg, #F4F8FF 0%, #FFFFFF 62%);
      box-shadow: 0 2px 10px rgba(0, 81, 213, 0.07);
    }
    .pb-anchor-top { display: flex; gap: 13px; align-items: flex-start; }
    .pb-anchor-meta { min-width: 0; flex: 1; }
    .pb-anchor-role {
      font-family: var(--font-display); font-size: 15.5px; font-weight: 650;
      color: var(--text-primary); line-height: 1.35; letter-spacing: -0.01em;
      margin-top: 7px;
    }
    .pb-goal { display: flex; gap: 10px; margin-top: 13px; padding-top: 13px; border-top: 1px solid rgba(0, 81, 213, 0.14); }
    .pb-goal-mark {
      flex-shrink: 0; width: 25px; height: 25px; border-radius: 8px;
      background: #FFFFFF; border: 1px solid #CFE6D8;
      display: flex; align-items: center; justify-content: center;
    }
    .pb-goal-body { min-width: 0; }
    .pb-goal-text { font-size: 13.5px; line-height: 1.5; color: #1D3260; font-weight: 500; margin-top: 3px; }

    /* Micro-label. 10.5px / #5F6779 measures 5.7:1 on white; it replaces the
       9.5px #8b93a7 (3.07:1) and #9aa3b8 (2.53:1) labels, which failed AA. */
    .pb-micro {
      font-size: 10.5px; font-weight: 700; letter-spacing: 0.06em;
      text-transform: uppercase; color: #5F6779;
    }
    .pb-micro.is-goal { color: #1D4ED8; }

    .pb-traits {
      display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
      gap: 1px; margin-top: 13px; overflow: hidden;
      background: var(--border-subtle);
      border: 1px solid var(--border-subtle); border-radius: 10px;
    }
    @container (min-width: 520px) { .pb-traits { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
    .pb-trait { background: rgba(255, 255, 255, 0.92); padding: 9px 11px; }
    /* A trait count that doesn't fill the last row leaves a dead cell showing
       the divider background through it. Let the last tile span the remainder.
       Three traits over two columns is the case this actually hits today. */
    .pb-trait:last-child:nth-child(odd) { grid-column: 1 / -1; }
    @container (min-width: 520px) {
      .pb-trait:last-child:nth-child(odd)  { grid-column: auto; }
      .pb-trait:last-child:nth-child(3n+1) { grid-column: 1 / -1; }
      .pb-trait:last-child:nth-child(3n+2) { grid-column: span 2; }
    }
    /* No text-transform: capitalize here on purpose — it rendered French as
       "Inquiet De Passer À Côté D'une Échéance". French takes sentence case. */
    .pb-trait-val { font-size: 12.5px; font-weight: 600; color: var(--text-primary); line-height: 1.35; margin-top: 3px; }

    /* Search journey — a 3-across progress track at >=520px, stacked rows
       below. The rail is each step's own top border, so it survives reflow.
       grid-auto-flow handles a 2-step journey without leaving a hole. */
    .pb-journey { display: grid; grid-template-columns: 1fr; gap: 0 14px; }
    @container (min-width: 520px) { .pb-journey { grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); } }
    .pb-step { position: relative; padding-top: 13px; border-top: 2px solid #E0E5F0; }
    .pb-step + .pb-step { margin-top: 13px; }
    @container (min-width: 520px) { .pb-step + .pb-step { margin-top: 0; } }
    .pb-step::before {
      content: ''; position: absolute; top: -5px; left: 0;
      width: 8px; height: 8px; border-radius: 50%;
      background: #FFFFFF; border: 2px solid #C7CFDE;
    }
    .pb-step.is-now { border-top-color: var(--brand-primary); }
    .pb-step.is-now::before {
      background: var(--brand-primary); border-color: var(--brand-primary);
      box-shadow: 0 0 0 3px rgba(0, 81, 213, 0.15);
    }
    .pb-step-text { font-size: 12.5px; line-height: 1.45; color: #4A5266; margin-top: 3px; }
    .pb-step.is-now .pb-step-text { color: var(--text-primary); font-weight: 650; }

    /* List rows */
    .pb-rows { display: flex; flex-direction: column; gap: 9px; }
    .pb-row { display: flex; gap: 9px; align-items: flex-start; font-size: 12.5px; line-height: 1.5; color: #3A4150; }
    .pb-mark {
      flex-shrink: 0; width: 16px; height: 16px; margin-top: 1px;
      display: flex; align-items: center; justify-content: center;
    }
    .pb-mark.is-q { border-radius: 5px; background: #EAF1FE; color: #1D4ED8; font-size: 10px; font-weight: 800; line-height: 1; }
    .pb-mark.is-x { border-radius: 50%; background: #FDEEF0; color: #C62B44; }
    .pb-mark.is-v { border-radius: 50%; background: #EAF7EF; color: #12833C; }

    /* Secondary personas */
    .pb-person { display: flex; gap: 10px; align-items: flex-start; }
    .pb-person + .pb-person { margin-top: 12px; }
    .pb-person-ico {
      flex-shrink: 0; width: 28px; height: 28px; border-radius: 9px;
      background: var(--brand-dim); border: 1px solid var(--brand-border);
      color: var(--brand-accent); display: flex; align-items: center; justify-content: center;
    }
    .pb-person-who { font-size: 12.5px; line-height: 1.4; color: var(--text-primary); font-weight: 600; }
    .pb-person-goal { font-size: 12px; line-height: 1.45; color: #5F6779; margin-top: 2px; }

    /* Related-search chips */
    .pb-chips { display: flex; flex-wrap: wrap; gap: 6px; }
    .pb-chip {
      font-size: 11.5px; font-weight: 500; line-height: 1.3; padding: 5px 10px;
      border-radius: 999px; background: var(--brand-dim);
      border: 1px solid var(--brand-border); color: var(--brand-accent);
    }

    /* Action toolbar */
    .pb-actions { display: flex; gap: 7px; padding: 12px 14px 0; flex-wrap: wrap; }
    .pb-act {
      display: inline-flex; align-items: center; gap: 6px;
      padding: 7px 12px; min-height: 32px;
      border: 1px solid var(--border); border-radius: 8px; background: #FFFFFF;
      font-family: var(--font-ui); font-size: 12px; font-weight: 500;
      color: var(--text-primary); cursor: pointer;
      transition: background .12s, border-color .12s;
    }
    .pb-act:hover { background: var(--surface); border-color: var(--text-muted); }
    .pb-act:focus-visible { outline: 2px solid var(--brand-primary); outline-offset: 2px; }
    /* Regenerate replaces the persona. Pushed away from the safe actions so it
       stops reading as interchangeable with Copy. */
    .pb-act.is-risky { margin-left: auto; color: #5F6779; }

    /* ── SERP result cards ───────────────────────────────────────────────
       The Google-chrome header and the per-result expanders. Namespaced .sr-*
       so this styling lives in one place instead of forty inline attributes. */
    .sr-searchbar-wrap { padding: 16px 16px 15px; border-bottom: 1px solid rgba(193, 199, 211, 0.3); }
    .sr-searchbar {
      display: flex; align-items: center; gap: 11px;
      padding: 10px 16px; border: 1px solid #DFE1E5; border-radius: 24px;
      box-shadow: 0 1px 6px rgba(32, 33, 36, 0.10);
    }
    .sr-searchbar-q {
      font-family: var(--font-ui); font-size: 14px; color: #202124;
      flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    }
    .sr-count { font-family: var(--font-ui); font-size: 11px; color: #70757A; margin-top: 11px; }

    /* Expanders.
       NEVER set overflow:hidden on .sr-det. These cards live inside a
       `flex: 1; overflow-y: auto; min-height: 0` scroll container, and Chrome
       refuses to expand a <details> with overflow:hidden in that position —
       the summary just does nothing when clicked. See the CSS rules in
       CLAUDE.md. border-radius renders correctly without it. */
    .sr-fold { margin-top: 10px; padding-top: 10px; border-top: 1px solid #EEF1F8; }
    .sr-det { border: 1px solid #E6EAF3; border-radius: 9px; background: #FBFCFE; }
    .sr-det + .sr-det { margin-top: 7px; }
    .sr-det > summary {
      display: flex; align-items: center; gap: 8px;
      padding: 8px 11px; min-height: 34px; border-radius: 9px;
      font-family: var(--font-ui); font-size: 11.5px; font-weight: 600; color: #41506F;
      cursor: pointer; list-style: none;
    }
    .sr-det > summary::-webkit-details-marker { display: none; }
    .sr-det > summary:hover { background: #F3F7FE; }
    .sr-det > summary:focus-visible { outline: 2px solid var(--brand-primary); outline-offset: 2px; }
    /* #7C88A3 measured 3.46:1 at this size. Weight, not colour, carries the
       "secondary to the label" read. */
    .sr-det-n { font-weight: 500; color: #5F6779; }
    .sr-det-chev { margin-left: auto; flex-shrink: 0; color: #7C88A3; transition: transform .15s ease; }
    .sr-det[open] .sr-det-chev { transform: rotate(180deg); }
    .sr-det-body { padding: 3px 11px 11px; }

    /* Heading outline — indent carries the level, the chip names it. */
    .sr-h { display: flex; gap: 8px; align-items: flex-start; padding: 3px 0; font-size: 12px; line-height: 1.45; color: #41506F; }
    .sr-h.d2 { padding-left: 13px; }
    .sr-h.d3 { padding-left: 26px; }
    .sr-h.d4 { padding-left: 39px; }
    .sr-h-lvl {
      flex-shrink: 0; min-width: 23px; text-align: center;
      padding: 2px 5px; border-radius: 4px; line-height: 1.35;
      font-size: 9.5px; font-weight: 800; letter-spacing: 0.03em;
    }
    .sr-h-lvl.l1 { background: var(--brand-dim); color: var(--brand-accent); }
    .sr-h-lvl.l2 { background: #EAF1FE; color: #1D4ED8; }
    .sr-h-lvl.l3 { background: #F1F4FA; color: #5F6779; }
    .sr-h-txt { min-width: 0; }
    .sr-h.d1 .sr-h-txt { font-weight: 600; color: #0F1B3D; }
    .sr-h-more { padding: 6px 0 0; font-size: 11px; color: #5F6779; font-style: italic; }

    /* Tag lengths. Google truncates on pixel width, not characters, so these
       counts are the conventional proxy — the hint says so rather than
       implying the number is a hard limit. */
    .sr-tag + .sr-tag { margin-top: 11px; }
    .sr-tag-head { display: flex; align-items: center; gap: 7px; margin-bottom: 4px; }
    .sr-tag-label { font-size: 10px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: #5F6779; }
    .sr-len { margin-left: auto; padding: 2px 7px; border-radius: 999px; font-size: 10px; font-weight: 700; line-height: 1.5; }
    .sr-len.ok   { background: #EAF7EF; color: #0F6B31; }
    .sr-len.warn { background: #FDF3E4; color: #8A5A00; }
    .sr-len.over { background: #FDEEF0; color: #B02138; }
    .sr-tag-val {
      padding: 7px 9px; border: 1px solid #E6EAF3; border-radius: 7px; background: #FFFFFF;
      font-size: 12px; line-height: 1.5; color: #202124; word-break: break-word;
    }
    .sr-tag-val.is-missing { background: #FDEEF0; border-color: #F7D4DA; color: #B02138; font-style: italic; }
    .sr-tag-hint { margin-top: 4px; font-size: 10.5px; line-height: 1.4; color: #5F6779; }

    /* ── Scores panel — bento ────────────────────────────────────────────
       Top row: Plume score (left) beside SOSEO + DSEO (right).
       Then a 3-across grid of dimension cards, then keyword coverage, then
       the per-page word comparison.

       Status colour: #B91C1C / #A16207 / #047857. No red-amber-green trio
       clears the CVD gate — red and amber converge under deutan whatever the
       hexes (measured: 4.4-4.9 ΔE across four candidate trios), so the
       documented mitigation applies instead: every coloured number ships with
       a state WORD beside it, and meaning never rests on hue alone. All three
       clear 4.5:1 as text on white (6.5 / 4.9 / 5.5). */
    .qb { container-type: inline-size; padding: 20px 18px 26px; }
    .qb-grid { display: grid; grid-template-columns: 1fr; gap: 12px; align-items: start; }
    @container (min-width: 520px) {
      .qb-grid { grid-template-columns: 1.35fr 1fr; }
      .qb-grid > .qb-wide { grid-column: 1 / -1; }
    }
    .qb-title { font-family: var(--font-ui); font-size: 15px; font-weight: 600; color: #0F1117; letter-spacing: -0.015em; }
    .qb-sub { font-family: var(--font-ui); font-size: 11.5px; color: #5F6779; margin: 3px 0 18px; }
    .qb-head { display: flex; align-items: baseline; gap: 12px; }
    /* Admin-only manual recompute. Ghost weight on purpose: it is an ops
       affordance sitting next to the panel's headline, not a call to action. */
    .qb-refresh {
      margin-left: auto; flex: none; cursor: pointer;
      font-family: var(--font-ui); font-size: 11px; font-weight: 500; color: #5F6779;
      background: #FFFFFF; border: 1px solid #E3E8F1; border-radius: 999px;
      padding: 5px 11px; transition: border-color .15s ease, color .15s ease;
    }
    .qb-refresh:hover:not(:disabled) { border-color: #0051D5; color: #0051D5; }
    .qb-refresh:disabled { opacity: .55; cursor: default; }
    .qb-refresh-note { font-family: var(--font-ui); font-size: 11px; margin: -12px 0 14px; }

    .qb-dish { background: #FFFFFF; border: 1px solid #E3E8F1; border-radius: 16px; padding: 18px; min-width: 0; }
    .qb-dish--hero {
      background: linear-gradient(158deg, #F2F6FD 0%, #FFFFFF 64%);
      border-color: rgba(0,81,213,0.22);
      align-self: stretch; display: flex; flex-direction: column;
    }
    /* Inherits .qb-dish's 1px #E3E8F1 rather than blanking it: the tint alone
       stopped reading as an edge once the cards held gauges. */
    .qb-dish--quiet { background: #F6F8FC; }
    /* .qb-col had no rule, so the two cards butted at a shared pixel and the
       only thing between them was the notch where their radii met. */
    .qb-col { display: flex; flex-direction: column; gap: 12px; }

    .qb-eyebrow { font-family: var(--font-ui); font-size: 9.5px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: #5F6779; }
    .qb-note { font-family: var(--font-ui); font-size: 10.5px; line-height: 1.45; color: #5F6779; }

    /* Hero figure, set in the mouth of an arc gauge.
       The arc encodes MAGNITUDE only, in one accent on one track — the same
       pairing _bar() uses. The status trio stays on the number, beside its
       state word, which is where its contrast was measured (as text on white).
       A 110px band of #A16207 would make the arc the loudest thing in the
       panel and demote the non-colour channel to a 10px afterthought, which is
       exactly the failure the CVD note above guards against. Which BAND the
       score sits in is the zone bar's job, at the foot of the card.
       Proportional figures on purpose — tabular-nums gives every digit the
       width of a 0, which makes 61 look loose at display size. */
    .qb-gauge { position: relative; width: 100%; max-width: 168px; margin: 10px auto 2px; }
    .qb-gauge-svg { display: block; width: 100%; height: auto; }
    /* The figure is HTML layered on the SVG, never inside it — same reason
       _zoneBar is HTML. Geometry survives being scaled into a 234px card; 12px
       type does not.
       The viewBox stops just under the arc's mouth rather than running to a
       centre-symmetric height, which would leave ~25 units of dead box under
       an arc that is already open there. That makes the arc's centre 62% down
       the box, not 50%, so the overlay is 124% tall (62 × 2) and pinned to the
       top: its own centre then lands on the arc's centre at every scale, with
       no magic pixel offsets. */
    .qb-gauge-mid { position: absolute; left: 0; right: 0; top: 0; height: 124%; display: flex; align-items: center; justify-content: center; pointer-events: none; }
    .qb-hero { display: inline-flex; align-items: baseline; gap: 2px; font-family: var(--font-ui); font-size: 40px; font-weight: 700; line-height: 1; letter-spacing: -0.04em; }
    .qb-hero small { font-size: 13.5px; font-weight: 600; color: #5F6779; letter-spacing: -0.01em; }
    /* Secondary scores get the same gauge, sized down and set BESIDE its label
       rather than above it. Three full-size gauges stacked made the side column
       half again taller than the hero it is meant to sit flush with. */
    .qb-gauge--sm { max-width: 92px; margin: 0; flex: 0 0 92px; }
    .qb-gauge--sm .qb-hero { font-size: 23px; letter-spacing: -0.03em; }
    .qb-gauge--sm .qb-hero small { font-size: 9.5px; }
    .qb-verdict { font-family: var(--font-ui); font-size: 12.5px; line-height: 1.55; color: #41506F; margin-top: 12px; }

    /* State word — the non-colour channel that lets the number be coloured. */
    .qb-state { font-family: var(--font-ui); font-size: 10px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; }

    .qb-meter { display: flex; align-items: center; gap: 15px; }
    .qb-meter-body { flex: 1; min-width: 0; }
    .qb-meter-state { display: block; margin-top: 5px; }
    .qb-meter-body .qb-note { margin-top: 7px; }

    /* ── Dimension cards — the global card at small size, 3 across ── */
    .qb-cards { display: grid; grid-template-columns: 1fr; gap: 12px; margin-top: 12px; }
    @container (min-width: 380px) { .qb-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
    @container (min-width: 520px) { .qb-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
    .qb-card { background: #FFFFFF; border: 1px solid #E3E8F1; border-radius: 16px; padding: 15px; min-width: 0; }
    .qb-card-top { display: flex; align-items: baseline; gap: 8px; }
    .qb-card-val { font-family: var(--font-ui); font-size: 30px; font-weight: 700; line-height: 1; letter-spacing: -0.03em; }
    .qb-card-name { font-family: var(--font-ui); font-size: 12px; font-weight: 600; color: #191C1E; margin-top: 7px; line-height: 1.3; }
    .qb-card-bar { margin-top: 11px; }
    .qb-card-sec { margin-top: 12px; padding-top: 11px; border-top: 1px solid #ECEFF4; }
    .qb-card-lbl { font-family: var(--font-ui); font-size: 9px; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase; color: #5F6779; }
    .qb-card-txt { font-family: var(--font-ui); font-size: 11px; line-height: 1.5; color: #41506F; margin-top: 4px; }
    .qb-card-txt.is-muted { color: #5F6779; }

    /* ── Keyword coverage — every row is scaled to ITS OWN competitor
       average, so the dashed target sits at one x for all rows: a bar
       stopping short of the rule is under it, one crossing it is over.
       The wash paints the judged deficit (before the rule) or excess
       (after it); red and amber converge under deutan (ΔE 4.4 measured),
       so the SIDE of the rule, never the hue, is what tells them apart. */
    .qb-kwsum { font-family: var(--font-ui); font-size: 10.5px; color: #5F6779; margin-bottom: 12px; }
    .qb-kwsum b { font-weight: 700; color: #41506F; }
    .qb-kwlegend { margin-left: auto; display: inline-flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 4px 12px; font-family: var(--font-ui); font-size: 10.5px; color: #5F6779; }
    .qb-kwlegend > span { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
    .qb-kwsw { width: 14px; height: 6px; border-radius: 2px 3px 3px 2px; background: var(--brand-primary); display: inline-block; }
    .qb-kwsw.is-target { width: 0; height: 12px; border-left: 2px dashed #8C97AA; border-radius: 0; background: none; }
    .qb-kwsw.is-deficit { background: rgba(185,28,28,0.18); border-radius: 2px; }
    .qb-kwsw.is-excess { background: rgba(161,98,7,0.22); border-radius: 2px; }
    .qb-kwrow { display: grid; grid-template-columns: 118px minmax(0, 1fr) 72px; align-items: center; gap: 10px; }
    .qb-kwrow + .qb-kwrow { margin-top: 7px; }
    .qb-kwrow:hover .qb-kwtrack { background: #E7EBF2; }
    .qb-kwname { font-family: var(--font-ui); font-size: 11px; color: #41506F; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .qb-kwrow.is-missing .qb-kwname { font-weight: 700; color: #0F1117; }
    .qb-kwtrack { position: relative; height: 10px; border-radius: 3px; background: #F0F2F6; }
    .qb-kwfill { position: absolute; left: 0; top: 0; height: 100%; border-radius: 2px 4px 4px 2px; background: var(--brand-primary); min-width: 2px; }
    .qb-kwwash { position: absolute; top: 0; height: 100%; }
    .qb-kwwash.is-deficit { background: rgba(185,28,28,0.18); border-radius: 2px; }
    .qb-kwwash.is-excess { background: rgba(161,98,7,0.22); border-radius: 0 4px 4px 0; }
    /* 2px surface gap where a bar and its wash touch (the wash renders first,
       so the fill is its later sibling). Track-coloured so it reads as track. */
    .qb-kwwash ~ .qb-kwfill { box-shadow: 2px 0 0 #F0F2F6; }
    .qb-kwrow:hover .qb-kwwash ~ .qb-kwfill { box-shadow: 2px 0 0 #E7EBF2; }
    /* A THRESHOLD may dash; a gridline may not (same rule as .qb-wmed). */
    .qb-kwtarget { position: absolute; top: -3px; bottom: -3px; border-left: 2px dashed #8C97AA; }
    .qb-kwval { font-family: var(--font-ui); font-size: 11px; font-weight: 700; color: #0F1117; text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
    .qb-kwref { font-weight: 400; color: #5F6779; }
    @container (max-width: 420px) { .qb-kwrow { grid-template-columns: 92px minmax(0, 1fr) 64px; } }

    /* Per-site coverage strip — every ranking page plotted on the SOSEO
       scale against the recommended zone (the YourText-style gauge): the
       under-zone, the zone visée, and the over-optimisation side. The band
       WORDS in .qb-kwcaps carry the meaning; the washes only echo them. */
    .qb-kwsub { font-family: var(--font-ui); font-size: 9px; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase; color: #5F6779; margin-bottom: 12px; }
    .qb-kwyou { position: relative; height: 16px; font-family: var(--font-ui); font-size: 10px; font-weight: 700; color: var(--brand-primary); }
    .qb-kwyou > span { position: absolute; transform: translateX(-50%); white-space: nowrap; }
    .qb-kwlane { position: relative; height: 18px; }
    .qb-kwbands { position: absolute; inset: 0; border-radius: 4px; overflow: hidden; background: #F0F2F6; }
    .qb-kwband { position: absolute; top: 0; height: 100%; }
    .qb-kwband.is-under { background: rgba(161,98,7,0.16); }
    .qb-kwband.is-good  { background: rgba(4,120,87,0.20); }
    .qb-kwband.is-over  { background: rgba(185,28,28,0.15); }
    /* The dot's box is a 20px hit target; ::before draws the 9px mark with
       its 2px surface ring, so overlapping dots stay legible. */
    .qb-kwdot { position: absolute; top: 50%; width: 20px; height: 20px; transform: translate(-50%, -50%); }
    .qb-kwdot::before { content: ''; position: absolute; top: 50%; left: 50%; width: 9px; height: 9px; border-radius: 50%; transform: translate(-50%, -50%); background: #8C97AA; box-shadow: 0 0 0 2px #FFFFFF; }
    .qb-kwdot.is-ours { z-index: 2; }
    .qb-kwdot.is-ours::before { width: 12px; height: 12px; background: var(--brand-primary); }
    .qb-kwcaps { position: relative; height: 15px; margin-top: 6px; font-family: var(--font-ui); font-size: 9.5px; color: #5F6779; }
    .qb-kwcaps > span { position: absolute; transform: translateX(-50%); white-space: nowrap; }
    .qb-kwcaps b { font-weight: 700; color: #41506F; }
    /* Narrow panes: only the zone caption fits — the side bands keep their
       words in the title tooltip. */
    @container (max-width: 420px) {
      .qb-kwcaps > span { display: none; }
      .qb-kwcaps > .is-zone { display: inline; }
    }

    /* ── Per-page word comparison ── */
    .qb-wrow { display: flex; align-items: center; gap: 10px; }
    .qb-wrow + .qb-wrow { margin-top: 9px; }
    .qb-wname { width: 108px; flex-shrink: 0; font-family: var(--font-ui); font-size: 11px; color: #41506F; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .qb-wrow.is-ours .qb-wname { font-weight: 700; color: var(--brand-primary); }
    .qb-wtrack { position: relative; flex: 1; height: 10px; border-radius: 3px; background: #F0F2F6; }
    .qb-wrow.is-ours .qb-wtrack { height: 13px; }
    .qb-wfill { height: 100%; border-radius: 3px; background: #C7CEDB; }
    .qb-wrow.is-ours .qb-wfill { background: var(--brand-primary); }
    /* A THRESHOLD may dash; a gridline may not. */
    .qb-wmed { position: absolute; top: -3px; bottom: -3px; border-left: 2px dashed #8C97AA; }
    .qb-wval { flex-shrink: 0; min-width: 42px; text-align: right; font-family: var(--font-ui); font-size: 11px; color: #41506F; font-variant-numeric: tabular-nums; }
    .qb-wrow.is-ours .qb-wval { font-weight: 700; color: var(--brand-primary); }
    .qb-wcov { flex-shrink: 0; min-width: 30px; text-align: right; font-family: var(--font-ui); font-size: 10.5px; color: #5F6779; font-variant-numeric: tabular-nums; }

    /* Band scale — replaces the before/after dumbbell. A 5-point move on an
       abstract scale is not something you can act on; where the score sits
       against the publish bands, and how far the next one is, is. The bands
       themselves moved onto the gauge in 2026-08; what is left here is the
       distance to the next one, which no arc can say in words. */
    .qb-scale { margin-top: auto; padding-top: 15px; border-top: 1px solid rgba(0,81,213,0.14); }
    .qb-scale-note { font-family: var(--font-ui); font-size: 11.5px; line-height: 1.45; color: #41506F; }
    .qb-scale-note b { font-weight: 700; color: #0F1117; }

    .qb-sec { margin-top: 26px; }
    .qb-sechead { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }

    .qb-chart { display: block; width: 100%; height: auto; margin-top: 10px; overflow: visible; }
    .qb-gridline { stroke: #ECEFF4; stroke-width: 1; }
    .qb-thresh { stroke: #C7CEDB; stroke-width: 1; stroke-dasharray: 3 3; }

    .sc-seclabel { font-family: var(--font-ui); font-size: 10px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: #5F6779; }
    .sc-foot { margin-top: 16px; font-family: var(--font-ui); font-size: 10.5px; line-height: 1.5; color: #5F6779; }
    .sc-empty {
      font-family: var(--font-ui); font-size: 12px; color: #5F6779; line-height: 1.5;
      background: #FFFFFF; border: 1px dashed rgba(193, 199, 211, 0.7);
      border-radius: 12px; padding: 16px;
    }


    /* Phase 1 — per-step approve/reject footer at the bottom of every step panel */
    .pp-step-footer { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; padding: 1rem 1.2rem; border-top: 1px solid var(--border-subtle); background: var(--bg-surface); position: sticky; bottom: 0; }
    .pp-step-footer.approved { color: #065F46; font-weight: 600; }
    .pp-step-footer.failed   { color: #B91C1C; font-weight: 600; }
    .pp-step-footer.running  { color: #A05E00; font-style: italic; }
    .pp-step-footer .pp-step-state { font-size: 13px; }
    .pp-step-footer .pp-approve { padding: 0.5rem 1rem; font-weight: 600; }
    .pp-step-footer .pp-reject  { padding: 0.5rem 1rem; color: var(--text-muted); }

    /* Section block */
    .pp-sec-head { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.7rem; }
    .pp-sec-num {
      font-family: var(--font-code); font-size: 10px; font-weight: 800;
      width: 20px; height: 20px; border-radius: 6px; flex-shrink: 0;
      display: flex; align-items: center; justify-content: center; line-height: 1;
      color: var(--brand-primary); background: var(--brand-dim);
      border: 1px solid var(--brand-border);
    }
    .pp-sec-ico {
      width: 22px; height: 22px; border-radius: 6px; flex-shrink: 0;
      display: flex; align-items: center; justify-content: center;
      color: var(--brand-primary); background: var(--brand-dim);
    }
    .pp-sec-title {
      font-family: var(--font-ui); font-size: 12px; font-weight: 700;
      color: var(--text-primary); letter-spacing: -0.005em;
    }
    .pp-sec-count {
      margin-left: auto; font-family: var(--font-code); font-size: 9.5px;
      font-weight: 700; color: var(--text-muted); background: var(--surface);
      padding: 2px 8px; border-radius: 20px;
    }

    /* Item list */
    .pp-list { display: flex; flex-direction: column; gap: 0.4rem; }
    .pp-item {
      font-size: 13px; color: var(--text-primary); line-height: 1.55;
      padding: 0.6rem 0.8rem; background: #FFFFFF;
      border: 1px solid var(--border-subtle); border-radius: 9px;
      display: flex; gap: 0.6rem; align-items: flex-start;
    }
    .pp-item-dot {
      width: 5px; height: 5px; border-radius: 50%; flex-shrink: 0;
      background: var(--brand-primary); opacity: 0.55; margin-top: 7px;
    }

    /* Chips */
    .pp-chips { display: flex; flex-wrap: wrap; gap: 0.4rem; }
    .pp-chip {
      font-family: var(--font-ui); font-size: 11.5px; font-weight: 500;
      color: var(--brand-accent); background: var(--brand-dim);
      border: 1px solid var(--brand-border);
      padding: 0.3rem 0.65rem; border-radius: 5px;
    }

    /* Gap cards */
    .pp-gap-grouphead {
      display: flex; align-items: center; gap: 0.4rem;
      font-family: var(--font-ui); font-size: 10.5px; font-weight: 700;
      text-transform: uppercase; letter-spacing: 0.07em; margin: 0.5rem 0 0.45rem;
    }
    .pp-gap {
      display: flex; gap: 0.6rem; padding: 0.7rem 0.85rem;
      border-radius: 10px; border: 1px solid; margin-bottom: 0.4rem;
    }
    .pp-gap-ico {
      width: 22px; height: 22px; border-radius: 6px; flex-shrink: 0;
      display: flex; align-items: center; justify-content: center;
    }
    .pp-gap.missing { background: var(--red-bg); border-color: var(--red-border); }
    .pp-gap.missing .pp-gap-ico { background: rgba(192,57,43,0.12); color: var(--red); }
    .pp-gap.partial { background: var(--amber-bg); border-color: rgba(160,94,0,0.2); }
    .pp-gap.partial .pp-gap-ico { background: rgba(160,94,0,0.12); color: var(--amber); }
    .pp-gap.covered { background: var(--green-bg); border-color: var(--green-border); }
    .pp-gap.covered .pp-gap-ico { background: rgba(26,127,90,0.12); color: var(--green); }
    .pp-gap.other { background: var(--bg-base); border-color: var(--border-subtle); }
    .pp-gap.other .pp-gap-ico { background: var(--surface); color: var(--text-muted); }
    .pp-gap-topic { font-size: 12.5px; font-weight: 600; color: var(--text-primary); line-height: 1.4; }
    .pp-gap-why { font-size: 11.5px; color: var(--text-muted); line-height: 1.5; margin-top: 3px; }

    /* Fact cards */
    .pp-fact {
      display: flex; gap: 0.65rem; padding: 0.7rem 0.85rem;
      background: #FFFFFF; border: 1px solid var(--border-subtle);
      border-radius: 10px; margin-bottom: 0.4rem;
    }
    .pp-fact-num {
      font-family: var(--font-code); font-size: 10px; font-weight: 700;
      width: 20px; height: 20px; border-radius: 6px; flex-shrink: 0;
      display: flex; align-items: center; justify-content: center;
      background: var(--brand-primary); color: #FFFFFF;
    }
    .pp-fact-text { font-size: 12.5px; color: var(--text-primary); line-height: 1.55; }
    .pp-fact-src {
      font-family: var(--font-code); font-size: 10px; color: var(--brand-primary);
      margin-top: 5px; word-break: break-all; display: flex; align-items: center; gap: 4px;
    }

    /* Brief / generic field card */
    .pp-field {
      padding: 0.85rem 0.95rem; background: #FFFFFF;
      border: 1px solid var(--border-subtle); border-radius: 10px;
      display: flex; flex-direction: column; gap: 0.35rem;
    }
    .pp-field-label {
      font-family: var(--font-ui); font-size: 9.5px; font-weight: 700;
      text-transform: uppercase; letter-spacing: 0.1em; color: var(--text-muted);
    }
    .pp-field-title {
      font-family: var(--font-display); font-size: 15px; font-weight: 700;
      color: var(--text-primary); line-height: 1.4; letter-spacing: -0.01em;
    }
    .pp-field-text { font-size: 13px; color: var(--text-primary); line-height: 1.65; }
    .pp-field-quote {
      font-size: 13px; color: var(--text-primary); line-height: 1.6; font-style: italic;
      padding: 0.6rem 0.8rem; border-left: 3px solid var(--brand-primary);
      background: var(--brand-dim); border-radius: 0 7px 7px 0;
    }
    /* Prose block — for parsed multi-line agent text, no monospace */
    .pp-prose {
      font-size: 12.5px; color: var(--text-secondary); line-height: 1.7;
      white-space: pre-wrap; word-break: break-word;
    }

    /* Audit rows */
    .pp-audit {
      display: flex; align-items: center; gap: 0.6rem;
      padding: 0.6rem 0.8rem; border-radius: 9px; font-size: 12.5px; font-weight: 500;
      margin-bottom: 0.4rem;
    }
    .pp-audit-ico { width: 18px; height: 18px; flex-shrink: 0; display: flex; }
    .pp-audit.ok { background: var(--green-bg); color: var(--green); }
    .pp-audit.warn { background: var(--amber-bg); color: var(--amber); }

    /* Stat tiles — bigger centered numbers (SERP / quality) */
    .pp-statgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.55rem; }
    .pp-stat {
      text-align: center; padding: 0.9rem 0.4rem; background: #FFFFFF;
      border: 1px solid var(--border-subtle); border-radius: 12px;
    }
    .pp-stat-num {
      font-family: var(--font-display); font-size: 26px; font-weight: 700;
      color: var(--text-primary); line-height: 1;
    }
    .pp-stat-lbl {
      font-family: var(--font-ui); font-size: 9.5px; font-weight: 700;
      text-transform: uppercase; letter-spacing: 0.07em;
      color: var(--text-muted); margin-top: 6px;
    }

    /* Promoted action card (inject links, revision) */
    .pp-action-card {
      border: 1px solid var(--brand-border); border-radius: 13px;
      padding: 1rem; background: linear-gradient(157deg, var(--brand-dim) 0%, #FFFFFF 80%);
      display: flex; flex-direction: column; gap: 0.7rem;
    }
    .pp-action-head { display: flex; gap: 0.65rem; align-items: center; }
    .pp-action-tile {
      width: 36px; height: 36px; border-radius: 10px; flex-shrink: 0;
      display: flex; align-items: center; justify-content: center;
      background: #FFFFFF; border: 1px solid var(--brand-border); color: var(--brand-primary);
    }
    .pp-action-title { font-size: 12.5px; font-weight: 700; color: var(--text-primary); }
    .pp-action-sub { font-size: 11px; color: var(--text-muted); line-height: 1.45; margin-top: 1px; }
    .pp-btn-primary {
      width: 100%; height: 38px; border: none; border-radius: 9px;
      background: var(--brand-primary); color: #FFFFFF; cursor: pointer;
      font-family: var(--font-ui); font-size: 12.5px; font-weight: 600;
      display: flex; align-items: center; justify-content: center; gap: 6px;
      transition: background 0.12s;
    }
    .pp-btn-primary:hover { background: var(--brand-hover); }
    .pp-btn-primary:disabled { opacity: 0.55; cursor: default; }
    /* Revision-panel button colours. These used to be inline
       `style="background:#..."`, which outranks every class rule — so
       .pp-btn-primary:hover above never fired and five buttons sat dead under
       the cursor. As classes they keep their colour AND get a hover state.
       Each modifier needs its own :hover: a bare .pp-btn-primary.is-* (0,2,0)
       ties with .pp-btn-primary:hover (0,2,0) and wins on source order, so
       without the pair below the fix would silently reintroduce the bug.
       The teal here is the review subsystem's accent; whether it stays is an
       open BRAND.md question (TODOS.md), deliberately not settled by this fix. */
    .pp-btn-primary.is-review { background: #0B7285; }
    .pp-btn-primary.is-review:hover { background: #095C6B; }
    .pp-btn-primary.is-secondary { background: #505F76; }
    .pp-btn-primary.is-secondary:hover { background: #414D60; }
    .pp-btn-primary.is-save { background: #1A7F5A; }
    .pp-btn-primary.is-save:hover { background: #146A4B; }
    .pp-btn-soft {
      width: 100%; height: 38px; border: 1px solid var(--brand-border); border-radius: 9px;
      background: #FFFFFF; color: var(--brand-primary); cursor: pointer;
      font-family: var(--font-ui); font-size: 12.5px; font-weight: 600;
      display: flex; align-items: center; justify-content: center; gap: 6px;
      transition: 0.12s;
    }
    .pp-btn-soft:hover { background: var(--brand-dim); }

    /* Illustrated empty state */
    .pp-empty {
      display: flex; flex-direction: column; align-items: center; justify-content: center;
      text-align: center; padding: 2.6rem 1.5rem; gap: 0.7rem;
    }
    .pp-empty-title { font-size: 13px; font-weight: 600; color: var(--text-secondary); }
    .pp-empty-sub { font-size: 11.5px; color: var(--text-muted); line-height: 1.5; max-width: 250px; }

    /* Drawer backdrop (mobile overlay) — the drawer itself is styled in the
       variant-final block (search ".detail-panel {" with position:fixed). */
    .dp-backdrop {
      position: fixed; inset: 0; z-index: 299;
      background: rgba(0,0,0,0.18);
      opacity: 0; pointer-events: none;
      transition: opacity 0.25s;
    }
    .dp-backdrop.dp-open { opacity: 1; pointer-events: all; }


  /* ══ SIDEBAR — ATTIO LIGHT SHELL (2026-07-17) ══════════════════════
     Implements the approved April "variant B" (Notion/Attio-style light
     sidebar). Icon-only mode stays available via the bottom chevron;
     labelled mode is the default.
  ═══════════════════════════════════════════════════════════════════ */
  .nav {
    width: 48px !important;
    background: #F7F8FA !important;
    border-right: 1px solid rgba(193,199,211,0.45) !important;
    padding: 0 !important;
    align-items: center !important;
    overflow: visible !important;
    overflow-y: hidden !important;
  }
  .nav.collapsed { width: 48px !important; }
  /* Hide all text-only elements */
  .workspace-switcher, .quick-search, .nav-section-label, .nav-badge,
  .nav-item-label, .ws-text, .ws-chev, .nav-profile-info, .nav-profile-chev,
  .nav-profile-name, .nav-profile-plan, .nav-collapse-btn, .nav-help-item,
  .nav-cta-wrap, .nav-footer-links, .nav-foot-link, .brand-name, .brand-tagline,
  .brand-tag, .nav-brand-text, #nav-lang-toggle, .ws-popover { display: none !important; }
  /* Logo area */
  .nav-brand { padding: 12px 0 !important; justify-content: center !important; border: none !important; }
  .brand-icon { width: 26px !important; height: 26px !important; border-radius: 6px !important; box-shadow: none !important; }
  /* Nav items */
  .nav-items { padding: 0 !important; align-items: center !important; }
  .nav-item {
    width: 40px !important; height: 40px !important;
    border-radius: 8px !important;
    margin: 0 4px 2px !important;
    justify-content: center !important;
    padding: 0 !important;
    color: #6B7280 !important;
    background: transparent !important;
    border: 1px solid transparent !important;
    position: relative !important;
  }
  .nav-item:hover { background: rgba(15,23,42,0.05) !important; color: #191C1E !important; }
  .nav-item.active { background: #E9ECF1 !important; color: #191C1E !important; border-color: transparent !important; box-shadow: none !important; }
  .nav-item svg { color: currentColor !important; opacity: 1 !important; width: 16px !important; height: 16px !important; }
  /* Phase 3 — real tooltips on hover so users can finally tell what each icon does.
     Uses the data-tip attribute already set on every nav-item. */
  .nav-item::after {
    content: attr(data-tip);
    position: absolute !important;
    left: calc(100% + 8px) !important;
    top: 50% !important;
    transform: translateY(-50%) translateX(-4px) !important;
    background: #1F2937 !important;
    color: #F9FAFB !important;
    padding: 5px 10px !important;
    border-radius: 6px !important;
    font-family: var(--font-ui, inherit) !important;
    font-size: 12px !important;
    font-weight: 500 !important;
    white-space: nowrap !important;
    z-index: 1000 !important;
    pointer-events: none !important;
    box-shadow: 0 4px 14px rgba(0,0,0,0.35) !important;
    opacity: 0 !important;
    transition: opacity 0.12s ease, transform 0.12s ease !important;
    display: block !important;
  }
  .nav-item:hover::after {
    opacity: 1 !important;
    transform: translateY(-50%) translateX(0) !important;
  }
  /* Small arrow pointing back to the icon */
  .nav-item::before {
    content: "";
    position: absolute !important;
    left: calc(100% + 2px) !important;
    top: 50% !important;
    transform: translateY(-50%) !important;
    border: 4px solid transparent !important;
    border-right-color: #1F2937 !important;
    opacity: 0 !important;
    transition: opacity 0.12s ease !important;
    pointer-events: none !important;
    z-index: 1001 !important;
  }
  .nav-item:hover::before { opacity: 1 !important; }
  /* Separator line */
  .nav-separator { width: calc(100% - 12px) !important; margin: 8px 6px !important; background: rgba(193,199,211,0.4) !important; }
  /* Footer / avatar */
  .nav-footer { border-top: 1px solid rgba(193,199,211,0.4) !important; padding: 8px 0 !important; margin-top: 8px !important; }
  .nav-profile-mini { justify-content: center !important; padding: 4px 0 !important; }
  .avatar { width: 28px !important; height: 28px !important; }
  /* Main content adjustment */
  .main { margin-left: 48px !important; }
  .main.nav-collapsed { margin-left: 48px !important; }
  /* Mobile — keep existing mobile behavior */
  @media (max-width: 768px) {
    .nav { width: 220px !important; }
    .nav-item-label { opacity: 1 !important; width: auto !important; }
    .main, .main.nav-collapsed { margin-left: 0 !important; padding-top: 56px !important; }
  }

  /* Phase 3+ — labelled-rail mode. Audit said the icon-only sidebar was
     "mute / empty". Adding visible labels with a small left rail of icons,
     toggleable back to icon-only via the bottom chevron. */
  /* Hide labels by default — icon-only mode */
  .nav-item-label { display: none !important; }
  /* Default the toggle's compress-arrow to point right when collapsed */
  .nav-mode-icon { transition: transform .15s ease; }

  body[data-nav-mode="labelled"] .nav {
    width: 220px !important;
    align-items: stretch !important;
  }
  body[data-nav-mode="labelled"] .main,
  body[data-nav-mode="labelled"] .main.nav-collapsed { margin-left: 220px !important; }
  body[data-nav-mode="labelled"] .nav-brand { padding: 16px 18px !important; justify-content: flex-start !important; }
  body[data-nav-mode="labelled"] .nav-items { align-items: stretch !important; padding: 0 8px !important; }
  body[data-nav-mode="labelled"] .nav-item {
    width: auto !important; height: 32px !important;
    border-radius: 7px !important;
    justify-content: flex-start !important;
    padding: 0 10px !important;
    gap: 10px !important;
    margin: 0 0 1px !important;
    color: #414A56 !important;
  }
  body[data-nav-mode="labelled"] .nav-item svg { width: 15px !important; height: 15px !important; color: #6B7280 !important; }
  body[data-nav-mode="labelled"] .nav-item:hover svg,
  body[data-nav-mode="labelled"] .nav-item.active svg { color: #191C1E !important; }
  body[data-nav-mode="labelled"] .nav-item .nav-item-label {
    display: inline !important;
    font-family: var(--font-ui);
    font-size: 13px;
    font-weight: 500;
    color: inherit;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    flex: 1;
    text-align: left;
  }
  body[data-nav-mode="labelled"] .nav-item:hover { background: rgba(15,23,42,0.05) !important; color: #191C1E !important; }
  body[data-nav-mode="labelled"] .nav-item.active { background: #E9ECF1 !important; color: #191C1E !important; font-weight: 600 !important; }
  /* Suppress the hover tooltip when label is already visible (would duplicate) */
  body[data-nav-mode="labelled"] .nav-item::after,
  body[data-nav-mode="labelled"] .nav-item::before { display: none !important; }
  body[data-nav-mode="labelled"] .nav-sep-line { margin: 8px 14px !important; }
  /* Attio group labels ("Plan" / "Bibliothèque") — visible in labelled mode only */
  .nav-group-label { display: none !important; }
  body[data-nav-mode="labelled"] .nav-group-label {
    display: block !important;
    font-family: var(--font-ui) !important;
    font-size: 10.5px !important; font-weight: 600 !important;
    text-transform: uppercase !important; letter-spacing: 0.07em !important;
    color: #8A919C !important;
    padding: 12px 10px 5px !important;
    user-select: none !important;
    width: 100% !important; text-align: left !important;
  }
  /* Unbuilt destinations read as unbuilt: same size and position as a real nav
     item so the sidebar rhythm holds, but quieter, so the eye skips them until
     they are wanted. They stay fully clickable — the modal explains itself. */
  .nav-item-soon { opacity: 0.55 !important; }
  .nav-item-soon:hover { opacity: 1 !important; }
  /* Attio account row at the bottom: avatar + name + email */
  body[data-nav-mode="labelled"] .nav-avatar-wrap {
    width: calc(100% - 12px) !important; height: auto !important;
    display: flex !important; align-items: center !important; gap: 9px !important;
    padding: 7px 8px !important; margin: 4px 6px 10px !important;
    border-radius: 8px !important;
    justify-content: flex-start !important;
    transition: background 0.12s !important;
  }
  body[data-nav-mode="labelled"] .nav-avatar-wrap:hover { background: rgba(15,23,42,0.05) !important; }
  .nav-acct-info { display: none !important; }
  body[data-nav-mode="labelled"] .nav-acct-info {
    display: flex !important; flex-direction: column !important; min-width: 0 !important; flex: 1 !important; gap: 1px !important;
  }
  .nav-acct-name {
    font-family: var(--font-ui) !important;
    font-size: 12.5px !important; font-weight: 600 !important; color: #191C1E !important;
    white-space: nowrap !important; overflow: hidden !important; text-overflow: ellipsis !important;
    line-height: 1.2 !important; text-align: left !important;
  }
  .nav-acct-mail {
    font-family: var(--font-ui) !important;
    font-size: 10.5px !important; font-weight: 400 !important; color: #8A919C !important;
    white-space: nowrap !important; overflow: hidden !important; text-overflow: ellipsis !important;
    line-height: 1.2 !important; text-align: left !important;
  }
  /* ── Token wallet, above the account row ──────────────────────
     Sits at the bottom of the sidebar because it is status, not
     navigation: you check it, you do not travel to it. Deliberately
     quiet — no brand blue until the number needs attention, per
     DESIGN_SYSTEM ("one blue CTA per screen"). */
  .nav-wallet {
    width: calc(100% - 12px); margin: 2px 6px 6px; padding: 9px 10px 10px;
    display: flex; flex-direction: column; gap: 6px;
    background: transparent; border: 1px solid var(--border-subtle);
    border-radius: 8px; cursor: pointer; text-align: left;
    font-family: var(--font-ui);
    transition: background .12s, border-color .12s;
  }
  .nav-wallet:hover { background: rgba(15,23,42,0.04); border-color: var(--border-default); }
  .nav-wallet:focus-visible { outline: 2px solid var(--brand-primary); outline-offset: 2px; }
  .nav-wallet-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
  .nav-wallet-label {
    font-size: 10.5px; font-weight: 600; letter-spacing: 0.04em;
    text-transform: uppercase; color: #8A919C;
  }
  .nav-wallet-count {
    font-family: var(--font-code); font-size: 14px; font-weight: 600;
    color: #191C1E; font-variant-numeric: tabular-nums;
  }
  .nav-wallet-track {
    height: 3px; width: 100%; background: var(--border-default);
    border-radius: 2px; overflow: hidden;
  }
  .nav-wallet-fill {
    display: block; height: 100%; width: 0%; border-radius: 2px;
    background: var(--brand-primary); transition: width .4s ease;
  }
  .nav-wallet-sub {
    font-size: 10.5px; font-weight: 400; color: #8A919C; line-height: 1.25;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  /* Attention states. Thresholds are in ARTICLES, not tokens — "12 left"
     means nothing until you know 12 does not buy an article. */
  .nav-wallet.low  .nav-wallet-count { color: var(--warning); }
  .nav-wallet.low  .nav-wallet-fill  { background: var(--warning); }
  .nav-wallet.none .nav-wallet-count { color: var(--error); }
  .nav-wallet.none .nav-wallet-fill  { background: var(--error); }
  .nav-wallet.none { border-color: var(--error-border, rgba(192,57,43,0.22)); }

  /* Icon mode: the sidebar is 64px, so only the number survives. The bar and
     the caption would be unreadable slivers. */
  body:not([data-nav-mode="labelled"]) .nav-wallet {
    padding: 8px 0; align-items: center; margin: 2px 6px 6px;
  }
  body:not([data-nav-mode="labelled"]) .nav-wallet-label,
  body:not([data-nav-mode="labelled"]) .nav-wallet-track,
  body:not([data-nav-mode="labelled"]) .nav-wallet-sub { display: none; }

  /* The sidebar is always open, so the collapse control is gone. This needs
     !important: `body[data-nav-mode="labelled"] .nav-item` sets display with
     !important, which beats the inline style:none on the button — it stayed
     visible and clickable, doing nothing. */
  #nav-mode-toggle { display: none !important; }

  /* The sidebar is a fixed-height flex column with overflow:hidden, so anything
     past the fold is CLIPPED with no way to scroll to it. At a 620px-tall
     window it was already losing 32px before the wallet existed; the wallet
     made it 80px, which ate the wallet and the account row — the two things
     that have to stay reachable.
     Scroll the PRIMARY nav list instead of the whole sidebar: the bottom group
     stays pinned and visible, and the two popovers (account menu, brand
     switcher) live outside this box, so making it a scroll container cannot
     clip them. min-height:0 is what actually lets a flex child shrink.
     Scoped under #sidebar-nav on purpose: a later `.nav-items` rule sets
     `flex: 0 ... !important` at the SAME specificity, so a bare
     `.nav-items-primary` lost on source order and shrank nothing. */
  #sidebar-nav .nav-items-primary {
    flex: 0 1 auto !important; min-height: 0 !important; overflow-y: auto !important;
  }
  /* Never let the footer squash: at a short window these must lose nothing. */
  #sidebar-nav .nav-wallet,
  #sidebar-nav .nav-avatar-wrap,
  #sidebar-nav .nav-brand-switch { flex: 0 0 auto !important; }

  body[data-nav-mode="labelled"] .nav-mode-icon { transform: rotate(0deg); }
  /* Collapsed mode (default) — chevron points right ▶ */
  body:not([data-nav-mode="labelled"]) .nav-mode-icon { transform: rotate(180deg); }

  /* Mobile keeps full labelled layout regardless of mode setting, but the
     main content must stay full-width (no fixed sidebar — the nav slides
     in as an overlay drawer on mobile). */
  @media (max-width: 768px) {
    body[data-nav-mode="labelled"] .nav-item-label,
    .nav-item-label { display: inline !important; }
    body[data-nav-mode="labelled"] .main,
    body[data-nav-mode="labelled"] .main.nav-collapsed { margin-left: 0 !important; padding-top: 56px !important; }
    body[data-nav-mode="labelled"] .nav { width: 220px !important; }
    .nav-item { justify-content: flex-start !important; padding: 0 12px !important; gap: 10px !important; }
  }

 }

  #modal-export-columns .modal-box { max-width: 1180px; }
  .ec-layout { display: flex; gap: 1.75rem; align-items: flex-start; }
  .ec-pane-left { flex: 0 0 400px; min-width: 300px; }
  .ec-pane-right { flex: 1 1 auto; min-width: 0; }
  .ec-pane-label { display: flex; align-items: baseline; justify-content: space-between; margin: 0 0 0.6rem; }
  .ec-pane-title { font-family: var(--font-display); font-size: 0.95rem; font-weight: 600; color: var(--text-primary); margin: 0; }
  .ec-pane-sub { font-size: 11px; color: var(--text-muted); margin: 0; }
  .ec-col-count { font-family: var(--font-ui); font-size: 11px; color: var(--text-muted); flex-shrink: 0; }
  #ec-rows { display: flex; flex-direction: column; gap: 6px; margin-bottom: 10px; max-height: 48vh; overflow-y: auto; padding: 2px 2px 2px 0; }
  .ec-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; padding: 8px 9px; background: var(--bg-elevated); border: 1px solid var(--border-default); border-left: 3px solid var(--border-default); border-radius: 8px; transition: border-color .15s; }
  .ec-row[data-source="field"] { border-left-color: var(--brand-primary); }
  .ec-row.dragging { opacity: .4; }
  .ec-row-head { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }
  .ec-row-controls { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; flex: 1 1 auto; min-width: 0; }
  .ec-row-tail { display: flex; align-items: center; gap: 6px; flex: 1 1 100%; }
  .ec-drag-handle { cursor: grab; color: var(--text-muted); flex-shrink: 0; padding: 0 1px; user-select: none; font-size: 13px; }
  .ec-row-index { font-family: var(--font-ui); font-size: 10px; color: var(--text-muted); flex-shrink: 0; width: 14px; text-align: center; }
  .ec-move-group { display: flex; flex-direction: column; flex-shrink: 0; }
  .ec-move-btn { background: none; border: none; cursor: pointer; color: var(--text-muted); padding: 0; line-height: 0.9; }
  .ec-move-btn:hover { color: var(--brand-primary); }
  .ec-move-btn:disabled { opacity: .25; cursor: default; }
  .ec-field { flex: 1 1 128px; min-width: 108px; }
  .ec-label-input { flex: 1; min-width: 90px; }
  .ec-remove-btn { flex-shrink: 0; padding: 4px 9px; }

  .ec-sheet-wrap { border: 1px solid var(--border-default); border-radius: 10px; overflow: auto; background: var(--bg-elevated); max-height: 48vh; }
  .ec-sheet { width: 100%; border-collapse: collapse; font-size: 12px; }
  .ec-sheet th, .ec-sheet td { border-bottom: 1px solid var(--border-default); border-right: 1px solid var(--border-default); padding: 8px 10px; text-align: left; vertical-align: top; }
  .ec-sheet th:last-child, .ec-sheet td:last-child { border-right: none; }
  .ec-sheet thead th { background: var(--bg-surface); color: var(--text-secondary); font-family: var(--font-ui); font-weight: 700; font-size: 11px; border-bottom: 2px solid var(--brand-primary); white-space: nowrap; position: sticky; top: 0; }
  .ec-sheet tbody tr:nth-child(even) { background: var(--bg-base); }
  .ec-sheet .ec-gutter { width: 26px; text-align: center; color: var(--text-muted); background: var(--bg-surface); font-family: var(--font-ui); font-weight: 600; position: sticky; left: 0; }
  .ec-sheet td.ec-cell-short { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 200px; }
  .ec-sheet td.ec-cell-long { max-width: 340px; white-space: normal; color: var(--text-secondary); display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }

  @media (max-width: 900px) {
    #modal-export-columns .modal-box { max-width: 640px; }
    .ec-layout { flex-direction: column; }
    .ec-pane-left, .ec-pane-right { flex: 1 1 auto; width: 100%; min-width: 0; }
    #ec-rows { max-height: none; }
    .ec-sheet-wrap { max-height: none; }
  }
  @media (max-width: 480px) {
    .ec-pane-label { flex-direction: column; align-items: flex-start; gap: 2px; }
  }


  #modal-style-kit .modal-box { max-width: 1080px; }
  .sk-layout { display: flex; gap: 1.75rem; align-items: flex-start; }
  .sk-pane-left { flex: 0 0 380px; min-width: 300px; max-height: 60vh; overflow-y: auto; padding: 2px 6px 2px 0; }
  .sk-pane-right { flex: 1 1 auto; min-width: 0; }
  .sk-section-title { font-family: var(--font-display); font-size: 0.9rem; font-weight: 600; color: var(--text-primary); margin: 0 0 0.5rem; }
  .sk-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 10px; margin-bottom: 14px; }
  .sk-el-row { display: flex; align-items: center; gap: 6px; min-width: 0; }
  .sk-el-tag { font-family: var(--font-ui); font-size: 11px; color: var(--text-muted); flex: 0 0 82px; }
  .sk-el-row input { flex: 1 1 auto; min-width: 0; height: 28px; font-size: 12px; }
  .sk-wrapper-row { display: flex; gap: 6px; margin-bottom: 14px; }
  #sk-preview-css { width: 100%; min-height: 120px; font-family: var(--font-ui); font-size: 12px; resize: vertical; }
  #sk-preview-frame { width: 100%; height: 56vh; border: 1px solid var(--border-default); border-radius: 10px; background: #fff; }
  @media (max-width: 900px) {
    #modal-style-kit .modal-box { max-width: 640px; }
    .sk-layout { flex-direction: column; }
    .sk-pane-left { flex: 1 1 auto; width: 100%; max-height: none; }
    .sk-grid { grid-template-columns: 1fr; }
    #sk-preview-frame { height: 40vh; }
  }


  /* Wizard scoped styles. Shares modal-overlay base but adds full-step layout. */
  /* position:relative is load-bearing — .modal-close is absolutely positioned,
     and .modal-overlay is position:fixed, so without it the × anchors to the
     viewport corner instead of the modal corner. */
  /* ── Full-screen split onboarding (2026-08-18) ─────────────────────────
     The wizard is the first thing a new client sees, so it owns the whole
     viewport: the flow lives in the LEFT pane, the RIGHT pane (#wiz-side-slot)
     is a swap zone for marketing/benefit designs. Below 1024px the right pane
     disappears and the flow takes the full width. */
  #modal-wizard.modal-overlay { padding: 0; }
  #modal-wizard .modal-box {
    max-width: none; width: 100%; height: 100vh; height: 100dvh;
    /* max-height:none beats the global ≤768 `.modal-box { max-height: 92vh }`,
       which otherwise leaves a strip of dashboard visible above the wizard */
    max-height: none;
    padding: 0; position: relative; border: none; border-radius: 0;
    box-shadow: none; background: var(--bg-elevated);
    display: flex; align-items: stretch;
    /* no overflow:hidden — clips native select popups (see CLAUDE.md) */
  }
  #modal-wizard .wiz-main {
    flex: 0 1 70%; min-width: 0; display: flex; flex-direction: column;
    height: 100%; background: var(--bg-elevated); position: relative;
    border-right: 1px solid var(--border);
  }
  /* The pane is 70% of the viewport but a form column must not stretch with
     it — fields wider than ~55rem read as a spreadsheet, not a flow. The
     column is CENTERED in the pane so it sits where the eye lands, not
     pinned into the left corner of a wide pane. */
  #modal-wizard .wiz-header, #modal-wizard .wiz-body {
    max-width: 860px; width: 100%; margin-inline: auto;
  }
  #modal-wizard .modal-close {
    position: absolute; top: 1rem; right: 1rem; z-index: 2;
    width: 34px; height: 34px; border-radius: 8px;
    display: flex; align-items: center; justify-content: center;
    background: none; border: none; cursor: pointer;
    font-size: 1.4rem; line-height: 1; color: var(--text-muted);
    transition: background 0.15s, color 0.15s;
  }
  #modal-wizard .modal-close:hover { background: var(--bg-subtle); color: var(--text-primary); }
  #modal-wizard .modal-close:focus-visible { outline: 2px solid var(--brand-primary); outline-offset: 2px; }
  #modal-wizard .wiz-header {
    padding: 2.25rem 3rem 1.5rem; display: flex; flex-direction: column; gap: 0.55rem;
  }
  #modal-wizard .wiz-eyebrow {
    font-size: 0.7rem; font-weight: 700; letter-spacing: 0.09em;
    text-transform: uppercase; color: var(--brand-primary); margin: 0;
  }
  #modal-wizard .wiz-title {
    margin: 0; font-family: var(--font-display, var(--font-ui));
    font-size: 1.65rem; font-weight: 700; letter-spacing: -0.02em;
    color: var(--text-primary); line-height: 1.2;
  }
  #modal-wizard .wiz-subtitle { margin: 0; font-size: 0.9rem; color: var(--text2); line-height: 1.5; }
  #modal-wizard .wiz-progress { display: flex; gap: 6px; margin-top: 0.9rem; }
  #modal-wizard .wiz-dot { flex: 1; height: 4px; background: var(--bg-subtle); border-radius: 999px; transition: background 0.25s; }
  #modal-wizard .wiz-dot.done { background: var(--brand-primary); opacity: 0.45; }
  #modal-wizard .wiz-dot.active { background: linear-gradient(90deg, var(--brand-primary), var(--brand-container)); }
  #modal-wizard .wiz-body {
    padding: 0.5rem 3rem 2rem; flex: 1; min-height: 0; overflow-y: auto;
  }
  #modal-wizard .wiz-footer {
    /* The bar spans the pane; its CONTENTS align with the centered 860px
       column above (column inset + the column's own 3rem inline padding). */
    padding: 1.1rem max(3rem, calc((100% - 860px) / 2 + 3rem));
    border-top: 1px solid var(--border);
    display: flex; justify-content: space-between; align-items: center; gap: 0.8rem;
    background: var(--bg-base); flex-shrink: 0;
  }
  #modal-wizard .wiz-footer-left {
    font-size: 0.78rem; font-weight: 500; color: var(--text3);
    font-variant-numeric: tabular-nums;
  }
  /* Onboarding-sized actions — the global .btn-primary is dashboard-compact */
  #modal-wizard .wiz-footer .btn-primary {
    padding: 10px 20px; font-size: 13.5px; border-radius: 9px; min-height: 40px;
  }
  #modal-wizard .wiz-footer .btn-primary:hover { background: var(--brand-hover); }
  #modal-wizard .wiz-footer .btn-ghost {
    padding: 10px 16px; font-size: 13.5px; border-radius: 9px; min-height: 40px;
    background: var(--bg-elevated); border: 1px solid var(--border2);
    color: var(--text2); cursor: pointer; font-family: var(--font-ui); font-weight: 500;
    transition: border-color 0.15s, color 0.15s;
  }
  #modal-wizard .wiz-footer .btn-ghost:hover { border-color: var(--text3); color: var(--text-primary); }

  /* ── Right pane: swap zone for future benefit/result designs ────────── */
  #modal-wizard .wiz-side {
    flex: 1 1 30%; min-width: 0; height: 100%; overflow: hidden;
    background: linear-gradient(160deg, #EAF1FC 0%, #DCE7FA 45%, #CBDAF7 100%);
    display: flex; flex-direction: column; justify-content: center;
    padding: 3rem 2.75rem; position: relative;
  }
  /* Pixel grid: a faint static dot lattice (::before) + a handful of grid
     dots that flicker in near-transparent blue (.wiz-side-dots). Both live
     OUTSIDE #wiz-side-slot so the background survives a slot swap. */
  #modal-wizard .wiz-side::before {
    content: ''; position: absolute; inset: 0; pointer-events: none;
    background-image: radial-gradient(rgba(0, 81, 213, 0.13) 1.2px, transparent 1.3px);
    background-size: 20px 20px;
    -webkit-mask-image: radial-gradient(ellipse at 50% 45%, #000 25%, transparent 80%);
    mask-image: radial-gradient(ellipse at 50% 45%, #000 25%, transparent 80%);
  }
  #modal-wizard .wiz-side-dots { position: absolute; inset: 0; pointer-events: none; }
  #modal-wizard .wiz-side-dots span {
    position: absolute; width: 4px; height: 4px; border-radius: 1px;
    background: var(--brand-primary); opacity: 0;
    animation: wiz-flicker var(--fd, 3.2s) ease-in-out var(--fdel, 0s) infinite;
  }
  #modal-wizard #wiz-side-slot { position: relative; }
  @keyframes wiz-flicker { 0%, 100% { opacity: 0; } 50% { opacity: 0.32; } }
  #modal-wizard .wiz-side-eyebrow {
    font-size: 0.7rem; font-weight: 700; letter-spacing: 0.09em;
    text-transform: uppercase; color: var(--brand-primary); margin: 0 0 0.7rem;
  }
  #modal-wizard .wiz-side-title {
    margin: 0; font-size: 1.55rem; font-weight: 700; letter-spacing: -0.02em;
    color: var(--text-primary); line-height: 1.25; max-width: 20ch;
  }
  #modal-wizard .wiz-side-sub {
    margin: 0.6rem 0 0; font-size: 0.9rem; color: var(--text2);
    line-height: 1.55; max-width: 44ch;
  }
  /* ── Mock analytics card — the animated "value" asset ─────────────────
     A depiction of Plume's own GSC tracking (clicks curve + positions),
     not a results claim: no percentages, no growth figures. The curve
     draws itself, a comet sweeps the line, the counter ticks up on open.
     Animations restart naturally each open (display:none → visible). */
  #modal-wizard .wiz-mock {
    margin-top: 2rem; max-width: 420px;
    background: var(--bg-elevated); border: 1px solid rgba(0, 81, 213, 0.14);
    border-radius: 12px; padding: 1.1rem 1.25rem 1.25rem;
    box-shadow: 0 12px 32px rgba(0, 81, 213, 0.10);
    animation: wiz-fade-up 0.5s ease-out both;
  }
  #modal-wizard .wiz-mock-head { display: flex; justify-content: space-between; align-items: baseline; gap: 0.8rem; }
  #modal-wizard .wiz-mock-label {
    font-size: 0.66rem; font-weight: 700; letter-spacing: 0.08em;
    text-transform: uppercase; color: var(--text3);
  }
  #modal-wizard .wiz-mock-period { font-size: 0.7rem; color: var(--text3); white-space: nowrap; }
  #modal-wizard .wiz-mock-valuerow { display: flex; align-items: center; gap: 0.5rem; margin: 0.35rem 0 0.75rem; }
  #modal-wizard .wiz-mock-value {
    font-size: 1.9rem; font-weight: 700; letter-spacing: -0.02em;
    color: var(--text-primary); font-variant-numeric: tabular-nums; line-height: 1;
    min-width: 5ch;
  }
  #modal-wizard .wiz-mock-trend { color: var(--success); flex-shrink: 0; }
  #modal-wizard .wiz-mock-chart { display: block; width: 100%; height: auto; }
  #modal-wizard .wiz-mock-line {
    stroke-dasharray: 1; stroke-dashoffset: 1;
    animation: wiz-draw 1.4s cubic-bezier(0.4, 0, 0.2, 1) 0.35s forwards;
  }
  #modal-wizard .wiz-mock-area { opacity: 0; animation: wiz-appear 0.7s ease-out 1.15s forwards; }
  #modal-wizard .wiz-mock-end { opacity: 0; animation: wiz-appear 0.4s ease-out 1.6s forwards; }
  #modal-wizard .wiz-mock-ping {
    transform-box: fill-box; transform-origin: center;
    animation: wiz-ping 2.4s ease-out 1.9s infinite;
  }
  #modal-wizard .wiz-comet { filter: drop-shadow(0 0 5px rgba(49, 107, 243, 0.95)); }
  #modal-wizard .wiz-mock-rows { margin-top: 0.9rem; border-top: 1px solid rgba(0, 81, 213, 0.10); padding-top: 0.75rem; }
  #modal-wizard .wiz-mock-rowlabel {
    font-size: 0.62rem; font-weight: 700; letter-spacing: 0.08em;
    text-transform: uppercase; color: var(--text3); margin-bottom: 0.45rem;
  }
  #modal-wizard .wiz-mock-row {
    display: flex; justify-content: space-between; align-items: center;
    gap: 0.8rem; padding: 0.4rem 0; font-size: 0.8rem;
  }
  #modal-wizard .wiz-mock-kw { color: var(--text2); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  #modal-wizard .wiz-mock-pos { display: inline-flex; align-items: center; gap: 0.4rem; flex-shrink: 0; font-variant-numeric: tabular-nums; }
  #modal-wizard .wiz-pos-old { color: var(--text3); }
  #modal-wizard .wiz-pos-arrow { color: var(--text3); font-size: 0.7rem; }
  #modal-wizard .wiz-pos-new {
    background: var(--success-bg); color: var(--success);
    border: 1px solid var(--success-border); border-radius: 999px;
    font-weight: 700; font-size: 0.72rem; padding: 0.1em 0.55em;
  }
  @keyframes wiz-draw { to { stroke-dashoffset: 0; } }
  @keyframes wiz-appear { to { opacity: 1; } }
  @keyframes wiz-fade-up { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
  @keyframes wiz-ping { 0% { transform: scale(0.5); opacity: 0.9; } 70% { transform: scale(2.2); opacity: 0; } 100% { opacity: 0; } }
  @media (prefers-reduced-motion: reduce) {
    #modal-wizard .wiz-mock { animation: none; }
    #modal-wizard .wiz-mock-line { animation: none; stroke-dasharray: none; stroke-dashoffset: 0; }
    #modal-wizard .wiz-mock-area, #modal-wizard .wiz-mock-end { animation: none; opacity: 1; }
    #modal-wizard .wiz-mock-ping, #modal-wizard .wiz-comet { display: none; }
    #modal-wizard .wiz-side-dots span { animation: none; }
  }

  @media (max-width: 1279px) {
    #modal-wizard .wiz-side { padding: 2.5rem; }
  }
  /* Below this the side pane would get ~220px of content and the headline
     wraps to shreds — the flow takes the full width instead. */
  @media (max-width: 1151px) {
    #modal-wizard .wiz-side { display: none; }
    #modal-wizard .wiz-main { flex: 1 1 auto; border-right: none; }
  }
  /* The wizard disables Continue while the site scan runs and while a step
     saves. Without a disabled affordance the button stays fully saturated and
     reads as clickable, so users click it repeatedly and nothing happens. */
  #modal-wizard .wiz-footer button:disabled {
    opacity: 0.45; cursor: not-allowed; box-shadow: none;
  }
  #modal-wizard .wiz-footer button:disabled:hover { background: var(--brand-primary); }
  #modal-wizard .wiz-step { display: none; }
  #modal-wizard .wiz-step.active { display: block; animation: wiz-fade 0.2s; }
  @keyframes wiz-fade { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } }
  #modal-wizard .wiz-step h3 { margin: 0 0 0.35rem; font-size: 1.15rem; font-weight: 700; letter-spacing: -0.01em; color: var(--text-primary); }
  #modal-wizard .wiz-step .wiz-help { margin: 0 0 1.5rem; font-size: 0.85rem; color: var(--text2); line-height: 1.55; max-width: 58ch; }
  #modal-wizard .wiz-step .field { margin-bottom: 1.15rem; }
  #modal-wizard .wiz-step label { font-size: 0.78rem; font-weight: 600; color: var(--text-secondary); display: block; margin-bottom: 0.4rem; }
  #modal-wizard .wiz-step input[type=text], #modal-wizard .wiz-step input[type=url],
  #modal-wizard .wiz-step input[type=number], #modal-wizard .wiz-step select,
  #modal-wizard .wiz-step textarea { width: 100%; box-sizing: border-box; }
  /* Onboarding-sized fields: same tokens, more presence than dashboard inputs */
  #modal-wizard .wiz-step input[type=text], #modal-wizard .wiz-step input[type=url],
  #modal-wizard .wiz-step input[type=number], #modal-wizard .wiz-step select {
    padding: 0.65rem 0.85rem; font-size: 0.9rem; border-radius: 8px;
    background: var(--bg-elevated); border: 1px solid var(--border2);
  }
  #modal-wizard .wiz-step select { padding-right: 2.1rem; }
  #modal-wizard .wiz-step textarea { border-radius: 8px; background: var(--bg-elevated); border: 1px solid var(--border2); }
  /* Step 1: quiet expectation-setting under the two fields */
  #modal-wizard .wiz-next-up {
    margin-top: 1.6rem; padding-top: 1.2rem; border-top: 1px solid var(--border);
    font-size: 0.8rem; color: var(--text3); line-height: 1.55; max-width: 52ch;
  }
  #modal-wizard .wiz-step textarea { font-family: var(--font-ui); font-size: 0.85rem; padding: 0.6rem 0.7rem; border: 1px solid var(--border); border-radius: 6px; resize: vertical; }
  #modal-wizard .wiz-loading { text-align: center; padding: 2rem 0; color: var(--text-muted); }
  #modal-wizard .wiz-loading-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--text-secondary); margin: 0 3px; opacity: 0.4; animation: wiz-pulse 1s infinite; }
  #modal-wizard .wiz-loading-dot:nth-child(2) { animation-delay: 0.15s; }
  #modal-wizard .wiz-loading-dot:nth-child(3) { animation-delay: 0.3s; }
  @keyframes wiz-pulse { 0%,100% { opacity: 0.3; transform: scale(1); } 50% { opacity: 1; transform: scale(1.15); } }
  #modal-wizard .wiz-notice { padding: 0.6rem 0.8rem; border-radius: 6px; font-size: 0.8rem; margin-bottom: 1rem; line-height: 1.5; }
  #modal-wizard .wiz-notice.info { background: rgba(0, 100, 200, 0.06); border: 1px solid rgba(0, 100, 200, 0.2); color: var(--text-secondary); }
  #modal-wizard .wiz-notice.warn { background: rgba(220, 140, 0, 0.06); border: 1px solid rgba(220, 140, 0, 0.25); color: var(--text-secondary); }
  #modal-wizard .wiz-product-card { border: 1px solid var(--border); border-radius: 8px; padding: 0.9rem 1rem; margin-bottom: 0.8rem; background: var(--bg-surface, transparent); }
  #modal-wizard .wiz-product-card .pc-row { display: flex; justify-content: space-between; align-items: flex-start; gap: 0.8rem; margin-bottom: 0.6rem; }
  /* The name field carried its affordance on :hover only, which does not exist
     on touch — it read as static text. Keep a permanent (quiet) border. */
  #modal-wizard .wiz-product-card .pc-name-input { font-weight: 600; font-size: 0.95rem; flex: 1; min-width: 0; border: 1px solid var(--border-subtle); padding: 8px 10px; border-radius: 4px; background: var(--bg-base, white); }
  #modal-wizard .wiz-product-card .pc-name-input:focus, #modal-wizard .wiz-product-card .pc-name-input:hover { border-color: var(--border); }
  #modal-wizard .wiz-product-card .pc-actions { display: flex; gap: 6px; flex-shrink: 0; }
  /* 44px minimum touch target — these were 20-23px tall. */
  #modal-wizard .wiz-product-card .pc-main-toggle,
  #modal-wizard .wiz-product-card .pc-remove {
    min-height: 44px; display: inline-flex; align-items: center; justify-content: center;
    font-size: 0.75rem; padding: 0 12px; cursor: pointer;
    border: 1px solid var(--border); background: transparent;
    transition: background 0.15s, border-color 0.15s, color 0.15s;
  }
  #modal-wizard .wiz-product-card .pc-main-toggle { border-radius: 22px; color: var(--text-secondary); }
  #modal-wizard .wiz-product-card .pc-main-toggle:hover { border-color: var(--text-secondary); color: var(--text-primary); }
  #modal-wizard .wiz-product-card .pc-main-toggle.is-main { background: var(--brand-primary); color: var(--text-on-brand, #fff); border-color: var(--brand-primary); }
  #modal-wizard .wiz-product-card .pc-remove { border-radius: 6px; color: var(--text-muted); }
  #modal-wizard .wiz-product-card .pc-remove:hover { border-color: var(--error, #C0392B); color: var(--error, #C0392B); }
  #modal-wizard .wiz-product-card .pc-main-toggle:focus-visible,
  #modal-wizard .wiz-product-card .pc-remove:focus-visible,
  #modal-wizard .wiz-bk-toggle:focus-visible,
  #modal-wizard .wiz-add-product:focus-visible {
    outline: 2px solid var(--brand-primary); outline-offset: 2px;
  }
  #modal-wizard .wiz-product-card textarea { width: 100%; min-height: 50px; font-size: 0.8rem; }
  #modal-wizard .wiz-product-card .pc-fields { display: grid; grid-template-columns: 1fr; gap: 0.5rem; }
  #modal-wizard .wiz-add-product { width: 100%; padding: 0.6rem; background: transparent; border: 1px dashed var(--border); border-radius: 6px; cursor: pointer; color: var(--text-muted); font-size: 0.85rem; }
  #modal-wizard .wiz-add-product:hover { border-color: var(--text-secondary); color: var(--text-primary); }
  #modal-wizard .wiz-review-section { margin-bottom: 1.1rem; padding-bottom: 0.9rem; border-bottom: 1px solid var(--border); }
  #modal-wizard .wiz-review-section:last-child { border-bottom: none; }
  #modal-wizard .wiz-review-label { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.06em; font-weight: 700; color: var(--text-muted); margin-bottom: 0.3rem; }
  #modal-wizard .wiz-review-value { font-size: 0.85rem; color: var(--text-primary); white-space: pre-wrap; }
  #modal-wizard .wiz-field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 0.7rem; }
  /* Forced wizard variant — no close button, no overlay click dismiss */
  #modal-wizard.forced .modal-close { display: none; }

  /* The wizard had no breakpoint of its own, so .wiz-field-row stayed a hard
     1fr 1fr and put two inputs per row at 375px. */
  @media (max-width: 640px) {
    #modal-wizard .wiz-field-row { grid-template-columns: 1fr; }
    #modal-wizard .wiz-header { padding: 1.5rem 1.25rem 1rem; }
    #modal-wizard .wiz-title { font-size: 1.35rem; }
    #modal-wizard .wiz-body { padding: 0.4rem 1.25rem 1.25rem; }
    #modal-wizard .wiz-footer { padding: 0.85rem 1.25rem; gap: 0.6rem; }
    #modal-wizard .wiz-footer > div { flex: 1; }
    #modal-wizard .wiz-footer button { flex: 1; min-height: 44px; white-space: nowrap; }
    #modal-wizard .wiz-footer-left { flex-shrink: 0; }
    #modal-wizard .wiz-product-card .pc-row { flex-direction: column; align-items: stretch; }
    #modal-wizard .wiz-product-card .pc-actions > button { flex: 1; }
    #modal-wizard .wiz-bk-label { width: auto; }
  }

  /* ── Step 2: scan loading ─────────────────────────────────────────────
     The scan is the longest wait in the wizard (one Firecrawl scrape, then
     two parallel Claude calls). It used to be a centred blob in ~250px of
     dead space with an indeterminate 2px bar, which reads as "stalled".
     Now it states what is running, in the order the server actually runs it. */
  #modal-wizard .wiz-scan-wrap {
    display: flex; flex-direction: column; align-items: stretch;
    gap: var(--space-5, 1.25rem); padding: var(--space-6, 1.5rem) 0 var(--space-4, 1rem);
    text-align: left;
  }
  #modal-wizard .wiz-scan-head { display: flex; align-items: center; gap: 0.85rem; }
  #modal-wizard .wiz-scan-icon {
    width: 40px; height: 40px; border-radius: 10px; flex-shrink: 0;
    background: var(--brand-dim);
    display: flex; align-items: center; justify-content: center;
    color: var(--brand-primary);
  }
  #modal-wizard .wiz-scan-title {
    font-size: 0.9rem; font-weight: 600; color: var(--text-primary); margin: 0;
  }
  #modal-wizard .wiz-scan-url {
    font-size: 0.8rem; color: var(--text-muted); margin: 0.1rem 0 0;
    word-break: break-all;
  }
  #modal-wizard .wiz-scan-track {
    width: 100%; height: 2px; background: var(--border); border-radius: 1px; overflow: hidden;
  }
  #modal-wizard .wiz-scan-fill {
    height: 100%; width: 30%;
    background: var(--brand-primary); border-radius: 1px;
    animation: wiz-sweep 1.8s cubic-bezier(0.4,0,0.6,1) infinite;
  }
  @keyframes wiz-sweep { 0% { transform: translateX(-120%); } 100% { transform: translateX(430%); } }

  #modal-wizard .wiz-scan-stages { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.7rem; }
  #modal-wizard .wiz-scan-stage {
    display: flex; align-items: center; gap: 0.7rem;
    font-size: 0.83rem; color: var(--text-muted);
    transition: color 0.25s;
  }
  #modal-wizard .wiz-scan-stage.active { color: var(--text-primary); font-weight: 600; }
  #modal-wizard .wiz-scan-stage.done  { color: var(--text-secondary); }
  #modal-wizard .wiz-stage-icon {
    width: 16px; height: 16px; flex-shrink: 0; border-radius: 50%;
    border: 1.5px solid var(--border2); box-sizing: border-box;
    display: flex; align-items: center; justify-content: center;
  }
  #modal-wizard .wiz-scan-stage.active .wiz-stage-icon {
    border-color: var(--brand-primary); border-right-color: transparent;
    animation: wiz-spin 0.7s linear infinite;
  }
  #modal-wizard .wiz-scan-stage.done .wiz-stage-icon {
    border-color: var(--green, #1A7F5A); background: var(--green, #1A7F5A);
  }
  #modal-wizard .wiz-scan-stage.done .wiz-stage-icon::after {
    content: ''; width: 4px; height: 7px; margin-top: -1px;
    border: solid #fff; border-width: 0 1.5px 1.5px 0; transform: rotate(45deg);
  }
  @keyframes wiz-spin { to { transform: rotate(360deg); } }
  #modal-wizard .wiz-scan-note { font-size: 0.76rem; color: var(--text-muted); margin: 0; }
  @media (prefers-reduced-motion: reduce) {
    #modal-wizard .wiz-scan-fill { animation: none; width: 100%; opacity: 0.5; }
    #modal-wizard .wiz-scan-stage.active .wiz-stage-icon { animation: none; }
  }

  /* ── Step 2: brand kit accordion ─────────────────────────────────── */
  #modal-wizard .wiz-bk-field {
    border: 1px solid var(--border); border-radius: 8px;
    margin-bottom: 0.5rem; overflow: hidden; transition: border-color 0.15s;
  }
  #modal-wizard .wiz-bk-field.expanded { border-color: var(--brand-primary, #0051D5); }
  #modal-wizard .wiz-bk-toggle {
    display: flex; align-items: center; gap: 0.75rem;
    padding: 0.8rem 1rem; cursor: pointer; background: none; border: none;
    width: 100%; text-align: left;
  }
  #modal-wizard .wiz-bk-toggle:hover { background: var(--bg-surface, rgba(0,0,0,0.02)); }
  #modal-wizard .wiz-bk-label {
    font-size: 0.74rem; font-weight: 700; color: var(--text-secondary);
    flex-shrink: 0; width: 80px;
  }
  /* Real (auto-detected) content, so it must NOT use the app's placeholder
     styling — italic + --text-muted is what ::placeholder uses, which made
     generated text read as an empty field. Only the genuinely empty state
     falls back to that treatment. */
  #modal-wizard .wiz-bk-preview {
    font-size: 0.8rem; color: var(--text-secondary);
    flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  #modal-wizard .wiz-bk-preview.is-empty { color: var(--text-muted); font-style: italic; }
  #modal-wizard .wiz-bk-chevron {
    flex-shrink: 0; color: var(--text-muted); transition: transform 0.2s;
  }
  #modal-wizard .wiz-bk-field.expanded .wiz-bk-chevron { transform: rotate(180deg); }
  #modal-wizard .wiz-bk-content { display: none; padding: 0 1rem 0.9rem; }
  #modal-wizard .wiz-bk-field.expanded .wiz-bk-content { display: block; }
  #modal-wizard .wiz-bk-content textarea { resize: vertical; min-height: 100px; }

  /* Workspace switcher popover */
  .ws-popover { position: absolute; top: calc(100% + 4px); left: 0; right: 0; background: var(--bg-base, white); border: 1px solid var(--border); border-radius: 8px; box-shadow: 0 8px 24px rgba(0,0,0,0.12); padding: 6px; z-index: 1200; display: none; max-height: 400px; overflow-y: auto; }
  .ws-popover.open { display: block; }
  .ws-popover .ws-row { display: flex; align-items: center; gap: 0.6rem; padding: 0.5rem 0.6rem; border-radius: 6px; cursor: pointer; }
  .ws-popover .ws-row:hover { background: var(--bg-surface, rgba(0,0,0,0.04)); }
  .ws-popover .ws-row.active { background: var(--bg-surface, rgba(0,0,0,0.06)); }
  .ws-popover .ws-row-name { flex: 1; font-size: 0.85rem; font-weight: 500; color: var(--text-primary); }
  .ws-popover .ws-row-check { font-size: 0.75rem; color: var(--text-muted); }
  .ws-popover .ws-divider { height: 1px; background: var(--border); margin: 4px 0; }
  .ws-popover .ws-new { display: flex; align-items: center; gap: 0.4rem; padding: 0.55rem 0.6rem; border-radius: 6px; cursor: pointer; color: var(--text-secondary); font-weight: 500; font-size: 0.85rem; }
  .ws-popover .ws-new:hover { background: var(--bg-surface, rgba(0,0,0,0.04)); }


/* ── editor shell ─────────────────────────────────────── */
.stb-back {
  display:inline-flex;align-items:center;gap:6px;margin-bottom:18px;
  padding:5px 10px 5px 7px;border:0;border-radius:8px;background:none;
  font-family:inherit;font-size:13px;font-weight:600;color:var(--text3);
  cursor:pointer;transition:background .12s,color .12s;
}
.stb-back:hover { background:var(--bg-subtle);color:var(--text); }
.stb-back svg { width:15px;height:15px;flex-shrink:0; }

.stb-head { display:flex;align-items:center;gap:13px;min-width:0; }
.stb-head-body { min-width:0;flex:1; }
.stb-head .st-lede { margin-top:3px; }
#cl-brand-avatar {
  width:38px;height:38px;border-radius:10px;flex-shrink:0;
  background:var(--cl-brand,var(--brand-primary));
  display:flex;align-items:center;justify-content:center;
  font-size:15px;font-weight:700;color:#fff;
  position:relative;overflow:hidden;
}
/* With a favicon the tile becomes a white card with a hairline border and the
   mark sits inside it, exactly like the avatars on the brand list. */
#cl-brand-avatar.has-fav { background:#fff;border:1px solid var(--border);color:transparent; }
#cl-brand-avatar img {
  position:absolute;inset:0;margin:auto;
  width:26px;height:26px;object-fit:contain;display:block;
}

/* Sections read as tabs, not as wizard steps: editing a saved brand has no
   order to it, so a "Step 3 of 4" footer was describing a journey nobody was
   on. Each tab is a destination; Enregistrer is always available. */
.stb-tabs {
  display:flex;gap:2px;margin-top:22px;
  border-bottom:1px solid var(--border-subtle);
}
.stb-tab {
  padding:9px 13px;border:0;background:none;cursor:pointer;
  font-family:inherit;font-size:13.5px;font-weight:550;color:var(--text3);
  border-bottom:2px solid transparent;margin-bottom:-1px;
  transition:color .12s,border-color .12s;white-space:nowrap;
}
.stb-tab:hover { color:var(--text); }
.stb-tab.active { color:var(--brand-text);font-weight:650;border-bottom-color:var(--brand-primary); }
.stb-tab:focus-visible { outline:2px solid var(--brand-primary);outline-offset:-2px;border-radius:6px 6px 0 0; }

.stb-status { font-size:12px;color:var(--text3);padding:12px 18px 0; }
.stb-status:empty { display:none; }

.stb-actions {
  display:flex;justify-content:flex-end;gap:9px;
  margin-top:22px;padding-top:18px;border-top:1px solid var(--border-subtle);
}

/* ── fields ───────────────────────────────────────────────
   Same class the old modal used, so _clStepFields' markup is untouched; only
   the tokens changed, from the modal's hardcoded hexes to the settings
   surface's variables. */
.cl-step-exp-fields { padding:18px; }
.cl-step-exp-fields .field { margin-bottom:16px; }
.cl-step-exp-fields .field:last-child { margin-bottom:0; }
.cl-step-exp-fields label { font-size:12.5px;font-weight:600;color:var(--text2);margin-bottom:6px;display:block; }
.cl-step-exp-fields .field-hint { font-size:12.5px;line-height:1.5;color:var(--text3);margin:-2px 0 7px; }
.cl-step-exp-fields input[type=text],.cl-step-exp-fields input[type=url],.cl-step-exp-fields input[type=number],.cl-step-exp-fields textarea,.cl-step-exp-fields select {
  width:100%;box-sizing:border-box;background:var(--bg-elevated);
  border:1px solid var(--border);border-radius:8px;
  padding:8px 11px;font-size:13.5px;color:var(--text);font-family:inherit;outline:none;
  transition:border-color .12s,box-shadow .12s;
}
.cl-step-exp-fields input:not([type=range]):focus,.cl-step-exp-fields textarea:focus,.cl-step-exp-fields select:focus {
  border-color:var(--brand-primary);box-shadow:0 0 0 3px var(--brand-dim);
}
.cl-step-exp-fields textarea { resize:vertical;line-height:1.55; }
.cl-step-exp-fields select { appearance:none;-webkit-appearance:none;padding-right:2rem;cursor:pointer;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%230051D5' stroke-width='1.8' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right .75rem center; }
.cl-field-row { display:grid;grid-template-columns:1fr 1fr;gap:14px; }
@media (max-width: 720px) {
  .cl-field-row { grid-template-columns:1fr; }
  .stb-tabs { overflow-x:auto; }
}

/* ── Brand Kit tab: grouped sections ──────────────────────────────────
   The tab is 8 fields. Flat, they were one undifferentiated stack with no
   way to tell the auto-fillable core from the guardrails from the CTA. */
.cl-bk-lead {
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  padding:12px 14px;margin-bottom:18px;
  background:var(--bg-surface);border:1px solid var(--border);border-radius:9px;
}
.cl-bk-lead-text { flex:1;min-width:200px;font-size:12.5px;line-height:1.5;color:var(--text2);margin:0; }
/* Secondary (outline) on purpose: Enregistrer is the one solid blue on this
   screen. Two solid blues would compete and neither would read as primary. */
.cl-bk-autofill {
  display:inline-flex;align-items:center;gap:7px;flex-shrink:0;
  min-height:38px;padding:0 14px;border-radius:8px;
  background:var(--bg-elevated);color:var(--brand-text);
  border:1px solid var(--brand-border);
  font-family:inherit;font-size:13px;font-weight:600;cursor:pointer;
  transition:background .15s,border-color .15s;
}
.cl-bk-autofill:hover:not(:disabled) { background:var(--brand-dim);border-color:var(--brand-primary); }
.cl-bk-autofill:focus-visible { outline:2px solid var(--brand-primary);outline-offset:2px; }
.cl-bk-autofill:disabled { opacity:.55;cursor:not-allowed; }

.cl-bk-section { margin-bottom:24px; }
.cl-bk-section:last-child { margin-bottom:0; }
.cl-bk-section-head {
  display:flex;align-items:baseline;gap:8px;
  padding-bottom:7px;margin-bottom:14px;
  border-bottom:1px solid var(--border-subtle);
}
.cl-bk-section-title {
  margin:0;font-family:inherit;font-size:11.5px;font-weight:700;
  letter-spacing:.06em;text-transform:uppercase;color:var(--text2);
}
.cl-bk-section-note { font-size:11.5px;color:var(--text3);font-weight:400; }
.cl-bk-auto-tag {
  display:inline-flex;align-items:center;gap:4px;
  font-size:10.5px;font-weight:600;letter-spacing:.02em;text-transform:none;
  color:var(--brand-text);background:var(--brand-dim);
  border-radius:10px;padding:2px 8px;
}
.cl-bk-legacy { margin-top:22px;padding-top:16px;border-top:1px dashed var(--border); }

/* Inline-style leftovers from the modal, now classes so the editor's markup
   carries no hardcoded hexes. */
.cl-step-exp-fields .cl-lbl-note { font-weight:400;font-size:11.5px;color:var(--text3); }
/* Readability slider. `accent-color` on a bare native range read as an
   unstyled form control sitting next to fully styled selects, and Chrome drew
   its own focus box around it. Custom track and thumb so it belongs to the
   same surface, with the fill showing the chosen position at a glance.
   --rl-pct is written by _rlSync on every change. */
.cl-step-exp-fields .cl-rl-field {
  padding:14px 15px;background:var(--bg-surface);
  border:1px solid var(--border);border-radius:10px;
}
.cl-rl-head { display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:14px; }
.cl-step-exp-fields .cl-rl-head label { margin-bottom:0; }
.cl-rl-chip {
  display:inline-flex;align-items:baseline;gap:5px;flex-shrink:0;
  padding:3px 10px;border-radius:999px;
  background:var(--brand-dim);color:var(--brand-text);
  font-size:11.5px;font-weight:600;line-height:1.5;
}
.cl-rl-chip strong { font-size:14px;font-weight:700;letter-spacing:-.01em; }
.cl-rl-chip em { font-style:normal;font-weight:500;opacity:.75; }
.cl-step-exp-fields .cl-range {
  -webkit-appearance:none;appearance:none;
  display:block;width:100%;height:18px;margin:0;padding:0;
  background:none;border:0;outline:none;cursor:pointer;
}
.cl-step-exp-fields .cl-range::-webkit-slider-runnable-track {
  height:6px;border-radius:999px;
  background:linear-gradient(90deg,
    var(--brand-primary) 0 var(--rl-pct,50%),
    var(--border) var(--rl-pct,50%) 100%);
}
.cl-step-exp-fields .cl-range::-webkit-slider-thumb {
  -webkit-appearance:none;appearance:none;
  width:16px;height:16px;margin-top:-5px;border-radius:50%;
  background:#fff;border:2px solid var(--brand-primary);
  box-shadow:0 1px 3px rgba(16,24,40,.18);
  transition:transform .12s,box-shadow .12s;
}
.cl-step-exp-fields .cl-range:hover::-webkit-slider-thumb { transform:scale(1.1); }
.cl-step-exp-fields .cl-range:focus-visible::-webkit-slider-thumb { box-shadow:0 0 0 4px var(--brand-dim); }
.cl-step-exp-fields .cl-range::-moz-range-track { height:6px;border-radius:999px;background:var(--border); }
.cl-step-exp-fields .cl-range::-moz-range-progress { height:6px;border-radius:999px;background:var(--brand-primary); }
.cl-step-exp-fields .cl-range::-moz-range-thumb {
  width:14px;height:14px;border-radius:50%;box-sizing:content-box;
  background:#fff;border:2px solid var(--brand-primary);
  box-shadow:0 1px 3px rgba(16,24,40,.18);
}
.cl-rl-scale {
  display:flex;justify-content:space-between;margin-top:7px;
  font-size:11px;font-weight:500;color:var(--text3);
}
.cl-step-exp-fields .cl-rl-desc {
  margin:12px 0 0;padding-top:11px;border-top:1px solid var(--border-subtle);
  font-size:12.5px;font-weight:550;line-height:1.45;color:var(--text2);
}
.cl-step-exp-fields .cl-rl-note { margin:5px 0 0;font-size:11.5px;line-height:1.5;color:var(--text3); }
.cl-step-exp-fields input.cl-input-sm { width:90px; }
.cl-step-exp-fields .cl-li-status { margin:-8px 0 16px; }
.cl-step-exp-fields .cl-li-status:empty { display:none; }
.cl-step-exp-fields .cl-color-field { display:flex;align-items:center;gap:11px; }
.cl-step-exp-fields .cl-color-field label { flex:1;margin-bottom:0; }
.cl-step-exp-fields .cl-check-lbl { display:flex;align-items:flex-start;gap:9px;cursor:pointer;margin-bottom:0;font-weight:600; }
.cl-step-exp-fields .cl-check-lbl input[type=checkbox] { width:auto;margin-top:1px;accent-color:var(--brand-primary);flex-shrink:0; }

/* Colour swatch for the brand colour picker on the Identity tab */
#cl-color-preview { width:26px;height:26px;border-radius:7px;border:2px solid var(--border);
  background:var(--cl-brand,var(--brand-primary));cursor:pointer;flex-shrink:0;transition:border-color .15s; }
#cl-color-preview:hover { border-color:var(--brand-primary); }
#cl-brand-color { position:absolute;opacity:0;width:0;height:0; }

/* ==================== 48px OBSIDIAN SIDEBAR OVERRIDE ==================== */

/* Nav is position:fixed — body/html overflow is not needed to stabilize it */

/* The sidebar: fixed, Attio-light, never moves */
.nav {
  width: 48px !important;
  background: #F7F8FA !important;
  border-right: 1px solid rgba(193,199,211,0.45) !important;
  padding: 0 !important;
  align-items: center !important;
  overflow: visible !important;
  overflow-y: hidden !important;
  transition: none !important;
  display: flex !important;
  flex-direction: column !important;
  position: fixed !important;
  top: 0 !important; left: 0 !important; bottom: 0 !important;
  z-index: 200 !important;
}
.nav.collapsed { width: 48px !important; }

/* Legacy logo classes — kept in case other surfaces still reference them */
.nav-logo-wrap { width: 40px !important; height: 40px !important; display: flex !important; align-items: center !important; justify-content: center !important; margin: 10px 0 0 !important; flex-shrink: 0 !important; }
.nav-logo-img { width: 28px !important; height: 28px !important; border-radius: 6px !important; object-fit: contain !important; display: block !important; }

/* ── Plume product mark — sits above the brand switcher so the product
   identity is always visible even when the workspace shows a client name. */
.nav-plume-mark {
  display: flex !important; align-items: center !important; gap: 8px !important;
  padding: 14px 14px 4px !important;
  flex-shrink: 0 !important;
  user-select: none !important;
}
.nav-plume-mark-img {
  width: 22px !important; height: 22px !important;
  border-radius: 5px !important; object-fit: contain !important;
  flex-shrink: 0 !important;
}
.nav-plume-mark-text {
  font-family: var(--font-ui) !important;
  font-size: 17px !important; font-weight: 700 !important;
  letter-spacing: -0.01em !important;
  color: #191C1E !important;
  line-height: 1 !important;
}
/* Collapsed sidebar: hide the wordmark, center the small mark */
body:not([data-nav-mode="labelled"]) .nav-plume-mark-text { display: none !important; }
body:not([data-nav-mode="labelled"]) .nav-plume-mark {
  justify-content: center !important;
  padding: 12px 0 0 !important;
}

/* ── Brand switcher (replaces the static logo).
   In collapsed sidebar mode it shrinks to a 40px avatar-only puck.
   In labelled mode it expands to show the brand name + chevron. */
.nav-brand-switch {
  width: calc(100% - 12px) !important;
  display: flex !important; align-items: center !important; gap: 9px !important;
  margin: 12px 6px 6px !important;
  padding: 7px !important;
  background: transparent !important;
  border: 1px solid transparent !important;
  border-radius: 9px !important;
  cursor: pointer !important;
  color: inherit !important;
  font-family: inherit !important;
  min-height: 42px !important;
  text-align: left !important;
  transition: background 0.12s, border-color 0.12s !important;
}
.nav-brand-switch:hover {
  background: rgba(15,23,42,0.05) !important;
  border-color: rgba(193,199,211,0.5) !important;
}
.nav-brand-switch[aria-expanded="true"] {
  background: rgba(15,23,42,0.06) !important;
  border-color: rgba(193,199,211,0.6) !important;
}
.nav-brand-avatar {
  width: 28px !important; height: 28px !important;
  border-radius: 7px !important;
  background: linear-gradient(135deg, #0051D5, #3B82F6) !important;
  color: #fff !important;
  font-family: var(--font-ui) !important;
  font-size: 13px !important; font-weight: 700 !important;
  display: flex !important; align-items: center !important; justify-content: center !important;
  flex-shrink: 0 !important;
  line-height: 1 !important;
  box-shadow: 0 1px 2px rgba(0,0,0,0.18) !important;
  position: relative !important;
  overflow: hidden !important;
}
/* When a favicon is present, the avatar becomes a clean transparent canvas.
   The PNG itself sits directly on the dark sidebar — no white wrapper. */
.nav-brand-avatar.has-fav {
  background: transparent !important;
  box-shadow: none !important;
}
.nav-brand-avatar.has-fav { color: transparent !important; }
.nav-brand-avatar img {
  position: absolute !important; inset: 0 !important;
  width: 100% !important; height: 100% !important;
  object-fit: contain !important;
  padding: 0 !important;
  background: transparent !important;
}
.nav-brand-info {
  flex: 1 !important;
  display: flex !important; flex-direction: column !important;
  min-width: 0 !important;
  gap: 1px !important;
}
.nav-brand-name {
  font-family: var(--font-ui) !important;
  font-size: 12.5px !important; font-weight: 600 !important;
  color: #191C1E !important;
  line-height: 1.2 !important;
  white-space: nowrap !important; overflow: hidden !important; text-overflow: ellipsis !important;
}
.nav-brand-cap {
  font-family: var(--font-ui) !important;
  font-size: 9.5px !important; font-weight: 600 !important;
  color: #6B7280 !important;
  text-transform: uppercase !important; letter-spacing: 0.06em !important;
  line-height: 1.2 !important;
}
.nav-brand-chev { color: #9CA3AF !important; flex-shrink: 0 !important; transition: transform 0.18s ease !important; }
.nav-brand-switch[aria-expanded="true"] .nav-brand-chev { transform: rotate(180deg) !important; color: #191C1E !important; }

/* Collapsed-sidebar mode: hide label + chevron, center the puck */
body:not([data-nav-mode="labelled"]) .nav-brand-info,
body:not([data-nav-mode="labelled"]) .nav-brand-chev { display: none !important; }
body:not([data-nav-mode="labelled"]) .nav-brand-switch {
  width: 40px !important;
  margin: 12px auto 6px !important;
  padding: 6px !important;
  justify-content: center !important;
  gap: 0 !important;
}

/* Brand popover — anchored next to the switcher button */
.nav-brand-popover {
  position: fixed !important;
  min-width: 240px !important;
  max-width: 300px !important;
  max-height: 420px !important;
  overflow-y: auto !important;
  background: #FFFFFF !important;
  border: 1px solid rgba(193,199,211,0.6) !important;
  border-radius: 12px !important;
  padding: 6px !important;
  box-shadow: 0 14px 40px rgba(15,23,42,0.14), 0 2px 6px rgba(15,23,42,0.08) !important;
  z-index: 2000 !important;
  display: none !important;
}
.nav-brand-popover.open { display: block !important; }
.nav-brand-popover::-webkit-scrollbar { width: 6px; }
.nav-brand-popover::-webkit-scrollbar-thumb { background: rgba(193,199,211,0.6); border-radius: 3px; }
.nav-brand-popover-head {
  font-family: var(--font-ui) !important;
  font-size: 9.5px !important; font-weight: 700 !important;
  color: #9CA3AF !important;
  text-transform: uppercase !important; letter-spacing: 0.08em !important;
  padding: 8px 10px 5px !important;
}
.nav-brand-opt {
  display: flex !important; align-items: center !important; gap: 9px !important;
  padding: 7px 8px !important;
  border-radius: 7px !important;
  cursor: pointer !important;
  font-family: var(--font-ui) !important;
  font-size: 12.5px !important; font-weight: 500 !important;
  color: #37404C !important;
  transition: background 0.1s !important;
}
.nav-brand-opt:hover { background: rgba(15,23,42,0.05) !important; }
.nav-brand-opt.active { background: #EEF2FF !important; color: #0051D5 !important; }
.nav-brand-opt-avatar {
  width: 24px !important; height: 24px !important;
  border-radius: 6px !important;
  background: linear-gradient(135deg, #0051D5, #3B82F6) !important;
  color: #fff !important;
  font-family: var(--font-ui) !important;
  font-size: 11.5px !important; font-weight: 700 !important;
  display: flex !important; align-items: center !important; justify-content: center !important;
  flex-shrink: 0 !important;
  line-height: 1 !important;
  position: relative !important;
  overflow: hidden !important;
}
.nav-brand-opt-avatar.has-fav {
  background: transparent !important;
  color: transparent !important;
}
.nav-brand-opt-avatar img {
  position: absolute !important; inset: 0 !important;
  width: 100% !important; height: 100% !important;
  object-fit: contain !important;
  padding: 0 !important;
  background: transparent !important;
}
.nav-brand-opt-name { flex: 1 !important; min-width: 0 !important; overflow: hidden !important; text-overflow: ellipsis !important; white-space: nowrap !important; }
.nav-brand-opt-check { color: #0051D5 !important; flex-shrink: 0 !important; opacity: 0 !important; }
.nav-brand-opt.active .nav-brand-opt-check { opacity: 1 !important; }
.nav-brand-popover-sep { height: 1px !important; background: rgba(193,199,211,0.5) !important; margin: 5px 4px !important; }

/* Separators */
.nav-sep-line { width: calc(100% - 12px) !important; height: 1px !important; background: rgba(193,199,211,0.45) !important; margin: 8px 6px !important; flex-shrink: 0 !important; }

/* Items group */
.nav-items { padding: 0 !important; align-items: center !important; display: flex !important; flex-direction: column !important; width: 100% !important; flex: 0 0 auto !important; }

/* Icon button */
.nav-item {
  width: 40px !important; height: 40px !important;
  border-radius: 8px !important;
  margin: 0 4px 2px !important;
  justify-content: center !important;
  padding: 0 !important;
  color: #4B5563 !important;
  background: transparent !important;
  border: none !important;
  position: relative !important;
  display: flex !important;
  align-items: center !important;
  cursor: pointer !important;
  flex-shrink: 0 !important;
  text-decoration: none !important;
}
.nav-item:hover { background: rgba(15,23,42,0.05) !important; color: #191C1E !important; }
.nav-item.active { background: #E9ECF1 !important; color: #191C1E !important; }
.nav-item svg { color: currentColor !important; opacity: 1 !important; width: 16px !important; height: 16px !important; flex-shrink: 0 !important; }

/* No tooltip on nav items */
.nav-item::after { display: none !important; }

/* Avatar at bottom — the collapsed rail keeps the 40px puck. */
.nav-avatar-wrap { width: 40px !important; height: 40px !important; display: flex !important; align-items: center !important; justify-content: center !important; margin: 0 0 10px !important; cursor: pointer !important; flex-shrink: 0 !important; position: relative !important; }
.nav-acct-chev { display: none !important; }

/* ── Labelled rail: the account row is a real button ────────
   It opens a menu, so it says so — a chevron, a hover surface and a
   distinct open state. It used to be an unmarked strip of text that
   happened to be clickable, which is the "make clickable things
   obviously clickable" rule broken in the one place every user ends
   up when they are looking for a way out.
   Scoped and placed AFTER the block near the top of this file: that
   one carries the same specificity, so source order is what decides. */
body[data-nav-mode="labelled"] .nav-avatar-wrap {
  width: calc(100% - 12px) !important; height: auto !important;
  display: flex !important; align-items: center !important; gap: 9px !important;
  padding: 7px 8px !important; margin: 4px 6px 8px !important;
  border: 1px solid transparent !important; border-radius: 9px !important;
  justify-content: flex-start !important;
  transition: background .12s, border-color .12s !important;
}
body[data-nav-mode="labelled"] .nav-avatar-wrap:hover {
  background: rgba(15,23,42,0.05) !important; border-color: var(--border-subtle) !important;
}
body[data-nav-mode="labelled"] .nav-avatar-wrap[aria-expanded="true"] {
  background: var(--bg-elevated) !important; border-color: var(--border) !important;
}
body[data-nav-mode="labelled"] .nav-acct-chev {
  display: block !important; width: 13px !important; height: 13px !important;
  flex-shrink: 0 !important; color: var(--text3) !important;
  transition: transform .15s ease !important;
}
body[data-nav-mode="labelled"] .nav-avatar-wrap[aria-expanded="true"] .nav-acct-chev {
  transform: rotate(180deg) !important;
}
.nav-avatar-wrap .avatar { width: 28px !important; height: 28px !important; border-radius: 8px !important; background: linear-gradient(135deg,#316BF3,#0051D5) !important; display: flex !important; align-items: center !important; justify-content: center !important; font-family: var(--font-ui) !important; font-size: 11px !important; font-weight: 700 !important; color: #fff !important; flex-shrink: 0 !important; letter-spacing: .02em !important; }

/* ── Account menu ─────────────────────────────────
   Opens ABOVE the row, on the rail's own width, so it never lands on
   top of the article the user is reading. Four sections — upgrade,
   account, resources, exit — and exactly one blue row and one red
   row, per DESIGN_SYSTEM's one-CTA rule. */
.nav-account-menu {
  position: absolute !important; left: 0 !important; right: 0 !important;
  bottom: calc(100% + 6px) !important;
  /* No min-width. left/right:0 already sizes it to the account row, and the
     rail is 220px wide with 6px margins — 208px of usable space. A 224px
     min-width overflowed by 10px, and `.nav` clips on x (see the flyout note
     below), so the excess was not cropped, it was invisible. */
  background: var(--bg-elevated) !important; border: 1px solid var(--border) !important;
  border-radius: 12px !important; padding: 0 !important;
  box-shadow: 0 12px 32px rgba(15,23,42,0.13), 0 2px 6px rgba(15,23,42,0.06) !important;
  z-index: 1000 !important; display: none !important;
}
/* Collapsed rail has no width to align to, so it falls back to the side. */
body:not([data-nav-mode="labelled"]) .nav-account-menu {
  left: calc(100% + 8px) !important; right: auto !important; bottom: 0 !important;
  min-width: 224px !important;   /* nothing to align to out here, so name one */
}
.nav-account-menu.open { display: block !important; animation: navAcctIn .13s ease-out !important; }
@keyframes navAcctIn { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .nav-account-menu.open { animation: none !important; }
  .nav-acct-chev { transition: none !important; }
}
/* Header — who you are signed in as. Not a menu item, so not hoverable. */
.nav-account-head { padding: 11px 13px 10px !important; border-bottom: 1px solid var(--border-subtle) !important; }
.nav-account-head-name { font-family: var(--font-ui) !important; font-size: 13px !important; font-weight: 600 !important; color: var(--text) !important; line-height: 1.3 !important; white-space: nowrap !important; overflow: hidden !important; text-overflow: ellipsis !important; }
.nav-account-head-mail { font-family: var(--font-ui) !important; font-size: 11.5px !important; font-weight: 400 !important; color: var(--text3) !important; line-height: 1.35 !important; margin-top: 1px !important; white-space: nowrap !important; overflow: hidden !important; text-overflow: ellipsis !important; }
/* A section is a run of items between two hairlines. */
.nav-account-sec { padding: 4px 0 !important; border-bottom: 1px solid var(--border-subtle) !important; }
.nav-account-sec:last-child { border-bottom: 0 !important; }
/* `display` is deliberately NOT !important, and nothing else may make it so.
   Three rows are hidden through an inline style — the client-only "Mon
   profil", the Admin link, and every owner row when a reviewer is logged in
   — and an !important stylesheet declaration beats a plain inline one. With
   it on, a client saw Paramètres and Facturation, both of which 403. */
.nav-account-item { display: flex; align-items: center !important; gap: 11px !important;
  width: 100% !important; padding: 7px 13px !important; text-align: left !important;
  background: transparent !important; border: 0 !important; text-decoration: none !important;
  font-family: var(--font-ui) !important; font-size: 13px !important; font-weight: 500 !important;
  line-height: 1.35 !important; color: var(--text) !important; cursor: pointer !important;
  position: relative !important; transition: background .1s !important; }
.nav-account-item:hover { background: var(--bg-surface) !important; }
.nav-account-item:focus-visible { background: var(--bg-surface) !important; outline: none !important;
  box-shadow: inset 2px 0 0 var(--brand-primary) !important; }
.nav-account-item svg { width: 16px !important; height: 16px !important; flex-shrink: 0 !important;
  color: var(--text2) !important; stroke-width: 1.9 !important; }
.nav-account-item-label { flex: 1 !important; min-width: 0 !important; white-space: nowrap !important; overflow: hidden !important; text-overflow: ellipsis !important; }
.nav-account-item-value { font-size: 11.5px !important; font-weight: 500 !important; color: var(--text3) !important; flex-shrink: 0 !important; }
.nav-account-item-chev { width: 13px !important; height: 13px !important; flex-shrink: 0 !important; color: var(--text3) !important; stroke-width: 2.2 !important; }
.nav-account-item.upgrade { color: var(--brand-primary) !important; font-weight: 600 !important; }
.nav-account-item.upgrade svg { color: var(--brand-primary) !important; }
.nav-account-item.upgrade:hover { background: var(--brand-dim) !important; }
.nav-account-item.danger { color: var(--red) !important; }
.nav-account-item.danger svg { color: var(--red) !important; }
.nav-account-item.danger:hover { background: var(--red-bg) !important; }
/* Language flyout. Hover OR focus-within, so it is reachable by keyboard.
   It opens DOWNWARD INSIDE the rail, not sideways like a desktop submenu:
   `.nav` carries `overflow: visible; overflow-y: hidden`, and a box with one
   axis visible and the other not computes the visible axis to `auto` — so
   overflow-x clips, and a flyout at `left: calc(100% + 6px)` was laid out at
   x=228 on a 220px rail and painted nothing at all. Same family as the
   `<select>` clipping note in CLAUDE.md: the element is there, measurable,
   and invisible. */
.nav-account-sub { position: relative !important; }
.nav-account-flyout { position: absolute !important; left: 8px !important; right: 8px !important;
  top: calc(100% + 2px) !important;
  background: var(--bg-elevated) !important;
  border: 1px solid var(--border) !important; border-radius: 10px !important; padding: 4px 0 !important;
  box-shadow: 0 12px 32px rgba(15,23,42,0.13), 0 2px 6px rgba(15,23,42,0.06) !important;
  display: none !important; z-index: 1001 !important; }
.nav-account-sub:hover .nav-account-flyout,
.nav-account-sub:focus-within .nav-account-flyout { display: block !important; }
.nav-account-flyout .check { width: 14px !important; height: 14px !important; color: var(--brand-primary) !important; stroke-width: 2.6 !important; }
.nav-account-flyout .check.hidden { visibility: hidden !important; }

/* ══════════════════════════════════════════════════════════════════════
   GETTING STARTED  (.pm-*)
   One progress counter for setup, DERIVED from account state - never a
   checkbox the user ticks. Ticking is a second source of truth that drifts:
   a brand deleted after the box was ticked would leave the list claiming a
   step that is no longer true. Every step here answers a question the
   dashboard can already answer (a brand exists, a card exists, an article has
   text, GSC is connected, a link index was built), so the list cannot lie and
   there is nothing to keep in sync.

   It disappears on its own when everything is done, so "dismiss" is a
   convenience, not the exit condition.
   ══════════════════════════════════════════════════════════════════════ */
.gs-wrap { position: relative; }
.gs-btn { display: inline-flex; align-items: center; gap: 7px; padding: 6px 11px;
  border-radius: 8px; border: 1px solid var(--brand-border); background: var(--bg-elevated);
  color: var(--brand-text); font-family: var(--font-ui); font-size: 13px; font-weight: 600;
  cursor: pointer; position: relative; white-space: nowrap; }
.gs-btn:hover { background: var(--brand-dim); }
.gs-btn svg { width: 15px; height: 15px; }
.gs-badge { position: absolute; top: -6px; right: -6px; min-width: 18px; height: 18px;
  padding: 0 5px; border-radius: 99px; background: var(--brand-primary); color: #fff;
  font-size: 11px; font-weight: 700; display: flex; align-items: center;
  justify-content: center; border: 2px solid var(--bg-elevated); }

.gs-pop { position: absolute; top: calc(100% + 8px); right: 0; width: 340px;
  background: var(--bg-elevated); border: 1px solid var(--border); border-radius: 12px;
  z-index: 1100; display: none;
  box-shadow: 0 16px 40px rgba(15,23,42,.16), 0 2px 6px rgba(15,23,42,.06); }
.gs-pop.open { display: block; animation: stFade .14s ease-out; }
.gs-head { display: flex; align-items: center; gap: 9px; padding: 14px 14px 0; }
.gs-head h3 { font-size: 14px; font-weight: 650; letter-spacing: -.01em; margin: 0; }
.gs-count { font-size: 12.5px; color: var(--text3); font-weight: 600; }
.gs-x { margin-left: auto; width: 24px; height: 24px; border: 0; background: none;
  border-radius: 6px; color: var(--text3); cursor: pointer; display: flex;
  align-items: center; justify-content: center; }
.gs-x:hover { background: var(--bg-subtle); color: var(--text); }
.gs-x svg { width: 15px; height: 15px; }
.gs-track { height: 5px; border-radius: 99px; background: var(--bg-subtle);
  margin: 11px 14px 4px; overflow: hidden; }
.gs-track i { display: block; height: 100%; background: var(--brand-primary);
  border-radius: 99px; transition: width .25s ease; }
.gs-list { padding: 6px 6px 8px; }
.gs-item { display: flex; align-items: flex-start; gap: 10px; width: 100%; padding: 8px;
  border: 0; background: none; border-radius: 8px; cursor: pointer; text-align: left;
  font-family: var(--font-ui); }
.gs-item:hover { background: var(--bg-surface); }
.gs-mark { width: 17px; height: 17px; flex-shrink: 0; margin-top: 1px; }
.gs-mark svg { width: 17px; height: 17px; display: block; }
/* Both spans are block: as inline they ran together into one paragraph
   ("Relisez et approuvezVous gardez le dernier mot"). */
.gs-item .gs-t { display: block; font-size: 13px; font-weight: 600; color: var(--text);
  line-height: 1.35; }
.gs-item .gs-s { display: block; font-size: 12px; color: var(--text3); line-height: 1.4;
  margin-top: 2px; }
.gs-item.done .gs-t { color: var(--text3); font-weight: 500; text-decoration: line-through; }
.gs-item.done .gs-s { display: none; }
.gs-foot { border-top: 1px solid var(--border-subtle); padding: 9px 14px; display: flex;
  align-items: center; justify-content: space-between; gap: 10px; }
.gs-foot-t { font-size: 12px; color: var(--text3); }
.gs-dismiss { font-size: 12px; font-weight: 600; color: var(--text3); background: none;
  border: 0; cursor: pointer; font-family: var(--font-ui); padding: 0; }
.gs-dismiss:hover { color: var(--text); }

/* The empty state's copy of the list. Same rows, same marks, same track -
   only the chrome differs, because here it is the page rather than a popover:
   no dismiss, no close, and it is as wide as a reading column instead of
   340px. */
.gs-empty { width: 100%; max-width: 470px; margin: 0 auto; text-align: left;
  border: 1px solid var(--border); border-radius: 13px; background: var(--bg-elevated);
  padding: 18px 10px 12px; }
.gs-empty-head { display: flex; align-items: baseline; gap: 9px; padding: 0 10px 2px; }
.gs-empty-head h2 { font-family: var(--font-display); font-size: 1.05rem; font-weight: 640;
  letter-spacing: -.01em; margin: 0; }
.gs-empty .gs-track { margin: 10px 10px 4px; }
.gs-empty .gs-item { padding: 9px 10px; }

/* ══════════════════════════════════════════════════════════════════════
   SETTINGS MODAL  (.st-*)
   One surface for what used to be three full-page views - Profil,
   Abonnement and Marques - plus the account menu's Langue row. The rail
   groups them the way the account owns them: COMPTE (you) vs ESPACE DE
   TRAVAIL (the work). Nothing was dropped in the move; every control kept
   its id, which is what tests/test_nothing_removed.py freezes.

   No `!important` anywhere in this block: the classes are new, so nothing
   competes for them, and `display` in particular must stay overridable -
   several rows here are hidden imperatively (`el.style.display='none'`) by
   the client-mode hide and by renderWithdrawalOption, and an !important
   stylesheet rule beats a plain inline one. That exact mistake un-hid the
   account menu's owner-only rows once already.
   ══════════════════════════════════════════════════════════════════════ */
.st-overlay { position: fixed; inset: 0; background: rgba(15,23,42,.42);
  display: none; align-items: center; justify-content: center; z-index: 1150;
  padding: 24px; }
.st-overlay.open { display: flex; animation: stFade .14s ease-out; }
@keyframes stFade { from { opacity: 0 } to { opacity: 1 } }

.st-modal { width: 100%; max-width: 1180px; height: min(830px, calc(100vh - 48px));
  background: var(--bg-elevated); border-radius: 14px;
  box-shadow: 0 24px 64px rgba(15,23,42,.30); display: flex; position: relative;
  overflow: hidden; animation: stRise .16s ease-out; }
@keyframes stRise { from { opacity: 0; transform: translateY(8px) } to { opacity: 1; transform: none } }

.st-close { position: absolute; top: 14px; right: 14px; width: 30px; height: 30px;
  border: 0; background: none; border-radius: 7px; color: var(--text3);
  cursor: pointer; display: flex; align-items: center; justify-content: center; z-index: 3; }
.st-close:hover { background: var(--bg-subtle); color: var(--text); }
.st-close svg { width: 18px; height: 18px; }

/* ── rail ───────────────────────────────────────────── */
.st-rail { width: 250px; flex-shrink: 0; background: var(--bg-base);
  border-right: 1px solid var(--border-subtle); display: flex; flex-direction: column; }
.st-rail-head { display: flex; align-items: center; gap: 10px; padding: 16px 14px 14px; min-width: 0; }
.st-ws-mark { width: 30px; height: 30px; border-radius: 8px; background: var(--bg-elevated);
  border: 1px solid var(--border); display: flex; align-items: center; justify-content: center;
  color: var(--text2); flex-shrink: 0; font-size: 12px; font-weight: 700; }
.st-ws-name { font-size: 14px; font-weight: 650; line-height: 1.25; letter-spacing: -.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.st-ws-sub { font-size: 11.5px; color: var(--text3); line-height: 1.3; margin-top: 1px; }

.st-group { font-size: 10.5px; font-weight: 650; letter-spacing: .07em; text-transform: uppercase;
  color: var(--text3); padding: 14px 18px 6px; }
.st-rail-items { padding: 0 8px; flex: 1; overflow-y: auto; min-height: 0; }
.st-rail-foot { border-top: 1px solid var(--border-subtle); padding: 8px; }

.st-nav { display: flex; align-items: center; gap: 11px; width: 100%; padding: 8px 10px;
  border: 0; background: none; border-radius: 8px; cursor: pointer; text-align: left;
  font-family: inherit; font-size: 13.5px; font-weight: 500; color: var(--text2);
  text-decoration: none; transition: background .12s, color .12s; }
.st-nav:hover { background: var(--bg-subtle); color: var(--text); }
.st-nav svg { width: 16px; height: 16px; flex-shrink: 0; }
.st-nav.active { background: var(--brand-dim); color: var(--brand-text); font-weight: 600; }

/* ── pane ───────────────────────────────────────────── */
.st-pane { flex: 1; overflow-y: auto; padding: 34px 40px 44px; min-width: 0; }
.st-panel { display: none; }
.st-panel.on { display: block; animation: stFade .16s ease-out; }
.st-title { font-size: 21px; font-weight: 680; letter-spacing: -.02em; color: var(--text); }
.st-lede { font-size: 13.5px; color: var(--text3); margin-top: 5px; line-height: 1.55; max-width: 640px; }

.st-sec { margin-top: 28px; }
.st-sec-h { font-size: 14px; font-weight: 640; margin-bottom: 10px; letter-spacing: -.01em;
  display: flex; align-items: center; justify-content: space-between; gap: 12px; color: var(--text); }
.st-sec-note { font-size: 12.5px; color: var(--text3); margin: -4px 0 10px; line-height: 1.5; }
.st-sec-meta { font-size: 12px; font-weight: 500; color: var(--text3); }

.st-card { border: 1px solid var(--border); border-radius: 11px; background: var(--bg-elevated);
  overflow: hidden; }
.st-row { display: flex; align-items: center; gap: 13px; padding: 14px 16px; }
/* Rows carrying chips under the subtitle are three lines tall; a centred icon
   then floats away from the title it labels. */
.st-row.top { align-items: flex-start; }
.st-row + .st-row { border-top: 1px solid var(--border-subtle); }
.st-ico { width: 30px; height: 30px; border-radius: 8px; background: var(--bg-surface);
  display: flex; align-items: center; justify-content: center; color: var(--text2);
  flex-shrink: 0; font-size: 12px; font-weight: 700; }
.st-ico svg { width: 15px; height: 15px; }
.st-ico.brand { background: var(--brand-dim); color: var(--brand-text); }
.st-row-body { flex: 1; min-width: 0; }
.st-row-t { font-size: 13.5px; font-weight: 600; display: flex; align-items: center;
  gap: 7px; flex-wrap: wrap; color: var(--text); }
.st-row-s { font-size: 12.5px; color: var(--text3); margin-top: 2px; line-height: 1.45; }
.st-row-n { font-size: 19px; font-weight: 700; }

.st-field { padding: 14px 16px; }
.st-field + .st-field { border-top: 1px solid var(--border-subtle); }
.st-field label { display: block; font-size: 12.5px; font-weight: 600; color: var(--text2);
  margin-bottom: 6px; }
.st-input, .st-select { width: 100%; max-width: 380px; padding: 8px 11px;
  border: 1px solid var(--border); border-radius: 8px; font-family: inherit;
  font-size: 13.5px; color: var(--text); background: var(--bg-elevated); outline: none; }
.st-input:focus, .st-select:focus { border-color: var(--brand-primary);
  box-shadow: 0 0 0 3px var(--brand-dim); }

.st-btn { display: inline-flex; align-items: center; gap: 6px; padding: 7px 13px;
  border-radius: 8px; font-family: inherit; font-size: 13px; font-weight: 600;
  cursor: pointer; border: 1px solid var(--border); background: var(--bg-elevated);
  color: var(--text); text-decoration: none; white-space: nowrap; }
.st-btn:hover { background: var(--bg-surface); }
.st-btn svg { width: 14px; height: 14px; flex-shrink: 0; }
.st-btn.primary { background: var(--brand-primary); border-color: var(--brand-primary); color: #fff; }
.st-btn.primary:hover { background: var(--brand-hover); }
.st-btn.danger { background: var(--red); border-color: var(--red); color: #fff; }
.st-btn.quiet { color: var(--brand-text); border-color: var(--brand-border); }
.st-btn.outline-danger { color: var(--red); border-color: var(--red-border); background: var(--bg-elevated); }

.st-chip { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px;
  border-radius: 20px; font-size: 11px; font-weight: 650; white-space: nowrap; }
.st-chip svg { width: 11px; height: 11px; }
.st-chip.ok { background: var(--green-bg); color: var(--green); border: 1px solid var(--green-border); }
.st-chip.off { background: var(--bg-surface); color: var(--text3); border: 1px solid var(--border); }
.st-chip.warn { background: var(--amber-bg); color: var(--amber); border: 1px solid var(--warning-border); }

.st-meter { height: 6px; border-radius: 99px; background: var(--bg-subtle);
  overflow: hidden; margin-top: 9px; }
.st-meter i { display: block; height: 100%; background: var(--brand-primary); border-radius: 99px; }

.st-danger-h { font-size: 14px; font-weight: 640; color: var(--red); margin-bottom: 10px; }
.st-danger { border: 1px solid var(--red-border); background: var(--red-bg);
  border-radius: 11px; padding: 15px 16px; }
.st-danger .st-row { padding: 0; }

.st-feats { display: grid; grid-template-columns: 1fr 1fr; gap: 16px 22px; }
.st-feat { display: flex; gap: 12px; }
.st-feat .st-ico { background: var(--brand-dim); color: var(--brand-text); }
.st-steps { display: grid; grid-template-columns: 1fr 1fr; gap: 11px; }
.st-step { border: 1px solid var(--border); border-radius: 11px; padding: 14px 15px; }
.st-step-t { font-size: 13.5px; font-weight: 640; display: flex; align-items: center; color: var(--text); }
.st-step-n { width: 21px; height: 21px; border-radius: 6px; background: var(--brand-dim);
  color: var(--brand-text); font-size: 11.5px; font-weight: 700; display: inline-flex;
  align-items: center; justify-content: center; margin-right: 8px; flex-shrink: 0; }
.st-step-s { font-size: 12.5px; color: var(--text3); margin: 6px 0 9px; line-height: 1.5; }
.st-step-a { font-size: 12.5px; font-weight: 640; color: var(--brand-text);
  text-decoration: none; background: none; border: 0; padding: 0; cursor: pointer;
  font-family: inherit; }

/* Blocks lifted out of the old Profil view kept their .profile-* classes, so
   nothing had to be retyped and no id moved. These rules make them read as
   .st-card sections instead of the old grey panels. Scoped to .st-panel so the
   originals are untouched wherever else they are used. */
.st-panel .profile-card { background: var(--bg-elevated); border: 1px solid var(--border);
  border-radius: 11px; padding: 16px; margin: 0; }
.st-panel .profile-section-title { font-size: 14px; font-weight: 640; text-transform: none;
  letter-spacing: -.01em; color: var(--text); margin: 0 0 12px; }
/* .st-card carries NO padding by design - its children (.st-row, .st-field)
   own it, so they can draw full-width separators between rows. A block lifted
   straight in, like the name/email pair, therefore has none at all: the label
   sat on the card's top border and the input ran flush against its left edge. */
.st-panel .st-card > .profile-fields { padding: 14px 16px; }
/* .field brings its own 1rem bottom margin, which stacked on top of the flex
   gap and left ~30px between two fields. One spacing owner, not two. */
.st-panel .profile-fields { gap: 16px; }
.st-panel .profile-fields .field { margin-bottom: 0; }
.st-panel .profile-fields label { font-size: 12.5px; font-weight: 600; color: var(--text2); }
/* Not scoped to .profile-card: the name/email pair was lifted out of it into a
   plain .st-card, so a .profile-card ancestor selector matches nothing there
   and the inputs run the full 930px pane. */
.st-panel .profile-fields input { max-width: 380px; }
.st-panel .stat-card { border-radius: 10px; background: var(--bg-elevated); }

/* The brand list and the plan grid were authored for a full-bleed view. Inside
   the pane they get a narrower column, so relax their fixed track widths rather
   than restyling either component. */
.st-panel .brands-grid-wrap, .st-panel .sub-wrap, .st-panel .profile-wrap {
  padding: 0; margin: 0; max-width: none; overflow: visible; }
.st-panel .sub-grid { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 12px; }

@media (max-width: 900px) {
  .st-modal { flex-direction: column; height: calc(100vh - 32px); }
  .st-rail { width: auto; border-right: 0; border-bottom: 1px solid var(--border-subtle); }
  .st-rail-items { display: flex; overflow-x: auto; gap: 4px; padding: 6px 8px; }
  .st-rail-items .st-group { display: none; }
  .st-nav { width: auto; white-space: nowrap; }
  .st-pane { padding: 22px 20px 32px; }
  .st-feats, .st-steps { grid-template-columns: 1fr; }
}

/* Main: offset by nav width, full height, no scrollbar on main itself */
.main { margin-left: 48px !important; }
.main.nav-collapsed { margin-left: 48px !important; }

/* Article list pane: scrollbar always visible so no width-jump on content change.
   (Drawer-open padding + .main transition live next to the .detail-panel block.) */
.article-list-pane { overflow-y: scroll !important; scrollbar-gutter: stable !important; }

/* Mobile: the nav is an off-canvas drawer opened by the burger. It was
   previously display:none here, which silently broke the burger menu —
   the overlay dimmed the page but no drawer ever appeared. */
@media (max-width: 768px) {
  .nav {
    display: flex !important;
    transform: translateX(-100%) !important;
    transition: transform .25s ease !important;
    z-index: 400 !important;
    width: 230px !important;
    overflow-y: auto !important;
    align-items: stretch !important;
  }
  .nav.open { transform: translateX(0) !important; }
  .main, .main.nav-collapsed { margin-left: 0 !important; }
}

/* ==================== DASHBOARD VISUAL OVERRIDE (variant-final) ==================== */

/* ── Topbar ── */
.dashboard-topbar {
  height: 52px !important;
  background: #FFFFFF !important;
  border-bottom: 1px solid rgba(193,199,211,0.4) !important;
  padding: 0 20px !important;
  gap: 12px !important;
}
.topbar-title {
  font-family: var(--font-ui) !important;
  font-size: 15px !important;
  font-weight: 700 !important;
  letter-spacing: 0 !important;
  color: #191C1E !important;
  flex: 1 !important;
}
.topbar-search {
  height: 32px !important;
  border: 1px solid rgba(193,199,211,0.6) !important;
  border-radius: 7px !important;
  background: #F7F9FB !important;
  padding: 0 10px 0 30px !important;
  font-family: var(--font-ui) !important;
  font-size: 12px !important;
  max-width: 200px !important;
  flex: 0 0 200px !important;
  margin: 0 !important;
}
.topbar-search:hover { border-color: rgba(193,199,211,0.9) !important; }
.topbar-search:focus-within { border-color: #0051D5 !important; background: #FFFFFF !important; box-shadow: 0 0 0 3px rgba(0,81,213,0.1) !important; }
.topbar-cta {
  height: 32px !important;
  background: #0051D5 !important;
  color: white !important;
  border: none !important;
  border-radius: 6px !important;
  padding: 0 14px !important;
  font-family: var(--font-ui) !important;
  font-size: 13px !important;
  font-weight: 600 !important;
  cursor: pointer !important;
  white-space: nowrap !important;
  display: flex !important; align-items: center !important; gap: 5px !important;
}
.topbar-cta:hover { background: #003EA8 !important; }
.topbar-cta-label { font-size: 13px !important; }
.dash-topbar-right { display: flex; align-items: center; gap: 6px; }
.header-icon-btn {
  width: 32px !important; height: 32px !important;
  border: 1px solid rgba(193,199,211,0.6) !important;
  border-radius: 7px !important;
  background: #FFFFFF !important;
  display: flex !important; align-items: center !important; justify-content: center !important;
  color: #717783 !important;
  cursor: pointer !important;
  position: relative !important;
}
.header-icon-btn:hover { background: #F2F4F6 !important; }
.btn-ghost {
  height: 32px !important;
  border: 1px solid rgba(193,199,211,0.6) !important;
  border-radius: 6px !important;
  background: #FFFFFF !important;
  color: #505F76 !important;
  font-family: var(--font-ui) !important;
  font-size: 12px !important;
  font-weight: 500 !important;
  padding: 0 10px !important;
  display: flex !important; align-items: center !important; gap: 5px !important;
  cursor: pointer !important;
}
.btn-ghost:hover { background: #F2F4F6 !important; }
/* Quota visibility is a business signal, not clutter. It moved from the topbar
   to the sidebar (.nav-wallet) rather than being dropped — the topbar rules
   that used to live here are gone with the element. */

/* ── Status strip → pill tabs (variant-final style) ── */
.status-strip {
  height: 44px !important;
  background: #FFFFFF !important;
  border-bottom: 1px solid var(--border-subtle) !important;
  display: flex !important;
  align-items: center !important;
  padding: 0 20px !important;
  gap: 4px !important;
}
.view-header .status-strip { overflow-x: auto !important; flex-wrap: nowrap !important; gap: 4px !important; padding: 0 20px !important; }
.status-chip {
  height: 26px !important;
  padding: 0 10px !important;
  border-radius: var(--radius-pill) !important;
  font-family: var(--font-ui) !important;
  font-size: 12px !important;
  font-weight: 500 !important;
  color: #717783 !important;
  background: transparent !important;
  border: 1px solid transparent !important;
  border-bottom: 1px solid transparent !important;
  cursor: pointer !important;
  display: flex !important;
  align-items: center !important;
  gap: 5px !important;
  transition: background 0.12s, color 0.12s !important;
  white-space: nowrap !important;
  margin-bottom: 0 !important;
}
.status-chip:hover { background: #F2F4F6 !important; color: #505F76 !important; border-bottom-color: transparent !important; }
.status-chip.active {
  background: #191C1E !important;
  color: white !important;
  border-color: #191C1E !important;
  font-weight: 500 !important;
}
.status-chip-count {
  font-family: var(--font-ui) !important;
  font-size: 11px !important;
  opacity: 0.75 !important;
  background: transparent !important;
  padding: 0 !important;
  border-radius: 0 !important;
  color: inherit !important;
  letter-spacing: 0 !important;
}
.status-chip.active .status-chip-count { color: rgba(255,255,255,0.75) !important; }

/* ── Article list filter bar ──────────────────────────────────────────────
   This bar was `display:none !important` for months, which silently took the
   language filter (#al-lang-filter) and the sort control (#al-sort) off the
   screen even though both were wired and working. They are back.

   The search input and the brand filter stay hidden INSIDE the bar rather than
   being moved out: the topbar search proxies into #al-search by dispatching a
   synthetic `input` event, and the sidebar brand switcher reads
   #al-client-filter as its source of truth. Both must remain in the DOM, and
   showing them here would put a second search box and a second brand picker on
   a screen that already has one of each. */
.al-filter-bar { display: flex !important; justify-content: flex-end; margin: 0 !important; gap: 8px; }
.al-filter-bar .al-search-wrap { display: none !important; }
/* Delta text sits inline beside its value now, not stacked under it. */
.al-toolbar .kpi-delta { margin-top: 0 !important; min-height: 0 !important; font-size: 10.5px; }

/* ── Transient action bars ────────────────────────────────────────────────
   The selection bar and the batch-progress pill used to sit in the flow above
   the table, so ticking a single checkbox shoved the whole list down ~40px and
   ticking it again shoved it back. They now float over the bottom-right of the
   list, so the content never moves. Anchored above the pager row, and inset to
   clear the detail drawer when it is open. */
.al-floatbar {
  position: absolute;
  right: 20px; bottom: 20px;
  z-index: 60;
  max-width: min(700px, calc(100% - 40px));
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
}
/* No drawer offset is needed: .detail-panel is position:fixed and
   .main.drawer-open sets padding-right, so .article-list-wrap — the positioned
   ancestor this bar anchors to — already ends where the drawer begins.
   Offsetting again here would push the bar a second 380/600px to the left. */
@media (max-width: 768px) {
  .al-floatbar { right: 12px; left: 12px; bottom: 12px; max-width: none; }
}
/* _alBulkRefreshBar() / _bulkPill() set style.display directly, so direction
   and alignment live here where an inline display cannot clobber them. */
.al-floatbar-row { align-items: center; gap: 8px; padding: 8px 12px; }
/* The selection bar grew two buttons when bulk share shipped, and at the old
   560px cap the count was the flex item that gave way: "2 selectionnes"
   rendered as "2...", which is the one word in the bar that has to be legible.
   It keeps its intrinsic width here and the row wraps instead. Scoped to
   -row because the batch progress pill's count (.al-floatbar-head) genuinely
   wants flex:1 + ellipsis - its text is long and its column is narrow. */
.al-floatbar-row { flex-wrap: wrap; }
.al-floatbar-row > .al-floatbar-count { flex: 0 0 auto; }
.al-floatbar-col { flex-direction: column; gap: 0; overflow: hidden; }
.al-floatbar-head { display: flex; align-items: center; gap: 8px; padding: 8px 12px; }
.al-floatbar-count {
  flex: 1; min-width: 0;
  font-size: 12px; color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.al-floatbar .btn-ghost { font-size: 12px; }
.al-floatbar-x { font-size: 11px !important; padding: 4px 8px; }
.al-floatbar-danger { color: var(--red); }
.al-floatbar-danger:hover { color: var(--red); border-color: var(--red); }
.al-select {
  height: 28px !important;
  border: 1px solid var(--border) !important;
  border-radius: var(--radius-sm) !important;
  background: #FFFFFF !important;
  font-family: var(--font-ui) !important;
  font-size: 12px !important;
  color: #191C1E !important;
  padding: 0 20px 0 8px !important;
}
.al-search-wrap {
  height: 28px !important;
  border: 1px solid var(--border) !important;
  border-radius: var(--radius-sm) !important;
  background: #F7F9FB !important;
  padding: 0 8px 0 26px !important;
}

/* ══════════════════════════════════════════════════════════
   Attio grid skin (2026-07-17): flat spreadsheet, single source
   of truth for the planner's look.
   - White surface, hairline row/column borders, no card chrome
   - Normal-case quiet headers with icons
   - Pastel chips for statuses, muted empties
   - Status pills as chips in white cells (no full-cell fill)
   ══════════════════════════════════════════════════════════ */

/* Rows — breathable but still dense.
   grid-template-rows pins the implicit grid track to the row height so
   cells (which are grid items) can't auto-size taller than the row box and
   leak their hover bg into the row below.
   overflow:hidden is the belt — even if a child tries to escape, it's
   clipped at the row's outer edge.

   64px since 2026-08-24, and it is arithmetic, not taste: 8px padding + a
   28px segment + a 4px gap + a 16px caption + 8px padding. At 56px the rail
   cell measured 70px tall inside a 56px box, so its 8px of padding was
   entirely eaten and the rail cleared the row edge by ONE pixel top and
   bottom — every other column had 8. This trio (height + grid-template-rows +
   overflow, all !important) clips anything taller AND DOES SO SILENTLY: the
   caption simply did not render, with no error and no layout shift to notice.
   If you change any of those four numbers, change this one to their sum. */
.al-row {
  transition: background 0.1s !important;
  height: 64px !important;
  grid-template-rows: 64px !important;
  overflow: hidden !important;
  background: #FFFFFF !important;
  /* The row is the containing block for anything a cell positions against it.
     Without it, an absolutely-positioned descendant escapes up to
     .article-list-wrap (the next positioned ancestor) and paints across the
     whole list area — which is what the old row-level shimmer bar did before
     this line existed. */
  position: relative !important;
}
.al-row:hover {
  background: #F7F9FB !important;
}

/* ══════════════════════════════════════════════════════════════════════════
   Pipeline rail (design-shotgun 2026-08-23, variant B1). The action button
   moved INSIDE the article cell 2026-08-23; .al-act-cell is now a modifier on
   .al-step-cell, not a column of its own.
   Replaced seven per-step columns that took 70% of the table's width to
   carry one bit each. Segment geometry is deliberate: 28px tall, which with
   the 4px gap and the 16px caption fills the row's 48px content box exactly.
   ══════════════════════════════════════════════════════════════════════════ */
.al-rail-cell {
  display: flex; flex-direction: column; justify-content: center;
  min-width: 0; padding: 0 12px !important; gap: 0;
}
.al-rail { display: flex; gap: 4px; width: 100%; }
.al-rail-seg {
  flex: 1 1 0; min-width: 0; height: 28px;
  border-radius: 6px;
  display: flex; align-items: center; justify-content: center;
  line-height: 1;
  /* Not-yet-run: the icon is legible but clearly inert. It was #DDE2E9 on
     #F7F9FB, which is under 1.3:1 — you could not see which step it was. */
  background: #F4F6F8; color: #AEB6C2;
  cursor: pointer;
  position: relative;
  transition: filter 0.1s, box-shadow 0.1s;
}
.al-rail-seg:hover { filter: brightness(0.95); }
.al-rail-seg:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; }
.al-rail-seg.is-queued { background: #EDF0F3; color: #9CA6B4; }
/* Done: green fill, DARKER green icon. The icon is what tells you which step
   this is; a ✓ told you only that something finished, so seven completed
   segments read as seven identical marks. 4.9:1 on the fill. */
.al-rail-seg.is-done   { background: #DCFCE7; color: #15803D; }
/* ── Flux ring — the "this step is running" border ──
   One palette, one keyframe, one geometry, read by the running rail segment
   below and by the Article cell's ring. (It was shared with a topbar
   generation pill until 2026-08-26, when that pill was removed and its
   percentage moved into the per-card Article cell.)

   RECOLOURING IS NOT JUST --flux-from / --flux-to. This comment used to say
   it was, and it is wrong: `--flux-gradient` resolves its own var() calls
   HERE, at :root, and what inherits downward is the finished token stream
   with these two hexes already baked in. Overriding the endpoints on a
   descendant changes nothing — the ring stays blue, silently, and looks like
   the override simply had no effect. To recolour, an element must redeclare
   --flux-mid and --flux-gradient as well; the `.al-flux-ring` block below
   does that once so the recipe still lives in exactly one place.
   Ported from the Progressive Flux loader (vivid blue → cyan, sweeping left
   to right) to plain CSS: this app has no React and no Tailwind, so the
   component itself could not be used.

   The ring is a masked pseudo-element, not a border: `padding` sets its
   thickness and the two-layer mask punches the content box out of the
   gradient, leaving the perimeter. `mask-composite` MUST be written after the
   `mask` shorthand, which resets it. */
:root {
  --flux-from: #1d6ffb;
  --flux-to:   #74e1ff;
  --flux-mid:  color-mix(in oklab, var(--flux-from), var(--flux-to));
  /* Both ends are --flux-from, so a 200%-wide background loops seamlessly. */
  --flux-gradient: linear-gradient(90deg,
    var(--flux-from) 0%, var(--flux-mid) 35%, var(--flux-to) 55%,
    var(--flux-mid) 78%, var(--flux-from) 100%);
  --flux-ring-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  --flux-glow: 0 0 8px color-mix(in oklab, var(--flux-from) 35%, transparent);
}

/* The step that is running. The ring sits on the SEGMENT and never on the row:
   `.al-row` is `overflow: hidden` with a hard 64px grid track, so a row-level
   ring loses its top edge to the row above's border and to the sticky header —
   it renders, it measures correctly, and it is visibly clipped. The segment has
   8px of vertical slack inside that track (28px chip + 4px gap + 16px caption
   in a 48px content box), which is what makes an OUTER ring safe here.

   -1.5px keeps the exact geometry of the flat `0 0 0 1.5px` ring this replaced,
   so the chip does not move when a step starts, and it leaves the 0..2px band
   free for the open-step inset ring below to stack into. */
.al-rail-seg.is-active {
  background: #DBEAFE; color: #1D4ED8;
  box-shadow: var(--flux-glow);
}
.al-rail-seg.is-active::before {
  content: '';
  position: absolute; inset: -1.5px;
  box-sizing: border-box;
  padding: 1.5px;                      /* = ring thickness */
  border-radius: 7.5px;                /* the chip's 6px + the 1.5px outside it */
  background: var(--flux-gradient);
  background-size: 200% 100%;
  -webkit-mask: var(--flux-ring-mask);
  -webkit-mask-composite: xor;
  mask: var(--flux-ring-mask);
  mask-composite: exclude;
  /* Re-render survival: renderArticleList() replaces innerHTML on every SSE
     event and on a 1s interval during a run, which restarts every CSS
     animation at frame 0 — all rows snapping back together is the "global
     blink". buildArticleRow() inlines --shimmer-phase on the row as
     `-(elapsed % 3000)` and it inherits down to here, so the freshly-created
     ring picks up where the destroyed one left off. KEEP THIS AT 3s: any other
     duration desynchronises against that modulo, silently. */
  animation: shimmer-sweep-vf 3s infinite linear;
  animation-delay: var(--shimmer-phase, 0s);
  pointer-events: none;
}
.al-rail-seg.is-ask,
.al-rail-seg.is-ready   { background: #FDE68A; color: #92400E; }
.al-rail-seg.is-failed,
.al-rail-seg.is-persona-empty { background: #FDEEEC; color: #B02A1C; }

/* The step you are looking at. An INSET ring, so it stacks with the running
   state's flux ring instead of fighting it — a step can be running and open at
   the same time, and both facts matter. The caret underneath is the
   part that survives a squint: colour differences between seven small chips
   are easy to miss, a pointer is not. */
.al-rail-seg[data-open="1"] {
  box-shadow: inset 0 0 0 2px #191C1E;
  color: #191C1E;
}
.al-rail-seg[data-open="1"]::after {
  content: ''; position: absolute; left: 50%; bottom: -5px;
  width: 0; height: 0; transform: translateX(-50%);
  border-left: 4px solid transparent; border-right: 4px solid transparent;
  border-top: 4px solid #191C1E;
}
/* Restated because box-shadow does not stack across rules and `[data-open]`
   above matches at equal specificity but later, so it would drop the glow. The
   ring itself is a pseudo-element and survives on its own. */
.al-rail-seg.is-active[data-open="1"] { box-shadow: inset 0 0 0 2px #191C1E, var(--flux-glow); }

/* The caption is the only place in the row that says WHERE the run is, in
   words. It must ellipsize rather than clip: a bare text node inside a flex
   box has no box to ellipsize, so this is a block-level span on purpose. */
.al-rail-cap {
  display: block; margin-top: 4px;
  font-family: var(--font-ui); font-size: 10.5px; line-height: 16px; color: #9CA3AF;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.al-rail-cap.is-waiting { color: #B45309; font-weight: 600; }

/* ── The Article cell IS the control (2026-08-26) ──────────────────────────
   The action was a 32px pill floating inside a 12px-padded cell: a rounded
   rectangle drawn inside the rectangle the column rules already draw, with
   the cell's own hover tint reading as a second, larger hit target that did
   nothing. The button is now the cell — it fills the content box edge to
   edge, so the column rule frames the control and there is exactly one box.

   Same colour language, painted on a bigger surface. The two OUTLINED
   variants become tinted fills (matching .pill-review / .pill-error, which
   already carry those exact hues) because a 1px outline at the cell's edge
   would sit one pixel from the column rule and read as a doubled line. */
/* Specificity note: `.al-row > * { padding: 8px 12px !important }` in the grid
   skin below is (0,1,0) and comes LATER in the file, so a bare `.al-act-cell`
   loses the tie and the button sat 48px tall in a 64px cell. Two classes wins
   it outright rather than relying on source order. */
.al-step-cell.al-act-cell {
  display: flex; align-items: stretch;
  min-width: 0; padding: 0 !important;
}
/* WHITE BASE, TINT ON TOP, COLOUR IN THE TEXT — the announcement pill's
   recipe (static/css/announcement.css), which is the one surface in this app
   whose colour treatment the owner picked deliberately. Its rule there is
   worth restating: "the tint is deliberately weak — the glass carries the
   look, the colour only names the kind. A strong fill kills the blur
   underneath." Solid #2563EB and #D97706 cells were the opposite of that:
   twenty drafts made a wall of saturated blue, and the amber that means
   "this row wants you" stopped being the loudest thing on screen because
   everything was loud.
   The tint is a pseudo-element under the label (z-index:-1 against
   `isolation: isolate`), exactly as `.ann::before` does it, so the button
   keeps a real white ground instead of a flattened blend. */
.al-act {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  position: relative; isolation: isolate;
  font-family: var(--font-ui); font-size: 11.5px; font-weight: 600;
  /* Fills the cell, so the row's height is the only height there is. */
  width: 100%; height: 100%;
  background: #FFFFFF;
  border: 0; border-radius: 0; padding: 0 12px; cursor: pointer;
  white-space: nowrap; overflow: hidden;
  transition: box-shadow 0.16s ease;
}
.al-act::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: var(--act-tint, transparent);
  transition: opacity 0.16s ease;
  opacity: 1;
}
.al-act:hover::before { opacity: 0.55; }
.al-act svg { width: 10px; height: 10px; flex-shrink: 0; }
.al-act span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Démarrer and Répondre are the two cells that ASK for something, so they
   carry the stronger of the two tint weights the announcement uses (.10/.05,
   its `new` and `warning` types). Relire only offers, so it takes the weaker
   `info` weight. The hairline is an inset shadow, never a border: a real
   border would change the box and shift the label by a pixel between states. */
.al-act-start {
  --act-tint: linear-gradient(180deg, rgba(0, 81, 213, 0.10), rgba(0, 81, 213, 0.05));
  color: #0051D5;
}
.al-act-answer {
  --act-tint: linear-gradient(180deg, rgba(160, 94, 0, 0.12), rgba(160, 94, 0, 0.05));
  color: #8A5100;
}
.al-act-review {
  --act-tint: linear-gradient(180deg, rgba(0, 81, 213, 0.07), rgba(0, 81, 213, 0.03));
  color: #0051D5;
  box-shadow: inset 0 0 0 1px rgba(0, 81, 213, 0.14);
}
/* A run that died. Red so the row still reads as failed once the "Interrompu"
   pill it replaced is gone; the stored error is on the button's title. */
.al-act-restart {
  --act-tint: linear-gradient(180deg, rgba(180, 35, 24, 0.10), rgba(180, 35, 24, 0.04));
  color: #B42318;
}

/* ── THE RING MEANS "THIS CELL IS THE RUN" ────────────────────────────────
   The same masked gradient border the running cell animates, held at one
   frame. Blue: ready to start. Amber: the run is blocked on YOU. Red: the run
   died. Relire and Publié get NO ring, because they are about the article,
   not about the run — which is what stops the ring from becoming decoration.

   Recoloured by overriding --flux-from / --flux-to, exactly as the flux block
   says to: --flux-gradient is a token stream, so it re-resolves against
   whichever element finally uses it. No second copy of the gradient.

   This is also what buys back the prominence the amber slab used to have.
   "This row wants you" has to stay the loudest thing on the page, and a weak
   tint alone was quieter than the blue rings around it — which would have
   made a paying client's blocked article the calmest row in the grid. */
/* The recipe, re-declared on the elements that change its inputs — see the
   flux token block for why inheriting it is not enough. Listed once; each
   variant below sets only the two endpoints. */
.al-act-start,
.al-act-answer,
.al-act-restart {
  --flux-mid: color-mix(in oklab, var(--flux-from), var(--flux-to));
  --flux-gradient: linear-gradient(90deg,
    var(--flux-from) 0%, var(--flux-mid) 35%, var(--flux-to) 55%,
    var(--flux-mid) 78%, var(--flux-from) 100%);
}
.al-act-start::after,
.al-act-answer::after,
.al-act-restart::after {
  content: ''; position: absolute; inset: 0; z-index: 0;
  box-sizing: border-box;
  padding: 1.5px;                      /* = ring thickness */
  background: var(--flux-gradient);
  background-size: 200% 100%;
  background-position: 32% 0;          /* a frame carrying both ends of the ramp */
  -webkit-mask: var(--flux-ring-mask);
  -webkit-mask-composite: xor;
  mask: var(--flux-ring-mask);
  mask-composite: exclude;
  pointer-events: none;
}
.al-act-start::after   { opacity: 0.60; }
.al-act-answer::after  { opacity: 1;    padding: 2px; }
.al-act-restart::after { opacity: 0.65; }
.al-act-answer  { --flux-from: #D97706; --flux-to: #FBBF24; }
.al-act-restart { --flux-from: #B42318; --flux-to: #F97066; }
.al-act-start:hover::after,
.al-act-restart:hover::after { opacity: 0.95; }
/* The cell no longer paints anything of its own — the button covers it — so
   its hover tint would only show through a transparent button, which none of
   the variants are. Killed so there is one hover, on the control. */
.al-step-cell.al-act-cell:hover { background: transparent !important; }

/* Somebody is blocked on this row. inset so it cannot be clipped by the row's
   own overflow:hidden, and on the row rather than a cell so it reads before
   you have parsed any column. */
.al-row.awaits-user { box-shadow: inset 3px 0 0 #D97706 !important; }

.al-row.selected {
  background: #EEF2FF !important;
  box-shadow: inset 3px 0 0 0 #0051D5 !important;
  border-color: var(--border-subtle) !important;
}
.al-row > * {
  padding-top: 8px !important;
  padding-bottom: 8px !important;
}
.al-row-header {
  /* Solid off-white (opacity is what matters for the anti-bleed fix below,
     not the exact hue) + own compositing layer (will-change:transform) so
     Chrome paints the header on a separate layer above the rows. Without
     this, sub-pixel rendering or stacking-context quirks were letting row
     text visibly bleed through the background during scroll. */
  background: #FFFFFF !important;
  /* The rule under the header is the box-shadow on the next line, NOT a
     border. Two reasons. It was drawing BOTH, which stacks two 1px lines into
     a 2px seam heavier than every other horizontal in the table. And a border
     eats layout height: the header is a fixed 40px, so a 1px border left a
     39px content box, which is what the stretched header cells fill -- their
     column rules then stopped 1px short AND 39 is off the 4px grid that
     `tests/test_grid_columns.py` enforces. A shadow paints outside the box and
     costs no height, so the cells get the full 40. */
  border-bottom: 0 !important;
  box-shadow: 0 1px 0 var(--border);
  position: sticky !important;
  top: 0 !important;
  z-index: 50 !important;
  height: 40px !important;
  border-radius: 0 !important;
  will-change: transform;
  transform: translateZ(0);
  isolation: isolate;
}
/* Belt-and-suspenders: each header cell carries its own solid bg so no
   sub-pixel gap or transparent child can let a row peek through. */
.al-row-header > .al-th { background: #FFFFFF !important; }

/* Sortable headers — icon + label + ▲▼ arrows visible on every column */
.al-row-header > * {
  position: relative;
  cursor: pointer;
  border-right: 1px solid var(--border-subtle) !important;
  display: flex !important;
  align-items: center !important;
  gap: 8px !important;
}
.al-row-header > *:last-child { border-right: 0 !important; }
.al-row-header > .al-th > span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* The ▲▼ affordance is drawn ONLY on headers that can actually sort.
   It used to be drawn on all eleven, and no header had a click handler bound
   at all — every column promised a sort and none of them delivered one. The
   list supports exactly three sorts (newest / seo / status, see the sort block
   in renderArticleList), so Article and Score carry data-sort and the pipeline
   step columns correctly show nothing. */
.al-row-header > .al-th[data-sort] { cursor: pointer; }
.al-row-header > .al-th[data-sort]:hover { color: var(--text-primary) !important; }
.al-row-header > .al-th[data-sort]:focus-visible {
  outline: 2px solid var(--brand-primary); outline-offset: -2px;
}
.al-row-header > .al-th[data-sort]::after {
  content: '▲\A▼';
  white-space: pre;
  display: inline-block;
  font-family: var(--font-ui);
  font-size: 7px;
  line-height: 7px;
  margin-left: auto;
  padding-left: 6px;
  opacity: 0.32;
  vertical-align: middle;
  transform: translateY(-1px);
  flex-shrink: 0;
}
.al-row-header > .al-th.al-sorted::after { opacity: 1; color: var(--brand-primary); }

/* Header icons — small, muted, in front of the label */
.al-th-icon {
  width: 13px; height: 13px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.7;
  flex-shrink: 0;
  color: #4B5563;
}
.al-th-icon polygon { fill: currentColor; stroke: currentColor; opacity: 0.55; }

/* Step-cell checkmark — clean green check, no redundant label */
.al-step-check {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px; height: 22px;
  border-radius: 50%;
  background: #ECFDF5;
  color: #047857;
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
}
.al-step-cell:hover .al-step-check {
  background: #D1FAE5;
}

/* ── Status as filled cell background (the defining Variant C move).
   Resting states (published/review/draft) are consolidated further down,
   next to the pill-chrome strip — this block keeps only the shared font
   rule and the in-progress "generating" shimmer, which is untouched. ── */
.al-step-cell[data-step="article"] {
  font-weight: 600 !important;
  font-family: var(--font-ui) !important;
  font-size: 12.5px !important;
}
/* The running state used to fill this whole cell amber (#FEF3C7 + italic
   #92400E). Three problems, all visible in one screenshot: it is the same
   amber as .al-step-review-pill, so "working" and "needs you" looked
   identical; it painted 241x64 of the grid's loudest colour for a state that
   asks nothing of the reader; and the blue spinner + blue progress rule sat
   on top of it, so one cell carried two unrelated hues. It is now one blue
   pill like every other state on the row — see .al-gen-pill below, which
   must come AFTER .al-step-cell.active to beat its background. */

/* Score column — small rounded badge (brief: "70+ green badge, 50-69 amber
   badge, missing score gray dash"). Keeps the monospace numeric styling from
   Variant C but restores real padding so the pale green/amber fill reads as
   a badge/chip rather than a same-size color-behind-text sliver. */
.al-cell-seo .score-badge {
  font-family: var(--font-ui) !important;
  font-size: 12.5px !important;
  font-weight: 700 !important;
  border: 0 !important;
  padding: 1px 8px !important;
  min-width: 32px !important;
}
.al-cell-seo .score-badge.none { padding: 0 !important; min-width: 12px !important; }
/* Attio headers: normal case, quiet gray, no shouting */
.al-row-header > * {
  font-family: var(--font-ui) !important;
  font-size: 12.5px !important;
  font-weight: 500 !important;
  text-transform: none !important;
  letter-spacing: 0 !important;
  color: var(--text2, #505F76) !important;
}

/* ── Step cells — column dividers come from the single border-right rule
   in the grid-lines section below (one line per boundary, no doubling) ── */
.al-step-cell {
  font-size: 11.5px !important;
  font-weight: 500 !important;
  font-family: var(--font-ui) !important;
}
/* The generation percentage used to render as a 2px rule pinned to this
   cell's bottom edge (left/right 8px, bottom 5px) — three px above the row's
   OWN blue underline, so a running row showed two near-identical blue lines
   stacked, and the pale track read as a stray horizontal rule rather than as
   progress. It is now the cell's own fill (.al-gen-fill) plus the number
   beside the label (.al-gen-pct) — see the running block further down.
   `.gen-progress-bar` is not emitted here, and as of 2026-08-26 nothing in
   this file emits it at all; its rules near :1851 are unreferenced. */
.al-step-cell.done[data-step="persona"] { color: #5B21B6 !important; }
.al-step-cell.done[data-step="persona"]:hover { background: rgba(124,58,237,0.06) !important; }
.al-step-cell.done[data-step="brief"] { color: #1D4ED8 !important; }
.al-step-cell.done[data-step="brief"]:hover { background: rgba(37,99,235,0.06) !important; }
.al-step-cell.done[data-step="interview"] { color: #92400E !important; }
.al-step-cell.done[data-step="interview"]:hover { background: rgba(217,119,6,0.06) !important; }
.al-step-cell.done[data-step="article"] { color: #065F46 !important; }
.al-step-cell.done[data-step="article"]:hover { background: rgba(5,150,105,0.06) !important; }
/* Published pill: primary-action affordance — clicking opens the editor directly. */
.al-step-cell.published-pill { cursor: pointer; position: relative; transition: background 120ms ease, transform 120ms ease; }
.al-step-cell.published-pill:hover { background: rgba(5,150,105,0.10) !important; transform: translateY(-1px); }
.al-step-cell.published-pill:active { transform: translateY(0); }
.al-step-cell.published-pill .al-step-text { font-weight: 600; }
/* Active step — the CELL is the button.
   Solid pale-blue base; a white sweep animates ON TOP as a pseudo-element so
   the gradient stays fully contained (overflow:hidden) and the text/spinner
   sit static above it via z-index. No bleed into neighbouring cells. */
@keyframes al-shimmer-blue { 0% { background-position: 200% 0; } 100% { background-position: -100% 0; } }
@keyframes al-step-spin { to { transform: rotate(360deg); } }
.al-step-cell.active {
  position: relative !important;
  overflow: hidden !important;
  background: #DBEAFE !important;
  color: #1E40AF !important;
  font-style: normal !important;
  font-weight: 600 !important;
  isolation: isolate !important;
}
.al-step-cell.active::before {
  content: '';
  position: absolute;
  inset: 0;
  /* Soft, continuous reflection — wider+softer band so the highlight reads
     as a breathing gradient rather than a pulse-flash. Stays inside the cell
     (overflow:hidden + isolation:isolate above), so no neighbour or site bleed.
     animation-delay reads --cell-shimmer-phase (inlined per render) so the
     animation survives renderArticleList()'s innerHTML thrash — see
     `.al-rail-seg.is-active::before` for the full story. */
  background: linear-gradient(110deg,
    transparent 30%,
    rgba(255,255,255,0.30) 50%,
    transparent 70%);
  background-size: 200% 100%;
  background-repeat: no-repeat;
  background-position: 200% 0;
  animation: al-shimmer-blue 3.6s linear infinite;
  animation-delay: var(--cell-shimmer-phase, 0s);
  pointer-events: none;
  z-index: 0;
}
.al-step-cell.active > * { position: relative; z-index: 1; }
.al-step-spin {
  display: inline-block;
  width: 11px; height: 11px;
  border: 1.5px solid rgba(30,64,175,0.25);
  border-top-color: #1E40AF;
  border-radius: 50%;
  margin-right: 6px;
  vertical-align: middle;
  animation: al-step-spin 0.8s linear infinite;
  /* Inherits from the .al-step-cell.active inline style — same phase-sync
     trick as the shimmer, otherwise the spinner snaps back to 0° on every
     1s render. */
  animation-delay: var(--spin-phase, 0s);
  flex-shrink: 0;
}
.al-step-cell.active .al-step-text { display: inline-flex; align-items: center; white-space: nowrap; min-width: 0; }
/* The label span is what ellipsizes — the inline-flex parent above cannot (see
   activeTxt). Without this, "Génération…" hard-clips in a 104px column. */
.al-step-cell.active .al-step-text > .al-step-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.al-step-cell.queued { color: #9CA3AF !important; opacity: 0.55 !important; cursor: default !important; }

/* Review needed — amber pill with pulsing dot, matches the AirOps "Review Needed" treatment */
.al-step-cell.needs-input { color: #B45309 !important; cursor: pointer !important; }
.al-step-cell.needs-input:hover { background: rgba(180,83,9,0.06) !important; }
.al-step-review-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px 3px 7px;
  background: #FEF3C7;
  border: 1px solid #FDE68A;
  border-radius: var(--radius-xs);
  font-family: var(--font-ui);
  font-size: 11px; font-weight: 600;
  color: #92400E;
  white-space: nowrap;
  max-width: 100%;
  min-width: 0;
  overflow: hidden;
}
.al-step-review-pill > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.al-step-review-pill::before {
  content: '';
  width: 6px; height: 6px;
  border-radius: 50%;
  background: #D97706;
  flex-shrink: 0;
  animation: al-step-pulse 1.4s ease-in-out infinite;
}
@keyframes al-step-pulse { 0%,100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.55; transform: scale(0.85); } }

.al-step-cell.empty { color: #9CA3AF !important; cursor: default !important; }
.al-step-cell.failed { color: #B91C1C !important; cursor: pointer !important; font-weight: 600 !important; }
.al-step-cell.failed:hover { background: rgba(185,28,28,0.07) !important; }

/* Legacy keyframe kept for the residual amber refs in other components */
@keyframes al-shimmer { 0%,100% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } }

/* ── Runnable chip — idle state for a step the user can launch.
   Default: button-look with step label (e.g. "Démarrer"). On hover, label
   slides out and a ▶ Play icon takes over. Click triggers the pipeline. */
.al-step-cell.runnable { cursor: pointer !important; }
.al-step-runchip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 11px;
  background: rgba(0,81,213,0.06);
  border: 1px solid rgba(0,81,213,0.22);
  border-radius: var(--radius-sm);
  font-family: var(--font-ui);
  font-size: 11px; font-weight: 600;
  color: #0051D5;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
  white-space: nowrap;
  user-select: none;
}
.al-step-runchip .al-step-runplay { display: none; align-items: center; justify-content: center; }
.al-step-runchip .al-step-runplay svg { width: 11px; height: 11px; fill: currentColor; }
.al-step-cell.runnable:hover .al-step-runchip {
  background: #0051D5;
  border-color: #0051D5;
  color: #fff;
}
.al-step-cell.runnable:hover .al-step-runchip .al-step-runlabel { display: none; }
.al-step-cell.runnable:hover .al-step-runchip .al-step-runplay { display: inline-flex; }

/* ── View output hover overlay on completed cells.
   The base cell shows the green check pill; on hover an overlay slides in
   with "View output" text — clicking the cell opens the right detail panel. */
/* ── Done cell hover = "Voir" via CSS only, no overlay element ──
   The cell IS the button. On hover its background turns mint, the green
   check is hidden, and ::after renders "Voir" in its place. Nothing floats
   on top of the cell — everything happens inside the cell's own box, so
   there's nothing that can bleed past the column divider. */
.al-step-cell.done {
  transition: background 0.12s ease, color 0.12s ease;
}
.al-step-cell.done:hover {
  background: #ECFDF5 !important;
  color: #047857 !important;
}
.al-step-cell.done:hover .al-step-check { display: none; }
.al-step-cell.done:hover::after {
  content: 'Voir';
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 600;
  color: #047857;
  letter-spacing: 0.01em;
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}
/* HTML root is always lang="en", so use data-ui-lang (set by i18n.setLang)
   to flip to English. Default stays "Voir" for the French primary audience. */
[data-ui-lang="en"] .al-step-cell.done:hover::after { content: 'View'; }

/* Suppress the "Voir" swap on cells that have their own content language
   (Brief preview text, Article status pills) — we don't want to hide
   "ANGLE A — SAFE" or "Publié" behind a generic "Voir" label.
   !important because the EN swap rule above ([data-ui-lang="en"] …) has
   HIGHER specificity than this suppression — without it, English UI paints
   "View" on top of the status pill (text-on-text overlap bug). */
.al-step-cell[data-step="brief"].done:hover::after,
.al-step-cell[data-step="article"]:hover::after { content: none !important; }
.al-step-cell[data-step="brief"].done:hover .al-step-check,
.al-step-cell[data-step="article"]:hover .al-step-check { display: inline-flex; }

/* ── Relancer button ── */
.al-step-run { display: none !important; font-size: 10px !important; font-weight: 500 !important; font-family: var(--font-ui) !important; border: 1px solid currentColor !important; border-radius: var(--radius-xs) !important; padding: 2px 5px !important; cursor: pointer !important; background: transparent !important; color: inherit !important; position: absolute !important; right: 4px !important; bottom: 6px !important; opacity: 0.7 !important; transition: opacity 0.15s !important; align-items: center !important; }
.al-row:hover .al-step-cell.done .al-step-run { display: flex !important; }
.al-step-run:hover { opacity: 1 !important; }

/* ── Kebab menu button ── */
.al-kebab-col { width: 28px !important; display: flex !important; align-items: center !important; justify-content: center !important; padding: 0 !important; }
.al-kebab-btn { width: 24px !important; height: 24px !important; border-radius: var(--radius-xs) !important; border: none !important; background: transparent !important; color: #717783 !important; cursor: pointer !important; opacity: 0 !important; transition: opacity 0.15s !important, background 0.15s !important; display: flex !important; align-items: center !important; justify-content: center !important; }
.al-row:hover .al-kebab-btn { opacity: 1 !important; }
.al-kebab-btn:hover { background: #F2F4F6 !important; color: #191C1E !important; }

/* ── Row open button ── */
.al-open-btn { display: none !important; align-items: center !important; gap: 4px !important; height: 22px !important; padding: 0 8px !important; border: 1px solid var(--border) !important; border-radius: var(--radius-xs) !important; background: #FFFFFF !important; color: #505F76 !important; font-family: var(--font-ui) !important; font-size: 11px !important; font-weight: 500 !important; cursor: pointer !important; white-space: nowrap !important; flex-shrink: 0 !important; transition: background 0.12s, color 0.12s, border-color 0.12s !important; }
.al-row:hover .al-open-btn { display: inline-flex !important; }
.al-row.content-ready .al-open-btn { display: inline-flex !important; }
.al-open-btn:hover { background: #0051D5 !important; color: #FFFFFF !important; border-color: #0051D5 !important; }

/* ── Score badges ── */
.score-badge {
  height: 22px !important;
  min-width: 44px !important;
  border-radius: var(--radius-xs) !important;
  font-family: var(--font-ui) !important;
  font-size: 12px !important;
  font-weight: 600 !important;
  padding: 0 8px !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
}
.score-badge.green { background: #EDFAF4 !important; color: #1A7F5A !important; }
.score-badge.amber { background: #FDF5E6 !important; color: #A05E00 !important; }
.score-badge.none { color: #9CA3AF !important; background: transparent !important; }
.score-badge { border-radius: var(--radius-sm) !important; }

/* ── Grid polish pass — AirOps-style spreadsheet chrome: real checkboxes,
   row numbers, clearer vertical grid lines, and pill-in-cell status.
   Additive on purpose: placed after every earlier rule in this file so
   equal-!important cascade order resolves in favor of these without
   touching the documented shimmer/bleed-fix rules above (.active,
   .status-running stay untouched — only the resting states change). ── */

/* Row + header checkboxes — a real spreadsheet checkbox, not an invisible hitbox */
.al-row-check {
  width: 15px !important; height: 15px !important;
  border-radius: var(--radius-xs) !important;
  border: 1.5px solid var(--border-strong) !important;
  background: #FFFFFF !important;
  flex-shrink: 0 !important;
  display: inline-flex !important; align-items: center !important; justify-content: center !important;
  cursor: pointer !important;
  transition: background 0.12s, border-color 0.12s !important;
}
.al-row-check:hover { border-color: #0051D5 !important; }
.al-row-check.checked { background: #0051D5 !important; border-color: #0051D5 !important; }
.al-row-check.checked::after {
  content: '' !important;
  width: 4px !important; height: 7px !important;
  border: solid #FFFFFF !important; border-width: 0 1.6px 1.6px 0 !important;
  transform: rotate(45deg) translate(-1px, -1.5px) !important;
}
.al-header-check {
  width: 15px !important; height: 15px !important;
  border-radius: var(--radius-xs) !important;
  border: 1.5px solid var(--border-strong) !important;
  background: #FFFFFF !important;
  flex-shrink: 0 !important;
  display: inline-flex !important; align-items: center !important; justify-content: center !important;
  cursor: pointer !important;
  transition: background 0.12s, border-color 0.12s !important;
}
.al-header-check:hover { border-color: #0051D5 !important; }
.al-header-check.checked { background: #0051D5 !important; border-color: #0051D5 !important; }
.al-header-check.checked::after {
  content: '' !important;
  width: 4px !important; height: 7px !important;
  border: solid #FFFFFF !important; border-width: 0 1.6px 1.6px 0 !important;
  transform: rotate(45deg) translate(-1px, -1.5px) !important;
}
.al-header-check.indeterminate { background: #0051D5 !important; border-color: #0051D5 !important; }
.al-header-check.indeterminate::after {
  content: '' !important;
  width: 7px !important; height: 1.6px !important;
  background: #FFFFFF !important; border: none !important;
  transform: none !important;
}
/* Reserve the same width in the header as the row-number gutter below it,
   so the header icon/label lines up with row content rather than the checkbox. */
.al-th-rownum-sp { display: inline-block !important; width: 18px !important; flex-shrink: 0 !important; }

/* Rows belonging to a bulk-import group carry the same rail color as their
   .al-group header (at low opacity), so the banding visually ties a run of
   rows back to the header it came from — see the .al-group comment above. */
.al-row.al-row-grouped {
  border-left: 3px solid rgba(0,81,213,0.15) !important;
}

/* Row numbers — muted spreadsheet gutter, between checkbox and icon */
.al-row-num {
  font-family: var(--font-ui) !important;
  font-size: 10.5px !important;
  color: #9CA3AF !important;
  min-width: 18px !important;
  text-align: right !important;
  flex-shrink: 0 !important;
  user-select: none !important;
}

/* Stronger, clearer vertical grid lines — the spreadsheet feel.
   Every column boundary is drawn by the cell on its LEFT, and the header and
   the body must agree on every one of them. They did not: the header put a
   border on all four `.al-th`, while the body covered only the title and the
   article cell. The Pipeline|Article boundary was therefore drawn for the
   40px of the header and then stopped dead — a vertical line that is cut,
   which is what makes the grid read as a fabricated contour rather than as a
   spreadsheet. `.al-rail-cell` is the body cell under the Pipeline header; it
   was missed when the rail replaced the seven per-step columns on 2026-08-23.
   If you add a column, its body cell belongs in this rule. */
.al-row > .al-step-cell,
.al-row > .al-rail-cell,
.al-row > .al-client-cell,
.al-row-header > .al-th {
  border-right: 1px solid var(--border-subtle) !important;
}
.al-row > .al-title-col {
  border-right: 1px solid var(--border-subtle) !important;
}
.al-row > .al-cell-seo {
  border-left: none !important;
  /* No divider after Score: the 28px kebab gutter (hover-reveal ⋯ button)
     otherwise reads as an empty, useless column between two full-height
     lines. Same rule for the header cell just below. */
  border-right: none !important;
}
.al-row-header > .al-th[data-col="score"] { border-right: none !important; }

/* A rule is only a rule if it runs the full height of its row.
   `.al-row` and `.al-row-header` CENTER their grid items, so a cell is only
   as tall as its content and the border-right above is drawn on that content
   box, not on the row: 16px of line in a 40px header, 48px in a 64px row.
   Stack those down a column and the "grid line" is a column of short dashes
   with a gap at every row boundary -- visible the moment you zoom, and the
   reason the table reads as a fabricated contour rather than a spreadsheet.
   `.al-rail-cell` and `.al-step-cell` already filled their rows, which is why
   only some boundaries looked broken.
   Every cell that draws a rule is stretched to its row instead. Each one
   centres its own content internally (the header cells and `.al-title-col`
   are `display:flex; align-items:center`, `.al-rail-cell` is a centred
   column), so nothing on screen moves except the lines closing up. */
.al-row-header > *,
.al-row > .al-title-col,
.al-row > .al-rail-cell,
.al-row > .al-client-cell,
.al-row > .al-step-cell {
  align-self: stretch !important;
}

/* ── Article/status column — Attio style: WHITE cell, the status is a
   pastel tag chip (like Attio's Categories tags). Hover tints the cell
   only faintly; the chip carries the color. ── */
.al-step-cell[data-step="article"].status-published:hover,
.al-step-cell[data-step="article"].status-review:hover,
.al-step-cell[data-step="article"].status-draft:hover { background: #F7F9FB !important; }
.al-status-pill {
  display: inline-flex !important; align-items: center !important; gap: 4px !important;
  padding: 4px 8px !important;
  line-height: 16px !important;
  border-radius: var(--radius-xs) !important;
  font-family: var(--font-ui) !important;
  font-size: 11px !important; font-weight: 600 !important;
  white-space: nowrap !important;
  max-width: 100% !important;
}
.al-status-pill span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.al-status-pill svg { width: 11px; height: 11px; flex-shrink: 0; }
.al-status-pill.pill-published { background: #EDFAF4 !important; color: #1A7F5A !important; }
.al-status-pill.pill-review    { background: #EAF1FE !important; color: #1D4ED8 !important; }
.al-status-pill.pill-draft     { background: #F1F2F4 !important; color: #6B7280 !important; }
.al-status-pill.pill-error     { background: #FEF2F2 !important; color: #B91C1C !important; }

/* ── Running: the cell is the progress surface ─────────────────────────────
   Blue, because blue already means "in progress" everywhere else in this grid
   — the row underline, .al-step-cell.active, the fill gradient — which leaves
   amber meaning only "this row wants you".

   Full-bleed since 2026-08-26, for the same reason as .al-act above: a 24px
   pill inside a 64px cell was a second rectangle inside the one the column
   rules already draw. Filling the cell also bought the width that had been
   the whole argument against showing the number here — the label ellipsizes
   and the percentage is pinned right, so it is legible at every column width
   instead of living in a topbar pill that could only ever report ONE run.
   That pill is gone; this readout is per card, which is what a grid of
   independent generations actually needs. */
.al-step-cell.status-running {
  background: transparent !important;
  color: inherit !important;
  font-style: normal !important;
  padding: 0 !important;
}
/* .al-step-cell.active paints a white shimmer sweep across its own pale-blue
   slab. The sweep would now animate over the fill — a third moving thing next
   to the spinner and the progress. */
.al-step-cell.status-running::before { display: none !important; }
.al-gen-pill {
  position: relative !important;
  overflow: hidden !important;
  display: flex !important;
  align-items: center !important;
  gap: 6px !important;
  width: 100% !important; height: 100% !important;
  padding: 0 12px !important;
  border-radius: 0 !important;
  font-family: var(--font-ui) !important;
  font-size: 11.5px !important; font-weight: 600 !important;
  white-space: nowrap !important;
  /* WHITE, not a blue slab. The colour is in the ring and in the text; the
     progress is a wash over white rather than a fill of it. Same reasoning as
     the announcement pill and the action cells above. */
  background: #FFFFFF !important;
  color: #1D4ED8 !important;
}
/* THE RING, ALL THE WAY AROUND THE CELL.
   `inset: 0`, not the rail segment's `-1.5px`: `.al-row` is
   `overflow: hidden` with a hard 64px grid track and this cell fills that
   track exactly, so an OUTER ring would lose its top and bottom edges to the
   row box — it would render, measure correctly, and be visibly clipped. The
   documented reason the rail's ring lives on the 28px chip is that the chip
   has 8px of slack; a full-height cell has none, so the ring goes inside.
   Radius 0 because the cell is square: the gradient becomes the cell's own
   border for the length of the run, column rule included.
   `--shimmer-phase` is inlined on the row by buildArticleRow and inherits
   here, so the sweep survives the 1s innerHTML rebuild instead of snapping
   back to frame 0 with every other row at once. KEEP THIS AT 3s — the phase
   is a modulo of 3000 and any other duration desynchronises silently. */
.al-gen-pill::before {
  content: ''; position: absolute; inset: 0; z-index: 2;
  box-sizing: border-box;
  padding: 2px;                        /* = ring thickness */
  background: var(--flux-gradient);
  background-size: 200% 100%;
  -webkit-mask: var(--flux-ring-mask);
  -webkit-mask-composite: xor;
  mask: var(--flux-ring-mask);
  mask-composite: exclude;
  animation: shimmer-sweep-vf 3s infinite linear;
  animation-delay: var(--shimmer-phase, 0s);
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  /* Keep the ring, drop the sweep — the border still says "running". */
  .al-gen-pill::before { animation: none; background-position: 32% 0; }
}
.al-step-cell.status-running:hover .al-gen-fill { opacity: 0.75; }
.al-gen-fill {
  position: absolute !important;
  left: 0 !important; top: 0 !important; bottom: 0 !important;
  /* The leading edge is FEATHERED, not a hard step. A flat block ending at
     62% puts a vertical seam straight through whichever glyph happens to sit
     there — it reads as a rendering fault, not as progress.
     A WASH over white since 2026-08-26, at the announcement pill's tint
     weight rather than a solid blue-100: the cell's ground has to stay
     legibly white for the ring to read as a border rather than as an edge
     between two blues. */
  background: linear-gradient(90deg,
    rgba(0, 81, 213, 0.10) 0%,
    rgba(0, 81, 213, 0.10) calc(100% - 18px),
    rgba(0, 81, 213, 0) 100%) !important;
  /* Width easing was chosen to match .gen-progress-fill's; opacity rides the
     same declaration so the hover wash and the advance cannot be split into
     two rules that later disagree. Both gated below for reduced-motion. */
  transition: opacity 0.16s ease,
              width 0.8s cubic-bezier(0.4, 0, 0.2, 1) !important;
  pointer-events: none !important;
}
.al-gen-pill > .al-step-spin,
.al-gen-pill > .al-gen-label { position: relative !important; z-index: 1 !important; }
.al-gen-pill > .al-step-spin {
  /* border-box, so the ring measures 11px like the .al-status-pill svg icons
     it sits beside — content-box made it 12.3 and the pill's two marks were
     visibly different sizes. */
  box-sizing: border-box !important;
  width: 11px !important; height: 11px !important;
  margin-right: 0 !important;
  border-width: 1.5px !important;
  border-color: rgba(29, 78, 216, 0.28) !important;
  border-top-color: #1D4ED8 !important;
}
.al-gen-pill > .al-gen-label {
  flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  /* The cell inherits `text-align: center`, and the label is the flex item
     that absorbs the slack — so its text centred itself inside a 141px box
     and floated away from the spinner it belongs to. `start`, not `left`, so
     it still follows the writing direction. */
  text-align: start;
}
/* The number is the one thing that must never ellipsize, so it is taken out
   of the flex give entirely and the label absorbs every squeeze. Tabular
   figures so 9% -> 10% -> 100% does not shuffle the text beside it. */
.al-gen-pill > .al-gen-pct {
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
  z-index: 1; position: relative;
}
@media (prefers-reduced-motion: reduce) {
  .al-gen-fill { transition: none !important; }
}

/* Error icon — parity with the green done-check, red circle instead */
.al-step-error {
  display: inline-flex !important; align-items: center !important; justify-content: center !important;
  width: 15px !important; height: 15px !important;
  border-radius: 50% !important;
  background: #FDEEEC !important; color: #C0392B !important;
  flex-shrink: 0 !important;
  vertical-align: middle !important;
}
.al-step-error svg { width: 8px; height: 8px; }

/* Answer-needed button — icon + label, matches the icon-forward cell style */
.al-step-answer { display: inline-flex !important; align-items: center !important; gap: 5px !important; }

/* ── Detail panel slide-in (variant-final drawer style) ── */
.detail-panel {
  position: fixed !important;
  right: 0 !important; top: 0 !important; bottom: 0 !important;
  width: 380px !important;
  background: #FFFFFF !important;
  border-left: 1px solid var(--border) !important;
  box-shadow: -8px 0 32px rgba(0,81,213,0.08) !important;
  transform: translateX(100%) !important;
  transition: transform 0.15s ease !important;
  display: flex !important; flex-direction: column !important;
  overflow: hidden !important;
  /* Above the article-drawer (#editor-view, 150): when both are open the step
     drawer stays in front and the article slides in behind it. */
  z-index: 180 !important;
  flex-shrink: 0 !important;
}
.detail-panel.dp-open {
  transform: translateX(0) !important;
}
/* Wider drawer when a pipeline step is open */
.detail-panel.dp-wide { width: 600px !important; }
.main.drawer-open.drawer-wide { padding-right: 600px !important; }
/* Main content shifts right when drawer opens — CSS class replaces inline style to avoid scrollbar-jump */
.main { transition: padding-right 0.25s cubic-bezier(0.4,0,0.2,1) !important; }
.main.drawer-open { padding-right: 380px !important; }
/* Always-on scrollbar on article list prevents width shift when drawer opens */
.article-list-pane { overflow-y: scroll !important; }
.article-list-wrap { position: relative !important; }
/* Hide backdrop on desktop — drawer slides alongside content, no overlay needed */
@media (min-width: 769px) { .dp-backdrop { display: none !important; } }

/* ≤768: the drawer overlays with a backdrop — it must span the viewport and
   never push the page. The base 380/600px !important rules above win on
   source order, so these need !important too. */
@media (max-width: 768px) {
  .detail-panel, .detail-panel.dp-wide { width: 100vw !important; max-width: 100vw !important; }
  .main.drawer-open, .main.drawer-open.drawer-wide { padding-right: 0 !important; }
  /* Above the fixed .mobile-header (z-index 300) — it was covering the
     drawer's title row and ✕ close button, leaving no visible way to close */
  .detail-panel { z-index: 400 !important; }
  .dp-backdrop { z-index: 399 !important; }
}
/* Tablets: cap the wide (pipeline-step) drawer so content keeps ≥30vw */
@media (min-width: 769px) and (max-width: 1024px) {
  .detail-panel.dp-wide { width: min(600px, 70vw) !important; }
  .main.drawer-open.drawer-wide { padding-right: min(600px, 70vw) !important; }
}
/* 1025–1440px with drawer closed: the 1180px grid outgrows the pane and the
   only affordance is an out-of-sight scrollbar. Plain fr columns refuse to
   shrink below their pill text (min-content), so the band needs explicit
   shrinkable minmax() floors + truncating pills. */
@media (min-width: 1025px) and (max-width: 1440px) {
  .al-row, .al-row-header {
    min-width: 0;
    /* Six tracks since 2026-08-23, matching the base rule. This override
       exists ONLY to give every column a shrinkable floor at this width; it
       must carry the same track COUNT or the row shears away from its header
       and, before the rail, silently squeezed the pipeline to 9px segments. */
    grid-template-columns: minmax(200px,2fr) minmax(210px,1.35fr) minmax(130px,1fr) 96px 28px;
  }
  .al-step-cell { min-width: 0; overflow: hidden; }
  .al-step-cell .al-status-pill span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .al-title-col, .al-title-text { min-width: 0; }
  .al-kw { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block; }
  .al-kw-sub { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  /* Headers must stay words, not "PE…": tighten type, keep the Attio icons —
     ellipsis on the label handles any residual overflow */
  .al-row-header > .al-th { font-size: 11.5px !important; line-height: 16px !important; padding: 0 12px !important; gap: 8px !important; }
  .al-th .al-th-icon { width: 12px; height: 12px; }
  .al-step-answer { min-width: 0; overflow: hidden; }
  .al-step-answer span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

/* When the detail panel is open on a not-huge desktop, the 380–600px it steals
   crushes the 11-column article grid into an unreadable smear. Below ~1500px,
   fall back to the same stacked-card layout used on tablet so the keyword grid
   stays usable while the panel is open. Closing the panel restores the grid. */
@media (min-width: 1025px) and (max-width: 1500px) {
  .main.drawer-open .article-list-pane .al-row-header { display: none !important; }
  .main.drawer-open .article-list-pane .al-row {
    display: flex !important; flex-wrap: wrap; row-gap: 0.55rem; column-gap: 0;
    padding: 0.8rem 1rem !important; align-items: center;
    min-width: 0 !important; height: auto !important;
  }
  .main.drawer-open .article-list-pane .al-row .al-title-col { order: 1; flex: 1 1 calc(100% - 50px); min-width: 0; display: flex; align-items: center; gap: 10px; padding: 0 !important; }
  .main.drawer-open .article-list-pane .al-row .al-title-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
  .main.drawer-open .article-list-pane .al-row .al-kw { font-size: 0.9rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .main.drawer-open .article-list-pane .al-row .al-kw-sub { margin-top: 0; white-space: nowrap; }
  .main.drawer-open .article-list-pane .al-row .al-kebab-btn { order: 2; flex-shrink: 0; width: 34px; height: 34px; border-radius: var(--radius-md); display: flex; align-items: center; justify-content: center; padding: 0 !important; }
  .main.drawer-open .article-list-pane .al-row .al-step-cell {
    order: 3; flex: 1 1 90px; min-width: 60px;
    font-size: 11px !important; padding: 6px 6px !important;
    justify-content: center; border-left: 1px solid var(--border-subtle) !important; height: 30px;
  }
  .main.drawer-open .article-list-pane .al-row .al-cell-seo { order: 4; width: 100%; padding: 0 !important; }
  .main.drawer-open .article-list-pane .al-row .al-cell-seo:has(.al-cell-dash) { display: none; }
}

/* The running indicator is the flux ring on the RAIL SEGMENT (see
   `.al-rail-seg.is-active` above), not an edge on the row. A row-level ring —
   the 2px bottom line this file carried until 2026-08-25, and the full-row ring
   that briefly replaced it — is clipped at the top by `.al-row`'s
   `overflow: hidden` against the row above's border and the sticky header. It
   also said only "something here is running", while the segment says WHICH
   step, in the place the reader is already looking. */
@keyframes shimmer-sweep-vf {
  0% { background-position: 0% 0; }
  100% { background-position: -200% 0; }
}

/* ── Scrollbar ── */
.article-list-pane::-webkit-scrollbar { width: 4px !important; }
.article-list-pane::-webkit-scrollbar-thumb { background: var(--border) !important; border-radius: var(--radius-xs) !important; }

/* ==================== DRAWER (variant-final) ==================== */

/* Empty state */
.dp-empty-state { display:flex;flex-direction:column;align-items:center;justify-content:center;flex:1;height:100%;font-family:var(--font-ui);font-size:13px;color:#9CA3AF;text-align:center;padding:40px 20px; }

/* Shell */
#dp-shell { display:flex;flex-direction:column;flex:1;overflow:hidden; }

/* Body + panels */
.dr-body { flex:1;overflow-y:auto; }
.drawer-panel { display:none;padding:20px; }
.drawer-panel.active { display:block; }
/* Section headers — Attio collapsible sections: chevron + title, click toggles
   the rows beneath (delegated handler `_drSectionToggle` in JS; div-based on
   purpose — native <details> is forbidden inside this flex scroll container,
   see the CSS rules in CLAUDE.md). */
.dr-section-label { font-family:var(--font-ui);font-size:12px;font-weight:600;text-transform:none;letter-spacing:0;color:#191C1E;margin-bottom:10px;margin-top:0;display:flex;align-items:center;gap:5px;cursor:pointer;user-select:none; }
.dr-section-label::before { content:'';width:0;height:0;border-left:4px solid #9CA3AF;border-top:3.5px solid transparent;border-bottom:3.5px solid transparent;flex-shrink:0;transform:rotate(90deg);transition:transform 0.15s; }
.dr-section-label.collapsed::before { transform:rotate(0deg); }
.dr-section-label:hover { color:#0051D5; }
.dr-div { height:1px;background:var(--border-subtle);margin:18px 0; }

/* (Stepper + gen-step-card styles removed 2026-07-17 with the editor's
   Pipeline tab — they had no other consumer.) */
.live-log { background:#F7F9FB;border-radius: var(--radius-sm);padding:8px;margin-top:8px; }
.log-line { font-family:var(--font-ui);font-size:10px;color:#717783;line-height:1.6;display:block; }

/* (Per-card AEO-row + GSC-tile styles removed 2026-07-17 with the editor's
   Pipeline tab — its summaries were their only consumer; the dedicated AEO
   view and GSC analytics view use their own classes.) */
.sparkline-wrap { margin-top:10px; }

.score-bar-row { display:flex;align-items:center;gap:8px;margin-bottom:6px; }
.score-bar-label { font-family:var(--font-ui);font-size:12px;color:#505F76;flex:1; }
.score-bar-track { flex:1;height:4px;background:#F2F4F6;border-radius:2px;overflow:hidden; }
.score-bar-fill { height:100%;background:#0051D5;border-radius:2px; }
.score-bar-val { font-family:var(--font-ui);font-size:12px;color:#191C1E;min-width:24px;text-align:right; }
/* Label/value rows — Attio record-details pattern: fixed gray label column,
   value fills the rest, no per-row borders */
.seo-meta-row { display:flex;gap:10px;padding:6px 0;border-bottom:none;align-items:baseline; }
.seo-meta-label { font-family:var(--font-ui);font-size:12px;font-weight:500;color:#717783;min-width:96px;flex-shrink:0; }
.seo-meta-val { font-family:var(--font-ui);font-size:12.5px;color:#191C1E;line-height:1.5;min-width:0; }
.seo-meta-val.mono { font-family:var(--font-ui);color:#505F76; }
.btn-outline-blue { margin-top:16px;height:34px;border:1px solid #0051D5;border-radius:6px;background:transparent;color:#0051D5;font-family:var(--font-ui);font-size:12px;font-weight:600;padding:0 14px;cursor:pointer;display:flex;align-items:center;gap:5px; }
.btn-outline-blue:hover { background:#EEF2FF; }

/* Revision tab */
.audit-item { display:flex;align-items:center;gap:8px;padding:6px 0;font-family:var(--font-ui);font-size:13px;color:#191C1E; }
.audit-dot { width:8px;height:8px;border-radius:50%;flex-shrink:0; }
.audit-dot.ok { background:#1A7F5A; }
.audit-dot.warn { background:#A05E00; }
.audit-item.warn { color:#A05E00; }
.fact-badges { display:flex;gap:6px;margin-bottom:8px; }
.fact-badge { height:22px;padding:0 8px;border-radius:4px;font-family:var(--font-ui);font-size:11px;font-weight:600;display:flex;align-items:center; }
.fact-badge.green { background:#EDFAF4;color:#1A7F5A; }
.fact-list { margin:0;padding:0 0 0 16px;font-family:var(--font-ui);font-size:12px;color:#505F76;line-height:1.8; }
.dr-textarea { width:100%;box-sizing:border-box;border:1px solid rgba(193,199,211,0.6);border-radius:8px;padding:10px;resize:vertical;font-family:var(--font-ui);font-size:13px;color:#191C1E;outline:none; }
.dr-textarea:focus { border-color:#0051D5;box-shadow:0 0 0 3px rgba(0,81,213,0.1); }

/* Publish tab */
.publish-status-card { background:#EDFAF4;border:1px solid rgba(26,127,90,0.2);border-radius:8px;padding:14px 16px;margin-bottom:16px; }
.publish-status-title { font-family:var(--font-ui);font-size:14px;font-weight:700;color:#1A7F5A; }
.publish-status-sub { font-family:var(--font-ui);font-size:12px;color:#505F76;margin-top:2px; }
.share-row { display:flex;gap:6px; }
.share-input { flex:1;height:32px;border:1px solid rgba(193,199,211,0.6);border-radius:6px;padding:0 8px;font-family:var(--font-ui);font-size:11px;color:#505F76;background:#F7F9FB;outline:none; }
.share-copy-btn { height:32px;padding:0 12px;border:1px solid rgba(193,199,211,0.6);border-radius:6px;background:white;font-family:var(--font-ui);font-size:12px;font-weight:600;color:#505F76;cursor:pointer; }
.share-copy-btn:hover { background:#F2F4F6; }
.export-btn { display:block;width:100%;height:34px;border:1px solid rgba(193,199,211,0.6);border-radius:6px;background:white;text-align:left;padding:0 12px;font-family:var(--font-ui);font-size:12px;color:#505F76;cursor:pointer;margin-bottom:6px; }
.export-btn:hover { background:#F2F4F6; }
.depublish-link { font-family:var(--font-ui);font-size:12px;color:#B91C1C;cursor:pointer;display:inline-block;margin-top:8px; }
.depublish-link:hover { text-decoration:underline; }

/* Gate banner (awaiting-input) */
.gate-banner { background:#FDF5E6;border:1px solid rgba(160,94,0,0.2);border-radius:8px;padding:14px 16px;margin-bottom:16px; }
.gate-banner-title { font-family:var(--font-ui);font-size:13px;font-weight:700;color:#A05E00; }
.gate-banner-sub { font-family:var(--font-ui);font-size:12px;color:#A05E00;margin-top:2px;opacity:0.85; }
.context-card { background:#F7F9FB;border:1px solid rgba(193,199,211,0.5);border-radius:8px;padding:12px 14px;margin-bottom:12px; }
.context-card-label { font-family:var(--font-ui);font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:0.08em;color:#717783;margin-bottom:6px; }
.context-item { font-family:var(--font-ui);font-size:12px;color:#505F76;line-height:1.6; }
.q-card { background:white;border:1px solid rgba(193,199,211,0.5);border-radius:8px;padding:12px 14px;margin-bottom:8px; }
.q-label { font-family:var(--font-ui);font-size:13px;font-weight:600;color:#191C1E;margin-bottom:8px; }
.q-answered { display:flex;align-items:center;gap:6px; }
.q-answer-pill { height:22px;padding:0 8px;border-radius:4px;background:#EEF2FF;font-family:var(--font-ui);font-size:12px;font-weight:500;color:#0051D5;display:flex;align-items:center; }
.q-check { color:#1A7F5A;font-weight:700; }
.q-toggle-group { display:flex;gap:6px;flex-wrap:wrap; }
.q-toggle { height:28px;padding:0 10px;border:1px solid rgba(193,199,211,0.6);border-radius:6px;background:white;font-family:var(--font-ui);font-size:12px;color:#717783;cursor:pointer; }
.q-toggle.active { background:#191C1E;color:white;border-color:#191C1E; }
.gate-progress { font-family:var(--font-ui);font-size:11px;color:#9CA3AF;display:block;margin-top:4px; }

/* Detail panel scrollbar */
.dr-body::-webkit-scrollbar { width:4px; }
.dr-body::-webkit-scrollbar-thumb { background:rgba(193,199,211,0.5);border-radius:2px; }
.ip-label { font-family:var(--font-ui);font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:0.08em;color:#717783; }

/* Actions panel */
.rp-actions-body { padding:16px;display:flex;flex-direction:column;gap:0;overflow-y:auto;flex:1; }
.rp-actions-body .btn-primary { width:100%;margin-bottom:0; }
.rp-actions-body .review-actions-divider { margin:10px 0 6px;font-family:var(--font-ui);font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:0.06em;color:#9CA3AF;text-align:center; }
.rp-actions-body .review-section { margin-bottom:12px; }

/* Scores panel sub-elements */
.rp-score-main { display:flex;align-items:center;gap:12px;padding:14px 16px;border-bottom:1px solid rgba(193,199,211,0.3); }
.rp-score-ring { position:relative;width:56px;height:56px;flex-shrink:0; }
.rp-score-ring-inner { position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);text-align:center; }
.rp-score-num { font-family:var(--font-ui);font-size:16px;font-weight:700;color:#191C1E;display:block; }
.rp-score-info { flex:1; }
.rp-score-label { font-family:var(--font-ui);font-size:13px;font-weight:700;color:#191C1E;display:block; }
.rp-score-sub { font-family:var(--font-ui);font-size:11px;color:#717783;display:block;margin-top:2px; }
.rp-dim-row { display:flex;align-items:center;gap:8px;padding:8px 16px;border-bottom:1px solid rgba(193,199,211,0.15); }
.rp-dim-label { font-family:var(--font-ui);font-size:12px;color:#505F76;flex:1; }
.rp-dim-track { flex:1;max-width:80px;height:4px;background:#F2F4F6;border-radius:2px;overflow:hidden; }
.rp-dim-fill { height:100%;border-radius:2px; }
.rp-dim-val { font-family:var(--font-ui);font-size:11px;color:#191C1E;min-width:24px;text-align:right; }
/* SEO drawer score ring */
.score-ring-wrap { display:flex;flex-direction:column;align-items:center;margin-bottom:16px; }
.score-ring-inner { position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);text-align:center; }
.score-ring-num { font-family:var(--font-ui);font-size:18px;font-weight:700;color:#191C1E; }
.score-ring-lbl { font-family:var(--font-ui);font-size:13px;font-weight:600;color:#191C1E;margin-top:8px; }
.score-ring-sub { font-family:var(--font-ui);font-size:11px;color:#717783; }

/* SERP result cards */
.rp-serp-item { padding:10px 14px;border-bottom:1px solid rgba(193,199,211,0.2); }
.rp-serp-item.ours { background:rgba(0,81,213,0.02);border-left:2px solid #0051D5; }
.rp-serp-domain { display:flex;align-items:center;gap:5px;margin-bottom:2px; }
.rp-serp-favicon { width:14px;height:14px;border-radius:50%;background:#E8EAED;display:flex;align-items:center;justify-content:center;font-size:7px;font-weight:700;color:#5F6368;flex-shrink:0; }
.rp-serp-host { font-family:var(--font-ui);font-size:11px;color:#5F6368; }
.rp-serp-rank { font-family:var(--font-ui);font-size:10px;color:#717783;margin-left:auto; }
.rp-serp-rank.ours { color:#1A7F5A;background:#EDFAF4;padding:1px 6px;border-radius:8px; }
.rp-serp-title { font-family:var(--font-ui);font-size:13px;color:#1A0DAB;line-height:1.35;margin-bottom:3px; }
.rp-serp-snippet { font-family:var(--font-ui);font-size:11.5px;color:#4D5156;line-height:1.5; }
.rp-serp-chips { display:flex;gap:5px;flex-wrap:wrap;margin-top:5px; }
.rp-serp-chip { font-family:var(--font-ui);font-size:9px;color:#717783;background:#F7F9FB;border:1px solid rgba(193,199,211,0.5);border-radius:4px;padding:2px 6px; }

/* Gap cards */
.rp-gap-card { margin:8px 14px;border-radius:8px;padding:10px 12px;border:1px solid rgba(193,199,211,0.4); }
.rp-gap-card.missing { border-color:rgba(192,57,43,0.25);border-left:3px solid #C0392B; }
.rp-gap-card.partial { border-color:rgba(160,94,0,0.25);border-left:3px solid #A05E00; }
.rp-gap-card.covered { border-color:rgba(26,127,90,0.2);border-left:3px solid #1A7F5A; }
.rp-gap-title { font-family:var(--font-ui);font-size:12px;font-weight:600;margin-bottom:3px; }
.rp-gap-card.missing .rp-gap-title { color:#C0392B; }
.rp-gap-card.partial .rp-gap-title { color:#A05E00; }
.rp-gap-card.covered .rp-gap-title { color:#1A7F5A; }
.rp-gap-desc { font-family:var(--font-ui);font-size:11px;color:#717783;line-height:1.5; }

/* Score panel layout helpers */
.rp-score-hero { display:flex;flex-direction:column;align-items:center;gap:4px;padding:16px 0 14px;border-bottom:1px solid rgba(193,199,211,0.3); }
.rp-dim-list { display:flex;flex-direction:column; }

/* SERP item layout */
.rp-serp-item { padding:10px 14px;border-bottom:1px solid rgba(193,199,211,0.2);display:flex;align-items:flex-start;gap:8px; }
.rp-serp-item .rp-serp-rank { margin-left:0;font-family:var(--font-ui);font-size:10px;font-weight:700;color:#9CA3AF;min-width:18px;padding-top:2px;flex-shrink:0; }
.rp-serp-body { flex:1;min-width:0; }
.rp-serp-url { font-family:var(--font-ui);font-size:10px;color:#5F6368;margin-bottom:2px; }
.rp-serp-desc { font-family:var(--font-ui);font-size:11.5px;color:#4D5156;line-height:1.45;margin-top:3px; }

/* ==================== FULL-SCREEN EDITOR (injected) ==================== */
/* ═══════════════════════════════════════════════════════════════
   FULL-SCREEN EDITOR VIEW
═══════════════════════════════════════════════════════════════ */
/* The editor is the article "drawer": it fills the screen EXCEPT the app
   sidebar, which stays visible and usable on the left (Attio record-page
   pattern). left tracks the sidebar's current mode; z-index sits below the
   sidebar's 200 so nav popovers (brand switcher, account menu) paint above. */
#editor-view{
  display:flex;
  position:fixed;top:0;right:0;bottom:0;left:220px;
  background:#F7F9FB;
  z-index:150; /* BELOW the step drawer (180): the article slides in BEHIND it */
  flex-direction:row;
  overflow:hidden;
  border-left:1px solid rgba(193,199,211,0.45);
  /* Drawer behavior: slides in from the right in 150ms (owner spec). Kept in
     the DOM (display:flex) so the transform can animate; parked off-screen
     and inert when closed. */
  transform:translateX(103%);
  transition:transform .15s ease, right .18s cubic-bezier(0.4,0,0.2,1), visibility 0s linear .15s;
  visibility:hidden;
  pointer-events:none;
}
body:not([data-nav-mode="labelled"]) #editor-view{ left:48px; }
@media (max-width:768px){ #editor-view{ left:0; z-index:350; } }
#editor-view.open{ transform:translateX(0); visibility:visible; pointer-events:auto; transition:transform .15s ease, visibility 0s; }

/* ── PANEL MODE — ONE drawer for everything (owner spec 2026-07-17) ─────────
   Clicking a step (Persona/SERP/Brief/…) on the dashboard opens THIS editor as
   a narrow right-hand panel: the article pane is hidden, the intel pane fills
   it, and the dashboard stays visible/usable behind. The tab strip stays, so
   SERP/Brief switch in place instead of spawning a second drawer. Clicking the
   article opens the same editor in full mode (article + tabs). The old
   #detail-panel is no longer used for step artifacts. */
/* !important is required on left/right: the nav rule above
   (body:not([data-nav-mode="labelled"]) #editor-view{left:48px}) has specificity
   (1,1,1) and beats a plain #editor-view.ev-panel-mode (1,1,0). Without this the
   panel keeps left:48px, and left+right+width together over-constrain the box so
   the browser drops `right` and docks the panel to the LEFT. */
#editor-view.ev-panel-mode{ left:auto !important; right:0 !important; width:600px; max-width:100vw; }
#editor-view.ev-panel-mode #ev-editor-pane{ display:none; }
#editor-view.ev-panel-mode #ev-intel-pane{ flex:1 1 100%; max-width:100%; }
/* Save has no article pane to save in panel mode */
#editor-view.ev-panel-mode #ev-topbar .ev-topbar-btn.primary{ display:none; }
@media (min-width:769px) and (max-width:1024px){ #editor-view.ev-panel-mode{ width:min(600px,70vw); } }
@media (max-width:768px){ #editor-view.ev-panel-mode{ left:0 !important; width:auto; } }

/* Editor open: prevent scroll bleed-through on body */
body.editor-open { overflow:hidden !important; }
/* …except in panel mode, where the dashboard behind stays scrollable */
body.editor-open.editor-panel-mode { overflow:auto !important; }
/* Step views hosted inside the editor tabs: neutralize the -20px bleed margin
   that compensates the small drawer's padding */
.ev-ipanel .pp-panel{ margin:0; }

/* ── Editor main column ── */
#ev-main{
  flex:1;display:flex;flex-direction:column;overflow:hidden;min-width:0;
}

/* ── Editor topbar ── */
#ev-topbar{
  height:52px;flex-shrink:0;
  background:#FFFFFF;
  border-bottom:1px solid rgba(193,199,211,0.4);
  display:flex;align-items:center;padding:0 20px;gap:12px;
}
/* Phones: the fixed 52px bar with nowrap children clipped Réviser/Publier
   offscreen (inside #ev-main{overflow:hidden}) — let the bar scroll sideways */
@media (max-width: 768px) {
  #ev-topbar{ overflow-x:auto; -webkit-overflow-scrolling:touch; padding:0 12px; gap:8px; scrollbar-width:none; }
  #ev-topbar::-webkit-scrollbar{ display:none; }
}
.ev-back-btn{
  display:flex;align-items:center;gap:6px;
  height:32px;border:1px solid var(--border);border-radius:6px;
  background:transparent;color:#505F76;padding:0 12px;
  font-family:var(--font-ui);font-size:13px;font-weight:500;
  cursor:pointer;transition:background 0.12s,color 0.12s;white-space:nowrap;flex-shrink:0;
}
.ev-back-btn:hover{background:#F2F4F6;color:#191C1E;}
.ev-title{
  font-family:var(--font-ui);font-size:15px;font-weight:600;color:#191C1E;
  flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;
}
.ev-badge{
  display:flex;align-items:center;gap:6px;flex-shrink:0;
}
.ev-status-dot{width:7px;height:7px;border-radius:50%;background:#1A7F5A;flex-shrink:0;}
.ev-status-lbl{font-family:var(--font-ui);font-size:12px;color:#1A7F5A;font-weight:600;}
.ev-score-chip{
  height:26px;padding:0 10px;border-radius:13px;
  background:rgba(26,127,90,0.12);color:#1A7F5A;
  font-family:var(--font-ui);font-size:12px;font-weight:600;
  display:flex;align-items:center;gap:4px;
}
.ev-topbar-btn{
  height:32px;border:1px solid var(--border);border-radius:6px;
  background:transparent;color:#505F76;padding:0 12px;
  font-family:var(--font-ui);font-size:12px;font-weight:500;
  cursor:pointer;transition:background 0.12s;white-space:nowrap;flex-shrink:0;
}
.ev-topbar-btn:hover{background:#F2F4F6;}
.ev-topbar-btn.primary{background:var(--blue);color:white;border-color:var(--blue);}
.ev-topbar-btn.primary:hover{background:var(--blue-hover);}

/* ── Two-column body ── */
#ev-body{
  flex:1;display:flex;overflow:hidden;min-height:0;
}

/* ── LEFT: Editor pane (65%) ── */
#ev-editor-pane{
  flex:0 0 65%;max-width:65%;
  display:flex;flex-direction:column;
  border-right:1px solid rgba(193,199,211,0.4);
  background:#FFFFFF;
  overflow:hidden;
}
/* Editor toolbar */
#ev-toolbar{
  display:flex;align-items:center;flex-wrap:wrap;gap:1px;
  padding:7px 10px;
  background:#FAFBFC;
  border-bottom:1px solid var(--border);
  flex-shrink:0;
}
/* Toolbar format-block select */
#ev-toolbar .tt-select{
  height:28px;border:1px solid var(--border);border-radius:5px;
  background:#FFFFFF;color:#505F76;
  font-family:var(--font-ui);font-size:12px;
  padding:0 6px;cursor:pointer;outline:none;flex-shrink:0;
}
#ev-toolbar .tt-select:hover{background:#F2F4F6;}
/* Toolbar button tooltips */
#ev-toolbar .tt-btn[data-tip]{position:relative;}
#ev-toolbar .tt-btn[data-tip]::after{
  content:attr(data-tip);
  position:absolute;
  bottom:calc(100% + 7px);left:50%;
  transform:translateX(-50%);
  background:#191C1E;color:#FFFFFF;
  font-family:var(--font-ui);font-size:11px;font-weight:500;
  padding:4px 8px;border-radius:5px;
  white-space:nowrap;pointer-events:none;
  opacity:0;transition:opacity 0.12s;
  z-index:200;
}
#ev-toolbar .tt-btn[data-tip]:hover::after{opacity:1;}
/* Editor content area */
#ev-content{
  flex:1;overflow-y:auto;
  padding:48px 64px;
  cursor:text;outline:none;
  min-height:0;
}
/* Audit fix: editor body was 15px — too small for sustained
   reading. Bumped to 17px with a tighter line-height (1.65 instead of 1.8
   because 1.8 at 17px is too loose) and capped measure at 72ch so long
   paragraphs don't run across an ultra-wide screen. */
#ev-content h1{font-family:var(--font-ui);font-size:32px;font-weight:700;color:#09090B;line-height:1.2;margin:0 0 18px;}
#ev-content h2{font-family:var(--font-ui);font-size:24px;font-weight:600;color:#09090B;line-height:1.3;margin:36px 0 14px;}
#ev-content h3{font-family:var(--font-ui);font-size:19px;font-weight:600;color:#191C1E;line-height:1.4;margin:28px 0 10px;}
#ev-content p{font-family:var(--font-ui);font-size:17px;line-height:1.65;color:#1F2937;margin:0 0 18px;max-width:72ch;}
#ev-content strong{font-weight:700;color:#191C1E;}
#ev-content em{font-style:italic;}
#ev-content a{color:var(--blue);text-decoration:underline;text-underline-offset:2px;}
#ev-content ul,#ev-content ol{font-family:var(--font-ui);font-size:17px;line-height:1.65;color:#1F2937;margin:0 0 18px;padding-left:26px;max-width:72ch;}
#ev-content li{margin-bottom:8px;}
#ev-content blockquote{
  border-left:3px solid var(--blue);
  margin:22px 0;padding:14px 22px;
  background:rgba(0,81,213,0.04);border-radius:0 8px 8px 0;
  color:#505F76;font-style:italic;font-size:17px;font-family:var(--font-ui);
  line-height:1.65;max-width:72ch;
}
#ev-content code{
  font-family:var(--font-ui);font-size:13px;
  background:#F2F4F6;border:1px solid var(--border);
  padding:2px 6px;border-radius:4px;color:#191C1E;
}
#ev-content pre{
  font-family:var(--font-ui);font-size:13px;
  background:#0F1117;color:#E5E7EB;
  padding:16px 20px;border-radius:10px;
  overflow-x:auto;margin:20px 0;line-height:1.65;
}
#ev-content table{width:100%;border-collapse:collapse;margin:20px 0;font-size:14px;}
#ev-content th{
  background:#F7F9FB;font-weight:600;color:#191C1E;
  padding:10px 16px;text-align:left;
  border:1px solid rgba(193,199,211,0.7);font-family:var(--font-ui);
}
#ev-content td{
  padding:9px 16px;border:1px solid rgba(193,199,211,0.5);
  color:#505F76;vertical-align:top;font-family:var(--font-ui);
}
#ev-content tr:hover td{background:rgba(0,81,213,0.02);}
#ev-content .kw-mark{background:rgba(0,81,213,0.1);border-radius:2px;padding:1px 3px;}
#ev-content img.ev-img{width:100%;border-radius:10px;margin:20px 0;display:block;}
.ev-img-placeholder{
  width:100%;background:#F7F9FB;border:2px dashed rgba(193,199,211,0.8);
  border-radius:10px;display:flex;align-items:center;justify-content:center;
  flex-direction:column;gap:8px;padding:32px;
  color:#9CA3AF;font-size:13px;cursor:pointer;margin:20px 0;
  transition:border-color 0.15s,background 0.15s;font-family:var(--font-ui);
}
.ev-img-placeholder:hover{border-color:var(--blue);background:rgba(0,81,213,0.03);}

/* Editor status bar */
#ev-statusbar{
  display:flex;align-items:center;gap:14px;padding:6px 16px;
  background:#FAFBFC;border-top:1px solid var(--border);flex-shrink:0;
  font-family:var(--font-ui);font-size:11px;color:#9CA3AF;
}
.ev-statusbar-spacer{flex:1;}
.ev-word-count{color:#9CA3AF;}

/* ── RIGHT: Intelligence pane (35%) ── — surface matched to the dashboard's
   .detail-panel drawer (white body, off-white #FAFBFC tab strip, 40px tabs)
   so the two "intel" side panels read as the same component. Existing white
   +bordered cards inside (score tiles, etc.) still define
   themselves via border, same as the drawer's own cards on its white body. */
#ev-intel-pane{
  flex:0 0 35%;max-width:35%;
  display:flex;flex-direction:column;
  background:#FFFFFF;
  overflow:hidden;
}
/* ── Agency editor on mobile (<=768px) ─────────────────────────────────────
   #ev-intel-pane is flex:0 0 35% with no mobile rules, so on a 390px phone it
   collapsed to ~136px. Measured at 390px: the pane was 136px but the buttons
   inside it rendered 74px wide starting at x=285 — i.e. overflowing their own
   column and painting over whatever sits beside them. Every control in the
   Reviser / Publier tabs was a cramped mis-tap target, and any fixed overlay
   (the cookie banner is position:fixed z-index:9999) covered them outright.

   Fix: stack the two panes on mobile so the intel pane is full width — 389px
   pane / 327px buttons at a 390px viewport. The client portal already does
   this via its own bottom sheet, so this is scoped to :not(.client-mode) to
   leave that sheet exactly as it is. Panel mode is unaffected — it hides the
   editor pane and already gives intel 100%. */
@media (max-width:768px){
  body:not(.client-mode) #ev-body{ flex-direction:column; }
  body:not(.client-mode) #ev-editor-pane{
    flex:1 1 auto;max-width:100%;min-height:0;
    border-right:none;border-bottom:1px solid rgba(193,199,211,0.4);
  }
  body:not(.client-mode) #ev-intel-pane{
    flex:1 1 auto;max-width:100%;width:100%;min-height:0;
  }
}
/* Intel tab bar */
/* Optimization diagnosis panel.
   The verdict is FIRST and it is a sentence. There is deliberately no dial and
   no score at the top of this panel: the score already lives in the Scores tab,
   and a number above the verdict is what turns this feature back into the
   commodity it was built to avoid. */
.opt-wrap{padding:14px;font-family:var(--font-ui);display:flex;flex-direction:column;gap:12px;}
.opt-verdict{border-radius:12px;padding:13px 14px;border:1px solid;}
.opt-verdict.is-refuse{background:#FFF7ED;border-color:#FED7AA;}
.opt-verdict.is-content{background:#F0F7FF;border-color:#BFDBFE;}
.opt-verdict.is-unknown{background:#F5F6F8;border-color:#E2E5EA;}
.opt-verdict-label{font-size:10.5px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:#7C8698;margin-bottom:5px;}
.opt-verdict-line{font-family:var(--font-ui);font-weight:600;font-size:15.5px;line-height:1.35;color:#22303F;}
.opt-why{font-size:12px;color:#5B6779;line-height:1.6;margin-top:7px;}
.opt-ev{display:flex;flex-wrap:wrap;gap:6px;margin-top:9px;}
.opt-chip{font-size:11px;background:#fff;border:1px solid #E2E5EA;border-radius:999px;padding:3px 9px;color:#505F76;}
.opt-actions{display:flex;flex-direction:column;gap:7px;}
.opt-btn{border:none;border-radius:9px;padding:10px 12px;font-family:var(--font-ui);font-size:12.5px;font-weight:600;cursor:pointer;text-align:left;}
.opt-btn-primary{background:#22303F;color:#fff;}
.opt-btn-primary:hover{background:#101A25;}
.opt-btn-ghost{background:transparent;color:#7C8698;border:1px solid #E2E5EA;font-weight:500;}
.opt-btn-ghost:hover{color:#22303F;border-color:#C1C7D3;}
.opt-btn[disabled]{opacity:.5;cursor:not-allowed;}
.opt-sub{font-size:11px;color:#9CA3AF;line-height:1.5;}
.opt-blind{background:#F5F6F8;border-radius:9px;padding:10px 11px;font-size:11.5px;color:#7C8698;line-height:1.6;}
.opt-blind b{color:#505F76;font-weight:600;}
.opt-steps{font-size:12px;color:#505F76;display:flex;flex-direction:column;gap:5px;}
.opt-step-done{color:#9CA3AF;}
.opt-proof{background:#F0FDF4;border:1px solid #BBF7D0;border-radius:10px;padding:11px 12px;}
.opt-proof.is-pending{background:#F5F6F8;border-color:#E2E5EA;}
.opt-delta{font-family:var(--font-ui);font-size:17px;font-weight:600;color:#15803D;}
.opt-delta.is-worse{color:#B91C1C;}
/* Opportunities panel in the analytics view */
.opp-row{display:flex;align-items:center;gap:10px;padding:9px 11px;border-bottom:1px solid #EEF0F3;font-family:var(--font-ui);}
.opp-row:last-child{border-bottom:none;}
.opp-url{flex:1;min-width:0;font-size:12px;color:#22303F;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.opp-num{font-size:11.5px;color:#7C8698;font-variant-numeric:tabular-nums;white-space:nowrap;}
#ev-intel-tabs{
  display:flex;height:40px;border-bottom:1px solid rgba(193,199,211,0.3);background:#FFFFFF;flex-shrink:0;
  overflow-x:auto;
}
#ev-intel-tabs::-webkit-scrollbar{height:0;}
.ev-itab{
  padding:0 11px;height:40px;
  border:none;background:transparent;
  font-family:var(--font-ui);font-size:12.5px;font-weight:500;color:#717783;
  cursor:pointer;white-space:nowrap;
  border-bottom:2px solid transparent;
  transition:color 0.15s,border-color 0.15s;flex-shrink:0;
  letter-spacing:-0.005em;
  display:inline-flex;align-items:center;gap:6px;
}
.ev-itab svg{width:13px;height:13px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0;opacity:0.75;}
.ev-itab:hover{color:#505F76;}
.ev-itab.active{color:#191C1E;border-bottom-color:#191C1E;font-weight:600;}
.ev-itab.active svg{opacity:1;}

/* ── Client comments (review portal) ────────────────────────────────────
   Highlights are painted with the CSS Custom Highlight API, NOT by wrapping
   nodes in <mark>: #ev-content is contenteditable, and mutating its DOM to
   show a highlight would put the marks into the saved article. */
/* Highlight is warm yellow, never blue: --brand-primary is reserved for active
   states and CTAs, and a blue wash would fight the body text and blur the
   "this sentence has a comment" signal. */
::highlight(client-comment){background:#FDF0C8;}
::highlight(client-comment-active){background:#F8DE8A;}

.ev-cmt-dot{
  width:6px;height:6px;border-radius:50%;background:#C0392B;
  display:inline-block;flex-shrink:0;
}
/* ── Article verdict strip ──────────────────────────────────────────────── */
.ev-status-strip{
  padding:11px 12px;border-bottom:1px solid var(--border);
  display:flex;flex-direction:column;gap:8px;
}
/* Validation checkbox. Green is the whole point — the agency reads this state
   from across the room, not by parsing a word. */
.ev-check{
  display:flex;align-items:center;gap:9px;cursor:pointer;
  font-family:var(--font-ui);font-size:13px;font-weight:600;
  color:var(--text-primary);
}
.ev-check input{
  width:17px;height:17px;flex-shrink:0;cursor:pointer;
  accent-color:var(--brand-primary);
}
.ev-check.on{color:#1A7F5A;}
.ev-check.on input{accent-color:#1A7F5A;}
/* Approved but the text moved underneath: amber, never green. A green tick on
   copy the client never read is worse than no tick. */
.ev-check.stale{color:#8A5B18;}
.ev-check.stale input{accent-color:#8A5B18;}
.ev-check.locked{cursor:default;}
.ev-check.locked input{cursor:default;}
.ev-status-strip.approved{background:#EDFAF4;border-bottom-color:rgba(26,127,90,.22);}
/* The agency strip's state line. Replaced .ev-st-note, which was a red text
   string shown for changes_requested and nothing else. */
.ev-st-state{margin-top:2px;}

/* ── The reviewer's decision block ────────────────────────────────────────
   Their whole job is one of two answers, so both are buttons at the top of
   the panel rather than a checkbox and a conditionally-hidden link. The state
   is named in words above them, because "is this done?" is the question they
   open the drawer to answer. */
.ev-decision{
  padding:14px 13px 13px;border-bottom:1px solid var(--border);
  background:var(--bg-surface);
}
.ev-dec-eyebrow{
  font-family:var(--font-ui);font-size:10.5px;font-weight:700;
  letter-spacing:.08em;text-transform:uppercase;color:var(--text-muted);
}
.ev-dec-state{
  font-family:var(--font-ui);font-size:15px;font-weight:700;
  color:var(--text-primary);margin-top:3px;letter-spacing:-.01em;
}
.ev-dec-note{
  font-family:var(--font-ui);font-size:11.5px;line-height:1.5;
  color:var(--text-secondary);margin-top:4px;
}
.ev-dec-actions{display:flex;flex-wrap:wrap;gap:7px;margin-top:11px;}
.ev-dec-btn{
  display:inline-flex;align-items:center;gap:6px;
  padding:8px 13px;border-radius:8px;cursor:pointer;
  border:1px solid var(--border);background:var(--bg-elevated);
  font-family:var(--font-ui);font-size:12.5px;font-weight:600;
  color:var(--text-primary);line-height:1;
}
.ev-dec-btn:hover{border-color:var(--text-muted);}
.ev-dec-btn svg{width:13px;height:13px;flex-shrink:0;}
/* Green belongs to the one irreversible-feeling action: "this is finished".
   Same green as the grid's Validé pill, so the two read as one statement. */
.ev-dec-btn.go{background:#1A7F5A;border-color:#1A7F5A;color:#fff;}
.ev-dec-btn.go:hover{background:#14684A;border-color:#14684A;}
.ev-dec-btn.ask:hover{border-color:#C0392B;color:#C0392B;}
/* State tints. Keyed off the SAME rs-* class the badge uses, not a private
   done/stale/ask vocabulary that had to be kept in sync by hand — "matching
   the grid's État column" was a comment, and comments do not hold. Now the
   drawer and the grid cannot disagree, because it is one class name. */
.ev-decision.rs-ok{background:#E7F7EF;border-bottom-color:rgba(20,107,74,.22);}
.ev-decision.rs-ok .ev-dec-state{color:#146B4A;}
.ev-decision.rs-stale{background:#FDF3E3;border-bottom-color:rgba(122,78,18,.22);}
.ev-decision.rs-stale .ev-dec-state{color:#7A4E12;}
.ev-decision.rs-wip{background:#E8F0FE;border-bottom-color:rgba(26,70,192,.2);}
.ev-decision.rs-wip .ev-dec-state{color:#1A46C0;}
.ev-decision.rs-back{background:#E4F3F7;border-bottom-color:rgba(11,94,112,.2);}
.ev-decision.rs-back .ev-dec-state{color:#0B5E70;}
/* rs-todo keeps the panel's default surface — "nothing has happened yet" is
   the one state that should not be tinted at all. */
.ev-dec-state .rs-sub{font-weight:600;font-size:13px;opacity:.72;}
/* "Comparer les versions", not "Voir les modifications": the banner over the
   article already owns that phrase for "what the agency just changed". Two
   controls with one label was the confusing part, not the controls. */
.ev-dec-versions{
  display:inline-flex;align-items:center;gap:6px;margin-top:10px;
  background:none;border:0;padding:0;cursor:pointer;
  font-family:var(--font-ui);font-size:11.5px;font-weight:600;
  color:var(--text-secondary);
}
.ev-dec-versions:hover{color:var(--brand-primary);}
/* "New since you last looked" — on the client's article row and on a comment. */
.cm-new-dot{
  display:inline-block;width:7px;height:7px;border-radius:50%;
  background:var(--brand-primary);flex-shrink:0;
}
/* The .cm-flag / .cm-row-flags chips lived on the old flat reviewer list.
   That list is now the .cm-row-grid grid, and its chips are .cm-chip-rev /
   .cm-chip-mod / .cm-chip-new next to the title. Rules deleted rather than
   left behind: dead CSS with a live-looking name is what makes the next grep
   for "revision chip" land in the wrong place. */

/* Revision banner above the client's article. Sits in the flow rather than
   over the text: this view is read-then-approve, and an overlay would cover
   the very passage they came to check. */
.cm-revision-banner{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  margin:0 0 14px;padding:10px 14px;
  background:#E7F5F7;border:1px solid #B7DFE5;border-radius:10px;
  font-family:var(--font-ui);font-size:12.5px;color:#0B4A55;
}
.cm-rb-dot{width:8px;height:8px;border-radius:50%;background:#0B7285;flex-shrink:0;}
.cm-rb-text{flex:1;min-width:0;}
.cm-rb-btn{
  flex-shrink:0;border:0;border-radius:999px;cursor:pointer;
  background:#0B7285;color:#fff;padding:6px 14px;
  font-family:var(--font-ui);font-size:12px;font-weight:600;
}
.cm-rb-btn:hover{background:#095E6E;}
.cm-rb-btn:disabled{opacity:.6;cursor:default;}
/* Diff rendering inside the article body — same colours as the agency's
   version comparison so "what changed" looks identical on both sides. */
.cm-diff-mode del{background:#FDE2E1;color:#8C2F1E;text-decoration:line-through;
  border-radius:3px;padding:0 2px;}
.cm-diff-mode ins{background:#D8F3E3;color:#1A6B45;text-decoration:none;
  border-radius:3px;padding:0 2px;}
.ev-cmt-card.unseen{border-left:3px solid var(--brand-primary);}

/* ── Review-state badge (.rs-*) ──────────────────────────────────────────
   The one badge for a client-review state, on every surface. It replaced
   .ev-st-badge (dead — its stCls was computed and never rendered), the
   .ev-st-<status> colour set and .row-st-badge, which between them gave the
   same state three sizes and two colour vocabularies.

   Sized for reading, not for fitting: 11.5px/600 with the qualifier at the
   same size rather than shrunk, because a reason nobody can read is worse
   than no reason. Colour carries WHOSE TURN it is, so the palette is grouped
   by that and not by good/bad — teal and grey both mean "the client", amber
   means "the client, and something is off", blue means "the writer". */
.rs-badge{
  display:inline-flex;align-items:center;gap:5px;flex-shrink:0;
  align-self:flex-start;border-radius:999px;padding:3px 10px;
  font-family:var(--font-ui);font-size:11.5px;font-weight:600;
  line-height:1.35;white-space:nowrap;max-width:100%;
}
.rs-badge > span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.rs-badge svg{width:11px;height:11px;flex-shrink:0;opacity:.85;}
/* The qualifier keeps the badge's size and loses only its weight — it is the
   part that explains the state, so it must stay legible. */
.rs-sub{font-weight:500;opacity:.82;}

/* Nothing remaining. */
.rs-ok{background:#E7F7EF;color:#146B4A;}
/* The client's turn, first read. */
.rs-todo{background:#EEF0F3;color:#4B5563;}
/* The writer's turn — the one state that owes the client nothing, so it must
   never read "À relire". */
.rs-wip{background:#E8F0FE;color:#1A46C0;}
/* Back with the client after a revision. Teal, matching the comment badge it
   answers, so a delivered revision reads as progress rather than as a fault. */
.rs-back{background:#E4F3F7;color:#0B5E70;}
/* Validated, but the text moved underneath. Amber not green — a green tick on
   copy the client never read is worse than no tick at all. */
.rs-stale{background:#FDF3E3;color:#7A4E12;}

.ev-st-actions{display:flex;flex-wrap:wrap;gap:6px;}
.ev-st-btn{
  border:1px solid var(--border);background:var(--bg-elevated);border-radius:7px;
  padding:5px 11px;cursor:pointer;
  font-family:var(--font-ui);font-size:11.5px;color:var(--text-primary);
}
.ev-st-btn:hover{border-color:var(--brand-border);color:var(--brand-primary);}
.ev-st-btn.primary{background:var(--brand-primary);border-color:var(--brand-primary);color:#fff;}
.ev-st-btn.primary:hover{background:var(--brand-hover);color:#fff;}

/* E1 — general (unanchored) comment box, always available. */
.ev-cmt-general{padding:11px 12px;border-bottom:1px solid var(--border);}
.ev-cmt-general textarea{margin-top:0;}

/* E2 — a reply, nested under its root. Depth is capped at 1 server-side. */
.ev-cmt-reply-item{
  margin:8px 0 0 12px;padding:8px 10px;
  border-left:2px solid var(--brand-border);background:var(--bg-surface);
  border-radius:0 7px 7px 0;
}
.ev-cmt-reply-item .ev-cmt-head{margin-bottom:3px;}
.ev-cmt-reply-item .ev-cmt-body{font-size:12px;}

/* The CLIENT cell. Two pills on one line, because they are two independent
   facts: what the client did, and what you did after. An article can be read
   AND edited since — that pairing is the case that used to be invisible, so the
   layout has to be able to show both at once rather than pick one. */
.al-client-cell {
  display: flex; align-items: center; gap: 6px;
  min-width: 0; padding: 8px 12px;
}
/* Pill 2. Amber and lighter than pill 1 on purpose: pill 1 is the state, this
   is a qualifier on it. Two pills of equal weight read as two competing badges
   and the eye has to decide which one is the answer.
   It shrinks before pill 1 does (flex-shrink) — if anything has to ellipsise it
   is the qualifier, never the state. */
.al-client-p2 {
  display: inline-flex; align-items: center; flex-shrink: 1; min-width: 0;
  border-radius: 999px; padding: 3px 9px;
  font-family: var(--font-ui); font-size: 11px; font-weight: 600;
  line-height: 1.35; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
  background: #FDF3E3; color: #7A4E12;
}
/* Pill 1 holds its width; the qualifier gives first. */
.al-client-cell .rs-badge { flex-shrink: 0; }

/* Row badge on the agency dashboard: .rs-badge, tightened for the 44px row.
   It used to be .row-st-badge at 10.5px with its own colours — the same state
   two sizes smaller than in the drawer, which is how it stopped reading as the
   same thing. Only the padding differs now; the size and palette are shared. */
.al-kw-sub .rs-badge{padding:2px 8px;}
/* Open client comments on a dashboard row. The count is the whole point: a
   verdict says something happened, a number says how much work is waiting. */
.al-cmt-badge{
  display:inline-flex;align-items:center;gap:3px;flex-shrink:0;
  border-radius:999px;padding:2px 7px;
  background:#0B7285;color:#FFFFFF;
  font-family:var(--font-ui);font-size:10.5px;font-weight:700;
  line-height:1.2;font-variant-numeric:tabular-nums;
}
.al-cmt-badge svg{opacity:.9;}
/* A client is waiting on a paid revision the owner has to approve. Amber, not
   the comment badge's teal: a comment is information, this is a queue item
   with someone on the other end of it. Uses the warning tokens like every
   other "you need to act" surface (DESIGN_SYSTEM.md). */
.al-chip-waiting{
  background:var(--warning-bg,#FFFBEB);
  color:var(--warning,#A05E00);
  border:1px solid var(--warning-border,rgba(160,94,0,.28));
}
/* Same signal, one level up: how many, without reading the list. Hidden at
   zero by renderWaitingBanner — an always-on "0 waiting" is furniture. */
/* Inset 20px to sit on the same left edge as the status strip above it and the
   article pane below it — the banner is a sibling of both, outside the pane's
   own padding, so it has to repeat the gutter itself. 12px of air under the
   strip's border: flush against a 1px rule reads as part of the chrome rather
   than as a message. */
.al-waiting-banner{
  display:flex;align-items:center;gap:8px;cursor:pointer;
  margin:12px 20px 10px;padding:8px 12px;border-radius:9px;
  background:var(--warning-bg,#FFFBEB);
  border:1px solid var(--warning-border,rgba(160,94,0,.28));
  color:var(--warning,#A05E00);
  font-family:var(--font-ui);font-size:12px;line-height:1.35;
  transition:background .12s;
}
.al-waiting-banner:hover{background:rgba(160,94,0,.10);}
.al-waiting-banner svg{flex-shrink:0;}
/* The brand/language text yields first so the chips never wrap onto a third
   line — the row is 44px and a third line overlaps the next row's title. */
.al-kw-sub-text{
  min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}

/* Drawer header — "Commentaires · N". The count was previously only a red dot
   on the tab, which said "something happened" without saying how much. */
.ev-cmt-drawer-head{
  display:flex;align-items:center;gap:8px;
  padding:12px 12px 10px;border-bottom:1px solid var(--border);
}
.ev-cmt-drawer-head h5{
  font-family:var(--font-ui);font-weight:600;
  font-size:13.5px;color:var(--text-primary);margin:0;
}
.ev-cmt-drawer-count{
  background:var(--brand-primary);color:#fff;border-radius:999px;
  padding:1px 8px;font-family:var(--font-ui);font-size:10.5px;font-weight:600;
}
.ev-cmt-card{
  border:1px solid var(--border);border-radius:10px;padding:11px 12px;margin-bottom:9px;
  background:var(--bg-elevated);cursor:pointer;
  transition:border-color .15s,box-shadow .15s;
}
.ev-cmt-card:hover{border-color:var(--brand-border);}
/* Active card is tied to its highlight with the BRAND colour, so the drawer and
   the sentence in the article read as one selection. */
.ev-cmt-card.active{
  border-color:var(--brand-primary);
  box-shadow:0 0 0 2px var(--brand-glow);
}
.ev-cmt-card.resolved{opacity:.5;}
.ev-cmt-head{
  display:flex;align-items:center;gap:6px;margin-bottom:6px;
  font-family:var(--font-ui);font-size:11.5px;color:#717783;
}
.ev-cmt-head strong{color:var(--text-primary);font-weight:600;}
.ev-cmt-role{
  background:#EEF1F6;color:#505F76;border-radius:999px;padding:1px 6px;
  font-size:10.5px;font-weight:600;
}
.ev-cmt-quote{
  /* Border matches the in-article highlight so the card visibly belongs to
     that sentence — this is what makes the drawer layout legible. */
  margin:0 0 6px;padding:5px 8px;border-left:3px solid #F8DE8A;background:#FEFAEF;
  font-family:var(--font-ui);font-size:11.5px;color:var(--text2);
  border-radius:0 5px 5px 0;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.ev-cmt-body{
  font-family:var(--font-ui);font-size:12.5px;color:var(--text-primary);line-height:1.55;
  white-space:pre-wrap;word-wrap:break-word;
}
.ev-cmt-tags{margin-top:6px;display:flex;flex-wrap:wrap;gap:5px;}
.ev-cmt-tag{
  font-family:var(--font-ui);font-size:10.5px;border-radius:999px;
  padding:2px 7px;background:#F0F1F3;color:#717783;
}
.ev-cmt-tag.warn{background:#FDF3E3;color:#8A5B18;}
.ev-cmt-acts{margin-top:7px;display:flex;gap:9px;}
.ev-cmt-acts button{
  background:none;border:0;padding:0;cursor:pointer;
  font-family:var(--font-ui);font-size:11.5px;color:#717783;text-decoration:underline;
}
.ev-cmt-acts button:hover{color:var(--brand-primary);}
/* .ev-cmt-reply is the box created when replying to a comment.
   .ev-cmt-input is the composer. Same look, DIFFERENT class on purpose: one
   class serving two roles made every selector ambiguous. */
.ev-cmt-reply, .ev-cmt-input{
  width:100%;min-height:58px;resize:vertical;padding:8px 10px;margin-top:4px;
  border:1px solid var(--border);border-radius:8px;
  font-family:var(--font-ui);font-size:12.5px;color:#242A32;
}
.ev-cmt-reply:focus, .ev-cmt-input:focus{outline:2px solid var(--brand-glow);border-color:var(--brand-primary);}
.ev-cmt-empty{
  padding:26px 14px;text-align:center;
  font-family:var(--font-ui);font-size:12px;color:#9CA3AF;line-height:1.6;
}

/* ── Modern comment card meta ──────────────────────────────────────────── */
.ev-cmt-head{display:flex;align-items:center;gap:8px;margin-bottom:7px;}
.ev-cmt-meta{display:flex;align-items:center;gap:6px;flex-wrap:wrap;min-width:0;}
.ev-cmt-author{font-family:var(--font-ui);font-size:12.5px;font-weight:600;color:#191C1E;}
.ev-cmt-time{font-family:var(--font-ui);font-size:11px;color:#9CA3AF;}

/* "Voir les modifications" button in the status strip. */
.ev-ver-btn{
  display:inline-flex;align-items:center;gap:6px;margin-top:2px;
  background:none;border:1px solid var(--border);border-radius:8px;
  padding:5px 11px;cursor:pointer;color:var(--text2);
  font-family:var(--font-ui);font-size:11.5px;font-weight:500;
}
.ev-ver-btn:hover{border-color:var(--brand-border);color:var(--brand-primary);}

/* Diff overlay — read-only before/after. */
#ev-diff-overlay{
  display:none;position:fixed;inset:0;z-index:1300;
  background:rgba(25,28,30,.42);align-items:center;justify-content:center;padding:24px;
}
#ev-diff-overlay.open{display:flex;}
.ev-diff-box{
  width:100%;max-width:720px;max-height:84vh;display:flex;flex-direction:column;
  background:#fff;border:1px solid var(--border);border-radius:16px;overflow:hidden;
}
.ev-diff-top{
  display:flex;align-items:center;justify-content:space-between;
  padding:16px 20px;border-bottom:1px solid var(--border-subtle);
}
.ev-diff-top strong{font-family:var(--font-display);font-size:16px;}
.ev-diff-sub{font-family:var(--font-ui);font-size:12px;color:var(--text-muted);margin-left:8px;}
.ev-diff-x{background:#F2F4F6;border:1px solid var(--border);border-radius:50%;
  width:28px;height:28px;cursor:pointer;color:var(--text2);font-size:17px;line-height:1;}
.ev-diff-picker{display:flex;gap:6px;flex-wrap:wrap;padding:12px 20px 0;}
.ev-diff-chip{
  background:var(--bg-surface);border:1px solid var(--border);border-radius:999px;
  padding:4px 11px;cursor:pointer;font-family:var(--font-ui);font-size:11.5px;color:var(--text2);
}
.ev-diff-chip.active{background:var(--brand-primary);border-color:var(--brand-primary);color:#fff;}
.ev-diff-legend{display:flex;gap:14px;padding:12px 20px 0;
  font-family:var(--font-ui);font-size:11.5px;color:var(--text-muted);}
.lg-del::before{content:'';display:inline-block;width:10px;height:10px;border-radius:2px;
  background:#FDE2E1;margin-right:5px;vertical-align:middle;}
.lg-ins::before{content:'';display:inline-block;width:10px;height:10px;border-radius:2px;
  background:#D8F3E3;margin-right:5px;vertical-align:middle;}
.ev-diff-body{
  flex:1;min-height:0;overflow-y:auto;padding:18px 20px 24px;
  font-family:var(--font-ui);font-size:15px;line-height:1.85;color:#242A32;
}
.ev-diff-body del{background:#FDE2E1;color:#8C2F1E;text-decoration:line-through;
  border-radius:3px;padding:0 2px;}
.ev-diff-body ins{background:#D8F3E3;color:#1A6B45;text-decoration:none;
  border-radius:3px;padding:0 2px;}

/* ── Notifications + avatars (shared) ──────────────────────────────────── */
.notif-count{
  position:absolute;top:-3px;right:-3px;min-width:16px;height:16px;padding:0 4px;
  border-radius:999px;background:#C0392B;color:#fff;
  font-family:var(--font-ui);font-size:10px;font-weight:700;line-height:16px;
  display:flex;align-items:center;justify-content:center;box-shadow:0 0 0 2px var(--bg-base);
}
#header-notif-dot{
  /* Reuse the count style for the agency dot too. */
  position:absolute;top:-2px;right:-2px;min-width:15px;height:15px;padding:0 3px;
  border-radius:999px;background:#C0392B;color:#fff;font-size:9px;font-weight:700;
  align-items:center;justify-content:center;box-shadow:0 0 0 2px var(--bg-base);
}
.notif-head{
  display:flex;align-items:center;justify-content:space-between;
  padding:11px 14px;border-bottom:1px solid var(--border-subtle);
  font-family:var(--font-display);font-size:13.5px;font-weight:700;color:var(--text-primary);
}
.notif-readall{
  background:none;border:0;cursor:pointer;font-family:var(--font-ui);
  font-size:11.5px;color:var(--brand-primary);text-decoration:underline;padding:0;
}
.notif-empty{padding:26px 14px;text-align:center;font-family:var(--font-ui);
  font-size:12.5px;color:var(--text-muted);}
.notif-list{max-height:380px;overflow-y:auto;}
.notif-row{
  width:100%;display:flex;align-items:flex-start;gap:10px;padding:11px 14px;
  background:none;border:0;border-bottom:1px solid var(--border-subtle);
  cursor:pointer;text-align:left;
}
.notif-row:hover{background:var(--bg-subtle);}
.notif-row.unread{background:var(--brand-dim);}
.notif-row.unread:hover{background:var(--brand-dim);filter:brightness(.98);}
.notif-ic{
  flex-shrink:0;width:26px;height:26px;border-radius:50%;display:flex;
  align-items:center;justify-content:center;font-size:12px;
  background:var(--bg-subtle);color:var(--text2);
}
.notif-ic.k-approved{background:#EDFAF4;color:#1A7F5A;}
.notif-ic.k-changes_requested{background:#FDEEEC;color:#C0392B;}
.notif-ic.k-edited{background:#FDF3E3;color:#8A5B18;}
.notif-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px;}
.notif-title{font-family:var(--font-ui);font-size:12.5px;color:var(--text-primary);line-height:1.4;}
.notif-time{font-family:var(--font-ui);font-size:11px;color:var(--text-muted);}
/* Client bell in the review header */
.cm-notif-wrap{position:relative;margin-left:auto;}
.cm-notif-btn{
  position:relative;width:38px;height:38px;border-radius:10px;
  border:1px solid var(--border);background:var(--bg-elevated);cursor:pointer;
  color:var(--text2);display:flex;align-items:center;justify-content:center;
}
.cm-notif-btn:hover{border-color:var(--brand-border);color:var(--brand-primary);}
.notif-pop{
  display:none;position:absolute;top:46px;right:0;width:340px;max-width:90vw;z-index:500;
  background:var(--bg-elevated);border:1px solid var(--border);border-radius:12px;
  box-shadow:0 10px 40px rgba(30,47,77,.16);overflow:hidden;
}
.notif-pop.open{display:block;}
/* Avatar chip for comment authors + notifications */
.av-chip{
  flex-shrink:0;width:28px;height:28px;border-radius:50%;color:#fff;
  display:inline-flex;align-items:center;justify-content:center;
  font-family:var(--font-ui);font-size:11px;font-weight:700;
}
.av-chip.sm{width:22px;height:22px;font-size:9.5px;}

/* ── E4: client review panel on mobile (<=768px) ───────────────────────────
   Scoped to body.client-mode ON PURPOSE. #ev-intel-pane is flex:0 0 35% with
   no mobile rules at all, so on a phone it collapses to ~136px — broken for
   the agency too, but fixing the shared editor for mobile is a separate and
   much larger piece of work, deliberately not attempted here.

   768px matches the editor's existing breakpoints; 900 would have landed
   inside the 769-1024 rule and fought .ev-panel-mode. */
@media (max-width:768px){
  body.client-mode #ev-body{flex-direction:column;}
  body.client-mode #ev-editor-pane{flex:1 1 auto;min-height:0;}
  body.client-mode #ev-intel-pane{
    position:fixed;left:0;right:0;bottom:0;top:auto;z-index:400;
    flex:none;max-width:100%;width:100%;height:70vh;
    border-top:1px solid var(--border);border-radius:14px 14px 0 0;
    background:var(--bg-elevated);box-shadow:0 -8px 30px rgba(30,47,77,.18);
    transform:translateY(100%);transition:transform .18s ease;
  }
  body.client-mode.cm-sheet-open #ev-intel-pane{transform:translateY(0);}
  body.client-mode #ev-intel-tabs{display:none;}
  body.client-mode #cm-sheet-btn{
    display:flex;align-items:center;gap:7px;
    position:fixed;right:16px;bottom:16px;z-index:401;
    background:var(--brand-primary);color:#fff;border:0;border-radius:999px;
    padding:11px 17px;box-shadow:0 4px 20px rgba(0,81,213,.32);
    font-family:var(--font-ui);font-size:13px;font-weight:600;cursor:pointer;
  }
  body.client-mode.cm-sheet-open #cm-sheet-btn{background:var(--bg-inverse);}
}
#cm-sheet-btn{display:none;}


/* ── Client mode ─────────────────────────────────────────────────────────
   Same shell, fewer affordances. Only styles the client-specific list; the
   editor overlay is reused verbatim so it looks identical to the agency's. */
/* Header sits above the scroll area. The client view has no agency topbar, so
   it supplies its own top padding — without it the title was flush against the
   window edge. */
.cm-head{
  flex-shrink:0;display:flex;align-items:baseline;gap:10px;
  padding:26px 28px 16px;border-bottom:1px solid var(--border-subtle);
  background:var(--bg-base);
}
.cm-head h1{
  font-family:var(--font-display);font-size:22px;font-weight:700;
  color:var(--text-primary);margin:0;letter-spacing:-0.015em;
}
.cm-head-sub{font-family:var(--font-ui);font-size:13px;color:var(--text-muted);}
/* .view is overflow:hidden, so the list needs its own scroller or it simply
   cannot be scrolled past the fold. */
.cm-scroll{flex:1;min-height:0;overflow-y:auto;padding:18px 28px 40px;}

/* ── Reviewer grid ───────────────────────────────────────────────────────
   Same .al-row / .al-row-header machinery as the agency dashboard, retuned
   to five columns. The agency template hard-codes eleven columns and a
   1180px min-width; overriding BOTH is what lets the same row chrome fit a
   1440px reviewer window with no horizontal scroll. Scoped to .cm-row-grid
   so nothing here can reach the agency grid. */
.cm-row-grid{
  grid-template-columns:minmax(240px,1fr) 130px 130px 200px 104px !important;
  min-width:0 !important;
}
/* Capped, not full-bleed. Five columns stretched across a 1400px window put
   a desert between the article title and its status cells — the eye has to
   travel the whole row to answer "is this one done?". */
.cm-grid-wrap,.cm-kpi{max-width:1060px;}
/* 8px, not a rounder number of my own: the agency KPI strip and table are 8px,
   and the point of this whole screen is that the two dashboards are the same
   object seen from two sides. A 2px difference is exactly the kind of thing
   that reads as "generated" rather than designed. */
.cm-grid-wrap{
  border:1px solid var(--border-subtle);border-radius:8px;
  background:var(--bg-elevated);overflow:hidden;
}
.cm-kpi{
  border:1px solid var(--border-subtle);border-radius:8px;
  background:var(--bg-elevated);overflow:hidden;margin-bottom:12px;
}
/* The header is sticky against .cm-scroll, not the agency's list pane. */
.cm-grid-wrap .al-row-header{border-radius:8px 8px 0 0 !important;}
.cm-grid-rows .al-row:last-child{border-bottom:0 !important;}
.cm-grid-rows .al-row{cursor:pointer !important;}
.cm-grid-rows .al-group:first-child{margin-top:0;}
.cm-chev{transition:transform .15s;}
.cm-chev.collapsed{transform:rotate(-90deg);}

/* Chips on the title sub-line. Each states WHY the row wants attention.
   .cm-chip-rev is gone with the "Révision · à relire" chip it coloured: that
   is a review STATE now (rs-back, teal, in the État column), and a row showing
   both said it twice. .al-status-pill.pill-warn went the same way — the stale
   tick is rs-stale. */
.cm-chip-mod{background:#FDF3E3 !important;color:#8A5B18 !important;}
.cm-chip-new{background:var(--brand-dim) !important;color:var(--brand-accent) !important;}

/* In the reviewer's grid green means exactly one thing: "you validated this".
   The agency's step checks are green too, so a row showed a green Persona
   check beside a green "Validé" pill and the two read as the same statement —
   the reviewer could take "the agency built a persona" as "I approved this".
   Neutral blue here; the État column keeps green to itself. */
body.client-mode .cm-row-grid .al-step-cell.done .al-step-check{
  background:var(--brand-dim,#DBE1FF) !important;
  color:var(--brand-accent,#003EA8) !important;
}
body.client-mode .cm-row-grid .al-step-cell.done:hover{
  background:var(--brand-dim,#DBE1FF) !important;
  color:var(--brand-accent,#003EA8) !important;
}
body.client-mode .cm-row-grid .al-step-cell.done:hover::after{
  color:var(--brand-accent,#003EA8);
}

/* ── Reviewer's Persona / SERP panel ────────────────────────────
   There is no bespoke viewer any more: this is #editor-view in .ev-panel-mode,
   the same 600px right-hand drawer a step cell opens for the agency. All that
   is left to say is what the reviewer's shell must NOT show inside it.

   The tab strip goes: openClientEditor leaves only the "Client" tab visible,
   which in a Persona panel is a stray control pointing at the article's
   comments. The panel's own pp-hero already carries the title and the close. */
body.cm-ctx-mode #ev-intel-tabs{display:none !important;}
body.cm-ctx-mode #ev-topbar{display:none !important;}
body.cm-ctx-mode #client-edit-bar{display:none !important;}
body.cm-ctx-mode #cm-sheet-btn{display:none !important;}
/* The <=768px client rule turns #ev-intel-pane into a bottom sheet that only
   opens via #cm-sheet-btn. In panel mode the pane IS the drawer, so that sheet
   behaviour would park the whole panel off-screen with no way back. */
@media (max-width:768px){
  body.cm-ctx-mode #ev-intel-pane{
    position:static;height:auto;transform:none;
    border-top:0;border-radius:0;box-shadow:none;flex:1 1 auto;min-height:0;
  }
}

/* Phones: the five-column grid cannot survive 390px, so the row stacks —
   title on its own line, the four cells sharing the second. Same shape the
   agency grid uses at this width. */
@media (max-width:768px){
  .cm-scroll{padding:14px 14px 32px;}
  .cm-kpi{display:grid;grid-template-columns:1fr 1fr;}
  .cm-grid-wrap .al-row-header{display:none !important;}
  .cm-row-grid{
    display:flex !important;flex-wrap:wrap;align-items:center;gap:6px;
    height:auto !important;padding:10px 12px !important;
    grid-template-rows:none !important;
  }
  .cm-row-grid .al-title-col{flex:1 1 100%;min-width:0;padding:0 !important;
    border-right:0 !important;}
  .cm-row-grid .al-step-cell,
  .cm-row-grid .al-cell-seo{
    flex:0 0 auto;padding:0 !important;height:auto !important;
    justify-content:flex-start;border:0 !important;
  }
  /* The header row is hidden here, so a bare "✓ ✓" says nothing about WHAT
     was done. Each proof cell carries its own label once the column heading
     is gone. */
  .cm-row-grid .al-step-cell[data-step="persona"]::before,
  .cm-row-grid .al-step-cell[data-step="serp"]::before{
    content:attr(data-step);
    margin-right:4px;font-family:var(--font-ui);font-size:10.5px;
    font-weight:600;text-transform:uppercase;letter-spacing:.03em;
    color:var(--text-muted);
  }
}

/* Import batches are grouped by .al-group / .al-row-grouped — the agency's
   own group chrome — so the two dashboards band an import identically. The
   bespoke .cm-group / .cm-row / .cm-count rules that used to live here were
   the old flat list and are gone with it. */
.cm-empty{
  margin-top:16px;padding:44px 20px;text-align:center;background:#fff;
  border:1px solid #E4E7EC;border-radius:12px;
  font-family:var(--font-ui);font-size:13px;color:#9CA3AF;line-height:1.7;
}
/* The floating "Commenter" bubble that follows a text selection. */
#cm-bubble{
  position:absolute;z-index:2000;display:none;
  background:#191C1E;color:#fff;border-radius:8px;padding:6px 12px;
  font-family:var(--font-ui);font-size:12.5px;font-weight:500;cursor:pointer;
  box-shadow:0 6px 20px rgba(0,0,0,.22);white-space:nowrap;
}
#cm-bubble:hover{background:#000;}

/* Intel panels */
.ev-ipanel{display:none;flex:1;overflow:hidden;}
.ev-ipanel.active{display:flex;flex-direction:column;}

/* Section labels inside panels */
.ip-label{
  font-family:var(--font-ui);font-size:10px;font-weight:700;
  color:#9CA3AF;letter-spacing:0.08em;text-transform:uppercase;
  margin:0 0 8px;
}
.ip-card{
  background:#FFFFFF;border:1px solid var(--border);border-radius:10px;
  padding:12px 14px;margin-bottom:10px;
}
.ip-card-title{
  font-family:var(--font-ui);font-size:13px;font-weight:600;color:#191C1E;
  margin-bottom:4px;
}
.ip-card-sub{
  font-family:var(--font-ui);font-size:12px;color:#717783;line-height:1.5;
}

/* ── SERP result card (scoped to editor to avoid overriding production) ── */
#editor-view .serp-card{
  background:#FFFFFF;border:1px solid var(--border);border-radius:10px;
  padding:12px 14px;margin-bottom:8px;
  display:flex;gap:10px;
}
#editor-view .serp-rank{
  font-family:var(--font-ui);font-size:18px;font-weight:700;
  color:#DBE1FF;line-height:1;width:24px;flex-shrink:0;text-align:center;
  margin-top:2px;
}
#editor-view .serp-rank.our{color:var(--blue);}
#editor-view .serp-body{flex:1;min-width:0;}
#editor-view .serp-title{font-family:var(--font-ui);font-size:13px;font-weight:600;color:#191C1E;margin-bottom:2px;line-height:1.35;}
#editor-view .serp-url{font-family:var(--font-ui);font-size:10px;color:#9CA3AF;margin-bottom:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
#editor-view .serp-snippet{font-family:var(--font-ui);font-size:12px;color:#717783;line-height:1.5;}
#editor-view .serp-metrics{display:flex;gap:8px;margin-top:6px;flex-wrap:wrap;}
#editor-view .serp-metric{
  font-family:var(--font-ui);font-size:10px;color:#717783;
  background:#F7F9FB;border:1px solid var(--border);border-radius:4px;
  padding:2px 6px;
}
#editor-view .serp-gap-badge{
  display:inline-block;font-family:var(--font-ui);font-size:10px;font-weight:600;
  padding:2px 7px;border-radius:10px;margin-top:4px;
}
#editor-view .serp-gap-badge.miss{background:#FDEEEC;color:#C0392B;}
#editor-view .serp-gap-badge.hit{background:#EDFAF4;color:#1A7F5A;}

/* ── Keyword frequency table (scoped to editor) ── */
#editor-view .kw-freq-table{width:100%;border-collapse:collapse;margin-top:4px;}
#editor-view .kw-freq-table tr+tr td{border-top:1px solid var(--border);}
#editor-view .kw-freq-table td{padding:6px 0;font-family:var(--font-ui);font-size:12px;}
#editor-view .kw-freq-table .kw-name{color:#191C1E;font-weight:500;}
#editor-view .kw-freq-table .kw-bar-wrap{padding:0 8px;}
#editor-view .kw-freq-bar{height:4px;border-radius:2px;background:var(--blue);opacity:0.6;}
#editor-view .kw-freq-table .kw-count{color:#717783;font-family:var(--font-ui);font-size:11px;text-align:right;}

/* ── Facts panel (scoped to editor) ── */
#editor-view .fact-card{
  background:#FFFFFF;border:1px solid var(--border);border-radius:10px;
  padding:11px 14px;margin-bottom:8px;
  display:flex;gap:10px;align-items:flex-start;
}
#editor-view .fact-num{
  font-family:var(--font-ui);font-size:11px;font-weight:600;
  color:#FFFFFF;background:var(--blue);border-radius:4px;
  padding:2px 6px;flex-shrink:0;margin-top:1px;
}
#editor-view .fact-body{flex:1;min-width:0;}
#editor-view .fact-text{font-family:var(--font-ui);font-size:12px;color:#191C1E;line-height:1.55;margin-bottom:4px;}
#editor-view .fact-source{font-family:var(--font-ui);font-size:10px;color:#9CA3AF;}
#editor-view .fact-used{
  display:inline-block;font-family:var(--font-ui);font-size:10px;font-weight:600;
  padding:2px 7px;border-radius:10px;margin-top:4px;
  background:#EDFAF4;color:#1A7F5A;
}
#editor-view .fact-unused{background:#F7F9FB;color:#9CA3AF;}

/* ── SEO Conformity panel (scoped to editor) ── */
#editor-view .seo-ring-row{
  display:flex;align-items:center;gap:16px;
  background:#FFFFFF;border:1px solid var(--border);border-radius:10px;
  padding:14px;margin-bottom:12px;
}
#editor-view .seo-conf-bar-row{
  display:flex;align-items:center;gap:8px;margin-bottom:8px;
}
#editor-view .seo-conf-label{font-family:var(--font-ui);font-size:12px;color:#505F76;width:140px;flex-shrink:0;}
#editor-view .seo-conf-track{flex:1;height:5px;background:#F2F4F6;border-radius:3px;overflow:hidden;}
#editor-view .seo-conf-fill{height:100%;border-radius:3px;}
#editor-view .seo-conf-fill.great{background:#1A7F5A;}
#editor-view .seo-conf-fill.good{background:var(--blue);}
#editor-view .seo-conf-fill.warn{background:#A05E00;}
#editor-view .seo-conf-fill.bad{background:#C0392B;}
#editor-view .seo-conf-val{font-family:var(--font-ui);font-size:11px;font-weight:600;width:26px;text-align:right;flex-shrink:0;}
#editor-view .seo-conf-check{width:16px;text-align:center;font-size:12px;flex-shrink:0;}

/* ── SERP gap table (scoped to editor) ── */
#editor-view .gap-table{width:100%;border-collapse:collapse;}
#editor-view .gap-table th{
  font-family:var(--font-ui);font-size:10px;font-weight:700;color:#9CA3AF;
  text-transform:uppercase;letter-spacing:0.06em;
  padding:6px 10px;border-bottom:1px solid var(--border);text-align:left;
}
#editor-view .gap-table td{
  font-family:var(--font-ui);font-size:12px;padding:7px 10px;
  border-bottom:1px solid rgba(193,199,211,0.3);color:#505F76;vertical-align:top;
}
#editor-view .gap-table td.topic{color:#191C1E;font-weight:500;}
#editor-view .gap-badge{
  display:inline-block;font-size:10px;font-weight:600;font-family:var(--font-ui);
  padding:2px 7px;border-radius:10px;
}
#editor-view .gap-badge.covered{background:#EDFAF4;color:#1A7F5A;}
#editor-view .gap-badge.missing{background:#FDEEEC;color:#C0392B;}
#editor-view .gap-badge.partial{background:#FDF5E6;color:#A05E00;}

/* ── Revision / audit panel (scoped to editor) ── */
.ev-audit-item{
  display:flex;gap:10px;align-items:flex-start;
  background:#FFFFFF;border:1px solid var(--border);border-radius:10px;
  padding:11px 14px;margin-bottom:8px;
}
.ev-audit-icon{font-size:14px;flex-shrink:0;margin-top:1px;}
.ev-audit-body{flex:1;min-width:0;}
.ev-audit-title{font-family:var(--font-ui);font-size:12px;font-weight:600;color:#191C1E;margin-bottom:2px;}
.ev-audit-desc{font-family:var(--font-ui);font-size:12px;color:#717783;line-height:1.5;}
.ev-audit-fix{
  display:inline-block;margin-top:6px;
  font-family:var(--font-ui);font-size:11px;font-weight:600;
  color:var(--blue);cursor:pointer;border-bottom:1px solid transparent;
  transition:border-color 0.12s;
}
.ev-audit-fix:hover{border-bottom-color:var(--blue);}
