/*
 * bb-podcast-tokens.css
 * BreachBuilders — Podcast · design system foundation.
 * Loaded as a dependency of every other podcast stylesheet.
 *
 * Lot 22 (v3 refonte, inspirée Radio France — voir design/mockups-v3.html) :
 * la section podcast passe en SOMBRE. Ce fichier ajoute la palette sombre
 * (`--bb-d-*`) et bascule les composants transverses (police, boutons, puces,
 * reset des titres) — sans RETIRER les tokens v2 (`--bb-green*`, `--bb-cream*`,
 * `--bb-white`) : les fiches épisode / saison / invité et le lecteur les
 * utilisent encore telles quelles jusqu'à leur propre lot de refonte (23-25).
 * Elles resteront lisibles (texte clair sur bandeau vert, cartes claires sur
 * fond desormais sombre) mais visuellement dépareillées entre-temps — normal
 * en cours de Phase 3, à ne pas déployer avant la fin.
 *
 * Palette : vert de marque #044229 (fond + surfaces) · accent #F2CFB3
 * Type : DM Sans seule (Playfair Display abandonné, cf. décision Lot 21)
 * Mobile-first. Breakpoints alignés sur Elementor Site Settings du site :
 *   base ≤767 · @768 (mobile landscape) · @992 (tablet portrait)
 *   · @1280 (laptop) · @1731 (desktop/widescreen)
 * Content width & gouttières = réglages container Elementor (1440 · 80/50/20).
 * Class prefix : .bbp-   ·   JS : bbPodcast*
 */

.bbp,
.bbp *,
.bbp *::before,
.bbp *::after { box-sizing: border-box; }
.bbp { margin: 0; }
/* :where() = spécificité nulle — ce reset ne doit JAMAIS l'emporter sur la
   marge d'un composant (bug identifié en maquette v3 : `.bbp h2{margin:0}`
   avait une spécificité classe+balise qui battait silencieusement toute
   règle à une seule classe comme `.bbp-section__h{margin-bottom:…}`, quel
   que soit l'ordre des règles dans le fichier). */
:where(.bbp h1, .bbp h2, .bbp h3, .bbp h4, .bbp p, .bbp ul, .bbp ol, .bbp blockquote, .bbp figure) { margin: 0; }

