/* Pictolang — feuille de style principale (SPEC §12.7).
   Palette : indigo / turquoise sur gris-bleu clair (volontairement différente de celle de Dicteo : même structure, autre look).
   Tout passe par des variables : un seul endroit à changer. L'ambre reste réservé à l'état « attention ». Thème clair par défaut, variante sombre. */

:root {
  --ink: #2B2468;          /* indigo : barres, titres, boutons */
  --ink-soft: #4a3fa0;
  --amber: #E0A458;        /* ambre : l'état « attention / en attente » (pastille .pill.amber, bandeau .banner.warn) : jamais décoratif */
  --amber-dark: #b9812f;
  --amber-soft: #f6e4c8;   /* ambre pâle : pastilles .pill.amber et bandeaux d'avertissement */
  --accent: #0E9C8A;       /* turquoise : la couleur d'accent du site (menu courant, survols, barre de progression, focus) */
  --accent-dark: #0a7567;  /* turquoise foncé : texte et survols sur fond clair */
  --accent-soft: #d7f3ef;  /* turquoise pâle : pastilles, cadre de la tuile « moins cher » */
  --on-accent: #04312c;    /* texte sur un fond --accent */
  --paper: #F3F5FA;        /* gris-bleu clair : fond de page */
  --card: #FFFFFF;         /* surface : cartes */
  --surface: #EAEEF7;      /* panneaux secondaires */
  --text: #1F2340;         /* encre */
  --muted: #5E6482;
  --line: #d6daea;
  --track: #e3e7f2;        /* piste pâle des barres de progression */
  --track-edge: #c9cfe2;

  --ok: #1E8E5A;           /* correct */
  --ok-bg: #ddf3e8;
  --ok-fort: #166b43;      /* vert lisible sur --ok-bg */
  --err: #C23B3B;          /* faux / lettres fautives */
  --err-bg: #f9dcdc;
  --miss: #8A8A8A;         /* manquant */
  --mauve: #7A54A8;        /* mot à deux graphies admises (1990 / tradition) */
  --mauve-bg: #efe8f7;
  --orange: #C25A0A;       /* passage dont deux écritures se prononcent pareil : toutes deux admises (variantes.txt) */
  --orange-bg: #fdecdb;
  --surligne: #fff2a6;     /* le texte tapé par l'élève, surligné au jaune (sans signaler les fautes) */

  --radius: 14px;
  --radius-sm: 10px;
  --shadow: 0 2px 10px rgba(43, 36, 104, .08);
  --font-ui: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-serif: Georgia, "Iowan Old Style", "Palatino Linotype", serif;
  --maxw: 760px;
  --maxw-wide: 1080px;
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 24px; --s6: 32px; --s8: 48px;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ink: #a99cf0; --ink-soft: #c1b8f6;
    --amber: #e6b169; --amber-dark: #e6b169;
    --accent: #3CCDB8; --accent-dark: #3CCDB8; --accent-soft: #14302d; --on-accent: #04312c;
    --paper: #14162A; --card: #1D2040; --surface: #262A52;
    --text: #ECEEFA; --muted: #A5AAC8; --line: #363B6A; --track: #2E3366; --track-edge: #454c86;
    --ok: #6fbf8a; --ok-bg: #1e2f26; --ok-fort: #8fd6a8; --err: #ef7a68; --err-bg: #3a221e; --miss: #98a0aa;
    --mauve: #b99be3; --mauve-bg: #2c2439;
    --orange: #f0a35e; --orange-bg: #3a2a1b;
    --surligne: #5c4f14;
    --shadow: 0 2px 12px rgba(0,0,0,.4);
  }
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--font-ui);
  font-size: 1.0625rem;
  line-height: 1.55;
  color: var(--text);
  background: var(--paper);
}
h1, h2, h3 { color: var(--ink); line-height: 1.2; }
a { color: var(--ink); }
p { margin: 0 0 var(--s4); }
.muted { color: var(--muted); }
.center { text-align: center; }
.container { width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 0 var(--s4); }
.container.wide { max-width: var(--maxw-wide); }
.stack > * + * { margin-top: var(--s4); }

/* --- Buttons --- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  min-height: 44px; padding: 0 var(--s5);
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--card); color: var(--ink);
  font: inherit; font-weight: 600; cursor: pointer; text-decoration: none;
  transition: filter .12s ease, background .12s ease;
}
.btn:hover { filter: brightness(.97); }
.btn-primary { background: var(--ink); color: #fff; border-color: var(--ink); }
.btn-amber { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
.btn-ghost { background: transparent; border-color: transparent; }
.btn-danger { background: var(--err); color: #fff; border-color: var(--err); }
.btn-block { width: 100%; }
.btn-lg { min-height: 54px; font-size: 1.1rem; padding: 0 var(--s6); }
.btn:has(.btn-fine) { flex-direction: column; gap: 0; padding-top: var(--s2); padding-bottom: var(--s2); text-align: center; }
.btn-fine { display: block; font-size: .72em; font-weight: 400; opacity: .9; line-height: 1.2; }   /* la précision entre parenthèses d'un bouton : plus petite, sous son libellé */
.btn[disabled] { opacity: .5; cursor: not-allowed; }
:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }

/* --- Cards, fields --- */
.card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow); padding: var(--s5);
}
label { display: block; font-weight: 600; margin-bottom: var(--s1); color: var(--ink); }
input[type=text], input[type=email], input[type=password], input[type=search],
textarea, select {
  width: 100%; padding: 10px 12px; font: inherit; font-size: 16px;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--card); color: var(--text);
}
textarea { min-height: 160px; resize: vertical; line-height: 1.6; }
/* La zone de la dictée : deux lignes de plus (les longues dictées obligeaient à défiler). */
#transcription { min-height: calc(160px + 3.2em); }
.field + .field { margin-top: var(--s4); }
/* Champ de mot de passe + bouton Afficher/Masquer (ajouté par app.js). */
.pw-wrap { display: flex; gap: var(--s2); align-items: stretch; }
.pw-wrap input { flex: 1; min-width: 0; }
.pw-toggle {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  min-width: 44px; padding: 0 var(--s3);
  color: var(--ink); background: var(--surface); cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
}
.pw-toggle svg { display: block; }
.pw-toggle:hover { background: var(--line); }
.pw-count { margin: var(--s1) 0 0; font-size: .86rem; }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.error-text { color: var(--err); font-weight: 600; }
.ok-text { color: var(--ok); font-weight: 600; }
.pill {
  display: inline-block; padding: 2px 10px; border-radius: 999px;
  background: var(--surface); color: var(--ink-soft); font-size: .82rem; font-weight: 700;
}
.pill.amber { background: var(--amber-soft); color: var(--amber-dark); }
.pill.accent { background: var(--accent-soft); color: var(--accent-dark); }          /* décoratif (étiquettes du site public), jamais un état */

/* --- Aides : bulle sur un champ ou un bouton, texte permanent seulement pour un avis important ---
   .hint  : visible en permanence — réservé aux avis qui ne doivent PAS se cacher derrière un survol
   (mention légale, message dynamique de connexion, avertissement portant sur plusieurs champs à la fois).
   L'explication d'UN champ précis est une bulle [data-tip] posée sur son ``.field`` (ou directement sur
   lui s'il n'a pas de conteneur), jamais un ``.hint``.
   [data-tip] : une bulle qui apparaît au survol (souris) après une seconde, jamais pendant la saisie.
   Rien n'est inséré dans la page tant que la bulle est cachée (display:none), pour qu'elle
   ne fasse jamais défiler la page. data-tip-pos="bottom" la place sous l'élément (barre du haut). */
