/* Inter, servie par le portail lui-même (police variable, graisses 100 à 900,
   licence SIL OFL 1.1 : fonts/LICENSE-Inter-OFL.txt). Avant, elle venait de
   Google Fonts : chaque visite envoyait l'adresse IP du partenaire chez Google
   (Loi 25), et la politique de contenu devait ouvrir deux domaines externes.
   Source : @fontsource-variable/inter 5.3.0. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url("fonts/inter-latin-ext-wght-normal.woff2") format("woff2-variations");
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url("fonts/inter-latin-wght-normal.woff2") format("woff2-variations");
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* ============================================================================
   Fuel — Portail partenaires. Thème clair.

   Les jetons de couleur des séries viennent de la palette validée du design
   system (contrôle daltonisme + contraste exécuté, pas estimé), avec l'orange
   Fuel #FF5C28 en emplacement 2. Trois teintes claires (aqua, jaune, magenta)
   passent sous 3:1 sur blanc : c'est pourquoi CHAQUE graphique offre une vue
   tableau et des étiquettes directes — la couleur ne porte jamais seule.
   ========================================================================= */

:root {
  color-scheme: light;

  /* Surfaces */
  --plane:        #F4F6F9;
  --surface:      #FFFFFF;
  --surface-2:    #F8FAFC;
  --surface-3:    #EEF2F7;

  /* Encre */
  --ink:          #101B2D;
  --ink-2:        #55617A;
  --ink-muted:    #8A93A3;

  /* Traits */
  --line:         #E4E8EE;
  --line-2:       #D3DAE4;
  --grid:         #EDF0F5;

  /* Marque */
  --fuel:         #FF5C28;
  --fuel-dark:    #E04A19;
  --fuel-wash:    #FFF1EC;

  /* Séries — ordre fixe, jamais recyclé.
     Les deux premières sont les couleurs de marque : le bleu foncé Fuel porte
     la mesure principale, le bleu clair la mesure secondaire. L'orange reste
     réservé aux commandes de l'interface, pour qu'on ne confuse jamais « ceci
     est une donnée » et « ceci se clique ». */
  --s1: #7a9cc8;   /* bleu clair Fuel */
  --s2: #1a2740;   /* bleu foncé Fuel */
  --s3: #1baf7a;   /* aqua     */
  --s4: #eda100;   /* jaune    */
  --s5: #e87ba4;   /* magenta  */
  --s6: #008300;   /* vert     */
  --dim: #C3C9D4;  /* série en retrait */

  /* États */
  --good:     #0F8F3C;
  --good-wash:#E8F6EC;
  --warn:     #B57200;
  --warn-wash:#FDF3E2;
  --bad:      #C42B2B;
  --bad-wash: #FDECEC;

  --radius:    12px;
  --radius-sm: 8px;
  --shadow:    0 1px 2px rgba(16,27,45,.05), 0 8px 24px rgba(16,27,45,.06);
  --shadow-sm: 0 1px 2px rgba(16,27,45,.06);

  --bloc:       #1a2740;   /* forme pleine du schéma — texte clair par-dessus */
  --bloc-ink:   #FFFFFF;

  --topbar:     rgba(255, 255, 255, .88);
  --fuel-wash-2:#FFE6DD;
  --good-line:  #BFE3CA;
  --bad-line:   #F5C6C6;
  --banner-hover: rgba(255, 255, 255, .55);
  --shadow-tip: 0 8px 28px rgba(16, 27, 45, .16);

  --font: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
}

/* ── Thème sombre ─────────────────────────────────────────────────────────
   Posé sur un attribut, pas sur une media query : le choix est celui du
   lecteur, mémorisé, et il doit pouvoir contredire son système. La préférence
   système ne sert que de valeur de départ, appliquée en JS à la première
   visite.

   LES SÉRIES CHANGENT, elles aussi. Le bleu foncé Fuel (#1a2740) est la
   couleur de la mesure principale sur fond blanc ; sur fond sombre il
   disparaît. Les rôles sont donc conservés — s2 reste « la mesure
   principale » — mais leurs valeurs sont reprises pour le fond sur lequel
   elles se posent. Toutes tiennent au moins 4,5:1 sur --surface.

   Les pages lisent ces jetons au lieu de porter leurs propres hexadécimaux :
   changer de thème redessine les graphiques avec la bonne palette. */
:root[data-theme="dark"] {
  color-scheme: dark;

  --plane:        #0D131E;
  --surface:      #161E2B;
  --surface-2:    #1C2634;
  --surface-3:    #26313F;

  --ink:          #E9EEF6;
  --ink-2:        #AAB6C7;
  --ink-muted:    #7C8899;

  --line:         #26313F;
  --line-2:       #38465C;
  --grid:         #212B38;

  --fuel:         #FF6B3D;
  --fuel-dark:    #FF8A63;
  --fuel-wash:    #3A1D12;
  --fuel-wash-2:  #4C2718;

  --s1: #5C90D6;   /* bleu moyen  — mesure secondaire */
  --s2: #AECBF0;   /* bleu clair  — mesure principale, la plus lisible ici */
  --s3: #35D3A0;   /* aqua    */
  --s4: #F2B93F;   /* jaune   */
  --s5: #F09BBD;   /* magenta */
  --s6: #56CB56;   /* vert    */
  --dim: #46566D;  /* série en retrait */

  --good:      #4FD37E;
  --good-wash: #12301D;
  --good-line: #1E5333;
  --warn:      #F0B849;
  --warn-wash: #33260C;
  --bad:       #FF7A7A;
  --bad-wash:  #3A1618;
  --bad-line:  #5E2226;

  --bloc:       #3C5680;   /* assez clair pour trancher sur --surface-2 */
  --bloc-ink:   #FFFFFF;

  --topbar:       rgba(22, 30, 43, .88);
  --banner-hover: rgba(255, 255, 255, .14);
  --shadow:       0 1px 2px rgba(0, 0, 0, .35), 0 8px 24px rgba(0, 0, 0, .28);
  --shadow-sm:    0 1px 2px rgba(0, 0, 0, .35);
  --shadow-tip:   0 8px 28px rgba(0, 0, 0, .45);
}

/* La pastille du logo est déjà sombre : sur fond sombre elle se fond dans la
   barre et le logo flotte. Un filet la redétache. */
:root[data-theme="dark"] .brand-logo { box-shadow: inset 0 0 0 1px var(--line-2); }

/* Le bandeau d'alerte : ses fonds sont des voiles de couleur à 30 %, lisibles
   sur blanc comme sur sombre. Seul le texte doit suivre le thème. */
:root[data-theme="dark"] .banner { color: var(--ink); }

/* Le remplissage automatique du navigateur repeint le champ en jaune pâle et
   ignore color-scheme sur plusieurs versions de Chrome : un champ rempli
   ressortait en clair au milieu d'un formulaire sombre. */
:root[data-theme="dark"] input:-webkit-autofill,
:root[data-theme="dark"] input:-webkit-autofill:hover,
:root[data-theme="dark"] input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--ink);
  -webkit-box-shadow: 0 0 0 1000px var(--surface-2) inset;
  caret-color: var(--ink);
}

/* ── La bascule de thème ────────────────────────────────────────────────── */
.themetoggle { display: inline-flex; }
.themetoggle .btn { gap: 6px; }
.themetoggle svg { width: 15px; height: 15px; display: block; }

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

/* hidden doit l'emporter sur un display posé en style inline */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--plane);
  color: var(--ink);
  font-family: var(--font);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { margin: 0; font-weight: 650; letter-spacing: -.011em; }
a { color: var(--s1); }

/* ── Barre supérieure ─────────────────────────────────────────────────── */
.topbar {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: 16px;
  padding: 0 24px; height: 60px;
  background: var(--topbar);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--line);
}
.brand { display: flex; align-items: center; gap: 10px; font-weight: 700; letter-spacing: -.02em; font-size: 15px; }
/* Le logo sur sa pastille foncée — même traitement que le hub : le logo est
   en bleu foncé sur fond transparent, on le sert recoloré en blanc et on le
   pose sur le fond du hub (#0a1018). */
.brand-logo {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  background: #0a1018; border-radius: 6px; padding: 7px 11px;
  text-decoration: none; user-select: none;
}
.brand-logo img { height: 15px; width: auto; display: block; }
.brand-logo.large { padding: 10px 15px; border-radius: 9px; }
.brand-logo.large img { height: 22px; }
.brand-sub { color: var(--ink-muted); font-weight: 500; font-size: 13px; padding-left: 10px; margin-left: 2px; border-left: 1px solid var(--line-2); }
.topbar-spacer { flex: 1; }

