/* =============================================================================
   Non au permis de tuer — feuille de style
   =============================================================================

   Palette héritée du site SAVE — noir, rouge, encre chaude — mais la
   typographie a sa propre règle, tirée d'un constat d'usage : la voix
   d'affiche (Tusker, capitales condensées) et les étiquettes mono en
   capitales rendaient bien les grands titres, et illisible tout le reste.

   La règle, donc : CE QU'ON PROCLAME EST EN AFFICHE, CE QU'ON LIT EST EN
   TEXTE. Tusker pour les titres géants et le décompte ; Plex Sans, en casse
   normale et à taille de lecture, pour tout ce qui se lit et se manipule —
   boutons, menus, libellés, métadonnées ; Plex Mono, réservé aux données qui
   gagnent à l'alignement : dates, statuts, surtitres.

   Le dispositif propre à cette application est le DÉCOMPTE. Tout ici est
   orienté vers une date ; chaque séance, chaque marche porte donc son « J-5 »
   dans la même fonte d'affichage que les grands titres. C'est une information
   vraie, pas un ornement : à trois semaines de l'échéance, « J-2 » se lit plus
   vite que « 18 septembre ».

   Chargé par <link> depuis /app.css plutôt qu'importé en CSS global : l'admin
   Payload a sa propre feuille, et rien de ce fichier ne doit fuir dedans.
   ========================================================================== */

/* --- Fontes ---------------------------------------------------------------
   Fichiers locaux, servis par l'application. Aucune requête vers un tiers :
   une fonte Google trahirait l'IP de chaque visiteur (SPEC §10.4). */
@font-face {
  font-family: 'TuskerGrotesk';
  src: url('/fonts/TuskerGrotesk-3500Medium.ttf') format('truetype');
  font-weight: 500; font-display: swap;
}
@font-face {
  font-family: 'TuskerGrotesk';
  src: url('/fonts/TuskerGrotesk-3700Bold.ttf') format('truetype');
  font-weight: 700; font-display: swap;
}
@font-face {
  font-family: 'TuskerGroteskWide';
  src: url('/fonts/TuskerGrotesk-5500Medium.ttf') format('truetype');
  font-weight: 500; font-display: swap;
}
@font-face {
  font-family: 'TuskerGroteskWide';
  src: url('/fonts/tusker-grotesk-5700-bold.ttf') format('truetype');
  font-weight: 700; font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Sans';
  src: url('/fonts/IBMPlexSans-400.woff2') format('woff2');
  font-weight: 400; font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Sans';
  src: url('/fonts/IBMPlexSans-500.woff2') format('woff2');
  font-weight: 500; font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Sans';
  src: url('/fonts/IBMPlexSans-600.woff2') format('woff2');
  font-weight: 600; font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Sans';
  src: url('/fonts/IBMPlexSans-700.woff2') format('woff2');
  font-weight: 700; font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('/fonts/IBMPlexMono-400.woff2') format('woff2');
  font-weight: 400; font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('/fonts/IBMPlexMono-600.woff2') format('woff2');
  font-weight: 600; font-display: swap;
}

:root {
  --bg: #0a0a0a;
  --bg-2: #141414;
  --bg-3: #1c1c1c;
  --ink: #f4f1ec;
  --ink-dim: #aca69f;
  /* Assez clair pour rester lisible en petit corps (§ contraste) : l'ancien
     #6b6764 passait sous 3.5:1 sur les métadonnées de 11 px. */
  --ink-faint: #8a837c;
  --rule: #262626;
  --rule-strong: #3a3a3a;
  --red: #e02424;
  --red-deep: #a81818;
  --red-wash: rgba(224, 36, 36, .08);

  --font-display: 'TuskerGroteskWide', 'Haettenschweiler', 'Impact', 'Arial Black', sans-serif;
  --font-narrow: 'TuskerGrotesk', 'Impact', 'Arial Narrow', sans-serif;
  --font-body: 'IBM Plex Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, 'Cascadia Mono', Consolas, monospace;

  --step: 6px;
  --gutter: 20px;
  --radius: 2px;
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html { -webkit-text-size-adjust: 100%; }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; }
img { max-width: 100%; height: auto; display: block; }
::selection { background: var(--red); color: #fff; }

/* Le focus doit rester visible : on organise ces pages au clavier, vite. */
:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
  }
}

/* --- Primitives de texte -------------------------------------------------- */

/* Le surtitre est le SEUL endroit où le mono en capitales subsiste comme
   ornement : une ligne courte, jamais un paragraphe, jamais un contrôle. */
.eyebrow {
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.eyebrow--red { color: var(--red); }

.display {
  font-family: var(--font-display);
  text-transform: uppercase;
  line-height: .88;
  letter-spacing: -.01em;
}

h1.title {
  font-family: var(--font-display);
  text-transform: uppercase;
  font-size: clamp(34px, 9vw, 68px);
  line-height: .88;
  letter-spacing: -.015em;
}
h1.title em { font-style: italic; color: var(--red); }

h2.section-title {
  font-family: var(--font-narrow);
  text-transform: uppercase;
  font-size: clamp(22px, 5vw, 32px);
  line-height: 1;
  letter-spacing: .01em;
}

.lede { color: var(--ink-dim); font-size: 17px; line-height: 1.65; max-width: 58ch; }
.muted { color: var(--ink-dim); }
.faint { color: var(--ink-faint); }
.mono { font-family: var(--font-mono); }
.nowrap { white-space: nowrap; }

/* Une phrase d'accompagnement — précision, contexte, renvoi. C'est de la
   prose : elle se compose en texte, jamais en mono. */
.note { font-size: 13.5px; line-height: 1.55; color: var(--ink-dim); max-width: 62ch; }
.note--faint { color: var(--ink-faint); }

/* --- Mise en page --------------------------------------------------------- */

.wrap { max-width: 1080px; margin: 0 auto; padding: 0 var(--gutter); }
.wrap--narrow { max-width: 620px; }

.stack > * + * { margin-top: calc(var(--step) * 3); }
.stack-lg > * + * { margin-top: calc(var(--step) * 7); }

.row-between {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
}

.section-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
  padding-bottom: 10px; margin-bottom: 18px;
  border-bottom: 1px solid var(--rule);
}

