/* ===========================================================================
   EXKAVE — SYSTÈME UI GLOBAL
   Extrait de la landing « La Cave + La Planche », gelée le 2026-08-16.

   CE FICHIER NE TOUCHE PAS LA LANDING.
   Les jetons portent les valeurs de la landing, à l'identique. Les composants
   sont préfixés `ex-` : aucun nom n'entre en collision avec `.bouton`,
   `.mono`, `.scene`, `.titre-*` ou `.puce` de exkave-home-v2.css. La landing
   reste donc rendue par sa propre feuille, et le test de gel le vérifie.

   Les autres pages s'habillent ici. À mesure qu'une famille migre, elle cesse
   de porter ses propres jetons : c'est le but, un seul endroit où la palette
   est écrite.

   TROIS MATIÈRES, ET RIEN D'AUTRE
     LAQUE   — recherche, contrôles, panneaux d'action. Graphite noir, filet
               laiton. Elle reste sombre de jour comme de nuit : une façade
               d'ampli ne blanchit pas au soleil.
     CARTON  — listes, éditorial, surfaces de lecture. C'est elle, et elle
               seule, qui bascule avec le thème.
     PHOTO   — les moments où l'interface disparaît derrière l'image.

   Light est PRÉPARÉ ici mais reste éteint dans le shell (exkave-theme.js
   n'active que "modern") tant que les vingt routes n'ont pas passé la recette.
   =========================================================================== */