.hint {
  margin: 0 0 var(--s2); padding: 4px 10px; width: fit-content; max-width: 100%;
  background: var(--surface); border-radius: var(--radius-sm);
  color: var(--ink-soft); font-size: .86rem; font-weight: 400; line-height: 1.4;
}
[data-tip] { position: relative; }
[data-tip]::after {
  content: attr(data-tip); display: none;
  position: absolute; z-index: 30; bottom: calc(100% + 8px); left: 50%; transform: translateX(-50%);
  width: max-content; max-width: min(260px, 80vw); padding: 6px 10px;
  background: var(--ink); color: var(--paper); border-radius: var(--radius-sm);
  font-size: .82rem; font-weight: 400; line-height: 1.35; text-align: center; white-space: normal;
  box-shadow: var(--shadow); pointer-events: none;
}
[data-tip]::before {
  content: ""; display: none;
  position: absolute; z-index: 30; bottom: calc(100% + 2px); left: 50%; transform: translateX(-50%);
  border: 6px solid transparent; border-top-color: var(--ink); border-bottom-width: 0;
  pointer-events: none;
}
/* Seulement quand la souris repose sur l'élément, après une pause d'une seconde (la bulle apparaît en fondu, donc ne clignote
   pas quand le pointeur ne fait que passer) ; jamais quand le contrôle a le focus (saisie dans un champ, bouton cliqué). */
[data-tip]:hover::after, [data-tip]:hover::before { display: block; animation: tip-in .15s ease 1s both; }
[data-tip]:focus-within::after, [data-tip]:focus-within::before { display: none; }
@keyframes tip-in { from { opacity: 0; } to { opacity: 1; } }
/* Petit bouton dont le sens doit se lire tout de suite (« ? » : voir la règle) : pas d'attente avant la bulle. */
[data-tip][data-tip-fast]:hover::after, [data-tip][data-tip-fast]:hover::before { animation: none; }
details[open] > summary[data-tip]::after, details[open] > summary[data-tip]::before { display: none; }
[data-tip][data-tip-pos="bottom"]::after { bottom: auto; top: calc(100% + 8px); }
[data-tip][data-tip-pos="bottom"]::before {
  bottom: auto; top: calc(100% + 2px);
  border-top-width: 0; border-top-color: transparent; border-bottom-width: 6px; border-bottom-color: var(--ink);
}
@media (hover: none) { [data-tip]:hover::after, [data-tip]:hover::before { display: none; } }
/* Bulle d'un choix de petit menu : pause courte (data-tip-quick, une fraction de seconde) et posée À GAUCHE de l'entrée (data-tip-pos="left"), pour ne pas dépasser le bord de l'écran. */
[data-tip][data-tip-quick]:hover::after, [data-tip][data-tip-quick]:hover::before { animation-delay: .35s; }
[data-tip][data-tip-pos="left"]::after {
  bottom: auto; top: 50%; left: auto; right: calc(100% + 10px); transform: translateY(-50%);
  max-width: min(240px, calc(100vw - 280px)); text-align: left;
}
[data-tip][data-tip-pos="left"]::before {
  bottom: auto; top: 50%; left: auto; right: calc(100% + 4px); transform: translateY(-50%);
  border: 6px solid transparent; border-right-width: 0; border-left-color: var(--ink);
}


/* --- Public nav / footer --- */
.site-head { background: var(--card); border-bottom: 1px solid var(--line); }
.nav { display: flex; align-items: center; justify-content: space-between; gap: var(--s4); height: 64px; }
.brand { display: inline-flex; align-items: center; gap: var(--s2); font-weight: 800; color: var(--ink); text-decoration: none; font-size: 1.15rem; }
.brand-stack { display: inline-flex; flex-direction: column; line-height: 1.05; }
.brand-domain { margin-top: 2px; font-size: .68rem; font-weight: 600; letter-spacing: .02em; opacity: .7; }   /* l'adresse du site sous le nom : un nom de marque, jamais traduit */
.nav-links { display: flex; align-items: center; gap: var(--s4); }
.nav-links a { text-decoration: none; font-weight: 600; white-space: nowrap; }
.site-foot { border-top: 1px solid var(--line); margin-top: var(--s8); padding: var(--s5) 0; }
.site-foot .container { display: flex; flex-wrap: wrap; gap: var(--s4); align-items: center; }
.site-foot a { text-decoration: none; font-weight: 600; }
.site-foot .muted a { font-weight: inherit; text-decoration: underline; }

/* --- App bar --- */
.appbar { background: var(--ink); position: sticky; top: 0; z-index: 20; }
.appbar-inner { display: flex; align-items: center; gap: var(--s5); height: 60px; }
.appbar .brand, .appbar .main-dests a, .appbar .btn-ghost { color: #fff; }
.main-dests { display: flex; gap: var(--s4); flex: 1; }
.main-dests a { text-decoration: none; font-weight: 600; opacity: .8; padding: 4px 2px; border-bottom: 2px solid transparent; }
.main-dests a[aria-current="page"] { opacity: 1; border-bottom-color: var(--accent); }
.admin-bar { background: #2a2118; }
.admin-actions { display: flex; align-items: center; gap: var(--s3); }

/* dropdown menu (details/summary) */
.menu { position: relative; }
.menu summary { list-style: none; }
.menu summary::-webkit-details-marker { display: none; }
.menu-panel {
  position: absolute; right: 0; top: 110%; min-width: 210px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-sm);
  box-shadow: var(--shadow); padding: var(--s2); display: flex; flex-direction: column;
}
.menu-panel a, .menu-logout {
  display: flex; align-items: center; gap: var(--s3); padding: 8px 10px; text-decoration: none; color: var(--text);
  border-radius: 8px; background: none; border: 0; font: inherit; text-align: left; cursor: pointer; width: 100%;
}
/* Icône à gauche de chaque entrée du menu : trait de la couleur du texte, taille fixe, jamais écrasée. */
.menu-ico { flex: none; width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round; color: var(--ink-soft); }.menu-panel a:hover, .menu-logout:hover { background: var(--surface); }
/* Bouton « Connexion » en deux parties : le bouton lui-même (va à l'écran de connexion) et une flèche qui ouvre le petit menu des quatre entrées. */
.login-menu { display: flex; align-items: stretch; }
.login-menu .login-main { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.login-menu .login-caret { padding: 0 var(--s3); border-top-left-radius: 0; border-bottom-left-radius: 0; border-left-color: rgba(255,255,255,.35); }
.login-menu .menu-panel { z-index: 20; }
.nav-links .login-menu .menu-panel a { font-weight: 500; }
.menu-sep { height: 1px; background: var(--line); margin: var(--s2) 0; }
.menu-user { padding: 6px 12px; font-size: .85em; color: var(--muted); overflow-wrap: anywhere; max-width: 260px; }

/* --- Landing --- */
.hero { background: linear-gradient(180deg, var(--surface), var(--paper)); padding: var(--s8) 0; }
.hero-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--s6); align-items: center; }
.hero h1 { font-size: 2.4rem; margin: var(--s3) 0; }
.hero .lead { font-size: 1.2rem; color: var(--muted); }
.hero-art { background: var(--card); border-radius: var(--radius); box-shadow: var(--shadow); padding: var(--s5); }