/* =============================================================================
   LE DÉCOMPTE — dispositif signature
   ========================================================================== */

/**
 * Un jalon relatif à la date de la marche. « J-5 », « JOUR J », « J+2 ».
 * Toujours dans la fonte d'affichage, toujours tabulaire, pour qu'une colonne
 * de jalons s'aligne au pixel et se parcoure d'un coup d'oeil.
 */
.jour {
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  letter-spacing: -.02em;
  line-height: .8;
  color: var(--ink);
  display: inline-block;
}
.jour--xl { font-size: clamp(56px, 18vw, 132px); color: var(--red); }
.jour--lg { font-size: clamp(28px, 7vw, 40px); }
.jour--sm { font-size: 22px; }
/* Le jour même, et lui seul, passe au rouge : c'est le seul jour qui compte. */
.jour[data-today="true"] { color: var(--red); }
/* Le passé s'efface sans disparaître. */
.jour[data-past="true"] { color: var(--ink-faint); }

.jour-label {
  font-family: var(--font-mono);
  font-size: 10px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink-faint); display: block; margin-top: 8px;
}

/* =============================================================================
   Contrôles
   ========================================================================== */

/* Un bouton dit une phrase — « Créer la séance », « Je viens » — et une
   phrase se lit en bas-de-casse, à taille de lecture. L'ancien habillage
   (mono 12 px, capitales espacées) faisait ressembler chaque action à un
   code d'erreur. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 46px;                 /* cible tactile : ces pages servent dans la rue */
  padding: 10px 20px;
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius);
  background: transparent;
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 15px; font-weight: 600; letter-spacing: .01em;
  text-decoration: none;
  cursor: pointer;
  transition: background .12s ease, border-color .12s ease, color .12s ease;
}
.btn:hover { border-color: var(--ink-dim); background: var(--bg-3); }
.btn:disabled { opacity: .45; cursor: not-allowed; }

.btn--primary { background: var(--red); border-color: var(--red); color: #fff; }
.btn--primary:hover { background: var(--red-deep); border-color: var(--red-deep); }

.btn--ghost { border-color: transparent; color: var(--ink-dim); padding-inline: 8px; font-weight: 500; }
.btn--ghost:hover { color: var(--ink); background: transparent; text-decoration: underline; }

.btn--danger { border-color: var(--red-deep); color: var(--red); }
.btn--danger:hover { background: var(--red-wash); border-color: var(--red); }

.btn--sm { min-height: 38px; padding: 6px 14px; font-size: 14px; }
.btn--block { width: 100%; }

.btn-group { display: flex; gap: 8px; flex-wrap: wrap; }

/* --- Champs --------------------------------------------------------------- */

label.field { display: block; }
.field-label {
  font-size: 13.5px; font-weight: 600; letter-spacing: .01em;
  color: var(--ink); display: block; margin-bottom: 6px;
}
.field-hint {
  font-size: 13px; line-height: 1.5; font-weight: 400;
  color: var(--ink-faint); margin-top: 6px; display: block;
}

input[type="text"], input[type="tel"], input[type="email"], input[type="date"],
input[type="time"], input[type="number"], input[type="password"], select, textarea {
  width: 100%;
  min-height: 44px;
  padding: 10px 12px;
  background: var(--bg-2);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;                  /* < 16px déclenche un zoom au focus sur iOS */
  line-height: 1.4;
}
textarea { min-height: 96px; resize: vertical; }
input:focus, select:focus, textarea:focus { border-color: var(--ink-dim); outline-offset: 0; }
input::placeholder, textarea::placeholder { color: var(--ink-faint); }

select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-dim) 50%),
                    linear-gradient(135deg, var(--ink-dim) 50%, transparent 50%);
  background-position: calc(100% - 18px) 50%, calc(100% - 13px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 34px;
}

/* Le code d'accès : caractères espacés, lecture chiffre par chiffre. */
input.code-input {
  font-family: var(--font-mono);
  font-size: 26px;
  letter-spacing: .34em;
  text-align: center;
  text-transform: uppercase;
  padding: 14px 12px;
}

/* --- Messages ------------------------------------------------------------- */

.notice {
  border: 1px solid var(--rule);
  border-left: 3px solid var(--ink-faint);
  background: var(--bg-2);
  padding: 12px 14px;
  font-size: 14.5px;
  line-height: 1.55;
  border-radius: var(--radius);
}
.notice--error { border-left-color: var(--red); color: var(--ink); }
.notice--ok { border-left-color: var(--ink); }

/* Encart juridique des collages : ne se replie pas, ne se ferme pas. */
.notice--legal {
  border-left-color: var(--red);
  background: var(--red-wash);
  font-size: 13.5px;
  line-height: 1.5;
}
.notice--legal strong { color: var(--ink); }

.empty {
  border: 1px dashed var(--rule-strong);
  border-radius: var(--radius);
  padding: 30px 20px;
  text-align: center;
  color: var(--ink-dim);
  font-size: 15px;
  line-height: 1.6;
}
.empty strong { display: block; color: var(--ink); font-size: 16.5px; margin-bottom: 6px; }