:root {
  /* --- LAQUE : identique de jour comme de nuit --------------------------- */
  --ex-laque:            #0b0a09;
  --ex-laque-2:          #141210;
  --ex-laque-3:          #201c17;
  --ex-sur-laque:        #fffdf7;
  --ex-sur-laque-doux:   rgba(255, 253, 247, .64);
  --ex-sur-laque-faible: rgba(255, 253, 247, .34);

  /* --- LAITON : l'or du produit ------------------------------------------ */
  --ex-laiton:         #d8b765;
  --ex-laiton-clair:   #f4e6b8;
  --ex-laiton-profond: #6f541f;
  --ex-filet:          rgba(216, 183, 101, .30);
  --ex-filet-doux:     rgba(216, 183, 101, .15);
  --ex-lustre:         linear-gradient(180deg, rgba(255,253,247,.11) 0%, rgba(255,253,247,.025) 36%, rgba(0,0,0,0) 72%);
  --ex-laiton-degrade: linear-gradient(135deg, #fff0bd 0%, #d8b765 40%, #9b7425 72%, #4f3a13 100%);

  /* --- CARTON : la seule famille qui bascule avec le thème --------------- */
  --ex-page:        #0a0908;
  --ex-carton:      #14110d;
  --ex-carton-2:    #1e1912;
  --ex-encre:       #fffdf7;
  --ex-encre-douce: rgba(255, 253, 247, .70);
  --ex-cendre:      #8b8478;          /* gris chaud, tiré vers le laiton */
  --ex-trait:       rgba(255, 253, 247, .13);

  /* --- textures : petits SVG locaux, jamais du base64 -------------------- */
  --ex-grain:   url('/brand/cave-m-grain.svg');
  --ex-amas:    url('/brand/cave-m-amas.svg');
  --ex-papier:  url('/brand/cave-m-papier.svg');
  --ex-trame:   url('/brand/cave-m-trame.svg');
  --ex-dechire: url('/brand/cave-m-dechire.svg');
  --ex-grain-op:   .34;
  --ex-amas-op:    .13;
  --ex-papier-op:  .07;
  --ex-papier-melange: soft-light;

  /* --- typographie ------------------------------------------------------- */
  --ex-display: var(--font-display);
  --ex-mono: var(--font-mono);

  /* Échelle reprise de la landing. Les grands corps ne servent qu'aux
     ouvertures : une page de liste n'a pas d'usage d'un titre de 100 px. */
  --ex-t-xl: clamp(2.9rem, 7vw, 6.4rem);      /* ouverture de page uniquement */
  --ex-t-l:  clamp(2rem, 4.1vw, 3.4rem);      /* titre de page */
  --ex-t-m:  clamp(1.2rem, 1.8vw, 1.6rem);    /* titre de zone */
  --ex-t-s:  1.0625rem;                       /* titre de bloc */
  --ex-corps: 1.03rem;
  --ex-corps-petit: .9375rem;
  --ex-meta: .66rem;                          /* mono, capitales, interlettré */

  /* --- espacement : deux paliers de respiration, et une trame fine ------- */
  --ex-souffle:      clamp(56px, 6vw, 96px);
  --ex-souffle-fort: clamp(90px, 10vw, 150px);
  --ex-gout:  clamp(14px, 1.5vw, 26px);
  --ex-e-1: 4px;
  --ex-e-2: 8px;
  --ex-e-3: 14px;
  --ex-e-4: 22px;
  --ex-e-5: 34px;
  --ex-e-6: 52px;

  /* --- largeurs de contenu ------------------------------------------------ */
  --ex-scene:  min(1680px, calc(100vw - clamp(40px, 5vw, 104px)));
  --ex-lecture: 72ch;                          /* texte long */
  --ex-prose:   58ch;                          /* paragraphe courant */

  /* --- formes, ombres, durées -------------------------------------------- */
  --ex-r-0: 0;
  --ex-r-1: 2px;
  --ex-r-2: 4px;
  --ex-r-rond: 999px;
  --ex-ombre-1: 0 10px 24px -12px rgba(0,0,0,.55);
  --ex-ombre-2: 0 26px 54px -22px rgba(0,0,0,.62);
  --ex-ombre-objet: 0 40px 78px -26px rgba(0,0,0,.62);
  --ex-duree: .28s;
  --ex-duree-longue: .55s;
  --ex-courbe: cubic-bezier(.2, .7, .2, 1);
}

/* ===========================================================================
   LIGHT — PRÉPARÉ, PAS ACTIVÉ.
   Le shell n'expose pas encore ce thème. Seule la famille CARTON bascule :
   papier ivoire, champagne, encre noire. La LAQUE et le LAITON ne bougent pas,
   sinon le produit change d'identité au lieu de changer de lumière.
   Les photos ne sont pas dégradées : aucune règle n'éclaircit une pochette.
   =========================================================================== */
html[data-exkave-theme="light"] {
  --ex-page:        #f3eee1;
  --ex-carton:      #eae2d0;
  --ex-carton-2:    #ded4be;
  --ex-encre:       #131210;
  --ex-encre-douce: rgba(19, 18, 16, .76);
  --ex-cendre:      #6b6355;
  --ex-trait:       rgba(19, 18, 16, .16);
  --ex-laiton-profond: #8a6620;      /* le laiton pur manque de contraste sur ivoire */
  --ex-grain-op:   .15;
  --ex-amas-op:    .07;
  --ex-papier-op:  .16;
  --ex-papier-melange: multiply;
}

/* ===========================================================================
   PRIMITIVES
   =========================================================================== */
.ex-scene { position: relative; width: var(--ex-scene); margin-inline: auto; }
.ex-lecture { max-width: var(--ex-lecture); }

.ex-titre-xl, .ex-titre-l, .ex-titre-m, .ex-titre-s {
  margin: 0;
  font-family: var(--font-display);
  color: var(--ex-encre);
  text-wrap: balance;
}
.ex-titre-xl { font-size: var(--ex-t-xl); font-weight: 400; letter-spacing: -.042em; line-height: .88; }
.ex-titre-l  { font-size: var(--ex-t-l);  font-weight: 400; letter-spacing: -.032em; line-height: .96; }
.ex-titre-m  { font-size: var(--ex-t-m);  font-weight: 400; letter-spacing: -.02em;  line-height: 1.16; }
.ex-titre-s  { font-size: var(--ex-t-s);  font-weight: 400; letter-spacing: -.015em; line-height: 1.24; }

/* La metadata dit un fait court : référence, pays, état. Elle est monospacée
   et interlettrée pour se distinguer du texte, jamais pour décorer. */
.ex-meta {
  font-family: var(--font-mono);
  font-size: var(--ex-meta);
  letter-spacing: .19em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  color: var(--ex-laiton);
}
.ex-meta--sourd { color: var(--ex-cendre); }

.ex-prose { max-width: var(--ex-prose); color: var(--ex-encre-douce); font-size: var(--ex-corps); line-height: 1.62; }
.ex-prose strong { color: var(--ex-encre); font-weight: 400; }
.ex-note { margin: 0; font-size: var(--ex-corps-petit); line-height: 1.6; color: var(--ex-cendre); }

/* ===========================================================================
   SURFACES
   =========================================================================== */
.ex-laque {
  position: relative;
  background: var(--ex-lustre), linear-gradient(180deg, var(--ex-laque-2), var(--ex-laque));
  border: 1px solid var(--ex-filet-doux);
  color: var(--ex-sur-laque);
  box-shadow: inset 0 1px 0 rgba(255,253,247,.09), var(--ex-ombre-2);
}
.ex-laque .ex-meta { color: var(--ex-laiton); }
.ex-laque .ex-meta--sourd { color: var(--ex-sur-laque-faible); }

.ex-carton { position: relative; isolation: isolate; background: var(--ex-carton); color: var(--ex-encre); }
.ex-carton--2 { background: var(--ex-carton-2); }

/* Le papier et le grain sont posés en couches, jamais sur le contenu.
   `isolation: isolate` garde le mélange à l'intérieur de la surface. */
.ex-carton::before,
.ex-carton::after { content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 0; }
.ex-carton::before {
  background-image: var(--ex-papier);
  background-size: 300px 300px;
  opacity: var(--ex-papier-op);
  mix-blend-mode: var(--ex-papier-melange);
}
.ex-carton::after {
  background-image: var(--ex-grain);
  background-size: 240px 240px;
  opacity: var(--ex-grain-op);
  mix-blend-mode: overlay;
}
.ex-carton > * { position: relative; z-index: 1; }

.ex-panneau { padding: clamp(22px, 2.6vw, 44px); border-radius: var(--ex-r-2); }

/* ===========================================================================
   BOUTONS
   Trois seulement : plein laiton pour l'action principale, nu pour le reste,
   discret pour ce qui ne doit pas attirer l'œil. Pas de bouton coloré.
   =========================================================================== */
.ex-bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--ex-e-2);
  min-height: 44px;                   /* cible tactile */
  padding: 13px 24px;
  border: 0;
  border-radius: var(--ex-r-rond);
  cursor: pointer;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: .91rem;
  letter-spacing: -.01em;
  text-decoration: none;
  color: #16120a;
  background-image: var(--ex-lustre), var(--ex-laiton-degrade);
  box-shadow: inset 0 1px 0 rgba(255,253,247,.45), inset 0 -2px 0 rgba(0,0,0,.24), var(--ex-ombre-1);
  transition: transform var(--ex-duree) var(--ex-courbe), box-shadow var(--ex-duree);
}
.ex-bouton:hover { transform: translateY(-2px); box-shadow: inset 0 1px 0 rgba(255,253,247,.5), var(--ex-ombre-2); }
.ex-bouton:active { transform: none; }
.ex-bouton[disabled], .ex-bouton[aria-disabled="true"] {
  cursor: not-allowed; opacity: .5; transform: none; box-shadow: none;
}
.ex-bouton--nu {
  background: transparent;
  background-image: none;
  color: var(--ex-encre);
  border: 1px solid var(--ex-trait);
  box-shadow: none;
}
.ex-bouton--nu:hover { border-color: var(--ex-laiton); box-shadow: none; transform: none; }
.ex-laque .ex-bouton--nu { color: var(--ex-sur-laque); border-color: var(--ex-filet-doux); }
.ex-bouton--discret {
  background: none; box-shadow: none; padding: 8px 12px; min-height: 36px;
  color: var(--ex-cendre); font-weight: 400;
}
.ex-bouton--discret:hover { color: var(--ex-encre); transform: none; }

