/* ===========================================================================
   tir-tar.fr — page des scores. Thème « Cible ».

   Le motif vient de la cible elle-même : des formes rondes, un bleu franc,
   beaucoup de blanc. Les chiffres sont en Sora, le texte en Public Sans.

   Les polices sont servies depuis ce serveur, et non depuis Google : sinon
   l'adresse IP de chaque visiteur partirait chez un tiers à chaque page, ce
   qu'aucune fonction du site ne justifie.
   =========================================================================== */

@font-face {
  font-family: 'Sora';
  font-style: normal;
  font-weight: 100 800;              /* fonte variable : une seule requête */
  font-display: swap;
  src: url('/fonts/sora-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: 'Public Sans';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/fonts/publicsans-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;
}
/* Le tireur saisit lui-même ses armes et ses lots : un nom tchèque ou polonais
   doit s'écrire correctement, d'où ce second sous-ensemble. */
@font-face {
  font-family: 'Public Sans';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/fonts/publicsans-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;
}

:root {
  --bg: #ffffff;
  --card: #ffffff;
  --surface: #f6f7f9;        /* champs, totaux, blocs de chiffres */
  --text: #16181d;
  --muted: #5a6070;
  --line: #e3e5ea;
  /* Le bleu de la Fédération, relevé sur le logo lui-même (#00388c) : le
     pictogramme de la discipline et le logo FFTir le partagent exactement.
     Un bleu de site voisin mais différent se serait vu au premier coup d'œil. */
  --accent: #00388c;
  --accent-text: #ffffff;
  --accent-doux: #e9eff9;
  --fftir-rouge: #ed2939;
  --ok: #10664a;
  --err: #c02626;

  --titre: 'Sora', system-ui, sans-serif;
  --corps: 'Public Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;

  --r-card: 18px;
  --r-champ: 12px;
  --r-pill: 999px;

  color-scheme: light dark;
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0e1015;
    --card: #171a21;
    --surface: #1d212a;
    --text: #e9ebf0;
    --muted: #9aa1b2;
    --line: #2a2f3a;
    /* Le bleu de plein jour tombe sous le seuil de lisibilité sur fond sombre :
       ce n'est pas le même bleu éclairci, c'est un bleu repensé pour ce fond. */
    /* Sur fond sombre, le bleu fédéral tombe très en dessous du seuil de
       lisibilité : on en prend une déclinaison claire de même teinte. Le
       LOGO, lui, n'est jamais recoloré — la charte l'interdit. */
    --accent: #7ba7e8;
    --accent-text: #08142a;
    --accent-doux: #16233a;
    --ok: #4ade80;
    --err: #f97066;
  }
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 17px/1.5 var(--corps);
  -webkit-text-size-adjust: 100%;
}

/* ================================ entête ================================= */
.top {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  max-width: 560px; margin: 0 auto;
  padding: max(16px, env(safe-area-inset-top)) 18px 10px;
}
.home {
  display: inline-flex; align-items: center; gap: 9px;
  color: var(--text); text-decoration: none;
  font-family: var(--titre); font-size: 1.12rem; font-weight: 700; letter-spacing: -.02em;
}
/* Le pictogramme de la discipline, à côté du nom. Sur fond sombre il
   disparaîtrait : on le pose sur une pastille claire plutôt que de le
   recolorer. */
.home img { width: 26px; height: 26px; object-fit: contain; display: block; }
@media (prefers-color-scheme: dark) {
  .home img { background: #fff; border-radius: 6px; padding: 2px; box-sizing: content-box; }
}
.who {
  margin: 0; color: var(--muted); font-size: .9rem; font-weight: 500;
}

.wrap {
  max-width: 560px; margin: 0 auto;
  padding: 10px 18px calc(88px + env(safe-area-inset-bottom));
  display: grid; gap: 14px;
}
/* Un élément de grille ne rétrécit pas sous sa largeur minimale de contenu
   tant qu'on ne le lui autorise pas : sans ces min-width, une liste déroulante
   un peu longue élargit toute la page et fait défiler l'écran de côté. */
#app, .page { display: grid; gap: 14px; min-width: 0; }
.page > .card, .wrap > * { min-width: 0; }

.head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.head h1 { margin: 0; }
.head select { width: auto; max-width: 60%; min-width: 0; min-height: 42px; padding: 6px 12px; font-size: .92rem; }

h1 { font-family: var(--titre); font-size: 1.45rem; font-weight: 700; letter-spacing: -.02em; margin: 0 0 14px; }
h2 { font-family: var(--titre); font-size: 1.08rem; font-weight: 600; letter-spacing: -.01em; margin: 0 0 12px; }
.muted { color: var(--muted); margin: -8px 0 14px; font-size: .92rem; }
.notice { color: var(--muted); text-align: center; }
.count { color: var(--muted); font-family: var(--corps); font-weight: 500; font-size: .88rem; }

.card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-card); padding: 18px;
}

/* ================================ champs ================================= */
form { display: grid; gap: 14px; }
label { display: grid; gap: 7px; font-weight: 600; font-size: .92rem; color: var(--muted); }
/* Deux champs côte à côte réclament chacun leur largeur minimale, et le champ
   de date d'iOS réclame plus que sa moitié : il écrase le voisin, et les deux
   finissent par se chevaucher. Sur téléphone on les empile — une ligne de plus
   vaut mieux qu'un champ illisible. Les deux colonnes ne reviennent que quand
   la place existe vraiment. */
.row2 { display: grid; grid-template-columns: 1fr; gap: 12px; }
.row2 > * { min-width: 0; }
@media (min-width: 480px) {
  .row2 { grid-template-columns: 1fr 1fr; }
}
.hint { color: var(--muted); font-weight: 400; font-size: .82rem; }

/* 16 px minimum : en dessous, Safari zoome sur le champ à la saisie. */
input, select {
  width: 100%; font: inherit; font-weight: 400; font-size: 1rem;
  color: var(--text); background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-champ);
  padding: 12px; min-height: 50px;
}
input:focus, select:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
input::placeholder { color: var(--muted); opacity: .75; }

.score-row {
  display: flex; align-items: center; gap: 10px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-champ); padding: 0 12px;
}
/* Le champ vit dans la boîte : c'est elle qui porte le cadre, sinon deux
   bordures se superposent et le chiffre paraît enfermé deux fois. */
.score-row input {
  border: 0; background: none; padding: 0; min-height: 52px;
  font-family: var(--titre); font-size: 1.3rem; font-weight: 700; text-align: center;
}
.score-row input:focus { outline: 0; }
.score-row:focus-within { outline: 2px solid var(--accent); outline-offset: 1px; }
.max { color: var(--muted); font-weight: 500; font-size: .88rem; white-space: nowrap; }

.btn {
  font: inherit; font-family: var(--titre); font-weight: 600; font-size: 1rem;
  min-height: 54px; border: 0; border-radius: var(--r-pill);
  background: var(--accent); color: var(--accent-text); cursor: pointer;
}
.btn:disabled { opacity: .55; cursor: progress; filter: none; }
.link {
  font: inherit; background: none; border: 0; padding: 0;
  color: var(--accent); text-decoration: underline; cursor: pointer;
}

.msg { margin: 0; min-height: 1.4em; font-weight: 600; font-size: .95rem; }
.msg.ok { color: var(--ok); }
.msg.err { color: var(--err); }