/* =============================================================================
   Statuts — encodés par le POIDS DE L'ENCRE, pas par la couleur
   =============================================================================
   Une palette de statuts multicolore (vert = soutien, orange = en cours…) est
   la solution attendue, mais elle jure avec une identité qui n'a que deux
   couleurs, et elle échoue pour qui distingue mal le rouge du vert. Ici, un
   statut acquis est plein, un statut en cours est en contour, un statut mort
   est barré. Le rouge reste réservé à ce qui appelle une action.
   ========================================================================== */

.pip {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  padding: 3px 9px;
  border: 1px solid var(--rule-strong);
  border-radius: 999px;
  color: var(--ink-dim);
  white-space: nowrap;
}
/* Acquis : plein. */
.pip[data-tone="acquis"] { background: var(--ink); border-color: var(--ink); color: var(--bg); font-weight: 600; }
/* En cours : contour net. */
.pip[data-tone="encours"] { border-color: var(--ink-dim); color: var(--ink); }
/* À faire : contour discret, mais marqué en rouge — c'est ce qui appelle. */
.pip[data-tone="afaire"] { border-color: var(--red); color: var(--red); }
/* Perdu : barré. */
.pip[data-tone="perdu"] { color: var(--ink-faint); text-decoration: line-through; }
/* Neutre : rien. */
.pip[data-tone="neutre"] { color: var(--ink-faint); }

/* Le menu de statut porte lui-même son ton : il se lit sans qu'on ait besoin
   d'une pastille en plus, qui répétait la même information. */
.select-statut {
  min-height: 38px;
  font-family: var(--font-mono);
  font-size: 12.5px;
  letter-spacing: .04em;
  text-transform: uppercase;
  border-color: var(--rule-strong);
}
.select-statut[data-tone="acquis"] { background: var(--ink); color: var(--bg); font-weight: 700; border-color: var(--ink); }
.select-statut[data-tone="encours"] { color: var(--ink); border-color: var(--ink-dim); }
.select-statut[data-tone="afaire"] { color: var(--red); border-color: var(--red); }
.select-statut[data-tone="perdu"] { color: var(--ink-faint); }

/* =============================================================================
   Listes et tableaux
   =============================================================================
   Pas de <table> pour les registres : sur un téléphone, un tableau à huit
   colonnes est illisible quoi qu'on fasse. Une grille CSS qui se replie en
   fiche empilée sous 760 px donne les deux lectures sans dupliquer le balisage.
   ========================================================================== */

.list { border-top: 1px solid var(--rule); }

.item {
  display: block;
  padding: 15px 0;
  border-bottom: 1px solid var(--rule);
  text-decoration: none;
  color: inherit;
}
a.item:hover, button.item:hover { background: var(--red-wash); }

.item-head {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
}
/* Les intitulés sont écrits par les militants — « Forum des associations,
   secteur 6/8 » — et une phrase de quelqu'un ne se compresse pas en
   capitales condensées : graisse et casse normale. */
.item-name {
  font-size: 16.5px;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: 0;
}
.item-meta {
  font-size: 13.5px;
  color: var(--ink-dim);
  margin-top: 4px;
  display: flex; gap: 10px; flex-wrap: wrap;
}
.item-meta span::after { content: " ·"; color: var(--rule-strong); }
.item-meta span:last-child::after { content: ""; }

/* Grille de registre : colonnes sur grand écran, fiches empilées sur mobile.
   Le tableau défile horizontalement plutôt que de comprimer les colonnes —
   un champ de six caractères de large ne sert à personne. */
.tableau-defilant { overflow-x: auto; padding-bottom: 4px; }
.grid-rows { border-top: 1px solid var(--rule); }
.grid-row {
  display: grid;
  gap: 6px;
  padding: 8px 0;
  border-bottom: 1px solid var(--rule);
  align-items: center;
}
.grid-head {
  display: none;
  font-family: var(--font-mono);
  font-size: 10px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink-faint);
  padding-bottom: 8px;
  border-bottom: 1px solid var(--rule-strong);
}
@media (min-width: 760px) {
  .grid-head { display: grid; gap: 6px; grid-template-columns: var(--cols); min-width: max-content; }
  .grid-row { grid-template-columns: var(--cols); min-width: max-content; }
}

/* Sous 760 px, la ligne devient une FICHE : cadre, fond, nom en tête.
   Empilées à nu, dix cellules transparentes par organisation se fondaient en
   une colonne continue où rien n'indiquait où l'une finissait et où la
   suivante commençait. */
@media (max-width: 759.98px) {
  .grid-rows { border-top: 0; }
  .grid-row {
    position: relative;
    background: var(--bg-2);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    padding: 12px;
    margin-bottom: 14px;
    gap: 8px;
  }
  /* Dans une fiche, les champs redeviennent des champs : fond et bord
     visibles, hauteur confortable. */
  .grid-row .cellule {
    background: var(--bg);
    border-color: var(--rule);
    height: 42px; min-height: 42px;
    font-size: 15px;
  }
  .grid-row .cellule--nom {
    font-size: 16.5px;
    height: 46px; min-height: 46px;
    padding-right: 44px;            /* la place de la croix de suppression */
  }
  .grid-row .cellule--notes { height: auto; min-height: 42px; }
  /* La croix se range en haut à droite de la fiche au lieu d'occuper une
     rangée entière à elle seule. */
  .grid-row .cellule--supprimer {
    position: absolute;
    top: 12px; right: 12px;
    width: 42px; height: 42px; min-height: 42px;
    background: transparent;
    border-color: transparent;
  }
}