.ex-lien {
  color: var(--ex-encre);
  text-decoration: none;
  border-bottom: 1px solid var(--ex-trait);
  padding-bottom: 2px;
  transition: color var(--ex-duree), border-color var(--ex-duree);
}
.ex-lien:hover { color: var(--ex-laiton); border-color: var(--ex-filet); }
.ex-lien--sourd { color: var(--ex-cendre); border-bottom-color: transparent; }

/* ===========================================================================
   CHAMPS
   Un champ Exkave est posé sur la laque : c'est un contrôle d'appareil, pas
   une case de formulaire administratif.
   =========================================================================== */
.ex-champ, .ex-select, .ex-zone {
  width: 100%;
  min-height: 46px;
  padding: 12px 14px;
  border: 1px solid var(--ex-trait);
  border-radius: var(--ex-r-1);
  background: var(--ex-laque-2);
  color: var(--ex-sur-laque);
  font-family: var(--font-display);
  font-size: 1rem;                    /* 16 px : en dessous, iOS zoome au focus */
  line-height: 1.4;
  transition: border-color var(--ex-duree), box-shadow var(--ex-duree);
}
.ex-zone { min-height: 120px; resize: vertical; }
.ex-champ::placeholder, .ex-zone::placeholder { color: var(--ex-sur-laque-faible); }
.ex-champ:hover, .ex-select:hover, .ex-zone:hover { border-color: var(--ex-filet-doux); }
.ex-champ:focus-visible, .ex-select:focus-visible, .ex-zone:focus-visible {
  outline: none;
  border-color: var(--ex-laiton);
  box-shadow: 0 0 0 3px rgba(216,183,101,.22);
}
.ex-champ[aria-invalid="true"] { border-color: #b5563f; }

.ex-etiquette-champ {
  display: block;
  margin-bottom: var(--ex-e-2);
  font-family: var(--font-mono);
  font-size: var(--ex-meta);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ex-cendre);
}
.ex-aide { margin: var(--ex-e-2) 0 0; font-size: .8125rem; color: var(--ex-cendre); }