.bbp {
  /* ---- Palette de marque (retour utilisateur) : UN SEUL vert — #044229 —
     partout où le thème sombre v2/v3 utilisait jusqu'ici toute une gamme de
     verts/charbons proches mais différents (fond de page, surfaces
     élevées, accent v2) sans que ce soit jamais demandé explicitement.
     Idem pour l'accent : #F2CFB3 remplace l'ancien or/bronze #C8963E.
     Conséquence assumée : plus de dégradé de profondeur entre le fond de
     page et les surfaces "élevées" (cartes, badges…) — elles partagent
     toutes désormais le même vert. */
  --bb-green:      #044229;
  --bb-green-deep: #044229;
  --bb-green-soft: #044229;
  --bb-green-line: rgba(250, 247, 242, 0.14);
  --bb-cream:      #FAF7F2;
  --bb-cream-2:    #F1EADD;
  --bb-ink:        #1A1A17;
  --bb-ink-2:      #5C574E;
  --bb-line:       rgba(15, 34, 25, 0.12);
  --bb-white:      #FFFFFF;

  /* ---- accent BreachBuilders : partagé v2/v3 ---- */
  --bb-gold:       #F2CFB3;
  --bb-gold-soft:  #F2CFB3;
  --bb-gold-deep:  #F2CFB3;

  /* ---- v3 (Lot 22+) : fond + surfaces — même vert de marque partout,
     voir note ci-dessus. ---- */
  --bb-d-bg:          #044229;
  --bb-d-bg-soft:     #044229;
  --bb-d-surface:     #044229;
  --bb-d-surface-2:   #044229;
  --bb-d-surface-3:   #044229;
  --bb-d-ink:         #F4F1EA;
  --bb-d-ink-2:       #A7B0A5;
  --bb-d-ink-3:       #6E7A6E;
  --bb-d-line:        rgba(244, 241, 234, .12);
  --bb-d-line-strong: rgba(244, 241, 234, .22);

  --bb-font-title: "Playfair Display", Georgia, "Times New Roman", serif; /* v2 only, see note above */
  --bb-font-body:  "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

  --bb-radius:      14px;
  --bb-radius-sm:   10px;
  --bb-radius-lg:   16px;
  --bb-radius-pill: 999px;
  --bb-ease:        cubic-bezier(.22, 1, .36, 1);
  --bb-shadow:      0 4px 24px rgba(15, 34, 25, .08);
  --bb-shadow-lg:   0 16px 48px rgba(15, 34, 25, .18);
  --bb-maxw:        1440px;   /* = Elementor Content Width */
  --bb-readw:       720px;    /* readable column for long-form body text (v3) */
  --bb-listw:       1040px;   /* episode list / rail column (v3) */
  --bb-gutter:      20px;     /* = Elementor Container Padding (mobile) ; 50 @992 ; 80 @1280 */
  --bb-mini-z:      999999;
  /* offset for sticky elements — override if an Elementor sticky header sits on top */
  --bb-sticky-top:  0px;
  /* Translucent "pastille" card fill (Lot 23 ter, radiofrance-capture/ —
     rgba(255,255,255,.05-.08)-on-black there, adapted to our ink colour) :
     Provenant, Guests/"Avec", Team, transcript, aside cards, pager, most
     liked… anywhere a card sits directly on a dark page background without
     a visible border. Shared here (not per-stylesheet) since both the
     episode and the season page use it. */
  --bbp-card-fill:  rgba(244, 241, 234, .05);

  font-family: var(--bb-font-body);
  color: var(--bb-ink);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

.bbp img { max-width: 100%; height: auto; display: block; }
/* :where() — same bug class as above : plenty of components set their own
   link colour via a single class on an <a> (.bbp-guest__more, .bbp-guest__org,
   .bbp-prose a…) ; without this, ".bbp a" (0,1,1) silently forced them back
   to color:inherit regardless of source order. Found while checking the
   Lot 23 type-scale fix — same root cause, different property. */
:where(.bbp a) { color: inherit; }

.bbp :focus-visible {
  outline: 2px solid var(--bb-gold);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ---- Container ---- (mirrors the Elementor container: max-width + side padding) */
.bbp-wrap { max-width: var(--bb-maxw); margin-inline: auto; padding-inline: var(--bb-gutter); }
/* Narrower centred column for long-form body text (episode/season/guest prose,
   the "Resources & documentation" block…). */
.bbp-read { max-width: var(--bb-readw); margin-inline: auto; padding-inline: var(--bb-gutter); }
/* Episode list / rails : wider than .bbp-read, narrower than the full 1440
   content width (v3, Lot 22). */
.bbp-list-col { max-width: var(--bb-listw); margin-inline: auto; padding-inline: var(--bb-gutter); }
@media (min-width: 992px)  { .bbp { --bb-gutter: 50px; } }
@media (min-width: 1280px) { .bbp { --bb-gutter: 80px; } }

/* When the shortcode already sits inside a padded Elementor container, add
   .bbp--flush on the root so we don't double the constraint. */
/* --bb-listw (1040px, .bbp-list-col — episode list column on the season/guest
 * pages) needs resetting here too : found live on the season page, retour
 * utilisateur (« ça devrait être pleine largeur ») — the episode rows stayed
 * capped at 1040px and centered even in flush/elementor mode, unlike every
 * other rail/section already fixed for this. */
.bbp.bbp--flush { --bb-gutter: 0px; --bb-maxw: none; --bb-listw: none; }

/* ---- Headings ---- */
.bbp-eyebrow { font-size: 12px; font-weight: 600; letter-spacing: .16em; text-transform: uppercase; }
/* :where() — même raison que le reset de marge ci-dessus (Lot 22) : ce
   défaut ne doit jamais battre un composant à une seule classe qui choisit
   sa propre graisse (ex. .bbp-ep-title{font-weight:800}, Lot 23). Sans ça,
   « .bbp h1 » (classe+balise, spécificité 0,1,1) gagne toujours contre
   « .bbp-ep-title » (0,1,0) quel que soit l'ordre des règles — même bug que
   le reset de marge, sur font-weight cette fois. */
:where(.bbp h1, .bbp h2, .bbp h3, .bbp h4) {
  /* Lot 22 : DM Sans partout, Playfair Display abandonné (décision Lot 21).
     --bb-font-title reste défini (ci-dessus) pour ne rien casser ailleurs si
     une règle plus spécifique le réclame encore, mais n'est plus le défaut. */
  font-family: var(--bb-font-body); font-weight: 700; line-height: 1.15; letter-spacing: -.01em;
  color: inherit; /* follow the container — beat theme h1{} */
}
.bbp-h1 { font-size: clamp(32px, 20.8px + 3.4vw, 52px); }
.bbp-h2 { font-size: clamp(24px, 18.4px + 1.7vw, 32px); }

/* ---- Buttons ---- */
.bbp-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 44px; padding: 11px 22px;
  font-family: var(--bb-font-body); font-size: 15px; font-weight: 600;
  border: 1.5px solid transparent; border-radius: var(--bb-radius-pill);
  text-decoration: none; cursor: pointer;
  transition: transform .18s var(--bb-ease), background .18s, border-color .18s, color .18s;
}
.bbp-btn svg { width: 18px; height: 18px; flex: none; }
.bbp .bbp-btn--gold  { background: var(--bb-gold); color: var(--bb-green-deep); }
.bbp .bbp-btn--gold:hover  { background: var(--bb-gold-soft); transform: translateY(-1px); }
.bbp .bbp-btn--ghost { background: transparent; border-color: currentColor; color: var(--bb-green); }
.bbp .bbp-btn--ghost:hover { background: rgba(15, 34, 25, .06); }

/* ---- Back link (shared: episode / season / guest green headers) ----
   Selectors below are double-qualified (".bbp .bbp-x") on purpose: a plain
   single class on an <a> can lose its color to a same-or-higher-specificity
   theme/Elementor rule like ".elementor-kit-10 a" (found while auditing Lot
   23 — see tokens.css header). ".bbp .bbp-x" (0,2,0) reliably beats that
   (0,1,1) regardless of stylesheet order. */
.bbp .bbp-back {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 14px; font-weight: 600; color: rgba(250, 247, 242, .72);
  text-decoration: none; margin-bottom: 22px;
}
.bbp .bbp-back:hover { color: var(--bb-cream); }
.bbp-back svg { width: 15px; height: 15px; }

/* ---- "Listen also on" chips (shared: episode page, expanded mini-player) ---- */
.bbp-listen { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.bbp-listen__label { font-size: 13px; font-weight: 600; opacity: .75; flex-basis: 100%; }
@media (min-width: 768px) { .bbp-listen__label { flex-basis: auto; } }
.bbp .bbp-chip {
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 40px; padding: 8px 16px;
  border-radius: var(--bb-radius-pill);
  border: 1.5px solid var(--bb-line);
  background: var(--bb-white);
  font-size: 14px; font-weight: 600; text-decoration: none; color: var(--bb-ink);
  transition: border-color .18s, transform .18s var(--bb-ease);
}
.bbp .bbp-chip:hover { transform: translateY(-1px); border-color: var(--bb-gold); }
.bbp-chip__dot { width: 10px; height: 10px; border-radius: 50%; flex: none; }
.bbp--on-green .bbp-chip { background: transparent; border-color: var(--bb-green-line); color: var(--bb-cream); }

/* ---- Body sections — shared rhythm (episode + season pages, Lot 23 ter) ---- */
.bbp-section { padding-block: clamp(24px, 4vw, 36px); }
.bbp-section:first-child { padding-top: 0; }
.bbp-section + .bbp-section { border-top: 1px solid var(--bb-d-line); }
.bbp-section__h {
  font-weight: 800; letter-spacing: -.01em; color: var(--bb-d-ink);
  font-size: clamp(22px, 19.2px + .7vw, 28px); /* 22px → 28px : matches the site's H3 scale */
  margin-bottom: 20px;
}

/* ---- "People" card row — shared by episode "The team" / "Avec" (guests)
   and the season page's "Guests this season" / "The team" (Lot 23 ter).
   Translucent pastille, no border (radiofrance-capture/ reference). ---- */
.bbp-team { position: relative; }
.bbp-team__row { display: flex; flex-wrap: wrap; gap: 12px; }
.bbp-person {
  flex: 1 1 220px; display: flex; align-items: center; gap: 12px;
  background: var(--bbp-card-fill); border-radius: var(--bb-radius-lg); padding: 12px 16px;
}
.bbp .bbp-person { text-decoration: none; color: inherit; } /* when it's an <a> (guest line-up) */
.bbp-person__ph {
  width: 44px; height: 44px; border-radius: 50%; flex: none; overflow: hidden;
  display: grid; place-items: center;
  background: var(--bb-d-surface-3); color: var(--bb-d-ink); font-weight: 700; font-size: 13px;
}
.bbp-person__ph img { width: 100%; height: 100%; object-fit: cover; }
.bbp-person__name { display: block; font-weight: 700; font-size: 15px; color: var(--bb-d-ink); }
.bbp-person__role { display: block; font-size: 13px; color: var(--bb-d-ink-3); margin-top: 1px; }

/* ---- Carousel nav arrows (Lot 25) — radiofrance-capture/'s round prev/next
   buttons next to a section title. Shared: the archive page's Seasons strip
   AND its per-season episode carousels, plus the episode page's "More from
   this…" rails — anywhere `bbp_episode_group_heading(['arrows'=>true])` or
   the Seasons strip head is used, paired with a `[data-bbp-carousel]`
   wrapper for bb-podcast-archive.js to find. ---- */
/* Retour utilisateur : les flèches n'ont leur place que sur desktop (souris) —
 * sur mobile/tablette l'interaction naturelle est le swipe/scroll, garder les
 * flèches n'y ajoute que du bruit. Mobile-first : masquées par défaut,
 * révélées seulement à partir de @1280 — puis potentiellement re-masquées
 * par bb-podcast-archive.js (`.hidden`) s'il n'y a rien à faire défiler à
 * cette largeur (pas assez d'épisodes/saisons pour dépasser le conteneur).
 * `[hidden]` a besoin de sa propre règle : sans elle, `display:flex`
 * ci-dessous (règle auteur) bat le `display:none` de l'UA sur `[hidden]`
 * (même famille de piège que .bbp-mini[hidden]/.bbp-accordion__panel[hidden]
 * ailleurs dans le plugin). */
.bbp-carousel-arrows { display: none; gap: 8px; flex: none; }
.bbp-carousel-arrows[hidden] { display: none; }
@media (min-width: 1280px) { .bbp-carousel-arrows { display: flex; } }
.bbp .bbp-carousel-arrow {
  width: 40px; height: 40px; border-radius: 50%; flex: none; padding: 0;
  display: grid; place-items: center; cursor: pointer;
  background: var(--bb-d-surface); border: 1px solid var(--bb-d-line-strong); color: var(--bb-d-ink);
  transition: border-color .18s, color .18s, opacity .18s;
}
.bbp-carousel-arrow svg { width: 18px; height: 18px; }
.bbp-carousel-arrow:hover:not(:disabled) { border-color: var(--bb-gold); color: var(--bb-gold-soft); }
.bbp-carousel-arrow:disabled { opacity: .35; cursor: default; }

/* ---- Episode card rail (Lot 23, shared Lot 25) — "More from this season" /
   "More on this theme" (episode page) AND the archive page's episode-group
   carousels — redrawn Lot 25 on a real radiofrance.fr "Les derniers épisodes
   de {émission}" capture : 16:9 cover with duration overlaid bottom-left and
   a round play/watch button bottom-right (both over a bottom gradient
   scrim), title below, then the series name as an underlined line. ---- */
.bbp-rail { position: relative; }
/* Left/right inset, ALL breakpoints incl. desktop (retour utilisateur,
 * captures radiofrance.fr à l'appui) : un padding posé sur un ANCÊTRE
 * (section Elementor, ou même `.bbp-wrap`) contraint le défilement EN
 * PERMANENCE — testé en Elementor (padding-left 20px sur la section), le
 * décalage restait visible à chaque clic sur la flèche, contrairement à la
 * référence. Un padding posé directement sur l'élément qui défile
 * (`overflow-x:auto`, ici) se comporte différemment : visible au repos
 * (scrollLeft=0) avant la 1re carte, il sort du cadre dès qu'on scrolle et
 * ne revient plus — et un padding-inline étant symétrique, le même espace
 * réapparaît à droite une fois arrivé au bout du défilement (dernière
 * carte). Pas de marge négative ici — inutile (et contre-productive : elle
 * annule exactement ce padding) puisqu'il n'y a plus de gouttière ambiante
 * à contourner sur `.bbp-wrap` depuis que `container="elementor"` (flush)
 * est le défaut. */
.bbp-rail__row {
  display: flex; gap: 16px; overflow-x: auto; scrollbar-width: none; scroll-snap-type: x mandatory; padding-bottom: 6px;
  padding-inline: 20px; scroll-padding-inline: 20px;
}
.bbp-rail__row::-webkit-scrollbar { display: none; }
/* Inset progressif par palier — mêmes breakpoints Elementor que le reste du
 * plugin (768/992/1280/1731). Même sélecteur qu'au-dessus (spécificité
 * égale) : l'ordre dans le fichier suffit à prioriser la bonne valeur. */
@media (min-width: 768px)  { .bbp-rail__row { padding-inline: 25px; scroll-padding-inline: 25px; } }
@media (min-width: 992px)  { .bbp-rail__row { padding-inline: 40px; scroll-padding-inline: 40px; } }
@media (min-width: 1280px) { .bbp-rail__row { padding-inline: 60px; scroll-padding-inline: 60px; } }
@media (min-width: 1731px) { .bbp-rail__row { padding-inline: 80px; scroll-padding-inline: 80px; } }
.bbp .bbp-card {
  flex: 0 0 auto; width: 220px; scroll-snap-align: start; text-decoration: none; color: inherit;
  display: flex; flex-direction: column; border-radius: var(--bb-radius); overflow: hidden;
  background: #044229;
}
/* ".bbp .bbp-card" (0,2,0) here too — a bare ".bbp-card" override loses to
   the base rule above regardless of media query (same specificity trap the
   header comment warns about for the :where() resets). Found live: the
   pre-existing @768 override never actually applied either. */
@media (min-width: 768px)  { .bbp .bbp-card { width: 260px; } }
/* radiofrance-capture/ shows 3 full cards + a sliver of the 4th at desktop
   width (~1280px content column) — the fixed 260px card left ~5 fitting
   instead. Widening at the same breakpoints the page's own container/gutter
   already use (bb-podcast-tokens.css:121-122) keeps the two in step. */
@media (min-width: 992px)  { .bbp .bbp-card { width: 300px; } }
/* Retour utilisateur (revient sur l'essai "exactement 3, jamais coupée") :
 * même sur desktop, on veut le rendu radiofrance.fr — 3 cartes pleines +
 * une 4e visiblement entamée, cohérent avec l'inset gauche/droite ci-dessus
 * qui s'applique maintenant à tous les breakpoints. */
@media (min-width: 1280px) { .bbp .bbp-card { width: 380px; } }
/* display:block — .bbp-card__media is a <span> (inline by default), and
   aspect-ratio/width/height are no-ops on a non-replaced inline box. Without
   this, any card whose episode has no cover image (just the "Ep. N" text
   placeholder, no <img>) collapses to near-zero height and its neighbours'
   text overlaps it (found live on the archive page, Lot 25 — previously
   masked wherever every rail episode happened to have a real cover).
   Ratio widened to ~2:1 (was 16:10) — radiofrance-capture/'s own cards read
   noticeably flatter/wider than our original crop.
   overflow:hidden matters just as much as the aspect-ratio itself : a box
   with `aspect-ratio` but visible overflow gets an automatic min-height
   from its content, so a REAL cover photo (arbitrary intrinsic ratio, e.g.
   a square 800×800 upload) stretches the box past 2:1 to fit — exactly what
   happened here when this rule briefly lost its overflow:hidden migrating
   from bb-podcast-archive.css: episodes with a real cover rendered a
   near-square media box while coverless "Ep. N" placeholder cards (an
   absolutely-positioned <span>, unaffected by this) correctly stayed 2:1 —
   inconsistent card heights in the same rail. overflow:hidden makes the
   ratio a hard clip regardless of what's inside. */
.bbp-card__media { display: block; position: relative; aspect-ratio: 2 / 1; overflow: hidden; background: #044229; flex: none; }
.bbp-card__media img { width: 100%; height: 100%; object-fit: cover; }
.bbp-card__media .bbp-card__ph { position: absolute; inset: 0; display: grid; place-items: center; font: 700 20px var(--bb-font-body); color: var(--bb-d-ink-3); }
.bbp-card__dur {
  position: absolute; left: 10px; bottom: 10px; z-index: 1;
  font: 700 13px/1 var(--bb-font-body); color: #fff; text-shadow: 0 1px 3px rgba(0, 0, 0, .5);
}
.bbp-card__play {
  position: absolute; right: 10px; bottom: 10px; z-index: 1; width: 34px; height: 34px; border-radius: 50%;
  display: grid; place-items: center; background: #fff; color: #171410;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .35);
}
.bbp-card__play svg { width: 13px; height: 13px; margin-left: 2px; }
.bbp-card__play--yt { background: #FF3D3D; color: #fff; }
.bbp-card__badge {
  position: absolute; right: 8px; top: 8px; z-index: 1; background: rgba(18, 22, 15, .75); color: var(--bb-d-ink);
  font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  padding: 3px 8px; border-radius: var(--bb-radius-pill);
}
/* Title + series sit on their own surface block below the cover — matching
   radiofrance-capture/'s cards, where the caption is a distinct dark panel
   under the photo, not text floating on the page background. */
.bbp-card__body { display: block; flex: 1 1 auto; padding: 12px 14px 14px; }
.bbp-card__t {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  font-size: 15px; font-weight: 700; line-height: 1.35; color: var(--bb-d-ink);
}
.bbp-card:hover .bbp-card__t { color: var(--bb-gold-soft); }
.bbp-card__series { display: block; margin-top: 6px; font-size: 13px; color: var(--bb-gold-soft); text-decoration: underline; text-underline-offset: 2px; }

/* ---- Visually hidden (a11y) ---- */
.bbp-vh {
  position: absolute !important; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

@media (prefers-reduced-motion: reduce) {
  .bbp *, .bbp *::before, .bbp *::after { transition: none !important; animation: none !important; }
}