/* --- Cellules -------------------------------------------------------------
   TOUTES les cellules ont la même hauteur et la même assise. C'est la seule
   règle qui compte : une ligne dont les champs ne s'alignent pas se lit comme
   un escalier, et rend un tableau de cent lignes pénible à parcourir. */
.cellule {
  height: 36px;
  min-height: 36px;
  padding: 4px 8px;
  font-size: 14px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius);
  color: var(--ink);
  width: 100%;
}
.cellule:hover:not(:disabled) { border-color: var(--rule); background: var(--bg-2); }
.cellule:focus { border-color: var(--ink-dim); background: var(--bg-2); }
.cellule:disabled { color: var(--ink-faint); cursor: not-allowed; }
.cellule::placeholder { color: var(--ink-faint); }
select.cellule { padding-right: 26px; background-position: calc(100% - 12px) 50%, calc(100% - 7px) 50%; }

.cellule--nom { font-weight: 600; font-size: 14.5px; }

/* Les notes prennent toute la largeur, sous la rangée principale. */
.cellule--notes {
  grid-column: 1 / -1;
  font-size: 13.5px;
  color: var(--ink-dim);
  border-color: transparent;
}

.cellule--supprimer {
  padding: 0; font-size: 18px; line-height: 1;
  color: var(--ink-faint); cursor: pointer;
}
.cellule--supprimer:hover:not(:disabled) { color: var(--red); border-color: var(--red); background: transparent; }
.cellule--supprimer:disabled { opacity: 0; pointer-events: none; }

button.cellule { justify-content: center; }

/* La ligne d'ajout.
   Elle était trop discrète : un champ vide au bas d'une liste de cinquante
   lignes ne se voit pas, et on en conclut qu'il faut passer par l'admin. Elle
   porte donc un cadre pointillé et un « + » rouge — la seule chose de la page
   qui ressemble à un bouton d'ajout. */
.ligne-ajout {
  display: flex; align-items: center; gap: 10px;
  margin-top: 8px;
  padding: 4px 10px;
  border: 1px dashed var(--rule-strong);
  border-radius: var(--radius);
  transition: border-color .12s ease, background .12s ease;
}
.ligne-ajout:hover, .ligne-ajout:focus-within {
  border-color: var(--red);
  background: var(--red-wash);
}
.ligne-ajout-plus {
  font-family: var(--font-display);
  font-size: 22px; line-height: 1;
  color: var(--red);
  flex: 0 0 auto;
}
.ligne-ajout-champ {
  flex: 1 1 auto;
  height: 40px; min-height: 40px;
  background: transparent;
  border: 0;
  color: var(--ink);
  font-size: 15px;
  padding: 0;
}
.ligne-ajout-champ:focus { outline: none; }
.ligne-ajout-champ::placeholder { color: var(--ink-dim); }

/* =============================================================================
   Cartes de séance
   ========================================================================== */

.card {
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--bg-2);
  padding: 18px;
}
/* Une séance qui manque de bras porte la marque rouge — c'est le seul appel. */
.card[data-needs="true"] { border-left: 3px solid var(--red); }
.card[data-status="annulee"] { opacity: .5; }

.card-top {
  display: flex; gap: 14px; align-items: flex-start; justify-content: space-between;
}
.card-title {
  font-size: 17px; font-weight: 700; line-height: 1.3;
}
.card-when {
  font-size: 14px; color: var(--ink-dim); margin-top: 4px;
  font-variant-numeric: tabular-nums;
}
/* Le délai d'une séance, en toutes lettres. Volontairement PAS traité comme le
   décompte « J-n » de la marche : ce sont deux repères différents, et leur
   donner la même apparence les faisait confondre. */
.card-delai {
  flex: 0 0 auto;
  font-size: 13px;
  color: var(--ink-faint);
  white-space: nowrap;
  padding-top: 3px;
}
.card-delai[data-imminent] { color: var(--red); font-weight: 600; }

.card-body { margin-top: 12px; font-size: 14.5px; color: var(--ink-dim); }
.card-body dt {
  font-size: 12px; font-weight: 600; letter-spacing: .05em;
  text-transform: uppercase; color: var(--ink-faint); margin-top: 12px;
}
.card-body dd { color: var(--ink); font-size: 15px; line-height: 1.5; margin-top: 2px; }
/* Le matériel à apporter est une demande adressée à qui lit : il porte la
   couleur des choses qui appellent une action, comme les séances dégarnies. */
.card-body dd.card-ask {
  color: var(--red);
  border-left: 2px solid var(--red);
  padding-left: 10px;
  margin-left: -12px;
}

.card-actions {
  display: flex; gap: 8px; flex-wrap: wrap;
  margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--rule);
}

