/*
 * f031 — Bestiaire Kart, thème « écran de menu ».
 *
 * Ce fichier ne reprend PLUS les jetons du thème Bestiaire du portail Authelia
 * (files/authelia/bestiaire/theme.css). C'est une rupture volontaire,
 * expliquée dans Specifications/f031-kart.md : le portail est un seuil
 * sobre qu'on traverse en trois secondes, celui-ci est un tableau de tournoi
 * qu'on projette dans un salon pendant quatre heures. On est propriétaires de
 * l'application, donc on assume un thème à elle — ciel, contours cartoon,
 * rouge et jaune de la série — au lieu de le rendre optionnel comme pour
 * Authelia (f022) ou Jellyfin (f019), où l'on habille le logiciel de
 * quelqu'un d'autre.
 *
 * Ce que ça coûte : une couture visible au login. On arrive sur un portail
 * noir, on atterrit sur un ciel bleu. Le prix est payé une fois, par le seul
 * arbitre, et jamais par les trente invités qui ne passent pas par /admin.
 *
 * Deux fontes, toutes deux auto-hébergées (la CSP interdit toute origine
 * tierce, donc pas de Google Fonts et surtout aucun appel sortant depuis le
 * téléphone d'un invité) :
 *   Baloo 2 — les titres, les badges, les pastilles de position. Ronde et
 *     bombée, c'est elle qui fait le « menu de sélection de circuit ».
 *   Archivo — le corps de texte et TOUTES les tables. Baloo 2 est illisible
 *     en colonne de chiffres serrée ; Archivo est dessinée pour ça, et elle
 *     est déjà là, donc il reste un fil avec le portail.
 *
 * Contrastes : tous vérifiés au calcul, AA minimum. Deux règles en découlent
 * et expliquent des choix qui paraîtraient arbitraires — le rouge #e52521 ne
 * porte JAMAIS de texte sur fond clair (4,47:1, échoue), il ne sert que de
 * pavé sous du blanc (4,55:1) ; le texte rouge est un rouge foncé, #c1121a
 * (6,12:1). Le vert ne porte jamais de blanc (2,79:1) mais du noir (6,25:1).
 */

@font-face {
  font-family: "Baloo 2";
  src: url("/static/fonts/baloo2-latin.woff2") format("woff2");
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
}

@font-face {
  font-family: "Archivo";
  src: url("/static/fonts/archivo-latin.woff2") format("woff2");
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
}