/* Aperçu de correction de la page d'accueil (texte corrigé + règle de grammaire). */
.demo-head { margin: 0 0 var(--s3); }
.hero-art .demo-copy { font-size: 1.1rem; line-height: 2; margin: 0; padding: var(--s4);
  box-shadow: none; background: var(--paper); }
.demo .w-variante { cursor: default; }
.demo-fiche { margin-top: var(--s4); padding: var(--s3) var(--s4); background: var(--surface);
  border-left: 4px solid var(--accent); border-radius: var(--radius-sm); font-size: .92rem;
  height: 20rem; overflow-y: auto; }
.demo-fiche h3 { margin: 0 0 var(--s2); font-size: 1.05rem; color: var(--ink); }
.demo-fiche p { margin: 0 0 var(--s2); }
.fiche-btn.is-on { outline: 2px solid var(--ink); outline-offset: 2px; }
.demo-note { margin: var(--s3) 0 0; font-size: .88rem; }
.cta-row { display: flex; gap: var(--s3); flex-wrap: wrap; margin-top: var(--s4); }
.reassure { list-style: none; padding: 0; margin: var(--s4) 0 0; color: var(--muted); font-size: .95rem; }
.reassure li::before { content: "✓ "; color: var(--ok); font-weight: 800; }
/* Niveaux des dictées : une seule ligne de texte simple, avec le même crochet
   vert que la liste au-dessus. Volontairement ni bordure, ni fond, ni
   arrondi : ce n'est pas un bouton et rien ne doit inviter à cliquer. La taille
   suit la largeur de l'écran pour que les quatre niveaux tiennent sur une ligne
   même sur un téléphone étroit. */
.levels-title { margin: var(--s4) 0 var(--s1); font-weight: 700; color: var(--ink); font-size: .95rem; }
.hero-copy { container-type: inline-size; }   /* la taille des niveaux suit CETTE colonne */
.levels { list-style: none; padding: 0; margin: 0; display: flex; flex-wrap: nowrap;
  gap: var(--s1) var(--s3); color: var(--muted); cursor: default;
  font-size: clamp(.62rem, 3.3vw, .95rem);        /* repli : suit la fenêtre */
  font-size: clamp(.62rem, 3.6cqw, .95rem); }     /* suit la colonne (navigateurs récents) */
.levels li { white-space: nowrap; }
.levels li::before { content: "✓ "; color: var(--ok); font-weight: 800; }
/* Vertical seulement : « container band » perdait sa gouttière latérale (texte collé au bord). */
.band { padding-block: var(--s8); }
.feature-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--s4); }
.feature { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: var(--s5); }
.feature .ico { font-size: 1.6rem; }
.section-title { text-align: center; margin-bottom: var(--s5); }

/* --- Plans --- (section en bas de l'accueil ; la nav pointe sur l'ancre) */
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
.pricing-faq { max-width: 560px; margin: var(--s5) auto 0; text-align: left; }
.pricing-faq summary { cursor: pointer; font-weight: 700; }
.plans { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--s4); }
/* Cinq forfaits : une par une sur téléphone, deux par deux (la dernière pleine
   largeur) jusqu'au conteneur standard, puis trois + deux centrées sur six colonnes. */
.plans-5 { grid-template-columns: repeat(2, 1fr); }
.plans-5 .plan:last-child { grid-column: 1 / -1; }
@media (max-width: 480px) { .plans-5 { grid-template-columns: 1fr; } }
@media (min-width: 800px) {
  .plans-5 { grid-template-columns: repeat(6, 1fr); gap: var(--s3); }
  .plans-5 .plan, .plans-5 .plan:last-child { grid-column: span 2; padding: var(--s4) var(--s3); }
  .plans-5 .plan:nth-child(4) { grid-column: 2 / span 2; }
  .plans-5 .plan:nth-child(5) { grid-column: 4 / span 2; }
}
/* Quatre forfaits : deux par deux (sinon trois puis une carte seule sur la ligne
   suivante), une par une sur téléphone, et quatre en ligne dès que le conteneur
   standard (760 px, celui des trois cartes « principe en trois étapes ») est
   atteint. Les cartes y sont plus étroites : marges et prix se resserrent. */
.plans-4 { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 480px) { .plans-4 { grid-template-columns: 1fr; } }
@media (min-width: 800px) {
  .plans-4 { grid-template-columns: repeat(4, 1fr); gap: var(--s3); }
  .plans-4 .plan { padding: var(--s4) var(--s3); }
  .plans-4 .plan .price { font-size: 1.7rem; }
}
.plan { position: relative; text-align: center; }
/* La tuile entière est un lien vers le récapitulatif de la commande. */
a.plan { display: flex; flex-direction: column; color: inherit; text-decoration: none; cursor: pointer;
  transition: border-color .15s ease, box-shadow .15s ease; }
a.plan:hover { border-color: var(--accent); box-shadow: 0 4px 14px rgba(30, 58, 95, .16); }
/* margin-top: auto colle le lien au bas de la tuile : il reste aligné d'une tuile
   à l'autre même quand l'une a une ligne de texte en moins. */
.plan-cta { display: block; margin-top: auto; padding-top: var(--s3); font-size: .9rem; font-weight: 700; color: var(--ink); }
a.plan:hover .plan-cta { text-decoration: underline; }

/* Récapitulatif de la commande (avant le paiement). */
.order-row { display: flex; justify-content: space-between; align-items: baseline; gap: var(--s4);
  padding-bottom: var(--s3); border-bottom: 1px solid var(--line); }
.order-row:last-child { border-bottom: 0; padding-bottom: 0; }
.order-row .text-ok { white-space: nowrap; }   /* « −17 % » ne se coupe pas entre le chiffre et le signe */
.order-title { font-size: 1.05rem; margin: var(--s5) 0 var(--s2); }
.order-fine { font-size: .88rem; margin: 0; }
.order-total-row { border-bottom: 0; padding-bottom: 0; font-weight: 700; color: var(--ink); }
.order-total { font-size: 1.7rem; font-weight: 800; }
.order-notes { margin: var(--s4) 0 0; padding-left: var(--s5); color: var(--muted); }
.order-notes li + li { margin-top: var(--s2); }
.plan.highlight { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent) inset, var(--shadow); }
/* Tuile « le moins cher par mois » : le même cadre que la tuile recommandée, en
   plus pâle — exactement la couleur de l'étiquette qui la coiffe. */
.plan.cheapest { border-color: var(--accent-soft); box-shadow: 0 0 0 2px var(--accent-soft) inset, var(--shadow); }
.plan .price { font-size: 2rem; font-weight: 800; color: var(--ink); }
.plan .per { color: var(--muted); font-size: .9rem; }
.plan .badge { position: absolute; top: -12px; left: 50%; transform: translateX(-50%); white-space: nowrap; }

/* --- Petite fenêtre de conversion de devises (indicatif, paiement en EUR) --- */
.fx-link { background: none; border: none; padding: 0; margin: 0; font: inherit;
  color: var(--ink); text-decoration: underline; cursor: pointer; }
.fx-link:hover { color: var(--accent-dark); }
.fx-overlay { position: fixed; inset: 0; z-index: 1000; display: flex;
  align-items: center; justify-content: center; padding: var(--s4);
  background: rgba(30,58,95,.5); }
.fx-modal { background: var(--card); color: var(--text); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow); width: 100%;
  max-width: 460px; max-height: 85vh; overflow-y: auto; padding: var(--s5); }
.fx-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s3); }
.fx-title { margin: 0; font-size: 1.25rem; }
.fx-close { background: none; border: none; font-size: 1.6rem; line-height: 1;
  color: var(--muted); cursor: pointer; padding: 0 4px; }