/* Les inscrit·es : des initiales, jamais des noms complets. */
.people { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.person {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 999px;
  background: var(--bg-3); border: 1px solid var(--rule-strong);
  font-family: var(--font-mono); font-size: 11px; color: var(--ink);
  text-transform: uppercase;
}
.person[data-status="peut_etre"] { border-style: dashed; color: var(--ink-dim); }
.person[data-me="true"] { background: var(--red); border-color: var(--red); color: #fff; }
.people-count { font-size: 13px; color: var(--ink-faint); }

/* =============================================================================
   Pads
   ========================================================================== */

/* Le titre s'édite sur place : pas de bouton « renommer », on tape dedans. */
.pad-titre {
  font-family: var(--font-narrow);
  text-transform: uppercase;
  font-size: clamp(22px, 5vw, 32px);
  line-height: 1;
  letter-spacing: .01em;
  background: transparent;
  border: 1px solid transparent;
  padding: 4px 8px;
  margin-left: -8px;
  min-height: 0;
  flex: 1 1 auto;
}
.pad-titre:hover { border-color: var(--rule); }
.pad-titre:focus { border-color: var(--ink-dim); background: var(--bg-2); }

/* --- Barre d'outils ------------------------------------------------------
   Collante en haut de la zone : sur un compte rendu d'une page, on met en
   forme aussi bien au milieu du texte qu'au début. */
.pad-barre {
  position: sticky; top: 96px; z-index: 5;
  display: flex; align-items: center; gap: 2px; flex-wrap: wrap;
  padding: 6px 8px;
  background: var(--bg-3);
  border: 1px solid var(--rule);
  border-bottom: 0;
  border-radius: var(--radius) var(--radius) 0 0;
}
.pad-outil {
  min-width: 32px; min-height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0 7px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius);
  color: var(--ink-dim);
  font-family: var(--font-body);
  font-size: 14px;
  cursor: pointer;
}
.pad-outil:hover { background: var(--bg-2); color: var(--ink); }
.pad-outil[data-actif] { background: var(--ink); color: var(--bg); border-color: var(--ink); }
.pad-pastille {
  width: 15px; height: 15px; border-radius: 3px;
  border: 1px solid rgba(0,0,0,.25); display: block;
}
.pad-sep { width: 1px; height: 20px; background: var(--rule-strong); margin: 0 5px; }
.pad-taille {
  min-height: 32px; width: auto; min-width: 120px;
  padding: 4px 26px 4px 8px;
  font-size: 12.5px;
  background-color: var(--bg-2);
}

/* --- Zone d'écriture ------------------------------------------------------
   Haute et aérée : on y prend des notes de réunion, ce qui compte est de voir
   beaucoup de lignes à la fois. */
.pad-zone {
  background: var(--bg-2);
  border: 1px solid var(--rule);
  border-radius: 0 0 var(--radius) var(--radius);
}
.pad-contenu {
  min-height: 58vh;
  padding: 18px;
  outline: none;
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 15.5px;
  line-height: 1.65;
}
.pad-contenu > * + * { margin-top: .7em; }
.pad-contenu h1 { font-family: var(--font-narrow); text-transform: uppercase; font-size: 30px; line-height: 1.1; }
.pad-contenu h2 { font-family: var(--font-narrow); text-transform: uppercase; font-size: 23px; line-height: 1.15; }
.pad-contenu h3 { font-size: 18px; font-weight: 700; }
.pad-contenu ul, .pad-contenu ol { padding-left: 1.4em; }
.pad-contenu li { margin-top: .25em; }
.pad-contenu blockquote {
  border-left: 3px solid var(--red);
  padding-left: 14px;
  color: var(--ink-dim);
}
.pad-contenu code {
  font-family: var(--font-mono); font-size: .9em;
  background: var(--bg-3); padding: 1px 5px; border-radius: 3px;
}
.pad-contenu pre {
  background: var(--bg-3); padding: 12px; border-radius: var(--radius);
  overflow-x: auto; font-family: var(--font-mono); font-size: 13px;
}
/* Le surligneur porte du texte sombre : nos couleurs sont claires, et de
   l'encre claire dessus serait illisible. */
.pad-contenu mark { color: #16130f; padding: 1px 3px; border-radius: 2px; }
.pad-contenu hr { border: 0; border-top: 1px solid var(--rule-strong); }

/* Cases à cocher : le compte rendu se termine souvent en liste de choses à faire. */
.pad-contenu ul[data-type="taskList"] { list-style: none; padding-left: 0; }
.pad-contenu ul[data-type="taskList"] li { display: flex; gap: 10px; align-items: flex-start; }
.pad-contenu ul[data-type="taskList"] li > label { margin-top: .2em; }
.pad-contenu ul[data-type="taskList"] li > div { flex: 1 1 auto; }
.pad-contenu input[type="checkbox"] { width: 17px; height: 17px; min-height: 0; accent-color: var(--red); }

/* Placeholder de premier usage : une page blanche n'aide personne à démarrer. */
.pad-contenu p.is-editor-empty:first-child::before {
  content: attr(data-placeholder);
  color: var(--ink-faint);
  float: left; height: 0; pointer-events: none;
}

.pad-etat {
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-faint);
  margin-top: 8px;
}
.pad-etat[data-etat="hors-ligne"] { color: var(--red); text-transform: none; letter-spacing: .02em; }

.pad-apercu {
  font-size: 14px;
  color: var(--ink-dim);
  margin-top: 6px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* =============================================================================
   Compteurs du tableau de bord
   ========================================================================== */

.counters {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  overflow: hidden;
}
@media (min-width: 700px) { .counters { grid-template-columns: repeat(4, 1fr); } }

.counter { padding: 16px 14px; border-right: 1px solid var(--rule); border-bottom: 1px solid var(--rule); }
.counter:nth-child(2n) { border-right: 0; }
@media (min-width: 700px) {
  .counter { border-bottom: 0; }
  .counter:nth-child(2n) { border-right: 1px solid var(--rule); }
  .counter:last-child { border-right: 0; }
}
.counter-value {
  font-family: var(--font-display);
  font-size: clamp(30px, 8vw, 44px);
  line-height: .85;
  font-variant-numeric: tabular-nums;
}
.counter-value[data-alert="true"] { color: var(--red); }
.counter-label {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-faint); margin-top: 10px;
}

/* =============================================================================
   Barre de l'espace
   ========================================================================== */

.topbar {
  position: sticky; top: 0; z-index: 20;
  background: rgba(10, 10, 10, .94);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--rule);
}
.topbar-inner {
  max-width: 1080px; margin: 0 auto; padding: 10px var(--gutter);
  display: flex; align-items: center; gap: 12px; justify-content: space-between;
}
.topbar-city {
  font-family: var(--font-narrow); text-transform: uppercase;
  font-size: 18px; letter-spacing: .01em; text-decoration: none;
}
.topbar-city span { color: var(--red); }