:root {
  --ciel-haut: #8fd6ff;
  --ciel-bas: #4aa5ff;
  --encre: #1a1a1a;          /* le contour cartoon ET la couleur du texte */
  --carte: #fffdf6;          /* blanc cassé : moins dur qu'un #fff sous le ciel */
  --sourdine: #f0ece1;
  --texte-sourdine: #5a5750; /* 7,08:1 sur --carte */
  --rouge: #e52521;          /* pavés seulement */
  --rouge-texte: #c1121a;    /* 6,12:1 sur --carte */
  --jaune: #fbd000;
  --vert: #43b047;
  --bleu: #1565c0;
  --or: #fbd000;
  --argent: #cfd6dd;
  --bronze: #e08b3c;
  --trait: 4px;
  --rayon: 20px;
  --rayon-petit: 12px;
  /* L'ombre portée est FRANCHE et décalée, jamais floue : c'est ce qui donne
     l'impression d'un sticker posé sur la page plutôt que d'un panneau qui
     lévite. Un seul décalage partout, sinon l'éclairage part dans tous les
     sens. */
  --ombre: 5px 5px 0 var(--encre);
  --ombre-petite: 3px 3px 0 var(--encre);
  --titre: "Baloo 2", "Archivo", system-ui, sans-serif;
  --police: "Archivo", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  color-scheme: light;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  color: var(--encre);
  font-family: var(--police);
  line-height: 1.5;
  -webkit-text-size-adjust: 100%;
  /* Le ciel. Deux couches : les nuages (data:, la CSP l'autorise en img-src
     et n'autorise rien d'autre), puis le dégradé. Le fond est posé
     explicitement sur body ET sur la couleur de secours, pour qu'un rendu
     sans image ne laisse jamais du texte noir sur du blanc de navigateur. */
  background-color: var(--ciel-bas);
  background-image:
    /* Tuile de 620x480 et non 340x260 : à la petite taille, la répétition
       se voyait comme un quadrillage sur les grandes plages de ciel du
       tableau winner. Six nuages de tailles et de hauteurs différentes,
       placés hors grille, cassent la lecture du motif. */
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='620' height='480'%3E%3Cg fill='%23ffffff' opacity='.46'%3E%3Cellipse cx='74' cy='62' rx='54' ry='22'/%3E%3Cellipse cx='108' cy='48' rx='33' ry='20'/%3E%3Cellipse cx='402' cy='128' rx='40' ry='17'/%3E%3Cellipse cx='424' cy='118' rx='24' ry='15'/%3E%3Cellipse cx='238' cy='268' rx='62' ry='25'/%3E%3Cellipse cx='206' cy='254' rx='36' ry='22'/%3E%3Cellipse cx='530' cy='330' rx='46' ry='19'/%3E%3Cellipse cx='556' cy='318' rx='27' ry='17'/%3E%3Cellipse cx='96' cy='408' rx='38' ry='16'/%3E%3Cellipse cx='118' cy='398' rx='23' ry='14'/%3E%3Cellipse cx='356' cy='432' rx='58' ry='23'/%3E%3Cellipse cx='326' cy='420' rx='34' ry='20'/%3E%3C/g%3E%3C/svg%3E"),
    linear-gradient(180deg, var(--ciel-haut) 0%, var(--ciel-bas) 620px, var(--ciel-bas) 100%);
  background-repeat: repeat, no-repeat;
  background-attachment: fixed, fixed;
}

h1, h2, h3 {
  font-family: var(--titre);
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: .005em;
  margin: 0;
}

a { color: var(--bleu); }

/* ---- Contrôles ----------------------------------------------------------- */

