/* =====================================================================
   ESS — Components: buttons, tags, cards, forms, stats, motifs
   ===================================================================== */

/* ---- Icons: sensible default size ---------------------------------
   SVG icons carry a viewBox but no width/height, and the base reset sets
   svg { max-width:100%; height:auto }. Without a scoped size an icon
   expands to fill its container. This baseline keeps any un-scoped icon
   at text size; contextual rules (.btn .ico, .tag .ico, …) still win. */
.ico { width: 1.15em; height: 1.15em; flex: none; }

/* ---- Jeu d'icônes : HugeIcons en SVG local (js/hugeicons.js) --------
   Une icône est un <i class="ico"> qui CONTIENT un <svg>, et non un <svg>
   nu. L'enveloppe n'est pas décorative : 128 règles de ces feuilles
   dimensionnent les icônes par `i.ico { font-size: … }` — hérité de la
   webfont Phosphor qu'on vient de remplacer. Le <svg> mesurant 1em, ces
   règles continuent de commander la taille, à l'identique.

   Le <i> reste au format 1.15em fixé ci-dessus (la boîte qu'occupait le
   glyphe) et centre son SVG : la géométrie des lignes existantes ne
   bouge pas d'un pixel. */
i.ico { display: inline-flex; align-items: center; justify-content: center; line-height: 1; }
i.ico > svg { width: 1em; height: 1em; max-width: 100%; max-height: 100%; flex: none; display: block; }

/* ---- Eyebrow (sur-titre) with signature diamond -------------------- */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-eyebrow);
  font-weight: var(--fw-bold);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-blue);
}
.eyebrow::before {
  content: "";
  width: 10px; height: 10px;
  background: var(--c-green);
  transform: rotate(45deg);
  flex: none;
}
.eyebrow--light { color: #cfe5f6; }
.eyebrow--light::before { background: var(--c-green); }

/* Double-diamond brand mark (∙∙) as inline motif */
.diamonds { display: inline-flex; gap: 6px; }
.diamonds i { width: 12px; height: 12px; background: var(--c-green); transform: rotate(45deg); }

/* ---- Section header ------------------------------------------------ */
.section-head { max-width: 720px; margin-bottom: var(--sp-6); }
.section-head.center { margin-inline: auto; }
.section-head .lead { color: var(--c-slate); font-size: var(--fs-lead); margin-top: var(--sp-3); }
.section--blue .section-head .lead,
.section--blue .lead { color: #d5e6f4; }

/* ---- Lead paragraph ------------------------------------------------ */
.lead { font-size: var(--fs-lead); color: var(--c-slate); line-height: 1.55; }

/* ---- Buttons ------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  /* Boîte resserrée autour du label. À 0.85em/1.5em, le rembourrage était
     généreux autour d'un texte de 14px : grande boîte, petit label — la
     proportion qui date un bouton plus vite que sa couleur. L'échelle
     typographique, elle, ne bouge pas. */
  padding: 0.75em 1.35em;
  border-radius: 5px;   /* CTA : coins légèrement adoucis (direction client) */
  font-family: var(--font-latin);
  font-weight: var(--fw-semi);
  font-size: var(--fs-sm);
  line-height: 1;
  letter-spacing: 0.012em;
  /* 1px et non 2px : à 2px, le contour pesait visuellement PLUS LOURD que
     l'aplat posé à côté de lui, ce qui inversait la hiérarchie voulue. */
  border: 1px solid transparent;
  transition: background var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease),
              box-shadow var(--dur-fast) var(--ease);
  white-space: nowrap;
}
/* Plus de `translateY(-2px)` au survol. Ce soulèvement était posé sur `.btn`,
   donc sur TOUTES les variantes : un lien texte `.btn--ghost` sautillait comme
   un aplat. Le mouvement quitte la boîte et passe dans le contenu (voir le
   double-losange du primaire plus bas), et l'accusé de survol se joue
   désormais en fond + anneau interne. L'appui devient un vrai enfoncement. */
.btn:active { box-shadow: inset 0 1px 3px rgba(18, 33, 46, .28); }
.btn .ico { width: 1.15em; height: 1.15em; }

/* PAS d'ombre au repos. `--sh-blue` était posée en permanence sous le primaire :
   c'est la signature datée de l'aplat surélevé, et c'était le seul endroit du
   système qui enfreignait sa propre règle « aucune ombre sur une surface au
   repos » (DESIGN.md, Floating-Only Rule). Le jeton reste défini : il garde sa
   place dans le vocabulaire d'ombres pour ce qui flotte réellement. */