/* --- Navigation de l'espace ------------------------------------------------
   Sur téléphone : un bouton qui nomme la section courante et déplie la liste.
   À partir de 760 px : la rangée d'onglets.

   La barre défilante d'avant ne marchait pas — elle montrait trois sections sur
   dix, sans rien indiquer qu'il y en avait d'autres. */

.nav-espace { border-bottom: 1px solid var(--rule); }

.nav-bouton {
  display: flex; align-items: center; gap: 10px; width: 100%;
  min-height: 46px; padding: 0 var(--gutter);
  background: transparent; border: 0; border-top: 1px solid var(--rule);
  color: var(--ink); cursor: pointer; text-align: left;
}
.nav-bouton-icone { font-size: 17px; color: var(--red); width: 16px; }
.nav-bouton-libelle {
  flex: 1 1 auto;
  font-size: 15px; font-weight: 600;
}
.nav-bouton-compte {
  font-size: 12px;
  color: var(--ink-faint);
  border: 1px solid var(--rule-strong); border-radius: 999px;
  padding: 1px 8px;
  font-variant-numeric: tabular-nums;
}

.nav-liste { display: none; padding-bottom: 6px; }
.nav-liste[data-ouvert] { display: block; }

.nav-lien {
  display: block;
  min-height: 46px; line-height: 46px;
  padding: 0 var(--gutter);
  font-size: 14.5px; font-weight: 500;
  color: var(--ink-dim); text-decoration: none;
  border-left: 3px solid transparent;
}
.nav-lien:hover { color: var(--ink); background: var(--bg-2); }
.nav-lien[aria-current="page"] { color: var(--ink); font-weight: 600; border-left-color: var(--red); }

.nav-quitter { padding: 8px var(--gutter) 0; border-top: 1px solid var(--rule); margin-top: 6px; }

@media (min-width: 760px) {
  /* Le bouton et le repli n'ont plus lieu d'être : tout tient sur une ligne. */
  .nav-bouton { display: none; }
  .nav-quitter { display: none; }

  .nav-liste {
    display: flex; gap: 2px;
    padding-bottom: 0;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .nav-liste::-webkit-scrollbar { display: none; }

  .nav-lien {
    flex: 0 0 auto;
    min-height: 0; line-height: 1;
    padding: 14px 12px;
    font-size: 14px;
    border-left: 0;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    white-space: nowrap;
  }
  .nav-lien:hover { background: transparent; }
  .nav-lien[aria-current="page"] { border-bottom-color: var(--red); }
}

/* Le nom et « Quitter » passent dans le menu sur petit écran. */
.topbar-fin { display: none; align-items: center; gap: 12px; }
@media (min-width: 760px) { .topbar-fin { display: flex; } }

/* =============================================================================
   Pages publiques
   ========================================================================== */

/* =============================================================================
   Accueil d'une ville
   ========================================================================== */

/* L'affiche en plein écran à l'arrivée. Fond blanc derrière le visuel : ces
   affiches sont des PNG transparents dessinés pour du papier. */
.splash {
  position: fixed; inset: 0; z-index: 9999;
  background: rgba(5, 5, 5, .95);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 18px; padding: 24px;
  animation: splash-entree .3s ease;
  cursor: pointer;
}
@keyframes splash-entree { from { opacity: 0 } to { opacity: 1 } }
@media (prefers-reduced-motion: reduce) { .splash { animation: none } }

.splash-affiche {
  background: #fff;
  padding: 8px;
  max-height: 78vh;
  box-shadow: 0 24px 70px rgba(0, 0, 0, .7);
}
.splash-affiche img {
  max-width: min(430px, 86vw);
  max-height: 74vh;
  width: auto; height: auto; display: block;
}
.splash-fermer {
  background: var(--red); border: 0; color: #fff;
  font-family: var(--font-body); font-size: 15px; font-weight: 600;
  padding: 13px 28px; cursor: pointer;
}
.splash-fermer:hover { background: var(--red-deep); }

.ville-hero {
  display: grid; gap: 28px;
  grid-template-columns: 1fr;
  align-items: center;
}
@media (min-width: 820px) {
  .ville-hero { grid-template-columns: 1fr minmax(240px, 360px); gap: 40px; }
}
.ville-hero-texte { display: flex; flex-direction: column; gap: 18px; }

/* L'affiche porte la page : c'est elle qu'on reconnaît et qu'on partage.
   Fond BLANC, et non le fond du site : ces affiches sont des PNG à canal
   alpha, dessinés pour du papier. Sur notre fond sombre, leur texte noir
   disparaissait purement et simplement. */
.ville-affiche {
  background: #fff;
  padding: 8px;
  box-shadow: 0 0 0 1px var(--rule-strong);
}
.ville-affiche img { width: 100%; height: auto; display: block; }

.ville-quand { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.ville-date {
  font-family: var(--font-narrow); text-transform: uppercase;
  font-size: clamp(18px, 3.4vw, 24px); line-height: 1.1;
}
.ville-lieu { font-size: 15.5px; color: var(--ink-dim); margin-top: 4px; }

/* --- Le programme public ---------------------------------------------------
   Composé comme une affiche de concert : le jour en grand sous un trait
   plein, l'heure en rouge dans la fonte condensée, le titre en gras. Tout ce
   qui figure ici est ouvert au public — pas de pastille « ouvert à tous »,
   ce serait dire deux fois la même chose. */
.prog-jour {
  display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap;
  padding-bottom: 8px; margin-bottom: 4px;
  border-bottom: 2px solid var(--ink);
}
.prog-date {
  font-family: var(--font-narrow); text-transform: uppercase;
  font-size: clamp(24px, 5.4vw, 32px); line-height: 1;
}
.prog-delai {
  margin-left: auto;
  font-size: 13px; color: var(--ink-faint);
}
.prog-evt {
  display: grid;
  grid-template-columns: 86px 1fr;
  gap: 2px 18px;
  align-items: baseline;
  padding: 16px 0;
  border-bottom: 1px solid var(--rule);
}
.prog-heure {
  font-family: var(--font-narrow); text-transform: uppercase;
  font-size: 24px; line-height: 1;
  color: var(--red);
  white-space: nowrap;
}
.prog-heure[data-vide] { color: var(--ink-faint); }
.prog-titre {
  font-size: 18.5px; font-weight: 700; line-height: 1.3;
}
.prog-lieu {
  grid-column: 2;
  font-size: 14.5px; color: var(--ink-dim);
}

/* --- En-tête public --------------------------------------------------------
   Collant, discret, toujours là : on arrive souvent sur une page intérieure
   par un lien partagé, et il faut pouvoir remonter au reste du site. */
.entete {
  position: sticky; top: 0; z-index: 30;
  background: rgba(10, 10, 10, .94);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--rule);
}
.entete-inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; flex-wrap: wrap;
  min-height: 54px; padding-block: 8px;
}
.entete-marque {
  font-family: var(--font-narrow);
  text-transform: uppercase;
  font-size: 19px; line-height: 1;
  letter-spacing: .01em;
  text-decoration: none;
  white-space: nowrap;
}
.entete-marque span { color: var(--red); }
.entete-nav { display: flex; gap: 6px; flex-wrap: wrap; }
.entete-nav a {
  display: inline-flex; align-items: center;
  min-height: 40px; padding: 0 11px;
  font-size: 14.5px; font-weight: 500;
  color: var(--ink-dim); text-decoration: none;
  border-bottom: 2px solid transparent;
}
.entete-nav a:hover { color: var(--ink); border-bottom-color: var(--red); }