.fx-close:hover { color: var(--ink); }
.fx-loading { color: var(--muted); margin: var(--s4) 0 0; }
.fx-list { list-style: none; margin: var(--s4) 0 0; padding: 0; }
.fx-row { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px var(--s3);
  padding: var(--s3) 0; border-bottom: 1px solid var(--line); }
.fx-row:last-child { border-bottom: none; }
.fx-row-label { flex: 1 1 100%; color: var(--muted); font-size: .9rem; }
.fx-row-base { font-weight: 700; }
.fx-row-conv { color: var(--muted); }
.fx-note { margin: var(--s4) 0 0; color: var(--muted); font-size: .85rem; }
.fx-unavailable { margin: var(--s4) 0 0; }

/* --- Dictation list --- */
.filters { display: flex; flex-wrap: wrap; gap: var(--s2); margin: var(--s4) 0; }
.filters a {
  text-decoration: none; padding: 6px 12px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--card); font-weight: 600; font-size: .9rem; color: var(--ink);
}
.filters a.on { background: var(--ink); color: #fff; border-color: var(--ink); }
.dictation-list { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--s3); }
.dictation-row {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s4);
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: var(--s4) var(--s5); text-decoration: none; color: var(--text); box-shadow: var(--shadow);
}
.dictation-row:hover { border-color: var(--accent); }
.dictation-row .title { font-weight: 700; color: var(--ink); }
.badge-status { font-size: .78rem; font-weight: 700; padding: 2px 10px; border-radius: 999px; }
.st-not_started { background: var(--surface); color: var(--muted); }
.st-in_progress { background: var(--amber-soft); color: var(--amber-dark); }
.st-done { background: var(--ok-bg); color: var(--ok); }

