/* ════════════════════════════════════════════════════════════════════
   REPORTING — CSS extracted from index.html (Phase 1.I)
   ────────────────────────────────────────────────────────────────────
   Scoped under .rep-tool so Reporting's typography, layout and chart
   styles don't leak out to other views. ~80 KB / 2530 lines. Loaded
   from <head> of index.html. Pair file : public/tools/reporting.js.

   Small Reporting-related styles still inline in index.html for now :
     - .reporting-landing-* (landing card grid)
     - body.is-share-mode-reporting (client-share mode overrides)
     - .view-reporting #reporting-root (layout shim)
   These are < 50 lines combined ; will fold into this file when
   index.html itself is split into modules.
   ════════════════════════════════════════════════════════════════════ */

  /* Headlines use StackSans italic for that nerdstack feel.
     We don't have the actual variable font here, so we fall back
     to system serif italic — the visual rhythm stays consistent. */
  .rep-tool h1, .rep-tool h2, .rep-tool h3, .rep-tool h4 {
    font-family: 'Roboto', 'Inter', system-ui, sans-serif;
    font-weight: 400;
    letter-spacing: -0.015em;
    margin: 0;
  }
  .rep-tool h1 em, .rep-tool h2 em, .rep-tool h3 em { font-style: italic; color: var(--p-test); }

  /* "Eyebrow" label — a small uppercase mono caption above titles.
     Used a lot in the original tool for "Phase 1 · Setup" patterns. */
  .rep-tool .ey {
    font-family: 'JetBrains Mono', 'Courier New', monospace;
    font-size: 0.55rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
  }

  .rep-tool button {
    font-family: inherit;
    cursor: pointer;
  }

  /* ═══════════ APP SHELL ═══════════ */
  .rep-tool #app {
    display: grid;
    grid-template-rows: auto 1fr;
    height: 100vh;
    overflow: hidden;
  }

  .rep-tool .topbar {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.6rem 1.2rem;
    background: var(--surface);
    border-bottom: 1px solid var(--line);
    flex-shrink: 0;
  }
  .rep-tool .topbar-brand {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    flex-shrink: 0;
  }
  .rep-tool .topbar-brand h1 {
    font-size: 1rem;
    color: var(--fg);
  }
  .rep-tool .topbar-brand h1 em { font-style: italic; color: var(--p-test); }
  .rep-tool .topbar-brand .mark {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.55rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted);
  }
  .rep-tool .topbar-project {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-left: 0.6rem;
    padding: 0 0.6rem;
    border-left: 1px solid var(--line-soft);
    border-right: 1px solid var(--line-soft);
  }
  .rep-tool .topbar-project-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.35rem 0.7rem;
    font-size: 0.78rem;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    color: var(--fg);
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
  }
  .rep-tool .topbar-project-btn:hover {
    background: var(--bg);
    border-color: var(--fg);
  }
  /* Stepper in the topbar — 4 dots showing where the user is in the
     reporting workflow (Import → Config → Preview → Export). */
  .rep-tool .topbar-steps {
    display: flex;
    align-items: center;
    gap: 0;
    flex: 1;
    justify-content: center;
  }
  .rep-tool .step-pill {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.35rem 0.85rem;
    font-size: 0.7rem;
    color: var(--muted);
    background: transparent;
    border: 1px solid transparent;
    border-radius: 999px;
    cursor: pointer;
    transition: all 0.15s;
  }
  .rep-tool .step-pill .step-num {
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: var(--depth);
    border: 1px solid var(--line);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.55rem;
    color: var(--muted);
  }
  .rep-tool .step-pill.active {
    color: var(--fg);
    background: var(--surface);
    border-color: var(--line);
  }
  .rep-tool .step-pill.active .step-num {
    background: var(--p-test);
    border-color: var(--p-test);
    color: var(--surface);
  }
  .rep-tool .step-pill.done .step-num {
    background: var(--p-cold);
    border-color: var(--p-cold);
    color: var(--surface);
  }
  .rep-tool .step-sep {
    width: 24px;
    height: 1px;
    background: var(--line);
    flex-shrink: 0;
  }
  .rep-tool .topbar-actions {
    display: flex;
    gap: 0.4rem;
    flex-shrink: 0;
  }
  .rep-tool .topbar-actions .btn {
    padding: 0.4rem 0.85rem;
    font-size: 0.75rem;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    color: var(--fg);
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
  }
  .rep-tool .topbar-actions .btn:hover { background: var(--bg); border-color: var(--fg); }
  .rep-tool .topbar-actions .btn.primary {
    background: var(--fg);
    color: var(--surface);
    border-color: var(--fg);
  }
  .rep-tool .topbar-actions .btn.primary:hover { background: var(--p-test); border-color: var(--p-test); }

  /* ═══════════ MAIN STAGE ═══════════ */
  .rep-tool .stage {
    /* Vertical scroll for long content; horizontal is hard-disabled so
       any layout glitch (e.g. an absolutely-positioned slide page that
       briefly renders before its scale transform is applied) can't push
       the whole UI sideways. */
    overflow-y: auto;
    overflow-x: hidden;
    padding: 2rem 1.5rem 4rem;
  }
  .rep-tool .stage-inner {
    max-width: 1100px;
    margin: 0 auto;
  }

  .rep-tool .stage-head {
    margin-bottom: 1.6rem;
  }
  .rep-tool .stage-head .ey { margin-bottom: 0.3rem; }
  .rep-tool .stage-head h2 {
    font-size: 1.6rem;
    color: var(--fg);
  }
  .rep-tool .stage-head .sub {
    margin-top: 0.45rem;
    color: var(--muted);
    font-size: 0.85rem;
  }

  /* ═══════════ STEP 1 — IMPORT ═══════════
     3 drop zones, one per CSV template, side by side. Each shows its
     state (empty / parsed / error) and the auto-detected row count. */
  .rep-tool .import-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1rem;
  }
  .rep-tool .csv-card {
    background: var(--surface);
    border: 1.5px dashed var(--line);
    border-radius: var(--r-md);
    padding: 1.2rem;
    transition: border-color 0.15s, background 0.15s;
    cursor: pointer;
    text-align: center;
    min-height: 200px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    position: relative;
  }
  .rep-tool .csv-card:hover {
    border-color: var(--p-test);
    background: var(--orchid-soft);
  }
  .rep-tool .csv-card.is-loaded {
    border-style: solid;
    border-color: var(--p-cold);
    background: var(--mint-soft);
  }
  .rep-tool .csv-card.is-error {
    border-style: solid;
    border-color: var(--s-lost);
    background: var(--coral-soft);
  }
  .rep-tool .csv-card.dragover {
    border-color: var(--p-test);
    background: var(--orchid-soft);
    transform: scale(1.02);
  }
  .rep-tool .csv-card-icon {
    font-size: 2rem;
    line-height: 1;
  }
  .rep-tool .csv-card-title {
    font-style: italic;
    font-size: 1.1rem;
    color: var(--fg);
  }
  .rep-tool .csv-card-hint {
    font-size: 0.7rem;
    color: var(--muted);
  }
  .rep-tool .csv-card-meta {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.6rem;
    color: var(--p-cold);
    background: var(--surface);
    padding: 0.25rem 0.5rem;
    border-radius: var(--r-sm);
    border: 1px solid var(--p-cold);
  }
  .rep-tool .csv-card.is-error .csv-card-meta {
    color: var(--s-lost);
    border-color: var(--s-lost);
  }
  .rep-tool .csv-card-clear {
    position: absolute;
    top: 0.5rem;
    right: 0.5rem;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: transparent;
    border: 1px solid var(--line);
    color: var(--muted);
    font-size: 0.7rem;
    cursor: pointer;
    display: none;
  }
  .rep-tool .csv-card.is-loaded .csv-card-clear, .rep-tool .csv-card.is-error .csv-card-clear { display: flex; align-items: center; justify-content: center; }
  .rep-tool .csv-card-clear:hover { background: var(--coral-soft); color: var(--s-lost); border-color: var(--s-lost); }

  /* "optionnel" badge — top-left of the Auction Insights card so the user
     knows the deck still works without it. */
  .rep-tool .csv-card-badge {
    position: absolute;
    top: 8px;
    left: 8px;
    background: var(--surface);
    color: var(--muted);
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.5rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    padding: 2px 6px;
    border-radius: 999px;
    border: 1px solid var(--line);
  }
  .rep-tool .csv-card.is-optional { border-style: dashed; }
  .rep-tool .csv-card.is-optional.is-loaded { border-style: solid; }

  .rep-tool .import-info {
    margin-top: 1.4rem;
    padding: 1rem 1.2rem;
    background: var(--surface);
    border: 1px solid var(--line-soft);
    border-radius: var(--r-md);
    font-size: 0.75rem;
    color: var(--muted);
    line-height: 1.6;
  }
  .rep-tool .import-info strong { color: var(--fg); }

  /* ═══════════ STEP 2 — CONFIG ═══════════ */
  .rep-tool .config-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.2rem;
  }
  .rep-tool .config-card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    padding: 1.2rem 1.3rem;
  }
  .rep-tool .config-card h3 {
    font-style: italic;
    font-size: 1rem;
    margin-bottom: 0.85rem;
  }
  .rep-tool .config-row {
    display: grid;
    grid-template-columns: 140px 1fr;
    align-items: center;
    gap: 0.8rem;
    margin-bottom: 0.6rem;
  }
  .rep-tool .config-row label {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.55rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--muted);
  }
  .rep-tool .config-row input, .rep-tool .config-row select {
    width: 100%;
    padding: 0.45rem 0.65rem;
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    font-family: inherit;
    font-size: 0.8rem;
    color: var(--fg);
    outline: none;
  }
  .rep-tool .config-row input:focus, .rep-tool .config-row select:focus { border-color: var(--p-cold); background: var(--surface); }

  /* ═══════════ STEP 3 — PREVIEW ═══════════ */
  .rep-tool .preview-shell {
    display: grid;
    grid-template-columns: 220px 1fr;
    gap: 1.2rem;
    align-items: start;
  }
  .rep-tool .preview-nav {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    padding: 0.8rem 0.5rem;
    position: sticky;
    top: 0;
    max-height: calc(100vh - 6rem);
    overflow-y: auto;
  }
  .rep-tool .preview-nav-title {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.55rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted);
    padding: 0.3rem 0.6rem 0.6rem;
    border-bottom: 1px solid var(--line-soft);
    margin-bottom: 0.4rem;
  }
  /* Sidebar header: title on the left, bulk toggle buttons on the right.
     Bulk buttons are minimal circle glyphs (◉ / ◯) — one to check all,
     the other to uncheck all. Tooltip carries the verbose description. */
  .rep-tool .preview-nav-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    border-bottom: 1px solid var(--line-soft);
    margin-bottom: 0.4rem;
    padding: 0.3rem 0.6rem 0.5rem;
  }
  .rep-tool .preview-nav-head .preview-nav-title {
    border: none;
    margin: 0;
    padding: 0;
  }
  .rep-tool .preview-nav-bulk {
    display: flex;
    gap: 0.25rem;
  }
  .rep-tool .preview-nav-bulk .pp-action {
    padding: 0.15rem 0.4rem;
    font-size: 0.7rem;
    line-height: 1;
    min-width: auto;
  }
  .rep-tool .preview-nav-link {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.35rem 0.5rem;
    font-size: 0.72rem;
    color: var(--muted);
    cursor: pointer;
    border-radius: var(--r-sm);
    transition: background 0.12s, color 0.12s, opacity 0.12s;
  }
  .rep-tool .preview-nav-link:hover { background: var(--bg); color: var(--fg); }
  .rep-tool .preview-nav-link.active {
    background: var(--orchid-soft);
    color: var(--p-test);
    font-weight: 500;
  }
  /* ─ Sidebar : chapitres repliables ─ */
  .rep-tool .preview-nav-chapter { margin-bottom: 2px; }
  .rep-tool .preview-nav-chap-head {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.3rem 0.4rem;
    border-radius: var(--r-sm);
  }
  .rep-tool .preview-nav-chap-head:hover { background: var(--bg); }
  .rep-tool .preview-nav-chap-toggle {
    border: none;
    background: transparent;
    cursor: pointer;
    color: var(--muted);
    font-size: 0.7rem;
    line-height: 1;
    padding: 2px;
    flex-shrink: 0;
  }
  .rep-tool .preview-nav-chap-check {
    display: inline-flex;
    align-items: center;
    cursor: pointer;
    flex-shrink: 0;
  }
  .rep-tool .preview-nav-chap-label {
    flex: 1;
    text-align: left;
    border: none;
    background: transparent;
    cursor: pointer;
    color: var(--fg);
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    padding: 0;
  }
  .rep-tool .preview-nav-chap-count {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.58rem;
    color: var(--muted);
    flex-shrink: 0;
  }
  /* Sections légèrement indentées sous leur chapitre. */
  .rep-tool .preview-nav-chapter .preview-nav-link { margin-left: 0.6rem; }
  .rep-tool .preview-nav-num {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.6rem;
    color: var(--muted);
    width: 14px;
    flex-shrink: 0;
  }
  /* Title takes remaining space so the checkbox lines up at the right edge */
  .rep-tool .preview-nav-label {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  /* Inline checkbox at the right of each nav row — toggles whether the
     section is included in the PDF/PPTX export. The wrapping <label>
     widens the click target so it's easy to hit on mobile too. */
  .rep-tool .preview-nav-check {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    padding: 0.15rem 0.25rem;
    cursor: pointer;
    border-radius: var(--r-sm);
  }
  .rep-tool .preview-nav-check input[type="checkbox"] {
    margin: 0;
    cursor: pointer;
    width: 14px;
    height: 14px;
    accent-color: var(--p-test);
  }
  /* Visual cue for excluded sections: faded text + struck-through title */
  .rep-tool .preview-nav-link.is-hidden-link {
    opacity: 0.45;
  }
  .rep-tool .preview-nav-link.is-hidden-link .preview-nav-label {
    text-decoration: line-through;
    text-decoration-thickness: 1px;
  }
  .rep-tool .preview-nav-link.active .preview-nav-num { color: var(--p-test); }

  .rep-tool .preview-pages {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    /* Visual size reduction for the on-screen preview only.
       The internal page layout (charts, tables, sankey at 1180px viewBox)
       stays calibrated for 1280px logical width — zooming the parent is
       the cleanest way to fit the deck on narrower viewports without
       touching pixel-level design.
       Unlike `transform: scale`, the `zoom` property shrinks both the
       visual rendering AND the layout box, so the pages naturally fit
       the available column with no horizontal overflow.
       Disabled during rasterizing (see body.rasterizing override below)
       so the PDF/PPTX export captures pages at full crisp resolution. */
    zoom: 0.75;
  }
  /* ═══════════ DEUX VIEWERS SÉPARÉS — one-pager (autonome, portrait) PUIS
     deck PPT (nav + slides paysage). Chacun son cadre + en-tête titré. ═══════════ */
  .rep-tool .preview-viewer { margin-bottom: 1.8rem; }
  .rep-tool .preview-viewer:last-child { margin-bottom: 0; }
  .rep-tool .preview-viewer-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.7rem;
    padding-bottom: 0.55rem;
    border-bottom: 1px solid #2B1F0F1A;
  }
  .rep-tool .preview-viewer-titles {
    display: flex;
    flex-direction: column;
    gap: 0.12rem;
    min-width: 0;
  }
  .rep-tool .preview-viewer-title {
    font-size: 0.95rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: #231F23;
  }
  .rep-tool .preview-viewer-sub {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.56rem;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--muted);
  }
  /* Stage du one-pager autonome : cadre chaud (comme le viewer deck), page
     portrait centrée, zoom propre + responsive (container query sur le stage). */
  .rep-tool .preview-onepager-stage {
    container-type: inline-size;
    display: flex;
    justify-content: center;
    background: #EFE9DC;
    border-radius: 10px;
    padding: 1.3rem 1rem;
    overflow-x: auto;
  }
  .rep-tool .preview-onepager-stage .op-page { zoom: 0.58; }
  @container (min-width: 760px) {
    .rep-tool .preview-onepager-stage .op-page { zoom: 0.66; }
  }
  /* Each .preview-page is rasterized into the PDF/PPTX at full resolution,
     so its on-screen styling IS the export styling. */
  .rep-tool .preview-page {
    /* Strict A4 paysage logical dimensions — matches the export page size
       (PDF 297 × 210 mm, PPTX 11.69 × 8.27"). 1280 × 905 keeps internal
       layouts that were tuned for 1280 px width unchanged.
       overflow: hidden clips any content that overflows so the user
       sees the same thing they'll get in the export.

       font-family: explicitly use --report-font (Roboto by default,
       overridden by loadClientFont when the user picks one). This is
       what html2canvas rasterises — without an explicit family here,
       the page would inherit body's `font-family: 'Inter', system-ui`
       and html2canvas would screenshot whatever the browser picked
       as fallback (often a serif italic on macOS — the cause of the
       "broken italic" text in exported PDFs). */
    font-family: var(--report-font, 'Roboto', system-ui, sans-serif);
    width: 1280px;
    height: 720px; /* 16:9 (keynote/luxgap) — slides PPT widescreen */
    overflow: hidden;
    background: #FFFFFF;
    border: none;
    border-radius: 0;
    padding: 36px 44px 24px;
    box-shadow: 0 2px 12px rgba(35,31,35,0.06);
    scroll-margin-top: 1rem;
    color: #231F23;
    display: flex;
    flex-direction: column;
    /* scoped warm tokens — nested kpi-tile, data-table, compar-table inherit.
       Page BLANCHE : --bg/--surface éclaircis (fills visibles sur blanc) +
       --line-soft un poil renforcé pour des filets visibles. */
    --line:        #2B1F0F1F;
    --line-soft:   #2B1F0F12;
    --bg:          #F3F0EA;
    --surface:     #FBFAF7;
    --muted:       #8A8276;
    --s-won:       #2E7D4F;
    --s-won-soft:  #DAEFE0;
    --s-lost:      #B33A3A;
    --s-lost-soft: #F4D8D5;
    --s-incon:     #8A6D2E;
    --s-incon-soft:#F2EAD8;
    --section-accent: #3D8B5C;
  }
  .rep-tool .preview-page.is-hidden { opacity: 0.45; }

  .rep-tool .preview-page-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1.6rem;
    padding-bottom: 1rem;
    border-bottom: 1px solid var(--line);
  }
  .rep-tool .preview-page-title {
    font-size: 1.55rem;
    font-style: normal;
    font-weight: 400;
    color: #231F23;
    line-height: 1.2;
    display: flex;
    align-items: center;
    gap: 0.75rem;
  }
  .rep-tool .preview-page-title::before {
    content: '';
    display: inline-block;
    width: 10px;
    height: 10px;
    background: var(--section-accent);
    border-radius: 50%;
    flex-shrink: 0;
  }
  .rep-tool .preview-page-num {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.55rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
    margin-bottom: 0.35rem;
  }

  /* Footer signature — runs along the bottom-right of every slide,
     mirrors the discreet "client · Google Ads" mark in the reference decks */
  .rep-tool .preview-page-footer {
    /* La page est en flex-column hauteur fixe (905px) : margin-top:auto épingle
       le footer TOUT EN BAS, même quand le contenu de la section est court. */
    margin-top: auto;
    padding-top: 0.8rem;
    border-top: 1px solid var(--line-soft);
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 0.55rem;
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.55rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
  }
  .rep-tool .preview-page-footer .pf-dot {
    display: inline-block;
    width: 3px;
    height: 3px;
    background: var(--section-accent);
    border-radius: 50%;
  }
  .rep-tool .preview-page-footer .pf-strong {
    color: #231F23;
  }

  /* Refined tables inside the deck — italic small column headers, soft striping */
  .rep-tool .preview-page .compar-table th, .rep-tool .preview-page .data-table th {
    font-family: inherit;
    font-style: italic;
    text-transform: none;
    letter-spacing: 0.01em;
    font-size: 0.7rem;
    color: var(--muted);
    background: transparent;
    font-weight: 400;
    padding-bottom: 0.7rem;
    border-bottom: 1px solid var(--line);
  }
  .rep-tool .preview-page .compar-table td, .rep-tool .preview-page .data-table td {
    border-bottom: 1px solid var(--line-soft);
  }
  .rep-tool .preview-page .data-table tbody tr:nth-child(even) {
    background: rgba(255,255,255,0.32);
  }
  .rep-tool .preview-page .data-table tbody tr:hover { background: rgba(255,255,255,0.5); }

  /* Soft pastel pills with rounded shape */
  .rep-tool .preview-page .delta-pill {
    border-radius: 999px;
    padding: 1px 8px;
    font-size: 0.62rem;
    font-weight: 500;
  }

  /* KPI tiles — translucent on cream paper */
  .rep-tool .preview-page .kpi-tile {
    background: rgba(255,255,255,0.4);
    border: 1px solid var(--line-soft);
    border-radius: 6px;
  }

  /* Insight block — quotation feel, picks up the section accent */
  .rep-tool .preview-page .insight-block {
    background: rgba(255,255,255,0.4);
    border-left: 3px solid var(--section-accent);
    border-radius: 0;
    margin-top: 1.4rem;
  }
  .rep-tool .preview-page .insight-block-label {
    color: var(--section-accent);
  }
  .rep-tool .preview-page .insight-block-text {
    font-style: italic;
    font-size: 0.85rem;
  }
  .rep-tool .preview-page .insight-regen-btn {
    background: transparent;
    color: var(--section-accent);
    border-color: var(--section-accent);
  }
  .rep-tool .preview-page .insight-regen-btn:hover {
    background: rgba(255,255,255,0.6);
  }
  .rep-tool .preview-page-actions {
    display: flex;
    gap: 0.3rem;
  }
  .rep-tool .pp-action {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.55rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    padding: 0.25rem 0.55rem;
    background: transparent;
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    color: var(--muted);
    cursor: pointer;
    transition: all 0.15s;
  }
  .rep-tool .pp-action:hover { color: var(--fg); border-color: var(--fg); background: var(--bg); }
  .rep-tool .pp-action.is-toggle-hidden { color: var(--s-lost); border-color: var(--s-lost); }

  /* Insight block — editable text + "regenerate AI" button */
  .rep-tool .insight-block {
    margin-top: 1.1rem;
    padding: 0.9rem 1rem;
    background: var(--bg);
    border-left: 3px solid var(--p-test);
    border-radius: var(--r-sm);
    position: relative;
  }
  .rep-tool .insight-block-label {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.55rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--p-test);
    margin-bottom: 0.4rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
  }
  .rep-tool .insight-block-text {
    width: 100%;
    border: none;
    background: transparent;
    resize: vertical;
    min-height: 60px;
    font-family: inherit;
    font-size: 0.82rem;
    color: var(--fg);
    line-height: 1.55;
    outline: none;
  }
  .rep-tool .insight-regen-btn {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.55rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    padding: 0.2rem 0.5rem;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    color: var(--p-test);
    cursor: pointer;
    transition: all 0.15s;
  }
  .rep-tool .insight-regen-btn:hover { background: var(--orchid-soft); border-color: var(--p-test); }
  .rep-tool .insight-regen-btn:disabled { opacity: 0.5; cursor: wait; }

  /* KPI tiles — 4 across at the top of "Vue totale" + executive summary */
  .rep-tool .kpi-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 0.8rem;
  }
  .rep-tool .kpi-tile {
    background: var(--bg);
    border: 1px solid var(--line-soft);
    border-radius: var(--r-md);
    padding: 0.95rem 1.1rem;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
  }
  .rep-tool .kpi-tile-label {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.55rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted);
  }
  .rep-tool .kpi-tile-value {
    font-size: 1.5rem;
    font-weight: 400;
    color: var(--fg);
    font-feature-settings: 'tnum';
    line-height: 1;
  }
  .rep-tool .kpi-tile-delta {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.62rem;
    color: var(--muted);
    margin-top: 0.1rem;
  }
  .rep-tool .kpi-tile-delta.up { color: var(--s-won); }
  .rep-tool .kpi-tile-delta.down { color: var(--s-lost); }

  /* Comparatif table — 1 KPI per row, compared across actuel/N-1/M-2/objectif */
  .rep-tool .compar-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.8rem;
  }
  .rep-tool .compar-table th, .rep-tool .compar-table td {
    padding: 0.6rem 0.8rem;
    text-align: left;
    border-bottom: 1px solid var(--line-soft);
  }
  .rep-tool .compar-table th {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.55rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted);
    font-weight: 400;
  }
  .rep-tool .compar-table td.num {
    font-family: 'JetBrains Mono', monospace;
    font-feature-settings: 'tnum';
    text-align: right;
  }
  .rep-tool .delta-pill {
    display: inline-block;
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.6rem;
    padding: 1px 5px;
    border-radius: 3px;
    background: var(--depth);
    color: var(--muted);
    margin-left: 0.4rem;
  }
  .rep-tool .delta-pill.up { background: var(--s-won-soft); color: var(--s-won); }
  .rep-tool .delta-pill.down { background: var(--s-lost-soft); color: var(--s-lost); }

  /* Generic table for keywords, products, ads, audiences ranking */
  .rep-tool .data-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.75rem;
    margin-top: 0.6rem;
  }
  .rep-tool .data-table th, .rep-tool .data-table td {
    padding: 0.5rem 0.7rem;
    text-align: left;
    border-bottom: 1px solid var(--line-soft);
  }
  .rep-tool .data-table th {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.55rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted);
    background: var(--bg);
    font-weight: 400;
  }
  .rep-tool .data-table td.num {
    font-family: 'JetBrains Mono', monospace;
    font-feature-settings: 'tnum';
    text-align: right;
  }
  .rep-tool .data-table tbody tr:hover { background: var(--bg); }
  /* Padded "empty" rows on the monthly tables — months with no data, kept
     to fill out the year. Visually muted so they don't dominate. */
  .rep-tool .data-table tbody tr.row-empty td {
    color: var(--muted);
    font-style: italic;
    background: transparent;
  }
  .rep-tool .data-table tbody tr.row-empty:hover { background: var(--surface); }

  /* ═══════════ QS META REPORT TABLE — 17-column dense matrix ═══════════
     Each numeric cell is colored by relative tercile (relative to the
     values in the same column across the displayed rows). The 3 last
     columns (Quality / Engagement / Conversion rankings) are pill-shaped
     badges with the AU-DESSUS / MOYEN / EN-DESSOUS labels. */
  .rep-tool .qs-report-scroll {
    /* The matrix is 17 columns wide — narrow viewports get a horizontal
       scroll rather than a squished, illegible table. */
    overflow-x: auto;
    margin-top: 0.4rem;
  }
  .rep-tool .qs-report-table {
    width: 100%;
    min-width: 1100px;
    border-collapse: separate;
    border-spacing: 3px 4px;
    font-size: 0.7rem;
    font-family: 'JetBrains Mono', monospace;
    font-feature-settings: 'tnum';
  }
  .rep-tool .qs-report-table th {
    background: #231F23;
    color: #F5F1E8;
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.55rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    font-weight: 500;
    padding: 0.55rem 0.55rem;
    text-align: center;
    white-space: nowrap;
    border-radius: 3px;
  }
  .rep-tool .qs-report-table th:first-child {
    text-align: left;
    padding-left: 0.8rem;
  }
  .rep-tool .qs-report-name {
    font-family: var(--report-font, "Roboto", "Inter", system-ui, sans-serif);
    font-size: 0.75rem;
    padding: 0.55rem 0.7rem;
    color: #231F23;
    background: var(--surface);
    border-radius: 3px;
    white-space: nowrap;
    max-width: 220px;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .rep-tool .qs-cell {
    padding: 0.55rem 0.5rem;
    text-align: center;
    border-radius: 3px;
    white-space: nowrap;
    font-weight: 500;
  }
  .rep-tool .qs-cell-good {
    background: #DAEFE0;
    color: #1F6033;
  }
  .rep-tool .qs-cell-mid {
    background: #F2EAD8;
    color: #7A5A1F;
  }
  .rep-tool .qs-cell-bad {
    background: #F4D8D5;
    color: #A02E2E;
  }
  .rep-tool .qs-cell-empty {
    background: var(--surface);
    color: var(--muted);
    font-style: italic;
  }
  /* Ranking cells (3 last columns): pill-style label centered */
  .rep-tool .qs-rank-cell {
    font-size: 0.6rem;
    letter-spacing: 0.06em;
    font-weight: 600;
    padding: 0.5rem 0.4rem;
  }

  .rep-tool .chart-wrap {
    height: 280px;
    position: relative;
    margin: 0.5rem 0;
  }
  .rep-tool .chart-wrap.tall { height: 360px; }

  .rep-tool .empty-section {
    padding: 2rem 1rem;
    text-align: center;
    color: var(--muted);
    font-size: 0.78rem;
    font-style: italic;
  }

  /* ═══════════ PROJECT SWITCHER POPOVER ═══════════ */
  .rep-tool .proj-popover {
    position: absolute;
    background: var(--surface);
    border: 1px solid var(--fg);
    border-radius: var(--r-md);
    box-shadow: 0 8px 22px rgba(35,31,35,0.18);
    z-index: 100;
    min-width: 260px;
    padding: 0.5rem;
  }
  .rep-tool .proj-popover-list {
    max-height: 320px;
    overflow-y: auto;
    margin-bottom: 0.4rem;
  }
  .rep-tool .proj-popover-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.45rem 0.6rem;
    border-radius: var(--r-sm);
    cursor: pointer;
    font-size: 0.78rem;
    transition: background 0.12s;
  }
  .rep-tool .proj-popover-row:hover { background: var(--bg); }
  .rep-tool .proj-popover-row.is-active { background: var(--mint-soft); color: var(--p-cold); font-weight: 500; }
  .rep-tool .proj-popover-add {
    width: 100%;
    padding: 0.5rem 0.6rem;
    background: transparent;
    border: 1.5px dashed var(--line);
    border-radius: var(--r-sm);
    color: var(--muted);
    font-size: 0.72rem;
    cursor: pointer;
    text-align: left;
    transition: all 0.15s;
  }
  .rep-tool .proj-popover-add:hover { border-color: var(--p-cold); color: var(--fg); background: var(--mint-soft); }

  /* Toast notifications (success/error feedback for CSV import etc.) */
  .rep-tool .toast-stack {
    position: fixed;
    bottom: 1rem;
    right: 1rem;
    z-index: 1000;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
  }
  .rep-tool .toast {
    background: var(--surface);
    border: 1px solid var(--fg);
    border-left: 4px solid var(--p-test);
    border-radius: var(--r-sm);
    padding: 0.7rem 1rem;
    box-shadow: 0 4px 14px rgba(35,31,35,0.12);
    font-size: 0.78rem;
    color: var(--fg);
    max-width: 360px;
    animation: toastIn 0.25s ease;
  }
  .rep-tool .toast.error { border-left-color: var(--s-lost); }
  .rep-tool .toast.success { border-left-color: var(--p-cold); }
  @keyframes toastIn {
    from { opacity: 0; transform: translateY(8px); }
    to { opacity: 1; transform: translateY(0); }
  }

  /* ═══════════ STEP 4 — EXPORT panel ═══════════
     The big section list moved to the sidebar (with inline checkboxes).
     What remains here is just the export trigger: title + count meta on
     one line, then the 3 export buttons row below. */
  .rep-tool .export-selector { margin-bottom: 1.2rem; }
  .rep-tool .export-selector-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1rem;
    padding-bottom: 0.8rem;
    border-bottom: 1px solid var(--line-soft);
  }
  .rep-tool .export-selector-head h3 {
    font-style: italic;
    font-size: 1rem;
  }
  .rep-tool .export-selector-meta {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.6rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted);
  }
  .rep-tool .export-selector-bulk {
    display: flex;
    gap: 0.4rem;
  }
  .rep-tool .export-section-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.4rem 0.8rem;
  }
  @media (max-width: 720px) {
    .rep-tool .export-section-list { grid-template-columns: 1fr; }
    .rep-tool .export-selector-head { grid-template-columns: 1fr; }
  }
  .rep-tool .export-section-row label {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.55rem 0.75rem;
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    cursor: pointer;
    transition: background 0.12s, border-color 0.12s, opacity 0.12s;
    background: var(--bg);
    user-select: none;
  }
  .rep-tool .export-section-row label:hover { border-color: var(--fg); }
  .rep-tool .export-section-row input[type="checkbox"] {
    width: 14px;
    height: 14px;
    accent-color: var(--p-test);
    cursor: pointer;
    flex-shrink: 0;
    margin: 0;
  }
  .rep-tool .export-section-num {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.6rem;
    letter-spacing: 0.04em;
    color: var(--muted);
    flex-shrink: 0;
    width: 18px;
  }
  .rep-tool .export-section-title {
    font-size: 0.85rem;
    color: var(--fg);
    line-height: 1.3;
  }
  .rep-tool .export-section-row.is-off label {
    background: transparent;
    opacity: 0.5;
  }
  .rep-tool .export-section-row.is-off .export-section-title {
    text-decoration: line-through;
    text-decoration-color: var(--muted);
  }
  .rep-tool .export-empty-warn {
    text-align: center;
    margin-top: 1rem;
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.65rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--s-lost);
  }
  .rep-tool .btn:disabled, .rep-tool .btn[disabled] {
    cursor: not-allowed;
    opacity: 0.45;
  }
  .rep-tool .btn:disabled:hover, .rep-tool .btn[disabled]:hover {
    background: var(--fg);
    border-color: var(--fg);
  }

  /* PDF / PPTX export modal — shows during generation */
  .rep-tool .export-modal {
    position: fixed;
    inset: 0;
    background: rgba(35,31,35,0.5);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 200;
  }
  .rep-tool .export-modal-card {
    background: var(--surface);
    border-radius: var(--r-md);
    padding: 2rem 2.4rem;
    text-align: center;
    box-shadow: 0 10px 30px rgba(35,31,35,0.3);
    min-width: 360px;
  }
  .rep-tool .export-modal-spinner {
    width: 32px;
    height: 32px;
    border: 3px solid var(--line);
    border-top-color: var(--p-test);
    border-radius: 50%;
    margin: 0 auto 1rem;
    animation: spin 0.8s linear infinite;
  }
  @keyframes spin { to { transform: rotate(360deg); } }
  .rep-tool .export-modal-progress {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.65rem;
    letter-spacing: 0.04em;
    color: var(--muted);
    margin-top: 0.5rem;
  }

  /* ═══════════ STEP 1 — SETUP (combined import + config) ═══════════ */
  .rep-tool .setup-section {
    margin-bottom: 2rem;
  }
  .rep-tool .setup-section-head {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    margin-bottom: 1rem;
    padding-bottom: 0.7rem;
    border-bottom: 1px solid var(--line-soft);
  }
  .rep-tool .setup-num {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: var(--p-test);
    color: var(--surface);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.7rem;
    font-weight: 500;
    flex-shrink: 0;
  }
  .rep-tool .setup-section-head h3 {
    font-style: italic;
    font-size: 1.05rem;
    color: var(--fg);
    margin: 0;
  }
  .rep-tool .setup-section-hint {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.6rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--muted);
    margin-left: auto;
  }
  .rep-tool .demo-data-btn {
    color: var(--p-test);
    border-color: var(--p-test);
    background: var(--orchid-soft);
    font-weight: 500;
  }
  .rep-tool .demo-data-btn:hover {
    color: var(--surface);
    background: var(--p-test);
    border-color: var(--p-test);
  }

  /* Wide config card — branding spans both columns of the config grid */
  .rep-tool .config-card-wide {
    grid-column: 1 / -1;
  }

  /* "facultatif" tag next to optional field labels */
  .rep-tool .opt {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.5rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--muted);
    background: var(--bg);
    padding: 1px 5px;
    border-radius: 3px;
    margin-left: 0.4rem;
    font-weight: 400;
  }

  /* Logo uploaders — side by side under the client/agency name fields */
  .rep-tool .branding-logos {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.8rem;
    margin: 0.6rem 0 0.8rem;
  }
  .rep-tool .logo-uploader {
    border: 1.5px dashed var(--line);
    border-radius: var(--r-md);
    padding: 0.7rem;
    background: var(--bg);
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s;
    position: relative;
    text-align: center;
    min-height: 110px;
    display: flex;
    flex-direction: column;
  }
  .rep-tool .logo-uploader:hover { border-color: var(--p-test); background: var(--orchid-soft); }
  .rep-tool .logo-uploader.dragover { border-color: var(--p-test); background: var(--orchid-soft); border-style: solid; }
  .rep-tool .logo-uploader-label {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.55rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted);
    margin-bottom: 0.5rem;
  }
  .rep-tool .logo-drop {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    color: var(--muted);
    font-size: 0.72rem;
    line-height: 1.4;
  }
  .rep-tool .logo-drop span {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.55rem;
    letter-spacing: 0.04em;
    color: var(--muted);
    opacity: 0.75;
    margin-top: 0.4rem;
  }
  .rep-tool .logo-preview {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--surface);
    border-radius: var(--r-sm);
    padding: 0.5rem;
    min-height: 50px;
  }
  .rep-tool .logo-preview img {
    max-width: 100%;
    max-height: 56px;
    width: auto;
    height: auto;
    object-fit: contain;
  }
  .rep-tool .logo-clear-btn {
    margin-top: 0.4rem;
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.55rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    padding: 0.25rem 0.55rem;
    background: transparent;
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    color: var(--s-lost);
    cursor: pointer;
    align-self: center;
  }
  .rep-tool .logo-clear-btn:hover { border-color: var(--s-lost); background: var(--s-lost-soft); }

  /* Color picker (config-row variant: full-width inline editors) */
  .rep-tool .config-row-color, .rep-tool .config-row-font {
    grid-template-columns: 140px 1fr;
  }
  .rep-tool .color-picker {
    display: flex;
    align-items: center;
    gap: 0.5rem;
  }
  .rep-tool .color-picker input[type="color"] {
    width: 40px;
    height: 32px;
    padding: 2px;
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    background: var(--bg);
    cursor: pointer;
    flex-shrink: 0;
  }
  .rep-tool .color-picker input[type="text"] {
    flex: 0 0 110px;
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.78rem;
    text-transform: uppercase;
  }
  .rep-tool .branding-reset-btn {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.55rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    padding: 0.35rem 0.65rem;
    background: transparent;
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    color: var(--muted);
    cursor: pointer;
    transition: all 0.15s;
  }
  .rep-tool .branding-reset-btn:hover:not(:disabled) { color: var(--fg); border-color: var(--fg); background: var(--bg); }
  .rep-tool .branding-reset-btn:disabled { opacity: 0.4; cursor: not-allowed; }

  .rep-tool .config-row-hint {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.58rem;
    letter-spacing: 0.04em;
    color: var(--muted);
    margin: -0.3rem 0 0.6rem 140px;
    line-height: 1.5;
  }

  /* Font picker — inputs row + live preview line below */
  .rep-tool .font-picker {
    display: flex;
    align-items: center;
    gap: 0.5rem;
  }
  .rep-tool .font-picker input[type="text"] { flex: 1; }
  .rep-tool .font-preview-line {
    grid-column: 2;
    margin-top: 0.4rem;
    padding: 0.6rem 0.8rem;
    background: var(--bg);
    border-radius: var(--r-sm);
    font-size: 1.1rem;
    line-height: 1.3;
    color: var(--fg);
    border-left: 3px solid var(--p-test);
  }

  /* ═══════════ STEP 2 — DELIVER (preview + export combined) ═══════════ */
  .rep-tool .deliver-panel {
    margin-bottom: 1.2rem;
  }
  .rep-tool .deliver-export-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.8rem;
    margin-top: 1rem;
  }
  .rep-tool .deliver-export-btn {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: 0.7rem;
    padding: 0.85rem 1.1rem;
    text-align: left;
  }
  .rep-tool .deliver-export-icon { font-size: 1.3rem; line-height: 1; }
  .rep-tool .deliver-export-label { font-size: 0.85rem; font-weight: 500; }
  .rep-tool .deliver-export-meta {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.6rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    opacity: 0.75;
  }

  /* ═══════════ DECK BRANDING — applied inside .preview-page (export aesthetic) ═══════════ */
  /* Client font, when set via the branding card, applies to every preview
     page (and so to every rasterised PDF/PPTX page). */
  .rep-tool .preview-page {
    font-family: var(--report-font, "Roboto", "Inter", system-ui, sans-serif);
  }

  /* ═══════════ CHART HELPERS — explainer text + tall variants + tri-chart grid ═══════════ */
  .rep-tool .chart-explainer {
    font-size: 0.78rem;
    line-height: 1.45;
    color: var(--muted);
    margin: 0 0 0.8rem;
    font-style: italic;
  }
  .rep-tool .chart-wrap-tall {
    height: 420px;
    position: relative;
  }
  .rep-tool .chart-wrap-tall canvas { max-height: 100%; }

  /* Tri-chart grid: 2 pies (small) + CPA bar (wider) on the same row */
  .rep-tool .tri-chart-grid {
    display: grid;
    grid-template-columns: 1fr 1fr 1.5fr;
    gap: 1rem;
    margin-top: 0.4rem;
    flex: 1;
  }
  .rep-tool .tri-chart-card {
    background: rgba(255,255,255,0.4);
    border: 1px solid var(--line-soft);
    border-radius: var(--r-md);
    padding: 0.7rem 0.9rem 0.5rem;
    display: flex;
    flex-direction: column;
    min-height: 320px;
  }
  .rep-tool .tri-chart-title {
    font-size: 0.8rem;
    color: var(--muted);
    margin-bottom: 0.5rem;
    flex-shrink: 0;
  }
  .rep-tool .tri-chart-card .chart-wrap {
    flex: 1;
    min-height: 220px;
    position: relative;
  }
  .rep-tool .tri-chart-cpa { min-height: 340px; }
  .rep-tool .tri-chart-cpa .chart-wrap { min-height: 240px; }

  /* Legend below the CPA bar chart — colour swatches + threshold readout */
  .rep-tool .cpa-legend {
    display: flex;
    gap: 0.7rem;
    flex-wrap: wrap;
    align-items: center;
    margin-top: 0.5rem;
    padding-top: 0.4rem;
    border-top: 1px solid var(--line-soft);
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.55rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--muted);
  }
  .rep-tool .cpa-legend-item {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
  }
  .rep-tool .cpa-dot {
    width: 8px;
    height: 8px;
    border-radius: 2px;
    display: inline-block;
  }
  .rep-tool .cpa-good { background: #2E7D4F; }
  .rep-tool .cpa-warn { background: #B68A2E; }
  .rep-tool .cpa-bad { background: #B33A3A; }
  .rep-tool .cpa-legend-max {
    margin-left: auto;
    text-transform: none;
    font-style: italic;
    letter-spacing: 0;
    color: #231F23;
    font-family: inherit;
    font-size: 0.72rem;
  }
  .rep-tool .cpa-legend-max strong { font-weight: 500; }

  /* Compar table — pill polish */
  .rep-tool .compar-table .delta-pill { padding: 1px 7px; }

  /* ═══════════ CUSTOM SVG CHARTS — sankey / funnel / venn ═══════════
     Each renderer puts its SVG directly inside a host element. We size
     the host to match the wrap-tall chart-wraps (420px) and let the SVG
     scale to fit via preserveAspectRatio. */
  .rep-tool .sankey-host, .rep-tool .funnel-host, .rep-tool .venn-host {
    height: 420px;
    width: 100%;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .rep-tool .sankey-host svg, .rep-tool .funnel-host svg, .rep-tool .venn-host svg {
    width: 100%;
    height: 100%;
    display: block;
  }
  /* Sankey labels need the deck font */
  .rep-tool .sankey-host text, .rep-tool .funnel-host text, .rep-tool .venn-host text {
    font-family: var(--report-font, "Roboto", "Inter", system-ui, sans-serif);
  }

  /* ═══════════ TESTS-LIST SECTIONS — testsPast / testsToLaunch ═══════════
     Two-column bullet layout. Left column = positive (green), right column
     = negative (red), matching the editorial style of the reference deck. */
  .rep-tool .tests-list-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 2rem;
    margin-top: 0.5rem;
  }
  @media (max-width: 720px) {
    .rep-tool .tests-list-grid { grid-template-columns: 1fr; gap: 1.4rem; }
  }
  .rep-tool .tests-list-col-label {
    font-size: 0.85rem;
    color: var(--muted);
    margin-bottom: 1rem;
    padding-bottom: 0.4rem;
  }
  .rep-tool .tests-list-col-label em { font-style: italic; }
  .rep-tool .tests-list-items {
    list-style: none;
    padding: 0;
    margin: 0 0 0.6rem;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
  }
  .rep-tool .tests-list-item {
    display: grid;
    grid-template-columns: 12px 1fr 22px;
    align-items: flex-start;
    gap: 0.6rem;
    line-height: 1.5;
  }
  .rep-tool .tests-list-bullet {
    display: inline-block;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    margin-top: 0.55rem;
    flex-shrink: 0;
  }
  .rep-tool .tests-list-col.is-positive .tests-list-bullet { background: #2E7D4F; }
  .rep-tool .tests-list-col.is-negative .tests-list-bullet { background: #B33A3A; }
  .rep-tool .tests-list-input {
    flex: 1;
    min-width: 0;
    padding: 0.4rem 0.6rem;
    border: 1px solid transparent;
    border-radius: var(--r-sm);
    background: transparent;
    font: inherit;
    font-size: 0.85rem;
    color: #231F23;
    line-height: 1.4;
    transition: background 0.15s, border-color 0.15s;
  }
  .rep-tool .tests-list-input::placeholder { color: var(--muted); font-style: italic; }
  .rep-tool .tests-list-input:hover { background: rgba(255,255,255,0.5); }
  .rep-tool .tests-list-input:focus {
    outline: none;
    background: rgba(255,255,255,0.7);
    border-color: var(--line);
  }
  .rep-tool .tests-list-remove {
    background: transparent;
    border: 1px solid transparent;
    color: var(--muted);
    width: 22px;
    height: 22px;
    border-radius: 50%;
    cursor: pointer;
    line-height: 1;
    font-size: 0.95rem;
    padding: 0;
    margin-top: 0.35rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: color 0.15s, border-color 0.15s, background 0.15s;
  }
  .rep-tool .tests-list-remove:hover {
    color: var(--s-lost);
    border-color: var(--s-lost);
    background: var(--s-lost-soft);
  }
  .rep-tool .tests-list-add {
    background: transparent;
    border: 1px dashed var(--line);
    border-radius: var(--r-sm);
    color: var(--muted);
    padding: 0.4rem 0.85rem;
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.55rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    cursor: pointer;
    transition: color 0.15s, border-color 0.15s, background 0.15s;
    margin-left: 18px; /* align with bullet column */
  }
  .rep-tool .tests-list-add:hover {
    color: var(--fg);
    border-color: var(--fg);
    background: var(--bg);
  }
  .rep-tool .tests-list-empty {
    color: var(--muted);
    font-style: italic;
    font-size: 0.78rem;
    padding: 0.4rem 0 0.4rem 18px;
    list-style: none;
  }

  /* ── Rasterisation: wizard-only chrome must disappear from the export.
        We swap inputs/buttons for plain text so PDF/PPTX show the bullet
        list as it should look in the final deliverable. */
  .rep-tool body.rasterizing .tests-list-input {
    border-color: transparent !important;
    background: transparent !important;
    pointer-events: none;
  }
  .rep-tool body.rasterizing .tests-list-remove, .rep-tool body.rasterizing .tests-list-add { display: none; }

  /* ═══════════ IS & QUALITY SCORE — 2-column block layout ═══════════ */
  .rep-tool .is-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.4rem;
    margin-top: 0.5rem;
  }
  @media (max-width: 720px) {
    .rep-tool .is-grid { grid-template-columns: 1fr; }
  }
  .rep-tool .is-block {
    background: rgba(255,255,255,0.4);
    border: 1px solid var(--line-soft);
    border-radius: var(--r-md);
    padding: 1.1rem 1.2rem;
  }
  .rep-tool .is-block-head {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    margin-bottom: 1rem;
    padding-bottom: 0.7rem;
    border-bottom: 1px solid var(--line-soft);
  }
  .rep-tool .is-block-title {
    font-style: italic;
    font-size: 0.85rem;
    color: #231F23;
    line-height: 1.3;
  }
  .rep-tool .is-block-hint {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.55rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--muted);
  }

  /* Stacked horizontal bars: captured / lost (budget) / lost (rank) */
  .rep-tool .is-bars { display: flex; flex-direction: column; gap: 0.55rem; }
  .rep-tool .is-bar-row {
    display: grid;
    grid-template-columns: 100px 1fr 38px 56px;
    align-items: center;
    gap: 0.6rem;
    font-size: 0.72rem;
  }
  .rep-tool .is-bar-label {
    color: #231F23;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .rep-tool .is-bar-track {
    display: flex;
    height: 14px;
    border-radius: 3px;
    overflow: hidden;
    background: var(--line-soft);
  }
  .rep-tool .is-bar-seg { display: block; height: 100%; }
  .rep-tool .is-seg-captured { background: #2E7D4F; }
  .rep-tool .is-seg-budget { background: #D4A52A; }
  .rep-tool .is-seg-rank { background: #B33A3A; }
  .rep-tool .is-seg-unknown { background: #00000010; }
  .rep-tool .is-bar-value {
    text-align: right;
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.7rem;
    color: #231F23;
  }
  .rep-tool .is-bar-qs { text-align: right; }

  /* Legend below the bars */
  .rep-tool .is-legend {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
    margin-top: 0.9rem;
    padding-top: 0.6rem;
    border-top: 1px solid var(--line-soft);
  }
  .rep-tool .is-legend-item {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.55rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--muted);
  }
  .rep-tool .is-legend-dot {
    display: inline-block;
    width: 9px;
    height: 9px;
    border-radius: 2px;
  }

  /* Quality Score badges — 1-10 scale, bucketed good / avg / bad */
  .rep-tool .qs-badge {
    display: inline-block;
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.6rem;
    font-weight: 500;
    padding: 2px 7px;
    border-radius: 999px;
    line-height: 1.3;
    letter-spacing: 0.02em;
    white-space: nowrap;
  }
  .rep-tool .qs-good { background: #DAEFE0; color: #2E7D4F; }
  .rep-tool .qs-avg { background: #F2EAD8; color: #8A6D2E; }
  .rep-tool .qs-bad { background: #F4D8D5; color: #B33A3A; }
  .rep-tool .qs-na { background: var(--line-soft); color: var(--muted); }

  /* Meta table — uses existing data-table styling, with cell tints for
     CTR and Frequency outliers */
  .rep-tool .is-meta-table th, .rep-tool .is-meta-table td { padding: 0.5rem 0.6rem; font-size: 0.72rem; }
  .rep-tool .cell-good { color: #2E7D4F; font-weight: 500; }
  .rep-tool .cell-warn { color: #B33A3A; font-weight: 500; }
  .rep-tool .is-meta-note {
    margin-top: 0.7rem;
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.55rem;
    letter-spacing: 0.04em;
    color: var(--muted);
    line-height: 1.5;
  }

  .rep-tool .is-empty-mini {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.6rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--muted);
    text-align: center;
    padding: 1.5rem 0;
  }

  /* ═══════════ ONE-PAGER OVERLAY ═══════════
     Full-screen modal with edit panel (left) + A4 portrait preview (right).
     The .op-page is what gets rasterised — sized at exactly the A4 ratio
     (210 × 297 mm = 1:1.4142) so the preview matches the export 1:1. */
  /* body porte la classe op-open (elle n'est jamais descendante de
     .rep-tool) — sélecteur déscopé sinon la règle ne matche jamais. */
  body.op-open { overflow: hidden; }
  .rep-tool .op-overlay {
    position: fixed; inset: 0;
    background: var(--bg);
    z-index: 150;
    display: flex;
    flex-direction: column;
  }
  .rep-tool .op-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.7rem 1.2rem;
    background: var(--surface);
    border-bottom: 1px solid var(--line);
    flex-shrink: 0;
  }
  .rep-tool .op-toolbar-title {
    font-style: italic;
    font-size: 0.9rem;
    color: var(--fg);
  }
  .rep-tool .op-toolbar-actions { display: flex; gap: 0.5rem; }
  /* Boutons de la barre d'outils du one-pager — cohérents avec le reste du site
     (icône inline + label, radius, hover) au lieu des boutons quasi-défaut. */
  .rep-tool .op-toolbar .btn {
    display: inline-flex;
    align-items: center;
    gap: 0.42rem;
    padding: 0.5rem 0.9rem;
    border-radius: 8px;
    font-family: inherit;
    font-size: 0.82rem;
    font-weight: 500;
    line-height: 1;
    cursor: pointer;
    transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
  }
  .rep-tool .op-toolbar .btn svg { width: 15px; height: 15px; flex: 0 0 auto; }
  .rep-tool .op-btn-secondary {
    background: var(--surface);
    border: 1px solid var(--line);
    color: var(--fg);
  }
  .rep-tool .op-btn-secondary:hover { border-color: var(--fg); background: var(--bg); }
  .rep-tool .op-toolbar .btn.primary {
    background: var(--fg);
    border: 1px solid var(--fg);
    color: var(--surface);
  }
  .rep-tool .op-toolbar .btn.primary:hover {
    background: var(--p-test, #2A6B30);
    border-color: var(--p-test, #2A6B30);
  }

  .rep-tool .op-body {
    flex: 1;
    display: grid;
    grid-template-columns: 320px 1fr;
    overflow: hidden;
  }
  @media (max-width: 900px) {
    .rep-tool .op-body { grid-template-columns: 1fr; }
  }

  /* Edit panel */
  .rep-tool .op-edit {
    background: var(--surface);
    border-right: 1px solid var(--line);
    overflow-y: auto;
    padding: 1rem 1.1rem 2rem;
  }
  .rep-tool .op-edit-section {
    margin-bottom: 1.4rem;
    padding-bottom: 1rem;
    border-bottom: 1px solid var(--line-soft);
  }
  .rep-tool .op-edit-section:last-child { border-bottom: none; }
  .rep-tool .op-edit-section h4 {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.6rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted);
    margin-bottom: 0.7rem;
    font-weight: 500;
  }
  .rep-tool .op-edit textarea {
    width: 100%;
    padding: 0.5rem 0.65rem;
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    background: var(--bg);
    font: inherit;
    font-size: 0.78rem;
    line-height: 1.5;
    resize: vertical;
    min-height: 120px;
  }
  .rep-tool .op-edit textarea:focus { outline: none; border-color: var(--p-test); }
  .rep-tool .op-edit select {
    width: 100%;
    padding: 0.4rem 0.6rem;
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    background: var(--bg);
    font: inherit;
    font-size: 0.78rem;
  }

  .rep-tool .op-kpi-picker {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.4rem;
  }
  .rep-tool .op-kpi-pick {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.45rem 0.6rem;
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    cursor: pointer;
    background: var(--bg);
    transition: background 0.15s, border-color 0.15s;
    font-size: 0.74rem;
    color: var(--fg);
    user-select: none;
  }
  .rep-tool .op-kpi-pick:hover { border-color: var(--fg); }
  .rep-tool .op-kpi-pick.is-on { background: var(--orchid-soft); border-color: var(--p-test); }
  .rep-tool .op-kpi-pick input { width: 13px; height: 13px; accent-color: var(--p-test); margin: 0; flex-shrink: 0; }

  /* Preview pane — gray background to mimic a print viewer */
  .rep-tool .op-preview-wrap {
    background: var(--bg);
    overflow: auto;
    padding: 1.5rem;
    display: flex;
    align-items: flex-start;
    justify-content: center;
  }
  .rep-tool .op-preview-scroll {
    max-width: 100%;
  }

  /* THE A4 page itself — fixed CSS dimensions matching A4 portrait at 96dpi.
     210 × 297 mm at 96 dpi ≈ 794 × 1123 px. We slightly downscale so the
     page comfortably fits an average laptop without forcing horizontal
     scroll, while keeping the aspect ratio strict. */
  .rep-tool .op-page {
    width: 794px;
    min-height: 1123px;
    position: relative;            /* ancre du cachet Triman (coin absolu) */
    /* Document BLANC (façon relevé officiel). */
    background: #FFFFFF;
    box-shadow: 0 4px 24px rgba(35,31,35,0.12);
    padding: 36px 44px 28px;
    display: flex;
    flex-direction: column;
    color: #231F23;
    font-size: 12px;
    line-height: 1.45;
    /* Inherit deck token scope so KPI tiles, tables, pills look on-brand */
    --line:        #2B1F0F1F;
    --line-soft:   #2B1F0F12;
    --bg:          #F3F0EA;
    --surface:     #FBFAF7;
    --muted:       #8A8276;
    --section-accent: #3D8B5C;
    font-family: var(--report-font, "Roboto", "Inter", system-ui, sans-serif);
  }

  .rep-tool .op-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 1rem;
    padding-bottom: 14px;
    margin-bottom: 18px;
    border-bottom: 1px solid var(--line);
  }
  .rep-tool .op-header-left {
    display: flex;
    align-items: center;
    gap: 14px;
    flex: 1;
    min-width: 0;
  }
  .rep-tool .op-header-logo {
    height: 42px;
    max-width: 120px;
    object-fit: contain;
    flex-shrink: 0;
  }
  .rep-tool .op-header-titles {
    flex: 1;
    min-width: 0;
  }
  .rep-tool .op-title {
    font-size: 24px;
    font-style: normal;
    font-weight: 400;
    line-height: 1.15;
    margin: 0;
    color: #231F23;
    display: flex;
    align-items: center;
    gap: 10px;
  }
  .rep-tool .op-title::before {
    content: '';
    display: inline-block;
    width: 9px;
    height: 9px;
    background: var(--section-accent);
    border-radius: 50%;
    flex-shrink: 0;
  }
  .rep-tool .op-subtitle {
    font-size: 12px;
    color: var(--muted);
    margin-top: 4px;
    font-style: italic;
  }
  .rep-tool .op-header-right {
    text-align: right;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 6px;
  }
  .rep-tool .op-header-period {
    font-family: 'JetBrains Mono', monospace;
    font-size: 11px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--muted);
  }
  .rep-tool .op-header-marks .platform-marks-footer .pm-glyph { width: 14px; height: 14px; }
  .rep-tool .op-header-marks .platform-marks-footer .pm-label { font-size: 9px; }

  /* ═══════════ EN-TÊTE « RELEVÉ DE ROAS » (façon relevé bancaire, carré,
     sobre) — marque + logo agence (haut gauche), titre + période (haut
     droite), bloc émetteur (agence) | bloc annonceur (client). ═══════════ */
  .rep-tool .op-header.op-statement {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding-bottom: 0;
    margin-bottom: 18px;
    border-bottom: none;
  }
  .rep-tool .op-st-top {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 1rem;
    padding-bottom: 12px;
    border-bottom: 2px solid #231F23;
  }
  .rep-tool .op-st-brand {
    display: flex;
    align-items: center;
    gap: 13px;
    min-width: 0;
  }
  /* Vrai logo de l'app (haut gauche) — discret. */
  .rep-tool .op-st-applogo {
    height: 18px;
    max-width: 120px;
    object-fit: contain;
    display: block;
  }
  /* Logo agence — émetteur, EN PREMIER à gauche (avant ROAS Club). */
  .rep-tool .op-st-agencylogo {
    height: 26px;
    max-width: 150px;
    object-fit: contain;
    display: block;
  }
  /* Filet fin séparant le logo agence du logo ROAS Club. */
  .rep-tool .op-st-brand-sep {
    width: 1px;
    height: 22px;
    background: var(--line, #2B1F0F1F);
    flex-shrink: 0;
  }
  .rep-tool .op-st-titlebox { text-align: right; flex-shrink: 0; }
  .rep-tool .op-st-doc {
    font-size: 17px;
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: #231F23;
    line-height: 1.1;
  }
  .rep-tool .op-st-period {
    font-family: 'JetBrains Mono', monospace;
    font-size: 11px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted);
    margin-top: 4px;
  }
  .rep-tool .op-st-sub { font-size: 11px; font-style: italic; color: var(--muted); margin-top: 2px; }
  .rep-tool .op-st-parties {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.5rem;
    padding: 12px 0 13px;
    border-bottom: 1px solid var(--line);
  }
  /* Annonceur (destinataire) décalé plus bas que l'émetteur — façon courrier. */
  .rep-tool .op-st-party-client { text-align: right; margin-top: 40px; }
  .rep-tool .op-st-role {
    font-family: 'JetBrains Mono', monospace;
    font-size: 9px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--muted);
    margin-bottom: 3px;
  }
  .rep-tool .op-st-name {
    font-size: 13px;
    font-weight: 700;
    color: #231F23;
    line-height: 1.25;
  }
  .rep-tool .op-st-line {
    font-size: 10.5px;
    line-height: 1.45;
    color: #4A4540;
  }
  .rep-tool .op-st-id {
    font-family: 'JetBrains Mono', monospace;
    font-size: 9.5px;
    letter-spacing: 0.02em;
    color: var(--muted);
  }

  /* KPI band — equal columns */
  .rep-tool .op-kpi-band {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
    gap: 10px;
    margin-bottom: 18px;
  }
  .rep-tool .op-kpi-tile {
    background: #FAF8F3;
    border: 1px solid var(--line);
    border-radius: 5px;
    padding: 10px 12px;
    display: flex;
    flex-direction: column;
    gap: 4px;
  }
  .rep-tool .op-kpi-label {
    font-family: 'JetBrains Mono', monospace;
    font-size: 9px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted);
  }
  .rep-tool .op-kpi-value {
    font-size: 22px;
    line-height: 1.1;
    color: #231F23;
    font-weight: 500;
    letter-spacing: -0.01em;
  }

  /* Charts row — donut narrow, line wide */
  .rep-tool .op-charts {
    display: grid;
    grid-template-columns: 220px 1fr;
    gap: 12px;
    margin-bottom: 16px;
  }
  .rep-tool .op-chart-card {
    background: #FCFBF8;
    border: 1px solid var(--line);
    border-radius: 5px;
    padding: 10px 12px;
    display: flex;
    flex-direction: column;
  }
  .rep-tool .op-chart-title {
    font-style: italic;
    font-size: 11px;
    color: var(--muted);
    margin-bottom: 6px;
  }
  .rep-tool .op-chart-canvas-wrap {
    flex: 1;
    position: relative;
    min-height: 150px;
    height: 150px;
  }

  /* Table */
  .rep-tool .op-table-section { margin-bottom: 14px; }
  .rep-tool .op-section-title {
    font-style: italic;
    font-size: 12px;
    color: var(--muted);
    margin-bottom: 6px;
    padding-bottom: 4px;
    border-bottom: 1px solid var(--line-soft);
  }
  .rep-tool .op-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 11px;
  }
  .rep-tool .op-table th {
    text-align: left;
    font-family: inherit;
    font-style: italic;
    font-weight: 400;
    font-size: 10px;
    color: var(--muted);
    padding: 6px 6px 6px 0;
    border-bottom: 1px solid var(--line);
  }
  .rep-tool .op-table td {
    padding: 5px 6px 5px 0;
    border-bottom: 1px solid var(--line-soft);
  }
  .rep-tool .op-table .num { text-align: right; font-variant-numeric: tabular-nums; }
  .rep-tool .op-table tbody tr:last-child td { border-bottom: none; }

  /* Synthesis text block */
  .rep-tool .op-synthesis-block {
    margin-bottom: 14px;
    flex: 1;
  }
  .rep-tool .op-synthesis-text {
    font-size: 11.5px;
    line-height: 1.55;
    color: #231F23;
    background: rgba(255,255,255,0.4);
    border-left: 3px solid var(--section-accent);
    padding: 10px 14px;
    border-radius: 0 4px 4px 0;
  }

  /* Footer */
  .rep-tool .op-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding-top: 10px;
    border-top: 1px solid var(--line-soft);
    font-family: 'JetBrains Mono', monospace;
    font-size: 9px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted);
    margin-top: auto;
  }
  .rep-tool .op-footer-left, .rep-tool .op-footer-right {
    display: flex;
    align-items: center;
    gap: 8px;
  }
  /* Mentions légales d'éditeur — fine print tout en bas (statique, identique
     sur tous les relevés). Très petit, justifié, façon pied de relevé bancaire. */
  /* Cachet « vérifié par ROAS Club » — contenu partagé (one-pager + slides deck). */
  .rep-tool .op-vmark-text { font-style: italic; color: var(--muted); white-space: nowrap; }
  .rep-tool .op-vmark-logo { width: auto; object-fit: contain; }
  /* Coche verte — affichée UNIQUEMENT sur l'état « vérifiées » (sceau de
     confiance) ; absente de l'état « déclarées ». Taillée par contexte. */
  .rep-tool .op-vmark-check { display: inline-flex; align-items: center; flex-shrink: 0; }
  .rep-tool .op-vmark-check svg { width: 11px; height: 11px; display: block; }
  .rep-tool .op-signature .op-vmark-check svg { width: 12px; height: 12px; }
  .rep-tool .op-verified-mark .op-vmark-check svg { width: 10px; height: 10px; }
  /* ONE-PAGER — barre de bas : QR (gauche) · cachet vérifié + Triman (droite). */
  .rep-tool .op-botbar {
    margin-top: auto;
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    gap: 12px;
    padding-top: 16px;
  }
  .rep-tool .op-botbar + .op-legal { margin-top: 0; }
  .rep-tool .op-qr { width: 46px; height: 46px; object-fit: contain; flex-shrink: 0; }
  .rep-tool .op-botbar-right { display: flex; align-items: flex-end; gap: 12px; }
  /* Logo Triman — coin bas-droite, dans la marge (absolu / op-page relatif). */
  .rep-tool .op-triman { position: absolute; right: 12px; bottom: 12px; height: 54px; width: auto; object-fit: contain; }
  /* Code document aléatoire — marge EXTRÊME-GAUCHE, partie basse (un peu sous le
     milieu). writing-mode vertical → caractères tournés 90° : lisible seulement
     en mettant le document à l'horizontale. Discret (gris marge). */
  .rep-tool .op-doccode {
    position: absolute;
    left: 13px;          /* dans la marge gauche (padding op-page = 44px) */
    top: 58%;            /* un peu plus bas que le milieu → partie basse */
    writing-mode: vertical-rl;
    font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
    font-size: 7px;
    font-weight: 600;
    letter-spacing: 0.22em;
    color: #B7B0A4;
    white-space: nowrap;
    pointer-events: none;
    user-select: all;
  }
  /* Cachet « vérifié par ROAS Club » (dans la barre de bas du one-pager). */
  .rep-tool .op-signature { display: inline-flex; align-items: center; gap: 7px; }
  .rep-tool .op-signature .op-vmark-text { font-size: 9px; }
  .rep-tool .op-signature .op-vmark-logo { height: 15px; }
  /* Variante SLIDE DECK : bas droite de chaque diapositive (dans le footer). */
  .rep-tool .op-verified-mark { display: inline-flex; align-items: center; gap: 5px; }
  .rep-tool .op-verified-mark .op-vmark-text { font-size: 8px; }
  .rep-tool .op-verified-mark .op-vmark-logo { height: 11px; }
  /* Cover / closing : cachet en absolu, coin bas-droite. */
  .rep-tool .op-verified-abs { position: absolute; right: 44px; bottom: 16px; }

  .rep-tool .op-legal {
    margin-top: auto;
    padding-top: 8px;
    /* Dégage le coin bas-droite où vit le cachet Triman (absolu). */
    padding-right: 48px;
    border-top: 1px solid var(--line-soft);
    font-size: 6.8px;
    line-height: 1.5;
    letter-spacing: 0.01em;
    color: #9A938A;
    text-align: justify;
  }

  .rep-tool .op-empty {
    text-align: center;
    color: var(--muted);
    font-family: 'JetBrains Mono', monospace;
    font-size: 10px;
    padding: 18px 0;
  }

  /* ═══════════ PAGE 2 — « Commission sur ROAS » ═══════════ */
  .rep-tool .op-comm-note {
    font-size: 11px;
    color: #4A4540;
    margin-bottom: 14px;
    padding: 8px 10px;
    background: #FAF8F3;
    border: 1px solid var(--line);
    border-radius: 5px;
  }
  .rep-tool .op-comm-note-base {
    display: block;
    margin-top: 4px;
    font-size: 9.5px;
    color: var(--muted);
  }
  .rep-tool .op-comm-table .op-table { font-size: 11px; }
  .rep-tool .op-comm-table th.num,
  .rep-tool .op-comm-table td.num { text-align: right; white-space: nowrap; }
  .rep-tool .op-comm-total td {
    border-top: 2px solid #231F23;
    font-weight: 600;
    padding-top: 6px;
  }
  .rep-tool .op-comm-due {
    margin-top: 16px;
    padding: 14px 18px;
    background: #231F23;
    color: #fff;
    border-radius: 6px;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 2px;
  }
  .rep-tool .op-comm-due-label {
    font-family: 'JetBrains Mono', monospace;
    font-size: 9px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    opacity: 0.72;
  }
  .rep-tool .op-comm-due-value { font-size: 24px; font-weight: 700; letter-spacing: -0.01em; }
  .rep-tool .op-comm-due-sub { font-size: 11px; opacity: 0.72; }

  /* ═══════════ LIVRABLE — sidebar gauche RÉTRACTABLE + grand aperçu droite.
     Sidebar = conteneur transparent + blocs en cartes standard (var(--surface)
     + var(--line) + var(--r-md)), cohérent avec les autres outils. ═══════════ */
  .rep-tool .rep-deliver {
    display: flex;
    align-items: flex-start;
    gap: 18px;
    min-height: 72vh;
  }
  .rep-tool .rep-deliver-side {
    flex: 0 0 264px;
    width: 264px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    max-height: 84vh;
    overflow-y: auto;
    padding-right: 2px;
    transition: margin-left 0.18s ease, opacity 0.16s ease;
  }
  .rep-tool .rep-deliver.side-collapsed .rep-deliver-side {
    margin-left: -282px;
    opacity: 0;
    pointer-events: none;
  }
  .rep-tool .rep-deliver-main {
    flex: 1 1 auto;
    min-width: 0;
    position: relative;
    container-type: inline-size;
  }

  .rep-tool .rep-side-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
  .rep-tool .rep-side-head .ey { margin: 0 0 2px; }
  .rep-tool .rep-side-title { font-size: 0.92rem; font-weight: 600; line-height: 1.2; color: var(--fg); }
  .rep-tool .rep-side-title em { font-style: italic; font-weight: 400; }
  .rep-tool .rep-side-collapse, .rep-tool .rep-side-expand {
    appearance: none; cursor: pointer; border: 1px solid var(--line); background: var(--surface);
    color: var(--muted); border-radius: var(--r-sm, 6px); width: 26px; height: 26px; flex-shrink: 0;
    font-size: 13px; line-height: 1; display: inline-flex; align-items: center; justify-content: center;
  }
  .rep-tool .rep-side-collapse:hover, .rep-tool .rep-side-expand:hover { color: var(--fg); border-color: var(--fg); }
  .rep-tool .rep-side-expand {
    position: absolute; top: 10px; left: 10px; z-index: 5; display: none;
    box-shadow: 0 1px 5px rgba(35,31,35,0.14);
  }
  .rep-tool .rep-deliver.side-collapsed .rep-side-expand { display: inline-flex; }

  /* Bascule d'aperçu (one-pager / présentation) — segmented, façon app. */
  .rep-tool .rep-side-seg {
    display: flex; gap: 4px; background: var(--bg); border: 1px solid var(--line);
    border-radius: var(--r-sm, 6px); padding: 3px;
  }
  .rep-tool .rep-seg-btn {
    flex: 1; appearance: none; cursor: pointer; border: none; background: transparent;
    border-radius: 4px; padding: 8px 6px; font-size: 0.72rem; font-weight: 500; color: var(--muted);
  }
  .rep-tool .rep-seg-btn.is-on { background: var(--surface); color: var(--fg); box-shadow: 0 1px 3px rgba(35,31,35,0.1); }

  /* Blocs de la sidebar = cartes standard (mêmes tokens que .config-card). */
  .rep-tool .rep-side-block {
    display: flex; flex-direction: column; gap: 8px;
    background: var(--surface); border: 1px solid var(--line);
    border-radius: var(--r-md, 10px); padding: 12px;
  }
  .rep-tool .rep-side-label {
    font-family: 'JetBrains Mono', monospace; font-size: 0.58rem; letter-spacing: 0.08em;
    text-transform: uppercase; color: var(--muted);
  }
  .rep-tool .rep-side-count { color: var(--fg); }
  .rep-tool .rep-side-nav-block { flex: 1 1 auto; min-height: 0; padding: 8px 6px; }
  .rep-tool .rep-side-nav-block .preview-nav { max-height: none; width: 100%; }

  /* Grand aperçu (presque plein écran) — cadre neutre type visionneuse. */
  .rep-tool .rep-main-scroll {
    max-height: 84vh; overflow: auto; background: var(--bg); border: 1px solid var(--line);
    border-radius: var(--r-md, 10px); padding: 1.4rem;
    display: flex; flex-direction: column; align-items: stretch;
  }

  /* Deck dans le grand panneau : zoom responsive, sans cadre interne. */
  .rep-tool .rep-main-scroll .preview-pages {
    zoom: 0.62; max-height: none; overflow: visible; background: transparent;
    padding: 0; border-radius: 0; gap: 1.5rem; align-items: center;
  }
  @container (min-width: 760px)  { .rep-tool .rep-main-scroll .preview-pages { zoom: 0.72; } }
  @container (min-width: 1000px) { .rep-tool .rep-main-scroll .preview-pages { zoom: 0.85; } }
  @container (min-width: 1240px) { .rep-tool .rep-main-scroll .preview-pages { zoom: 0.95; } }

  /* One-pager dans le grand panneau : la scène prend toute la largeur (sinon le
     container-type la fait s'effondrer à 0), la page est centrée + agrandie. */
  .rep-tool .rep-main-scroll .preview-onepager-stage {
    width: 100%; background: transparent; padding: 0; overflow-x: auto;
  }
  .rep-tool .rep-main-scroll .preview-onepager-stage .op-page { zoom: 0.72; }
  @container (min-width: 900px)  { .rep-tool .rep-main-scroll .preview-onepager-stage .op-page { zoom: 0.85; } }
  @container (min-width: 1200px) { .rep-tool .rep-main-scroll .preview-onepager-stage .op-page { zoom: 0.98; } }

  /* Petit écran : sidebar empilée au-dessus. */
  @media (max-width: 720px) {
    .rep-tool .rep-deliver { flex-direction: column; }
    .rep-tool .rep-deliver-side { flex-basis: auto; width: auto; max-height: none; }
    .rep-tool .rep-deliver.side-collapsed .rep-deliver-side { margin-left: 0; display: none; }
  }

  /* During rasterising hide the chrome — only the A4 page survives */
  .rep-tool body.rasterizing .op-toolbar, .rep-tool body.rasterizing .op-edit { visibility: hidden; }

  /* The deliver export row — when 3 buttons, cap the one-pager column */
  .rep-tool .deliver-export-row.deliver-export-row-3 {
    grid-template-columns: 1fr 1fr 1fr;
  }
  @media (max-width: 720px) {
    .rep-tool .deliver-export-row.deliver-export-row-3 { grid-template-columns: 1fr; }
  }
  .rep-tool .deliver-export-btn-onepager {
    background: var(--surface);
    color: var(--fg);
    border: 1px solid var(--p-test);
  }
  .rep-tool .deliver-export-btn-onepager:hover {
    background: var(--orchid-soft);
    border-color: var(--p-test);
  }
  /* Case « Commission sur ROAS (p.2) » sous le bouton one-pager — alignée sur le
     reste de la sidebar export (mono discret, checkbox accent). */
  .rep-tool .rep-op-comm-toggle {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    margin-top: 0.5rem;
    padding: 0.1rem 0.1rem;
    font-size: 0.74rem;
    line-height: 1.35;
    color: var(--muted);
    cursor: pointer;
  }
  .rep-tool .rep-op-comm-toggle input { margin-top: 1px; accent-color: var(--p-test); cursor: pointer; flex: 0 0 auto; }
  .rep-tool .rep-op-comm-toggle:hover { color: var(--fg); }

  /* ═══════════ COVER & CLOSING SLIDES — title slides with centered logo group ═══════════ */
  .rep-tool .preview-page.preview-page-cover {
    /* Same A4 landscape dimensions as content slides (locked at 905px
       in the parent rule). The override here only adjusts padding +
       layout — content is centered vertically thanks to flex: 1. */
    padding: 3rem 2.6rem 2rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    position: relative;
  }
  .rep-tool .preview-page-cover .cover-actions {
    position: absolute;
    top: 1rem;
    right: 1rem;
  }
  .rep-tool .cover-stack {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1.2rem;
    padding: 2rem 0;
    flex-wrap: wrap;
  }
  .rep-tool .cover-client-logo {
    max-height: 110px;
    max-width: 380px;
    width: auto;
    height: auto;
    object-fit: contain;
  }
  .rep-tool .cover-id {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.65rem;
  }
  .rep-tool .cover-client-name {
    font-size: 2.4rem;
    font-style: italic;
    font-weight: 400;
    letter-spacing: -0.01em;
    color: #231F23;
  }
  .rep-tool .cover-period {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.82rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted, #8A8276);
  }
  .rep-tool .cover-sep {
    display: inline-block;
    width: 1px;
    height: 56px;
    background: #2B1F0F33;
  }

  /* ═══════════ SOURCES & MÉTHODOLOGIE (couverture) — rend le rapport
     auditable : provenance, période, marge, lecture seule. Bloc compact
     entre le bloc client et le footer. ═══════════ */
  .rep-tool .cover-methodo {
    width: 100%;
    max-width: 620px;
    margin: 0 auto;
    padding-top: 1.1rem;
    border-top: 1px solid #2B1F0F22;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
  }
  .rep-tool .cover-methodo-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.55rem;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: #5B4A2E;
    background: #2B1F0F0D;
    border: 1px solid #2B1F0F1F;
    border-radius: 999px;
    padding: 0.28rem 0.7rem;
  }
  .rep-tool .cover-methodo-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 0.55rem 1.4rem;
    width: 100%;
  }
  .rep-tool .cover-methodo-grid > div {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
    text-align: center;
  }
  .rep-tool .cover-methodo-grid .cmk-k {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.5rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
  }
  .rep-tool .cover-methodo-grid .cmk-v {
    font-size: 0.78rem;
    font-weight: 500;
    color: #231F23;
    overflow-wrap: anywhere;
  }
  .rep-tool .cover-methodo-note {
    font-size: 0.62rem;
    line-height: 1.45;
    color: var(--muted);
    text-align: center;
    max-width: 560px;
  }

  /* ═══════════ GLOSSAIRE (page de fin) — vocabulaire commun CFO/CMO.
     2 colonnes de définitions term→desc + repère méthodo en pied. ═══════════ */
  .rep-tool .cover-glossary {
    width: 100%;
    max-width: 1040px;
    margin: 0 auto;
    border-top: 1px solid #2B1F0F22;
    padding-top: 1.1rem;
  }
  .rep-tool .cover-glossary-title {
    font-size: 0.95rem;
    font-weight: 600;
    color: #231F23;
    margin-bottom: 0.8rem;
    text-align: center;
  }
  .rep-tool .cover-glossary-list {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.55rem 2.2rem;
    margin: 0;
  }
  .rep-tool .cgl-item {
    display: grid;
    grid-template-columns: 116px 1fr;
    gap: 0.6rem;
    align-items: baseline;
  }
  .rep-tool .cgl-item dt {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.6rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--section-accent, #3D8B5C);
    font-weight: 600;
  }
  .rep-tool .cgl-item dd {
    margin: 0;
    font-size: 0.68rem;
    line-height: 1.4;
    color: #4A4540;
  }
  .rep-tool .cover-glossary-foot {
    margin-top: 0.95rem;
    text-align: center;
    font-size: 0.62rem;
    font-style: italic;
    color: var(--muted);
  }

  /* ═══════════ PLATFORM MARKS — stylised SVG glyphs + label, used on
     cover slides (large) and per-page footer (small) ═══════════ */
  .rep-tool .platform-marks {
    display: inline-flex;
    align-items: center;
    gap: 0.7rem;
  }
  .rep-tool .platform-mark {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
  }
  .rep-tool .pm-glyph {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
  }
  .rep-tool .pm-glyph svg { display: block; width: 100%; height: 100%; }
  .rep-tool .pm-label {
    font-style: italic;
    font-weight: 400;
    color: #231F23;
    line-height: 1;
    white-space: nowrap;
  }
  .rep-tool .pm-sep {
    display: inline-block;
    width: 3px;
    height: 3px;
    background: #2B1F0F44;
    border-radius: 50%;
  }
  /* Large variant for cover slides */
  .rep-tool .platform-marks-cover .pm-glyph { width: 38px; height: 38px; }
  .rep-tool .platform-marks-cover .pm-label { font-size: 1.5rem; letter-spacing: -0.005em; }
  .rep-tool .platform-marks-cover { gap: 1rem; }
  /* Small variant for per-page footer */
  .rep-tool .platform-marks-footer .pm-glyph { width: 16px; height: 16px; }
  .rep-tool .platform-marks-footer .pm-label {
    font-style: normal;
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.55rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted);
  }
  .rep-tool .platform-marks-footer { gap: 0.45rem; }

  /* ═══════════ FOOTER — split in two halves, bottom of every slide ═══════════ */
  .rep-tool .preview-page-footer {
    justify-content: space-between;
  }
  .rep-tool .preview-page-cover .preview-page-footer {
    width: 100%;
    margin-top: 0;
    padding-top: 1rem;
  }
  .rep-tool .pf-left, .rep-tool .pf-right {
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    flex-wrap: nowrap;
    min-width: 0;
  }
  .rep-tool .pf-left { justify-self: start; }
  /* pf-right empilé : ligne métadonnées (client · marques · période) PUIS cachet
     « vérifié par ROAS Club » en dessous, le tout aligné à droite. */
  .rep-tool .pf-right { justify-self: end; margin-left: auto; flex-direction: column; align-items: flex-end; gap: 3px; }
  .rep-tool .pf-right-line { display: inline-flex; align-items: center; gap: 0.55rem; flex-wrap: nowrap; }
  .rep-tool .pf-logo-agency { height: 18px; max-width: 90px; }
  .rep-tool .pf-logo-client { height: 22px; max-width: 110px; }
  .rep-tool .pf-buyer {
    font-family: inherit;
    font-style: italic;
    text-transform: none;
    letter-spacing: 0;
    font-size: 0.8rem;
    color: #231F23;
    line-height: 1;
    padding-left: 0.4rem;
    border-left: 1px solid #2B1F0F22;
  }

  /* ═══════════ Hide wizard chrome during rasterisation ═══════════
     The Visible/Masquée toggle button and the ↻ Régénérer (IA) button are
     wizard UI — they must not appear in the rasterised PDF/PPTX. We hide
     them via a body class set immediately before html2canvas runs and
     cleared immediately after. visibility:hidden preserves layout so the
     deck doesn't shift mid-capture. */
  .rep-tool body.rasterizing .preview-page .pp-action, .rep-tool body.rasterizing .preview-page .insight-regen-btn, .rep-tool body.rasterizing .preview-page-actions { visibility: hidden; }
  /* During PDF/PPTX rasterizing, lift the visual zoom so html2canvas
     captures pages at their native 1280×905 logical resolution. */
  .rep-tool body.rasterizing .preview-pages {
    zoom: 1;
  }

  /* ════════════════════════════════════════════════════════════════════
     PRINT — used by exportPDF() and exportOnePagerPDF() via window.print().
     The export functions append a `<div class="print-clone-root">` to
     the document body containing cloned preview-pages, and toggle one of
     two body classes depending on the orientation needed.

     The strategy: in print mode, hide every direct child of the document
     body EXCEPT our clone container, which gets sized to A4. The clones
     themselves keep their original 1280×905 inline dimensions — print
     scaling makes them fit the A4 sheet automatically.

     IMPORTANT: keep this comment free of literal HTML tags like the body
     tag — the upstream integrate_reporting.py pipeline uses a regex to
     extract body HTML, and a literal opening body tag in a CSS comment
     can match before the real body element, causing the rest of the
     stylesheet to leak into the page text. Use prose ("the document
     body", "body element") rather than tag literals.
     ════════════════════════════════════════════════════════════════════ */
  /* Le clone d'impression est attaché à <body> (HORS #rep-tool) → les règles
     ci-dessous NE doivent PAS être scopées `.rep-tool` (sinon elles ne matchent
     jamais → app non masquée + clone non stylé = pages blanches). Le clone porte
     lui-même la classe `rep-tool` (cf. exportPDF) pour hériter des styles de base
     des slides. Hors impression, on le sort de l'écran (flash de 36 pages). */
  .print-clone-root { position: absolute; left: -100000px; top: 0; }

  @media print {
    /* When a print is in progress, hide every direct child of the
       document body except the clone root. Single targeted selector so
       CSS-injected stuff (modals, etc) is unaffected. */
    body.printing-deck > *:not(.print-clone-root), body.printing-onepager > *:not(.print-clone-root) {
      display: none !important;
    }
    /* The clone root itself just lays out its children — no padding,
       no extra spacing. Each child is one page. */
    .print-clone-root {
      display: block !important;
      position: static !important; /* annule l'off-screen écran */
      background: #FFFFFF;
      margin: 0 !important;
      padding: 0 !important;
    }

    /* ── Deck export: A4 landscape (297 × 210 mm) ───────────────────
       The original .preview-page is laid out at 1280×905 px (matches
       on-screen 16:9 wide). To make ONE preview-page fit ONE A4 sheet
       without the browser breaking it across pages, we:
        - lock the cloned page to the A4 dimensions in mm
        - scale its content area down so 1280px content → 297mm wide
        - force a page break after each one
       The scale ratio is 297mm / 1280px ≈ 0.2227 (with 1px = 0.2646mm,
       this matches: 1280 × 0.2646 / 1.187 ≈ 297). The browser does
       the math at print resolution so output stays sharp. */
    .print-clone-root .preview-page {
      width: 297mm !important;
      height: 167mm !important;        /* 16:9 de 297mm (slides widescreen) */
      min-height: 167mm !important;
      max-height: 167mm !important;
      margin: 0 !important;
      padding: 0 !important;          /* Padding moves into the inner */
      box-shadow: none !important;
      border-radius: 0 !important;
      page-break-after: always;
      break-after: page;
      page-break-inside: avoid;
      break-inside: avoid;
      overflow: hidden !important;
      background: #FFFFFF !important;
      box-sizing: border-box !important;
      /* The "scale" comes from rebuilding the page at native A4 width.
         transform: scale() doesn't reduce the layout box, so we use
         zoom which Chrome supports for print and which DOES reduce the
         flow box. The ratio: A4 landscape is ~1123px at 96dpi, original
         page is 1280px wide → zoom ≈ 0.877 to fit. We set zoom on the
         preview-page itself so its 1280px-wide internal flex/grid
         layout shrinks proportionally. */
      zoom: 0.877;
    }
    .print-clone-root .preview-page:last-child {
      page-break-after: auto;
      break-after: auto;
    }

    /* ── One-pager export: A4 portrait (210 × 297 mm) ───────────────
       Same idea but portrait. The .op-page is built at 794×1123 px
       which is exactly A4 at 96dpi, so we don't need to scale. */
    .print-clone-root .op-page {
      width: 210mm !important;
      min-height: 297mm !important;
      max-height: 297mm !important;
      margin: 0 !important;
      box-shadow: none !important;
      /* Saut de page entre les pages du one-pager (page 1 + page 2 commission). */
      page-break-after: always;
      break-after: page;
      page-break-inside: avoid;
      break-inside: avoid;
      overflow: hidden !important;
      background: #FFFFFF !important;
      box-sizing: border-box !important;
    }
    .print-clone-root .op-page:last-child {
      page-break-after: auto;
      break-after: auto;
    }
  }

  /* @page is the print-page-box rule. We set the dimensions and remove
     the browser's default 0.5"-1" margins. Body class scoping inside
     @page isn't supported across browsers so we declare two @page rules
     and let the right one apply via a body-class-driven media query —
     except @page can't go inside @media in standard CSS. The pragma
     here: declare landscape as the default. The one-pager portrait
     case still works because the .op-page itself is portrait-sized
     and the user can pick portrait in the print dialog if needed. */
  @page {
    size: A4 landscape;
    margin: 0;
  }



  /* ═══════════════════════════════════════════════════════════════════════
     REPORTING TOOL — scoped CSS
     Every selector below is prefixed with `.rep-tool` so Reporting's
     styles only apply inside #view-reporting. Globals (:root, *, html,
     body) are stripped — variant chrome owns those.
     ═══════════════════════════════════════════════════════════════════════ */

  /* Layout overrides for the embedded Reporting tool. Reporting was
     designed as a standalone fullscreen app (its #app wrapper is
     height:100vh which would push content below the variant's chrome).
     Here we constrain it to the available view-reporting space. */
  .view-reporting #reporting-root {
    height: 100%;
    overflow: hidden;
  }
  .rep-tool {
    height: 100%;
    display: block;
  }
  .rep-tool #app {
    height: 100% !important;
    overflow: hidden;
  }

  /* Slim sub-toolbar that replaces Reporting's stripped <header>.
     Hosts the step pills + prev/next nav buttons, sits ABOVE the
     stage content but BELOW the variant's chrome topbar. Visually
     subordinate so the variant's tab bar reads as the canonical
     navigation. */
  .rep-tool .rep-substep {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.5rem 0.6rem 0.8rem;
    border-bottom: 1px solid var(--line-soft);
    margin-bottom: 1rem;
    flex-wrap: wrap;
  }
  .rep-tool .rep-substep .topbar-steps,
  .rep-tool .rep-substep .topbar-actions {
    display: flex;
    align-items: center;
    gap: 0.4rem;
  }
  .rep-tool .rep-substep .topbar-actions {
    margin-left: auto;
  }

  /* ─ Slide preview viewer (deliver step) ─
     Goal: slides display large, the two-column layout (nav + slides)
     reads as a balanced pair, no document-height ballooning.
     Strategy:
       - Let .stage-inner go full-width when slides are present
         (`:has(.preview-shell)`), so the slide column has more room
         than the original 1100px cap (which assumed standalone
         Reporting's chrome).
       - Use container queries on .preview-shell so slide zoom adapts
         to whatever column width the iframe actually gives us, from
         narrow (~600px) to wide (~1400px) iframes.
       - Cap the sidebar height with a fixed pixel value (not vh) so
         it doesn't grow with the iframe-resize feedback loop.
       - Match sidebar height to viewer height for visual balance.
       - Drop the hard border, use a subtle warm background tint that
         echoes the slide page background — the viewer reads as a
         "frame around the slides" rather than a separate widget. */

  /* Free the stage from its 1100px cap when the deliver step is on,
     but only modestly — going to 100% on a wide iframe (2000px+)
     made the layout sprawl. 1300px gives slides more breathing room
     than the original Reporting cap without losing the centered
     "card" feel of the panel pair. */
  .rep-tool .stage-inner:has(.preview-shell) {
    max-width: 1300px;
  }
  /* Écran « Aperçu & export » (nouveau layout 2 colonnes) : presque plein
     écran — on lève le plafond pour donner toute la largeur à l'aperçu. */
  .rep-tool .stage-inner:has(.rep-deliver) {
    max-width: none;
  }

  /* Container-query context so slide zoom responds to column width.
     `align-items: stretch` overrides the original `start` so both
     columns fill the grid row equally. `grid-template-rows: 800px`
     pins the row to exactly that height — both nav and viewer end
     up at 800px tall, scrolling internally. This is more robust
     than relying on each child's max-height alone (sticky positioning
     on the sidebar can leak past max-height in some grid contexts). */
  .rep-tool .preview-shell {
    container-type: inline-size;
    align-items: stretch;
    grid-template-rows: 800px;
  }

  /* Sidebar: drop the sticky positioning that's leaking past
     max-height and any vh-based constraint that interacts badly
     with the postMessage iframe-resize loop. Position: relative is
     enough now that the grid row pins the height. The original
     overflow-y: auto on .preview-nav stays, so internal scroll
     still works for long section lists. */
  .rep-tool .preview-nav {
    position: relative;
    max-height: 800px;
  }

  /* Slide viewer: scrollable, soft warm tint matching the slides,
     no border (replaced by a subtle inner shadow at the scroll edges
     that gives a sense of "more above/below"). */
  .rep-tool .preview-pages {
    zoom: 0.5;                          /* base — bumped up via @container below */
    max-height: 800px;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 1.2rem 1rem;
    background: #EFE9DC;                /* warm tint matching slide page bg */
    border-radius: 10px;
    scrollbar-gutter: stable;
  }

  /* Slide pages must not shrink to fit the constrained viewer.
     Without this, a flex-column parent + max-height squashes its
     children proportionally — slides become thin horizontal stripes
     instead of full-height pages. flex-shrink: 0 keeps each slide
     at its authored 905px height; the parent's overflow-y: auto
     handles the scroll. */
  .rep-tool .preview-pages > .preview-page {
    flex-shrink: 0;
  }

  /* Responsive zoom — each tier ≈ 200px of extra column width.
     Native slide is 1280px wide; we want zoom × 1280 ≤ column width.
     With stage-inner capped at 1300px, the slide column tops out at
     ~1060px (1300 - 220 sidebar - 1.2rem gap), so the upper tiers
     (above 0.65) rarely trigger. Lower tiers cover narrower iframes:
       column 700px  → zoom 0.55 → slide 704px
       column 900px  → zoom 0.65 → slide 832px
       column 1100px → zoom 0.7  → slide 896px (caps below 1.0 here) */
  @container (min-width: 700px) {
    .rep-tool .preview-pages { zoom: 0.55; }
  }
  @container (min-width: 900px) {
    .rep-tool .preview-pages { zoom: 0.65; }
  }
  @container (min-width: 1100px) {
    .rep-tool .preview-pages { zoom: 0.7; }
  }

  /* ═══════════════ MODE PRÉSENTATION (Keynote web, style luxgap) ═══════════════
     Plein écran, une slide à la fois, apparition des éléments en cascade.
     Construit dans #rep-tool (cf. enterPresentMode) → les sélecteurs .rep-tool
     s'appliquent. Chaque .dp-slide est un clone de .preview-page (1280×905)
     mis à l'échelle via --dp-scale pour remplir l'écran. La barre/les bords/la
     progression sont SIBLINGS de .dp-stage (jamais enfants) : .dp-stage est
     `transform`é, ce qui re-ancrerait des position:fixed descendants. */
  body.dp-presenting { overflow: hidden; }

  .rep-tool .dp-overlay {
    position: fixed;
    inset: 0;
    z-index: 4000;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    background: radial-gradient(125% 125% at 50% 0%, #2c2a33 0%, #1a181f 55%, #0f0e13 100%);
    opacity: 0;
    transition: opacity 0.28s ease;
    --dp-scale: 1;
    --dp-accent: #3D8B5C;
  }
  .rep-tool .dp-overlay.dp-shown { opacity: 1; }

  .rep-tool .dp-stage {
    position: relative;
    width: 1280px;
    height: 720px; /* 16:9 — doit suivre .preview-page */
    flex: none;
    transform: scale(var(--dp-scale));
    transform-origin: center center;
  }
  .rep-tool .dp-slide {
    position: absolute;
    inset: 0;
    margin: 0;
    border-radius: 14px;
    box-shadow: 0 30px 90px rgba(0, 0, 0, 0.55), 0 2px 10px rgba(0, 0, 0, 0.4);
  }
  /* Spécificité 0,3,0 > base .rep-tool .preview-page (0,2,0) → masque les
     slides non-courantes ; la courante garde le display:flex de base. */
  .rep-tool .dp-slide:not(.dp-current) { display: none; }

  /* ── Apparition en cascade des unités [data-reveal] ── */
  .rep-tool .dp-slide [data-reveal] {
    opacity: 0;
    transform: translateY(22px);
    will-change: opacity, transform;
  }
  .rep-tool .dp-slide.dp-current.dp-live [data-reveal] {
    opacity: 1;
    transform: none;
    transition: opacity 0.5s ease, transform 0.58s cubic-bezier(0.18, 0.7, 0.2, 1);
    transition-delay: calc(var(--ri, 0) * 70ms);
  }
  @media (prefers-reduced-motion: reduce) {
    .rep-tool .dp-slide [data-reveal] { opacity: 1; transform: none; }
    .rep-tool .dp-slide.dp-current.dp-live [data-reveal] { transition: none; transition-delay: 0s; }
  }

  /* ── Barre de progression fine en haut ── */
  .rep-tool .dp-progress {
    position: fixed;
    top: 0;
    left: 0;
    height: 3px;
    width: 0;
    background: var(--dp-accent, #3D8B5C);
    box-shadow: 0 0 12px var(--dp-accent, #3D8B5C);
    z-index: 4010;
    transition: width 0.45s cubic-bezier(0.2, 0.7, 0.2, 1);
  }

  /* ── Zones de clic invisibles sur les bords (préc/suiv) ── */
  .rep-tool .dp-edge {
    position: fixed;
    top: 0;
    bottom: 64px; /* laisse la barre de contrôle cliquable */
    width: 16%;
    max-width: 220px;
    z-index: 4005;
    padding: 0;
    border: none;
    background: transparent;
    cursor: pointer;
  }
  .rep-tool .dp-edge-prev { left: 0; }
  .rep-tool .dp-edge-next { right: 0; }
  .rep-tool .dp-edge:focus-visible { outline: 2px solid rgba(255, 255, 255, 0.4); outline-offset: -4px; }

  /* ── Barre de contrôle flottante ── */
  .rep-tool .dp-bar {
    position: fixed;
    left: 50%;
    bottom: 22px;
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 6px 8px;
    background: rgba(18, 16, 22, 0.72);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 999px;
    box-shadow: 0 8px 30px rgba(0, 0, 0, 0.45);
    z-index: 4011;
    opacity: 0;
    transition: opacity 0.3s ease;
  }
  .rep-tool .dp-overlay:hover .dp-bar { opacity: 1; }
  .rep-tool .dp-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 999px;
    border: none;
    background: transparent;
    color: rgba(255, 255, 255, 0.85);
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease;
  }
  .rep-tool .dp-btn:hover { background: rgba(255, 255, 255, 0.14); color: #fff; }
  .rep-tool .dp-btn:disabled { opacity: 0.3; cursor: default; }
  .rep-tool .dp-btn:disabled:hover { background: transparent; }
  .rep-tool .dp-count {
    font-family: 'JetBrains Mono', 'Courier New', monospace;
    font-size: 12px;
    color: rgba(255, 255, 255, 0.82);
    padding: 0 10px;
    min-width: 58px;
    text-align: center;
    letter-spacing: 0.02em;
  }
  .rep-tool .dp-bar-sep {
    width: 1px;
    height: 20px;
    background: rgba(255, 255, 255, 0.16);
    margin: 0 3px;
  }