.hero {
  padding: 52px 0 44px;
  border-bottom: 1px solid var(--rule);
}
.hero-count { display: flex; align-items: flex-end; gap: 20px; flex-wrap: wrap; }

/* La confrontation chiffrée : 732 086 signatures contre 0 débat. */
.confront {
  display: grid; gap: 20px;
  grid-template-columns: 1fr;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: 22px 20px;
}
@media (min-width: 700px) { .confront { grid-template-columns: 1fr 1px 1fr; align-items: center; } }
.confront-rule { background: var(--rule); width: 100%; height: 1px; }
@media (min-width: 700px) { .confront-rule { height: 100%; width: 1px; } }
.confront-value {
  font-family: var(--font-display); font-size: clamp(38px, 10vw, 72px);
  line-height: .85; font-variant-numeric: tabular-nums;
}
.confront-value[data-tone="red"] { color: var(--red); }
.confront-label {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-dim); margin-top: 12px;
}

.doors { display: grid; gap: 1px; background: var(--rule); border: 1px solid var(--rule); }
/* Autant de colonnes que de portes : l'accueil national en a trois, celui
   d'une ville deux — une grille figée laisserait une case grise vide. */
@media (min-width: 700px) { .doors { grid-auto-flow: column; grid-auto-columns: 1fr; } }
.door {
  background: var(--bg); padding: 24px 20px; text-decoration: none;
  display: flex; flex-direction: column; gap: 8px; min-height: 120px;
  transition: background .12s ease;
}
.door:hover { background: var(--bg-2); }
/* Les portes gardent la voix d'affiche : un ou deux mots, en grand — c'est
   de la signalétique, pas du texte courant. */
.door-title { font-family: var(--font-narrow); text-transform: uppercase; font-size: 26px; line-height: 1; }
.door:hover .door-title { color: var(--red); }
.door-desc { font-size: 14.5px; line-height: 1.55; color: var(--ink-dim); }

/* =============================================================================
   Kit de mobilisation
   ========================================================================== */

.kit-grille {
  display: grid;
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
  grid-template-columns: 1fr;
}
@media (min-width: 620px) { .kit-grille { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 960px) { .kit-grille { grid-template-columns: repeat(3, 1fr); } }

.kit-carte {
  background: var(--bg);
  display: flex; flex-direction: column;
  text-decoration: none;
  transition: background .12s ease;
}
.kit-carte:hover { background: var(--bg-2); }

/* L'aperçu montre l'affiche : c'est elle qu'on reconnaît, pas son titre. */
.kit-apercu {
  display: flex; align-items: center; justify-content: center;
  aspect-ratio: 4 / 3;
  background: var(--bg-2);
  overflow: hidden;
  border-bottom: 1px solid var(--rule);
}
.kit-apercu img { width: 100%; height: 100%; object-fit: cover; }

/* Sans aperçu, la tuile ne doit pas être un aplat noir : une trame diagonale
   discrète et le format en grand disent au moins de quoi il s'agit. */
.kit-apercu:not(:has(img)) {
  background-image: repeating-linear-gradient(
    -45deg,
    var(--bg-2) 0 10px,
    var(--bg-3) 10px 20px
  );
}
.kit-format {
  font-family: var(--font-display);
  font-size: 34px;
  color: var(--ink-dim);
  text-transform: uppercase;
  padding: 6px 14px;
  border: 2px solid var(--rule-strong);
  background: var(--bg);
}
.kit-apercu[data-canva] .kit-format { color: var(--red); border-color: var(--red); }

.kit-corps { padding: 16px; display: flex; flex-direction: column; gap: 6px; flex: 1 1 auto; }
.kit-titre {
  font-size: 16.5px; font-weight: 600; line-height: 1.3;
}
.kit-carte:hover .kit-titre { color: var(--red); }
.kit-desc { font-size: 14px; color: var(--ink-dim); line-height: 1.5; }
.kit-action {
  margin-top: auto; padding-top: 12px;
  display: flex; justify-content: space-between; align-items: baseline; gap: 10px;
  font-size: 13.5px; font-weight: 600;
  color: var(--red);
}
.kit-meta { color: var(--ink-faint); font-weight: 400; font-size: 13px; }

.footer {
  border-top: 1px solid var(--rule);
  margin-top: 60px; padding: 28px 0 40px;
  font-size: 13.5px;
  color: var(--ink-faint);
}
.footer a { color: var(--ink-dim); }

/* Utilitaires ------------------------------------------------------------- */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}