/* --- Audio player + dictation screen --- */
.player { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: var(--s5); box-shadow: var(--shadow); }
.player audio { width: 100%; }
/* Lecteur de la dictée : bouton lecture, barre de progression (piste grise pâle, partie écoutée en bleu-nuit), temps, son. */
/* Le bouton du son porte maintenant son action (« Couper le son ») : sur un écran étroit il passe à la ligne plutôt que d'écraser la barre. */
.audio-bar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s3); margin-top: var(--s3); }
.audio-bar[hidden], .audio-status[hidden], .link-btn[hidden] { display: none; }
.play-btn, .mute-btn {
  flex: none; width: 44px; height: 44px; border-radius: 999px; border: 0; cursor: pointer;
  background: var(--ink); color: var(--card); font-size: 1rem; line-height: 1;
}
.mute-btn { width: auto; min-width: 56px; height: 40px; padding: 0 var(--s3); font-weight: 700; font-size: .9rem; background: var(--surface); color: var(--ink); border: 1px solid var(--track-edge); }
.play-btn:hover, .mute-btn:hover { filter: brightness(1.1); }
.audio-range {
  --pct: 0%;
  flex: 1 1 140px; min-width: 120px; height: 24px; margin: 0; cursor: pointer; background: transparent;
  appearance: none; -webkit-appearance: none;
}
.audio-range::-webkit-slider-runnable-track {
  height: 12px; border-radius: 999px; border: 1px solid var(--track-edge);
  background: linear-gradient(to right, var(--ink) var(--pct), var(--track) var(--pct));
}
.audio-range::-moz-range-track { height: 12px; border-radius: 999px; border: 1px solid var(--track-edge); background: var(--track); }
.audio-range::-moz-range-progress { height: 12px; border-radius: 999px; background: var(--ink); }
.audio-range::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none; width: 22px; height: 22px; margin-top: -6px; border-radius: 50%;
  background: var(--ink); border: 3px solid var(--card); box-shadow: 0 0 0 1px var(--ink);
}
.audio-range::-moz-range-thumb { width: 16px; height: 16px; border-radius: 50%; background: var(--ink); border: 3px solid var(--card); }
.audio-range:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 999px; }
.audio-time { font-variant-numeric: tabular-nums; white-space: nowrap; font-size: .9rem; color: var(--muted); }
.audio-status {
  margin-top: var(--s2); padding: var(--s1) var(--s3); border-radius: var(--radius-sm); font-size: .85rem; line-height: 1.4;
  background: var(--surface); color: var(--text); border-left: 3px solid var(--line);
}
.audio-status.is-playing { border-left-color: var(--accent); background: var(--accent-soft); color: var(--on-accent); }
.audio-status.is-problem { border-left-color: var(--err); background: var(--err-bg); color: var(--err); font-weight: 600; }
.link-btn {
  border: 0; background: none; padding: 0; margin-left: var(--s2); font: inherit; font-weight: 700;
  color: var(--ink); text-decoration: underline; cursor: pointer;
}
.sound-steps { padding-left: 1.3rem; display: grid; gap: var(--s2); }
.speed-row { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; margin-top: var(--s3); }
.speed-row .speeds { display: flex; flex-wrap: wrap; gap: var(--s1); }   /* huit vitesses : sur un écran étroit, la rangée passe à la ligne au lieu de déborder */
.speed-btn { min-height: 36px; padding: 0 12px; border-radius: 999px; border: 1px solid var(--line); background: var(--card); font-weight: 700; cursor: pointer; color: var(--ink); }
.speed-btn.on { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.dictation-actions { display: flex; gap: var(--s3); flex-wrap: wrap; margin-top: var(--s4); }
.savepill { color: var(--ok); font-weight: 700; align-self: center; }
.corrige-texte p { margin: 0 0 var(--s3); line-height: 1.7; }
/* Le texte tel que l'élève l'a tapé : ses retours à la ligne, ses espaces, surligné comme au marqueur jaune ; aucune faute n'y est marquée. */
.ecrit-texte { white-space: pre-wrap; line-height: 1.9; margin: 0; font-family: var(--font-serif); }
.ecrit-texte mark { background: var(--surligne); color: inherit; padding: .1em 0; -webkit-box-decoration-break: clone; box-decoration-break: clone; }
/* Le texte de la dictée affiché au résultat (le texte corrigé, coloré, et le « texte complet ») n'est pas sélectionnable : ni copier, ni glisser.
   Un frein, pas une serrure : voir docs/DECISIONS.md. La lecture d'écran n'est pas touchée. */
.no-copy, .no-copy * { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
.no-copy::selection, .no-copy *::selection { background: transparent; color: inherit; }
.keys-row { margin-top: var(--s2); }
.keys-row[hidden], .keypad[hidden] { display: none; }        /* display:flex plus bas l'emporterait sur l'attribut hidden */
.btn-small { min-height: 36px; padding: 0 12px; font-size: .92rem; }
.keypad { display: flex; flex-direction: column; gap: var(--s2); margin-top: var(--s2); padding: var(--s3); border: 1px solid var(--line); border-radius: 12px; background: var(--surface); }
/* Un groupe = UNE ligne : les touches se serrent pour tenir (elles rétrécissent). Sur téléphone, l'étiquette passe au-dessus et les touches rétrécissent encore. */
.keypad-group { display: flex; flex-wrap: nowrap; gap: 2px; align-items: center; }
.keypad-label { flex: 0 0 4.6rem; font-size: .8rem; }
.key { flex: 1 1 0; min-width: 22px; max-width: 42px; min-height: 38px; padding: 0; border-radius: 6px; border: 1px solid var(--line); background: var(--card); color: var(--text); font-size: 1.05rem; cursor: pointer; }
.key:hover { border-color: var(--accent); }
.key:active { background: var(--accent); color: var(--on-accent); }
@media (max-width: 520px) { .keypad { padding: var(--s2); } .keypad-group { flex-wrap: wrap; gap: 1px; } .keypad-label { flex-basis: 100%; } .key { min-width: 0; font-size: 1rem; } }

/* --- Result (coloured correction, §4.1 / §6) --- */
.copy {
  font-family: var(--font-serif); font-size: 1.3rem; line-height: 2.1;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: var(--s5); box-shadow: var(--shadow);
  /* Le texte reconstruit doit revenir à la ligne dans son cadre, y compris un
     mot très long, plutôt que déborder. */
  overflow-wrap: break-word; word-break: break-word;
}
.w { border-radius: 4px; padding: 0 1px; }
/* Un mot fautif et son bouton « ? » ne se séparent jamais en fin de ligne. */
.w-ens { white-space: nowrap; }
.w-correct { color: var(--ok); }
.w-modified { color: var(--err); font-weight: 700; }
/* La lettre fautive : fond teinté et barre pleine SOUS la lettre (une ombre interne, pas un soulignement) : le soulignement ondulé traversait la cédille du « ç »
   et de tout ce qui descend sous la ligne, et rendait la lettre illisible. */
.w-modified .bad { background: var(--err-bg); box-shadow: inset 0 -3px 0 var(--err); border-radius: 3px 3px 0 0; padding: 0 2px; text-decoration: none; }
/* Lettre que l'élève a oubliée : la lettre du corrigé, à sa place, pâle et pointillée. */
.w-modified .gap { color: var(--err); opacity: .65; font-weight: 600; border-bottom: 2px dotted var(--err); }
/* Au survol (ou au focus, pour le clavier et le toucher) d'un mot fautif : une infobulle verte AU-DESSUS donne le mot qu'il fallait écrire. */
.w-modified[data-corrige] { position: relative; cursor: help; }
.w-modified[data-corrige]::after {
  content: attr(data-corrige); display: none;
  position: absolute; z-index: 30; bottom: calc(100% + 6px); left: 50%; transform: translateX(-50%);
  width: max-content; max-width: min(260px, 80vw); padding: 3px 10px; text-align: center; white-space: normal;
  background: var(--ok-bg); color: var(--ok-fort); border: 1px solid var(--ok); border-radius: var(--radius-sm);
  font-size: 1rem; font-weight: 700; line-height: 1.35; box-shadow: var(--shadow); pointer-events: none;
}
.w-modified[data-corrige]:hover::after, .w-modified[data-corrige]:focus::after { display: block; }
.w-modified[data-corrige]:focus { outline: 0; }
.w-missing { color: var(--miss); text-decoration: underline dotted; }
.w-superfluous { color: var(--err); text-decoration: line-through; opacity: .6; }
/* Deux graphies admises : le mot reste vert (ce n'est pas une faute), le mauve
   ne fait que le souligner. Cliquable, donc focalisable au clavier. */
.w-variante {
  cursor: pointer; text-decoration: underline; text-decoration-color: var(--mauve);
  text-decoration-thickness: 3px; text-underline-offset: 6px;
}
.w-variante:hover, .w-variante:focus-visible { background: var(--mauve-bg); outline: 0; }
/* Deux écritures qui se prononcent pareil, toutes deux admises : même principe que le mauve, en orange. */
.w-ambigu {
  cursor: pointer; text-decoration: underline; text-decoration-color: var(--orange);
  text-decoration-thickness: 3px; text-underline-offset: 6px;
}
.w-ambigu:hover, .w-ambigu:focus-visible { background: var(--orange-bg); outline: 0; }
.variante-tag.ambigu-tag { background: var(--orange-bg); color: var(--orange); }
.variante-legende { margin-top: var(--s3); font-size: .95rem; }
.variante-list { list-style: none; margin: 0; padding: 0; }
.variante-list li {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s2);
  padding: var(--s3) 0; border-top: 1px solid var(--line);
}
.variante-label { flex-basis: 100%; color: var(--muted); font-size: .85rem; }
.variante-mot { font-family: var(--font-serif); font-size: 1.4rem; color: var(--ink); }
.variante-tag {
  font-size: .8rem; padding: 0 var(--s2); border-radius: 999px;
  background: var(--mauve-bg); color: var(--mauve);
}
.fiche-btn {
  display: inline-block; margin-left: 3px; font-size: .7rem; font-family: var(--font-ui);
  text-decoration: none; background: var(--accent); color: var(--on-accent); border-radius: 999px;
  width: 18px; height: 18px; line-height: 18px; text-align: center; font-weight: 800; vertical-align: super;
  border: 0; padding: 0; cursor: pointer;
}

/* --- Pagination (§8) --- */
.pager { display: flex; flex-wrap: wrap; gap: var(--s1); align-items: center; justify-content: center; margin: var(--s5) 0; }
.pager .pg {
  min-width: 40px; height: 40px; padding: 0 10px; display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--card);
  color: var(--ink); font-weight: 700; text-decoration: none;
}
.pager .pg.on { background: var(--ink); color: #fff; border-color: var(--ink); }
.pager .pg.disabled { opacity: .4; }
.list-head .pager { margin: 0; flex: 1 1 auto; }                  /* en haut : « Page 2 / 7 », les boutons et le menu sur la même ligne */
.pager .pg.gap { border: 0; background: none; min-width: 20px; }

/* --- Fenêtres de dialogue de l'application (confirmations, messages) : remplacent confirm()/alert() du navigateur --- */
dialog.app-dialog {
  border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow);
  background: var(--card); color: var(--text); max-width: 520px; width: calc(100% - 2rem); padding: var(--s5);
}
dialog.app-dialog::backdrop { background: rgba(30, 58, 95, .45); }
.app-dialog h3 { margin: 0 0 var(--s3); }
.app-dialog-body { white-space: pre-line; margin: 0 0 var(--s5); line-height: 1.5; }
.app-dialog-actions { display: flex; gap: var(--s3); justify-content: flex-end; flex-wrap: wrap; }

/* --- Modal de fiche de règle (§5) — pop-up, sans changer de route --- */
dialog.rule-modal {
  border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow);
  background: var(--card); color: var(--text); max-width: 560px; width: calc(100% - 2rem);
  padding: 0;
}
dialog.rule-modal::backdrop { background: rgba(30, 58, 95, .45); }
.rule-modal .modal-head { display: flex; justify-content: flex-end; padding: var(--s3) var(--s3) 0; }
.rule-modal .modal-close {
  border: 0; background: var(--surface); color: var(--ink); width: 34px; height: 34px;
  border-radius: 999px; font-size: 1.1rem; font-weight: 800; cursor: pointer; line-height: 1;
}
.rule-modal .modal-body { padding: 0 var(--s5) var(--s5); max-height: 70vh; overflow-y: auto; }
.rule-modal .modal-body hr { border: 0; border-top: 2px solid var(--line); margin: var(--s5) 0; }
.rule-src { display: none; }
.fault-count { font-size: 1.6rem; font-weight: 800; color: var(--ink); }
.fault-count.zero { color: var(--ok); }

/* --- Stats / by-type bars --- */
.by-type { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--s3); }
.by-type .row { display: grid; grid-template-columns: 180px 1fr auto; gap: var(--s3); align-items: center; }
.bar { height: 12px; border-radius: 999px; background: var(--surface); overflow: hidden; }
.bar > span { display: block; height: 100%; background: var(--accent); }
.evo { display: flex; gap: 3px; align-items: flex-end; height: 120px; padding: var(--s3); background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); }
.evo .col { flex: 1; background: var(--ink); border-radius: 3px 3px 0 0; min-height: 3px; }
.counter { display: flex; gap: var(--s5); flex-wrap: wrap; }
.counter .n { font-size: 2rem; font-weight: 800; color: var(--ink); }