/* ================================ liste ==================================
   Chaque séance est une carte à part entière : sur un téléphone, des cartes
   se distinguent mieux que des lignes séparées par un filet. */
.liste { display: grid; gap: 8px; min-width: 0; }
.ligne {
  padding: 12px 14px; min-width: 0;
  border: 1px solid var(--line); border-radius: 14px;
}
.vue { display: flex; align-items: baseline; gap: 10px; }
.meta {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; margin-top: 4px;
}
.infos {
  display: block; color: var(--muted); font-size: .82rem;
  font-variant-numeric: tabular-nums; min-width: 0;
}
.actions { display: flex; flex: 0 0 auto; gap: 2px; }
.ep { flex: 1 1 auto; min-width: 0; }
/* Un intitulé long ne doit pas faire une ligne de trois étages sur téléphone. */
.ep b { display: block; font-size: .95rem; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pts {
  font-family: var(--titre); font-size: 1.15rem; font-weight: 700;
  font-variant-numeric: tabular-nums; white-space: nowrap; letter-spacing: -.02em;
}
.pts small { color: var(--muted); font-weight: 500; font-size: .74rem; }

/* La pastille de discipline porte la teinte de sa courbe : on relie d'un coup
   d'œil une ligne du graphique à une séance de la liste. La teinte n'est que
   le fond — le code reste écrit, et l'encre du texte garde son contraste
   quelle que soit la couleur de la série. */
.code {
  display: inline-block; margin-right: 7px; padding: 2px 8px;
  border-radius: 7px; border: 1px solid color-mix(in srgb, var(--c, var(--accent)) 38%, var(--card));
  background: color-mix(in srgb, var(--c, var(--accent)) 12%, var(--card));
  color: var(--text);
  font-family: var(--titre); font-size: .74rem; font-weight: 700;
  letter-spacing: .01em; vertical-align: 1px;
}

/* 44 px : en dessous, la cible est trop petite pour le pouce et l'on croit
   que le bouton ne marche pas. */
.sup {
  display: grid; place-items: center;
  min-width: 42px; min-height: 42px;
  background: none; border: 0; cursor: pointer; color: var(--muted);
  border-radius: 10px;
}
.sup svg { width: 19px; height: 19px; display: block; }
.sup:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.sup.ouvert { color: var(--accent); background: var(--accent-doux); }

/* Confirmation, dans la ligne même */
.conf {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 10px; padding: 2px 0;
}
.q { font-size: .93rem; }
.acts { display: flex; gap: 8px; }
.mini {
  font: inherit; font-size: .9rem; font-weight: 600;
  min-height: 42px; padding: 8px 16px;
  border: 1px solid var(--line); border-radius: var(--r-pill);
  background: var(--card); color: var(--text); cursor: pointer;
}
.mini:disabled { opacity: .6; cursor: progress; }
.mini.danger { border-color: transparent; background: var(--err); color: #fff; }
.mini.vert { border-color: transparent; background: var(--accent); color: var(--accent-text); }
.err-ligne { margin: 6px 0 0; font-size: .88rem; }

.vide { color: var(--muted); }

/* =============================== comptes ================================= */
.bas { margin: 14px 0 0; color: var(--muted); font-size: .9rem; text-align: center; }
.tag {
  display: inline-block; vertical-align: 1px; margin-left: 6px;
  padding: 2px 9px; border-radius: var(--r-pill);
  background: var(--accent); color: var(--accent-text);
  font-size: .66rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
}
.etat { color: var(--muted); font-size: .85rem; }
#listeComptes .acts { flex-wrap: wrap; justify-content: flex-end; }
/* Le compte actif porte son bouton de suppression à droite de son nom. */
.compte-actif .vue { align-items: center; }
.compte-actif .actions { margin-left: auto; }

/* ========================== mode administrateur ==========================
   Le tireur est en bleu, l'administrateur en violet — et surtout, un bandeau
   plein barre le haut de l'écran. Une différence de teinte seule ne suffit
   pas : on doit savoir où l'on est sans avoir à comparer deux nuances. */
body.admin {
  --bg: #faf8ff;
  --card: #ffffff;
  --surface: #f4f1fd;
  --text: #1b1630;
  --muted: #5f5880;
  --line: #e4defa;
  --accent: #6d28d9;
  --accent-text: #ffffff;
  --accent-doux: #f1ebfe;
  border-top: 5px solid var(--accent);
}
@media (prefers-color-scheme: dark) {
  body.admin {
    --bg: #120f1c;
    --card: #1b1729;
    --surface: #221d33;
    --text: #ece9f6;
    --muted: #a79fc4;
    --line: #322b48;
    --accent: #b9a5fb;
    --accent-text: #160f28;
    --accent-doux: #241d3a;
  }
}
body.admin .top { border-bottom: 1px solid var(--line); padding-bottom: 10px; }

/* =============================== journal ================================= */
.journal .etat { font-size: .8rem; }
.journal.rate .etat { color: var(--err); font-weight: 700; }
.journal.rate b::after { content: ' ⚠'; color: var(--err); }
#listeJournal .ligne { grid-template-columns: none; }
#listeJournal .journal {
  display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 10px;
}

.sousliste { margin-top: 18px; padding-top: 6px; border-top: 1px solid var(--line); }
.sousliste h3 {
  margin: 8px 0 6px; font-family: var(--titre); font-size: .74rem; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--muted);
}

/* ================================= menu ==================================
   Barre fixe en bas : c'est là que se trouve le pouce sur un téléphone.
   Ce sont des boutons et non des liens — la page n'est jamais rechargée,
   donc la session ne peut pas se perdre en naviguant. */
.menu {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 10;
  display: flex; justify-content: center; gap: 2px;
  padding: 4px 8px calc(4px + env(safe-area-inset-bottom));
  background: color-mix(in srgb, var(--card) 92%, transparent);
  border-top: 1px solid var(--line);
  backdrop-filter: blur(10px);
}
.menu button {
  flex: 1 1 0; max-width: 150px;
  display: grid; justify-items: center; gap: 3px;
  min-height: 60px; padding: 8px 4px;
  font: inherit; font-size: .7rem; font-weight: 600;
  color: var(--muted); background: none; border: 0; border-radius: 14px;
  cursor: pointer;
}
.menu button .ico { display: grid; place-items: center; }
.menu button .ico svg { width: 22px; height: 22px; display: block; }
.menu button.actif { color: var(--accent); }
/* Le même menu sur les pages hors du carnet (prix) : des liens, habillés comme les boutons. */
.menu a {
  flex: 1 1 0; max-width: 150px;
  display: grid; justify-items: center; gap: 3px;
  min-height: 60px; padding: 8px 4px; text-align: center;
  font-size: .7rem; font-weight: 600; color: var(--muted); text-decoration: none; border-radius: 14px;
}
.menu a .ico { display: grid; place-items: center; }
.menu a .ico svg { width: 22px; height: 22px; display: block; }
.menu a.actif { color: var(--accent); }
.menu a:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* La barre du bas ne doit pas cacher la fin de la page. */
body.avec-menu { padding-bottom: calc(80px + env(safe-area-inset-bottom)); }

/* Le compte des demandes en attente, sur le bouton lui-même. Ambre et non
   rouge : c'est quelque chose à faire, pas une erreur. */