/* =============================================================================
   Éditeur de visuels personnalisables
   =============================================================================
   Repris de la feuille du site SAVE, dont le composant est repris aussi. Les
   classes gardent leur préfixe `pdt-` : renommer trente sélecteurs dans un
   composant de 19 Ko pour le seul plaisir de la cohérence des noms, c'est
   trente occasions de casser quelque chose sans rien gagner.

   Les variables (--red, --ink, --rule…) sont les mêmes des deux côtés : la
   charte est commune.
   ========================================================================== */
.pdt-kit-preview {
  border: 1px solid var(--rule); background: #000; padding: 16px;
  display: flex; align-items: center; justify-content: center; min-height: 320px;
}
.pdt-kit-preview canvas { max-width: 100%; max-height: 70vh; height: auto; display: block; }
.pdt-canvas { cursor: grab; touch-action: none; }
.pdt-canvas:active { cursor: grabbing; }
.pdt-hint {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .1em;
  color: var(--ink-dim); line-height: 1.6; margin: -4px 0 4px;
}
.pdt-field select {
  background: transparent; border: 1px solid var(--rule); color: var(--ink);
  padding: 11px 13px; font-family: var(--font-body); font-size: 14px;
}
.pdt-field select option { background: #0a0a0a; }
.pdt-field input[type="range"] { accent-color: var(--red); padding: 0; border: 0; }
.pdt-field input[type="color"] {
  width: 100%; height: 42px; padding: 2px; background: transparent;
  border: 1px solid var(--rule); cursor: pointer;
}
.pdt-field-inline { flex-direction: row; align-items: flex-end; gap: 16px; }
.pdt-field-inline > div { flex: 1; display: flex; flex-direction: column; gap: 6px; }
.pdt-check {
  display: flex; align-items: center; gap: 8px; white-space: nowrap;
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-dim); padding-bottom: 12px;
}
.pdt-check input { accent-color: var(--red); }
.pdt-dl-row { display: flex; flex-direction: column; gap: 10px; margin-top: 4px; }
.pdt-download-alt { background: transparent; color: var(--ink); border: 1px solid var(--rule); }
.pdt-download-alt:hover { background: transparent; border-color: var(--red); color: var(--red); }
.pdt-kit-form { display: flex; flex-direction: column; gap: 18px; }
.pdt-tpl-row { display: flex; flex-wrap: wrap; gap: 8px; }
.pdt-tpl {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .12em;
  text-transform: uppercase; padding: 9px 14px; cursor: pointer;
  background: transparent; color: var(--ink-dim); border: 1px solid var(--rule);
}
.pdt-tpl[aria-pressed="true"] { border-color: var(--red); color: var(--red); }
.pdt-field { display: flex; flex-direction: column; gap: 6px; }
.pdt-field label {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink-dim);
}
.pdt-field input {
  background: transparent; border: 1px solid var(--rule); color: var(--ink);
  padding: 11px 13px; font-family: var(--font-body); font-size: 14px;
}
.pdt-field input:focus { outline: none; border-color: var(--red); }
.pdt-download {
  padding: 15px 22px; background: var(--red); color: #fff; border: 0; cursor: pointer;
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .14em;
  text-transform: uppercase;
}
.pdt-download:hover { background: var(--red-deep); }
.pdt-download:disabled { opacity: .45; cursor: not-allowed; }
.pdt-kit-call:hover { border-color: var(--red); background: rgba(224,36,36,.04); }
.pdt-kit-call-counts {
  display: flex; flex-wrap: wrap; gap: 10px 32px;
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-dim);
}
.pdt-kit-call-counts strong {
  font-family: var(--font-display); font-size: 22px; color: var(--ink);
  margin-right: 8px; vertical-align: -2px;
}
.pdt-kit-call-cta {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--red); white-space: nowrap;
}
.pdt-kitsec:first-of-type { margin-top: 0; padding-top: 0; border-top: 0; }
.pdt-kitsec-head {
  display: flex; align-items: center; gap: 15px; margin-bottom: 12px;
}
.pdt-kitsec-num {
  flex: none; width: 30px; height: 30px; border-radius: 50%;
  background: var(--red); color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--font-mono); font-size: 13px;
}
.pdt-kitsec-title {
  font-family: var(--font-narrow); text-transform: uppercase;
  font-size: clamp(22px, 3.2vw, 34px); line-height: 1.05; color: var(--ink);
}
.pdt-kitsec-desc {
  color: var(--ink-dim); line-height: 1.6; max-width: 62ch;
  margin: 0 0 32px 45px; font-size: 14px;
}
.pdt-kit { grid-template-columns: 1fr; }