/* --- Tables (admin) --- */
.admin-table { width: 100%; border-collapse: collapse; background: var(--card); border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow); }
/* Tableau des durées de conservation (politique de confidentialité) */
.rule-body table { width: 100%; border-collapse: collapse; margin: var(--s4) 0; font-size: .95rem; }
.rule-body th, .rule-body td { text-align: left; vertical-align: top; padding: 8px 10px; border-bottom: 1px solid var(--line); }
.rule-body th { color: var(--ink-2, inherit); font-weight: 600; }
.admin-table th, .admin-table td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--line); }
.admin-table th { background: var(--surface); color: var(--ink); font-size: .85rem; text-transform: uppercase; letter-spacing: .03em; }
/* Historique : un titre de colonne court (« Fautes ») ne se coupe jamais en deux lignes (la règle « anywhere » du corps le coupait avant le « s »). */
.history-table th { white-space: nowrap; overflow-wrap: normal; min-width: max-content; }
/* Console : un titre de colonne ne se coupe JAMAIS en deux lignes (« Acteur » ne perd plus son « r ») ; le tableau défile de côté sur un écran étroit au lieu de se déformer. */
.admin-table th { white-space: nowrap; overflow-wrap: normal; min-width: max-content; }
.table-scroll { overflow-x: auto; }
/* Une cellule de tableau de la console ne coupe plus un nom ou une adresse e-mail au milieu : « anywhere » (règle générale du site) la laisse rétrécir à une lettre ;
   « break-word » garde le mot entier, donc la colonne prend la largeur de l'adresse (le tableau défile de côté s'il le faut). */
.admin-table td { overflow-wrap: break-word; }
/* Les pastilles d'un tableau restent sur une ligne et leur texte est centré (« Mot de passe temporaire » ne se coupe plus en deux, décalé à gauche). */
.admin-table .pill { white-space: nowrap; text-align: center; }
/* Un bouton qui n'est qu'une icône (le nom de l'action est dans sa bulle et son aria-label) : petit carré. */
.btn-icone { min-height: 34px; width: 38px; padding: 0; }
.btn-icone .menu-ico { color: currentColor; }
.btn-icone.btn-danger .menu-ico { color: #fff; }
/* Un titre ou une étiquette qui porte une bulle d'aide : le curseur « ? » et un pointillé le disent, la bulle garde sa casse normale. */
.has-help { cursor: help; text-decoration: underline dotted; text-underline-offset: 4px; text-decoration-thickness: 1px; }
.admin-table th[data-tip]::after { text-transform: none; letter-spacing: 0; font-weight: 400; text-align: left; }
.admin-table th[data-tip]:first-child::after { left: 0; transform: none; }
.admin-table th[data-tip]:last-child::after { left: auto; right: 0; transform: none; }
/* Formulaire de filtres d'une liste de la console : les champs se rangent en rangées, chacun avec son titre. */
.filtres-admin { display: flex; flex-wrap: wrap; gap: var(--s3); align-items: flex-end; margin-bottom: var(--s4); }
.filtres-admin .field { margin: 0; min-width: 0; }
.filtres-admin label { display: block; font-size: .82rem; font-weight: 600; margin-bottom: 2px; }
.filtres-admin input, .filtres-admin select { width: auto; max-width: 100%; }
.filtres-admin input[type=search], .filtres-admin input[type=text] { min-width: 12rem; }
.filtres-admin input[type=number], .filtres-admin input[type=date] {
  padding: 10px 12px; font: inherit; font-size: 16px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--card); color: var(--text);
}
.filtres-admin input[type=number] { width: 7rem; }
.filtres-admin .btn { align-self: flex-end; }
/* Une carte de la console qui réunit plusieurs idées : chaque idée est une section, séparée de la précédente par un trait. */
.bloc-separe { border-top: 1px solid var(--line); padding-top: var(--s4); margin-top: var(--s4); }
.bloc-separe h4 { margin: 0 0 var(--s2); }
.mode-ajout { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: var(--s3) var(--s4); margin-top: var(--s3); background: var(--surface); }
.mode-ajout h5 { margin: 0 0 var(--s1); font-size: 1rem; }
.mode-ajout p { margin: 0 0 var(--s2); }
.legende dt { font-weight: 700; margin-top: var(--s3); }
.legende dd { margin: 2px 0 0; }
/* Tableau de bord : des pastilles plus petites (chiffre, titre court, lien) pour que la page tienne à l'écran sans défiler. */
.stat-grid.compact { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--s2); }
.stat-grid.compact .stat-tile { padding: var(--s2) var(--s3); }
.stat-grid.compact .stat-value { font-size: 1.45rem; line-height: 1.15; }
.stat-grid.compact .stat-label { font-size: .8rem; line-height: 1.25; }
.stat-grid.compact .stat-more { margin-top: 2px; font-size: .75rem; }
.stat-tile .stat-label { cursor: help; text-decoration: underline dotted; text-underline-offset: 4px; text-decoration-thickness: 1px; }
.stat-tile .stat-more { display: block; margin-top: var(--s2); font-size: .85rem; }

.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--s4); }
.stat-tile { text-align: center; }
.stat-value { font-size: 2rem; font-weight: 800; color: var(--ink); }
.danger-zone { border-color: var(--err); }
.banner { padding: var(--s3) var(--s4); border-radius: var(--radius-sm); background: var(--surface); }
.banner.ok { background: var(--ok-bg); color: var(--ok); }
.banner.warn { background: var(--amber-soft); color: var(--amber-dark); }
/* Le bandeau des heures offertes (partials/compensations.html) : pleine largeur, sous la barre du haut. */
.banner.compensation { border-radius: 0; padding: var(--s3) 0; }
.compensation-in p { margin: 0 0 var(--s2); }
.compensation-titre { font-size: 1.05rem; margin: 0 0 var(--s2); }
.compensation-motif { font-style: italic; opacity: .85; }
.compensation-ok { margin-top: var(--s2); }
.rule-body { line-height: 1.7; }
.rule-body h4 { color: var(--ink); }
.rule-body code { background: var(--surface); padding: 1px 5px; border-radius: 4px; }

/* Aide-mémoire (/app/rules) et pied des fiches */
.rules-search { max-width: 480px; margin: var(--s4) 0; }
.rules-search input { width: 100%; }
.rules-toc { display: flex; flex-wrap: wrap; gap: var(--s2); margin: var(--s4) 0 var(--s5); }
.rules-toc a { text-decoration: none; }
.rules-theme { margin-top: var(--s6); }
.rules-tools { display: flex; gap: var(--s2); margin: 0 0 var(--s3); }
.rules-tools[hidden] { display: none; }
.rules-acc { display: grid; gap: var(--s2); margin-top: var(--s3); }
.rule-acc { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius-sm); }
.rule-acc > summary {
  cursor: pointer; padding: var(--s3) var(--s4); font-weight: 600; color: var(--ink); list-style: none;
  display: flex; justify-content: space-between; align-items: center; gap: var(--s3);
}
.rule-acc > summary::-webkit-details-marker { display: none; }
.rule-acc > summary::after { content: "▾"; color: var(--muted); flex: 0 0 auto; transition: transform .15s; }
.rule-acc[open] > summary::after { transform: rotate(180deg); }
.rule-acc > summary:hover { background: var(--surface); }
.rule-acc[open] > summary { border-bottom: 1px solid var(--line); }
.rule-acc-body { padding: var(--s3) var(--s4) var(--s4); }
.rule-alone { margin: var(--s3) 0 0; font-size: .9rem; }
.rules-theme[hidden], .rule-acc[hidden] { display: none; }
@media (prefers-reduced-motion: reduce) { .rule-acc > summary::after { transition: none; } }
.rule-see { margin-top: var(--s4); font-size: .92rem; }