button {
  font-family: var(--titre);
  font-size: 15px;
  font-weight: 700;
  color: var(--encre);
  background: var(--carte);
  border: var(--trait) solid var(--encre);
  border-radius: 999px;
  padding: 6px 18px;
  cursor: pointer;
  box-shadow: var(--ombre-petite);
  /* 44 px : la cible tactile d'un pouce, parce que la saisie des arrivées se
     fait sur un téléphone, debout, entre deux courses. Y COMPRIS les boutons
     « discrets » : ce sont eux qui ouvrent la saisie d'une arrivée, c'est le
     geste le plus fréquent de la soirée. */
  min-height: 44px;
}
button:hover:not(:disabled) { background: var(--jaune); }
/* Le bouton s'enfonce : l'ombre disparaît et le bouton descend d'autant. */
button:active:not(:disabled) { transform: translate(3px, 3px); box-shadow: none; }
button:disabled { opacity: .5; cursor: not-allowed; box-shadow: none; }
button.primaire { background: var(--rouge); color: #ffffff; }
button.primaire:hover:not(:disabled) { background: #ff3b35; }
button.danger { color: var(--rouge-texte); }
button.discret {
  background: var(--sourdine);
  font-size: 14px;
  padding: 6px 14px;
  box-shadow: none;
}
button.discret:active:not(:disabled) { transform: translate(2px, 2px); }

input[type=text], input[type=number] {
  font: inherit;
  color: var(--encre);
  background: #ffffff;
  border: var(--trait) solid var(--encre);
  border-radius: var(--rayon-petit);
  padding: 8px 12px;
  min-height: 44px;
}
input::placeholder { color: var(--texte-sourdine); opacity: 1; }
input:focus-visible, button:focus-visible, [tabindex]:focus-visible {
  /* Le contour de focus doit se voir sur le noir du cerne comme sur le blanc
     des cartes : un bleu franc doublé d'un liseré blanc. */
  outline: 3px solid var(--bleu);
  outline-offset: 3px;
}

/* ---- Ossature ------------------------------------------------------------ */

/* 1320 et non 1180 : c'est la largeur qu'il faut pour que les QUATRE poules
   tiennent sur une seule rangée sur un écran de 1280, ce qui est le mode
   d'emploi de cette page — un vidéoprojecteur dans un salon, tout le tournoi
   d'un coup d'œil. En dessous la grille retombe à trois puis à une colonne. */
.page { max-width: 1320px; margin: 0 auto; padding: 0 16px 64px; }

header.chapeau {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 22px 0 18px;
  flex-wrap: wrap;
}
.marque { display: flex; align-items: center; gap: 14px; text-decoration: none; color: inherit; }
.marque svg { width: 62px; height: 62px; flex: none; }
.marque h1 {
  font-size: 32px;
  /* Le titre est sur le ciel, pas sur une carte : il lui faut son propre
     détourage pour tenir sur un fond dégradé et nuageux. */
  color: #ffffff;
  -webkit-text-stroke: 4px var(--encre);
  paint-order: stroke fill;
  text-shadow: 3px 3px 0 var(--encre);
}
.marque .sous {
  font-family: var(--titre);
  font-weight: 700;
  font-size: 14px;
  /* 6,73:1 sur le bas du ciel, le pire cas. */
  color: var(--encre);
}
.chapeau .pousse { margin-left: auto; }

.etiquette {
  display: inline-block;
  font-family: var(--titre);
  padding: 4px 14px;
  border-radius: 999px;
  border: 3px solid var(--encre);
  background: var(--carte);
  color: var(--encre);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .02em;
  text-transform: uppercase;
  text-decoration: none;
  box-shadow: 2px 2px 0 var(--encre);
}
a.etiquette:hover { background: var(--jaune); }
/* Le fond ne porte pas l'information tout seul : le libellé dit déjà
   « Phase de poules » ou « Terminé ». La couleur ne fait que le redire. */
.etiquette.vivant { background: var(--vert); }
.etiquette.fini { background: var(--jaune); }

nav.onglets {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 20px;
}
nav.onglets button {
  background: var(--carte);
  color: var(--encre);
  font-size: 15px;
  padding: 6px 16px;
}
nav.onglets button[aria-current="page"] {
  background: var(--jaune);
  /* L'onglet courant n'est pas signalé QUE par sa couleur : il est enfoncé
     (pas d'ombre, décalé) et il porte aria-current. */
  transform: translate(3px, 3px);
  box-shadow: none;
}

.carte {
  background: var(--carte);
  border: var(--trait) solid var(--encre);
  border-radius: var(--rayon);
  box-shadow: var(--ombre);
  padding: 14px 16px 16px;
  /* Le bandeau plein déborde jusqu'aux bords arrondis : il faut rogner. */
  overflow: hidden;
}
/* Le classement général est la seule vue qui rend une carte SEULE dans #vue.
   À 1320 px elle s'étirait sur toute la largeur et le nom du pilote se
   retrouvait à un demi-écran de sa colonne de points. Les vues à grille
   (poules, pilotes) et les tableaux ne sont pas concernés : eux ont besoin de
   toute la largeur. */
#vue > section.carte { max-width: 920px; }

.grille { display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(288px, 1fr)); }
.pile { display: flex; flex-direction: column; gap: 12px; }
.rangee { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.vide {
  background: var(--carte);
  border: var(--trait) solid var(--encre);
  border-radius: var(--rayon);
  box-shadow: var(--ombre);
  padding: 28px 16px;
  text-align: center;
  font-family: var(--titre);
  font-weight: 700;
}

/* Le bandeau de poule, en pavé plein d'un bord à l'autre de la carte. C'est
   la pièce qui fait « menu » : un titre posé sur un aplat, pas un titre en
   l'air. Il est toujours le premier enfant de .carte, d'où les marges
   négatives qui annulent la gouttière. */
.bandeau {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  /* 2 px et non 14 : le bandeau est toujours le premier enfant d'une
     .carte.pile, dont la gouttière de 12 px fait le reste. */
  margin: -14px -16px 2px;
  padding: 10px 16px;
  background: var(--rouge);
  border-bottom: var(--trait) solid var(--encre);
}
.bandeau h2 {
  font-size: 21px;
  color: #ffffff; /* 4,55:1 sur le rouge */
}
.bandeau .etiquette { margin-left: auto; box-shadow: none; }
.bandeau.bleu { background: var(--bleu); }
.bandeau.jaune { background: var(--jaune); }
.bandeau.jaune h2 { color: var(--encre); }

/* ---- Classements --------------------------------------------------------- */

table { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
th, td { text-align: left; padding: 7px 8px; border-bottom: 2px solid #e2ddd0; }
th {
  font-family: var(--titre);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--texte-sourdine);
  font-weight: 700;
  border-bottom-color: var(--encre);
}
tr:last-child td { border-bottom: none; }
td.nombre, th.nombre { text-align: right; }
td.nombre { font-weight: 700; }
.rang {
  width: 34px;
  font-family: var(--titre);
  font-weight: 800;
  color: var(--texte-sourdine);
}

/* Les 4 qualifiés pour le tournoi winner, dans chaque poule. La couleur ne
   porte jamais l'information seule : le fond bleu est DOUBLÉ d'un liseré
   épais en tête de ligne, visible sans distinguer les teintes. */
tr.qualifie td { background: #dff0ff; font-weight: 700; }
tr.qualifie td:first-child { box-shadow: inset 5px 0 0 var(--bleu); }
tr.fantome td { color: var(--texte-sourdine); font-style: italic; background: none; }
/* Le signe « départagé au nom », dessiné dans kart.js. width/height en em
   pour qu'il suive la taille du nom à côté duquel il se pose. */
.exaequo {
  width: .78em;
  height: .78em;
  margin-left: .35em;
  vertical-align: -.04em;
  fill: var(--rouge-texte);
  cursor: help;
  flex: none;
}

/* ---- Courses ------------------------------------------------------------- */

.course {
  border: 3px solid var(--encre);
  border-radius: var(--rayon-petit);
  background: #ffffff;
  padding: 10px 12px 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
/* Ces deux états sont redits en clair dans le titre de la carte (le libellé
   de la course) et par la présence ou non des positions : la bande de
   couleur n'est qu'un repère de survol. */
.course.courue { background: #f3faf3; border-color: #1f6b23; }
.course.prete { border-color: var(--bleu); box-shadow: var(--ombre-petite); }
.course > .titre {
  display: flex; align-items: baseline; gap: 8px;
  font-size: 12px; color: var(--texte-sourdine);
}
.course > .titre b {
  font-family: var(--titre);
  color: var(--encre);
  font-size: 15px;
  letter-spacing: .02em;
}
.course ol { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.course li { display: flex; align-items: center; gap: 9px; padding: 2px 0; }

/* La pastille de position. « 1st / 2nd / 3rd / 4th » et pas un chiffre nu :
   c'est ce que l'écran d'arrivée de la série affiche, et un ordinal se lit
   sans légende là où un « 3 » isolé pourrait être un nombre de points. */
.place {
  flex: none;
  min-width: 40px;
  height: 28px;
  padding: 0 7px;
  border: 3px solid var(--encre);
  border-radius: 8px;
  display: grid; place-items: center;
  font-family: var(--titre);
  font-size: 14px; font-weight: 800; line-height: 1;
  background: var(--sourdine); color: var(--texte-sourdine);
}
.course li.p1 .place { background: var(--or); color: var(--encre); }
.course li.p2 .place { background: var(--argent); color: var(--encre); }
.course li.p3 .place { background: var(--bronze); color: var(--encre); }
.course li.p4 .place { background: #ffffff; color: var(--encre); }
.course li .pts {
  margin-left: auto;
  font-family: var(--titre);
  font-weight: 700;
  font-size: 13px;
  color: var(--texte-sourdine);
}
.course li.attente { color: var(--texte-sourdine); font-style: italic; }
.course li.spectre { color: var(--texte-sourdine); }
.course button { align-self: flex-start; }

/* ---- Tableaux winner / looser -------------------------------------------- */

.tableau { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); align-items: start; }
.colonne h3 {
  font-size: 15px;
  color: var(--encre);
  background: var(--jaune);
  border: 3px solid var(--encre);
  border-radius: 999px;
  box-shadow: 2px 2px 0 var(--encre);
  padding: 5px 14px;
  margin-bottom: 12px;
  text-align: center;
}
.colonne .pile { gap: 10px; }

/* Le bandeau du champion : le seul endroit de la page qui a le droit d'être
   grand. C'est l'écran de fin de course. */
.champion {
  display: flex; align-items: center; gap: 16px;
  border: var(--trait) solid var(--encre);
  background: linear-gradient(180deg, #ffe98a 0%, var(--jaune) 100%);
  border-radius: var(--rayon);
  box-shadow: var(--ombre);
  padding: 16px 20px;
}
.champion .nom {
  font-family: var(--titre);
  font-size: 30px;
  font-weight: 800;
  line-height: 1.1;
  color: var(--encre);
}
.champion .quoi {
  font-family: var(--titre);
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: .06em;
  font-weight: 700;
  color: var(--encre);
}
.champion .place { height: 46px; min-width: 62px; font-size: 22px; background: var(--carte); }

.consigne { color: var(--texte-sourdine); font-size: 14px; margin: 0; }

/* ---- Saisie d'une arrivée ------------------------------------------------ */

dialog {
  background: var(--carte);
  color: var(--encre);
  border: var(--trait) solid var(--encre);
  border-radius: var(--rayon);
  box-shadow: var(--ombre);
  padding: 0;
  width: min(440px, calc(100vw - 32px));
}
dialog::backdrop { background: rgba(26, 26, 26, .55); }
dialog .corps { padding: 18px; display: flex; flex-direction: column; gap: 14px; }
dialog h2 { font-size: 21px; }
.podium { display: flex; flex-direction: column; gap: 8px; }
.podium button {
  display: flex; align-items: center; gap: 10px;
  width: 100%; justify-content: flex-start; text-align: left;
  border-radius: var(--rayon-petit);
  font-family: var(--police);
  font-weight: 600;
  padding: 6px 10px;
}
.podium button .place { min-width: 46px; }
/* Choisi : fond jaune ET pastille noire ET l'ordinal qui remplace le point —
   trois signaux, dont deux non colorés. */
.podium button.choisi { background: var(--jaune); }
.podium button.choisi .place { background: var(--encre); color: var(--jaune); }

.alerte {
  border: 3px solid var(--rouge-texte);
  background: #fdeceb;
  color: var(--rouge-texte);
  border-radius: var(--rayon-petit);
  padding: 10px 12px;
  font-size: 14px;
  font-weight: 700;
  margin-bottom: 14px;
}

/* ---- Pied ---------------------------------------------------------------- */

footer {
  margin-top: 36px;
  background: var(--carte);
  border: 3px solid var(--encre);
  border-radius: var(--rayon-petit);
  box-shadow: var(--ombre-petite);
  padding: 12px 16px;
  color: var(--texte-sourdine);
  font-size: 13px;
}
footer code { background: var(--sourdine); padding: 1px 5px; border-radius: 4px; }

@media (max-width: 560px) {
  /* Gouttière de 16 px conservée telle quelle : c'est la marge qui empêche
     les cartes et leurs ombres de toucher le bord de l'écran. */
  .page { padding: 0 16px 48px; }
  .marque h1 { font-size: 25px; -webkit-text-stroke-width: 3px; }
  .marque svg { width: 48px; height: 48px; }
  .marque { gap: 10px; }
  .grille { grid-template-columns: 1fr; }
  .carte { padding: 12px 12px 14px; }
  .bandeau { margin: -12px -12px 2px; padding: 9px 12px; }
  th, td { padding: 6px 5px; }
  .rang { width: 30px; }
}

/* Une soirée de tournoi, ce sont des redessins toutes les 15 s : rien ne doit
   bouger tout seul pour quelqu'un qui a demandé moins d'animation. Les
   enfoncements de boutons restent (ce sont des transforms instantanés au
   :active, pas des animations), mais plus rien ne transitionne. */
@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}