.menu button { position: relative; }
.pastille {
  position: absolute; top: 6px; left: 50%; margin-left: 4px;
  min-width: 18px; height: 18px; padding: 0 5px;
  display: grid; place-items: center;
  border-radius: 999px; background: #b45309; color: #fff;
  font-family: var(--titre); font-size: .66rem; font-weight: 700; line-height: 1;
}
@media (min-width: 1024px) {
  /* Menu latéral : le bouton est large, la pastille se range à droite. */
  .pastille { top: 50%; left: auto; right: 12px; margin: -9px 0 0; }
}
.menu button:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* ================================ bandeau ================================
   Au-dessus du menu, muet tant que tout va bien. Il ne dit que deux choses :
   que le réseau manque, et combien de séances attendent de partir. */
.bandeau {
  position: fixed; left: 0; right: 0; z-index: 11;
  bottom: calc(60px + env(safe-area-inset-bottom));
  margin: 0; padding: 9px 18px;
  font-size: .82rem; font-weight: 600; text-align: center;
  background: var(--accent-doux); color: var(--accent);
  border-top: 1px solid var(--line);
}
.bandeau.hors { background: #b45309; color: #fff; border-top-color: #b45309; }
@media (min-width: 1024px) {
  /* Le menu est passé sur le côté : le bandeau se cale au-dessus du contenu. */
  .bandeau { bottom: 0; left: 232px; }
}

/* =============================== graphique ===============================
   SVG écrit à la main : rien à charger, et net à toutes les tailles. */
#graphique { overflow: hidden; }
.graph { width: 100%; height: auto; display: block; }
.g-grille { stroke: var(--line); stroke-width: 1; }
.g-axe { fill: var(--muted); font-size: 12px; font-family: var(--corps); }
/* La couleur de série est posée en ligne par le tracé ; celle-ci n'est que le
   repli quand aucune n'est fournie. Traits fins, marqueurs d'au moins 8 px. */
.g-ligne { fill: none; stroke: var(--accent); stroke-width: 2.4; stroke-linejoin: round; stroke-linecap: round; }
.g-point { fill: var(--card); stroke: var(--accent); stroke-width: 2.2; }
.g-val { fill: var(--text); font-size: 12px; font-weight: 700; font-family: var(--titre); }

/* ============================= statistiques ============================== */
.stats { display: flex; gap: 8px; margin-top: 14px; }
.stats div {
  flex: 1; padding: 12px 6px; text-align: center;
  background: var(--surface); border-radius: 14px;
}
.stats b {
  display: block; font-family: var(--titre); font-weight: 700;
  font-variant-numeric: tabular-nums; letter-spacing: -.02em;
  /* « 174,3 / 200 » ne doit pas se couper entre le nombre et son maximum :
     mieux vaut un chiffre un peu plus petit qu'une valeur sur deux lignes
     quand celle d'a cote tient sur une seule. */
  white-space: nowrap; font-size: clamp(.95rem, 4.4vw, 1.2rem);
}
.stats b small { color: var(--muted); font-size: .68rem; font-weight: 500; letter-spacing: 0; }
.stats span { color: var(--muted); font-size: .74rem; }

/* =========================== détail par série ============================
   Trois colonnes : l'intitulé, une jauge, la moyenne. La jauge ne porte pas
   de couleur distinctive — c'est sa LONGUEUR qui compare, et la phrase en
   dessous qui nomme la série à travailler. Une couleur de plus n'aurait rien
   ajouté qu'on ne lise déjà. */
.par-series { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line); }
.par-series h3 {
  margin: 0 0 12px; font-family: var(--titre); font-size: .76rem; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--muted);
}
.par-series h3 .count { letter-spacing: 0; text-transform: none; margin-left: 6px; }
.ss-ligne {
  display: grid; grid-template-columns: 1fr 72px auto;
  align-items: center; gap: 10px; padding: 7px 0;
}
.ss-nom {
  font-size: .86rem; font-weight: 600; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ss-jauge {
  height: 7px; border-radius: 999px; background: var(--surface);
  overflow: hidden; display: block;
}
.ss-jauge i { display: block; height: 100%; background: var(--accent); border-radius: 999px; }
.ss-val {
  font-family: var(--titre); font-size: 1rem; font-weight: 700;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.ss-val small { color: var(--muted); font-weight: 500; font-size: .72rem; }
.ss-mot { margin: 10px 0 0; font-size: .86rem; color: var(--muted); line-height: 1.45; }
.ss-mot b { color: var(--text); }

/* Écart au minima, séance par séance dans l'historique. La couleur ne porte
   rien seule : le signe et le mot « minima » sont écrits, et l'intitulé complet
   est dans l'infobulle. Un tireur qui ne distingue pas le vert de l'ambre lit
   exactement la même information. */
.rep {
  display: inline-block; margin-left: 2px; padding: 1px 7px;
  border-radius: 999px; font-size: .7rem; font-weight: 700;
  white-space: nowrap; vertical-align: 1px;
}
.rep.au-dessus { background: color-mix(in srgb, var(--ok) 15%, var(--card)); color: var(--ok); }
.rep.en-dessous { background: color-mix(in srgb, #b45309 15%, var(--card)); color: #8a4308; }
@media (prefers-color-scheme: dark) { .rep.en-dessous { color: #f0b429; } }
/* Tant que les chiffres sont des exemples, la pastille reste en pointillés :
   on ne fait pas passer une valeur provisoire pour un fait acquis. */
.rep[data-exemple] { border: 1px dashed currentColor; }

.note-exemple {
  margin: -6px 0 12px; font-size: .78rem; color: var(--muted); font-style: italic;
}

/* ============================ repère national ============================
   Une règle graduée, pas un classement. On y lit trois jalons et sa propre
   marque : le rang, lui, n'existe pas dans les données disponibles et on ne
   l'invente pas. */
.repere { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line); }
.repere h3 {
  margin: 0 0 6px; font-family: var(--titre); font-size: .76rem; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--muted);
}
.repere h3 .count { letter-spacing: 0; text-transform: none; margin-left: 6px; }
.rp-avertit {
  margin: 0 0 14px; padding: 8px 10px; border-radius: 10px;
  background: color-mix(in srgb, #b45309 12%, var(--card));
  color: #7c3a06; font-size: .78rem; font-weight: 600; line-height: 1.4;
}
@media (prefers-color-scheme: dark) { .rp-avertit { color: #f0b429; } }

.rp-echelle { position: relative; height: 74px; margin: 26px 0 4px; }
.rp-barre {
  position: absolute; left: 0; right: 0; top: 30px; height: 8px;
  border-radius: 999px; background: var(--surface);
}
.rp-atteint {
  position: absolute; left: 0; top: 30px; height: 8px;
  border-radius: 999px; background: color-mix(in srgb, var(--accent) 34%, var(--card));
}
.rp-jalon { position: absolute; top: 30px; transform: translateX(-50%); text-align: center; }
.rp-jalon i {
  display: block; width: 2px; height: 8px; margin: 0 auto; background: var(--muted);
}
.rp-jalon b {
  display: block; margin-top: 4px; font-family: var(--titre);
  font-size: .78rem; font-weight: 700; font-variant-numeric: tabular-nums;
}
.rp-jalon em {
  display: block; font-style: normal; font-size: .66rem; color: var(--muted);
  letter-spacing: .04em;
}
.rp-max b, .rp-max em { color: var(--muted); }

/* Sa propre marque passe au-dessus et porte la couleur : c'est la seule
   chose qu'on cherche des yeux. */
.rp-moi { position: absolute; top: 2px; transform: translateX(-50%); text-align: center; }
.rp-moi i {
  display: block; width: 14px; height: 14px; margin: 0 auto 2px;
  border-radius: 50%; background: var(--accent);
  box-shadow: 0 0 0 3px var(--card);
}
.rp-moi b {
  display: block; font-family: var(--titre); font-size: .95rem; font-weight: 700;
  color: var(--accent); font-variant-numeric: tabular-nums;
}
.rp-source { display: block; margin-top: 4px; font-size: .74rem; }

/* ============================== logo FFTir ===============================
   Charte FFTir 2016, appliquée à la lettre :
   — zone de protection d'un huitième de la hauteur du logo, tout autour ;
   — jamais sur un fond de couleur : version couleur sur fond clair, réserve
     blanche officielle sur fond sombre (un simple échange de fichier, aucune
     retouche) ;
   — proportions jamais modifiées : la hauteur commande, la largeur suit ;
   — taille minimale respectée : 38 px de haut, en dessous le sigle se brouille.
   Aucun filtre CSS n'est appliqué : ce serait modifier les couleurs du logo. */
.fftir {
  --h-fftir: clamp(52px, 13vw, 68px);   /* au-dessous, le sigle se brouille */
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  margin-top: 22px; padding-top: 20px; border-top: 1px solid var(--line);
  text-align: center;
}
.fftir img {
  /* content-box est ESSENTIEL : avec box-sizing: border-box (la règle
     générale du site), la zone de protection serait comptée DANS la hauteur
     et écraserait l'image — 1,43 au lieu de 1,58 de rapport, c'est-à-dire
     un logo déformé, ce que la charte interdit nommément.
     Ici la hauteur commande l'image, et la marge s'ajoute autour. */
  box-sizing: content-box;
  height: var(--h-fftir); width: auto; display: block;
  padding: calc(var(--h-fftir) / 8);
}
.fftir span { color: var(--muted); font-size: .76rem; line-height: 1.45; max-width: 30rem; }

/* ================================ fiche ================================== */
.fiche { margin: 0; display: grid; gap: 1px; }
.fiche div {
  display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  padding: 11px 2px; border-top: 1px solid var(--line);
}
.fiche div:first-child { border-top: 0; }
.fiche dt { color: var(--muted); font-size: .9rem; }
.fiche dd { margin: 0; font-weight: 600; text-align: right; }
.toolbar-bas { margin: 16px 0 0; display: grid; gap: 8px; }
.toolbar-bas .mini {
  width: 100%; text-align: center; text-decoration: none;
  display: flex; align-items: center; justify-content: center; gap: 8px;
}
.toolbar-bas .mini svg { width: 17px; height: 17px; flex: 0 0 auto; }

/* Le laboratoire est un banc d'essai, pas une fonction du carnet : le lien
   n'apparaît que pour l'administrateur. Ce n'est pas une protection — la page
   ne contient aucune donnée et ne parle à aucun serveur — mais un membre n'a
   rien à faire dans un outil de mise au point. */
/* ------------------------ séances d'initiation -------------------------- */
/* La mention d'information se déplie : présente pour qui la cherche, sans
   occuper l'écran de celui qui saisit. */
.rgpd {
  margin: 14px 0 0; padding: 12px 14px;
  background: var(--surface); border-radius: var(--r-champ);
  font-size: .87rem; line-height: 1.5;
}
.rgpd summary { font-weight: 700; cursor: pointer; color: var(--accent); }
.rgpd p { margin: 10px 0 0; }
.rgpd .aide { margin-top: 10px; }

/* Le contrôle FINIADA n'est pas une case parmi d'autres : sans lui, la
   personne ne tire pas. Il se voit. */
.coche-finiada {
  display: flex; align-items: flex-start; gap: 11px;
  margin-top: 14px; padding: 13px;
  background: var(--accent-doux); border-left: 3px solid var(--accent);
  border-radius: var(--r-champ);
  font-weight: 400; color: var(--text); font-size: .88rem; line-height: 1.45;
}
.coche-finiada input { width: 22px; height: 22px; flex: 0 0 auto; accent-color: var(--accent); }
.tag.ok-finiada { background: var(--accent-doux); color: var(--accent); }
.init-personne .vue, .init-seance .vue { align-items: center; }
.init-personne .actions, .init-seance .actions { margin-left: auto; gap: 8px; }
.init-seance .actions .mini svg { width: 17px; height: 17px; display: block; }

/* ----------------------- catalogue de logiciels -------------------------
   Une carte par outil. Le jour où il y en aura dix, la liste doit rester
   lisible au pouce : une colonne sur téléphone, deux dès qu'il y a la place. */
.outils-liste { display: grid; gap: 10px; }
@media (min-width: 620px) { .outils-liste { grid-template-columns: 1fr 1fr; } }

.outil-carte {
  display: flex; align-items: flex-start; gap: 12px; text-align: left;
  width: 100%; padding: 14px; font: inherit; cursor: pointer;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--line); border-radius: var(--r-card);
}
.outil-carte .ico {
  flex: 0 0 auto; display: grid; place-items: center;
  width: 40px; height: 40px; border-radius: 11px;
  background: var(--accent-doux); color: var(--accent);
}
.outil-carte .ico svg { width: 21px; height: 21px; }
.outil-carte .txt { display: grid; gap: 3px; min-width: 0; }
.outil-carte .txt b { font-family: var(--titre); font-size: 1rem; }
.outil-carte .txt span { color: var(--muted); font-size: .85rem; line-height: 1.4; }
@media (hover: hover) and (pointer: fine) {
  .outil-carte:hover { border-color: var(--accent); }
}

/* Une application pas encore écrite se montre, mais ne s'ouvre pas : cacher
   ce qui vient donnerait l'impression que rien ne vient. */
.outil-carte.a-venir { opacity: .62; cursor: default; }
.outil-carte .etat {
  font-size: .76rem; font-weight: 700; color: var(--accent);
  letter-spacing: .04em; text-transform: uppercase;
}
.outil-carte.a-venir .etat { color: var(--muted); }

/* La grille des droits : cinq applications, trois niveaux. Des menus
   déroulants plutôt que des rangées de boutons — c'est ce qui tient sur un
   téléphone, et ce que le doigt sait viser. */
.grille-droits {
  display: grid; gap: 12px; margin-top: 12px; padding: 13px;
  background: var(--surface); border-radius: var(--r-champ);
}
.grille-droits label { font-size: .88rem; }
.grille-droits label i { font-style: normal; color: var(--muted); font-weight: 400; }
.aide-droits { margin: 0; color: var(--muted); font-size: .8rem; line-height: 1.45; }
@media (min-width: 620px) { .grille-droits { grid-template-columns: 1fr 1fr; }
  .aide-droits { grid-column: 1 / -1; } }

/* --------------------- planning des permanences ------------------------- */
.mois-nav {
  display: flex; align-items: center; justify-content: center; gap: 14px;
  margin: 14px 0 6px;
}
.mois-nav b {
  font-family: var(--titre); font-size: 1.05rem; min-width: 11rem; text-align: center;
  text-transform: capitalize;
}
.mois-nav .mini { min-width: 46px; font-size: 1.2rem; line-height: 1; }

/* --------------------------- le calendrier ------------------------------ */
/* Les trois vues : un sélecteur segmenté, comme on en a l'habitude. */
.vues {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px;
  margin: 14px 0 0; padding: 4px;
  background: var(--surface); border-radius: var(--r-pill);
}
.vues button {
  font: inherit; font-size: .88rem; font-weight: 600;
  min-height: 40px; border: 0; border-radius: var(--r-pill);
  background: none; color: var(--muted); cursor: pointer;
}
.vues button[aria-pressed="true"] {
  background: var(--card); color: var(--accent);
  box-shadow: 0 1px 3px rgba(0,0,0,.12);
}

/* --- un créneau : QUI d'abord, en gras, et rien de coupé --------------- */
.creneau .ep { display: grid; gap: 3px; }
.creneau .ep b.qui {
  white-space: normal; overflow: visible;           /* le nom ne tombe plus dans « … » */
  font-family: var(--titre); font-size: 1.02rem;
}
.creneau .heures { color: var(--muted); font-size: .86rem; font-variant-numeric: tabular-nums; }
.creneau .note-perm { color: var(--muted); font-size: .82rem; }
.stand.tous { background: var(--accent); color: var(--accent-text); }

.jour-perm.sans h3 { opacity: .7; }
.jour-perm.sans .vide { margin: 0 0 4px; font-size: .84rem; }
.jour-perm.auj h3 { color: var(--accent); }

/* --- mois : la grille ---------------------------------------------------- */
.grille-mois {
  display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px;
  margin-top: 12px;
}
.grille-mois .entete {
  text-align: center; font-size: .72rem; font-weight: 700; color: var(--muted);
  padding: 4px 0;
}
.grille-mois .case {
  position: relative; display: grid; align-content: start; justify-items: center; gap: 1px;
  min-height: 58px; padding: 5px 2px; font: inherit; cursor: pointer;
  background: var(--surface); color: var(--text);
  border: 1px solid transparent; border-radius: 10px;
}
.grille-mois .case.hors { background: none; color: var(--muted); opacity: .35; cursor: default; }
.grille-mois .case .num { font-size: .84rem; font-weight: 600; font-variant-numeric: tabular-nums; }
/* Le nom du premier permanent, en tout petit : sur un téléphone il ne tient
   pas toujours, c'est le repère coloré qui dit l'essentiel — un jour pris. */
.grille-mois .case .qui-court {
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: .62rem; font-weight: 600; color: var(--accent);
}
.grille-mois .case .plus { font-size: .6rem; color: var(--muted); }
/* Matin (M) et après-midi (A) : deux pastilles côte à côte au bas de la case.
   Pleine = pris, vide = libre. La lettre porte l'information autant que la
   couleur. « tous » = tous les stands ouverts sur cette moitié de journée. */
.grille-mois .case { padding-bottom: 22px; }
.grille-mois .case .demis {
  position: absolute; left: 5%; right: 5%; bottom: 4px; display: flex; gap: 2px;
}
.grille-mois .case .demi {
  flex: 1; height: 15px; display: grid; place-items: center;
  font-size: .6rem; font-weight: 700; line-height: 1;
  border: 1px solid var(--line); border-radius: 4px; color: var(--muted);
}
.grille-mois .case .demi.on {
  background: var(--accent); border-color: var(--accent); color: var(--accent-text); opacity: .62;
}
.grille-mois .case .demi.on.tous { opacity: 1; }
.legende-demi { margin: 8px 0 0; font-size: .76rem; color: var(--muted); }
.creneau .moment {
  display: inline-block; margin-right: 6px; padding: 1px 7px; border-radius: 999px;
  font-size: .74rem; font-weight: 700;
  background: var(--accent-doux); color: var(--accent);
}
.creneau .moment.a { background: var(--surface); color: var(--text); box-shadow: inset 0 0 0 1px var(--line); }
.creneau .moment.j { background: var(--accent); color: var(--accent-text); }
.grille-mois .case.pris { background: var(--accent-doux); }
.grille-mois .case.auj .num { color: var(--accent); }
.grille-mois .case.auj { border-color: var(--accent); }
.grille-mois .case.choisi { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
@media (min-width: 620px) {
  .grille-mois .case { min-height: 74px; }
  .grille-mois .case .qui-court { font-size: .72rem; }
}
/* La semaine n'a qu'une rangée : on lui laisse plus de hauteur. */
.grille-mois.semaine .case { min-height: 84px; }
.grille-mois.semaine .case .num { font-size: 1rem; }
@media (min-width: 620px) { .grille-mois.semaine .case { min-height: 104px; } }

/* --- saison : douze petits mois ------------------------------------------ */
.grille-saison {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin-top: 12px;
}
@media (min-width: 620px) { .grille-saison { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1100px) { .grille-saison { grid-template-columns: repeat(4, 1fr); } }
.mini-mois {
  display: grid; gap: 6px; padding: 10px; text-align: left; font: inherit; cursor: pointer;
  background: var(--surface); color: var(--text);
  border: 1px solid transparent; border-radius: var(--r-champ);
}
@media (hover: hover) and (pointer: fine) { .mini-mois:hover { border-color: var(--accent); } }
.mini-mois .titre { font-weight: 700; font-size: .82rem; text-transform: capitalize; }
.mini-mois .mini-grille { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.mini-case { aspect-ratio: 1; border-radius: 2px; background: var(--line); }
.mini-case.hors { background: none; }
/* Une case coupée en deux : le haut est le matin, le bas l'après-midi. */
.mini-case.pris {
  --haut: var(--line); --bas: var(--line);
  background: linear-gradient(to bottom, var(--haut) 50%, var(--bas) 50%);
}
.mini-case.pris.m { --haut: var(--accent); }
.mini-case.pris.a { --bas: var(--accent); }
.mini-case.auj { outline: 1.5px solid var(--fftir-rouge, #ed2939); outline-offset: -1px; }
.mini-mois .total { font-size: .72rem; color: var(--muted); }

.jour-perm { margin-top: 14px; }
.jour-perm h3 {
  margin: 0 0 7px; font-family: var(--titre); font-size: .95rem; font-weight: 600;
  color: var(--muted); text-transform: capitalize;
}
.creneau .vue { align-items: center; }
.creneau .actions { margin-left: auto; }
.creneau .actions .mini { min-height: 38px; padding: 6px 12px; }
.creneau .actions .mini svg { width: 17px; height: 17px; display: block; }

/* Les pas de tir ouverts : des cases au formulaire, des pastilles à la
   lecture. C'est l'information que le tireur vient chercher — elle doit se
   voir sans lire la ligne en entier. */
.stands { border: 0; padding: 0; margin: 0 0 4px; }
.stands legend {
  padding: 0; margin-bottom: 8px;
  font-weight: 600; font-size: .92rem; color: var(--muted);
}
#standsCases { display: grid; gap: 9px; }
@media (min-width: 430px) { #standsCases { grid-template-columns: 1fr 1fr; } }
#standsCases .coche { margin-right: 0; color: var(--text); font-weight: 500; }
/* La case « Tous » coiffe les autres : sur toute la largeur, et séparée. */
#standsCases .coche.tous {
  grid-column: 1 / -1; padding-bottom: 8px; border-bottom: 1px solid var(--line);
}

.pastilles { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 3px; }
.stand {
  padding: 2px 9px; border-radius: var(--r-pill);
  background: var(--accent-doux); color: var(--accent);
  font-size: .75rem; font-weight: 700;
}
.stand.vide-stand {
  background: transparent; color: var(--muted); font-weight: 400;
  font-style: italic; padding-left: 0;
}

/* Le compte de l'année : le nom à gauche, le nombre à droite, sans fioriture. */
.tot {
  margin-left: auto; font-family: var(--titre); font-weight: 700; font-size: 1.1rem;
  font-variant-numeric: tabular-nums;
}

/* Date, début, fin : trois champs qui tiennent sur une ligne dès qu'il y a
   la place, et l'un sous l'autre sur un téléphone étroit. */
.trio { display: grid; gap: 12px; }
@media (min-width: 430px) { .trio { grid-template-columns: 1.4fr 1fr 1fr; } }

/* ---------------------------- gestion du club --------------------------- */
.avis {
  margin: 12px 0 0; padding: 11px 13px;
  background: var(--surface); border-left: 3px solid var(--accent);
  border-radius: var(--r-champ); font-size: .92rem;
}
/* La case « accès club » sur une demande, et l'état sur un compte actif. */
.coche {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: .88rem; font-weight: 600; color: var(--muted);
  margin-right: auto;
}
.coche input { width: 18px; height: 18px; accent-color: var(--accent); }
.acces { font-size: .82rem; color: var(--muted); font-style: italic; }
.compte-actif .actions .mini {
  display: inline-flex; align-items: center; gap: 7px; min-height: 38px;
}
.compte-actif .actions .mini svg { width: 16px; height: 16px; }

#lienLabo { display: none; }
body.admin .toolbar-bas #lienLabo { display: flex; }

/* ================================ séries =================================
   Une carte par série comptée : son intitulé et son déroulé à gauche, le
   résultat à droite. C'est la fiche de match, dans l'ordre où l'on tire. */
.series { display: grid; gap: 10px; }
.serie {
  display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 12px;
  padding: 14px; border: 1px solid var(--line); border-radius: var(--r-card);
}
.serie label { gap: 3px; min-width: 0; color: var(--text); }
.serie label b { font-family: var(--titre); font-size: .95rem; font-weight: 600; }
.serie label span { color: var(--muted); font-size: .8rem; font-weight: 400; }
.serie .score-row { width: 132px; }

/* Décomptes facultatifs, sous la série. Le règlement départage les égalités
   au nombre de 10 puis aux mouches — mais on doit pouvoir enregistrer une
   séance sans les avoir comptés. Ils passent donc sous la ligne du score, en
   petit : présents pour qui les relève, jamais en travers du geste principal. */
.decomptes {
  grid-column: 1 / -1;
  display: flex; flex-wrap: wrap; gap: 8px 16px;
  margin-top: 4px; padding-top: 10px; border-top: 1px solid var(--line);
}
.dec {
  display: flex; align-items: center; gap: 8px;
  font-size: .78rem; font-weight: 600; color: var(--muted);
}
.dec input {
  width: 68px; min-height: 40px; padding: 6px 8px;
  text-align: center; font-family: var(--titre); font-size: 1rem; font-weight: 700;
}
.serie input { font-size: 1.25rem; }

/* Une série et sa photo ne font qu'un seul bloc : la photo appartient à la
   série, elle ne flotte pas en dessous. */
.serie:has(+ .photo-ligne) { border-radius: var(--r-card) var(--r-card) 0 0; border-bottom: 0; }
.photo-ligne {
  display: flex; align-items: center; gap: 10px;
  margin-top: -10px; padding: 4px 14px 12px;
  border: 1px solid var(--line); border-top: 0;
  border-radius: 0 0 var(--r-card) var(--r-card);
}

/* Tant qu'aucune épreuve n'est choisie, le total n'a rien à dire : un cadre
   gris vide ferait croire à un champ qu'on a oublié de remplir. */
.total:empty { display: none; }
.total {
  margin: 2px 0 0; padding: 14px 16px; border-radius: 14px;
  background: var(--surface); text-align: center; font-size: .95rem; color: var(--muted);
}
.total b {
  font-family: var(--titre); font-size: 1.55rem; font-weight: 700;
  font-variant-numeric: tabular-nums; letter-spacing: -.02em; color: var(--text);
}
.total small { color: var(--muted); }
.muted-in { color: var(--muted); font-size: .88rem; font-weight: 400; }

/* ================================ photos =================================
   Le bouton reste discret : il ne doit pas concurrencer la saisie du score,
   qui est l'essentiel. Une fois la photo prise, la vignette le remplace. */
.photo-btn {
  display: inline-flex; align-items: center; gap: 7px;
  font: inherit; font-size: .84rem; font-weight: 600;
  min-height: 38px; padding: 6px 14px;
  color: var(--muted); background: none;
  border: 1px dashed var(--line); border-radius: var(--r-pill); cursor: pointer;
}
.photo-btn svg { width: 16px; height: 16px; flex: 0 0 auto; }
.photo-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.photo-apercu { display: inline-flex; align-items: center; gap: 8px; }
.photo-apercu img {
  width: 54px; height: 54px; object-fit: cover;
  border-radius: 10px; border: 1px solid var(--line);
}
.photo-retirer {
  display: grid; place-items: center;
  font: inherit; min-width: 38px; min-height: 38px;
  color: var(--muted); background: none; border: 0; border-radius: 10px; cursor: pointer;
}
.photo-retirer svg { width: 15px; height: 15px; }
.photo-msg { color: var(--muted); font-size: .8rem; }

/* Bande de cibles dépliée depuis l'historique */
.cibles { display: flex; gap: 10px; overflow-x: auto; padding: 10px 2px 2px; }
.cibles figure { margin: 0; flex: 0 0 auto; text-align: center; }
.cibles img {
  display: block; width: 168px; height: 168px; object-fit: cover;
  border-radius: 14px; border: 1px solid var(--line); background: var(--surface);
}
.cibles figcaption { margin-top: 5px; color: var(--muted); font-size: .76rem; }

/* Matériel employé, sous l'intitulé de la séance : une information de fond,
   utile quand on cherche pourquoi un lot tire mieux qu'un autre. */
.materiel {
  display: block; color: var(--muted); font-size: .78rem; font-weight: 400;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ========================== mode modification ============================
   Un liseré ambré rappelle qu'on retouche une séance existante, et non qu'on
   en crée une : l'écran est le même, l'effet ne l'est pas. */
body.edition #pageSaisie > .card {
  border-color: #b45309;
  box-shadow: inset 0 3px 0 #b45309;
}
#btnAnnulerEdition { width: 100%; }

/* =============================== segmenteur ==============================
   Deux ou trois choix qui s'excluent : des pastilles côte à côte se lisent
   d'un coup d'œil et se touchent du pouce, là où une liste déroulante demande
   d'ouvrir, lire, choisir, refermer.

   Le choix actif est en encre pleine, pas en bleu : le bleu reste réservé à
   l'action principale de l'écran, sinon deux choses réclament l'œil à la fois. */
.seg { display: flex; gap: 8px; }
.seg.mb { margin-bottom: 14px; }
.seg button {
  flex: 1; min-height: 44px; padding: 8px 6px;
  font: inherit; font-size: .88rem; font-weight: 500;
  color: var(--text); background: var(--card);
  border: 1px solid var(--line); border-radius: var(--r-pill); cursor: pointer;
}
.seg button.actif {
  color: var(--bg); background: var(--text); border-color: var(--text); font-weight: 600;
}
.seg button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Une séance de compétition se repère dans la liste sans avoir à lire. */
.tag.compet { background: #b45309; color: #fff; margin-left: 0; margin-right: 2px; }

/* ========================= couleurs des disciplines =======================
   Huit teintes catégorielles, dans un ordre fixe, validées : bande de clarté,
   plancher de chroma, séparation pour les daltonismes (ΔE 9,1 en clair / 8,4
   en sombre) et lisibilité sur le fond. Les valeurs sombres ne sont pas un
   simple éclaircissement : ce sont les mêmes teintes, repensées pour le fond
   sombre. Au-delà de huit disciplines, la neuvième passe en gris « Autres »
   plutôt que d'inventer une couleur de plus — un arc-en-ciel ne se lit pas.

   En clair, l'aqua, le jaune et le magenta passent sous 3:1 sur blanc : la
   règle de secours s'applique, chaque courbe porte donc son intitulé écrit. */
:root {
  --serie-1: #2a78d6;  --serie-2: #eb6834;  --serie-3: #1baf7a;  --serie-4: #eda100;
  --serie-5: #e87ba4;  --serie-6: #008300;  --serie-7: #4a3aa7;  --serie-8: #e34948;
  --serie-autres: #6b7280;
}
@media (prefers-color-scheme: dark) {
  :root {
    --serie-1: #3987e5;  --serie-2: #d95926;  --serie-3: #199e70;  --serie-4: #c98500;
    --serie-5: #d55181;  --serie-6: #008300;  --serie-7: #9085e9;  --serie-8: #e66767;
    --serie-autres: #9aa39c;
  }
}

/* Les étiquettes et la légende portent l'encre du texte, jamais la couleur de
   la série : c'est la pastille qui porte l'identité, pas les mots. */
.g-nom { fill: var(--text); font-size: 12px; font-weight: 700; font-family: var(--titre); }
.legende { display: flex; flex-wrap: wrap; gap: 8px 14px; margin-top: 14px; }
.legende span { display: inline-flex; align-items: center; gap: 7px; font-size: .8rem; color: var(--muted); }
.legende i { width: 14px; height: 3px; border-radius: 2px; flex: 0 0 auto; }

/* ============================== le survol ================================
   Un écran tactile n'a pas de survol : le style se déclenche à l'appui et
   reste collé au bouton jusqu'au prochain appui ailleurs, si bien qu'on
   croit un bouton resté enfoncé. On ne le donne donc qu'aux appareils qui
   ont réellement un pointeur. */
@media (hover: hover) and (pointer: fine) {
  .home:hover { color: var(--accent); }
  .btn:hover { filter: brightness(1.08); }
  .sup:hover { color: var(--accent); background: var(--accent-doux); }
  .sup[data-act="demander"]:hover { color: var(--err); background: color-mix(in srgb, var(--err) 10%, var(--card)); }
  .mini:hover { border-color: var(--accent); color: var(--accent); }
  .mini.danger:hover { border-color: transparent; color: #fff; filter: brightness(1.1); }
  .mini.vert:hover { border-color: transparent; color: var(--accent-text); filter: brightness(1.08); }
  .photo-btn:hover { color: var(--accent); border-color: var(--accent); border-style: solid; background: var(--accent-doux); }
  .photo-retirer:hover { color: var(--err); background: color-mix(in srgb, var(--err) 10%, var(--card)); }
  .seg button:hover { border-color: var(--accent); color: var(--accent); }
  .seg button.actif:hover { color: var(--bg); }
}

/* =============================== tablette ================================
   À partir d'ici l'écran n'est plus tenu d'une main : on rend de la largeur
   au contenu et de l'air aux cartes, sans toucher à l'organisation — la
   barre du bas reste le bon geste au pouce sur une tablette. */
@media (min-width: 640px) {
  .top, .wrap { max-width: 720px; }
  .top { padding-left: 24px; padding-right: 24px; }
  .wrap { padding-left: 24px; padding-right: 24px; gap: 16px; }
  #app, .page { gap: 16px; }
  .card { padding: 22px; }
  h1 { font-size: 1.6rem; }
  h2 { font-size: 1.15rem; }
  .row2 { gap: 16px; }   /* les deux colonnes sont deja revenues a 480 px */
  .menu button { font-size: .76rem; }
  .cibles img { width: 208px; height: 208px; }
  /* Les vignettes de cible méritent la place : c'est sur elles qu'on cherche
     ses impacts, et une bande qui défile de côté se lit mal. */
  .cibles { flex-wrap: wrap; overflow-x: visible; }
}

/* ============================== ordinateur ===============================
   La barre fixe en bas est une idée de téléphone : au clavier et à la souris
   elle mange de la hauteur et se trouve à l'opposé du regard. On range donc
   la navigation sur le côté, où elle reste visible en entier, et l'on rend
   toute la hauteur de l'écran au contenu. */
@media (min-width: 1024px) {
  .menu {
    top: 0; bottom: 0; right: auto; width: 232px;
    flex-direction: column; justify-content: flex-start; gap: 4px;
    padding: 22px 14px;
    background: var(--card);
    border-top: 0; border-right: 1px solid var(--line);
    backdrop-filter: none;
  }
  .menu button {
    flex: 0 0 auto; width: 100%; max-width: none;
    grid-template-columns: auto 1fr; justify-items: start; align-items: center;
    gap: 12px; min-height: 50px; padding: 12px 14px;
    font-size: .95rem; border-radius: 12px;
  }
  .menu button.actif { background: var(--accent-doux); }
  .menu a {
    flex: 0 0 auto; width: 100%; max-width: none;
    grid-template-columns: auto 1fr; justify-items: start; align-items: center;
    gap: 12px; min-height: 50px; padding: 12px 14px;
    font-size: .95rem; border-radius: 12px; text-align: left;
  }
  .menu a.actif { background: var(--accent-doux); }
  body.avec-menu { padding-bottom: 0; }

  /* Le décalage n'a lieu que lorsque la navigation est là : sur l'écran de
     connexion, elle est masquée et la page reste centrée d'un bord à l'autre. */
  body.connecte { padding-left: 232px; }

  .top, .wrap { max-width: 820px; }
  .wrap { padding-bottom: 40px; }
  h1 { font-size: 1.7rem; }

  /* Un formulaire ne se lit pas sur toute la largeur d'un écran : l'œil perd
     la ligne entre l'intitulé à gauche et le champ à droite. */
  #pageSaisie {
    width: 100%; max-width: 760px; margin-left: auto; margin-right: auto;
  }
}

/* ============================ grand écran ================================
   Deux colonnes seulement quand chacune a de quoi respirer. Les ouvrir dès
   1024 px donnait deux colonnes de 365 px : la largeur d'un téléphone, posée
   deux fois — les intitulés d'épreuve s'y coupaient de nouveau et la courbe
   n'avait plus de place. Il faut la barre latérale ET deux vraies colonnes,
   soit environ 1280 px. */
@media (min-width: 1280px) {
  .top, .wrap { max-width: 1000px; }

  /* La courbe et l'historique se lisent alors de front, sans faire défiler. */
  #pageAccueil, #pageCompte {
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
    align-items: start;
  }
  #pageDemandes, #pageJournal {
    width: 100%; max-width: 760px; margin-left: auto; margin-right: auto;
  }
}

/* ========================== minuteur de série ============================
   Plein écran, par-dessus la navigation : au stand, le téléphone est posé à
   un mètre et ne doit montrer qu'une chose. */
/* Statistiques de visite : des chiffres en grand, des barres simples. */
.stats-visite h2 { margin: 22px 0 8px; }
.stats-visite h3 { margin: 16px 0 6px; font-size: .95rem; color: var(--muted); }
.chiffres { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }
@media (min-width: 620px) { .chiffres { grid-template-columns: repeat(4, 1fr); } }
.chiffre { display: grid; gap: 2px; padding: 12px; border-radius: var(--r-champ); background: var(--surface); }
.chiffre .t { font-size: .8rem; font-weight: 600; color: var(--muted); }
.chiffre .v { font-family: var(--titre); font-size: 1.6rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.chiffre .aide { font-size: .76rem; color: var(--muted); }
.tend { font-size: .76rem; font-weight: 700; color: var(--muted); }
.tend.hausse { color: var(--ok); }
.tend.baisse { color: #b45309; }
.barres { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.barres li { display: grid; grid-template-columns: minmax(0, 1.4fr) 1fr auto; gap: 10px; align-items: center; font-size: .88rem; }
.barres .lib { overflow-wrap: anywhere; }
.barres .barre { height: 10px; border-radius: 999px; background: var(--surface); overflow: hidden; }
.barres .barre i { display: block; height: 100%; background: var(--accent); border-radius: 999px; }
.barres .val { font-variant-numeric: tabular-nums; font-weight: 700; }

/* Le minuteur : un vrai bouton, pleine largeur, juste sous le choix de l'épreuve. Contour plutôt
   qu'aplat : le bouton plein reste celui qui enregistre la séance. */
.btn-minuteur {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; min-height: 54px; padding: 10px 18px;
  font: inherit; font-family: var(--titre); font-weight: 600; font-size: 1rem;
  color: var(--accent); background: var(--accent-doux);
  border: 2px solid var(--accent); border-radius: var(--r-pill); cursor: pointer;
}
.btn-minuteur svg { width: 22px; height: 22px; display: block; }
.btn-minuteur:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

body.minuteur-ouvert { overflow: hidden; }
.minuteur {
  position: fixed; inset: 0; z-index: 50; overflow-y: auto; overscroll-behavior: contain;
  background: var(--bg); color: var(--text);
  padding: max(16px, env(safe-area-inset-top)) 16px max(16px, env(safe-area-inset-bottom));
}

/* --- préparation --------------------------------------------------------- */
.mn-prepa { display: grid; gap: 14px; max-width: 560px; margin: 0 auto; }
.mn-tete { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.mn-tete h1 { margin: 0; }
.mn-prepa .muted { margin: 0; }
.mn-prepa .hint { margin: 0; }
.mn-perso { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.mn-phases { border: 0; padding: 0; margin: 0; }
.mn-phases legend { padding: 0; margin-bottom: 8px; font-weight: 600; font-size: .92rem; color: var(--muted); }
#mnPhases { display: grid; gap: 6px; }
.mn-coche {
  margin: 0; padding: 10px 12px; align-items: flex-start;
  background: var(--surface); border-radius: var(--r-champ); color: var(--text);
}
.mn-coche input { width: 20px; height: 20px; margin-top: 1px; flex: 0 0 auto; }
.mn-coche span { display: grid; gap: 2px; }
.mn-coche b { font-weight: 600; font-size: .95rem; }
.mn-coche small { color: var(--muted); font-weight: 400; font-size: .84rem; }
.mn-total { font-variant-numeric: tabular-nums; }
.mn-reglage { display: grid; gap: 7px; }
.mn-reglage .lib { font-weight: 600; font-size: .92rem; color: var(--muted); }
.mn-reglage .seg { flex-wrap: wrap; }
.mn-reglage .seg button { flex: 1 1 22%; }
.mn-actions { display: grid; grid-template-columns: auto 1fr; gap: 10px; align-items: center; }

/* --- pendant les séries -------------------------------------------------
   Une couleur par commandement, sur tout l'écran : orange pour se préparer,
   vert pour tirer, rouge pour cesser. Le mot reste écrit en toutes lettres —
   la couleur seule ne dit rien à qui confond le rouge et le vert. Ces teintes
   portent du texte blanc à plus de 4,5:1, de jour comme de nuit. */
.minuteur.en-cours { --mn-fond: #8a4b0b; background: var(--mn-fond); color: #fff; }
.minuteur.en-cours[data-etat="tirez"] { --mn-fond: #0f6b37; }
.minuteur.en-cours[data-etat="stop"] { --mn-fond: #b01c1c; }
.minuteur.en-cours.en-pause { --mn-fond: #3b414d; }

.mn-run {
  min-height: 100%; max-width: 720px; margin: 0 auto;
  display: grid; grid-template-rows: auto auto 1fr auto auto; gap: 12px;
  text-align: center;
}
.mn-ep { margin: 0; font-size: .86rem; font-weight: 600; opacity: .85; font-variant-numeric: tabular-nums; }
.mn-phase { margin: 0; display: grid; gap: 3px; }
.mn-phase b { font-family: var(--titre); font-size: 1.25rem; font-weight: 700; }
.mn-phase span { font-size: .95rem; opacity: .9; }
.mn-centre { display: grid; align-content: center; justify-items: center; gap: 10px; }
.mn-ordre {
  margin: 0; font-family: var(--titre); font-weight: 800; text-transform: uppercase;
  font-size: clamp(2.2rem, 12vw, 5.5rem); line-height: 1.05; letter-spacing: .01em;
}
.mn-temps {
  margin: 0; min-height: 1em; font-family: var(--titre); font-weight: 700; line-height: 1;
  font-size: clamp(4.5rem, 28vw, 11rem); font-variant-numeric: tabular-nums; letter-spacing: -.03em;
}
.mn-barre {
  width: min(100%, 520px); height: 8px; border-radius: 4px; overflow: hidden;
  background: rgba(255, 255, 255, .25);
}
.mn-barre span { display: block; height: 100%; width: 0; background: #fff; }
.mn-etat { margin: 0; min-height: 1.3em; font-weight: 600; }
.mn-suite { margin: 0; font-size: .9rem; opacity: .85; }

/* Gros boutons : on les touche avec un gant, ou l'arme dans l'autre main. */
.mn-commandes { display: grid; grid-template-columns: 1fr 1.3fr 1fr; gap: 10px; }
.mn-commandes button {
  min-height: 64px; padding: 8px; border-radius: 16px; cursor: pointer;
  font: inherit; font-family: var(--titre); font-weight: 700; font-size: 1.05rem;
  color: #fff; background: rgba(0, 0, 0, .22); border: 2px solid rgba(255, 255, 255, .55);
}
.mn-commandes button:focus-visible { outline: 3px solid #fff; outline-offset: 2px; }
.mn-commandes #mnAvance { background: #fff; color: #16181d; border-color: #fff; }
.mn-commandes #mnAvance[hidden] { display: block !important; visibility: hidden; }
.mn-commandes button.confirmer { background: #fff; color: #b01c1c; border-color: #fff; }
.mn-fin { display: grid; gap: 10px; }