/* Petits écrans : l'en-tête ne déborde plus et ses éléments ne se touchent plus (vérifié de 320 à 480 px).
   - en-tête public : « Nous joindre » (déjà dans le pied de page) s'efface pour laisser la place au bouton ;
   - barre de l'application : marque + menu « Compte » sur la première rangée, les trois destinations sur la
     seconde, réparties sur toute la largeur. */
@media (max-width: 480px) {
  .nav { gap: var(--s3); }
  .nav-links { gap: var(--s3); }
  .nav-links .nav-secondary { display: none; }
  .nav-links { gap: var(--s2); }
  .login-menu .login-main { padding: 0 var(--s3); }
  .login-menu .login-caret { padding: 0 var(--s2); }
  .brand { font-size: 1.05rem; }
  .appbar-inner { flex-wrap: wrap; height: auto; padding-top: var(--s2); padding-bottom: var(--s2); row-gap: var(--s1); gap: var(--s3); }
  .appbar .menu { margin-left: auto; }
  .main-dests { order: 3; flex: 1 0 100%; justify-content: space-between; gap: var(--s2); font-size: .95rem; }
}

/* Téléphones (jusqu'à 480 px) : l'en-tête public déborderait et pousserait « Connexion » hors de l'écran.
   « Tarifs » s'efface (la section reste atteignable en défilant) et le bouton de langue se resserre ;
   sous 440 px le nom à côté du logo s'efface aussi. Vérifié à 320, 360, 390 et 430 px. */
@media (max-width: 480px) {
  .nav-links { gap: var(--s1); min-width: 0; }
  .nav-links > a:not(.btn):first-child { display: none; }
  .nav-links .lang-menu summary { padding-left: var(--s2); padding-right: var(--s2); }
}
@media (max-width: 440px) {
  .site-head .brand span { display: none; }
}

@media (max-width: 720px) {
  .hero-grid { grid-template-columns: 1fr; }
  .by-type .row { grid-template-columns: 120px 1fr auto; }
  .main-dests { gap: var(--s3); font-size: .95rem; }
}

/* Cinq destinations (avec « Aide ») : sur téléphone on resserre plutôt que de couper « Les dictées » en deux lignes. */
@media (max-width: 480px) {
  .main-dests { font-size: .82rem; gap: var(--s2); }
  .main-dests a { white-space: nowrap; }
}

/* 320 px : les cinq destinations ne tiennent pas sur une rangée au corps 0,82 rem — on resserre encore. */
@media (max-width: 340px) {
  .main-dests { font-size: .78rem; gap: 0; }
  .main-dests a { white-space: nowrap; }
}

/* Bouton de connexion sociale (Google) — logo + libellé alignés. */
.oauth-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2, 8px);
}
.oauth-logo { flex: 0 0 auto; }

/* --- Liste de dictées : en-tête + sélecteur de taille + lignes compactes --- */
.list-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s3); flex-wrap: wrap; margin: var(--s4) 0 var(--s3);
}
.per-page { display: flex; align-items: center; gap: var(--s2); margin: 0; }
.per-page label { margin: 0; font-size: .9rem; color: var(--muted); font-weight: 600; }
.list-head > p { margin: 0; font-size: .9rem; color: var(--muted); font-weight: 600; }   /* « Page 1 / 16 » : même fonte, même taille et même alignement que « Par page » */
.per-page select { width: 5.4rem; padding: 4px 22px 4px 10px; }   /* juste la place de « 100 » et de la flèche */
.btn-sm { padding: 4px 12px; font-size: .85rem; }

.dictation-list.compact { gap: var(--s2); }
.dictation-list.compact .dictation-row { padding: var(--s2) var(--s4); box-shadow: none; }
.row-main {
  display: flex; align-items: center; gap: var(--s2);
  flex-wrap: wrap; min-width: 0;
}
.pill.new { background: var(--ok-bg); color: var(--ok); }

/* --- Remplaçants des attributs style="" ---------------------------------
   La CSP (style-src 'self') refuse tout style inline : chaque style="" d'un
   gabarit est resté sans effet. Ces classes prennent le relais. */

/* Espacements (N = l'échelle --sN) */
.mt-3 { margin-top: var(--s3); } .mt-4 { margin-top: var(--s4); }
.mt-5 { margin-top: var(--s5); } .mt-6 { margin-top: var(--s6); }
.mb-4 { margin-bottom: var(--s4); } .mb-5 { margin-bottom: var(--s5); }
.py-8 { padding-top: var(--s8); padding-bottom: var(--s8); }

/* Colonnes étroites (connexion, mot de passe, porte de l'admin) */
.container.narrow-420 { max-width: 420px; }
.container.narrow-460 { max-width: 460px; }
.container.narrow-560 { max-width: 560px; }

/* Rangées flex et largeurs */
.row-between { display: flex; justify-content: space-between; align-items: center; gap: var(--s4); }
.flex-gap-2 { display: flex; gap: var(--s2); }
/* Filtres de la page Paiements : une rangée qui passe à la ligne, champs à leur hauteur naturelle. */
.filtre-paiements { display: flex; flex-wrap: wrap; gap: var(--s2); align-items: center; }
.filtre-paiements label { margin: 0; white-space: nowrap; }
.filtre-paiements select, .filtre-paiements input[type=date] { width: auto; }
.filtre-paiements input[type=search] { flex: 1 1 260px; width: auto; min-width: 0; }
.flex-wrap { flex-wrap: wrap; }
.flex-wrap > select { width: auto; }   /* sinon 100 % et une rangée à lui seul */
.items-center { align-items: center; }
.width-80 { width: 80px; }
.width-150 { width: 160px; }                 /* un champ date (le sélecteur de date du navigateur) */
.width-full { width: 100%; }
.check-auto { width: auto; margin-right: 6px; }
/* Case d'acceptation des conditions (inscription) et mention sous les boutons sociaux */
.consent { display: flex; align-items: flex-start; gap: var(--s2); font-size: .92rem; line-height: 1.4; }
.consent input { flex: none; margin-top: .2rem; }
.legal-note { font-size: .85rem; text-align: center; }
.code-area { min-height: 280px; font-family: monospace; }

/* Couleurs et fonds ponctuels */
.text-ok { color: var(--ok); }
.text-amber { color: var(--amber-dark); }
.text-accent { color: var(--accent-dark); }
.band-surface { background: var(--surface); }
.summary-strong { font-weight: 700; cursor: pointer; }

/* Barres de statistiques : la largeur et la hauteur arrivent en classes, par
   pas de 5 % (filtre `pct` de templating.py). */