/* ── Contrôles ────────────────────────────────────────────────────────── */
.btn {
  appearance: none; border: 1px solid var(--line-2); background: var(--surface);
  color: var(--ink); font: inherit; font-weight: 550; font-size: 13px;
  padding: 7px 13px; border-radius: var(--radius-sm); cursor: pointer;
  display: inline-flex; align-items: center; gap: 7px; white-space: nowrap;
  transition: background .12s, border-color .12s, box-shadow .12s;
}
.btn:hover { background: var(--surface-2); border-color: var(--line-2); }
.btn:focus-visible { outline: 2px solid var(--s1); outline-offset: 2px; }
.btn[disabled] { opacity: .5; cursor: not-allowed; }
.btn-primary { background: var(--fuel); border-color: var(--fuel); color: #fff; }
.btn-primary:hover { background: var(--fuel-dark); border-color: var(--fuel-dark); }
.btn-ghost { border-color: transparent; background: transparent; }
.btn-ghost:hover { background: var(--surface-3); }
/* Un bouton qui retire quelque chose se signale au survol, pas au repos :
   une rangée de rouge dans un tableau crie l'alarme sans raison. */
.btn-ghost.danger:hover { background: var(--bad-wash); color: var(--bad); }
.btn-sm { padding: 5px 10px; font-size: 12px; }
/* Bouton à deux états — « Comparer à l'an dernier » */
.btn[aria-pressed="true"] {
  background: var(--fuel-wash); border-color: var(--fuel); color: var(--fuel-dark); font-weight: 650;
}
.btn[aria-pressed="true"]:hover { background: var(--fuel-wash-2); }

select, input[type="date"], input[type="text"], input[type="email"], input[type="password"], input[type="number"], textarea {
  appearance: none; font: inherit; font-size: 13px; color: var(--ink);
  background: var(--surface); border: 1px solid var(--line-2);
  border-radius: var(--radius-sm); padding: 7px 11px; min-width: 0;
}
select { padding-right: 30px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M3 4.5 6 8l3-3.5' fill='none' stroke='%238A93A3' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 10px center; }
input:focus, select:focus, textarea:focus { outline: 2px solid var(--s1); outline-offset: -1px; border-color: var(--s1); }
label { font-size: 12px; font-weight: 600; color: var(--ink-2); }

/* Segmenté — les préréglages de dates */
.seg { display: inline-flex; background: var(--surface-3); border-radius: var(--radius-sm); padding: 3px; gap: 2px; }
.seg button {
  appearance: none; border: 0; background: transparent; font: inherit; font-size: 12.5px; font-weight: 550;
  color: var(--ink-2); padding: 5px 11px; border-radius: 6px; cursor: pointer; white-space: nowrap;
}
.seg button:hover { color: var(--ink); }
.seg button[aria-pressed="true"] { background: var(--surface); color: var(--ink); box-shadow: var(--shadow-sm); }

/* ── Mise en page ─────────────────────────────────────────────────────── */
.wrap { max-width: 1440px; margin: 0 auto; padding: 20px 24px 64px; }
.filters {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 14px 16px; background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow-sm); margin-bottom: 18px;
}
.filters .sep { width: 1px; height: 24px; background: var(--line); }
.grid { display: grid; gap: 16px; }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 1080px) { .grid-2, .grid-3 { grid-template-columns: 1fr; } }

/* La vue régie garde ses paires côte à côte plus longtemps : ses cartes sont
   des anneaux et des tableaux compacts, pas des graphiques qui ont besoin de
   largeur. Descendre le point de rupture GLOBAL aurait serré les tableaux de
   bord partenaires, dont la mise en page est déjà calée — la règle est donc
   portée par la page. Sa spécificité (0,2,0) l'emporte sur celle de la règle
   ci-dessus (0,1,0), quel que soit l'ordre. */
@media (min-width: 840px) {
  .vue-regie .grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Le rapport 0,62 / 2 du tableau de bord partenaire donnait 224 px à gauche —
     trop étroit pour cinq colonnes — et laissait quand même déborder le
     croisement à droite. Ici la répartition suit ce que les deux tableaux
     demandent réellement : cinq colonnes contre sept. */
  .vue-regie .grid-1-2 { grid-template-columns: minmax(0, 1fr) minmax(0, 1.65fr); }
}

/* Tableaux resserrés de la vue régie.
   À 473 px de large, cinq colonnes ne tiennent qu'en réduisant le rembourrage.
   Le vrai coupable n'était pas l'espace vide mais le retour à la ligne : « 25,1 % »
   se brisait en deux, ce qui doublait la hauteur de chaque rangée et rendait la
   colonne illisible. `nowrap` sur les valeurs règle le problème ; seule la
   première colonne — un nom de partenaire ou d'annonceur — garde le droit de
   passer à la ligne, parce qu'elle, elle peut être longue. */
.vue-regie table.data { font-size: 12.5px; }
.vue-regie table.data th,
.vue-regie table.data td { padding: 7px 7px; white-space: nowrap; }
.vue-regie table.data th:first-child,
.vue-regie table.data td:first-child { white-space: normal; padding-left: 10px; }
.vue-regie table.data th { letter-spacing: 0; }

/* ── Cartes ───────────────────────────────────────────────────────────── */
.card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow-sm); overflow: hidden;
}
.card-head {
  display: flex; align-items: baseline; gap: 12px;
  padding: 15px 18px 0;
}
.card-head h3 { font-size: 14px; }
.card-head .hint { font-size: 12px; color: var(--ink-muted); font-weight: 450; }
.card-head .spacer { flex: 1; }
/* En-tête sur deux lignes : les contrôles d'abord, la précision en dessous —
   pour que le titre ne se casse pas quand la carte porte trois contrôles. */
.card-head.stack { flex-direction: column; align-items: stretch; gap: 7px; }
.card-head.stack .head-line { display: flex; align-items: center; gap: 10px; }
.card-head.stack .hint { line-height: 1.35; }
.card-body { padding: 12px 18px 18px; }

/* Contrôle propre à une carte — plus discret que les filtres du haut, pour
   qu'on voie tout de suite qu'il ne cadre que cette carte. */
.card-filter {
  font-size: 12.5px; padding: 4px 26px 4px 9px; background-color: var(--surface-2);
  border-color: var(--line); background-position: right 8px center;
}
.card-filter:hover { background-color: var(--surface-3); }

/* ── Tuiles de mesure ─────────────────────────────────────────────────── */
.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(172px, 1fr)); gap: 14px; margin-bottom: 18px; }
.kpi {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 15px 17px; box-shadow: var(--shadow-sm); position: relative; overflow: hidden;
}
.kpi.lead { grid-column: span 2; }
@media (max-width: 720px) { .kpi.lead { grid-column: span 1; } }
.kpi .label { font-size: 12px; color: var(--ink-2); font-weight: 600; letter-spacing: .01em; }
/* Une mesure dont la définition n'est pas évidente porte un pointillé : on
   comprend qu'il y a une note au survol, sans encombrer la tuile. */
.kpi .label.has-note { border-bottom: 1px dotted var(--line-2); display: inline-block; cursor: help; }
.kpi .value { font-size: 27px; font-weight: 680; letter-spacing: -.025em; margin-top: 5px; line-height: 1.15; }
.kpi.lead .value { font-size: 40px; }
.kpi .sub { display: flex; align-items: center; gap: 8px; margin-top: 7px; font-size: 12px; color: var(--ink-muted); }
.kpi .spark { position: absolute; right: 0; bottom: 0; opacity: .9; pointer-events: none; }

.delta { display: inline-flex; align-items: center; gap: 3px; font-weight: 650; font-size: 12px; padding: 2px 6px; border-radius: 5px; }
.delta.up   { color: var(--good); background: var(--good-wash); }
.delta.down { color: var(--bad);  background: var(--bad-wash); }
.delta.flat { color: var(--ink-2); background: var(--surface-3); }

/* ── Tableaux ─────────────────────────────────────────────────────────── */
table.data { width: 100%; border-collapse: collapse; font-size: 13px; }
table.data th {
  text-align: right; font-size: 11.5px; font-weight: 650; color: var(--ink-2);
  padding: 8px 10px; border-bottom: 1px solid var(--line); white-space: nowrap;
  text-transform: uppercase; letter-spacing: .04em; cursor: pointer; user-select: none;
}
table.data th:first-child, table.data td:first-child { text-align: left; }
table.data th[aria-sort="descending"]::after { content: " ↓"; color: var(--fuel); }
table.data th[aria-sort="ascending"]::after  { content: " ↑"; color: var(--fuel); }
table.data td { padding: 9px 10px; border-bottom: 1px solid var(--grid); text-align: right; font-variant-numeric: tabular-nums; }
table.data tbody tr:hover { background: var(--surface-2); }
table.data tbody tr:last-child td { border-bottom: 0; }
table.data .name { display: flex; align-items: center; gap: 8px; font-weight: 550; }
.swatch { width: 9px; height: 9px; border-radius: 2px; flex: none; }
.scroll-x { overflow-x: auto; }

/* Tableau croisé — les blocs « Annonceur » et « Domaine ».
   Le croisé annonceurs peut faire 80 lignes : on le borne en hauteur avec un
   défilement interne et un en-tête collant, plutôt que d'étirer la page. */
/* Replié, le tableau des annonceurs tient sans défilement ; il n'apparaît que
   si le lecteur déplie plusieurs annonceurs. L'en-tête reste collant, mais pas
   le pied : `position: sticky` sur une cellule est peu fiable dans un tableau
   en `border-collapse: collapse`, et le pied s'y superposait mal. */
.crosstab-scroll { max-height: 680px; overflow: auto; }
.crosstab-scroll table.data thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--surface); box-shadow: inset 0 -1px 0 var(--line);
}
table.crosstab th.grouphead {
  text-align: left; vertical-align: top; font-size: 13px; font-weight: 600;
  text-transform: none; letter-spacing: 0; color: var(--ink);
  border-bottom: 1px solid var(--line); border-right: 1px solid var(--grid);
  cursor: default; padding-top: 11px; white-space: normal; min-width: 140px;
}
table.crosstab td.total, table.crosstab th.total { font-weight: 700; background: var(--surface-2); }
table.crosstab td.nil { color: var(--ink-muted); }
table.crosstab tfoot td, table.crosstab tfoot th {
  border-top: 2px solid var(--line-2); border-bottom: 0;
  font-weight: 700; font-size: 12.5px; padding-top: 10px;
}
table.crosstab tbody tr:hover { background: var(--surface-2); }