/* La recherche est un objet, pas un champ : c'est le geste central du produit. */
.ex-recherche {
  display: flex;
  align-items: center;
  gap: var(--ex-e-2);
  padding: 8px 8px 8px 18px;
  border: 1px solid var(--ex-filet);
  border-radius: var(--ex-r-rond);
  background: var(--ex-laque);
  box-shadow: var(--ex-ombre-1);
}
.ex-recherche input {
  flex: 1; min-width: 0; padding: 12px 0;
  border: 0; background: transparent; color: var(--ex-sur-laque);
  font: inherit; font-size: 1rem;
}
.ex-recherche input:focus-visible { outline: none; }
.ex-recherche:focus-within { border-color: var(--ex-laiton); box-shadow: 0 0 0 4px rgba(216,183,101,.20); }

/* ===========================================================================
   LISTES DE FAITS, TABLEAUX
   Une fiche de pressage est une liste de faits : libellé étroit, valeur large,
   filet entre les lignes. Pas de tableau à bordures pleines.
   =========================================================================== */
.ex-fiche { margin: 0; }
.ex-fiche-ligne {
  display: grid;
  grid-template-columns: 116px minmax(0, 1fr);
  gap: var(--ex-e-3);
  padding: 9px 0;
  border-bottom: 1px solid var(--ex-trait);
  align-items: baseline;
}
.ex-fiche-ligne dt { font-family: var(--font-mono); font-size: var(--ex-meta); letter-spacing: .16em; text-transform: uppercase; color: var(--ex-cendre); }
.ex-fiche-ligne dd { margin: 0; color: var(--ex-encre); font-variant-numeric: tabular-nums; }
/* Une donnée absente est dite, pas comblée. */
.ex-fiche-ligne dd.ex-manque { color: var(--ex-cendre); font-style: italic; }

