@font-face {
  font-family: 'Geist';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('polices/geist-400-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Geist';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('polices/geist-400-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Geist';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('polices/geist-600-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Geist';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('polices/geist-600-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Geist';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('polices/geist-700-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Geist';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('polices/geist-700-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Geist Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('polices/geist-mono-400-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Geist Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('polices/geist-mono-400-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}


/* AGENCE : feuille unique. Aucune police distante, aucun CDN -- la politique de
   securite l'interdit, et une page qui attend un fichier de 80 Ko n'est pas plus
   belle, elle est plus lente.

   Les caracteres sont GEIST (licence OFL), servis par le site lui-meme. Seuls les
   sous-ensembles latins sont embarques : le cyrillique, le grec et le vietnamien
   pesent autant que le reste et ne serviront jamais a une agence qui travaille en
   francais. Huit fichiers, 150 Ko, contre plusieurs centaines pour la famille
   entiere. `font-display: swap` affiche le texte tout de suite dans la police du
   systeme puis bascule : on lit avant que la police n'arrive, jamais apres.

   Trois regles tenues, reprises de STUDIO parce qu'elles y ont fait leurs preuves :

     1. la couleur de marque est de la CHROME : navigation, liens, bouton principal.
        Elle ne dit jamais l'etat d'une donnee. L'indigo a ete choisi pour cela --
        il ne ressemble ni au vert, ni a l'ambre, ni au rouge, donc il ne peut pas
        etre confondu avec un signal ;
     2. les couleurs d'ETAT restent vertes, ambre et rouges, et elles sont TOUJOURS
        doublees d'un mot. Une couleur seule ne se lit pas quand on ne la distingue
        pas, et ne survit pas a une impression ;
     3. l'echelle typographique a sept marches et on choisit dedans. Douze tailles
        decidees une par une ne font pas une hierarchie, elles font du bruit.

   Le tableau de l'arbre se dessine sans image et sans JavaScript : les tiges
   verticales sont un degrade repete, la coudee est un bord. Un arbre qui a besoin
   d'un script pour avoir la forme d'un arbre disparait quand le script echoue. */

:root {
  color-scheme: light;
  --plan: #f4f5f9;
  --surface: #ffffff;
  --surface-creuse: #eef0f6;
  --encre: #15171c;
  --encre-2: #565d6b;
  --filet: #e4e7ef;
  --filet-fort: #cbd1de;
  --marque: #4f46e5;            /* traits et fonds, jamais du texte sur fond clair */
  --marque-encre: #4338ca;      /* la meme teinte, assombrie pour ecrire : 7,4:1 */
  --marque-pale: #eef0fe;
  --lien: #4338ca;
  --bon: #12904a;
  --bon-encre: #0a6b34;
  --attention: #e0a200;
  --attention-encre: #7d5a00;
  --critique: #d03b3b;
  --critique-encre: #a72020;
  --bouton-fond: #4f46e5;
  --bouton-encre: #ffffff;
  --ombre: 0 1px 2px rgba(21, 23, 28, 0.06), 0 8px 24px rgba(21, 23, 28, 0.05);
  --r: 6px;
  --sans: "Geist", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --affichage: "Geist", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --mono: "Geist Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;

  --t-xs: 0.6875rem;
  --t-sm: 0.8125rem;
  --t-base: 0.875rem;
  --t-lg: 1.125rem;
  --t-xl: 1.3125rem;
  --t-xxl: 1.625rem;
  --t-geant: 2.5rem;

  --e1: 0.25rem;
  --e2: 0.375rem;
  --e3: 0.5rem;
  --e4: 0.75rem;
  --e5: 1.125rem;
  --e6: 1.625rem;

  --prose: 68ch;
  --indent: 1.5rem;   /* un cran de l'arbre */
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --plan: #0b0d12;
    --surface: #14171e;
    --surface-creuse: #1b1f28;
    --encre: #f2f4f9;
    --encre-2: #aeb6c6;
    --filet: #232833;
    --filet-fort: #333a49;
    --marque: #5850ec;
    --marque-encre: #a5b4fc;
    --marque-pale: #1d2140;
    --lien: #a5b4fc;
    --bon: #2fb864;
    --bon-encre: #4ade80;
    --attention: #e0a200;
    --attention-encre: #fbbf24;
    --critique: #ef4444;
    --critique-encre: #fca5a5;
    --bouton-fond: #5850ec;
    --bouton-encre: #ffffff;
    --ombre: 0 1px 2px rgba(0, 0, 0, 0.6);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --plan: #0b0d12;
  --surface: #14171e;
  --surface-creuse: #1b1f28;
  --encre: #f2f4f9;
  --encre-2: #aeb6c6;
  --filet: #232833;
  --filet-fort: #333a49;
  --marque: #5850ec;
  --marque-encre: #a5b4fc;
  --marque-pale: #1d2140;
  --lien: #a5b4fc;
  --bon: #2fb864;
  --bon-encre: #4ade80;
  --attention: #e0a200;
  --attention-encre: #fbbf24;
  --critique: #ef4444;
  --critique-encre: #fca5a5;
  --bouton-fond: #5850ec;
  --bouton-encre: #ffffff;
  --ombre: 0 1px 2px rgba(0, 0, 0, 0.6);
}

* { box-sizing: border-box; }
html, body { margin: 0; }

body {
  background: var(--plan);
  color: var(--encre);
  font: var(--t-base)/1.5 var(--sans);
  /* Chiffres a chasse fixe PARTOUT : sans cela deux nombres l'un sous l'autre ne
     s'alignent pas, et une colonne de montants se lit deux fois moins vite. */
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, .chiffre {
  font-family: var(--affichage);
  letter-spacing: -0.015em;
  text-wrap: balance;
}

h1 { font-size: var(--t-xxl); margin: 0 0 var(--e2); }
h2 { font-size: var(--t-xl); margin: var(--e6) 0 var(--e3); }
h3 { font-size: var(--t-lg); margin: var(--e5) 0 var(--e3); }
p { margin: 0 0 var(--e4); max-width: var(--prose); }

a { color: var(--lien); }
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible,
textarea:focus-visible, summary:focus-visible {
  outline: 2px solid var(--marque);
  outline-offset: 2px;
  border-radius: var(--r);
}

.hors-ecran {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

.saut-contenu {
  position: absolute; left: -9999px; top: 0; z-index: 10;
  background: var(--surface); color: var(--lien); padding: var(--e3) var(--e4);
  border: 1px solid var(--marque); border-radius: var(--r);
}
.saut-contenu:focus { left: var(--e3); top: var(--e3); }

/* ------------------------------------------------------------------ ossature */

.coque { display: flex; min-height: 100vh; align-items: stretch; }

.rail {
  width: 232px; flex: 0 0 232px;
  background: var(--surface);
  border-right: 1px solid var(--filet);
  padding: var(--e5) var(--e4);
  display: flex; flex-direction: column; gap: var(--e5);
}

.marque { display: flex; align-items: center; gap: var(--e3); }
.marque .jeton {
  width: 30px; height: 30px; border-radius: var(--r);
  background: var(--marque); color: #fff;
  display: grid; place-items: center;
  font-family: var(--affichage); font-weight: 700; font-size: var(--t-base);
}
.marque .mot strong { display: block; font-family: var(--affichage); letter-spacing: 0.02em; }
.marque .mot span { display: block; font-size: var(--t-xs); color: var(--encre-2); }

.menu { display: flex; flex-direction: column; gap: 2px; }
.menu a {
  display: flex; align-items: center; gap: var(--e3);
  padding: var(--e3) var(--e3);
  border-radius: var(--r);
  color: var(--encre); text-decoration: none;
  font-size: var(--t-sm);
}
.menu a:hover { background: var(--surface-creuse); }
.menu a[aria-current="page"] {
  background: var(--marque-pale); color: var(--marque-encre); font-weight: 600;
}
.menu .signe { width: 1.2em; text-align: center; }

.rail footer {
  margin-top: auto; display: flex; flex-direction: column; gap: var(--e2);
  font-size: var(--t-sm); color: var(--encre-2);
  border-top: 1px solid var(--filet); padding-top: var(--e4);
}

.page { flex: 1; min-width: 0; padding: var(--e6) var(--e6) 4rem; }
.page > header { margin-bottom: var(--e5); }
.page > header .meta { margin-top: var(--e1); }

@media (max-width: 880px) {
  .coque { flex-direction: column; }
  .rail { width: auto; flex: none; border-right: 0; border-bottom: 1px solid var(--filet); }
  .menu { flex-direction: row; flex-wrap: wrap; }
  .page { padding: var(--e5) var(--e4) 3rem; }
}

/* -------------------------------------------------------------------- pieces */

.meta { color: var(--encre-2); font-size: var(--t-sm); }
.discret { color: var(--encre-2); }

.carte {
  background: var(--surface);
  border: 1px solid var(--filet);
  border-radius: var(--r);
  box-shadow: var(--ombre);
  padding: var(--e5);
  margin-bottom: var(--e5);
}
.carte > :first-child { margin-top: 0; }
.carte > :last-child { margin-bottom: 0; }

.tuiles {
  display: grid; gap: var(--e4);
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  margin-bottom: var(--e5);
}
.tuile {
  background: var(--surface); border: 1px solid var(--filet);
  border-radius: var(--r); padding: var(--e4) var(--e5); box-shadow: var(--ombre);
}
/* Les trois lignes d'une tuile s'EMPILENT. Ce sont des <span>, donc inline par
   defaut : sans cette declaration elles coulent sur une seule ligne et la tuile se lit
   « JOUEURS 10 8 actifs », ou le 10 et le 8 se touchent. */
.tuile .etiquette, .tuile .chiffre, .tuile .sous { display: block; }
.tuile .etiquette {
  font-size: var(--t-xs); text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--encre-2);
}
.tuile .chiffre { font-size: var(--t-geant); line-height: 1.05; margin: var(--e2) 0; }
.tuile .chiffre.moyen { font-size: var(--t-xxl); }
.tuile .sous { font-size: var(--t-sm); color: var(--encre-2); }
.tuile.marquee { border-left: 3px solid var(--marque); }
.tuile.bonne { border-left: 3px solid var(--bon); }
.tuile.grave { border-left: 3px solid var(--critique); }
.tuile.attention { border-left: 3px solid var(--attention); }

.rangee { display: flex; flex-wrap: wrap; gap: var(--e4); align-items: flex-end; }
.rangee > * { min-width: 0; }
.colonnes { display: grid; gap: var(--e5); grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }

/* -------------------------------------------------------------------- etats */

.pastille {
  display: inline-flex; align-items: center; gap: var(--e1);
  padding: 1px var(--e3); border-radius: 999px;
  font-size: var(--t-xs); font-weight: 600;
  border: 1px solid var(--filet-fort); color: var(--encre-2);
  background: var(--surface-creuse);
  white-space: nowrap;
}
.pastille.bon { color: var(--bon-encre); border-color: var(--bon); }
.pastille.attention { color: var(--attention-encre); border-color: var(--attention); }
.pastille.grave { color: var(--critique-encre); border-color: var(--critique); }
.pastille.marque { color: var(--marque-encre); border-color: var(--marque); background: var(--marque-pale); }

.valeur-bonne { color: var(--bon-encre); }
.valeur-grave { color: var(--critique-encre); }
.valeur-attention { color: var(--attention-encre); }

.message {
  border: 1px solid var(--filet-fort); border-left-width: 3px;
  border-radius: var(--r); padding: var(--e3) var(--e4);
  margin-bottom: var(--e3); background: var(--surface);
}
.message.bon { border-left-color: var(--bon); }
.message.grave { border-left-color: var(--critique); }
.message.info { border-left-color: var(--marque); }

.avis {
  border: 1px solid var(--filet-fort); border-left: 3px solid var(--attention);
  background: var(--surface); border-radius: var(--r);
  padding: var(--e4); margin-bottom: var(--e4);
}
.avis.grave { border-left-color: var(--critique); }
.avis.bon { border-left-color: var(--bon); }
.avis h3 { margin-top: 0; font-size: var(--t-base); }
.avis p:last-child { margin-bottom: 0; }

.vide {
  border: 1px dashed var(--filet-fort); border-radius: var(--r);
  padding: var(--e6) var(--e5); text-align: center; color: var(--encre-2);
  background: var(--surface);
}
.vide strong { display: block; color: var(--encre); font-size: var(--t-lg);
  font-family: var(--affichage); margin-bottom: var(--e2); }

/* ---------------------------------------------------------------- formulaires */

.champ { display: block; margin-bottom: var(--e4); }
.champ > span { display: block; font-size: var(--t-sm); margin-bottom: var(--e1); font-weight: 600; }
.champ .aide { font-weight: 400; color: var(--encre-2); font-size: var(--t-xs); }

input[type="text"], input[type="password"], input[type="date"], input[type="search"],
input[type="number"], select, textarea {
  width: 100%; padding: var(--e2) var(--e3);
  border: 1px solid var(--filet-fort); border-radius: var(--r);
  background: var(--surface); color: var(--encre);
  font: inherit;
}
textarea { min-height: 5rem; resize: vertical; }
input:disabled, select:disabled, textarea:disabled {
  background: var(--surface-creuse); color: var(--encre-2);
}

.grille-champs {
  display: grid; gap: var(--e3) var(--e4);
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}
.serre input, .serre select { max-width: 11rem; }

.bouton {
  display: inline-flex; align-items: center; gap: var(--e2);
  padding: var(--e2) var(--e4);
  border-radius: var(--r); border: 1px solid transparent;
  background: var(--bouton-fond); color: var(--bouton-encre);
  font: inherit; font-weight: 600; cursor: pointer;
  text-decoration: none;
}
.bouton:hover { filter: brightness(1.08); }
.bouton.second {
  background: var(--surface); color: var(--encre); border-color: var(--filet-fort);
}
.bouton.second:hover { background: var(--surface-creuse); filter: none; }
.bouton.danger { background: var(--surface); color: var(--critique-encre); border-color: var(--critique); }
.bouton.petit { padding: 1px var(--e3); font-size: var(--t-sm); }

.actions { display: flex; flex-wrap: wrap; gap: var(--e3); align-items: center; }
.actions.fin { justify-content: flex-end; }

fieldset { border: 1px solid var(--filet); border-radius: var(--r); padding: var(--e4); margin: 0 0 var(--e4); }
legend { font-weight: 600; font-size: var(--t-sm); padding: 0 var(--e2); }

.bascule { display: flex; align-items: center; gap: var(--e3); font-size: var(--t-sm); }
.bascule input { width: auto; }

/* -------------------------------------------------------------------- tableaux */

.cadre-table { overflow-x: auto; margin-bottom: var(--e4); }

/* Le tableau n'est pas du texte secondaire : c'est LE corps de ce produit,
   celui ou on lit les montants. Mesure du 22/09 : a --t-sm, 62 % du texte
   visible du site etait a la taille reservee au secondaire. Une taille qui
   porte la majorite de l'ecran est le corps, par definition. */
table { border-collapse: collapse; width: 100%; font-size: var(--t-base); }
caption { text-align: left; color: var(--encre-2); font-size: var(--t-sm); padding-bottom: var(--e2); }
th, td { padding: var(--e2) var(--e3); text-align: left; border-bottom: 1px solid var(--filet); }
thead th {
  font-size: var(--t-xs); text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--encre-2); border-bottom: 1px solid var(--filet-fort);
  position: sticky; top: 0; background: var(--surface); z-index: 1;
}
tbody tr:hover { background: var(--surface-creuse); }
/* `tbody tr` ne peut pas porter `transform` dans tous les navigateurs : la ligne
   d'un tableau n'etablit pas toujours de contexte de transformation. On anime
   donc l'OPACITE de la ligne et la translation de ses CELLULES, ce qui est
   equivalent a l'oeil et marche partout. */
[data-vivant] tbody tr td { will-change: auto; }
tfoot td { font-weight: 700; border-top: 2px solid var(--filet-fort); border-bottom: 0; }
.chiffres, td.chiffres, th.chiffres { text-align: right; font-variant-numeric: tabular-nums; }
.etroit { width: 1%; white-space: nowrap; }

/* ---------------------------------------------------------------------- arbre

   Les tiges verticales sont un degrade repete dont la largeur vaut le nombre de
   crans : un trait par niveau traverse, pose au milieu du cran. La coudee est un
   bord de pseudo-element. Aucune image, aucun script : l'arbre garde sa forme meme
   si tout le reste tombe. */

.arbre { border: 1px solid var(--filet); border-radius: var(--r); background: var(--surface);
  box-shadow: var(--ombre); overflow: hidden; }

.noeud {
  position: relative;
  display: flex; align-items: center; gap: var(--e3);
  padding: var(--e3) var(--e4);
  border-bottom: 1px solid var(--filet);
  background-image: repeating-linear-gradient(to right,
    var(--filet-fort) 0 1px, transparent 1px var(--indent));
  background-repeat: no-repeat;
  background-position: calc(var(--e4) + var(--indent) / 2) 0;
  background-size: calc(var(--indent) * var(--niveau, 0)) 100%;
}
/* `[hidden]` ne vaut que par la feuille du navigateur : n'importe quel `display`
   ecrit ici l'ecrase, et l'attribut devient decoratif. Le script repliait donc les
   branches sans que rien ne disparaisse -- le bouton « − » ne faisait rien, et le
   filtre de recherche non plus. */
.noeud[hidden] { display: none; }
.noeud:last-child { border-bottom: 0; }
.noeud:hover { background-color: var(--surface-creuse); }
.noeud > .identite { padding-left: calc(var(--indent) * var(--niveau, 0)); min-width: 0; flex: 1; }
.noeud::before {
  content: ""; position: absolute; top: 50%;
  left: calc(var(--e4) + var(--indent) * (var(--niveau, 0) - 1) + var(--indent) / 2);
  width: calc(var(--indent) / 2);
  border-top: 1px solid var(--filet-fort);
}
.noeud.racine::before { display: none; }

.rang-1 { --niveau: 1; }
.rang-2 { --niveau: 2; }
.rang-3 { --niveau: 3; }
.rang-4 { --niveau: 4; }
.rang-5 { --niveau: 5; }
.rang-6 { --niveau: 6; }
.rang-7 { --niveau: 7; }
.rang-8 { --niveau: 8; }

.noeud .nom { font-weight: 600; }
.noeud .nom a { color: inherit; text-decoration: none; }
.noeud .nom a:hover { text-decoration: underline; }
.noeud .ligne2 { font-size: var(--t-xs); color: var(--encre-2); }
.noeud .cotes { display: flex; align-items: center; gap: var(--e4); flex: 0 0 auto; }
.noeud .cote { text-align: right; min-width: 6.5rem; }
.noeud .cote .etiquette {
  display: block; font-size: var(--t-xs); color: var(--encre-2);
  text-transform: uppercase; letter-spacing: 0.05em;
}
.noeud .cote .valeur { font-weight: 600; }
/* Pas d'opacite sur la ligne d'un joueur parti : elle ecrase le contraste de
   TOUT ce qu'elle contient, pastille comprise -- axe-core la classait
   « serious » en theme clair. Le statut est deja dit par un mot et une
   pastille, c'est la regle : une couleur seule ne signale rien. */
.noeud.parti .ligne2, .noeud.parti .cote .valeur { color: var(--encre-2); }

.plier {
  flex: 0 0 auto; width: 1.4rem; height: 1.4rem;
  border: 1px solid var(--filet-fort); border-radius: var(--r);
  background: var(--surface); color: var(--encre-2);
  cursor: pointer; font: inherit; line-height: 1; padding: 0;
}
.plier[aria-expanded="false"] { color: var(--marque-encre); border-color: var(--marque); }
.plier.fantome { visibility: hidden; }

@media (max-width: 720px) {
  .noeud { flex-wrap: wrap; }
  .noeud .cotes { width: 100%; justify-content: flex-start;
                  padding-left: calc(var(--indent) * var(--niveau, 0)); }
  .noeud .cote { min-width: 5rem; text-align: left; }
}

/* ------------------------------------------------------------------- saisie */

.saisie td { vertical-align: middle; }
.saisie input[type="text"] { max-width: 9rem; }
.saisie .joueur { font-weight: 600; }
.saisie tr.vide-du-jour .joueur { font-weight: 400; color: var(--encre-2); }

.barre {
  display: block; height: 6px; border-radius: 999px;
  background: var(--surface-creuse); overflow: hidden; margin-top: var(--e1);
}
.barre i { display: block; height: 100%; background: var(--marque); }
.barre i.bon { background: var(--bon); }
.barre i.grave { background: var(--critique); }

/* Neuf largeurs suffisent pour une barre de proportion : au-dela, l'oeil ne fait
   plus la difference, et une largeur par valeur exigerait un style en ligne que la
   politique de securite interdit. */
.p0 { width: 0; } .p1 { width: 12.5%; } .p2 { width: 25%; } .p3 { width: 37.5%; }
.p4 { width: 50%; } .p5 { width: 62.5%; } .p6 { width: 75%; } .p7 { width: 87.5%; }
.p8 { width: 100%; }

details.repli > summary {
  cursor: pointer; font-weight: 600; font-size: var(--t-sm);
  padding: var(--e2) 0;
}
details.repli[open] > summary { margin-bottom: var(--e3); }

.fil { display: flex; flex-wrap: wrap; gap: var(--e2); align-items: center;
       font-size: var(--t-sm); color: var(--encre-2); margin-bottom: var(--e4); }
.fil a { text-decoration: none; }
.fil .fleche { color: var(--encre-2); }   /* mesuree a 1,41:1 en --filet-fort :
   decorative, donc hors du seuil WCAG, mais une separation qu'on ne voit pas
   ne separe rien. */

.mono { font-family: var(--mono); font-size: var(--t-xs); }

/* ---------------------------------------------------------------- connexion */

/* ============================================================================
   MOUVEMENT

   Trois regles, et elles tiennent tout :

     1. on n'anime que `transform` et `opacity`. Ce sont les deux seules
        proprietes que le navigateur peut confier a la carte graphique ; animer
        une hauteur ou une couleur de fond refait la mise en page a chaque image
        et le telephone decroche ;
     2. tout mouvement est MOTIVE. Une apparition dit « voici l'ordre de lecture »,
        un survol dit « ceci repond », un enfoncement dit « c'est parti ». Une
        animation qui ne dit rien est du bruit qu'on a paye deux fois : en temps
        de calcul et en attention ;
     3. `prefers-reduced-motion` coupe TOUT. Ce n'est pas une option : pour qui
        souffre de troubles vestibulaires, une page qui bouge donne la nausee.

   Les cascades passent par `nth-child` plutot que par une variable posee dans le
   HTML, parce que la politique de securite interdit les styles en ligne. */

:root {
  --vif: 140ms;                                   /* survol : doit sembler instantane */
  --pose: 420ms;                                  /* apparition : doit se voir */
  --sortie: cubic-bezier(0.16, 1, 0.3, 1);        /* part vite, s'arrete doucement */
}

@keyframes monte {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
@keyframes fond {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes agrandit {
  from { opacity: 0; transform: scale(1.06); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: no-preference) {
  /* Les transitions de PAGE. Deux lignes, et la navigation cesse de clignoter :
     le navigateur garde l'ancienne page a l'ecran et fond vers la nouvelle. Le
     rail de navigation ne bouge pas, puisqu'il est identique des deux cotes.

     Un navigateur qui ne connait pas encore `@view-transition` l'ignore et se
     comporte comme avant : il n'y a rien a detecter ni a servir en secours. */
  @view-transition { navigation: auto; }
  ::view-transition-old(root) { animation: fond 140ms linear reverse; }
  ::view-transition-new(root) { animation: fond 200ms var(--sortie); }

  /* La photographie du fronton ne clignote pas d'une page a l'autre : le
     navigateur la reconnait par son nom et la fait glisser d'une position a
     l'autre. C'est ce qui donne l'impression d'une seule page qui se reorganise
     plutot que de deux pages qui se succedent. */
  .fronton-scene { view-transition-name: scene; }

  .tuile, .vignette, .menu a, .bouton, .marque .jeton, tbody tr, .noeud {
    transition: transform var(--vif) var(--sortie),
                box-shadow var(--vif) var(--sortie),
                border-color var(--vif) linear,
                background-color var(--vif) linear,
                color var(--vif) linear;
  }

  /* La revelation et les compteurs sont dans `vivant.js`, pas ici. Un etat de
     depart invisible pose par la FEUILLE laisse la page blanche quand le script
     ne se charge pas ; pose par le SCRIPT, il n'existe que si le script existe. */
}

/* -------------------------------------------------------------------- survols
   Le soulevement est de DEUX pixels. A quatre, la page respire sous la souris et
   on ne sait plus ou on en est ; a un, on ne le voit pas. Deux, c'est la limite
   ou l'oeil comprend « ceci repond » sans que la page bouge. */
.tuile, .vignette { position: relative; isolation: isolate; }
.tuile::before, .vignette::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  border-radius: inherit; opacity: 0;
  transition: opacity 220ms linear;
  background: radial-gradient(14rem 14rem at var(--sx, 50%) var(--sy, 50%),
              color-mix(in srgb, var(--marque) 22%, transparent), transparent 70%);
}
[data-vivant] .tuile:hover::before,
[data-vivant] .vignette:hover::before { opacity: 1; }

.tuile:hover {
  transform: translateY(-2px);
  border-color: var(--marque);
  box-shadow: 0 1px 2px rgba(21, 23, 28, 0.06), 0 14px 32px rgba(79, 70, 229, 0.16);
}
.vignette:hover {
  transform: translateY(-2px);
  border-color: var(--marque);
  background: var(--surface);
  box-shadow: 0 10px 26px rgba(79, 70, 229, 0.14);
}
.vignette:hover .jeton { transform: scale(1.08); }
.menu a:hover { transform: translateX(2px); }
.bouton:hover { transform: translateY(-1px); }
.bouton:active { transform: translateY(0) scale(0.985); }
.noeud:hover { background-color: var(--surface-creuse); }

/* Le focus clavier obtient le MEME relief que la souris. Une interface qui ne
   repond qu'au pointeur laisse a qui navigue au clavier l'impression d'un site
   mort -- et c'est precisement la personne qui a le plus besoin d'un reperage. */
.tuile:focus-within, .vignette:focus-within {
  transform: translateY(-2px); border-color: var(--marque);
}

/* ============================================================================
   LES PHOTOGRAPHIES

   Deux vues de Jeju, servies par le site lui-meme : la politique de securite
   interdit les images distantes (`img-src 'self'`) et le produit doit marcher
   hors ligne. Elles sont en WebP et dimensionnees pour leur emplacement -- une
   photo de 4 Mo mise a l'echelle par le navigateur n'est pas « de meilleure
   qualite », elle est juste plus lente.

   Le voile n'est pas une coquetterie. Le texte passe par-dessus une photographie
   dont on ne maitrise pas le contraste local : sans lui, le sous-titre tombe
   tantot sur le ciel clair, tantot sur la roche sombre, et la moitie du temps il
   n'est pas lisible. Il est calcule pour tenir AA sur toute la largeur. */

.fronton {
  position: relative; isolation: isolate; overflow: hidden;
  border: 1px solid var(--filet); border-radius: var(--r);
  margin-bottom: var(--e6);
  min-height: 13.5rem;
  display: flex; align-items: flex-end;
}
.fronton-scene {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%;
  object-fit: cover; object-position: center 58%;
  /* Un peu plus grand que son cadre, pour que la parallaxe ait de quoi glisser
     sans decouvrir de bord. L'agrandissement est ICI et non dans le script :
     pose apres coup, il ferait sauter la photographie au premier rendu. */
  transform: scale(1.1);
}
.fronton::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(to right, rgba(8, 10, 20, 0.90) 0%,
                    rgba(8, 10, 20, 0.62) 46%, rgba(8, 10, 20, 0.18) 100%),
    linear-gradient(to top, rgba(8, 10, 20, 0.78) 0%, transparent 62%);
}
.fronton-texte { padding: var(--e5) var(--e5) var(--e5); max-width: 34rem; }
/* Couleurs ecrites en dur, et c'est voulu : le fronton est sombre dans les DEUX
   themes, puisque c'est la photographie qui decide du fond. */
.fronton-texte h1 { color: #ffffff; margin: 0; text-shadow: 0 1px 12px rgba(0,0,0,0.45); }
.fronton-texte .meta { color: #d7dcea; margin: var(--e1) 0 0; }

@media (max-width: 40rem) {
  .fronton { min-height: 9.5rem; }
  .fronton-texte { padding: var(--e4); }
  .fronton::after {
    background: linear-gradient(to top, rgba(8, 10, 20, 0.90) 0%,
                rgba(8, 10, 20, 0.55) 70%, rgba(8, 10, 20, 0.30) 100%);
  }
}

/* ------------------------------------------------------- la porte d'entree */
.accueil { min-height: 100dvh; }
.scene {
  position: fixed; inset: 0; z-index: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: center 62%;
  /* Decoration plein ecran : elle ne recoit pas de clic. Voir la note sur le voile
     juste en dessous -- c'est la meme regle, et elle n'a pas d'exception. */
  pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
  /* Une lente montee de trois secondes, une seule fois. Elle ne boucle pas : une
     image qui bouge sans fin derriere un formulaire empeche de se concentrer sur
     le formulaire. */
  .scene { animation: agrandit 3s var(--sortie) backwards; }
  .seul .carte { animation: monte 560ms var(--sortie) 160ms backwards; }
}
.scene + .seul::before {
  content: ""; position: fixed; inset: 0; z-index: 0;
  /* UNE DÉCORATION NE DOIT JAMAIS RECEVOIR UN CLIC. Sans cette ligne, ce voile --
     qui couvre tout l'ecran -- avalait les clics du formulaire de connexion : le
     champ et le bouton etaient visibles, et morts. Pierre est reste dehors deux
     jours. La regle vaut pour tout ce qui est pose par-dessus pour l'oeil seul. */
  pointer-events: none;
  /* Deux voiles, et chacun fait un travail different.
     1. LE BLEU DU SOIR, pose sur toute la surface. La photographie est prise a
        l'heure bleue, juste apres le coucher : le voile prolonge ce bleu-la au lieu
        d'en inventer un autre. C'est pour cela qu'il est bleu et non gris -- un gris
        aurait eteint l'image, ce bleu la continue.
     2. LA FLAQUE SOUS LA CARTE, concentree au centre et presque nulle sur les bords.
        Un voile uniforme assez fort pour rendre le texte lisible eteint la photo, or
        c'est elle qu'on est venu voir. Celui-ci ne fonce que la ou on lit.
     Le phare rouge tombe sous la carte : il reste visible en bas, comme un point de
     couleur unique dans une page qui n'en a presque pas. */
  background:
    /* 1. La flaque sous la carte. */
    radial-gradient(46% 42% at 50% 47%, rgba(3, 6, 20, 0.86),
                    rgba(3, 6, 20, 0.42) 58%, rgba(3, 6, 20, 0.08)),
    /* 2. Le ciel. Il est le plus clair de la photographie et le plus vide : c'est
          donc lui qu'on fonce le plus, et le bas de l'image -- le port, le phare,
          la jetee -- qu'on laisse respirer. Foncer partout pareil aurait donne une
          image grise ; foncer le vide donne une image de nuit. */
    linear-gradient(to bottom, rgba(3, 6, 22, 0.74), rgba(3, 6, 22, 0.20) 46%,
                    rgba(2, 4, 14, 0.44)),
    /* 3. La vignette, sur les bords seulement : elle ferme l'image sans l'eteindre. */
    radial-gradient(130% 110% at 50% 56%, transparent 34%, rgba(2, 4, 14, 0.62));
}
.seul {
  position: relative; z-index: 1;
  min-height: 100dvh; display: grid; place-items: center; padding: var(--e5);
  background: var(--plan);
}
.scene ~ .seul { background: transparent; }
.seul .carte {
  width: min(26rem, 100%); margin: 0;
  /* AU-DESSUS DU VOILE, TOUJOURS, et non pas seulement pendant l'animation.
     Un bloc ordinaire se peint AVANT les elements positionnes du meme plan : le
     voile passait donc par-dessus la carte -- texte compris -- des que l'animation
     d'entree se terminait. D'ou le symptome : la page s'assombrit d'un coup,
     quelques dixiemes de seconde apres son apparition, et ne repond plus.
     Pendant l'animation, la carte etait promue et passait devant ; c'est ce qui
     rendait le defaut invisible a l'ouverture, et seulement a l'ouverture. */
  position: relative; z-index: 1;
  /* La carte reste OPAQUE. Un panneau translucide sur une photographie laisse
     passer les contrastes de l'image sous le texte, et le champ de saisie devient
     illisible selon l'endroit ou il tombe. Le verre depoli est joli tant qu'on ne
     lit rien au travers. */
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5), 0 28px 80px rgba(0, 0, 0, 0.62);
}
.seul .accroche { margin: calc(var(--e2) * -1) 0 var(--e5); }

/* --------------------------------------------------------- l'etiquette de base
   Elle ne s'affiche QUE si `AGENCE_ETIQUETTE` est pose : la vraie base n'en porte
   aucune. C'est le bon sens -- une marque sur tout ne marque rien, et si l'on
   etiquetait aussi la production, c'est l'absence qui deviendrait suspecte. */
.etiquette-base {
  margin: 0;
  align-self: start;
  padding: 0.2rem var(--e3);
  border: 1px solid var(--attention);
  border-radius: var(--r);
  background: var(--attention);
  color: #241a00;
  font: 700 var(--t-xs)/1.4 var(--sans);
  letter-spacing: 0.08em; text-transform: uppercase;
}
.seul .etiquette-base { margin-bottom: var(--e3); display: inline-block; }
.seul .bouton { width: 100%; justify-content: center; padding: var(--e3) var(--e5); }

/* --------------------------------------------------------------- les marches */
.marches { list-style: none; margin: 0; padding: 0; counter-reset: marche; }
.marches li {
  counter-increment: marche;
  position: relative; padding: var(--e4) 0 var(--e4) 2.75rem;
  border-bottom: 1px solid var(--filet);
  display: grid; gap: var(--e2); justify-items: start;
}
.marches li:last-child { border-bottom: 0; padding-bottom: 0; }
.marches li::before {
  content: counter(marche);
  position: absolute; left: 0; top: var(--e4);
  width: 1.75rem; height: 1.75rem; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--marque-pale); color: var(--marque-encre);
  font: 600 var(--t-sm)/1 var(--sans);
}
.marches strong { font-size: var(--t-lg); font-family: var(--affichage); }
.marches .meta { max-width: var(--prose); }

/* ------------------------------------------------------------- les vignettes
   L'agence, visible. Six noms valent mieux que le chiffre « 6 » : on voit d'un
   coup qui a amene qui, et quel agent n'a pas encore de pourcentage. */
.roster {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: var(--e4);
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
}
.vignette {
  display: grid; gap: var(--e1);
  padding: var(--e4);
  border: 1px solid var(--filet); border-radius: var(--r);
  background: var(--surface-creuse);
}
.vignette.parti { opacity: 0.72; }
.vignette-nom {
  display: flex; align-items: center; gap: var(--e3);
  font-weight: 600; text-decoration: none; color: var(--lien);
}
.vignette-nom:hover { text-decoration: underline; }
.vignette-nom .jeton { width: 1.9rem; height: 1.9rem; font-size: var(--t-xs); }
.vignette-ligne { font-size: var(--t-sm); color: var(--encre-2); }
.vignette-chiffre {
  margin-top: var(--e2); padding-top: var(--e3);
  border-top: 1px solid var(--filet);
  font: 600 var(--t-lg)/1.2 var(--affichage); color: var(--encre);
  display: grid; gap: 2px;
}
.vignette-chiffre .meta { font-weight: 400; }

/* ============================================================================
   LE GRAPHIQUE DES MOIS

   Un SVG ecrit par le gabarit : les hauteurs passent par l'attribut `height`
   d'un `<rect>`, qui est un attribut de PRESENTATION et non un style. La
   politique de securite bloque `style="height:42%"` mais pas celui-la, donc le
   graphique est complet avant qu'aucun script ne tourne et `vivant.js` ne fait
   que le faire pousser.

   Deux barres superposees par mois : ce qui est entre, et la part qui en est
   ressortie vers les agences. On lit la marge d'un coup d'oeil sans qu'aucun
   chiffre ne soit ecrit -- et les chiffres sont dans le tableau juste dessous,
   pour qui veut la precision. */

.courbe { margin: 0 0 var(--e5); }
.courbe svg {
  display: block; width: 100%; height: 9rem;
  overflow: visible;
}
.courbe .barre-fond { fill: var(--surface-creuse); }
.courbe .barre {
  fill: var(--marque);
  /* L'origine en BAS : une barre qui pousse depuis le haut tombe au lieu de
     croitre, et l'oeil lit l'inverse de ce qu'on veut dire. */
  transform-origin: center bottom;
}
.courbe .barre-part { fill: color-mix(in srgb, var(--attention) 78%, transparent); }

.courbe-pieds {
  list-style: none; margin: var(--e3) 0 0; padding: 0;
  display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
  gap: var(--e2); text-align: center;
}
.courbe-pieds li { display: grid; gap: 2px; min-width: 0; }
.courbe-pieds a {
  font-size: var(--t-sm); font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.courbe-pieds .meta { font-size: var(--t-xs); }
.courbe-legende { margin: var(--e4) 0 0; }
.puce-pleine, .puce-part {
  display: inline-block; width: 0.7em; height: 0.7em; border-radius: 2px;
  vertical-align: baseline;
}
.puce-pleine { background: var(--marque); }
.puce-part { background: color-mix(in srgb, var(--attention) 78%, transparent); }

@media (max-width: 40rem) {
  .courbe svg { height: 7rem; }
  .courbe-pieds a { font-size: var(--t-xs); }
  .courbe-pieds .meta { display: none; }
}

/* ------------------------------------------------------------------ dossiers
   Les numeros sont en chasse fixe : un passeport se compare caractere par
   caractere avec le document qu'on a en main, et une chasse proportionnelle fait
   danser les colonnes sous l'oeil. */
.dossier-vu {
  display: grid; gap: var(--e4); margin: 0 0 var(--e4);
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
}
.dossier-vu > div { display: grid; gap: 2px; }
.dossier-vu dt {
  font-size: var(--t-xs); text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--encre-2);
}
.dossier-vu dd { margin: 0; font-size: var(--t-lg); }
.dossier-vu dd.mono { font-family: var(--mono); font-size: var(--t-base); }

.liste-nue { list-style: none; margin: var(--e3) 0 0; padding: 0; display: grid; gap: var(--e2); }
.liste-nue li { display: flex; align-items: center; gap: var(--e3); flex-wrap: wrap; }

/* ------------------------------------------------------------------- pieces */
.pieces {
  list-style: none; margin: 0 0 var(--e5); padding: 0;
  display: grid; gap: var(--e4);
  grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
}
.pieces li {
  display: grid; gap: var(--e2); justify-items: start;
  border: 1px solid var(--filet); border-radius: var(--r);
  padding: var(--e3); background: var(--surface-creuse);
}
.pieces img {
  /* Hauteur FIXE et `object-fit` : des documents de proportions differentes
     feraient sinon sauter la grille a chaque chargement. */
  width: 100%; height: 9rem; object-fit: cover;
  border-radius: var(--r); background: var(--plan);
  display: block;
}
.pieces .piece-mot { display: grid; gap: 2px; }

@media print {
  .rail, .actions, .bouton, .plier { display: none !important; }
  .page { padding: 0; }
  .carte, .arbre { box-shadow: none; border-color: #999; }
}