/* Mode replié — dense, une ligne par groupe, détail au clic */
table.crosstab.dense td, table.crosstab.dense th { padding: 6px 10px; }
table.crosstab.dense th.grouphead { padding: 5px 10px 5px 4px; min-width: 0; border-right: 0; }
table.crosstab.dense tbody tr.summary th, table.crosstab.dense tbody tr.summary td { border-bottom: 1px solid var(--grid); }
table.crosstab.dense tbody tr.summary.open th, table.crosstab.dense tbody tr.summary.open td { border-bottom-color: transparent; }
table.crosstab.dense .linesum { color: var(--ink-muted); font-size: 12px; }
table.crosstab.dense tr.detail td { border-bottom: 0; padding-top: 3px; padding-bottom: 3px; }
table.crosstab.dense tr.detail:last-of-type td { border-bottom: 1px solid var(--grid); }
table.crosstab.dense tr.detail .detail-label { color: var(--ink-2); font-size: 12px; padding-left: 6px; }
table.crosstab.dense tr.detail .detail-cell { color: var(--ink-2); font-size: 12px; }
table.crosstab.dense tr.detail td.spacer { border-bottom: 0; }
table.crosstab.dense tr.detail:hover { background: var(--surface-2); }

.xt-toggle {
  appearance: none; border: 0; background: transparent; font: inherit; font-size: 13px; font-weight: 600;
  color: var(--ink); cursor: pointer; display: inline-flex; align-items: center; gap: 6px;
  padding: 2px 6px 2px 2px; border-radius: 6px; text-align: left; width: 100%;
}
.xt-toggle:hover { background: var(--surface-3); }
.xt-toggle:focus-visible { outline: 2px solid var(--s1, #2a78d6); outline-offset: 1px; }
.xt-toggle .caret { color: var(--ink-muted); font-size: 10px; width: 10px; flex: none; }

/* Barre de proportion dans une cellule */
.cellbar { position: relative; }
.cellbar .fill { position: absolute; left: 0; top: 3px; bottom: 3px; background: var(--s1); opacity: .13; border-radius: 3px; }
.cellbar span { position: relative; }

/* ── Bandeau de diffusion Fuel ────────────────────────────────────────── */
/* Le bandeau prend la teinte de son icône à 30 % : un message poussé par Fuel
   doit se voir, pas se fondre dans les cartes blanches. Contraste du texte
   mesuré sur les trois teintes : 10,9 · 10,9 · 11,2 pour 1 — bien au-dessus
   du seuil AA. Le contour reprend la même teinte, plus dense. */
.banner {
  display: flex; align-items: flex-start; gap: 11px; padding: 13px 16px; margin-bottom: 16px;
  border-radius: var(--radius); border: 1px solid var(--line); background: var(--surface);
  box-shadow: var(--shadow-sm); font-size: 13px; line-height: 1.5;
}
.banner .icon {
  flex: none; width: 20px; height: 20px; border-radius: 6px; margin-top: 1px;
  display: grid; place-items: center; font-size: 12px; font-weight: 700; color: #fff;
}
.banner.info      { background: rgba(42, 120, 214, .30); border-color: rgba(42, 120, 214, .45); }
.banner.info .icon      { background: #2a78d6; }
.banner.succes    { background: rgba(15, 143, 60, .30);  border-color: rgba(15, 143, 60, .45); }
.banner.succes .icon    { background: #0F8F3C; }
.banner.attention { background: rgba(181, 114, 0, .30);  border-color: rgba(181, 114, 0, .45); }
.banner.attention .icon { background: #B57200; }

.banner .close { margin-left: auto; flex: none; }
/* Sur fond teinté, le survol gris des boutons fantômes tranche mal. */
.banner .close:hover { background: var(--banner-hover); }

/* ── Graphiques ───────────────────────────────────────────────────────── */
.chart { width: 100%; display: block; overflow: visible; }
.chart text { font-family: var(--font); }
.axis-label { font-size: 11px; fill: var(--ink-muted); }
.grid-line { stroke: var(--grid); stroke-width: 1; }
.axis-line  { stroke: var(--line-2); stroke-width: 1; }
.chart-cursor { stroke: var(--ink-muted); }
/* Colonne survolée — ici ou sur un graphique voisin du même groupe. */
.chart-band { fill: var(--ink); fill-opacity: .07; pointer-events: none; }
/* Tuile de format : la légende de l'anneau pilote la courbe du haut. */
.donut-legend li.survolable { cursor: default; border-radius: 6px; }
.donut-legend li.survolable:hover { background: var(--surface-2); }
.spark-serie { transition: opacity .15s; }
.statcard.sur-appareil .tile-figures .label { color: var(--ink); }
@media (prefers-reduced-motion: reduce) { .spark-serie { transition: none; } }

.legend { display: flex; flex-wrap: wrap; gap: 14px; padding: 2px 0 10px; font-size: 12px; color: var(--ink-2); }
.legend .item { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
.legend .item[data-off="1"] { opacity: .4; }
.legend .key { width: 14px; height: 3px; border-radius: 2px; }
.legend .key.rect { height: 10px; width: 10px; border-radius: 2px; }

.tip {
  position: fixed; z-index: 90; pointer-events: none; opacity: 0;
  background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--radius-sm);
  box-shadow: var(--shadow-tip); padding: 9px 11px; font-size: 12px; min-width: 150px;
  transition: opacity .1s;
}
.tip .tip-title { font-weight: 650; margin-bottom: 6px; color: var(--ink); }
.tip .tip-row { display: flex; align-items: center; gap: 8px; margin-top: 3px; }
.tip .tip-key { width: 12px; height: 3px; border-radius: 2px; flex: none; }
.tip .tip-name { color: var(--ink-2); }
.tip .tip-val { margin-left: auto; font-weight: 650; font-variant-numeric: tabular-nums; }

/* Le pendant accessible de chaque graphique */
.viewtoggle { display: inline-flex; gap: 2px; background: var(--surface-3); border-radius: 6px; padding: 2px; }
.viewtoggle button { appearance: none; border: 0; background: transparent; font: inherit; font-size: 11.5px; font-weight: 600; color: var(--ink-2); padding: 3px 9px; border-radius: 5px; cursor: pointer; }
.viewtoggle button[aria-pressed="true"] { background: var(--surface); color: var(--ink); box-shadow: var(--shadow-sm); }

/* Rechargement : on garde l'image précédente en retrait, jamais de squelette */
.reloading { opacity: .45; transition: opacity .15s; }

/* ── Divers ───────────────────────────────────────────────────────────── */
.muted { color: var(--ink-muted); }
.chip { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; padding: 3px 9px; border-radius: 999px; background: var(--surface-3); color: var(--ink-2); }
.chip.on { background: var(--good-wash); color: var(--good); }
.chip.off { background: var(--surface-3); color: var(--ink-muted); }
.empty { padding: 40px 20px; text-align: center; color: var(--ink-muted); font-size: 13px; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
.err { background: var(--bad-wash); color: var(--bad); border: 1px solid var(--bad-line); border-radius: var(--radius-sm); padding: 10px 12px; font-size: 13px; }
.ok  { background: var(--good-wash); color: var(--good); border: 1px solid var(--good-line); border-radius: var(--radius-sm); padding: 10px 12px; font-size: 13px; }


/* ── Composants ajoutés pour le gabarit « performance » ───────────────── */
.mb { margin-bottom: 16px; }

.menu {
  position: absolute; right: 0; top: 38px; z-index: 50; min-width: 224px;
  background: var(--surface); border: 1px solid var(--line-2); border-radius: 10px;
  box-shadow: var(--shadow); padding: 6px; display: grid; gap: 2px;
}
.menu .btn { width: 100%; justify-content: flex-start; }

.range { display: flex; gap: 8px; align-items: center; }
.freshness { font-size: 12px; }

/* align-items: start — sinon la carte la plus courte s'étire pour égaler
   l'autre et se retrouve avec un grand vide sous son graphique. Des cartes de
   hauteurs différentes valent mieux qu'une carte à moitié vide. */
.grid-3-1 { display: grid; grid-template-columns: minmax(0, 2.15fr) minmax(0, 1fr); gap: 16px; align-items: start; }
/* Repères en colonne étroite, bloc mensuel large : un graphique de 12 mois
   avec ses contrôles a besoin de place, trois cartes de texte non. */
.grid-1-2 { display: grid; grid-template-columns: minmax(0, 0.62fr) minmax(0, 2fr); gap: 16px; }
@media (max-width: 1080px) { .grid-3-1, .grid-1-2 { grid-template-columns: 1fr; } }

/* Repères fixes — hier / ce mois-ci / cette année */
.marks {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 14px; align-content: start;
}
/* Dans la rangée du haut, les trois repères s'empilent pour laisser au bloc
   mensuel la largeur qu'un graphique demande. */
.grid-1-2 > .marks { grid-template-columns: 1fr; gap: 12px; }
.mark {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 13px 16px; box-shadow: var(--shadow-sm);
  border-left: 3px solid var(--line-2);
}
.mark-label { font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-muted); }
/* La date, sur la même ligne que l'étiquette : ni capitales ni interlettrage,
   pour qu'on lise « CE MOIS-CI septembre 2026 » comme une étiquette et sa
   précision, pas comme deux titres. */
.mark-quand { margin-left: 7px; font-weight: 500; text-transform: none; letter-spacing: 0; color: var(--ink-2); }
.mark-value { font-size: 21px; font-weight: 680; letter-spacing: -.02em; margin-top: 3px; }
.mark-value.muted { font-size: 16px; font-weight: 550; }
.mark-sub { font-size: 12px; color: var(--ink-2); margin-top: 2px; }
/* Pied de tuile : la ligne de contexte sous l'écart (revenu de la période,
   impressions de la veille). Elle existait sans règle depuis la refonte de
   la vue régie et s'affichait donc en corps de texte plein. */
.mark-foot { font-size: 11.5px; color: var(--ink-muted); margin-top: 5px; }

/* ═══ VUE RÉGIE — mise en page dense ════════════════════════════════════════
   Le modèle : tout à l'écran, rien à chercher. Des cartes blanches sur un fond
   légèrement teinté, des rangées de hauteurs voisines, et un rembourrage
   resserré partout — c'est le rembourrage, pas le nombre de blocs, qui fait
   qu'un tableau de bord déborde. */

/* En-tête de page : titre, onglets, et les deux pastilles d'état. */
.pagehead { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.pagehead h1 { font-size: 19px; font-weight: 700; letter-spacing: -.025em; margin: 0; }
.pagehead .spacer { flex: 1; }

/* Les onglets. Forme de gélule, comme les segments de période : c'est le même
   geste — on choisit une vue, on ne navigue pas ailleurs. */
.tabs { display: inline-flex; gap: 3px; background: var(--surface-3); border-radius: 999px; padding: 3px; }
.tabs button {
  appearance: none; border: 0; background: transparent; font: inherit; font-size: 13px;
  font-weight: 600; color: var(--ink-2); padding: 6px 17px; border-radius: 999px; cursor: pointer;
}
.tabs button:hover { color: var(--ink); }
.tabs button[aria-selected="true"] { background: var(--surface); color: var(--ink); box-shadow: var(--shadow-sm); }
.tabs button:focus-visible { outline: 2px solid var(--fuel); outline-offset: 2px; }

.majpill {
  font-size: 12px; color: var(--ink-2); background: var(--surface);
  border: 1px solid var(--line); border-radius: 999px; padding: 5px 13px; white-space: nowrap;
}

/* ── Tuiles de mesure ─────────────────────────────────────────────────────
   Deux par deux, à gauche de la courbe. Une pastille d'icône, l'étiquette, le
   montant, l'écart. Quatre lignes, jamais cinq. */
.kpis { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; align-content: start; }
.kpitile {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-sm); padding: 12px 14px;
}
.kpitile .chip {
  width: 28px; height: 28px; border-radius: 9px; display: grid; place-items: center;
  background: var(--surface-3); color: var(--s2); margin-bottom: 7px;
}
.kpitile .chip svg { width: 15px; height: 15px; }
.kpitile .etiq {
  font-size: 11.5px; font-weight: 650; color: var(--ink-2); letter-spacing: .01em;
  display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap;
}
/* La période, à côté du libellé et non à sa place : « Hier » reste le titre,
   « 19 sept. » précise de quel hier on parle. */
.kpitile .etiq-quand { font-weight: 500; color: var(--ink-muted); font-size: 11px; }
.kpitile .val { font-size: 22px; font-weight: 700; letter-spacing: -.03em; line-height: 1.2; margin-top: 1px; }
/* Hauteur réservée pour deux lignes : sans elle, un pied qui passe à la ligne
   décalait toute la colonne quand on changeait de filtre. */
.kpitile .pied {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  font-size: 11.5px; color: var(--ink-muted); margin-top: 5px; min-height: 1.5em;
}
.kpitile .pied + .pied { margin-top: 2px; }

/* ── Rangées ──────────────────────────────────────────────────────────────
   `align-items: start` : une carte courte ne s'étire pas pour égaler sa
   voisine, elle reste courte. Des hauteurs différentes valent mieux qu'une
   carte à moitié vide. */
.rangee { display: grid; gap: 14px; margin-bottom: 14px; align-items: start; grid-template-columns: 1fr; }
@media (min-width: 1100px) {
  .r-tete   { grid-template-columns: minmax(0, 320px) minmax(0, 1fr); }
  /* Six mesures en deux colonnes ont besoin d'un peu plus que trois. */
  .vue-partenaire .r-tete { grid-template-columns: minmax(0, 344px) minmax(0, 1fr); }
  .r-ssp    { grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr); }
  /* L'empilement a besoin de largeur, les deux anneaux non. */
  .r-tiers  { grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr) minmax(0, 1fr); }
  .r-tables { grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr); }
}

/* Cartes resserrées : 12/14 px au lieu de 15/18. Sur quinze cartes, ça rend
   près de deux cents pixels de hauteur — un bloc entier. La vue régie et les
   tableaux de bord partenaires partagent la même densité : c'est le même
   produit, il doit se lire pareil. */
.dense .card-head { padding: 12px 14px 0; gap: 9px; }
.dense .card-head h3 { font-size: 13px; letter-spacing: -.01em; }
.dense .card-head .hint { font-size: 11.5px; }
.dense .card-body { padding: 9px 14px 14px; }
.dense .cardnote { margin-top: 8px; }


/* ── Le tableau de bord partenaire ────────────────────────────────────────
   Écran de référence : 1300 px. Les mesures et la courbe doivent tenir dans
   le premier écran, sans défiler.

   Portée : `.vue-partenaire`. La vue régie porte `.dense` elle aussi — elle
   partage la densité des cartes, pas cette mise en page, et `.pagehead` comme
   `.kpis` existent des deux côtés. */
.vue-partenaire .wrap { padding: 14px 18px 40px; }
.vue-partenaire .filters { margin-bottom: 12px; }
.vue-partenaire .mb { margin-bottom: 14px; }
/* flex-wrap conservé : les onglets, la fraîcheur et l'export doivent pouvoir
   passer à la ligne plutôt que déborder. */
.vue-partenaire .pagehead { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.vue-partenaire .pagehead .spacer { flex: 1; }

/* Six tuiles dans un rail étroit : deux colonnes, trois rangées PLEINES. La
   tuile de tête ne s'étale plus sur la largeur — elle mangeait une rangée
   pour un seul chiffre, et les cinq autres laissaient alors un trou en bas. */
.vue-partenaire .kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.vue-partenaire .kpi { padding: 10px 12px; }
.vue-partenaire .kpi.lead { grid-column: auto; }
.vue-partenaire .kpi .label { font-size: 11.5px; line-height: 1.25; }
.vue-partenaire .kpi .value,
.vue-partenaire .kpi.lead .value { font-size: 20px; margin-top: 2px; }
/* L'étincelle se range en haut à droite, hors de la ligne de l'écart : au
   format compact elle se dessinait PAR-DESSUS le « ▼ -33,0 % ». */
.vue-partenaire .kpi { position: relative; }
.vue-partenaire .kpi .spark { top: 9px; right: 10px; bottom: auto; opacity: .55; }
.vue-partenaire .kpi .sub { margin-top: 4px; font-size: 11px; gap: 5px; }

/* Tuiles cliquables : une tuile dont la mesure a sa courbe est un <button>
   qui la trace à droite. Enfoncée, elle prend le filet orange des commandes —
   l'orange dit « ceci se clique », jamais « ceci est une donnée ». */
button.kpi {
  font: inherit; color: inherit; text-align: left; width: 100%; cursor: pointer;
  transition: border-color .12s, background .12s;
}
button.kpi:hover { border-color: var(--line-2); }
button.kpi[aria-pressed="true"] { border-color: var(--fuel); box-shadow: inset 0 0 0 1px var(--fuel); }
button.kpi:focus-visible { outline: 2px solid var(--fuel); outline-offset: 2px; }
/* Au survol d'un jour : la tuile lit ce jour-là ; celle qui n'a pas de
   valeur quotidienne garde sa période, en retrait. */
.kpi.au-jour { background: var(--surface-2); }
.kpi.au-jour .sub span:last-child { color: var(--ink); font-weight: 600; }
.kpi.hors-jour { opacity: .45; }
@media print { button.kpi[aria-pressed="true"] { box-shadow: none; border-color: var(--line); } }

/* Repères : dans le même rail de 320 px, empilés. */
/* Le libellé de période fait deux lignes dans la place que lui laissent le
   sélecteur de mesure et la bascule graphique/tableau. Sa boîte est réservée :
   sa longueur ne dépend plus des filtres (voir renderTrend), mais une période
   sur mesure peut encore la faire varier d'une ligne. */
.vue-partenaire #trendHint { display: block; line-height: 1.35; min-height: 2.7em; }

.vue-partenaire .marks { grid-template-columns: 1fr; gap: 10px; }
.vue-partenaire .mark { padding: 9px 12px; }
.vue-partenaire .mark-value { font-size: 20px; margin-top: 1px; }
.vue-partenaire .mark-label { font-size: 10.5px; }
.vue-partenaire .mark-sub { font-size: 11px; margin-top: 1px; }

/* Les quatre cartes courtes sur une rangée. Sous 1240 px elles repassent à
   deux par deux plutôt que de s'écraser. */
.r-un, .r-trois, .r-quatre, .r-deux { grid-template-columns: 1fr; }
@media (min-width: 900px) {
  .r-deux   { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .r-trois  { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .r-quatre { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1240px) {
  .r-quatre { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
/* Deux cartes courtes empilées dans une colonne de rangée : ensemble elles
   atteignent la hauteur de leurs voisines. */
.pile { display: grid; gap: 14px; align-content: start; }

/* Rangée dont la carte conditionnelle est absente : une seule colonne, pour
   que la carte restante ne se retrouve pas à côté d'un vide. */
.rangee.seul { grid-template-columns: 1fr !important; }

/* L'inventaire : la courbe empilée large, l'analyse à sa droite.

   HAUTEUR RÉSERVÉE. L'analyse est un texte calculé : deux ou trois
   paragraphes, deux ou trois lignes chacun selon les chiffres. Sa hauteur
   variait de 23 px d'un filtre à l'autre et faisait remonter les deux rangées
   du dessous. Les deux cartes s'étirent donc à la hauteur de la rangée, qui
   ne bouge plus ; un texte plus long défile au lieu de pousser. */
.r-inventaire { grid-template-columns: 1fr; align-items: stretch; }
@media (min-width: 1100px) {
  .r-inventaire { grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr); min-height: 306px; }
}
.vue-partenaire #inventaireAnalyse { max-height: 164px; overflow-y: auto; }
/* Trois mesures de front dans la colonne d'analyse. */
.vue-partenaire #inventaireTuiles { grid-template-columns: repeat(3, minmax(0, 1fr)); margin-bottom: 12px; }
.analyse {
  margin: 0 0 9px; font-size: 12.5px; line-height: 1.5; color: var(--ink-2);
  padding-left: 10px; border-left: 2px solid var(--line);
}
.analyse:last-child { margin-bottom: 0; }
.analyse strong { color: var(--ink); font-weight: 650; }

/* Les tableaux longs défilent DANS leur carte. Annonceurs, domaines, formats
   et régions n'ont pas de longueur bornée : à eux quatre ils ajoutaient
   2 700 px à la page, pour un contenu dont les dix premières lignes portent
   l'essentiel. L'en-tête reste collé, on sait toujours quelle colonne on lit.

   Portée : la vue partenaire seulement. La vue régie a les MÊMES
   identifiants (#sspChart, #advertiserPivot…) et sa propre mise en page —
   la borner ici la changerait sans que personne l'ait demandé. */
/* #advertiserPivot est ABSENT de cette liste : le tableau croisé gère déjà
   son propre défilement (`scroll: true`). Lui ajouter une hauteur maximale
   posait une SECONDE barre de défilement par-dessus la première. On agit sur
   la boîte du tableau croisé, pas sur son conteneur. */
.vue-partenaire #domainPivot,
.vue-partenaire #sizeTable, .vue-partenaire #campaignsTable {
  max-height: 372px; overflow-y: auto;
}
/* 680 px (le défaut, que garde la vue régie) occupaient tout le premier écran
   de l'onglet Détail pour un seul bloc. À 420, on voit aussi les domaines et
   les formats sans défiler, et les onze premiers annonceurs pèsent déjà
   l'essentiel du revenu. */
.vue-partenaire .crosstab-scroll { max-height: 420px; }
.vue-partenaire table.data thead th {
  position: sticky; top: 0; z-index: 1;
  background: var(--surface); box-shadow: inset 0 -1px 0 var(--line);
}
.vue-partenaire table.data th,
.vue-partenaire table.data td { padding: 6px 8px; }
.vue-partenaire table.data { font-size: 12.5px; }

/* Bloc indisponible sous le filtre courant : il GARDE SA PLACE.
   Le masquer faisait remonter toutes les cartes suivantes — on changeait de
   SSP et la page se réorganisait sous les yeux. Le corps est neutralisé, le
   titre reste, et une phrase dit pourquoi. */
/* ── Console : l'onglet Requêtes ──────────────────────────────────────────
   Le SQL se lit, il ne s'édite pas. Une police à chasse fixe et un fond
   distinct le disent avant même qu'on ait lu la note. */
.requete { border: 1px solid var(--line); border-radius: var(--radius-sm); margin-bottom: 8px; background: var(--surface); }
.requete > summary { padding: 10px 14px; cursor: pointer; font-size: 13px; list-style: none; }
.requete > summary::-webkit-details-marker { display: none; }
.requete > summary::before { content: "▸ "; color: var(--ink-muted); }
.requete[open] > summary::before { content: "▾ "; }
.requete > summary .muted { font-weight: 400; font-size: 12px; }
.requete-corps { padding: 0 14px 12px; }
pre.sql {
  margin: 0; padding: 12px 14px; max-height: 420px; overflow: auto;
  background: #0F1725; color: #D7E1F0; border-radius: var(--radius-sm);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11.5px; line-height: 1.55;
  white-space: pre; tab-size: 2;
}

/* Une expression modifiable : le texte est du SQL, il se lit en chasse fixe.
   La bordure orange dit « celle-ci ne dit plus ce qu'elle disait à l'origine ». */
.cas { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 14px; margin-bottom: 12px; background: var(--surface); }
.cas.modifie { border-color: var(--fuel); box-shadow: inset 3px 0 0 var(--fuel); }
.cas-tete { font-size: 13.5px; }
.cas-marque {
  font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
  color: var(--fuel); background: var(--fuel-wash); border-radius: 999px; padding: 2px 8px; margin-left: 6px;
}
.cas code { background: var(--surface-3); border-radius: 4px; padding: 1px 5px; font-size: 11px; }

/* « historique partiel » : un état à corriger, pas une erreur — la teinte
   d'avertissement, pas celle du danger. */
.marque-histo {
  font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: var(--warn); background: var(--warn-wash); border-radius: 999px;
  padding: 2px 7px; white-space: nowrap;
}
textarea.cas-sql {
  width: 100%; margin-top: 10px; padding: 11px 13px; resize: vertical;
  background: #0F1725; color: #D7E1F0; border: 1px solid #1E2A3D; border-radius: var(--radius-sm);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11.5px; line-height: 1.55;
  white-space: pre; overflow-wrap: normal; overflow-x: auto; tab-size: 2;
}
textarea.cas-sql:focus { outline: 2px solid var(--fuel); outline-offset: 1px; }
textarea.cas-sql[readonly] { opacity: .75; }
.cas-etat.erreur { color: var(--bad); font-weight: 600; }

/* La table de rattachement : des champs, pas du texte libre. Le serveur
   recompile, donc aucun invariant ne peut être contourné depuis l'écran. */
table.data.alias td { padding: 4px 6px; vertical-align: middle; }
table.data.alias input {
  width: 100%; min-width: 130px; font-size: 12.5px; padding: 5px 8px;
  border: 1px solid var(--line); border-radius: 6px; background: var(--surface);
}
table.data.alias td.rang { color: var(--ink-muted); font-variant-numeric: tabular-nums; width: 34px; }
table.data.alias td.actions { white-space: nowrap; width: 110px; }
table.data.alias td.actions .btn { padding: 2px 7px; min-width: 0; }

/* ── Chemin des impressions : le schéma ───────────────────────────────────
   Un SVG à viewBox fixe, mis à l'échelle de la carte. La géométrie est
   déterministe : les flèches tombent toujours au bon endroit, à toute largeur,
   et la lecture gauche-droite du schéma d'origine est préservée — une grille
   CSS l'aurait cassée au premier rétrécissement. */
.schema { display: block; width: 100%; height: auto; }
.schema text { font-family: var(--font); }
.sch-lab       { font-size: 12px; font-weight: 600; fill: var(--ink-2); }
.sch-titre     { font-size: 12.5px; font-weight: 700; fill: var(--ink-2); letter-spacing: .02em; }
.sch-titre-gam { font-size: 15px; font-weight: 800; fill: var(--ink); letter-spacing: .06em; }
.sch-titre-sombre { font-size: 11.5px; font-weight: 700; fill: #9FB4D0; letter-spacing: .08em; }
.sch-gros-sombre  { font-size: 27px; font-weight: 700; fill: var(--bloc-ink); letter-spacing: -.02em; }
.sch-sous-sombre  { font-size: 11.5px; fill: #9FB4D0; }
.sch-val       { font-size: 17px; font-weight: 700; fill: var(--ink); letter-spacing: -.02em; }
.sch-nom       { font-size: 12.5px; fill: var(--ink); }
.sch-nom-fort  { font-size: 12.5px; font-weight: 700; fill: var(--ink); }
.sch-sous      { font-size: 11px; fill: var(--ink-muted); }
.sch-puce      { font-size: 11.5px; font-weight: 700; fill: var(--bloc-ink); }

/* Les quatre mesures du chemin sur une seule ligne : l'entonnoir se lit de
   gauche à droite, ses mesures aussi. */
.kpis-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); margin-bottom: 14px; }
@media (min-width: 900px) { .kpis-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

/* Le tableau des SSP défile dans sa carte. Dix-neuf plateformes tiraient la
   rangée au double de la hauteur de sa voisine, et les six dernières lignes
   pèsent ensemble moins de 1 % du revenu — elles doivent rester accessibles,
   pas dicter la mise en page. L'en-tête reste collé pour qu'on sache toujours
   quelle colonne on lit. */
.vue-regie #cardSsp .scroll-x { max-height: 322px; overflow-y: auto; }
.vue-regie #cardSsp table.data thead th {
  position: sticky; top: 0; z-index: 1;
  background: var(--surface); box-shadow: inset 0 -1px 0 var(--line);
}

.card-body.bloque > *:not(.blocvide) { display: none; }
.blocvide {
  display: flex; align-items: center; justify-content: center; text-align: center;
  min-height: 150px; margin: 0; padding: 12px 20px;
  font-size: 12.5px; line-height: 1.5; color: var(--ink-muted);
  background: var(--surface-2); border: 1px dashed var(--line-2); border-radius: 8px;
}

/* Les taux moyens, dans l'en-tête de page. Aucun mot d'explication :
   « USD 1,39 » se comprend seul, et les quatre décimales sont au survol. */
.fxbadge {
  font-size: 12px; font-weight: 650; color: var(--ink-2); letter-spacing: .01em;
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 999px; padding: 3px 10px; cursor: help; white-space: nowrap;
}

/* Display et vidéo : le volume à gauche, la courbe comparée à droite. */
.fmtrow { display: grid; grid-template-columns: minmax(0, 118px) minmax(0, 1fr); gap: 12px; align-items: center; }
.fmtrow + .fmtrow { margin-top: 9px; padding-top: 9px; border-top: 1px solid var(--line); }
.fmt-value { font-size: 19px; font-weight: 700; letter-spacing: -.025em; margin-top: 1px; }
.fmt-chart { min-width: 0; }

/* Un second graphique dans la même carte, sous le premier : même axe de dates,
   même largeur, séparé par un filet pour qu'on voie que c'est une autre mesure. */
.subchart { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--line); }
.subchart-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 2px; }
.subchart-head h4 { font-size: 13px; font-weight: 650; }
@media (max-width: 620px) { .fmtrow { grid-template-columns: 1fr; } }

/* Tuiles empilées en colonne (Display/Vidéo, appareils, direct) */
.stackcards { display: grid; gap: 14px; align-content: start; }
.stackcards.tight { gap: 12px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.stackcards.tight .label { display: flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 600; color: var(--ink-2); }
.small-value { font-size: 19px; font-weight: 680; letter-spacing: -.02em; margin-top: 2px; }
.stackcards .sub { font-size: 11.5px; color: var(--ink-muted); margin-top: 1px; }

.statcard { padding: 15px 17px; position: relative; }
.statcard .label { font-size: 12.5px; font-weight: 650; color: var(--ink-2); }
.statcard .value { font-size: 26px; font-weight: 680; letter-spacing: -.025em; margin-top: 4px; }
.statcard .value .unit { font-size: 12.5px; font-weight: 550; color: var(--ink-muted); letter-spacing: 0; }
.statcard .sub { font-size: 12px; color: var(--ink-muted); margin-top: 3px; }
.statcard svg { margin-top: 8px; display: block; }

/* Tuiles Display / vidéo : chiffres à gauche et courbe à leur droite, puis la
   répartition par appareil en dessous, séparée par un filet. */
.tile-head { display: flex; align-items: flex-start; gap: 18px; flex-wrap: wrap; }
.tile-figures { flex: 0 1 auto; min-width: 0; }
/* La courbe prend tout ce qui reste à droite des chiffres. */
.tile-spark { flex: 1 1 150px; min-width: 130px; display: grid; justify-items: end; gap: 1px; }
.tile-spark svg { width: 100%; }
.tile-spark span { font-size: 11px; color: var(--ink-muted); }
.tile-ring { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--grid); }
.tile-ring .donut-wrap { margin-top: 0; gap: 16px; }

/* Anneau — part-à-tout par appareil, dans les tuiles Display / vidéo */
.donut-wrap { display: flex; align-items: center; gap: 16px; margin-top: 12px; }
.donut-wrap.stacked { flex-direction: column; align-items: flex-start; gap: 10px; }
svg.donut { flex: none; display: block; width: auto; }
.donut-legend { list-style: none; margin: 0; padding: 0; display: grid; gap: 5px; flex: 1; min-width: 0; }
.donut-legend li { display: flex; align-items: center; gap: 8px; font-size: 12.5px; }
.donut-legend .nm { color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.donut-legend .pc { margin-left: auto; font-weight: 650; font-variant-numeric: tabular-nums; color: var(--ink); }
.donut-legend .swatch { width: 10px; height: 10px; border-radius: 3px; }

.disclaimer {
  font-size: 11.5px; line-height: 1.6; color: var(--ink-muted);
  border-top: 1px solid var(--line); padding-top: 14px; margin: 22px 0 0; max-width: 100ch;
}

/* Note de bas de carte : explique une mesure là où elle est lue, plutôt que
   dans un avertissement général en fin de page que personne n'atteint. */
.cardnote {
  font-size: 11.5px; line-height: 1.6; color: var(--ink-muted);
  border-top: 1px solid var(--line); padding-top: 12px; margin: 16px 0 0; max-width: 95ch;
}
.cardnote:empty { display: none; }

@media print {
  .topbar, .filters, .viewtoggle, .btn, .tabs { display: none !important; }
  .card { break-inside: avoid; box-shadow: none; }
  /* Les deux onglets sont dépliés par beforeprint : la rangée d'onglets, elle,
     n'a plus de sens sur papier. */
  .pagehead:empty, .pagehead { margin-bottom: 0; }
}

/* ══ Interactivité — filtres par clic, zoom, entrées animées ══════════════
   Règle commune : l'orange dit « ceci se clique / ceci est choisi », jamais
   « ceci est une donnée ». Tout mouvement tombe si le lecteur demande moins
   d'animation (bloc prefers-reduced-motion en fin de section). */

/* Fil de chargement : fin, en haut, sans voiler la page. */
.progres {
  position: fixed; top: 0; left: 0; right: 0; height: 2px; z-index: 80;
  pointer-events: none; opacity: 0; transition: opacity .2s;
  background: linear-gradient(90deg, transparent, var(--fuel), transparent);
  background-size: 40% 100%; background-repeat: no-repeat;
}
.progres.actif { opacity: 1; animation: progres-glisse 1.1s ease-in-out infinite; }
@keyframes progres-glisse { from { background-position: -40% 0; } to { background-position: 140% 0; } }

/* Pastilles des filtres actifs, au bout de la rangée de filtres. */
.pastilles { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.pastilles:empty { display: none; }
.pastille {
  display: inline-flex; align-items: center; gap: 2px; padding: 2px 2px 2px 10px;
  border-radius: 999px; font-size: 12.5px; font-weight: 550;
  background: var(--fuel-wash); color: var(--ink); border: 1px solid var(--fuel-wash-2);
  animation: pastille-entre .2s ease-out;
}
.pastille-x {
  width: 24px; height: 24px; border: 0; border-radius: 999px; background: transparent;
  color: var(--fuel-dark); font-size: 16px; line-height: 1; cursor: pointer;
}
.pastille-x:hover { background: var(--fuel-wash-2); }
.pastille-x:focus-visible, .pastille-tout:focus-visible { outline: 2px solid var(--fuel); outline-offset: 1px; }
.pastille-tout {
  border: 0; background: transparent; color: var(--fuel-dark); font: inherit; font-size: 12.5px;
  text-decoration: underline; cursor: pointer; padding: 4px 6px;
}
@keyframes pastille-entre { from { opacity: 0; transform: scale(.92); } }

/* Courbe : le trait se dessine à l'entrée. */
.trace-entree { stroke-dasharray: 1; stroke-dashoffset: 1; animation: trace-dessine .9s cubic-bezier(.3,.7,.2,1) forwards; }
@keyframes trace-dessine { to { stroke-dashoffset: 0; } }

/* Colonnes : elles poussent depuis l'axe, en cascade. */
.barre-entree { transform-box: fill-box; transform-origin: 50% 100%; animation: barre-pousse .55s cubic-bezier(.2,.7,.2,1) both; }
@keyframes barre-pousse { from { transform: scaleY(0); } }
.colonne { transition: opacity .15s; }
.colonne.en-retrait { opacity: .35; }

/* Sélection du zoom sur la courbe. */
.chart-brush { fill: var(--fuel); fill-opacity: .14; stroke: var(--fuel); stroke-width: 1; pointer-events: none; }
.chart-focus:focus { outline: none; }
.chart-focus:focus-visible { outline: 2px solid var(--fuel); outline-offset: 2px; }

/* Tableau croisé : un domaine qui filtre. */
.xt-filtre {
  border: 0; background: transparent; padding: 0; font: inherit; color: inherit; text-align: left;
  cursor: pointer; text-decoration: underline; text-decoration-color: var(--line-2); text-underline-offset: 3px;
}
.xt-filtre:hover { color: var(--fuel-dark); text-decoration-color: currentColor; }
.xt-filtre[aria-pressed="true"] { color: var(--fuel-dark); font-weight: 700; }
.xt-filtre:focus-visible { outline: 2px solid var(--fuel); outline-offset: 2px; border-radius: 3px; }
table.crosstab tr.ligne-active > * { background: var(--fuel-wash); }

/* Tuile de format : son titre filtre le tableau de bord. */
.tile-filtre {
  border: 0; background: transparent; padding: 0; font: inherit; cursor: pointer;
  display: inline-flex; align-items: center; gap: 5px;
}
.tile-filtre::after { content: "›"; opacity: 0; transform: translateX(-3px); transition: opacity .15s, transform .15s; }
.tile-filtre:hover { color: var(--ink); }
.tile-filtre:hover::after, .tile-filtre:focus-visible::after { opacity: 1; transform: none; }
.tile-filtre[aria-pressed="true"] { color: var(--fuel-dark); }
.tile-filtre[aria-pressed="true"]::after { content: "×"; opacity: 1; transform: none; }
.tile-filtre:focus-visible { outline: 2px solid var(--fuel); outline-offset: 2px; border-radius: 3px; }

/* Changer d'onglet : la section arrive, elle ne « saute » pas. */
.onglet:not([hidden]) { animation: onglet-entre .25s ease-out; }
@keyframes onglet-entre { from { opacity: 0; transform: translateY(4px); } }

@media (prefers-reduced-motion: reduce) {
  .progres.actif, .pastille, .trace-entree, .barre-entree, .onglet:not([hidden]) { animation: none; }
  .trace-entree { stroke-dasharray: none; stroke-dashoffset: 0; }
  .tile-filtre::after, .colonne { transition: none; }
}
@media print {
  .progres, .pastilles { display: none !important; }
  .trace-entree, .barre-entree { animation: none; stroke-dasharray: none; stroke-dashoffset: 0; }
}

/* ══ Événements du partenaire ════════════════════════════════════════════ */

/* Marqueur sur les courbes : un trait fin, discret, sous les séries. */
.marqueur-ligne { stroke-width: 1.5; stroke-dasharray: 2 3; opacity: .75; }

.evenements { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.evenement {
  display: grid; grid-template-columns: 12px minmax(0, 1.2fr) minmax(0, 1.6fr) auto;
  gap: 14px; align-items: start; padding: 12px 4px; border-top: 1px solid var(--line);
}
.evenement:first-child { border-top: 0; }
.evenement.hors-periode { opacity: .6; }
.evenement-pastille { width: 12px; height: 12px; border-radius: 50%; margin-top: 4px; }
.evenement-titre { font-weight: 650; font-size: 14px; color: var(--ink); }
.evenement-cat { font-weight: 500; font-size: 12px; color: var(--ink-muted); }
.evenement-quand { font-size: 12.5px; color: var(--ink-2); margin-top: 2px; }
.evenement-note { font-size: 12px; color: var(--ink-muted); margin-top: 4px; white-space: pre-line; }
.evenement-effet { font-size: 13px; color: var(--ink-2); display: flex; flex-wrap: wrap; gap: 6px 16px; align-items: center; }
.evenement-mesure { display: inline-flex; align-items: center; gap: 6px; color: var(--ink); font-variant-numeric: tabular-nums; }
.evenement-comparaison { flex-basis: 100%; font-size: 11.5px; color: var(--ink-muted); }
.evenement-actions { display: flex; gap: 4px; }
.evenement-vide { padding: 14px 4px; color: var(--ink-muted); font-size: 13px; }
.evenement-n { display: none; }
@media (max-width: 900px) {
  .evenement { grid-template-columns: 12px minmax(0, 1fr); }
  .evenement-effet, .evenement-actions { grid-column: 2; }
}

/* Le formulaire, dans un <dialog> natif. */
.dialogue {
  border: 1px solid var(--line-2); border-radius: var(--radius); padding: 0;
  width: min(480px, calc(100vw - 32px)); background: var(--surface); color: var(--ink);
  box-shadow: var(--shadow-tip);
}
.dialogue::backdrop { background: rgba(8, 12, 20, .45); }
.dialogue form { padding: 20px 22px; display: flex; flex-direction: column; gap: 12px; }
.dialogue h3 { margin: 0 0 2px; font-size: 17px; }
.dialogue .champ { display: flex; flex-direction: column; gap: 5px; font-size: 12.5px; font-weight: 600; color: var(--ink-2); border: 0; margin: 0; padding: 0; }
.dialogue .champ legend { padding: 0; margin-bottom: 5px; }
.dialogue input[type="text"], .dialogue input[type="date"], .dialogue select, .dialogue textarea {
  font: inherit; font-weight: 400; font-size: 14px; color: var(--ink); background: var(--surface-2);
  border: 1px solid var(--line-2); border-radius: var(--radius-sm); padding: 8px 10px; min-height: 38px;
}
.dialogue textarea { resize: vertical; }
.dialogue .choix { display: flex; align-items: center; gap: 8px; font-weight: 500; color: var(--ink); font-size: 13.5px; min-height: 28px; }
.dialogue .jours { display: flex; flex-wrap: wrap; gap: 6px; }
.dialogue .jours label {
  display: inline-flex; align-items: center; gap: 5px; font-weight: 500; font-size: 13px; color: var(--ink);
  border: 1px solid var(--line-2); border-radius: 999px; padding: 5px 10px; cursor: pointer;
}
.dialogue .jours label:has(input:checked) { border-color: var(--fuel); background: var(--fuel-wash); }
.dialogue .deux { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.dialogue .muted { font-weight: 400; }
.dialogue-erreur { color: var(--bad); font-size: 13px; min-height: 0; }
.dialogue-erreur:empty { display: none; }
.dialogue-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 4px; }
@media print { #carteEvenements .evenement-actions, #ajouterEvenement { display: none; } }

/* ══ Export PDF (impression) ═════════════════════════════════════════════ */
.entete-impression { display: none; }
/* Marges de page à ZÉRO : sans marge, Chrome n'a plus où écrire ses en-têtes
   et pieds de page (date, 127.0.0.1…, « 1/3 ») — un rapport de partenaire
   n'en veut pas, et ils mangeaient la hauteur utile. Les marges sont posées
   par le rapport lui-même (body.impression .wrap et #ongletDetail). */
@page { size: letter landscape; margin: 0; }
@media print {
  /* Couleurs exactes : sans ça, le navigateur retire les aplats des barres,
     des pastilles et des tuiles « pour économiser l'encre ». */
  html, body { background: #fff !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  .entete-impression {
    display: block; margin: 0 0 12px; padding: 0 0 10px; border-bottom: 2px solid var(--fuel);
  }
  .entete-titre { font-size: 18px; font-weight: 750; color: var(--ink); margin-bottom: 6px; }
  .entete-impression dl { display: grid; grid-template-columns: max-content 1fr; gap: 2px 14px; margin: 0; font-size: 11px; }
  .entete-impression dt { color: var(--ink-muted); font-weight: 600; }
  .entete-impression dd { margin: 0; color: var(--ink); }
  /* Ce qui ne sert qu'à l'écran. */
  #banner, #alert, .pastilles, .progres, .tip, dialog, .legend .item[data-off="1"] { display: none !important; }
  .rangee { break-inside: avoid; }
  .onglet { animation: none !important; }
  /* L'onglet Détail commence sur une nouvelle page. */
  #ongletDetail { break-before: page; }
  .crosstab-scroll { max-height: none !important; overflow: visible !important; }
}

/* ══ PDF condensé : deux pages Lettre paysage ═════════════════════════════
   « body.impression » n'existe que le temps de l'impression (beforeprint →
   afterprint). Ces règles s'appliquent donc AUSSI à l'écran pendant ce
   temps : c'est voulu, les graphiques se redessinent à ce moment-là et
   prennent ainsi la largeur qu'ils auront sur la feuille (≈ 979 px).
   Page 1 : performance. Page 2 : détail. */
body.impression { font-size: 10.5px; }
body.impression .wrap { max-width: 979px !important; width: 979px; padding: 0 !important; margin: 0 !important; }
body.impression .pagehead, body.impression .filters, body.impression .topbar { display: none !important; }
body.impression .rangee { gap: 8px !important; margin-bottom: 8px !important; }
body.impression .card { border-radius: 8px; box-shadow: none; }
body.impression .card-head { padding: 6px 10px 2px !important; gap: 6px; min-height: 0; }
body.impression .card-head h3 { font-size: 12px; }
body.impression .card-head .hint, body.impression .hint { font-size: 9.5px; }
body.impression .card-body { padding: 4px 10px 8px !important; }
body.impression .legend { padding: 0 0 4px; gap: 10px; font-size: 9.5px; }
body.impression .axis-label { font-size: 10px; }

/* En-tête : titre et détails sur deux lignes, pas une colonne. */
body.impression .entete-impression { display: block; margin: 0 0 8px; padding: 0 0 6px; border-bottom: 2px solid var(--fuel); }
body.impression .entete-titre { font-size: 15px; font-weight: 750; margin-bottom: 3px; color: var(--ink); }
body.impression .entete-impression dl { display: flex; flex-wrap: wrap; gap: 1px 14px; margin: 0; font-size: 9.5px; }
body.impression .entete-impression dt { color: var(--ink-muted); font-weight: 600; }
body.impression .entete-impression dt::after { content: " :"; }
body.impression .entete-impression dd { margin: 0 6px 0 -10px; color: var(--ink); }

/* Tuiles de mesure : compactes. */
body.impression .kpis { gap: 6px !important; }
body.impression .kpi { padding: 6px 8px !important; }
body.impression .kpi .value { font-size: 15px !important; }
body.impression .kpi .sub { font-size: 9.5px !important; margin-top: 2px !important; }
body.impression .kpi .spark { display: none; }

/* Ce que le PDF laisse de côté : les repères du jour (datés, pas de la
   période) et les trois vues « par appareil » qui répètent la même chose —
   la barre « Part du revenu » les résume. */

body.impression .card:has(#devicesChart), body.impression .pile:has(#auctionChart) { display: none !important; }
body.impression .rangee:has(#deviceShare) { grid-template-columns: 1fr !important; }
body.impression #deviceTiles { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); margin-top: 6px !important; }

/* Tuiles de format : les chiffres et la courbe, sans l'anneau. */
body.impression .tile-ring { display: none; }
body.impression #formatTiles .statcard { padding: 6px 10px; }
body.impression #formatTiles .value { font-size: 15px; }

/* Événements : une ligne serrée chacun. */
body.impression .evenement { padding: 4px 2px; gap: 8px; grid-template-columns: 10px minmax(0, 1.1fr) minmax(0, 2fr); }
body.impression .evenement-actions, body.impression #ajouterEvenement { display: none !important; }
body.impression .evenement-titre { font-size: 11px; }
body.impression .evenement-quand, body.impression .evenement-comparaison, body.impression .evenement-note { font-size: 9.5px; }
body.impression .evenement-effet { font-size: 10.5px; gap: 2px 10px; }
body.impression .evenement.hors-periode { display: none; }

/* Page 2 : annonceurs à gauche, le reste empilé à droite. */
body.impression #ongletDetail {
  display: grid !important; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  gap: 8px; align-items: start; break-before: page;
}
body.impression #ongletDetail .rangee { display: contents; }
body.impression #ongletDetail .rangee:first-child > .card { grid-row: span 3; }
body.impression #ongletDetail .card { margin: 0; }
body.impression table.data { font-size: 9.5px; }
body.impression table.data th, body.impression table.data td { padding: 2px 6px !important; }
body.impression .crosstab-scroll, body.impression .scroll-x { max-height: none !important; overflow: visible !important; }
body.impression .cardnote, body.impression .disclaimer { font-size: 8.5px; line-height: 1.35; margin: 4px 0 0; }
body.impression #advertiserPivot .cardnote { font-size: 8.5px; }

/* Page 1 en grille de 12 colonnes : les graphiques côte à côte plutôt
   qu'empilés. Les rangées d'écran s'effacent (display: contents) et leurs
   cartes se placent directement dans la grille, dans l'ordre du document :
     tuiles (4) | courbe (8)
     événements (12)
     mensuel (4) | impressions (4) | inventaire (4)
     analyse (4) | trois formats (2+2+2) | part du revenu (2)          */
body.impression #ongletPerformance {
  display: grid !important; grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: 6px; align-items: stretch;
}
body.impression #ongletPerformance > .rangee { display: contents; }
body.impression #ongletPerformance > * > * { margin: 0 !important; min-width: 0; }
body.impression #kpis { grid-column: span 4; grid-template-columns: repeat(2, minmax(0, 1fr)) !important; align-content: start; }
body.impression .card:has(#trendChart) { grid-column: span 8; }
body.impression #carteEvenements { grid-column: span 8; }
body.impression .card:has(#monthlyChart),
body.impression .card:has(#impressionsChart),
body.impression .card:has(#inventaireChart),
body.impression .card:has(#inventaireAnalyse) { grid-column: span 4; }
body.impression #formatTiles > .statcard { grid-column: span 2; }
body.impression .card:has(#deviceShare) { grid-column: span 2; }
body.impression #deviceTiles { display: none !important; }
body.impression #impressionsChart { min-height: 0 !important; }
body.impression .card-head.stack { gap: 0; }
body.impression #monthlyHint, body.impression #inventaireHint, body.impression #analyseFenetre { display: none; }
body.impression .tile-head { gap: 6px; }
body.impression .tile-spark span { display: none; }
body.impression #inventaireTuiles { gap: 4px !important; }
body.impression #inventaireTuiles .small-value { font-size: 13px; }
body.impression .analyse { font-size: 9.5px; margin: 4px 0 0; }
/* Derniers resserrements (mesurés sur RPMweb : 766 px → objectif 733). */
body.impression .tile-spark { display: none; }
body.impression .kpi { padding: 5px 8px !important; }
body.impression .kpi .value { font-size: 14px !important; }
body.impression .kpi .label { font-size: 9.5px !important; }
body.impression #content > .cardnote, body.impression #content > .disclaimer { font-size: 7.5px; line-height: 1.3; margin-top: 3px; }
/* Sur papier, pas de commandes, et la période est déjà dans l'en-tête du PDF. */
body.impression #metricPicker, body.impression #monthlyMetric, body.impression #yoyToggle,
body.impression .seg, body.impression #trendHint { display: none !important; }
body.impression .vue-partenaire #trendHint, body.impression #trendHint { min-height: 0 !important; }
/* Six tuiles en 3 × 2 plutôt que 2 × 3 : la rangée du haut perd un tiers. */
body.impression #kpis { grid-template-columns: repeat(3, minmax(0, 1fr)) !important; }
body.impression .kpi .value { font-size: 13px !important; white-space: nowrap; }
body.impression .kpi .sub { flex-wrap: wrap; }
/* Page 2 : les tableaux tiennent dans leur demi-page. */
body.impression .card-filter, body.impression select { display: none !important; }
body.impression table.data { font-size: 8.5px; width: 100%; table-layout: auto; }
body.impression table.data th { font-size: 7.5px; white-space: normal; line-height: 1.15; }
body.impression table.data th, body.impression table.data td { padding: 2px 4px !important; }
body.impression table.crosstab th.grouphead { min-width: 0 !important; max-width: 150px; white-space: normal; }
body.impression table.data td, body.impression table.data th { min-width: 0 !important; }
/* En-têtes de tableaux : ni majuscules ni espacement sur papier — un mot seul
   (« ORDINATEUR ») ne passe pas à la ligne et imposait sa largeur. */
body.impression table.data th { text-transform: none; letter-spacing: 0; }
body.impression #ongletDetail { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
/* La ligne de total gardait sa taille d'écran et imposait la largeur des colonnes. */
body.impression table.data tfoot td, body.impression table.data tfoot th,
body.impression table.data tr.grandtotal td, body.impression table.data tr.grandtotal th { font-size: 8.5px !important; }
body.impression table.crosstab th.grouphead, body.impression table.crosstab th.grouphead button { font-size: 8.5px !important; }

/* ── Retouches après le premier vrai PDF (3 pages au lieu de 2) ──────────
   Page Lettre paysage sans marge : 1056 × 816 px CSS. Le rapport pose ses
   marges : 34 px en haut et en bas, 38 px sur les côtés → 980 × 748 utiles. */
body.impression .wrap { width: 1056px !important; max-width: 1056px !important; box-sizing: border-box;
  padding: 34px 38px 0 !important; }
body.impression #ongletDetail { padding-top: 34px; }

/* Repères (hier, ce mois-ci, cette année) : trois petites tuiles à droite
   des événements. */
body.impression #marks { display: grid !important; grid-column: span 4;
  grid-template-columns: repeat(3, minmax(0, 1fr)) !important; gap: 6px !important; align-content: start; }
body.impression .mark { padding: 6px 8px !important; margin: 0 !important; }
body.impression .mark-label { font-size: 8px; }
body.impression .mark-quand { margin-left: 3px; }
body.impression .mark-value { font-size: 13px; margin-top: 1px; white-space: nowrap; }
body.impression .mark-value.muted { font-size: 11px; }
body.impression .mark-sub, body.impression .mark-foot { font-size: 8px; margin-top: 1px; }

/* Événements : UNE ligne chacun. Les règles « écran étroit » ne doivent
   jamais s'appliquer au papier : tout est posé ici explicitement. */
body.impression #evenementsHint { display: none; }
body.impression .evenement { display: flex !important; align-items: center; gap: 8px; padding: 2px 0 !important;
  border-top: 0 !important; grid-template-columns: none !important; }
body.impression .evenement-pastille { width: 8px; height: 8px; margin: 0; flex: none; }
body.impression .evenement-corps { display: flex; align-items: baseline; gap: 6px; min-width: 0; flex: 1 1 auto; }
body.impression .evenement-titre { font-size: 10px; white-space: nowrap; }
body.impression .evenement-cat { display: none; }
body.impression .evenement-quand { margin: 0; font-size: 9px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
body.impression .evenement-note, body.impression .evenement-comparaison { display: none; }
body.impression .evenement-effet { flex: none; flex-wrap: nowrap !important; gap: 10px !important; font-size: 9.5px !important;
  grid-column: auto !important; }
body.impression .evenement-mesure .delta { font-size: 8.5px; padding: 0 4px; }
body.impression .evenement-n { display: inline !important; font-size: 8.5px; color: var(--ink-muted); }
body.impression .evenement-vide { padding: 2px 0; font-size: 9px; }
/* Le calendrier sous le titre plutôt que tronqué : la rangée a de toute
   façon la hauteur des trois repères à côté. */
body.impression .evenement-corps { flex-direction: column; align-items: flex-start; gap: 0; }
body.impression .evenement-quand { overflow: visible; white-space: nowrap; }

/* ══ Météo du jour ════════════════════════════════════════════════════════ */
.meteo {
  display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600;
  color: var(--ink); padding: 4px 10px; border-radius: 999px;
  background: var(--surface); border: 1px solid var(--line); cursor: help;
}
.meteo .meteo-icone { display: inline-flex; color: var(--s4); }
.meteo.indisponible { color: var(--ink-muted); font-weight: 500; }
.meteo.indisponible .meteo-icone { color: var(--ink-muted); }
.btn-icone { display: inline-flex; align-items: center; justify-content: center; padding: 0; width: 34px; height: 32px; }
.btn-icone[aria-pressed="false"] { color: var(--ink-muted); }
@media print { .meteo, #meteoBtn { display: none !important; } }
body.impression .meteo, body.impression #meteoBtn { display: none !important; }
.meteo .meteo-icone { color: var(--ink-2); }
.meteo[data-condition="ensoleille"] .meteo-icone { color: var(--s4); }

/* ══ Météo par jour : icônes au-dessus de la courbe, carte de lecture ══════ */
.meteo-jours { color: var(--ink-2); }
.meteo-jours .meteo-point { fill: var(--ink-muted); }
.meteo-picto.meteo-ensoleille, .meteo-ligne-icone.meteo-ensoleille { color: var(--s4); }
.meteo-picto.meteo-pluie, .meteo-picto.meteo-averses, .meteo-picto.meteo-orage,
.meteo-ligne-icone.meteo-pluie, .meteo-ligne-icone.meteo-averses, .meteo-ligne-icone.meteo-orage { color: var(--s1); }
.meteo-lignes { list-style: none; margin: 0; padding: 0; }
.meteo-ligne {
  display: grid; grid-template-columns: 20px minmax(90px, 1fr) 70px minmax(0, 1.6fr) minmax(0, 1.6fr) auto;
  gap: 10px; align-items: center; padding: 8px 4px; border-top: 1px solid var(--line); font-size: 13px;
}
.meteo-ligne:first-child { border-top: 0; }
.meteo-ligne-icone { display: inline-flex; color: var(--ink-2); }
.meteo-ligne-nom { font-weight: 650; color: var(--ink); }
.meteo-ligne-n { color: var(--ink-muted); font-size: 12px; }
.meteo-ligne-mesure { display: inline-flex; align-items: center; gap: 6px; color: var(--ink); font-variant-numeric: tabular-nums; }
.meteo-ligne-prudence { font-size: 11.5px; color: var(--ink-muted); }
@media (max-width: 900px) { .meteo-ligne { grid-template-columns: 20px 1fr auto; } .meteo-ligne-mesure { grid-column: 2 / -1; } }
/* PDF : la carte reste à l'écran (deux pages) ; les icônes de la courbe suivent. */
body.impression #carteMeteo { display: none !important; }
@media print { #carteMeteo { display: none !important; } }

/* Notes internes de Fuel : jamais dans un PDF remis au partenaire. */
.note-fuel { border-left: 2px solid var(--fuel); padding-left: 8px; }
@media print { .note-fuel { display: none !important; } }
body.impression .note-fuel { display: none !important; }

/* Seconde mesure sous la première (impressions sous le revenu). */
table.crosstab .xt-sous { display: block; font-size: 11px; font-weight: 500; color: var(--ink-muted); line-height: 1.3; }