.ex-table { width: 100%; border-collapse: collapse; font-size: var(--ex-corps-petit); }
.ex-table th {
  text-align: left; padding: 10px 12px;
  font-family: var(--font-mono); font-size: var(--ex-meta);
  letter-spacing: .16em; text-transform: uppercase; color: var(--ex-cendre);
  border-bottom: 1px solid var(--ex-trait);
}
.ex-table td { padding: 12px; border-bottom: 1px solid var(--ex-trait); color: var(--ex-encre-douce); vertical-align: top; }
.ex-table tbody tr:hover td { background: rgba(255,253,247,.03); }
.ex-table--nombres td { font-variant-numeric: tabular-nums; }

/* ===========================================================================
   BADGES ET ÉTATS
   Le produit dit ce qu'il sait. Un état n'est jamais une note ni un score :
   c'est le niveau de preuve atteint.
   =========================================================================== */
.ex-badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px;
  border: 1px solid var(--ex-trait);
  border-radius: var(--ex-r-1);
  font-family: var(--font-mono); font-size: var(--ex-meta);
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--ex-cendre);
}
.ex-badge--preuve  { color: var(--ex-laiton); border-color: var(--ex-filet); }
.ex-badge--attente { color: var(--ex-encre-douce); }
.ex-badge--absent  { color: var(--ex-cendre); border-style: dashed; }

/* ===========================================================================
   IMAGES ET POCHETTES
   Les visuels portent la surface. Toujours `cover`, toujours un fond en
   attendant, jamais d'image de contenu en base64.
   =========================================================================== */
.ex-pochette, .ex-visuel {
  display: block;
  width: 100%;
  background-color: var(--ex-carton-2);
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  object-fit: cover;
}
.ex-pochette { aspect-ratio: 1; box-shadow: var(--ex-ombre-1); }
.ex-visuel--43  { aspect-ratio: 4 / 3; }
.ex-visuel--32  { aspect-ratio: 3 / 2; }
.ex-visuel--169 { aspect-ratio: 16 / 9; }
.ex-visuel--45  { aspect-ratio: 4 / 5; }

/* ===========================================================================
   RAILS
   On feuillette un bac. Un rail n'a pas de rangée à compléter : tout doit
   rester atteignable au doigt.
   =========================================================================== */
.ex-rail {
  display: flex;
  gap: var(--ex-gout);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  padding-bottom: var(--ex-e-3);
  scrollbar-width: thin;
  scrollbar-color: var(--ex-filet) transparent;
  overscroll-behavior-x: contain;
}
.ex-rail::-webkit-scrollbar { height: 3px; }
.ex-rail::-webkit-scrollbar-thumb { background: var(--ex-filet); }
.ex-rail > * { flex: 0 0 auto; scroll-snap-align: start; width: clamp(180px, 17vw, 230px); }

/* Une grille de pochettes ne montre que des rangées complètes : le script
   partagé masque le reliquat, le CSS ne peut pas le savoir seul. */
.ex-grille-pochettes {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: var(--ex-gout);
}

/* ===========================================================================
   FOCUS CLAVIER
   Un seul anneau, partout, visible sur laque comme sur carton.
   =========================================================================== */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--ex-laiton);
  outline-offset: 3px;
  border-radius: var(--ex-r-1);
}
.ex-saut-contenu {
  position: absolute; left: -9999px;
  padding: 12px 18px; background: var(--ex-laque); color: var(--ex-sur-laque);
  border: 1px solid var(--ex-filet); border-radius: var(--ex-r-2);
}
.ex-saut-contenu:focus { left: var(--ex-e-3); top: var(--ex-e-3); z-index: 9999; }