.bar-w-0 { width: 0; }     .bar-w-5 { width: 5%; }     .bar-w-10 { width: 10%; }
.bar-w-15 { width: 15%; }  .bar-w-20 { width: 20%; }   .bar-w-25 { width: 25%; }
.bar-w-30 { width: 30%; }  .bar-w-35 { width: 35%; }   .bar-w-40 { width: 40%; }
.bar-w-45 { width: 45%; }  .bar-w-50 { width: 50%; }   .bar-w-55 { width: 55%; }
.bar-w-60 { width: 60%; }  .bar-w-65 { width: 65%; }   .bar-w-70 { width: 70%; }
.bar-w-75 { width: 75%; }  .bar-w-80 { width: 80%; }   .bar-w-85 { width: 85%; }
.bar-w-90 { width: 90%; }  .bar-w-95 { width: 95%; }   .bar-w-100 { width: 100%; }
.col-h-0 { height: 0; }    .col-h-5 { height: 5%; }    .col-h-10 { height: 10%; }
.col-h-15 { height: 15%; } .col-h-20 { height: 20%; }  .col-h-25 { height: 25%; }
.col-h-30 { height: 30%; } .col-h-35 { height: 35%; }  .col-h-40 { height: 40%; }
.col-h-45 { height: 45%; } .col-h-50 { height: 50%; }  .col-h-55 { height: 55%; }
.col-h-60 { height: 60%; } .col-h-65 { height: 65%; }  .col-h-70 { height: 70%; }
.col-h-75 { height: 75%; } .col-h-80 { height: 80%; }  .col-h-85 { height: 85%; }
.col-h-90 { height: 90%; } .col-h-95 { height: 95%; }  .col-h-100 { height: 100%; }

/* --- Un mot très long ne doit jamais élargir la page ------------------------------------------------------------
   Le titre d'une dictée peut avoir 200 caractères SANS espace, une adresse e-mail 254, un nom 100 : sans cette règle, la page entière devient plus large
   que l'écran (défilement horizontal, texte hors cadre). ``overflow-wrap: anywhere`` coupe un mot seulement quand il ne tient pas dans sa ligne, et laisse
   les éléments flexibles et les cellules de tableau rétrécir autour. Les commandes (boutons, pastilles, champs) gardent leur comportement habituel. */
body { overflow-wrap: anywhere; }
.btn, button, .pill, .badge-status, input, select, textarea, .brand, .nav-links a, .main-dests a, .filters a { overflow-wrap: normal; }
.dictation-row > *, .row-main > *, .card > *, .admin-table td, .admin-table th { min-width: 0; }

/* La barre de la console a plus d'entrées que celle de l'élève : sur un petit écran elle passe à la ligne au lieu de dépasser (32 px de trop à 375 px de large). */
.main-dests.admin-dests { flex-wrap: wrap; row-gap: 2px; }
.main-dests.admin-dests a { white-space: normal; }
/* La barre de la console a beaucoup d'entrées : elle grandit avec ses lignes au lieu de garder 60 px (sinon la 2e ligne, en blanc, tombait hors du fond sombre, donc invisible). */
.admin-bar .appbar-inner { height: auto; min-height: 60px; flex-wrap: wrap; row-gap: var(--s1); padding-top: var(--s2); padding-bottom: var(--s2); }
.admin-bar .main-dests.admin-dests { flex: 1 1 520px; }
/* Des entrées plus petites et plus serrées : douze entrées tiennent sur une ligne à la largeur d'un écran d'ordinateur. */
.admin-bar { font-size: .85rem; }
.admin-bar .appbar-inner { gap: var(--s3); max-width: none; }                /* toute la largeur de l'écran : la barre de la console n'est pas limitée comme le contenu */
.main-dests.admin-dests { gap: 6px 10px; }
.main-dests.admin-dests a { font-size: .82rem; padding: 2px 1px; }
.admin-bar .brand { font-size: .95rem; }
.admin-bar .btn-ghost { padding: 4px 10px; min-height: 0; font-size: .85rem; }

/* --- Offre B2B « organisations » ---------------------------------------------------------------------------------------------------
   Le code d'organisation et les mots de passe temporaires se lisent et se recopient à la main (fiche imprimée) : chasse fixe, espacement des signes. La fiche
   de connexion s'imprime seule : à l'impression, tout ce qui est marqué .no-print disparaît, et le titre .print-only apparaît. */
.org-code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 1.05rem; letter-spacing: .12em; }
.inline-form { display: inline-block; margin: 0 var(--s1) var(--s1) 0; }
.org-notice { border-radius: 0; padding: var(--s2) 0; font-size: .92rem; }
.print-only { display: none; }
/* La fiche ouverte dans son propre onglet (static/js/app.js, bindPrint) : une page simple, le titre visible, des cadres noirs comme à l'impression. */
.fiche-onglet { max-width: 900px; margin: 24px auto; padding: 0 16px; }
.fiche-onglet .print-only { display: block; }
.fiche-onglet .admin-table { box-shadow: none; }
.fiche-onglet .admin-table th, .fiche-onglet .admin-table td { border: 1px solid #000; padding: 8px 12px; }
@media print {
  .no-print, .appbar, .site-foot, .banner { display: none !important; }
  .print-only { display: block; }
  .org-code { font-size: 1.2rem; }
  .fiche .admin-table { box-shadow: none; }
  .fiche .admin-table th, .fiche .admin-table td { border: 1px solid #000; padding: 8px 12px; }
}


/* Connexion / création de compte : deux écrans distincts (onglets + couleur du panneau). */
.auth-tabs { display: flex; margin: 0 0 16px; border: 1px solid var(--line); border-radius: var(--radius-sm); overflow: hidden; }
.auth-tab { flex: 1; text-align: center; padding: 11px 8px; font-weight: 700; text-decoration: none; color: var(--ink); background: var(--card); }
.auth-tab:hover { background: var(--auth-hover); }
.auth-tab.active { background: var(--auth-main); color: #fff; }
.auth-tab-signup.active { background: var(--auth-alt); }
.auth-panel[hidden] { display: none; }
.auth-panel-login { border-top: 5px solid var(--auth-main); border-radius: var(--radius-sm); }
.auth-panel-signup { border-top: 5px solid var(--auth-alt); border-radius: var(--radius-sm); background: var(--auth-alt-soft); padding: 12px; }
.auth-title { margin: 0 0 8px; font-size: 1.15rem; }
:root { --auth-main: var(--ink); --auth-alt: var(--ink); --auth-alt-soft: rgba(30, 58, 95, .07); --auth-hover: var(--surface); }

/* Avertissement « verrouillage des majuscules » : une bulle à GAUCHE du champ de mot de passe (static/js/app.js). Sur écran étroit, il n'y a pas de place à gauche : elle passe au-dessus. */
.pw-caps-host { position: relative; }
.pw-caps {
  position: absolute; z-index: 40; right: calc(100% + 12px); top: 50%; transform: translateY(-50%); white-space: nowrap;
  padding: 6px 10px; border-radius: var(--radius-sm); background: var(--amber-soft); color: var(--ink); border: 1px solid var(--amber);
  font-size: .85rem; font-weight: 600; box-shadow: var(--shadow); pointer-events: none;
}
.pw-caps::before { content: "\26A0\FE0E  "; color: var(--amber-dark); }
.pw-caps::after { content: ""; position: absolute; left: 100%; top: 50%; transform: translateY(-50%); border: 6px solid transparent; border-left-color: var(--amber); border-right-width: 0; }
.pw-caps[hidden] { display: none; }
@media (max-width: 760px) {
  .pw-caps { right: auto; left: 0; top: auto; bottom: calc(100% + 8px); transform: none; }
  .pw-caps::after { left: 16px; top: 100%; transform: none; border: 6px solid transparent; border-bottom-width: 0; border-top-color: var(--amber); }
}
