/* Polices : chargées via <link rel="preconnect"> + <link rel="stylesheet"> dans le
   <head> de chaque page publique (parallélisé, non bloquant en chaîne comme @import).
   Les pages publiques rendent theme-piste par défaut (class sur <body>) → seules les
   fontes du thème PISTE (Fraunces, Plus Jakarta Sans, Newsreader, JetBrains Mono) sont
   chargées. Barlow/DM Mono ne servent plus qu'à login/backoffice (qui ont leur propre
   <link>). */

:root {
  --red: #E8002D;
  --red-dark: #b5001f;
  --black: #0a0a0a;
  --dark: #111111;
  --dark2: #1a1a1a;
  --dark3: #222222;
  --dark4: #2c2c2c;
  --mid: #444;
  --light: #aaaaaa;
  --lighter: #cccccc;
  --white: #f5f5f5;
  /* Identité de marque (pilotage du look depuis un seul endroit) */
  --brand-gradient: linear-gradient(to right, #ff3300 0%, #3a0000 100%);
  /* Podium — médailles unifiées site-wide (Phase 5b) */
  --medal-gold:   #f0c030;
  --medal-silver: #c0c0c0;
  --medal-bronze: #cd7f32;
  /* Couleurs de catégorie (sémantique éditoriale) — palette canonique (Phase 6) */
  --cat-results:  #E10600;
  --cat-culture:  #2E8F4E;
  --cat-actu:     #E8B400;
  --font-display: 'Barlow Condensed', sans-serif;
  --font-body: 'Barlow', sans-serif;
  --font-mono: 'DM Mono', monospace;

  /* ─── COUCHE SÉMANTIQUE (Phase 4) ────────────────────────────────────────
     Tokens de RÔLE, simples alias des primitives ci-dessus. Objectif : les
     composants consomment ces tokens (et non les primitives) → changer de
     design system = redéfinir cette seule couche. Aucun impact visuel (alias).
     ⚠️ var() est résolu UNE fois au :root → ces tokens ne suivent PAS seuls le
     mode clair ; ils sont RE-DÉCLARÉS dans body.light-mode (et le bloc chrome). */
  --color-accent:         var(--red);        /* accent principal (liens, hover, barres) */
  --color-accent-strong:  var(--red-dark);   /* accent appuyé / hover foncé */
  --color-bg:             var(--black);      /* fond de page */
  --color-surface:        var(--dark2);      /* cartes, widgets, panneaux */
  --color-surface-alt:    var(--dark3);      /* surface secondaire / fond subtil */
  --color-border:         var(--dark3);      /* bordures */
  --color-border-strong:  var(--dark4);      /* bordures appuyées */
  --text-primary:         var(--white);      /* titres, texte fort */
  --text-body:            var(--lighter);    /* corps de texte */
  --text-secondary:       var(--light);      /* méta, légendes */
  --text-muted:           var(--mid);        /* texte estompé */
  --font-heading:         var(--font-display); /* titres */
  --font-data:            var(--font-mono);    /* chiffres, labels, données */
  /* (--font-body est déjà un token de rôle : on le garde tel quel.) */

  /* ─── Tokens thématisables additionnels (migration des littéraux de page) ───
     Valeur par défaut = le littéral historique → AUCUN changement sur le thème
     par défaut. Un thème (ex. theme-piste) peut les redéfinir. */
  --color-accent-rgb: 232, 0, 45;   /* = #E8002D en composantes RGB, pour rgba(var(--color-accent-rgb), α) */
  --brand-stripe:     #cc0000;       /* rayures décoratives (SVG du header) */
  --hero-fallback:    linear-gradient(135deg, #1a0a0a 0%, #2d1010 40%, #1a0505 100%); /* fond de secours derrière les visuels hero */
  --img-matte:        #fff;          /* matte derrière les photos (letterbox / chargement) */
  --img-placeholder:  linear-gradient(135deg, #1a1a2e, #16213e); /* fond carte quand pas d'image (bleu) */
  --img-placeholder-warm: linear-gradient(135deg, #1a0a0a, #2d1010); /* fond hero/featured (rouge sombre) */
  --img-placeholder-cool: linear-gradient(135deg, #0e0814, #180f28); /* fond carte listing (violet sombre) */

  /* ─── ÉCHELLES DESIGN SYSTEM (Phase 1) ───────────────────────────────────
     Nouvelles variables, calquées sur les valeurs déjà utilisées dans le site.
     Rien ne les consomme encore : aucun impact visuel. Elles servent de
     vocabulaire commun pour la migration progressive des styles en dur. */

  /* Espacements (padding / margin / gap) */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
  --sp-5: 20px; --sp-6: 24px; --sp-8: 32px; --sp-10: 40px; --sp-12: 48px;

  /* Rayons de bordure */
  --radius-xs: 2px; --radius-sm: 3px; --radius-md: 4px;
  --radius-lg: 6px; --radius-xl: 10px; --radius-pill: 999px;

  /* Ombres */
  --shadow-sm: 0 1px 4px rgba(0,0,0,.2);
  --shadow-md: 0 8px 24px rgba(0,0,0,.4);
  --shadow-lg: 0 12px 40px rgba(0,0,0,.5);

  /* Tailles de texte (échelle observée 8 → 26px) */
  --fs-2xs: 8px; --fs-xs: 9px;  --fs-sm: 10px; --fs-base: 12px;
  --fs-md: 13px; --fs-lg: 15px; --fs-xl: 18px; --fs-2xl: 22px; --fs-3xl: 26px;

  /* Graisses */
  --fw-regular: 400; --fw-medium: 600; --fw-bold: 700; --fw-black: 900;

  /* Plans (z-index) — valeurs alignées sur l'existant */
  --z-header: 100; --z-mobile-menu: 98; --z-modal: 1000; --z-toast: 1100;

  /* Transitions usuelles */
  --transition-fast: .12s; --transition-base: .15s; --transition-slow: .25s;
}

/* ─── LIGHT MODE ─────────────────────────────── */
body.light-mode {
  --black:   #F8F7F4;
  --dark:    #ffffff;
  --dark2:   #ffffff;
  --dark3:   #eeece8;
  --dark4:   #dedbd6;
  --mid:     #888888;
  --light:   #555555;
  --lighter: #333333;
  --white:   #111111;
  /* Re-déclaration de la couche sémantique pour qu'elle suive le mode clair
     (sinon elle reste figée sur les valeurs résolues au :root). */
  --color-accent:        var(--red);
  --color-accent-strong: var(--red-dark);
  --color-bg:            var(--black);
  --color-surface:       var(--dark2);
  --color-surface-alt:   var(--dark3);
  --color-border:        var(--dark3);
  --color-border-strong: var(--dark4);
  --text-primary:        var(--white);
  --text-body:           var(--lighter);
  --text-secondary:      var(--light);
  --text-muted:          var(--mid);
}

/* Header et barre prochaine séance toujours en dark */
body.light-mode header,
body.light-mode #next-session-bar {
  --black:   #0a0a0a;
  --dark:    #111111;
  --dark2:   #1a1a1a;
  --dark3:   #222222;
  --dark4:   #2c2c2c;
  --mid:     #444;
  --light:   #aaaaaa;
  --lighter: #cccccc;
  --white:   #f5f5f5;
  /* idem : re-déclarer la sémantique pour que ce chrome reste dark en mode clair */
  --color-accent:        var(--red);
  --color-accent-strong: var(--red-dark);
  --color-bg:            var(--black);
  --color-surface:       var(--dark2);
  --color-surface-alt:   var(--dark3);
  --color-border:        var(--dark3);
  --color-border-strong: var(--dark4);
  --text-primary:        var(--white);
  --text-body:           var(--lighter);
  --text-secondary:      var(--light);
  --text-muted:          var(--mid);
}

/* ─── THÈME DE DÉMO (Phase 5) — preuve de concept du design system ────────────
   Redéfinit UNIQUEMENT la couche sémantique (Phase 4). Tout composant déjà câblé
   sur ces tokens (pour l'instant : la sidebar — widgets, tags, listes, classement)
   se re-skinne sans toucher au markup. NON appliqué par défaut : pour tester,
   ajouter  class="theme-demo"  sur le <body> d'une page. */
body.theme-demo {
  --color-accent:        #00d2ff;
  --color-accent-strong: #0090b0;
  --color-bg:            #07111a;
  --color-surface:       #0e1f2e;
  --color-surface-alt:   #16344a;
  --color-border:        #16344a;
  --color-border-strong: #1f4a66;
  --text-primary:        #eaf6ff;
  --text-body:           #b8d4e6;
  --text-secondary:      #7fa8c0;
  --text-muted:          #4a6678;
  /* le header (chrome de marque) suit aussi le thème de démo */
  --brand-gradient:      linear-gradient(to right, #00d2ff 0%, #07111a 100%);
}

/* ─── THÈME PISTE (built-in) — design system « asphalte + ember » ─────────────
   Look complet, dark canonique (cf. design system PISTE, juin 2026). Comme
   theme-demo, mais en version COMPLÈTE : en plus des 13 tokens, il redéfinit la
   typo (Fraunces / Plus Jakarta Sans / JetBrains Mono) et porte des signatures
   visuelles scopées (coins carrés, cartes bordées sans ombre, filet rouge appuyé,
   accent « ember » pour le live). NON appliqué par défaut : activé par la classe
   body.theme-piste (back-office → Design). Sans la classe, aucun impact. */
body.theme-piste {
  /* Primitives — redéclarées pour que les consommateurs directs (fond de page
     via var(--black), chrome header, dropdowns…) suivent PISTE. Cf. body.light-mode
     qui procède pareil : un var() au :root est résolu une fois, il faut redéclarer. */
  --red:     #E10600;
  --red-dark:#B30500;
  --black:   #0A0A0B;
  --dark:    #131316;
  --dark2:   #131316;
  --dark3:   #1C1C1F;
  --dark4:   #2A2A2E;
  --mid:     #6B6B72;
  --light:   #9A9AA0;
  --lighter: #C4C4C8;
  --white:   #F8F7F4;
  /* Couche sémantique — palette asphalte + rouge de marque */
  --color-accent:        #E10600;   /* brand-red */
  --color-accent-strong: #B30500;   /* brand-red-deep (hover/pressé) */
  --color-bg:            #0A0A0B;   /* asphalt-950 — fond de page */
  --color-surface:       #131316;   /* asphalt-900 — cartes / widgets */
  --color-surface-alt:   #1C1C1F;   /* asphalt-800 — surface surélevée */
  --color-border:        #2A2A2E;   /* asphalt-700 — bordures */
  --color-border-strong: #3D3D42;   /* asphalt-600 — bordures appuyées */
  --text-primary:        #F8F7F4;   /* bone — titres / texte fort */
  --text-body:           #C4C4C8;   /* asphalt-300 — corps */
  --text-secondary:      #9A9AA0;   /* asphalt-400 — méta / légendes */
  --text-muted:          #6B6B72;   /* asphalt-500 — estompé */
  /* Typo PISTE — le kit est SURTOUT EN SANS (Plus Jakarta, 40 usages) ; le serif
     Fraunces (12 usages) est réservé aux GRANDS titres éditoriaux. On met donc
     tout en sans par défaut (nav, cartes, listes, section labels, logo) et on
     applique Fraunces uniquement sur .hero-main-title/.article-title/.cat-title/
     .featured-title (règle plus bas). On redéfinit les primitives car beaucoup
     d'éléments consomment --font-display / --font-mono en direct. */
  --font-display:        "Plus Jakarta Sans", "Helvetica Neue", system-ui, sans-serif;
  --font-mono:           "JetBrains Mono", "SF Mono", Consolas, monospace;
  --font-heading:        "Plus Jakarta Sans", "Helvetica Neue", system-ui, sans-serif;
  --font-body:           "Plus Jakarta Sans", "Helvetica Neue", system-ui, sans-serif;
  --font-data:           "JetBrains Mono", "SF Mono", Consolas, monospace;
  /* Chrome de marque : barre rouge → tarmac */
  --brand-gradient:      linear-gradient(to right, #E10600 0%, #0A0A0B 100%);
  /* Tokens de rôle additionnels propres à PISTE */
  --color-live:          #FF6B00;   /* ember — live / breaking / pit heat */
  --radius-card:         0;          /* PISTE est « sharp » : coins carrés */
  --shadow-card:         none;       /* cartes bordées, pas flottées */
  /* Tokens thématisables additionnels — versions PISTE */
  --color-accent-rgb:    225, 6, 0;  /* #E10600 */
  --brand-stripe:        var(--color-accent);  /* les rayures suivent l'accent */
  --hero-fallback:       linear-gradient(135deg, #1C1C1F 0%, #131316 40%, #0A0A0B 100%); /* asphalte */
  --img-matte:           #0A0A0B;    /* matte sombre au lieu du blanc */
  --img-placeholder:     linear-gradient(135deg, #2A2A2E, #0A0A0B); /* asphalte */
  --img-placeholder-warm: linear-gradient(135deg, #2A2A2E, #0A0A0B);
  --img-placeholder-cool: linear-gradient(135deg, #2A2A2E, #0A0A0B);
  /* (couleurs de catégorie : pas d'override PISTE — elles n'existent pas dans le kit) */
}

/* ── PISTE — MODE CLAIR ──────────────────────────────────────────────────────
   Le kit supporte les DEUX modes (:root clair + [data-theme="dark"]). theme-piste
   pose le sombre par défaut ; ce bloc rétablit le toggle clair/sombre : quand
   body porte AUSSI .light-mode, on redéclare primitives + sémantique vers la
   palette CLAIRE de PISTE (bone/paper, texte asphalte). Spécificité (2 classes)
   > body.theme-piste seul → c'est bien le clair qui gagne quand il est actif. */
body.theme-piste.light-mode {
  /* Primitives — palette claire */
  --black:   #F8F7F4;   /* bone — fond de page */
  --dark:    #FFFFFF;
  --dark2:   #FFFFFF;   /* paper — surfaces/cartes */
  --dark3:   #E2E2E4;   /* asphalt-200 — bordures / surfaces subtiles */
  --dark4:   #C4C4C8;   /* asphalt-300 — bordures appuyées */
  --mid:     #9A9AA0;   /* asphalt-400 */
  --light:   #6B6B72;   /* asphalt-500 — texte secondaire */
  --lighter: #2A2A2E;   /* asphalt-700 — corps */
  --white:   #0A0A0B;   /* asphalt-950 — texte fort (foncé sur clair) */
  --red:     #E10600;
  --red-dark:#B30500;
  /* Sémantique — re-déclarée (sinon figée sur le sombre du :root theme-piste) */
  --color-accent:        #E10600;
  --color-accent-strong: #B30500;
  --color-bg:            #F8F7F4;
  --color-surface:       #FFFFFF;
  --color-surface-alt:   #F1F1F0;
  --color-border:        #E2E2E4;
  --color-border-strong: #C4C4C8;
  --text-primary:        #0A0A0B;
  --text-body:           #2A2A2E;
  --text-secondary:      #6B6B72;
  --text-muted:          #9A9AA0;
  --img-matte:           #FFFFFF;  /* matte clair derrière les photos */
}
/* Header en MODE CLAIR : suit le clair comme le kit (fond bone, texte foncé) —
   surcharge la convention site « header toujours sombre » (body.light-mode header). */
body.theme-piste.light-mode header {
  --black: #F8F7F4; --dark: #FFFFFF; --dark2: #FFFFFF; --dark3: #E2E2E4; --dark4: #C4C4C8;
  --mid: #9A9AA0; --light: #6B6B72; --lighter: #2A2A2E; --white: #0A0A0B;
  --color-bg: #F8F7F4; --color-surface: #FFFFFF; --color-border: #E2E2E4;
  --text-primary: #0A0A0B;
  background-color: rgba(248, 247, 244, 0.82);  /* bone translucide */
  background-image: none;                       /* neutralise le dégradé rouge de base */
  border-bottom: 1px solid var(--color-border);
}
/* Logo + toggle lisibles en MODE CLAIR : le logo est forcé blanc par un filtre
   inline (brightness(0) invert(1)) → on le repasse en noir ; la piste du toggle
   est blanc translucide (invisible sur bone) → on l'assombrit + pouce rouge. */
/* (ancien filtre du logo supprimé : le logo PF gère le mode clair par échange de variante) */
body.theme-piste.light-mode .theme-toggle-track { background: rgba(10,10,11,0.28); }
body.theme-piste.light-mode .theme-toggle-thumb { background: #0A0A0B; }

/* ── Signatures PISTE scopées au thème (au-delà des tokens) ─────────────────── */
/* Cartes : coins carrés, pas d'ombre au repos ; au survol, soulèvement + filet
   rouge à gauche (pas d'ombre). */
/* Cartes (NewsCard du kit) : radius 6, BARRE ROUGE 4px en haut du corps, et hover
   .race-card = léger lift + balayage rouge diagonal + zoom miniature + eyebrow qui
   glisse (le code du kit utilise bien ce hover, contrairement au texte du README). */
body.theme-piste .article-card {
  border-radius: 6px;
  box-shadow: none;
  transition: transform 360ms cubic-bezier(0.22,1,0.36,1);
}
body.theme-piste .article-card:hover {
  transform: translateY(-3px);
  box-shadow: none;
  border-color: var(--color-border);
}
body.theme-piste .article-card-body { border-top: 4px solid var(--color-accent); }
/* Variante LIVE NEWS (catégorie « Résultats ») : accent EMBER au lieu du rouge
   (barre de tête, eyebrow + pastille, balayage de survol) — 2e type de carte du kit. */
body.theme-piste .article-card.is-live .article-card-body { border-top-color: var(--color-live); }
/* Fond placeholder LIVE NEWS = ember (comme NewsCard.thumbBg du kit) ; editorial
   reste asphalte (token de carte). Vaut pour les cartes ET l'article en avant. */
body.theme-piste .article-card.is-live .article-card-img,
body.theme-piste .featured-article.is-live .featured-img {
  background: linear-gradient(135deg, #FF6B00, #B30500) !important;
}
body.theme-piste .article-card.is-live .article-card-cat { color: var(--color-live) !important; }
body.theme-piste .article-card.is-live .article-card-cat::before {
  content: ""; display: inline-block; width: 7px; height: 7px; border-radius: 50%;
  background: var(--color-live); margin-right: 6px; vertical-align: middle;
}
body.theme-piste .article-card.is-live .article-card-img::after {
  background: linear-gradient(115deg, transparent 38%, var(--color-live) 39%, var(--color-live) 41%, transparent 42%);
}
body.theme-piste .article-card-img { position: relative; }
body.theme-piste .article-card-img::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 3;
  background: linear-gradient(115deg, transparent 38%, var(--color-accent) 39%, var(--color-accent) 41%, transparent 42%);
  transform: translateX(-110%);
  transition: transform 520ms cubic-bezier(0.22,1,0.36,1);
}
body.theme-piste .article-card:hover .article-card-img::after { transform: translateX(110%); }
body.theme-piste .article-card-img img { transition: transform 520ms cubic-bezier(0.22,1,0.36,1); }
body.theme-piste .article-card:hover .article-card-img img { transform: scale(1.06); }
body.theme-piste .article-card-cat { display: inline-block; transition: transform 360ms cubic-bezier(0.22,1,0.36,1); }
body.theme-piste .article-card:hover .article-card-cat { transform: translateX(6px); }
@media (prefers-reduced-motion: reduce) {
  body.theme-piste .article-card,
  body.theme-piste .article-card-img::after,
  body.theme-piste .article-card-img img,
  body.theme-piste .article-card-cat { transition: none !important; transform: none !important; }
}
/* Widgets / panneaux : coins carrés, filet de titre rouge plus appuyé (4px). */
body.theme-piste .widget { border-radius: 6px; }
/* En-tête de widget (sbHead du kit) : filet 1px + segment rouge 40px en bas-gauche. */
body.theme-piste .widget-header {
  position: relative;
  border-bottom: 1px solid var(--color-border);
  font-weight: 700;
  letter-spacing: .14em;
}
body.theme-piste .widget-header::after {
  content: ""; position: absolute; left: 0; bottom: -1px;
  width: 40px; height: 2px; background: var(--color-accent);
}
/* Tags = PILULES (SidebarTags du kit : border-radius 999). */
body.theme-piste .tag { border-radius: 999px; }
/* Tableaux : entêtes en SANS 800 tracké (rtStyles.th du kit) ; n° de position en
   Fraunces serif (rtStyles.tdPos). */
body.theme-piste .res-table th { font-family: var(--font-body); font-weight: 800; letter-spacing: .14em; }
body.theme-piste .res-table .col-pos { font-family: "Fraunces", Georgia, serif; font-style: italic; }
/* Numéro pilote en BADGE (forme du kit : boîte mono arrondie centrée) — couleurs
   neutres de notre palette (pas le rouge-1er du kit, comme demandé). */
body.theme-piste .res-table .num-badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 28px; height: 20px; padding: 0 5px;
  font-family: var(--font-data); font-size: 11px; font-weight: 700;
  color: var(--text-primary);
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border-strong);
  border-radius: 2px;
}
/* Meilleur chrono de séance (temps du 1er sur séance chronométrée) : VIOLET
   « fastest » + ★ — convention timing MotoGP du kit (--data-fastest #8B2FB8).
   Scopé theme-piste : aucun effet sur le thème défaut. */
body.theme-piste .res-table .time-fastest { color: #8B2FB8; font-weight: 800; }
body.theme-piste .res-table .time-fastest::before { content: "\2605\00a0"; }

/* ── Tier 1 : MOTIFS PISTE (scopés au thème) ───────────────────────────────── */
/* Eyebrows / labels de catégorie : sans tracké (Plus Jakarta), pas le serif
   d'affichage. PISTE pose ses eyebrows en sans, pas en display. */
body.theme-piste .hero-card-cat,
body.theme-piste .article-card-cat,
body.theme-piste .small-cat,
body.theme-piste .featured-cat,
body.theme-piste .featured-badge,
body.theme-piste .page-banner-label,
body.theme-piste .eyebrow {
  font-family: var(--font-body);
  font-weight: 800;
  letter-spacing: .16em;
}
/* Catégories en ROUGE (comme le kit : eyebrow = brand-red), au lieu des couleurs
   par catégorie posées EN INLINE via getCategoryColor() → !important pour battre
   l'inline. Le badge plein de l'article passe en fond rouge. */
body.theme-piste .hero-card-cat,
body.theme-piste .article-card-cat,
body.theme-piste .small-cat,
body.theme-piste .featured-cat,
body.theme-piste .related-cat {
  color: var(--color-accent) !important;
}
body.theme-piste .article-cat-badge { background: var(--color-accent) !important; }
/* Filet de section : on GARDE le filet net d'origine. Le kit PISTE utilise des
   lignes nettes sous les titres, pas de rayures diagonales → pas d'override ici. */
/* En-têtes de page : on garde le filet 1px d'origine (lignes nettes, pas de rayures). */

/* ── Tier 2 : conteneurs d'images en coins CARRÉS (PISTE « sharp ») ─────────── */
body.theme-piste .hero-main-img,
body.theme-piste .hero-card-thumb,
body.theme-piste .article-card-img,
body.theme-piste .article-list-thumb,
body.theme-piste .related-img,
body.theme-piste .nav-thumb,
body.theme-piste .featured-img,
body.theme-piste .insta-thumb,
body.theme-piste .ig-thumb,
body.theme-piste .hv-thumb { border-radius: 0; }

/* .divider : on garde le séparateur fin d'origine (pas de rayures). */

/* Rayons « sharp » PISTE : cartes/conteneurs CARRÉS, micro-UI à 2px (échelle kit). */
body.theme-piste .insta-card,
body.theme-piste .ig-card,
body.theme-piste .featured-article,
body.theme-piste .hv-card { border-radius: 6px; }
body.theme-piste .see-all-btn,
body.theme-piste .filter-chip,
body.theme-piste .page-btn,
body.theme-piste .refresh-btn,
body.theme-piste .rescrape-btn,
body.theme-piste .cat-badge,
body.theme-piste .featured-badge,
body.theme-piste .nsb-pill,
body.theme-piste .search-box { border-radius: 2px; }

/* Utilitaire indicateur live (ember pulsant) : <span class="live-pulse">DIRECT</span> */
body.theme-piste .live-pulse { display: inline-flex; align-items: center; }
body.theme-piste .live-pulse::before {
  content: ""; width: 8px; height: 8px; border-radius: 50%; margin-right: 6px;
  background: var(--color-live);
  animation: piste-live-pulse 1.4s cubic-bezier(0.22,1,0.36,1) infinite;
}
@keyframes piste-live-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(255,107,0,.7); }
  70%  { box-shadow: 0 0 0 10px rgba(255,107,0,0); }
  100% { box-shadow: 0 0 0 0 rgba(255,107,0,0); }
}

/* ── Skin avancé PISTE (scopé thème) — rapproche du UI kit sans toucher la structure ── */
/* Header : NOIR PLAT + filet hairline, au lieu du dégradé rouge. C'est le plus gros
   levier visuel : le bandeau rouge est ce qui « date » le plus vs le kit PISTE.
   (Les rayures rouges SVG en haut à droite ressortent alors comme accent — voulu.) */
body.theme-piste header {
  background-color: rgba(10, 10, 11, 0.82);   /* translucide → laisse voir le blur */
  background-image: none;                     /* neutralise le dégradé rouge de base */
  border-bottom: none;
  position: sticky; top: 0; z-index: 100;     /* reste affiché au scroll */
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
}
/* (filet entre header et barre retiré) */
body.theme-piste header::after { content: none; }
/* Menu mobile + hamburger : suivent le mode clair/sombre (étaient figés en dark). */
body.theme-piste .hamburger span { background: var(--text-primary); }
body.theme-piste .mobile-menu { background: var(--color-bg); }
body.theme-piste .mobile-menu a { color: var(--text-primary); border-bottom-color: var(--color-border); }
body.theme-piste .mobile-menu a:hover { background: var(--color-surface-alt); }
/* Nav (hStyles.navItem du kit) : sans 13px/600, CASSE NORMALE, gris (fg-2) ;
   actif/survol = texte fort + soulignement rouge, sans fond. */
body.theme-piste .nav-item {
  display: inline-flex;
  align-items: center;
  height: 34px;            /* hauteur uniforme → soulignement actif aligné entre items ET avec le trait rouge du logo (36px, trait à ~95 % de sa hauteur) */
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--text-secondary);
  border-radius: 4px;
  padding: 0 12px;
}
body.theme-piste .nav-item:hover,
body.theme-piste .nav-item.active {
  background: transparent;
  color: var(--text-primary);
  border-radius: 0;
}
/* Trait rouge (actif/survol) via ::after positionné 2px SOUS l'item — au lieu du
   box-shadow collé au bas — pour aérer de 2px l'espace entre le texte et le trait. */
body.theme-piste .nav-item:hover::after,
body.theme-piste .nav-item.active::after {
  content: '';
  position: absolute;
  left: 0; right: 0;
  bottom: -2px;
  height: 2px;
  background: var(--color-accent);
}
/* Items de sous-menu : sans, casse normale (le kit n'a pas de dropdown, on reste cohérent). */
body.theme-piste .dropdown a {
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
}
/* Sous-menu : survol = fond subtil + texte clair, SANS liseré rouge vertical
   (le rouge reste réservé à l'état actif — parent souligné / sous-item .current).
   Évite les deux rouges concurrents. */
body.theme-piste .dropdown a:hover {
  background: var(--color-surface-alt);
  color: var(--text-primary);
  border-left-color: transparent;
}
/* Sous-item de la page courante : c'est LUI qui porte l'accent rouge (état). */
body.theme-piste .dropdown a.current {
  color: var(--color-accent);
  border-left-color: var(--color-accent);
}
/* Barre session = LiveBar du kit : TOUJOURS sombre + texte clair, dans les DEUX
   modes (on re-déclare ses tokens en sombre, donc le mode clair ne l'éclaircit pas). */
body.theme-piste #next-session-bar {
  --black: #1C1C1F; --dark2: #131316; --dark3: #2A2A2E; --dark4: #3D3D42;
  --white: #F8F7F4; --lighter: #C4C4C8; --light: #9A9AA0; --mid: #6B6B72;
  --color-bg: #19191c; --color-surface: #131316; --color-border: #3D3D42;
  --text-primary: #F8F7F4; --text-body: #C4C4C8; --text-secondary: #9A9AA0; --text-muted: #6B6B72;
  /* Barre en EMBRASEMENT : rouge à gauche → ember orange à droite (toutes pages). */
  background: linear-gradient(100deg, #D5211F 0%, #E10600 78%, #FF6B00 100%);
  position: relative;
  border-bottom: none;
}
/* (TEST) filet dégradé du bas de la barre séance retiré. */
body.theme-piste #next-session-bar::after { content: none; }
body.theme-piste .nsb-pill { background: #0A0A0B; border-radius: 999px; padding: 4px 14px; margin-right: 14px; }  /* pastille noire arrondie + un peu d'air avant le drapeau */
/* Texte de la barre lisible sur l'embrasement (la session était en rouge = invisible). */
body.theme-piste #next-session-bar .nsb-name,
body.theme-piste #next-session-bar .nsb-session,
body.theme-piste #next-session-bar .nsb-time {
  color: #fff;
  text-shadow: 0 1px 2px rgba(0,0,0,.35);
}
body.theme-piste #next-session-bar .nsb-sep { color: rgba(255,255,255,.5); }

/* Barre séance — version COMPACTE mobile. Cachée par défaut (tous thèmes) ;
   affichée ≤600px sous PISTE (le desktop ne bouge pas). */
#next-session-bar .nsb-ps { display: none; }
/* Mobile : la barre « Prochaine séance » n'apparaît QUE sur l'accueil
   (sur les autres pages elle porte .nsb-secondary → masquée ≤700px). Desktop inchangé. */
@media (max-width: 700px) {
  #next-session-bar.nsb-secondary { display: none !important; }
}
/* spécificité renforcée : bat la règle inline-flex des enfants (nsb-mobile est dans .nsb-right) */
#next-session-bar .nsb-right > .nsb-mobile { display: none; }
body.theme-piste #next-session-bar .nsb-mobile { font-family: var(--font-body); font-size: 10px; color: #fff; }
body.theme-piste #next-session-bar .nsb-mcode { font-weight: 700; text-shadow: 0 1px 2px rgba(0,0,0,.35); }
body.theme-piste #next-session-bar .nsb-mtime { font-family: var(--font-data); text-shadow: 0 1px 2px rgba(0,0,0,.35); }
body.theme-piste #next-session-bar .nsb-msep { color: rgba(255,255,255,.5); }
@media (max-width: 700px) {
  body.theme-piste #next-session-bar .nsb-flag,
  body.theme-piste #next-session-bar .nsb-name,
  body.theme-piste #next-session-bar .nsb-session,
  body.theme-piste #next-session-bar .nsb-time,
  body.theme-piste #next-session-bar .nsb-sep,
  body.theme-piste #next-session-bar .nsb-pf { display: none; }
  body.theme-piste #next-session-bar .nsb-ps { display: inline; }
  body.theme-piste #next-session-bar .nsb-mobile { display: inline-flex; align-items: center; gap: 8px; }
  body.theme-piste #next-session-bar .container { justify-content: center; }  /* mobile/très petit : centré (comme avant — la marque est masquée) */
}
/* Très petit écran : on retire le code du GP (et son séparateur), on garde le drapeau. */
@media (max-width: 350px) {
  body.theme-piste #next-session-bar .nsb-mgp { display: none; }
}
/* Hero : voile de protection NOIR (scrim du kit — l'ember venait du fond du
   placeholder, pas du voile ; sur une vraie photo le scrim est noir). */
body.theme-piste .hero-main-overlay {
  background: linear-gradient(180deg, transparent 0%, transparent 25%, rgba(10,10,11,0.92) 100%);
}
/* Densité éditoriale : un peu plus d'air sur les têtes de section (voix magazine). */
/* Titre de section (SectionHeader du kit) : sans 13px/800, tracking .18em. */
body.theme-piste .section-label { margin-bottom: 20px; font-size: 13px; font-weight: 800; letter-spacing: .18em; }
/* Lien « Voir tout » (SectionHeader.action du kit) : MONO 11px/500, tracking .12em. */
body.theme-piste .section-label > a {
  font-family: var(--font-data);
  font-weight: 500;
  letter-spacing: .12em;
}
/* Titres vidéo (VideoThumb du kit) : sans 12px, weight 500. */
body.theme-piste .hv-title { font-weight: 500; }
/* Léger dégonflage des titres de cartes (demande utilisateur — un cran sous le kit). */
body.theme-piste .article-card-title { font-size: 13px; }
body.theme-piste .article-list-title { font-size: 13px; }
/* Titres des cartes à droite du hero (« À la une ») — alignés à 13px. */
body.theme-piste .hero-card-title { font-size: 13px; }
/* Extrait de carte : un cran sous le titre pour garder la hiérarchie. */
body.theme-piste .article-card-excerpt { font-size: 12px; }
body.theme-piste .content-section { margin-bottom: 56px; }
/* Fraunces (serif) réservé aux GRANDS titres éditoriaux — comme le kit PISTE
   (serif = accent sur le hero/H1, le reste reste en sans). */
body.theme-piste .hero-main-title,
body.theme-piste .article-title,
body.theme-piste .cat-title,
body.theme-piste .featured-title {
  font-family: "Fraunces", Georgia, serif;
}
/* Hero + H1 d'article : Fraunces DROIT (préférence utilisateur ; le kit les met en italique). */
body.theme-piste .hero-main-title,
body.theme-piste .article-title { font-style: normal; letter-spacing: -0.025em; }
/* Footer = fStyles du kit : TOUJOURS asphalte (sombre) + texte clair, dans les
   deux modes (re-déclaration des tokens en sombre). */
body.theme-piste footer {
  --black: #0A0A0B; --dark2: #131316; --dark3: #2A2A2E; --dark4: #3D3D42;
  --white: #F8F7F4; --lighter: #C4C4C8; --light: #9A9AA0; --mid: #6B6B72;
  --color-bg: #0A0A0B; --color-surface: #131316; --color-border: #2A2A2E;
  --text-primary: #F8F7F4; --text-body: #C4C4C8; --text-secondary: #9A9AA0; --text-muted: #6B6B72;
  background: var(--color-bg);
  border-top: 1px solid var(--color-border);
}
/* ── Grain bitume (motif du design system, brand-motifs.html) ────────────────
   Trame de points quasi-blancs à ~5% sur les surfaces SOMBRES (footer, header,
   barre live). Les points étant quasi-blancs, ils sont invisibles sur fond clair
   → sans danger en mode clair (le header bone ne montre rien). */
body.theme-piste footer {
  background-image: radial-gradient(rgba(248,247,244,0.05) 1px, transparent 1.2px);
  background-size: 8px 8px;
}
/* ── FOOTER : barre unique (mutualisé, markup identique sur toutes les pages) ──
   Le pied de page est toujours sombre (tokens redéclarés ci-dessus). */
footer { padding: 28px 0; margin-top: 60px; }
.footer-bar {
  max-width: 1280px; margin: 0 auto; padding: 0 24px;
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 18px;
}
.footer-logo { display: inline-flex; align-items: center; justify-self: start; }
.footer-logo img { height: 26px; width: auto; display: block; }
.footer-links { display: flex; gap: 24px; justify-self: center; }
.footer-links a {
  font-family: var(--font-display); font-size: 12px; font-weight: 600;
  letter-spacing: 1px; text-transform: uppercase;
  color: var(--text-secondary); text-decoration: none; transition: color .12s;
}
.footer-links a:hover { color: var(--color-accent); }
.footer-links .footer-admin { display: inline-flex; align-items: center; }
.footer-copy {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: 1px;
  color: var(--text-muted); justify-self: end; text-align: right;
}
@media (max-width: 640px) {
  footer { padding: 24px 0; margin-top: 44px; }
  .footer-bar { grid-template-columns: 1fr; justify-items: center; text-align: center; gap: 14px; }
  .footer-logo, .footer-copy { justify-self: center; }
  .footer-copy { text-align: center; }
  .footer-links { flex-wrap: wrap; justify-content: center; gap: 12px 18px; }
}
/* Page article : corps long en Newsreader serif + lettrine rouge (ArticlePage du kit). */
body.theme-piste .article-body {
  font-family: "Newsreader", Georgia, serif;
  font-size: 17px;
  line-height: 1.7;
}
body.theme-piste .article-body p:first-of-type::first-letter {
  font-family: "Fraunces", Georgia, serif;
  font-style: italic;
  font-weight: 700;
  font-size: 78px;
  line-height: 0.85;
  float: left;
  margin: 8px 14px 0 0;
  color: var(--color-accent);
  letter-spacing: -0.04em;
}
/* Hero : on retire le cadre interne de 6px (`.hero-main-img::after`) qui crée une
   bordure sombre = la « marge » visible. L'image va alors bord à bord. */
body.theme-piste .hero-main-img::after { box-shadow: none; }

/* Pull-quote / citation (ArticlePage du kit) : Fraunces italique 26px, filet
   rouge à gauche. S'applique aux <blockquote> du corps d'article. */
body.theme-piste .article-body blockquote {
  font-family: "Fraunces", Georgia, serif;
  font-style: italic;
  font-weight: 600;
  font-size: 26px;
  line-height: 1.3;
  color: var(--text-primary);
  margin: 28px 0;
  padding: 20px 0 20px 24px;
  border-left: 3px solid var(--color-accent);
  letter-spacing: -0.015em;
}

/* Toggle switch */
.theme-toggle {
  display: flex;
  align-items: center;
  cursor: pointer;
  gap: 6px;
  flex-shrink: 0;
}
.theme-toggle-track {
  width: 32px;
  height: 18px;
  background: rgba(255,255,255,0.2);
  border-radius: 9px;
  position: relative;
  transition: background .25s;
}
.theme-toggle-thumb {
  width: 12px;
  height: 12px;
  background: white;
  border-radius: 50%;
  position: absolute;
  top: 3px;
  left: 3px;
  transition: transform .25s;
}
body.light-mode .theme-toggle-track { background: rgba(255,255,255,0.5); }
body.light-mode .theme-toggle-thumb { transform: translateX(14px); }
/* Icône du toggle thème : SVG « fil » (comme les autres icônes du header).
   Affiche l'icône du MODE COURANT : lune en sombre, soleil en clair.
   color:inherit sur le bouton → l'icône suit la couleur du header (un <button>
   n'hérite pas de la couleur par défaut, d'où l'invisibilité en sombre sans ça). */
.theme-toggle { color: inherit; }
.theme-toggle-icon { display: inline-flex; align-items: center; line-height: 0; }
.theme-toggle-icon svg { width: 15px; height: 15px; display: block; }
.theme-toggle-icon .icon-sun { display: none; }                     /* sombre → lune */
body.light-mode .theme-toggle-icon .icon-moon { display: none; }
body.light-mode .theme-toggle-icon .icon-sun  { display: block; }   /* clair → soleil */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* overflow-x: clip (et non hidden) → coupe le débordement horizontal SANS casser
   le position:sticky du header (hidden sur html/body empêche le sticky). */
html { scroll-behavior: smooth; overflow-x: clip; }
body {
  background: var(--black);
  color: var(--white);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.6;
  overflow-x: clip;
  max-width: 100%;   /* 100% (largeur hors scrollbar) et NON 100vw : 100vw inclut
                        la scrollbar verticale → la droite passait sous la barre et
                        était rognée (halos/effets coupés à droite). */
}
img, video { max-width: 100%; }
a { text-decoration: none; color: inherit; }
img { display: block; }

/* Empêche les iframes Getty (transform+scale) de déborder sur iOS Safari */
.hero-main-img,
.hero-card-thumb,
.article-card-img,
.article-list-thumb,
.related-img,
.nav-thumb {
  clip-path: inset(0);
  transform: translateZ(0);
}

/* ─── HEADER — socle partagé (Phase 2 : composant unifié) ────────────────────
   Auparavant copié-collé (avec dérives) dans chaque page. Désormais défini ici
   une seule fois. Le header utilise toujours ses propres couleurs (toujours dark). */
header {
  background: var(--brand-gradient);
  border-bottom: none;
  position: sticky;
  top: 0;
  z-index: 100;
  color: var(--white);
}

/* ─── Barre « Prochaine séance » — socle partagé (mutualisé, injecté par
   shared/session-bar.js sur toutes les pages). Le thème (embrasement, mobile…)
   est dans la section theme-piste plus haut. ───────────────────────────────── */
#next-session-bar {
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  padding: 9px 0;
  font-family: var(--font-body);
  font-size: 10px;
  color: var(--text-body);
}
#next-session-bar .container {
  max-width: 1280px; margin: 0 auto; padding: 0 24px;
  display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; line-height: 1;
}
#next-session-bar .container > * { display: inline-flex; align-items: center; line-height: 1; }
/* Marque à gauche de la barre (le header ne porte plus que le monogramme PF) */
.nsb-brand { gap: 8px; flex-shrink: 0; }
.nsb-brand-name {
  font-family: var(--font-display); font-size: 12px; font-weight: 800;
  letter-spacing: 2px; text-transform: uppercase; color: var(--text-primary); white-space: nowrap;
}
.nsb-brand-sep { opacity: .4; }
.nsb-brand-tag {
  font-family: var(--font-mono); font-size: 9px; letter-spacing: 1.5px;
  text-transform: uppercase; opacity: .75; white-space: nowrap;
}
body.theme-piste #next-session-bar .nsb-brand-name,
body.theme-piste #next-session-bar .nsb-brand-tag { color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,.35); }
/* Mobile : la marque ne s'affiche pas — la barre reste la version compacte d'origine */
@media (max-width: 700px) { #next-session-bar .nsb-brand { display: none; } }
/* Contenu séance : groupe aligné à droite */
.nsb-right { display: inline-flex; align-items: center; gap: 12px; flex-wrap: wrap; justify-content: flex-end; }
.nsb-pill {
  background: var(--color-accent); color: #fff;
  font-family: var(--font-display); font-size: 10px; font-weight: 700;
  letter-spacing: 1px; text-transform: uppercase; padding: 3px 8px;
  border-radius: 3px; flex-shrink: 0;
}
.nsb-session { color: var(--color-accent); font-weight: 700; text-transform: uppercase; font-size: 10px; letter-spacing: 0.5px; }
.nsb-name { color: var(--white); font-weight: 600; }
.nsb-sep { color: var(--dark4); }
.nsb-time { color: var(--lighter); }

.header-inner {
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 24px;
  display: flex;
  align-items: center;
  gap: 40px;
  height: 72px;
  position: relative;
  z-index: 2;
}
.logo { display: flex; flex-direction: row; align-items: center; gap: 10px; line-height: 1; flex-shrink: 0; }
/* Logo PF : deux variantes (blanche pour les fonds sombres, noire pour le mode clair) —
   pas de filtre CSS : le trait rouge du monogramme doit rester rouge dans les deux modes */
.logo-img { height: 42px; width: auto; display: block; }
.logo-img-light { display: none; }
body.theme-piste.light-mode .logo-img-dark { display: none; }
body.theme-piste.light-mode .logo-img-light { display: block; }
.logo-wordmark {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 800;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  color: var(--white);
  white-space: nowrap;
}
@media (max-width: 600px) { .logo-wordmark { display: none; } }
.logo-name {
  font-family: var(--font-display);
  font-size: 26px;
  font-weight: 900;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--white);
}
.logo-name span { color: var(--white); }
.logo-tagline {
  font-family: var(--font-mono);
  font-size: 9px;
  color: var(--white);
  letter-spacing: 2px;
  text-transform: uppercase;
  margin-top: 2px;
}

/* ─── NAVIGATION (desktop) — composant unifié (Phase 2b) ─────────────────────
   Menu principal + sous-menus déroulants. Canonique = page d'accueil.
   (États spécifiques type « .dropdown a.current » restent dans la page concernée.) */
nav { display: flex; align-items: center; gap: 4px; flex: 1; }
.nav-item {
  position: relative;
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
  padding: 8px 14px;
  border-radius: 3px;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
  white-space: nowrap;
}
.nav-item:hover { background: rgba(0,0,0,0.2); color: var(--white); }
.nav-item.active { color: var(--white); }
.nav-item .arrow { font-size: 8px; margin-left: 4px; opacity: 0.6; }
.dropdown {
  visibility: hidden; opacity: 0;
  position: absolute; top: 100%; left: 0;
  background: var(--dark2); border: 1px solid var(--dark4);
  border-radius: 4px; min-width: 230px;
  box-shadow: 0 8px 32px rgba(0,0,0,0.5); overflow: hidden;
  transition: opacity 0.15s, visibility 0.15s;
  transition-delay: 0.05s;
  pointer-events: none;
}
.nav-item:hover .dropdown { visibility: visible; opacity: 1; transition-delay: 0s; pointer-events: auto; }
.dropdown a {
  display: block;
  padding: 10px 16px;
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--lighter);
  transition: background 0.1s, color 0.1s;
  border-left: 3px solid transparent;
  border-bottom: 1px solid var(--dark3);
}
.dropdown a:last-child { border-bottom: none; }
.dropdown a:hover { background: var(--dark3); color: var(--white); border-left-color: var(--color-accent); }

/* ─── RECHERCHE + zone droite du header — composant unifié (Phase 2c) ────────
   La recherche se déplie au survol/focus. Canonique = page d'accueil. */
.header-right { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.search-box {
  display: flex; align-items: center; justify-content: center;
  background: transparent; border: 1px solid transparent;
  border-radius: 4px; padding: 6px 6px; gap: 0;
  width: 31px; overflow: hidden;
  transition: width 0.3s ease, border-color 0.2s, gap 0.3s ease, padding 0.3s ease;
  cursor: pointer;
}
.search-box:hover, .search-box:focus-within {
  width: 200px; border-color: var(--white);
  gap: 8px; padding: 6px 12px; cursor: text;
}
a[aria-label="Administration"]:hover { border-color: var(--white) !important; }
.search-box input {
  background: none; border: none; outline: none;
  color: var(--white); font-family: var(--font-body);
  font-size: 13px; width: 0; opacity: 0;
  transition: opacity 0.2s ease 0.1s;
}
.search-box:hover input, .search-box:focus-within input { width: 140px; opacity: 1; }
.search-box input::placeholder { color: rgba(255,255,255,0.5); }
.search-icon { color: var(--white); display: flex; align-items: center; flex-shrink: 0; }
.search-box:hover .search-icon, .search-box:focus-within .search-icon { color: var(--white); }

/* ─── CARTE ARTICLE (grille) — composant unifié (Phase 2d) ───────────────────
   Carte d'article en grille (accueil + listing). Canonique = page d'accueil. */
.article-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 5px;
  overflow: hidden;
  min-width: 0;
  cursor: pointer;
  transition: transform 0.15s, box-shadow 0.15s;
}
.article-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
  border-color: var(--color-border-strong);
}
.article-card-img {
  height: 240px;
  background: var(--img-placeholder);
  display: block;
  position: relative;
  overflow: hidden;
}
.article-card-body { padding: 14px; }
.article-card-title {
  font-family: var(--font-heading);
  font-size: 16px;
  font-weight: 700;
  line-height: 1.3;
  color: var(--text-primary);
  margin: 8px 0 6px;
}
/* Survol : titre légèrement atténué (opacity) au lieu du rouge — évite le
   « double rouge » avec le label de catégorie. opacity → marche en clair ET
   sombre (un gris fixe serait illisible en mode clair). Idem partout. */
.article-card:hover .article-card-title { opacity: 0.7; }
.article-card-excerpt {
  font-size: 13px;
  color: var(--text-secondary);
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.article-card-meta {
  font-family: var(--font-data);
  font-size: 10px;
  color: var(--text-muted);
  margin-top: 10px;
}
.article-card-cat {
  font-family: var(--font-data);
  font-size: 9px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--color-accent);
}
/* Variantes .article-card-cat.cX retirées (code mort) : la couleur des catégories
   vient de getCategoryColor() en inline → tokens --cat-results/analyses/culture/actu. */

/* ─── SIDEBAR (colonne de widgets) — composant unifié (Phase 2h) ─────────────
   Conteneur vertical des widgets (accueil, listing, article, évolution). */
.sidebar { display: flex; flex-direction: column; gap: 24px; }

/* ─── WIDGET (encart sidebar) — composant unifié (Phase 2e) ──────────────────
   Encart à en-tête rouge + corps (accueil, listing, article, évolution).
   Le contenu interne de chaque widget reste propre à sa page. */
.widget {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 5px;
  overflow: hidden;
}
.widget-header {
  background: var(--color-surface);
  padding: 10px 16px;
  font-family: var(--font-heading);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--text-primary);
  border-bottom: 2px solid var(--color-accent);
  display: flex;
  align-items: center;
  gap: 8px;
}
.widget-header .icon { color: var(--text-primary); display: flex; align-items: center; flex-shrink: 0; }
.widget-body { padding: 12px 16px; }

/* ─── TAGS (nuage de tags) — composant unifié (Phase 2f) ─────────────────────
   Widget « Tags » de la sidebar + barre de tags d'article. Base canonique = Home.
   (Évolution utilisait un survol vert : uniformisé en rouge à la mutualisation.) */
.tag-cloud { display: flex; flex-wrap: wrap; gap: 6px; }
.tag {
  font-family: var(--font-heading);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border-strong);
  color: var(--text-secondary);
  padding: 4px 10px;
  border-radius: 2px;
  cursor: pointer;
  transition: background 0.1s, color 0.1s, border-color 0.1s;
}
.tag:hover { background: var(--color-accent); color: #fff; border-color: var(--color-accent); }

/* ─── LIGNES DE LISTE — composant unifié (Phase 2f) ──────────────────────────
   Lignes numérotées des widgets de liste (articles récents, séances, plus lus).
   Base canonique = Home. */
.result-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px solid var(--color-border);
  cursor: pointer;
}
.result-item:last-child { border-bottom: none; }
.result-num {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 900;
  color: var(--dark4);
  width: 24px;
  flex-shrink: 0;
  line-height: 1;
}
.result-info { flex: 1; min-width: 0; }
.result-title {
  font-family: var(--font-heading);
  font-size: 12px;
  font-weight: 700;
  color: var(--text-body);
  line-height: 1.3;
}
.result-item:hover .result-title { opacity: 0.7; }
.result-meta {
  font-family: var(--font-data);
  font-size: 9px;
  color: var(--text-muted);
  margin-top: 2px;
}

/* ─── CLASSEMENT (lignes de standings) — composant unifié (Phase 2g) ──────────
   Widget « Classement Pilotes » de la sidebar (accueil, listing).
   Base canonique = Home. NB : le tableau de classement dans le corps d'article
   garde sa propre surcharge .stand-pts en local (composant distinct, hors widget). */
.stand-row {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 0;
  border-bottom: 1px solid var(--color-border);
}
.stand-row:last-child { border-bottom: none; }
.stand-pos {
  font-family: var(--font-heading);
  font-size: 13px; font-weight: 700;
  color: var(--text-secondary);
  width: 18px; text-align: center; flex-shrink: 0;
}
.stand-pos.p1 { color: var(--medal-gold); }
.stand-pos.p2 { color: var(--medal-silver); }
.stand-pos.p3 { color: var(--medal-bronze); }
.stand-name {
  flex: 1;
  font-family: var(--font-heading);
  font-size: 13px; font-weight: 700;
  color: var(--text-body);
}
.stand-pts {
  font-family: var(--font-heading);
  font-size: 13px; font-weight: 700;
  color: var(--text-secondary);
  width: 28px;
  text-align: right;
  flex-shrink: 0;
}

/* ─── TABLEAU RÉSULTATS / CLASSEMENT (corps d'article) — socle commun (Phase 3a) ─
   Squelette partagé par les tableaux du corps (résultats de course, classement
   général, évolution GP par GP). Accent unifié en rouge. Les colonnes propres à
   chaque type (moto/écart/temps/nation, GP) et la mise en page de .col-pts
   restent locales à chaque page ; seule leur COULEUR est mutualisée (rouge). */
.res-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.res-table thead tr { border-bottom: 1px solid rgba(255,255,255,.15); }
.res-table th { font-family: var(--font-data); font-size: 9px; font-weight: 400; letter-spacing: 1.5px; text-transform: uppercase; color: var(--text-secondary); padding: 6px 8px; text-align: left; }
.res-table td { padding: 8px 8px; border-bottom: 1px solid rgba(255,255,255,.05); color: var(--text-body); font-family: var(--font-body); }
.res-table tbody tr:hover { background: rgba(255,255,255,.03); }
.res-table .col-pos { font-family: var(--font-heading); font-weight: 800; font-size: 15px; width: 36px; }
.res-table .col-pos.p1 { color: var(--medal-gold); }
.res-table .col-pos.p2 { color: var(--medal-silver); }
.res-table .col-pos.p3 { color: var(--medal-bronze); }
.res-table .col-rider { font-weight: 600; color: var(--text-primary); min-width: 120px; }

/* ─── HAMBURGER ──────────────────────────────── */
.hamburger {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  background: none;
  border: none;
  cursor: pointer;
  padding: 6px;
  flex-shrink: 0;
  margin-left: 8px;
}
.hamburger span {
  display: block;
  width: 22px;
  height: 2px;
  background: #f5f5f5;
  border-radius: 2px;
  transition: transform 0.25s, opacity 0.25s;
}
.hamburger.open span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.hamburger.open span:nth-child(2) { opacity: 0; }
.hamburger.open span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* ─── MOBILE MENU ────────────────────────────── */
/* Toujours en dark quelle que soit le thème */
.mobile-menu {
  display: none;
  position: fixed;
  top: 72px;   /* = hauteur du header (.header-inner) : le menu mobile démarre juste dessous */
  left: 0;
  right: 0;
  bottom: 0;
  background: #0a0a0a;
  z-index: 98;
  overflow-y: auto;
  overscroll-behavior: contain;   /* le scroll du menu ne « fuit » pas vers la page */
  padding: 8px 0 32px;
}
.mobile-menu.open { display: block; }
.mobile-nav-group {
  display: block;
  padding: 16px 24px 6px;
  font-family: var(--font-display);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--color-accent);
}
.mobile-menu a {
  display: block;
  padding: 13px 24px;
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: #f5f5f5;
  border-bottom: 1px solid rgba(255,255,255,0.06);
  transition: background 0.15s, color 0.15s;
}
.mobile-menu a:hover  { background: rgba(255,255,255,0.05); }
.mobile-menu a.active { color: var(--color-accent); }
.mobile-menu a.sub    { padding-left: 36px; font-size: 13px; color: #aaaaaa; }

@media (max-width: 768px) {
  nav { display: none !important; }
  .hamburger { display: flex; }
  .logo-tagline { display: none; }
  .sidebar { display: none !important; }

  /* Vibreur décoratif du header : rogné d'un tiers sur la droite en mobile
     (280px × ⅓ ≈ 93px hors cadre ; le header masque le dépassement) */
  header { overflow: hidden; }
  header > svg[aria-hidden="true"] { right: -93px !important; }

  /* ── Contraintes largeur universelles ── */
  .container,
  .page-banner-inner,
  .header-inner {
    padding-left: 16px;
    padding-right: 16px;
    width: 100%;
    max-width: 100%;
  }
  .header-inner { gap: 12px; }

  /* ── Layouts grilles → colonne unique ── */
  .main-layout,
  .listing-layout,
  .article-layout,
  .evo-layout {
    grid-template-columns: 1fr !important;
    gap: 0;
  }

  /* ── Empêche les éléments de flux de dépasser ── */
  main, section, article, aside,
  .content-section, .instagram-section, .mobile-videos-section,
  .articles-grid, .article-card, .articles-list, .article-list-item,
  .insta-grid, .ig-grid, .ig-wrap,
  .videos-wrap, .videos-grid,
  .widget, .widget-body,
  .page-banner, .page-banner-inner,
  .hv-grid, .mobile-hv-grid {
    max-width: 100%;
    box-sizing: border-box;
  }
}