/* ===========================================================================
   RESPONSIVE
   Les points d'arrêt correspondent aux viewports de recette : 1440, 1024,
   768, 390, 360. On ne réduit pas une composition de bureau, on change de
   geste — les grilles deviennent des rails.
   =========================================================================== */
@media (max-width: 1024px) {
  :root { --ex-souffle: clamp(44px, 6vw, 72px); --ex-souffle-fort: clamp(64px, 9vw, 110px); }
}
@media (max-width: 768px) {
  .ex-fiche-ligne { grid-template-columns: minmax(0, 1fr); gap: 2px; padding: 11px 0; }
  .ex-table th { display: none; }
  .ex-table td { display: block; border: 0; padding: 4px 0; }
  .ex-table tbody tr { display: block; padding: 12px 0; border-bottom: 1px solid var(--ex-trait); }
}
@media (max-width: 640px) {
  :root { --ex-scene: calc(100vw - 36px); }
  .ex-grille-pochettes {
    display: flex; overflow-x: auto; scroll-snap-type: x proximity;
    scrollbar-width: none; overscroll-behavior-x: contain;
  }
  .ex-grille-pochettes::-webkit-scrollbar { display: none; }
  .ex-grille-pochettes > * { flex: 0 0 58vw; max-width: 240px; scroll-snap-align: start; }
  .ex-rail > * { width: 58vw; max-width: 240px; }
  .ex-bouton { width: 100%; }
  .ex-bouton--auto { width: auto; }
}

/* ===========================================================================
   MOUVEMENT RÉDUIT
   Aucun contenu ne dépend d'une animation pour devenir visible : c'est réglé
   à la source, `.rev` vaut opacity 1 par défaut. Ici on éteint le décor.
   =========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .ex-bouton, .ex-lien, .ex-champ, .ex-select, .ex-zone, .ex-pochette, .ex-visuel {
    transition-duration: .01ms;
  }
  .ex-bouton:hover { transform: none; }
  .ex-carton::after { animation: none; }
}

/* ===========================================================================
   PAS DE SILLONS DORÉS
   Le fond du site portait des cercles concentriques et des hachures laiton :
   `exkave-theme.css` les pose, `exkave-mobile-skin.css` les repose, et la
   coquille injecte cette dernière APRÈS toute feuille de page. Les deux les
   déclarent en `!important` — les effacer depuis ici demande donc de passer
   devant.

   C'est la seule exception `!important` du socle, et elle n'ajoute rien :
   elle efface. L'attribut est répété pour gagner en spécificité sans
   inventer un sélecteur plus large que la page qui a choisi le socle : une
   page sans `data-ex-socle` garde exactement son fond d'aujourd'hui.
   =========================================================================== */
html body[data-ex-socle][data-ex-socle],
html body[data-ex-socle][data-ex-socle]::before,
html body[data-ex-socle][data-ex-socle]::after {
  background-image: none !important;
}
body[data-ex-socle] .exkave-depth-far,
body[data-ex-socle] .exkave-depth-near,
body[data-ex-socle] .grain-layer {
  display: none !important;
}

/* ===========================================================================
   MARQUEUR DE FIN DE FEUILLE — NE PAS DÉPLACER, NE PAS SUPPRIMER
   Cette règle doit rester la DERNIÈRE du fichier. Le contrôle de recette
   vérifie sa présence dans `document.styleSheets[].cssRules` : si elle
   manque, c'est que le navigateur a cessé de lire la feuille avant la fin —
   syntaxe invalide, accolade orpheline — et que des règles sont ignorées en
   silence. C'est arrivé le 2026-08-17 : 41 règles perdues sans un signal.
   =========================================================================== */
:root { --ex-fin-exkave-ui-global: 1; }