.btn--primary { background: var(--c-blue); color: #fff; }
.btn--primary:hover { background: var(--c-blue-700); color: #fff; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .24); }

.btn--accent { background: var(--c-green); color: #fff; }
.btn--accent:hover { background: var(--c-green-700); color: #fff; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .28); }

.btn--outline { background: transparent; color: var(--c-blue); border-color: var(--c-line-strong); }
.btn--outline:hover { border-color: var(--c-blue); color: var(--c-blue); background: var(--c-mist); }

.btn--ghost { background: transparent; color: var(--c-blue); padding-inline: 0.6em; }
.btn--ghost:hover { color: var(--c-sky); }

/* REFUS — action destructrice, toujours SECONDAIRE : contour rouge, pas
   aplat. Un « Refuser » plein rivaliserait avec le primaire « Valider »
   posé à côté, alors que la règle plateforme veut un seul primaire par
   contexte. Le rouge dit la nature de l'action, le contour dit son rang. */
.btn--danger { background: transparent; color: var(--c-danger); border-color: var(--c-danger); }
.btn--danger:hover { background: var(--c-danger); color: #fff; border-color: var(--c-danger); }
.btn--danger:focus-visible { outline-color: var(--c-danger); }
/* Variante pleine : réservée à la CONFIRMATION d'un refus dans une
   modale, où elle est la seule action engageante de la boîte. */
.btn--danger-solid { background: var(--c-danger); color: #fff; border-color: var(--c-danger); }
.btn--danger-solid:hover { background: var(--c-danger-700); color: #fff; border-color: var(--c-danger-700); }

.btn--sky { background: var(--c-sky); color: #fff; }
.btn--sky:hover { background: var(--c-sky-600); color: #fff; }
.btn--on-blue { background: #fff; color: var(--c-blue); }
.btn--on-blue:hover { background: var(--c-mist); color: var(--c-blue); }
.btn--on-blue-outline { background: transparent; color: #fff; border-color: rgba(255,255,255,.55); }
.btn--on-blue-outline:hover { border-color: #fff; background: rgba(255,255,255,.1); color:#fff; }

.btn--yellow { background: var(--c-yellow); color: var(--c-ink); font-weight: var(--fw-bold); }
.btn--yellow:hover { background: #ffd84d; color: var(--c-ink); }

/* Tailles resserrées dans la même proportion que la base. */
.btn--lg { padding: 0.95em 1.7em; font-size: var(--fs-base); }
.btn--sm { padding: 0.55em 1em; font-size: var(--fs-xs); }
.btn--block { display: flex; width: 100%; }

/* ---- Le double-losange du primaire (EXTRANET) -----------------------
   Le motif de la marque — le « ∙∙ » vert du logo — signe l'action
   principale. C'est LUI qui déclare le rang, et non la couleur : le vert
   de `.btn--accent` peut donc rester vert sans prendre la place du bleu.

   Au repos un seul losange ; au survol le second se pose et le motif se
   complète, l'ensemble avançant de 4px — exactement le geste de
   `.link-arrow` déjà en place plus bas. Le mouvement est DANS le bouton,
   plus sous lui.

   Dessiné en pseudo-éléments : aucune modification du balisage, sur aucune
   page. `order` remet ::before APRÈS ::after dans la ligne flex, et la
   marge négative resserre la paire à 3px là où `gap` en imposerait 8.
   Propriétés `rotate`/`translate` séparées, et non `transform` : sinon la
   translation s'appliquerait dans le repère déjà tourné à 45°.

   Le second losange occupe sa place dès le repos (opacité 0) : la largeur
   du bouton ne bouge pas au survol. */
.btn--primary::after,
.btn--primary::before,
.btn--on-blue::after,
.btn--on-blue::before {
  content: "";
  width: 5px;
  height: 5px;
  flex: none;
  background: var(--c-green);
  rotate: 45deg;
  transition: opacity var(--dur-fast) var(--ease),
              translate var(--dur-fast) var(--ease);
}
/* `.btn--on-blue` EST le primaire de la bande bleue : le marqueur suit le
   rang, pas la classe. Sur cet aplat blanc, le losange reprend le bleu de
   marque — le vert sur blanc y perdrait le lien avec le bouton. */
.btn--on-blue::after,
.btn--on-blue::before { background: var(--c-blue); }

.btn--primary::after,
.btn--on-blue::after  { order: 8; }
/* -3px et non -5 : tourné à 45°, un carré de 5px présente une diagonale de
   7,07px et déborde donc de 1px de chaque côté de sa boîte. Un intervalle
   de boîte de 5px (gap 8 − 3) ne laisse que ~2,9px d'air visible entre les
   deux pointes — c'est l'écart du « ∙∙ » du logo, pas un chevauchement. */
.btn--primary::before,
.btn--on-blue::before { order: 9; margin-left: -3px; opacity: 0; translate: -3px 0; }
.btn--primary:hover::after,  .btn--primary:hover::before,
.btn--on-blue:hover::after,  .btn--on-blue:hover::before { translate: 4px 0; }
.btn--primary:hover::before,
.btn--on-blue:hover::before { opacity: 1; transition-delay: 40ms; }

/* L'intranet garde ses boutons tels quels : sa règle est « un seul primaire
   par écran, en haut à droite », et un marqueur décoratif dans un plan de
   travail dense ajoute du bruit là où il n'apporte aucun rang. */
.ix-shell .btn--primary::after,
.ix-shell .btn--primary::before,
.ix-shell .btn--on-blue::after,
.ix-shell .btn--on-blue::before { content: none; }

/* Text link with arrow */
.link-arrow {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  font-weight: var(--fw-semi); color: var(--c-blue);
}
.link-arrow .ico { transition: transform var(--dur-fast) var(--ease); }
.link-arrow:hover .ico { transform: translateX(4px); }

/* ---- Tags / chips -------------------------------------------------- */
.tag {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 0.35em 0.8em;
  border-radius: var(--r-pill);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semi);
  background: var(--tag-neutral-bg); color: var(--tag-neutral-fg);
  letter-spacing: 0.01em;
}
.tag .ico { width: 14px; height: 14px; }
.tag--blue   { background: var(--tag-blue-bg);   color: var(--tag-blue-fg); }
.tag--green  { background: var(--tag-green-bg);  color: var(--tag-green-fg); }
.tag--sky    { background: var(--tag-sky-bg);    color: var(--tag-sky-fg); }
.tag--orange { background: var(--tag-orange-bg); color: var(--tag-orange-fg); }
.tag--wine   { background: var(--tag-wine-bg);   color: var(--tag-wine-fg); }

/* ---- Card (base) --------------------------------------------------- */
.card {
  background: var(--c-paper);
  border: 1px solid var(--c-line);
  border-radius: var(--r-lg);
  overflow: hidden;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease), border-color var(--dur) var(--ease);
  display: flex;
  flex-direction: column;
}
.card--hover:hover { transform: translateY(-4px); box-shadow: var(--sh-md); border-color: var(--c-line-strong); }
.card__media { position: relative; aspect-ratio: 16 / 10; overflow: hidden; background: var(--c-mist-200); }
.card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--dur-slow) var(--ease); }
.card--hover:hover .card__media img { transform: scale(1.05); }
.card__media .tag { position: absolute; left: var(--sp-3); top: var(--sp-3); backdrop-filter: blur(4px); }
.card__body { padding: var(--sp-5); display: flex; flex-direction: column; gap: var(--sp-3); flex: 1; }
.card__meta { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; font-size: var(--fs-xs); color: var(--c-slate); }
.card__badges { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; }
.card__loc { display: flex; align-items: center; gap: 6px; font-size: var(--fs-xs); color: var(--c-slate); font-weight: var(--fw-medium); }
.card__loc .ico { width: 14px; height: 14px; color: var(--c-slate); }
.card__title { font-size: var(--fs-h4); font-weight: var(--fw-bold); line-height: var(--lh-snug); }
.card__title a { color: inherit; }
.card__title a:hover { color: var(--c-blue); }
.card__text { color: var(--c-slate); font-size: var(--fs-sm); }
.card__foot { margin-top: auto; padding-top: var(--sp-2); display: flex; align-items: center; justify-content: space-between; }

/* Clean CTA (no divider) — used with a stretched link on project cards */
.card__cta { margin-top: auto; padding-top: var(--sp-4); display: inline-flex; align-items: center; gap: 8px; color: var(--c-blue); font-weight: var(--fw-semi); font-size: var(--fs-sm); }
.card__cta .ico { width: 1.05em; height: 1.05em; transition: transform var(--dur-fast) var(--ease); }
.card--hover:hover .card__cta { color: var(--c-sky); }
.card--hover:hover .card__cta .ico { transform: translateX(4px); }

/* Whole project card is one click target (title link stretched over card) */
.card--project { position: relative; }
.card--project .card__title a::after { content: ""; position: absolute; inset: 0; z-index: 2; }

/* Feature card (icon + text, no image) */
.feature {
  background: var(--c-paper);
  border: 1px solid var(--c-line);
  border-radius: var(--r-lg);
  padding: var(--sp-6);
  display: flex; flex-direction: column; gap: var(--sp-3);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.feature:hover { transform: translateY(-4px); box-shadow: var(--sh-md); }
.feature__icon {
  width: 56px; height: 56px; border-radius: var(--r-md);
  display: grid; place-items: center;
  background: var(--tag-blue-bg); color: var(--c-blue);
}
.feature__icon .ico { width: 28px; height: 28px; }
.feature--green .feature__icon { background: var(--tag-green-bg); color: var(--c-green-700); }
.feature--sky .feature__icon { background: var(--tag-sky-bg); color: var(--c-sky-600); }
.feature--orange .feature__icon { background: var(--tag-orange-bg); color: var(--tag-orange-fg); }

/* ---- Teinte de carte (EXTRANET uniquement) --------------------------
   La couleur de variante ne portait que sur la pastille d'icône : posée
   sur toute la carte, elle distingue les parcours d'un coup d'œil, ce
   qui est précisément le rôle d'un trio de cartes d'orientation.
   Sur fond teinté la pastille repasse en blanc, sinon elle se fond.
   L'intranet est EXCLU plus bas : il partage cette feuille mais garde
   sa propre densité, et sa page design-system documente la carte dans
   son état d'origine. */
.feature { background: var(--tag-blue-bg); border-color: transparent; }
.feature--green { background: var(--tag-green-bg); }
.feature--sky { background: var(--tag-sky-bg); }
.feature--orange { background: var(--tag-orange-bg); }
.feature .feature__icon { background: var(--c-paper); }

/* Intranet : rendu d'origine, strictement inchangé. */
.ix-shell .feature { background: var(--c-paper); border-color: var(--c-line); }
.ix-shell .feature .feature__icon { background: var(--tag-blue-bg); }
.ix-shell .feature--green .feature__icon { background: var(--tag-green-bg); }
.ix-shell .feature--sky .feature__icon { background: var(--tag-sky-bg); }
.ix-shell .feature--orange .feature__icon { background: var(--tag-orange-bg); }

/* ---- Stat (chiffres-clés) ------------------------------------------ */
.stat { display: flex; flex-direction: column; gap: 2px; }
.stat__num {
  font-family: var(--font-head);
  font-size: var(--fs-stat);
  font-weight: var(--fw-black);
  line-height: 1;
  color: var(--c-blue);
  letter-spacing: -0.02em;
}
.stat__label { font-size: var(--fs-sm); color: var(--c-slate); font-weight: var(--fw-medium); }
.section--blue .stat__num { color: #fff; }
.section--blue .stat__label { color: var(--c-on-blue); }
.stat--green .stat__num { color: var(--c-green-700); }
.stat--sky .stat__num { color: var(--c-sky-600); }

/* ---- "À retenir" callout ------------------------------------------- */
.callout {
  border-left: 4px solid var(--c-green);
  background: var(--c-mist);
  border-radius: var(--r-md);
  padding: var(--sp-5);
}
.callout__title { display: flex; align-items: center; gap: var(--sp-2); font-weight: var(--fw-bold); color: var(--c-blue); margin-bottom: var(--sp-2); }

/* ---- Forms --------------------------------------------------------- */
.field { display: flex; flex-direction: column; gap: var(--sp-2); }
.field label { font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--c-ink); }
.field .hint { font-size: var(--fs-xs); color: var(--c-slate); }
/* Filled style: soft mist fill at rest (no border needed to read as a field),
   lifts to white with a border + ring on focus. Same recipe .search already
   uses for its pill field — extended here to the standard inputs. */
/* Champs — révision d'après shadcn/ui (registry, composant Input) :
   `rounded-md border bg-transparent px-3 py-1 shadow-xs`, plus un anneau
   de 3px à la mise au point. Trois écarts avec l'ancienne version, qui
   expliquent à eux seuls l'effet lourd :

     · le REMPLISSAGE gris devient un fond clair et une bordure VISIBLE.
       Une bordure transparente au repos laissait un pavé gris flottant,
       sans contour ni ancrage ;
     · l'ombre INTERNE disparaît. Elle creuse le champ, un effet daté que
       plus aucun système courant n'emploie ;
     · le rembourrage passe de 0,85em/1,1em à 0,6em/0,9em, ramenant la
       hauteur de ~53px à ~45px — soit la cible tactile de 44px, sans le
       surplus. shadcn descend à 36px, mais c'est une valeur pensée pour
       la souris.

   La police reste à --fs-base : shadcn fait de même (`text-base`, et
   `text-sm` seulement à partir de `md`), pour la raison connue — en
   dessous de 16px, Safari iOS agrandit la page à la mise au point. */
.input, .select, .textarea {
  width: 100%;
  /* Hauteur DÉCLARÉE, rembourrage réduit à sa fonction horizontale. Le
     rembourrage vertical subsiste pour que le champ grandisse avec le
     texte en mode A++, mais c'est `min-height` qui fixe le repos. */
  min-height: var(--control-h);
  padding: 0.4em 0.9em;
  background: var(--c-paper);
  color: var(--c-ink);
  border: 1px solid var(--c-line-strong);
  border-radius: var(--r-lg);
  font-family: inherit;
  font-size: var(--fs-base);
  box-shadow: var(--sh-xs);
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.input:hover, .select:hover, .textarea:hover { border-color: var(--c-slate-300); }
/* --c-slate-300 reads under 3:1 on the mist fill — too faint to clear the
   4.5:1 floor for placeholder text; --c-slate is the system's secondary-text
   token and clears it while staying visually lighter than filled-in --c-ink. */
.input::placeholder, .textarea::placeholder { color: var(--c-slate); }
.input:focus, .select:focus, .textarea:focus {
  outline: none;
  background: var(--c-paper);
  border-color: var(--c-sky);
  box-shadow: 0 0 0 3px rgba(22,159,219,0.18);
}
.input:disabled, .select:disabled, .textarea:disabled {
  /* Le champ désactivé garde une bordure, mais atténuée : sans contour
     il ne se lirait plus comme un champ du tout, seulement comme un
     aplat gris. */
  background: var(--c-mist); color: var(--c-slate-300); border-color: var(--c-line);
  box-shadow: none; cursor: not-allowed; opacity: .7;
}
.textarea { min-height: 130px; resize: vertical; line-height: var(--lh-snug); }
/* Native <select> keeps its own popup (no JS dropdown) — just replace the
   inconsistent OS arrow with one drawn from the app's own icon language. */
.select {
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Cpath d='M4 6l4 4 4-4' stroke='%235B6B7A' stroke-width='1.6' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.9em center;
  background-size: 16px;
  padding-right: 2.6em;
  cursor: pointer;
}
.field--error .input, .field--error .select, .field--error .textarea { border-color: var(--c-wine); background: var(--tag-wine-bg); }
.field--error .input:focus, .field--error .select:focus, .field--error .textarea:focus { box-shadow: 0 0 0 3px rgba(163,23,62,.16); }
.field__error { font-size: var(--fs-xs); color: var(--c-wine); font-weight: var(--fw-medium); }

.checkbox { display: flex; align-items: flex-start; gap: var(--sp-3); font-size: var(--fs-sm); color: var(--c-slate); }
.checkbox input { margin-top: 3px; width: 18px; height: 18px; accent-color: var(--c-blue); flex: none; }

/* Search input with icon */
.search {
  display: flex; align-items: center; gap: var(--sp-2);
  background: var(--c-paper);
  border: 1.5px solid var(--c-line-strong);
  border-radius: var(--r-pill);
  /* Même hauteur que les champs : la recherche EST un champ, elle ne
     doit pas être plus basse de deux pixels que ses voisins. */
  min-height: var(--control-h);
  padding: 0.25em 0.6em 0.25em 1em;
}
.search:focus-within { border-color: var(--c-sky); box-shadow: 0 0 0 3px rgba(22,159,219,0.18); }
.search input { border: none; outline: none; background: none; flex: 1; }
.search .ico { width: 20px; height: 20px; color: var(--c-slate); flex: none; }

/* ---- Breadcrumb ---------------------------------------------------- */
.breadcrumb { display: flex; flex-wrap: wrap; gap: var(--sp-2); font-size: var(--fs-sm); color: var(--c-slate); }
.breadcrumb a { color: var(--c-slate); }
.breadcrumb a:hover { color: var(--c-blue); }
.breadcrumb li + li::before { content: "/"; margin-right: var(--sp-2); color: var(--c-line-strong); }
.breadcrumb li { display: flex; align-items: center; gap: var(--sp-2); }
.breadcrumb [aria-current] { color: var(--c-ink); font-weight: var(--fw-semi); }

/* ---- Pagination ---------------------------------------------------- */
.pagination { display: flex; gap: var(--sp-2); align-items: center; justify-content: center; margin-top: var(--sp-7); }
/* `button` ajouté : une commande de pagination est un bouton, pas un
   lien — elle ne mène nulle part, elle repagine la liste en place. */
.pagination a, .pagination span, .pagination button {
  min-width: 42px; height: 42px; padding-inline: 10px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--r-md); border: 1px solid var(--c-line);
  color: var(--c-slate); font-weight: var(--fw-semi); font-size: var(--fs-sm);
}
.pagination a:hover { border-color: var(--c-blue); color: var(--c-blue); }
.pagination [aria-current] { background: var(--c-blue); color: #fff; border-color: var(--c-blue); }

/* ---- Pill filter / segmented -------------------------------------- */
.chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.chip {
  /* `inline-flex` : sans lui, `min-height` sur un <button> ne centre pas
     son libellé, il l'ancre en haut. */
  display: inline-flex; align-items: center; justify-content: center;
  min-height: var(--chip-h);
  padding: 0 1em; border-radius: var(--r-pill);
  border: 1.5px solid var(--c-line-strong);
  font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--c-slate);
  transition: all var(--dur-fast) var(--ease);
}
.chip:hover { border-color: var(--c-blue); color: var(--c-blue); }
.chip[aria-pressed="true"], .chip.is-active { background: var(--c-blue); border-color: var(--c-blue); color: #fff; }

/* Effectif porté par la pastille : en retrait, jamais à la même force que
   le libellé — c'est une précision sur le filtre, pas son nom. */
.chip__n { margin-left: 4px; font-variant-numeric: tabular-nums; opacity: .6; font-weight: var(--fw-regular); }
.chip.is-active .chip__n { opacity: .8; }
/* Filtre sans résultat : lisible, mais pas une fausse piste. */
.chip.is-empty { opacity: .45; cursor: default; }
.chip.is-empty:hover { border-color: var(--c-line-strong); color: var(--c-slate); }

/* ---- Barre de filtres à plusieurs critères -------------------------
   Une ligne par critère, chacune précédée de son nom : sans libellé, deux
   rangées de pastilles se lisent comme une seule liste en désordre. */
.filterbar { display: flex; flex-direction: column; gap: var(--sp-3); }
.filterbar__row { display: flex; align-items: baseline; gap: var(--sp-3); flex-wrap: wrap; }
.filterbar__lbl {
  flex: none; min-width: 52px;
  font-size: var(--fs-xs); font-weight: var(--fw-semi); letter-spacing: .06em;
  text-transform: uppercase; color: var(--c-slate);
}
.filterbar__count { margin: 0 0 var(--sp-4); font-size: var(--fs-sm); color: var(--c-slate); }
.filterbar__count b { color: var(--c-ink); font-variant-numeric: tabular-nums; }
.empty-line { margin: 0; padding: var(--sp-6); text-align: center; color: var(--c-slate);
  border: 1px dashed var(--c-line-strong); border-radius: var(--r-lg); }
@media (max-width: 620px) {
  .filterbar__row { flex-direction: column; align-items: flex-start; gap: var(--sp-2); }
}

/* ---- Surlignage éditorial ------------------------------------------
   `<mark>` est l'élément HTML du texte MIS EN ÉVIDENCE : on le restyle au
   lieu d'inventer une classe, pour que le surlignage porte aussi son sens
   aux lecteurs d'écran, qui l'annoncent. `.hl` existe en doublure pour les
   cas où le balisage vient d'un CMS qui ne produit que des <span>.

   Le jaune par défaut des navigateurs est remplacé par le couple de
   surlignage de la charte (vert de marque, texte noir, 7,93:1 — AAA).

   Trois détails qui font la différence entre un fond posé et un vrai
   surlignage :
     · un rembourrage horizontal, sinon le vert colle aux lettres ;
     · `box-decoration-break: clone` — sur deux lignes, la seconde reçoit
       elle aussi son rembourrage et ses coins, au lieu d'un bloc coupé ;
     · `print-color-adjust: exact` — un portail institutionnel s'imprime,
       et un surlignage que l'impression efface ne surligne plus rien. */
mark, .hl {
  background: var(--c-highlight);
  color: var(--c-highlight-fg);
  padding: 0.08em 0.28em;
  border-radius: var(--r-sm);
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
  print-color-adjust: exact;
  -webkit-print-color-adjust: exact;
}
/* Un lien surligné garde sa nature de lien : le noir du surlignage ne doit
   pas le déguiser en texte ordinaire. */
mark a, .hl a { color: var(--c-highlight-fg); text-decoration: underline; }

/* ---- Modale (extranet) ---------------------------------------------
   L'intranet a la sienne (.ix-modal), cloisonnée dans .ix-shell et régie
   par son propre jeu de densités. Celle-ci est son équivalent public.
   Feuille en bas d'écran sur mobile — le pouce y accède, et c'est la
   forme attendue d'un formulaire court sur téléphone — puis boîte
   centrée dès 640px. */
.modal { position: fixed; inset: 0; z-index: 200; display: grid; place-items: end center; visibility: hidden; }
.modal.is-open { visibility: visible; }
/* Même voile que le menu off-canvas (layout.css) : le bleu profond de la
   marque à 50 %, et non une quatrième teinte de voile inventée ici. */
.modal__scrim { position: absolute; inset: 0; background: rgba(0, 51, 95, .5); opacity: 0; transition: opacity var(--dur) var(--ease); }
.modal.is-open .modal__scrim { opacity: 1; }
.modal__box {
  position: relative; width: min(100%, 460px); max-height: 92vh; overflow-y: auto;
  background: var(--c-paper); border-radius: var(--r-xl) var(--r-xl) 0 0;
  padding: var(--sp-5); box-shadow: var(--sh-lg);
  transform: translateY(100%); transition: transform var(--dur) var(--ease);
}
.modal.is-open .modal__box { transform: none; }
.modal__head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-3); }
.modal__title { font-size: var(--fs-h3); }
.modal__sub { color: var(--c-slate); font-size: var(--fs-sm); margin-top: var(--sp-2); }
.modal__form { display: grid; gap: var(--sp-4); margin-top: var(--sp-5); }
/* Confirmation : bloc centré autour d'une pastille verte.
   Le `margin-inline: auto` ne centrait rien sur l'icône seule — .ico est
   `inline-flex`, il ne remplit pas la ligne. C'est l'enveloppe qui est
   centrée, et elle donne au passage à la coche le poids d'une
   illustration plutôt que d'un pictogramme d'interface. */
.modal__done { text-align: center; padding-block: var(--sp-6); }
.modal__done-ico {
  display: grid; place-items: center;
  width: 72px; height: 72px; margin-inline: auto;
  border-radius: var(--r-pill);
  background: var(--tag-green-bg); color: var(--c-green-700);
}
.modal__done-ico .ico { width: 34px; height: 34px; }
.modal__done h3 { margin-top: var(--sp-5); }
.modal__done p { color: var(--c-slate); margin-top: var(--sp-3); }
.modal__done .btn { margin-top: var(--sp-5); }
@media (min-width: 640px) {
  .modal { place-items: center; padding: var(--sp-5); }
  .modal__box { border-radius: var(--r-xl); transform: translateY(14px); }
}
@media (prefers-reduced-motion: reduce) {
  .modal__box { transition: none; }
}

/* ---- Divider swoosh (signature) ------------------------------------ */
.swoosh { display: block; width: 100%; height: auto; color: var(--c-blue); }

/* ---- Icon rotation utilities --------------------------------------- */
.ico.rot-left  { transform: rotate(90deg); }
.ico.rot-right { transform: rotate(-90deg); }
.ico.rot-up    { transform: rotate(180deg); }

/* ---- Badge / status ------------------------------------------------ */
.badge { display:inline-flex; align-items:center; gap:6px; font-size: var(--fs-xs); font-weight: var(--fw-semi); }
.badge::before { content:""; width:8px; height:8px; border-radius: 50%; background: currentColor; }
.badge--open { color: var(--c-green-700); }
.badge--soon { color: var(--tag-orange-fg); }
.badge--closed { color: var(--c-slate); }

/* ---- Agenda list (home, médias, participation) --------------------- */
.agenda { display: flex; flex-direction: column; gap: var(--sp-3); }
.agenda__item {
  display: grid; grid-template-columns: auto 1fr auto; gap: var(--sp-4); align-items: center;
  background: #fff; border: 1px solid var(--c-line); border-radius: var(--r-md);
  padding: var(--sp-4) var(--sp-5); transition: all var(--dur-fast) var(--ease);
}
.agenda__item:hover { border-color: var(--c-line-strong); box-shadow: var(--sh-sm); }
.agenda__date {
  text-align: center; background: var(--c-mist); border-radius: var(--r-md);
  padding: var(--sp-2) var(--sp-3); min-width: 64px; line-height: 1;
}
.agenda__date b { display: block; font-size: 1.5rem; color: var(--c-blue); font-weight: var(--fw-black); }
.agenda__date span { font-size: var(--fs-xs); text-transform: uppercase; color: var(--c-slate); letter-spacing: .06em; }
.agenda__meta { display: flex; gap: var(--sp-3); flex-wrap: wrap; color: var(--c-slate); font-size: var(--fs-sm); margin-top: 4px; }
.agenda__meta span { display: inline-flex; align-items: center; gap: 6px; }
.agenda__meta .ico { width: 16px; height: 16px; }
@media (max-width: 620px) {
  .agenda__item { grid-template-columns: auto 1fr; }
  .agenda__item .btn { grid-column: 2; justify-self: start; }
}

/* ---- Event card « À venir » (photo + date + détails) --------------
   Shared by the homepage agenda and the Médias agenda list. */
.agenda-grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1rem, .6rem + 1.4vw, 1.75rem); margin-top: var(--sp-6); }
@media (max-width: 760px) { .agenda-grid { grid-template-columns: 1fr; } }
/* Variante pleine largeur : une carte événement par ligne (ex. « Autres événements »). */
.agenda-grid--full { grid-template-columns: 1fr; }

.ev-card {
  display: flex; background: #F2F8FD; border: 1px solid #DCEAF6; border-radius: var(--r-lg); overflow: hidden;
  transition: box-shadow var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.ev-card:hover { box-shadow: var(--sh-md); transform: translateY(-2px); border-color: #C2DCF0; }
.ev-card__media { flex: 0 0 38%; max-width: 38%; overflow: hidden; background: var(--c-mist-200); }
.ev-card__media img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform var(--dur-slow) var(--ease); }
.ev-card:hover .ev-card__media img { transform: scale(1.05); }

.ev-card__body { flex: 1 1 auto; min-width: 0; display: flex; gap: var(--sp-3); padding: var(--sp-4); }
.ev-card__date {
  flex: none; text-align: center; background: #fff; border-radius: var(--r-sm);
  padding: 6px 10px; height: fit-content; line-height: 1.15;
}
.ev-card__date b { display: block; font-family: var(--font-head); font-size: 1.35rem; font-weight: var(--fw-bold); color: var(--c-blue); }
.ev-card__date span { display: block; font-size: var(--fs-xs); font-weight: var(--fw-bold); letter-spacing: .06em; text-transform: uppercase; color: var(--c-slate); }
.ev-card__date i { display: block; font-style: normal; font-size: var(--fs-xs); color: var(--c-slate); }

.ev-card__main { min-width: 0; display: flex; flex-direction: column; }
.ev-card__title { font-family: var(--font-head); font-weight: var(--fw-bold); font-size: clamp(1.05rem, .95rem + .4vw, 1.25rem); line-height: 1.2; color: var(--c-blue); }
.ev-card__title a { color: inherit; }
.ev-card__title a:hover { color: var(--c-sky); }
.ev-card__loc { display: flex; align-items: center; gap: 6px; margin-top: var(--sp-2); color: var(--c-slate); font-size: var(--fs-sm); }
.ev-card__loc .ico { width: 15px; height: 15px; flex: none; color: var(--c-green-700); }
.ev-card__desc { margin-top: var(--sp-2); color: var(--c-slate); font-size: var(--fs-sm); line-height: 1.5; }
.ev-card__tag { margin-top: var(--sp-3); align-self: flex-start; }

@media (max-width: 460px) {
  .ev-card { flex-direction: column; }
  .ev-card__media { flex-basis: auto; max-width: none; aspect-ratio: 16 / 9; }
}
