/* ==========================================================NoteScan — Design Universal (Or + Bleu Nuit)
========================================================== */
:root {
  --gold: #D4AF37; --gold-2: #F4D77E; --gold-3: #A88B2C; --gold-soft: rgba(212, 175, 55, .15);
  --navy: #0A1633; --navy-2: #142754; --navy-3: #2A4A9C;
  --bg: #050B1A; --bg-2: #0D152B; --surface: #111827;
  --line: #1F2937; --line-2: #374151;
  --ink: #F9FAFB; --ink-2: #9CA3AF; --ink-3: #8B93A1;
  --danger: #EF4444; --danger-soft: rgba(239, 68, 68, .15);
  --success: #10B981; --wa: #25D366;
  --r-md: 12px; --r-lg: 16px; --r-xl: 24px; --r-pill: 999px;
  --shadow-1: 0 4px 6px rgba(0, 0, 0, .3), 0 10px 15px rgba(0, 0, 0, .2);
  --shadow-2: 0 10px 25px rgba(0, 0, 0, .4);
  --shadow-3: 0 20px 40px rgba(0, 0, 0, .5);
  --shadow-gold: 0 4px 14px rgba(212, 175, 55, .3);
  --font: "Manrope", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --safe-b: env(safe-area-inset-bottom, 0px); --safe-t: env(safe-area-inset-top, 0px);
  --ease: cubic-bezier(.2, .7, .2, 1); --nav-height: 72px;
  --fs-scale: 1.15; /* echelle des textes : 1 = taille d origine */
}


*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body { margin: 0; font-family: var(--font); font-size: calc(15px * var(--fs-scale)); line-height: 1.5; color: var(--ink); background: var(--bg); -webkit-font-smoothing: antialiased; -webkit-tap-highlight-color: transparent; min-height: 100vh; padding-top: var(--nav-height); padding-bottom: 40px; overflow-x: hidden; }
button, input, select, textarea { font-family: inherit; }
button { cursor: pointer; border: 0; background: none; padding: 0; color: inherit; }
:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
svg { display: inline-block; vertical-align: middle; flex-shrink: 0; }


/* HEADER */
.navigation { position: fixed; top: 0; left: 0; right: 0; height: var(--nav-height); background: #0D152B; border-bottom: 1px solid var(--line); z-index: 100; box-shadow: 0 4px 20px rgba(0, 0, 0, .4); }
.nav-container { max-width: 100%; height: 100%; padding: 0 16px; display: flex; align-items: center; justify-content: space-between; position: relative; }


/* MENU */
.nav-menu { position: fixed; top: var(--nav-height); left: 0; right: 0; bottom: 0; background: #0D152B; z-index: 99; display: none; flex-direction: column; overflow-y: auto; border-top: 1px solid var(--line); }
.nav-menu.open { display: flex; }
.nav-menu ul { list-style: none; margin: 0; padding: 8px 0; }
.nav-menu li { width: 100%; }
.nav-menu li button { display: flex; align-items: center; gap: 14px; width: 100%; padding: 16px 25px; color: var(--ink); font-size: calc(15px * var(--fs-scale)); font-weight: 600; background: transparent; border-bottom: 1px solid var(--line); text-align: left; transition: all .2s; min-height: 60px; }
.nav-menu li button:hover { background: var(--bg-2); color: var(--gold); }
.nav-menu li button.actif { color: var(--gold); font-weight: 700; box-shadow: inset 3px 0 0 var(--gold); }
.nav-menu li .ic { display: grid; place-items: center; width: 36px; height: 36px; background: var(--bg-2); border-radius: 10px; color: var(--ink-2); }
.nav-menu li button.actif .ic, .nav-menu li button:hover .ic { background: var(--gold-soft); color: var(--gold); }


/* LAYOUT */
main { max-width: 560px; margin: 0 auto; padding: 24px 18px 60px; }
.ecran > * + * { margin-top: 22px; }
h1 { margin: 0; font-size: calc(26px * var(--fs-scale)); font-weight: 800; letter-spacing: -.025em; color: var(--ink); }
.ecran > h1 + .sous { margin-top: 6px; padding-bottom: 22px; border-bottom: 1px solid var(--line); }
h2 { margin: 0 0 18px; padding-bottom: 14px; font-size: calc(15px * var(--fs-scale)); font-weight: 700; color: var(--ink); display: flex; align-items: center; gap: 10px; border-bottom: 1px solid var(--line); }
h2 svg { color: var(--gold); }
.sous { margin: 0; color: var(--ink-2); font-size: calc(14px * var(--fs-scale)); }
.petit { font-size: calc(12.5px * var(--fs-scale)); color: var(--ink-3); margin: 0; }
.cnt { font-weight: 700; color: var(--gold); font-size: calc(13px * var(--fs-scale)); margin-left: auto; }
.mt { margin-top: 18px; } .mb { margin-bottom: 16px; } .tc { text-align: center; }
.row-flex { display: flex; align-items: center; justify-content: space-between; gap: 12px; }


/* CARTES */
.carte { position: relative; background: var(--surface); border-radius: var(--r-lg); padding: 24px 22px; box-shadow: var(--shadow-1); border: 1px solid var(--line); }
.carte > * + * { margin-top: 14px; }
.carte > h2 + * { margin-top: 0; }
.carte::before { content: ""; position: absolute; left: 0; top: 24px; bottom: 24px; width: 3px; background: linear-gradient(180deg, var(--gold) 0%, transparent 100%); border-radius: 0 3px 3px 0; }
.carte + .carte { margin-top: 20px; }


/* ÉTAT VIDE */
.empty-state { text-align: center; padding: 48px 26px; background: var(--surface); border-radius: var(--r-lg); border: 1px solid var(--line); color: var(--ink-2); }
.empty-state .ic { display: grid; place-items: center; width: 84px; height: 84px; margin: 0 auto 20px; color: var(--gold); background: var(--gold-soft); border-radius: 50%; }
.empty-state p { margin: 0 0 22px; }
.empty-state p b { color: var(--ink); }
.empty-state .btn { width: auto; display: inline-flex; padding-inline: 26px; }


/* FORMULAIRES */
label { display: block; margin: 18px 0 8px; font-size: calc(13px * var(--fs-scale)); font-weight: 600; color: var(--ink); }
.carte > h2 + label, .carte > label:first-child { margin-top: 0; }
.inp, select.inp, textarea.inp { width: 100%; height: 50px; padding: 0 16px; font-size: calc(15px * var(--fs-scale)); color: var(--ink); background: var(--bg-2); border: 1px solid var(--line-2); border-radius: var(--r-md); outline: none; transition: all .2s; }
.inp::placeholder { color: var(--ink-3); }
.inp:focus { border-color: var(--gold); box-shadow: 0 0 0 3px var(--gold-soft); }
select.inp { appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' fill='none' stroke='%23F4D77E' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='M1 1.5l5 5 5-5'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 16px center; }
textarea.inp { height: auto; min-height: 120px; padding: 16px; resize: vertical; line-height: 1.5; }


/* BOUTONS */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 10px; width: 100%; min-height: 50px; padding: 0 20px; font-size: calc(14px * var(--fs-scale)); font-weight: 700; color: var(--ink); background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--r-md); transition: all .2s var(--ease); }
/* Sur un téléphone, un appui laisse le « survol » actif plusieurs secondes.
   La règle générique repeignait donc en bleu sombre les boutons dorés, verts
   ou rouges juste après le clic : ils semblaient devenir noirs. Elle ne
   s'applique plus qu'aux boutons qui n'ont pas de couleur propre. */
.btn:hover:not(.btn-p):not(.btn-v):not(.btn-r):not(.btn-b):not(.btn-danger):not(.btn-pdf):not(.overview-primary):not(.btn-valide):not(.btn-mention) { background: var(--bg-2); }
.btn:active { transform: scale(.98); }
/* Le voile gris affiché par Android au moment du clic donne un aspect sale. */
button, a, .btn, [role="button"] { -webkit-tap-highlight-color: transparent; }
/* Repère visible au clavier et sur les appareils qui n'ont pas de survol. */
.btn:focus-visible, button:focus-visible, a:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.btn[disabled] { opacity: .5; pointer-events: none; }
.btn + .btn { margin-top: 10px; }
.btn-sm { min-height: 40px; font-size: calc(13px * var(--fs-scale)); padding: 0 16px; }
.btn-p { color: #0A1633; border: none; background: linear-gradient(135deg, var(--gold-2), var(--gold)); box-shadow: var(--shadow-gold); }
.btn-p:hover { background: linear-gradient(135deg, var(--gold-2), var(--gold)); box-shadow: 0 6px 20px rgba(212, 175, 55, .5); }
.btn-p:active { background: linear-gradient(135deg, var(--gold), var(--gold-3)); }
.btn-b { color: var(--gold); border: 1px solid var(--gold-3); background: var(--bg-2); }
.btn-b:hover { background: var(--gold-soft); }
.btn-s { background: var(--bg-2); border-color: var(--line); color: var(--ink-2); }
.btn-s:hover { color: var(--ink); border-color: var(--ink-3); }
.btn-r { color: var(--danger); background: var(--danger-soft); border-color: transparent; }
.btn-r:hover { background: rgba(239, 68, 68, .25); }
.btn-l { color: var(--ink-2); background: transparent; border-color: transparent; }
.btn-l:hover { background: var(--bg-2); }
.btn-v { color: #fff; background: var(--wa); border-color: transparent; }
.btn-v:hover { background: #1EBE5D; }
.duo { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 16px; }
.duo .btn + .btn { margin-top: 0; }


/* SEGMENTS & MENTIONS */
#mentions .inp { height: 46px; padding: 0 14px; font-size: calc(14px * var(--fs-scale)); }
#mentions button:not(.btn) { width: 44px; height: 44px; display: grid; place-items: center; color: var(--ink-3); background: var(--bg-2); border-radius: 50%; }
#mentions button:not(.btn):hover { color: var(--ink); background: var(--line); }


/* LISTES & CLASSEMENT */
#listeEleves > *, #listeNotes > * { display: flex; align-items: center; gap: 12px; padding: 16px 0; border-bottom: 1px solid var(--line); }
#listeEleves > *:last-child, #listeNotes > *:last-child { border-bottom: 0; }
#listeEleves > * > :first-child, #listeNotes > * > :first-child { flex: 1; min-width: 0; font-weight: 600; color: var(--ink); font-size: calc(15px * var(--fs-scale)); }
#listeNotes input { width: 88px; height: 44px; text-align: center; font-weight: 700; flex: none; background: var(--bg-2); border-color: var(--line-2); color: var(--ink); border-radius: var(--r-md); border: 1px solid var(--line-2); font-size: calc(15px * var(--fs-scale)); outline: none; }
#listeNotes input:focus { border-color: var(--gold); box-shadow: 0 0 0 3px var(--gold-soft); }
#listeEleves button:not(.btn) { width: 44px; height: 44px; color: var(--ink-3); background: var(--bg-2); border-radius: 50%; }
#listeEleves button:not(.btn):hover { color: var(--danger); background: var(--danger-soft); }


#evalsCheck > *, #evalsCheck label { display: flex; align-items: center; gap: 10px; margin: 0; padding: 14px 0; font-size: calc(14.5px * var(--fs-scale)); color: var(--ink); border-bottom: 1px solid var(--line); }
#evalsCheck > *:last-child { border-bottom: 0; }
input[type="checkbox"] { width: 22px; height: 22px; accent-color: var(--gold); }
.stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px; margin-top: 20px; }
.stats > * { padding: 20px; background: var(--surface); border-radius: var(--r-lg); border: 1px solid var(--line); font-size: calc(11px * var(--fs-scale)); color: var(--ink-3); font-weight: 700; text-transform: uppercase; }
.stats b, .stats strong { display: block; margin-bottom: 4px; font-size: calc(26px * var(--fs-scale)); font-weight: 800; color: var(--gold); text-transform: none; }
.tw { overflow-x: auto; margin: 0 -8px; padding: 0 8px; }
.rank { width: 100%; border-collapse: collapse; font-size: calc(14px * var(--fs-scale)); }
.rank th { padding: 12px; text-align: left; font-size: calc(12px * var(--fs-scale)); font-weight: 700; color: var(--ink-3); text-transform: uppercase; border-bottom: 1px solid var(--line-2); }
.rank td { padding: 16px 12px; border-bottom: 1px solid var(--line); color: var(--ink); }
.rank tbody tr:hover { background: var(--bg-2); }
.rank td:first-child, .rank th:first-child { text-align: left; width: auto; font-weight: 600; color: var(--ink); }
/* Le rang ferme désormais la ligne : c'est lui qui porte le centrage et l'or. */
.rank td:last-child, .rank th:last-child { text-align: center; width: 84px; font-weight: 700; color: var(--gold); }
.rank td b { color: var(--ink); }
/* Répartition des mentions — barres proportionnelles, une par mention,
   à la couleur définie dans les paramètres de la classe. */
#repartitionMentions { display: flex; flex-direction: column; gap: 16px; }
#repartitionMentions .rep-item { display: block; }
#repartitionMentions .rep-ligne { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 7px; }
#repartitionMentions .rep-nom { display: inline-flex; align-items: center; gap: 9px; font-size: calc(13.5px * var(--fs-scale)); font-weight: 700; color: var(--ink); min-width: 0; }
#repartitionMentions .rep-dot { width: 11px; height: 11px; border-radius: 50%; flex: none; box-shadow: 0 0 0 3px rgba(255, 255, 255, .05); }
#repartitionMentions .rep-val { font-size: calc(12.5px * var(--fs-scale)); font-weight: 700; color: var(--ink-2); white-space: nowrap; font-variant-numeric: tabular-nums; }
#repartitionMentions .rep-piste { height: 10px; border-radius: 99px; background: var(--bg-2); border: 1px solid var(--line); overflow: hidden; }
#repartitionMentions .rep-remplissage { display: block; height: 100%; border-radius: 99px; animation: repGrow .6s var(--ease) both; }
@keyframes repGrow { from { width: 0; } }


/* DIALOGUES & POP-UPS */
dialog { position: fixed; inset: 0; width: min(calc(100% - 32px), 420px); max-height: calc(100dvh - 32px); margin: auto; padding: 28px 24px 24px; color: var(--ink); background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--r-xl); box-shadow: var(--shadow-3); overflow-y: auto !important; }
dialog::backdrop { background: rgba(5, 11, 26, .8); backdrop-filter: blur(8px); }
dialog h2 { font-size: calc(20px * var(--fs-scale)); margin: 0 0 20px; padding-bottom: 16px; color: var(--gold); border-bottom: 1px solid var(--line); }
dialog p { color: var(--ink-2); margin: 0 0 14px; }
dialog li { position: relative; padding: 12px 0 12px 34px; font-size: calc(15px * var(--fs-scale)); color: var(--ink); border-bottom: 1px solid var(--line); list-style: none; }
dialog li:last-child { border-bottom: 0; }
dialog li::before { content: "✓"; position: absolute; left: 0; top: 12px; width: 22px; height: 22px; display: grid; place-items: center; font-size: calc(13px * var(--fs-scale)); font-weight: 900; color: #0A1633; background: var(--gold); border-radius: 50%; }
.prix { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 16px 0; }
.prix > div { padding: 16px; text-align: center; font-size: calc(12px * var(--fs-scale)); color: var(--ink-2); background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--r-md); }
.prix > div:last-child { background: var(--gold-soft); border-color: var(--gold-3); }
.prix b { display: block; font-size: calc(20px * var(--fs-scale)); font-weight: 800; color: var(--gold); margin-bottom: 2px; }
.pro-close-x { position: absolute; top: 12px; right: 12px; width: 44px; height: 44px; display: grid; place-items: center; background: var(--bg-2); color: var(--ink); border-radius: 50%; border: 0; }
.pro-close-x:hover { color: var(--danger); background: var(--danger-soft); }
#dlgPro { position: fixed; inset: 0; margin: auto; }
.pro-code-wrapper { height: 54px; border-radius: var(--r-md); padding: 4px; display: flex; align-items: center; background: var(--bg-2); border: 1.5px solid var(--line-2); gap: 4px; margin-top: 20px; }
.pro-code-wrapper:focus-within { border-color: var(--gold); box-shadow: 0 0 0 3px var(--gold-soft); }
.pro-code-input { flex: 1; height: 100%; border: 0; outline: 0; padding: 0 14px; background: transparent; color: var(--gold); font-size: calc(12px * var(--fs-scale)); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-weight: 600; min-width: 0; }
.pro-code-input::placeholder { color: var(--ink-3); font-family: inherit; font-size: calc(13px * var(--fs-scale)); }
.pro-code-btn { height: 100%; padding: 0 18px; border: 0; border-radius: var(--r-md); color: #0A1633; background: linear-gradient(135deg, var(--gold-2), var(--gold)); font-weight: 800; font-size: calc(14px * var(--fs-scale)); }
.pro-code-btn:disabled { opacity: .65; cursor: wait; }
.pro-sub { font-size: calc(13px * var(--fs-scale)); line-height: 1.5; color: var(--ink-2); margin: 0 0 14px; }
.pro-paiement-note { font-size: calc(12px * var(--fs-scale)); line-height: 1.45; color: var(--ink-3); text-align: center; margin: 10px 0 0; }
.pro-code-label { margin: 20px 0 0; font-size: calc(12px * var(--fs-scale)); font-weight: 800; letter-spacing: .4px; text-transform: uppercase; color: var(--gold); }
.pro-code-msg { min-height: 18px; margin: 8px 2px 0; font-size: calc(12.5px * var(--fs-scale)); font-weight: 600; line-height: 1.4; color: var(--ink-3); }
.pro-code-msg.err { color: var(--danger); }
.pro-code-msg.ok { color: var(--success); }


.dlg-profil { text-align: center; padding: 32px 24px 24px !important; border-radius: 28px; background: linear-gradient(180deg, #111827 0%, #0D152B 100%); border: 1px solid rgba(212, 175, 55, 0.15); max-height: calc(100dvh - 40px) !important; overflow-y: auto !important; }
.dlg-profil h2 { font-size: calc(24px * var(--fs-scale)); font-weight: 800; color: var(--gold); margin: 0 0 8px; padding: 0; border-bottom: 0; }
.dlg-profil .profil-intro { font-size: calc(14px * var(--fs-scale)); color: var(--ink-2); margin: 0 0 24px; line-height: 1.5; padding: 0 10px; }
.profil-form { text-align: left; background: rgba(13, 21, 43, 0.6); border: 1px solid rgba(255, 255, 255, 0.05); border-radius: 20px; padding: 20px; margin-bottom: 20px; }
.profil-label { display: flex; align-items: center; gap: 8px; margin: 0 0 10px; font-size: calc(12.5px * var(--fs-scale)); font-weight: 700; color: var(--ink-2); text-transform: uppercase; letter-spacing: 0.5px; }
.profil-label svg { color: var(--gold); opacity: 0.9; }
.profil-label.mt { margin-top: 18px; }
.profil-form .inp { background: var(--bg); border: 1px solid var(--line-2); height: 50px; padding: 0 16px; font-weight: 600; font-size: calc(15px * var(--fs-scale)); color: var(--ink); border-radius: 12px; }
.profil-form .inp:focus { background: var(--bg); border-color: var(--gold); box-shadow: 0 0 0 3px rgba(212, 175, 55, 0.15); }
.btn-profil-valider { width: 100%; height: 56px; margin-top: 4px; font-size: calc(16px * var(--fs-scale)); font-weight: 800; color: #0A1633; background: linear-gradient(135deg, var(--gold-2) 0%, var(--gold) 50%, var(--gold-3) 100%); border: none; border-radius: var(--r-md); box-shadow: 0 8px 25px rgba(212, 175, 55, 0.35); transition: all 0.25s ease; display: flex; justify-content: center; align-items: center; gap: 10px; cursor: pointer; flex-shrink: 0; }
.btn-profil-valider:hover { box-shadow: 0 10px 30px rgba(212, 175, 55, 0.5); transform: translateY(-1px); }
.btn-profil-valider:active { transform: scale(0.98); }


.dlg-erreur { text-align: center; padding-top: 32px; }
.erreur-icon { display: flex; justify-content: center; margin-bottom: 16px; color: var(--danger); }
.dlg-erreur h2 { display: block; text-align: center; font-size: calc(19px * var(--fs-scale)); color: var(--danger); border-bottom: 0; padding: 0; margin: 0 0 12px; }
.erreur-list { background: var(--danger-soft); border-radius: var(--r-md); padding: 16px 20px 16px 36px; margin: 0 0 20px; list-style: disc; text-align: left; }
.erreur-list li { padding: 6px 0; font-size: calc(14px * var(--fs-scale)); color: var(--ink); font-weight: 600; border: none; list-style: disc; }
.erreur-list li::before { display: none; }


.toast {
  position: fixed;
  left: 50%;
  bottom: calc(28px + var(--safe-b));
  transform: translateX(-50%);
  z-index: 999;
  max-width: calc(100% - 32px);
  padding: 16px 20px;
  font-size: calc(13.5px * var(--fs-scale));
  font-weight: 700;
  line-height: 1.45;
  text-align: center;
  color: var(--gold);
  background: linear-gradient(180deg, #131C33 0%, #0D152B 100%);
  border: 1.5px solid var(--gold-3);
  border-left-width: 4px;
  border-radius: var(--r-md);
  box-shadow: 0 14px 34px rgba(0, 0, 0, .55);
  animation: toastIn .26s var(--ease);
}
/* Message d'erreur : la même carte, en rouge. */
.toast.err {
  color: #FCA5A5;
  border-color: rgba(239, 68, 68, .75);
  background: linear-gradient(180deg, #2A1116 0%, #1A0B10 100%);
}
/* Message de réussite : la même carte, en vert. */
.toast.ok {
  color: #A7F3D0;
  border-color: rgba(16, 185, 129, .7);
  background: linear-gradient(180deg, #0C2119 0%, #08160F 100%);
}
@keyframes toastIn { from { opacity: 0; transform: translate(-50%, 20px) scale(.9); } to { opacity: 1; transform: translate(-50%, 0) scale(1); } }
/* Animation spéciale pour le Toast en haut */
.toast.top-toast {
  top: calc(var(--nav-height) + 8px); /* juste sous l'en-tête */
  bottom: auto;
  animation: toastSlideDown 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}


@keyframes toastSlideDown {
  from { opacity: 0; transform: translate(-50%, -30px); }
  to { opacity: 1; transform: translate(-50%, 0); }
}
/* =========================================================
   ACCUEIL (MODE FOCUS TOTAL & EFFET HUB) 
   ========================================================= */
body.accueil-actif { min-height: 100svh; padding: 0; overflow: hidden; background: radial-gradient(ellipse at 50% 46%, rgba(10, 22, 51, 0.9), #050B1A); }
body.accueil-actif .navigation, body.accueil-actif .nav-menu, body.accueil-actif .nav-mobile { display: none !important; }
body.accueil-actif main { display: grid; width: 100%; min-height: 100svh; margin: 0; padding: 24px; place-items: center; }
body.accueil-actif .ecran-accueil { display: grid; width: 100%; max-width: none; min-height: calc(100svh - 48px); margin: 0; padding: 0; place-items: center; }


#ecran-accueil .quick-card { 
  position: relative; 
  width: min(360px, calc(100vw - 40px)); 
  height: auto; 
  aspect-ratio: 1; 
  margin: 0; 
  border: 1px solid rgba(212, 175, 55, 0.2); 
  border-radius: 28px; 
  background: radial-gradient(circle at 50% 50%, #142754 0%, #0A1633 100%); 
  box-shadow: 0 28px 90px rgba(0, 0, 0, 0.6), inset 0 0 40px rgba(212, 175, 55, 0.05), 0 0 0 0 rgba(212, 175, 55, 0.3); 
  animation: homeCardIn .65s cubic-bezier(.2, .7, .2, 1) both, pulseGlow 4s infinite alternate ease-in-out; 
}


@keyframes pulseGlow { 
  0% { box-shadow: 0 28px 90px rgba(0, 0, 0, 0.6), inset 0 0 40px rgba(212, 175, 55, 0.05), 0 0 20px 2px rgba(212, 175, 55, 0.1); border-color: rgba(212, 175, 55, 0.2); } 
  100% { box-shadow: 0 28px 90px rgba(0, 0, 0, 0.6), inset 0 0 40px rgba(212, 175, 55, 0.1), 0 0 40px 6px rgba(212, 175, 55, 0.25); border-color: rgba(212, 175, 55, 0.4); } 
}


#ecran-accueil .quick-card .background { display: none; }


/* LE LOGO CENTRAL */
#ecran-accueil .quick-card .logo { 
  position: absolute; 
  top: 50%; 
  left: 50%; 
  transform: translate(-50%, -50%); 
  z-index: 10; 
  width: 120px; 
  height: 120px; 
  padding: 8px 10px; 
  color: #fff; 
  background-color: rgba(11, 24, 18, 0.95); 
  border: 1px solid rgba(212, 175, 55, 0.6); 
  border-radius: 20px; 
  box-shadow: 0 12px 35px rgba(0, 0, 0, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.1); 
  backdrop-filter: blur(12px); 
  display: flex; 
  flex-direction: column; 
  align-items: center; 
  justify-content: center; 
  overflow: hidden; 
  cursor: pointer; 
  transition: transform 0.3s ease, box-shadow 0.3s ease; 
}


#ecran-accueil .quick-card .quick-logo-img { 
  width: 78px; 
  height: 78px; 
  object-fit: contain; 
  display: block; 
  flex: none; 
  margin-bottom: 4px; 
  pointer-events: none; 
  user-select: none; 
}


#ecran-accueil .quick-card .logo:hover { 
  transform: translate(-50%, -50%) scale(1.05); 
  box-shadow: 0 15px 45px rgba(0, 0, 0, 0.8), inset 0 1px 0 rgba(255, 255, 255, 0.2); 
}


#ecran-accueil .quick-wordmark { 
  font-size: calc(13px * var(--fs-scale)); 
  color: #F4D77E; 
  font-weight: 800; 
  text-align: center; 
  line-height: 1.2; 
  margin: 0; 
}/* LES 4 BOX (CACHÉES PAR DÉFAUT) */
#ecran-accueil .quick-card .box { 
  position: absolute; 
  z-index: 1; 
  display: flex; 
  flex-direction: column; 
  align-items: center; 
  justify-content: center; 
  gap: 10px; 
  width: calc(50% - 22px); 
  height: calc(50% - 22px); 
  padding: 12px; 
  color: #FFF8E1; 
  text-align: center; 
  background: linear-gradient(135deg, rgba(20, 39, 84, 0.4) 0%, rgba(10, 22, 51, 0.6) 100%); 
  border: 1px solid rgba(212, 175, 55, 0.15); 
  border-radius: 22px; 
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.05); 
  backdrop-filter: blur(8px); 
  top: 50%; 
  left: 50%; 
  opacity: 0; 
  transform: translate(-50%, -50%) scale(0); 
  pointer-events: none; 
  transition: all 0.6s cubic-bezier(0.34, 1.56, 0.64, 1); 
}


/* ANIMATION D'OUVERTURE AU CLIC SUR LE LOGO */
#ecran-accueil .quick-card.menu-open .box { 
  opacity: 1; 
  transform: translate(0, 0) scale(1); 
  pointer-events: auto; 
}
#ecran-accueil .quick-card.menu-open .box1 { top: 16px; left: 16px; }
#ecran-accueil .quick-card.menu-open .box2 { top: 16px; right: 16px; left: auto; }
#ecran-accueil .quick-card.menu-open .box3 { bottom: 16px; top: auto; left: 16px; }
#ecran-accueil .quick-card.menu-open .box4 { bottom: 16px; top: auto; right: 16px; left: auto; }


#ecran-accueil .quick-card.menu-open .box:hover { 
  background: linear-gradient(135deg, rgba(30, 55, 110, 0.6) 0%, rgba(15, 30, 70, 0.8) 100%); 
  border-color: rgba(212, 175, 55, 0.6); 
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.1); 
  transform: scale(1.02); 
}


#ecran-accueil .quick-card .quick-label { 
  color: #FFF8E1; 
  font-size: calc(11px * var(--fs-scale)); 
  font-weight: 800; 
  text-transform: uppercase; 
  letter-spacing: 0.5px; 
  line-height: 1.2; 
  white-space: nowrap; 
}


#ecran-accueil .quick-card .icon { 
  width: 24px; 
  height: 24px; 
  color: var(--gold); 
}
#ecran-accueil .quick-card .icon svg { fill: currentColor; }


@keyframes homeCardIn { 
  from { opacity: 0; transform: translateY(12px) scale(.96); } 
  to { opacity: 1; transform: translateY(0) scale(1); } 
}


/* =========================================================
   SAISIE VOCALE (Tri-mode + Zone Vocal)
   ========================================================= */
/* Les deux modes doivent être strictement identiques : même hauteur, même
   largeur, même fond, même icône. Seul l'état actif les distingue — auparavant
   l'un était gris et l'autre vert, ce qui laissait croire à deux boutons
   différents alors qu'ils font la même chose. */
.mode-btn {
  min-height: 56px;
  padding: 0 10px;
  font-size: calc(13px * var(--fs-scale));
  font-weight: 700;
  flex-direction: column;
  gap: 5px;
  background: var(--bg-2);
  border: 1px solid var(--line-2);
  color: var(--ink-2);
}
.mode-btn:hover { background: var(--bg-2); border-color: var(--ink-3); color: var(--ink); }
.mode-btn svg { width: 18px; height: 18px; }
.mode-btn.mode-actif {
  background: var(--gold-soft);
  border-color: var(--gold);
  color: var(--gold);
  box-shadow: 0 0 0 2px var(--gold-soft);
}
.mode-btn:active { transform: scale(.98); }


.nav-center-btn { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 1; }
.btn-accueil-top { display: flex; align-items: center; gap: 8px; padding: 10px 20px; background: var(--bg-2); border: 1px solid var(--line-2); border-radius: var(--r-pill); color: var(--ink); font-size: calc(13px * var(--fs-scale)); font-weight: 700; cursor: pointer; transition: all .25s var(--ease); -webkit-tap-highlight-color: transparent; white-space: nowrap; }
.btn-accueil-top:hover, .btn-accueil-top:active { color: var(--gold); border-color: var(--gold-3); background: var(--gold-soft); box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2); }
.btn-accueil-top svg { color: var(--gold); }


/* BOUTONS MICRO ET VOCAL */
.mode-saisie { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }


.note-row-mic { width: 44px; height: 44px; display: grid; place-items: center; background: var(--bg-2); border: 1px solid var(--line-2); border-radius: 12px; color: var(--ink-2); flex-shrink: 0; transition: all .2s var(--ease); cursor: pointer; }
.note-row-mic:hover { color: var(--gold); border-color: var(--gold-3); background: var(--gold-soft); }
/* Micro ouvert : couleur rouge fixe, sans animation (voir la fin de feuille). */
@keyframes micPulse { 0% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7); } 70% { box-shadow: 0 0 0 12px rgba(239, 68, 68, 0); } 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0); } }


.vocal-head { display: flex; align-items: center; gap: 14px; padding-bottom: 16px; border-bottom: 1px solid var(--line); margin-bottom: 14px; }
.vocal-icon { width: 52px; height: 52px; display: grid; place-items: center; background: linear-gradient(135deg, rgba(37, 211, 102, 0.2), rgba(16, 185, 129, 0.3)); color: var(--wa); border-radius: 14px; border: 1px solid rgba(37, 211, 102, 0.4); }
.vocal-title { font-size: calc(16px * var(--fs-scale)); font-weight: 800; color: var(--ink); margin: 0 0 4px; }
.vocal-sub { font-size: calc(12.5px * var(--fs-scale)); color: var(--ink-2); margin: 0; line-height: 1.4; }


.vocal-status { display: flex; align-items: center; gap: 10px; padding: 12px 16px; background: var(--bg-2); border: 1px solid var(--line-2); border-radius: var(--r-md); font-size: calc(13px * var(--fs-scale)); font-weight: 600; color: var(--ink-2); margin-bottom: 12px; }
.vocal-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--ink-3); flex-shrink: 0; transition: all .25s; }
.vocal-status.active .vocal-dot { background: var(--danger); box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7); animation: micPulse 1.1s infinite; }
.vocal-status.active { color: var(--ink); border-color: rgba(239, 68, 68, 0.4); }
.vocal-status.listening { border-color: rgba(37, 211, 102, 0.5); }
.vocal-status.listening .vocal-dot { background: var(--wa); }


.vocal-transcript { min-height: 60px; padding: 14px 16px; background: var(--bg); border: 1px dashed var(--line-2); border-radius: var(--r-md); font-size: calc(14px * var(--fs-scale)); color: var(--ink); font-weight: 500; line-height: 1.5; margin-bottom: 12px; max-height: 140px; overflow-y: auto; }
.vocal-transcript em { color: var(--ink-3); font-style: normal; }
.vocal-transcript .final { color: var(--ink); }
.vocal-transcript .interim { color: var(--gold); opacity: 0.85; }


.vocal-log { max-height: 200px; overflow-y: auto; margin-bottom: 14px; }
.vocal-log:empty { display: none; }
.vocal-log-item { display: flex; align-items: center; gap: 10px; padding: 10px 12px; background: var(--bg-2); border-radius: 10px; margin-bottom: 8px; font-size: calc(13px * var(--fs-scale)); animation: logIn .3s var(--ease); border-left: 3px solid var(--success); }
.vocal-log-item.warn { border-left-color: var(--gold); }
.vocal-log-item.err { border-left-color: var(--danger); }
.vocal-log-name { font-weight: 700; color: var(--ink); flex: 1; }
.vocal-log-note { font-weight: 800; color: var(--success); }
.vocal-log-item.warn .vocal-log-note { color: var(--gold); }
.vocal-log-item.err .vocal-log-note { color: var(--danger); }
@keyframes logIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: translateY(0); } }


/* Strictement la même taille que « Valider les notes » : deux actions de même
   importance ne doivent pas différer d'un pixel, encore moins de six. */
.vocal-big-btn {
  width: 100%;
  height: 50px;
  min-height: 50px;
  max-height: 50px;
  margin-top: 18px;
  padding: 0 20px;
  font-size: calc(14px * var(--fs-scale));
  font-weight: 700;
  border-radius: var(--r-md);
}
/* Bouton de dictée ouvert : couleur seule, sans animation. */

/* =========================================================
   BIENVENUE PRO (UNE SEULE FOIS)
   ========================================================= */
#dlgProBienvenue { text-align: center; padding: 34px 24px 26px; border-color: rgba(212, 175, 55, .45); background: radial-gradient(circle at 50% 0%, rgba(212, 175, 55, .18), transparent 48%), linear-gradient(180deg, #111827 0%, #0D152B 100%); }
#dlgProBienvenue .pro-welcome-badge { width: 78px; height: 78px; margin: 0 auto 8px; display: grid; place-items: center; color: #20170A; background: linear-gradient(135deg, #F7E7A6 0%, #D4AF37 55%, #A88B2C 100%); border-radius: 50%; box-shadow: 0 0 0 8px rgba(212, 175, 55, .12), 0 12px 34px rgba(212, 175, 55, .4); animation: homeProPulse 2.6s infinite alternate ease-in-out; }
#dlgProBienvenue h2 { border: 0; padding: 0; margin: 16px 0 12px; font-size: calc(25px * var(--fs-scale)); color: var(--gold); }
#dlgProBienvenue p { font-size: calc(15px * var(--fs-scale)); line-height: 1.6; color: var(--ink); margin: 0 0 24px; }
#dlgProBienvenue .pro-welcome-start { width: 100%; min-height: 54px; font-size: calc(16px * var(--fs-scale)); font-weight: 800; }

/* =========================================================
   MODALE PROFIL
   ========================================================= */


/* =========================================================
   ESPACE DE TRAVAIL, MENTIONS ET ÉVALUATIONS
   ========================================================= */

.workspace-overview { position: relative; overflow: hidden; padding: 20px; border: 1px solid rgba(212, 175, 55, .22); border-radius: var(--r-lg); background: linear-gradient(135deg, rgba(212, 175, 55, .09) 0%, rgba(17, 24, 39, .95) 45%, rgba(13, 21, 43, .98) 100%); box-shadow: var(--shadow-2); }
.workspace-overview::after { content: ""; position: absolute; width: 170px; height: 170px; right: -70px; top: -90px; border-radius: 50%; background: radial-gradient(circle, rgba(212, 175, 55, .18), transparent 68%); pointer-events: none; }
.overview-head { position: relative; z-index: 1; display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 16px; }
.overview-eyebrow { font-size: calc(9.5px * var(--fs-scale)); font-weight: 800; letter-spacing: .14em; color: var(--gold); }
.overview-state { display: inline-flex; align-items: center; gap: 6px; font-size: calc(11px * var(--fs-scale)); font-weight: 700; color: var(--success); }
.overview-state > span { width: 6px; height: 6px; border-radius: 50%; background: currentColor; box-shadow: 0 0 8px currentColor; }
.overview-main { position: relative; z-index: 1; display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.overview-identity { min-width: 0; }
.overview-identity h2 { display: block; margin: 0; padding: 0; border: 0; font-size: calc(25px * var(--fs-scale)); font-weight: 800; letter-spacing: -.03em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.overview-identity p { margin: 6px 0 0; color: var(--ink-2); font-size: calc(12.5px * var(--fs-scale)); }
.overview-divider { margin: 0 7px; color: var(--gold-3); }
.overview-actions { display: flex; flex-direction: column; gap: 8px; flex: 0 0 auto; }
.overview-actions .btn { width: auto; min-height: 44px; padding: 0 14px; font-size: calc(12px * var(--fs-scale)); white-space: nowrap; }
.overview-actions .btn + .btn { margin-top: 0; }
.overview-primary { color: #0A1633; border: 0; background: linear-gradient(135deg, var(--gold-2), var(--gold)); box-shadow: var(--shadow-gold); }
.overview-secondary { color: var(--ink-2); background: rgba(255,255,255,.03); border: 1px solid var(--line-2); }
.overview-metrics { position: relative; z-index: 1; display: grid; grid-template-columns: .8fr .8fr 1.5fr; gap: 12px; margin-top: 18px; padding-top: 15px; border-top: 1px solid rgba(255,255,255,.08); }
.overview-metric > span, .overview-completion > div:first-child > span { display: block; margin-bottom: 3px; color: var(--ink-3); font-size: calc(9px * var(--fs-scale)); font-weight: 800; letter-spacing: .1em; }
.overview-metric strong { font-size: calc(20px * var(--fs-scale)); line-height: 1.1; color: var(--ink); }
.overview-completion > div:first-child { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.overview-completion strong { font-size: calc(15px * var(--fs-scale)); color: var(--gold); }
.overview-progress { height: 6px; margin-top: 8px; border-radius: 999px; overflow: hidden; background: var(--bg-2); }
.overview-progress > span { display: block; width: 0; height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--gold-2), var(--gold)); transition: width .35s var(--ease); }

#evalsCheck { display: flex; flex-direction: column; gap: 9px; }
#evalsCheck .eval-check { display: flex; align-items: center; gap: 11px; margin: 0; padding: 12px 13px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--bg-2); color: var(--ink); font-size: calc(13.5px * var(--fs-scale)); font-weight: 600; cursor: pointer; }
#evalsCheck .eval-check:has(input:checked) { border-color: var(--gold-3); background: var(--gold-soft); }
#evalsCheck input[type="checkbox"] { width: 18px; height: 18px; margin: 0; flex: none; accent-color: var(--gold); }
#evalsCheck small { margin-left: auto; color: var(--ink-3); font-size: calc(11px * var(--fs-scale)); font-weight: 700; }
#mentions .mention-row { align-items: center; }
#mentions .mention-del { font-size: calc(13px * var(--fs-scale)); }
.inp:disabled, .btn:disabled { opacity: .45; cursor: not-allowed; }

@media (max-width: 480px) {
  .overview-main { flex-direction: column; }
  .overview-actions { flex-direction: row; width: 100%; }
  .overview-actions .btn { flex: 1; min-width: 0; }
  .overview-actions { flex-wrap: wrap; }
  .overview-actions .btn { white-space: normal; text-align: center; }
  .overview-metrics { grid-template-columns: 1fr 1fr; }
  .overview-completion { grid-column: 1 / -1; }
}


/* =========================================================
   BOUTON PRO SUR L'ACCUEIL
   ========================================================= */
#ecran-accueil .home-pro-btn {
  position: absolute;
  left: 50%;
  top: calc(50% + 78px);
  transform: translateX(-50%);
  z-index: 9;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 42px;
  padding: 0 20px;
  border: 1px solid rgba(255, 239, 180, .9);
  border-radius: 999px;
  color: #20170A;
  background: linear-gradient(135deg, #F7E7A6 0%, #D4AF37 52%, #A88B2C 100%);
  font-size: calc(13px * var(--fs-scale));
  font-weight: 800;
  letter-spacing: .2px;
  white-space: nowrap;
  cursor: pointer;
  box-shadow: 0 0 0 1px rgba(212, 175, 55, .2), 0 8px 24px rgba(212, 175, 55, .4), inset 0 1px 0 rgba(255, 255, 255, .55);
  animation: homeProPulse 2.6s infinite alternate ease-in-out;
  transition: opacity .28s ease, transform .28s ease, box-shadow .28s ease;
}
#ecran-accueil .home-pro-btn[hidden] { display: none !important; }
#ecran-accueil .home-pro-btn svg { color: #20170A; flex: none; }
#ecran-accueil .home-pro-btn:hover,
#ecran-accueil .home-pro-btn:focus-visible {
  transform: translateX(-50%) translateY(-1px) scale(1.03);
  box-shadow: 0 0 0 1px rgba(255, 239, 180, .55), 0 10px 32px rgba(212, 175, 55, .55), inset 0 1px 0 rgba(255, 255, 255, .7);
}
#ecran-accueil .home-pro-btn.actif {
  color: #052E1F;
  border-color: rgba(167, 243, 208, .9);
  background: linear-gradient(135deg, #A7F3D0 0%, #34D399 52%, #10B981 100%);
  animation: none;
}
#ecran-accueil .quick-card.menu-open .home-pro-btn {
  opacity: 0;
  transform: translateX(-50%) scale(.86);
  pointer-events: none;
}
@keyframes homeProPulse {
  0% { box-shadow: 0 0 0 1px rgba(212, 175, 55, .15), 0 6px 18px rgba(212, 175, 55, .28), inset 0 1px 0 rgba(255, 255, 255, .5); }
  100% { box-shadow: 0 0 0 1px rgba(255, 239, 180, .5), 0 10px 32px rgba(212, 175, 55, .58), inset 0 1px 0 rgba(255, 255, 255, .7); }
}
@media (prefers-reduced-motion: reduce) {
  #ecran-accueil .home-pro-btn { animation: none; }
}

/* Photo de profil */


/* ==========================================================
   GESTION DES ÉLÈVES — actions (modifier / supprimer)
   ========================================================== */
#listeEleves .eleve-actions { display: flex; align-items: center; gap: 6px; flex: none; }
#listeEleves button[data-act="modif"]:hover { color: var(--gold); background: var(--gold-soft); }
#listeEleves > * > :first-child,
#listeNotes > * > :first-child { overflow-wrap: anywhere; line-height: 1.3; }
#listeEleves button:disabled,
#listeNotes .note-input:disabled { opacity: .45; cursor: not-allowed; }


/* ==========================================================
   DIALOGUE « MODIFIER L'ÉLÈVE »
   ========================================================== */
#dlgModifierEleve { max-width: 360px; }
#dlgModifierEleve label { display: block; margin-bottom: 6px; font-size: calc(13px * var(--fs-scale)); font-weight: 700; color: var(--ink-2); }
#dlgModifierEleve label .petit { font-weight: 500; margin: 0; }
#dlgModifierEleve .inp { margin-bottom: 4px; }


/* ==========================================================
   BANDEAU HORS LIGNE
   ========================================================== */
.bandeau-hors-ligne {
  position: fixed;
  left: 0; right: 0; top: var(--nav-height);
  z-index: 98;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  padding: 8px 16px;
  font-size: calc(12px * var(--fs-scale));
  font-weight: 700;
  color: #FDE68A;
  background: rgba(120, 53, 15, .92);
  border-bottom: 1px solid rgba(212, 175, 55, .45);
  text-align: center;
}
.bandeau-hors-ligne span { line-height: 1.3; }


/* ==========================================================
   BLOC D'ACTIONS DU CLASSEMENT (PDF + réinitialisation)
   Séparé de la carte « Répartition », en bas de l'écran.
   ========================================================== */
.actions-classement {
  margin-top: 36px;
  padding: 22px 20px 18px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
  position: relative;
}
.actions-classement::before {
  content: "";
  position: absolute;
  left: 0; top: 22px; bottom: 22px;
  width: 3px;
  background: linear-gradient(180deg, var(--gold) 0%, transparent 100%);
  border-radius: 0 3px 3px 0;
}
.actions-classement .btn {
  min-height: 56px;
  font-size: calc(15px * var(--fs-scale));
  letter-spacing: .01em;
}
.actions-classement .btn + .btn { margin-top: 14px; }

/* Bouton PDF : mis en avant, bien détaché de la répartition. */
.btn-pdf {
  box-shadow: 0 8px 22px rgba(212, 175, 55, .35);
}
.btn-pdf:hover {
  box-shadow: 0 10px 28px rgba(212, 175, 55, .55);
  transform: translateY(-1px);
}

/* Bouton destructif : rouge plein, impossible à manquer. */
.btn-danger {
  color: #FFF;
  border: none;
  background: linear-gradient(135deg, #EF4444 0%, #B91C1C 100%);
  box-shadow: 0 8px 20px rgba(239, 68, 68, .38);
}
.btn-danger:hover {
  background: linear-gradient(135deg, #F87171 0%, #DC2626 100%);
  box-shadow: 0 10px 26px rgba(239, 68, 68, .55);
}
.btn-danger:active { transform: scale(.98); }

.actions-note {
  margin: 14px 0 0;
  text-align: center;
  line-height: 1.45;
}

/* Champ bonus : le signe est mis en avant pour qu'on lise « +1 » d'un coup d'œil. */
.bonus-inp {
  font-weight: 800;
  letter-spacing: .04em;
  font-variant-numeric: tabular-nums;
  text-align: left;
}

/* ==========================================================
   BLOC STATISTIQUES DU CLASSEMENT
   Le bloc respire : ni collé à la carte « Paramètres » au-dessus,
   ni collé à la carte « Classement » en dessous.
   ========================================================== */
.stats {
  margin: 0;
  gap: 16px;
}
/* Les tuiles sont maintenant à l'intérieur d'une carte : on les distingue
   du fond de la carte au lieu de les fondre dedans. */
.carte .stats > * {
  background: var(--bg-2);
  border-color: var(--line-2);
}

/* ==========================================================
   EN-TÊTE D'ÉCRAN CENTRÉ (titre + sous-titre)
   Aligné sur la présentation de l'écran « Saisie des notes ».
   ========================================================== */
.ecran-titre-centre {
  text-align: center;
  margin-bottom: 26px;
}
.ecran-titre-centre h1 { text-align: center; }
.ecran-titre-centre .sous {
  margin-top: 8px;
  padding-bottom: 0;
  border-bottom: none;
  text-align: center;
  line-height: 1.45;
}


/* Conteneur des bandeaux d'information (hors ligne). */
.bandeaux {
  position: fixed;
  left: 0; right: 0; top: var(--nav-height);
  z-index: 98;
  display: flex;
  flex-direction: column;
}
.bandeaux .bandeau-hors-ligne {
  position: static;
  top: auto;
  z-index: auto;
}

/* Un champ verrouillé se voit : curseur interdit + teinte atténuée. */
.classe-verrouillee input:disabled,
.classe-verrouillee textarea:disabled,
.classe-verrouillee select:disabled {
  cursor: not-allowed;
  opacity: .6;
}


/* ==========================================================
   CLASSE VERROUILLÉE — TOUT EST GRISÉ SAUF « DÉVERROUILLER »
   On grise chaque contrôle, jamais la carte qui le contient :
   c'est ce qui permet au bouton de déverrouillage de rester net.
   ========================================================== */
.classe-verrouillee select:disabled,
.classe-verrouillee textarea:disabled,
.classe-verrouillee input:disabled,
.classe-verrouillee button:disabled {
  opacity: .38;
  cursor: not-allowed;
  filter: grayscale(1);
  box-shadow: none;
  transform: none;
}

/* Boutons ronds de la liste (crayon, corbeille, micro). */
.classe-verrouillee #listeEleves button:disabled,
.classe-verrouillee .note-row-mic:disabled {
  opacity: .3;
  filter: grayscale(1);
}

/* Champs de notes : lecture seule évidente, mais LISIBLE. Une classe verrouillée
   sert à relire ses notes avant le conseil : elles ne doivent pas devenir
   grises au point d'être illisibles. */
.classe-verrouillee .note-input:disabled {
  background: var(--bg-2);
  color: var(--ink);
  border-style: dashed;
  opacity: 1;
  filter: none;
  font-weight: 700;
}

/* Les tuiles de statistiques et les barres restent lisibles
   (ce sont des affichages, pas des contrôles). */
.classe-verrouillee .stats > * { opacity: 1; }
.classe-verrouillee #repartitionMentions .rep-remplissage { opacity: .85; }

/* Le bouton de déverrouillage garde toute sa présence. */
.classe-verrouillee #btnVerrouiller {
  opacity: 1;
  filter: none;
  box-shadow: var(--shadow-gold);
}


/* ==========================================================
   BOUTON « VALIDER LES NOTES » — état validé
   ========================================================== */
.btn-valide {
  color: #04240F;
  border: none;
  background: linear-gradient(135deg, #34D399 0%, #10B981 100%);
  box-shadow: 0 8px 20px rgba(16, 185, 129, .35);
  cursor: default;
}
.btn-valide:hover {
  background: linear-gradient(135deg, #34D399 0%, #10B981 100%);
}

/* Avertissement de modifications non validées, sous le bouton de validation. */
#notesBrouillonInfo {
  margin: 12px 0 0;
  padding: 10px 12px;
  font-size: calc(12.5px * var(--fs-scale));
  font-weight: 700;
  line-height: 1.4;
  text-align: center;
  color: #FDE68A;
  background: rgba(120, 53, 15, .55);
  border: 1px solid rgba(212, 175, 55, .35);
  border-radius: var(--r-md);
}


/* ==========================================================
   BOUTON DE VERROUILLAGE — COULEUR GARANTIE
   On ne compte plus sur la présence des classes .btn-p / .btn-r :
   l'apparence est attachée à l'identifiant, donc impossible à perdre.
   Sans classe .btn-r -> jaune doré ; avec .btn-r -> rouge plein.
   ========================================================== */
#btnVerrouiller {
  opacity: 1 !important;
  filter: none !important;
  transition: background .25s var(--ease), box-shadow .25s var(--ease);
}
#btnVerrouiller:not(.btn-r) {
  color: #0A1633;
  border: none;
  background: linear-gradient(135deg, var(--gold-2) 0%, var(--gold) 55%, var(--gold-3) 100%);
  box-shadow: var(--shadow-gold);
}
#btnVerrouiller.btn-r {
  color: #FFF;
  border: none;
  background: linear-gradient(135deg, #EF4444 0%, #B91C1C 100%);
  box-shadow: 0 6px 18px rgba(239, 68, 68, .38);
}

/* Offre unique : la carte de prix occupe toute la largeur. */
.prix.prix-unique { grid-template-columns: 1fr; }
.prix.prix-unique > div { background: var(--gold-soft); border-color: var(--gold-3); padding: 20px; }


/* ==========================================================
   FÉLICITATIONS PRO — centrage, confettis, apparition du bouton
   ========================================================== */
.dlg-pro-bienvenue {
  text-align: center;
  position: relative;
  overflow: hidden;
  padding: 34px 26px 26px !important;
}
.dlg-pro-bienvenue h2 {
  /* le h2 global est en display:flex : sans ceci, text-align ne centre rien */
  display: block;
  justify-content: center;
  margin: 0 0 10px;
  padding: 0;
  border: 0;
  text-align: center;
  font-size: calc(23px * var(--fs-scale));
  font-weight: 800;
  color: var(--gold);
  letter-spacing: -.01em;
}
.dlg-pro-bienvenue p {
  margin: 0 auto 22px;
  max-width: 34ch;
  text-align: center;
  line-height: 1.5;
  color: var(--ink-2);
}

/* Zone des confettis : au-dessus du contenu, sans intercepter les clics. */
.confettis {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 2;
}
.confetti {
  position: absolute;
  top: -14px;
  width: 8px;
  height: 12px;
  border-radius: 2px;
  opacity: 0;
  animation: confettiChute linear forwards;
  will-change: transform, opacity;
}
@keyframes confettiChute {
  0%   { opacity: 0; transform: translate3d(0, -10px, 0) rotate(0deg); }
  12%  { opacity: 1; }
  100% { opacity: 0; transform: translate3d(var(--derive, 0px), 340px, 0) rotate(var(--rotation, 540deg)); }
}

/* Le bouton reste visible même si l'animation ne se déclenche pas : sinon la
   fenêtre de félicitations devient un cul-de-sac (aucune autre sortie sur
   téléphone). L'animation ne fait que l'accompagner. */
.pro-welcome-start {
  opacity: 0;
  transform: translateY(14px) scale(.94);
  pointer-events: none;
  transition: opacity .25s var(--ease);
}
.pro-welcome-start.pret {
  opacity: 1;
  transform: none;
  pointer-events: auto;
  animation: commencerBounce .62s cubic-bezier(.2, 1.6, .4, 1) both;
}
@keyframes commencerBounce {
  0%   { transform: translateY(16px) scale(.86); }
  55%  { transform: translateY(-4px) scale(1.04); }
  75%  { transform: translateY(2px) scale(.99); }
  100% { transform: translateY(0) scale(1); }
}

/* Respect des préférences d'accessibilité : pas d'effet, bouton direct. */
@media (prefers-reduced-motion: reduce) {
  .confetti { display: none; }
  .pro-welcome-start { opacity: 1; transform: none; pointer-events: auto; animation: none; }
}


/* ==========================================================
   BOUTON DE DÉFILEMENT RAPIDE (Classement · Saisie des notes)
   Juste une flèche, rien d'autre : pas de pastille, pas de cadre.
   Seul le flou d'arrière-plan la détache du texte qu'elle survole.
   ========================================================== */
.btn-defilement {
  position: fixed;
  width: 44px;
  height: 44px;
  right: 8px;
  bottom: calc(14px + var(--safe-b));
  z-index: 90;
  /* Zone tactile confortable (44 px) alors que le dessin reste minuscule. */
  display: grid;
  place-items: center;
  padding: 0;
  color: var(--gold);
  background: transparent;
  border: 0;
  border-radius: 50%;
  box-shadow: none;
  /* Le flou seul crée le détachement, sans ajouter de forme visible. */
  backdrop-filter: blur(12px) saturate(1.15);
  -webkit-backdrop-filter: blur(12px) saturate(1.15);
  opacity: .55;
  cursor: pointer;
  transition: opacity .2s var(--ease), transform .2s var(--ease);
  -webkit-tap-highlight-color: transparent;
}
.btn-defilement svg {
  /* Ombre portée : lisible même sur une note claire ou une ligne colorée. */
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .85)) drop-shadow(0 0 7px rgba(0, 0, 0, .55));
}
.btn-defilement:active { transform: scale(.88); opacity: 1; }
.btn-defilement:hover { opacity: .95; }
.btn-defilement[hidden] { display: none; }

/* Informations de licence : numéro et code de récupération bien lisibles. */
#licenceInfo b { color: var(--gold); }
#licenceInfo .code-recup {
  font-family: ui-monospace, monospace;
  font-size: calc(15px * var(--fs-scale));
  letter-spacing: .12em;
  color: var(--gold);
}


/* =========================================================
   RÉGLAGES D'ACCESSIBILITÉ DU TÉLÉPHONE
   Une personne sensible au mouvement, ou un appareil modeste, doit pouvoir
   couper les animations : elles ne doivent jamais gêner l'usage.
   ========================================================= */
/* Respect global */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}




/* Le bandeau « hors ligne » est fixe sous l'en-tête : sans cette réserve, il
   recouvrait le titre de l'écran. */
body.bandeau-actif { padding-top: calc(var(--nav-height) + 34px); }
/* Notification rattachée à une fenêtre ouverte : elle doit rester dans le cadre. */
dialog .toast { position: fixed; left: 50%; bottom: 24px; }


/* =========================================================
   MODALE PROFIL — CENTRAGE
   Auparavant forcé depuis le JavaScript avec « !important ».
   ========================================================= */
.dlg-profil { text-align: center; }
.dlg-profil h2#profilTitre { display: block; width: 100%; text-align: center; padding: 0; border: 0; }
.dlg-profil .profil-intro { display: block; width: 100%; text-align: center; }
.dlg-profil .profil-form { text-align: left; }


/* =========================================================
   FENÊTRE DE MESSAGE
   Remplace les alert() natifs : même style que le reste de
   l'application, message lisible et copiable.
   ========================================================= */
.dlg-message { text-align: center; }
.dlg-message h2 { display: block; text-align: center; }
.dlg-message p { text-align: center; line-height: 1.6; margin: 0 0 20px; }
.dlg-message .btn { width: 100%; }

/* Le bouton Enregistrer du profil reste visible quand un champ manque : il
   passe simplement en gris, puis redevient doré dès que tout est rempli. */
.btn-profil-valider:disabled {
  color: #4B5563;
  background: linear-gradient(135deg, #374151 0%, #1F2937 100%);
  box-shadow: none;
  opacity: 1;
  cursor: not-allowed;
  transform: none;
}
.btn-profil-valider:disabled:hover { transform: none; box-shadow: none; }




/* =========================================================
   ICÔNE EN HAUT DE CHAQUE ÉCRAN
   Rappelle d'un coup d'œil sur quel écran on se trouve.
   ========================================================= */
.ecran-icone {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 64px;
  height: 64px;
  margin: 0 auto 14px;
  color: var(--gold);
  background: var(--gold-soft);
  border: 1px solid rgba(212, 175, 55, .25);
  border-radius: 50%;
  box-shadow: 0 6px 18px rgba(212, 175, 55, .12);
}
.ecran-icone svg { width: 34px; height: 34px; }

/* =========================================================
   ÉCRAN CLASSES — BOUTONS DE LA LISTE ET DES MENTIONS
   ========================================================= */

/* Ajouter une mention / Mentions par défaut : visibles, même poids. */
.btn-mention {
  min-height: 44px;
  font-size: calc(13px * var(--fs-scale));
  font-weight: 700;
  color: var(--gold);
  background: var(--gold-soft);
  border: 1px solid rgba(212, 175, 55, .4);
  opacity: 1;
}
.btn-mention:hover { background: rgba(212, 175, 55, .24); border-color: var(--gold); }

/* L'aperçu « Saisir les notes » : icône collée au texte. */
.overview-actions .btn { gap: 6px; }

/* Le bouton Paramètres pointe sur l'en-tête, sous la barre fixe. */
#classSettings { scroll-margin-top: calc(var(--nav-height) + 14px); }

/* =========================================================
   ÉLÈVES : BOUTON EN HAUT, EFFECTIF EN BAS
   ========================================================= */
.ajouter-eleves { margin-bottom: 16px; }


/* =========================================================
   MENTIONS EN TABLEAU CLAIR
   Chaque mention est une fiche : son nom en haut, en entier,
   puis sa règle de calcul écrite en clair.
   ========================================================= */
#mentions { display: flex; flex-direction: column; gap: 10px; }

#mentions .mention-row {
  padding: 12px 14px;
  background: var(--bg-2);
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
}

#mentions .mention-tete {
  display: grid;
  grid-template-columns: 12px minmax(0, 1fr) 40px;
  align-items: center;
  gap: 10px;
}

#mentions .mention-puce {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  box-shadow: 0 0 0 3px rgba(255, 255, 255, .05);
}

/* Le nom de la mention se lit en entier : plus de coupure. */
#mentions .mention-label {
  width: 100%;
  min-width: 0;
  height: 42px;
  padding: 0 12px;
  font-size: calc(14px * var(--fs-scale));
  font-weight: 700;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: 10px;
}

#mentions .mention-regle {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
  padding-left: 22px;
  font-size: calc(12px * var(--fs-scale));
  color: var(--ink-2);
}

#mentions .mention-regle input {
  width: 58px;
  height: 36px;
  padding: 0 8px;
  text-align: center;
  font-size: calc(13px * var(--fs-scale));
  font-weight: 700;
  color: var(--gold);
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: 8px;
}

#mentions .mention-regle input:focus {
  outline: none;
  border-color: var(--gold);
  box-shadow: 0 0 0 3px var(--gold-soft);
}

#mentions .mention-sur { color: var(--ink-3); font-weight: 700; }

#mentions .mention-del {
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  font-size: calc(15px * var(--fs-scale));
  color: var(--ink-3);
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: 10px;
  transition: background .18s var(--ease), color .18s var(--ease), border-color .18s var(--ease);
}
#mentions .mention-del:hover { color: var(--ink); background: var(--bg-2); border-color: var(--ink-3); }

/* Le bouton « Mentions par défaut » doit s'enfoncer au clic, comme les autres. */
/* Les boutons de mentions restent identiques au clic : seule la liste change
   à l'écran. Pas d'enfoncement, pas de changement de teinte. */
.btn-mention,
.btn-mention:hover,
.btn-mention:active,
.btn-mention:focus,
.btn-mention:focus-visible {
  transform: none;
  box-shadow: none;
  background: var(--gold-soft);
  border-color: rgba(212, 175, 55, .4);
  color: var(--gold);
}

/* =========================================================
   MENTION INVALIDE : SIGNALEMENT EN DIRECT
   ========================================================= */
#mentions .mention-invalide {
  border-color: var(--danger);
  background: var(--danger-soft);
}
#mentions .mention-invalide .mention-regle input {
  border-color: var(--danger);
  color: var(--danger);
}

#mentions .mention-erreur {
  margin: 8px 0 0;
  padding-left: 22px;
  font-size: calc(12px * var(--fs-scale));
  font-weight: 700;
  line-height: 1.4;
  color: var(--danger);
}

/* =========================================================
   ÉVALUATIONS PRISES EN COMPTE : CADRE DYNAMIQUE
   La case native disparaît, tout le cadre montre l'état choisi.
   ========================================================= */
#evalsCheck .eval-check {
  position: relative;
  padding: 14px 14px 14px 46px;
  border: 1.5px solid var(--line-2);
  border-radius: var(--r-md);
  background: var(--bg-2);
  transition: border-color .18s var(--ease), background .18s var(--ease);
}
#evalsCheck .eval-check input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  pointer-events: none;
}
#evalsCheck .eval-pivot {
  position: absolute;
  left: 14px;
  top: 50%;
  width: 22px;
  height: 22px;
  margin-top: -11px;
  border-radius: 7px;
  border: 2px solid var(--ink-3);
  background: transparent;
  transition: all .18s var(--ease);
}
#evalsCheck .eval-pivot::after {
  content: "";
  position: absolute;
  left: 6px;
  top: 2px;
  width: 6px;
  height: 11px;
  border: solid #0A1633;
  border-width: 0 2.5px 2.5px 0;
  transform: rotate(45deg) scale(0);
  transition: transform .18s var(--ease);
}
#evalsCheck .eval-check.actif {
  border-color: var(--gold);
  background: var(--gold-soft);
}
#evalsCheck .eval-check.actif .eval-pivot {
  border-color: var(--gold);
  background: var(--gold);
}
#evalsCheck .eval-check.actif .eval-pivot::after { transform: rotate(45deg) scale(1); }
#evalsCheck .eval-check:active { transform: none; }
#evalsCheck .eval-nom { font-weight: 700; color: var(--ink); }
#evalsCheck .eval-check.actif .eval-nom { color: var(--gold); }

/* =========================================================
   DICTÉE DE LA LISTE DES ÉLÈVES
   Le micro est posé juste au-dessus de la zone des noms.
   ========================================================= */
.btn-dicter {
  width: 100%;
  min-height: 46px;
  margin-bottom: 10px;
  font-size: calc(13.5px * var(--fs-scale));
  font-weight: 700;
  color: var(--gold);
  background: var(--gold-soft);
  border: 1.5px dashed rgba(212, 175, 55, .5);
}
.btn-dicter:hover { background: rgba(212, 175, 55, .22); }
.btn-dicter.btn-valide {
  color: #04240F;
  background: linear-gradient(135deg, #34D399 0%, #10B981 100%);
  border-style: solid;
  border-color: var(--success);
  box-shadow: 0 8px 20px rgba(16, 185, 129, .3);
}

/* Les deux modes de saisie gardent exactement la même hauteur. */
.mode-saisie { grid-template-columns: 1fr 1fr; }
.mode-saisie .mode-btn {
  height: 56px;
  min-height: 56px;
  max-height: 56px;
  padding: 0 10px;
  font-size: calc(13px * var(--fs-scale));
  font-weight: 700;
}

/* =========================================================
   ERREURS DE LA LISTE D'ÉLÈVES
   Même langage que les mentions : un cadre rouge et une phrase
   qui dit précisément quelle ligne pose problème.
   ========================================================= */
.liste-erreurs {
  margin: 10px 0 0;
  padding: 12px 14px;
  font-size: calc(12.5px * var(--fs-scale));
  font-weight: 700;
  line-height: 1.5;
  color: var(--danger);
  background: var(--danger-soft);
  border: 1.5px solid rgba(239, 68, 68, .55);
  border-left-width: 4px;
  border-radius: var(--r-md);
}
#bulkEleves[aria-invalid="true"] {
  border-color: var(--danger);
  box-shadow: 0 0 0 3px var(--danger-soft);
}


/* =========================================================
   MODES DE SAISIE : ALIGNEMENT STRICT
   Les deux boutons ont exactement la même structure interne :
   une icône de 18 px, puis une étiquette de même hauteur de
   ligne. Rien ne peut plus se décaler d'un bouton à l'autre.
   ========================================================= */
.mode-saisie {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  align-items: stretch;
}
.mode-saisie .mode-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 58px;
  min-height: 58px;
  max-height: 58px;
  padding: 0 8px;
  line-height: 1;
}
.mode-saisie .mode-btn .mode-icone {
  display: block;
  width: 18px;
  height: 18px;
  flex: none;
}
.mode-saisie .mode-btn .mode-libelle {
  display: block;
  height: 14px;
  line-height: 14px;
  font-size: calc(13px * var(--fs-scale));
  font-weight: 700;
  white-space: nowrap;
}


/* =========================================================
   MODES DE SAISIE — ALIGNEMENT DÉFINITIF (ne pas déplacer)
   Les deux boutons occupent la même boîte, côte à côte, et leur
   contenu est centré de la même manière. Aucune autre règle de
   la feuille ne peut modifier ces valeurs.
   ========================================================= */
.mode-saisie {
  display: flex !important;
  flex-direction: row !important;
  flex-wrap: nowrap !important;
  align-items: stretch !important;
  gap: 10px !important;
  width: 100% !important;
}
.mode-saisie .mode-btn {
  flex: 1 1 0 !important;
  min-width: 0 !important;
  display: flex !important;
  flex-direction: column !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 6px !important;
  height: 58px !important;
  min-height: 58px !important;
  max-height: 58px !important;
  margin: 0 !important;
  padding: 0 6px !important;
  line-height: 1 !important;
  vertical-align: middle !important;
  transform: none !important;
}
.mode-saisie .mode-btn .mode-icone,
.mode-saisie .mode-btn svg {
  display: block !important;
  width: 18px !important;
  height: 18px !important;
  margin: 0 !important;
  flex: none !important;
  vertical-align: middle !important;
}
.mode-saisie .mode-btn .mode-libelle {
  display: block !important;
  margin: 0 !important;
  padding: 0 !important;
  height: 15px !important;
  line-height: 15px !important;
  font-size: calc(13px * var(--fs-scale)) !important;
  font-weight: 700 !important;
  white-space: nowrap !important;
}

/* Le bouton « Valider les notes » reste visible quand une note est invalide :
   il est grisé, comme « Enregistrer » dans le profil. */
#btnValiderSaisieManuelle:disabled {
  opacity: 1;
  color: #4B5563;
  background: linear-gradient(135deg, #374151 0%, #1F2937 100%);
  box-shadow: none;
  cursor: not-allowed;
  transform: none;
}

/* Une valeur incorrecte s'écrit en rouge, dans le champ, sans cadre ni texte. */
#listeNotes .note-input.note-invalide {
  color: var(--danger);
  border-color: var(--line-2);
  background: var(--bg-2);
  box-shadow: none;
}


/* =========================================================
   CONFIRMATION AVANT SUPPRESSION
   Un cadre doré, aux couleurs de NoteScan, qui évite les
   suppressions accidentelles.
   ========================================================= */
.dlg-confirm {
  text-align: center;
  border: 1.5px solid rgba(212, 175, 55, .55);
  background: radial-gradient(circle at 50% 0%, rgba(212, 175, 55, .12), transparent 55%), linear-gradient(180deg, #131C33 0%, #0D152B 100%);
}
.dlg-confirm .confirm-icone {
  width: 62px;
  height: 62px;
  margin: 0 auto 14px;
  display: grid;
  place-items: center;
  color: var(--gold);
  background: var(--gold-soft);
  border: 1px solid rgba(212, 175, 55, .35);
  border-radius: 50%;
}
.dlg-confirm h2 {
  display: block;
  text-align: center;
  padding: 0;
  border: 0;
  margin: 0 0 10px;
  font-size: calc(19px * var(--fs-scale));
  color: var(--gold);
}
.dlg-confirm p {
  text-align: center;
  line-height: 1.55;
  margin: 0 0 20px;
  color: var(--ink-2);
}
.dlg-confirm .btn-r { min-height: 50px; font-weight: 800; }
.dlg-confirm .btn-s { min-height: 50px; }

/* Le bouton de dictée grisé garde son aspect lisible quand la classe est verrouillée. */
#btnDicterEleves:disabled {
  opacity: 1;
  color: #4B5563;
  background: linear-gradient(135deg, #374151 0%, #1F2937 100%);
  border: 1.5px solid var(--line-2);
  border-style: solid;
  box-shadow: none;
  cursor: not-allowed;
}


/* =========================================================
   PHOTO DE PROFIL — UN ROND CLIQUABLE, RIEN DE PLUS
   ========================================================= */
.profil-avatar-wrap {
  display: flex;
  justify-content: center;
  margin-bottom: 18px;
}
.profil-avatar {
  position: relative;
  width: 96px;
  height: 96px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  color: var(--gold);
  background: linear-gradient(135deg, rgba(212, 175, 55, .16) 0%, rgba(212, 175, 55, .28) 100%);
  border: 1.5px solid rgba(212, 175, 55, .45);
  border-radius: 50%;
  box-shadow: 0 0 26px rgba(212, 175, 55, .18), inset 0 0 16px rgba(212, 175, 55, .1);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .18s var(--ease), box-shadow .18s var(--ease);
}
.profil-avatar:active { transform: scale(.97); }
.profil-avatar-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;                /* la photo remplit tout le rond */
  object-position: center top;      /* on montre le haut : la tête entière */
  border-radius: 50%;
  display: block;
}
.profil-avatar-img[hidden],
.profil-avatar-icon[hidden] { display: none !important; }

/* Rappel du format attendu, aligné à droite sous le champ. */
.profil-hint {
  margin: 8px 0 0;
  font-size: calc(12px * var(--fs-scale));
  font-weight: 500;
  text-align: right;
  color: var(--ink-3);
}


/* PHOTO : FOND DU ROND
   Si la photo n'a pas la forme du rond, les bandes prennent la couleur du
   fond de l'application : elles se voient à peine. */
.profil-avatar { background-color: var(--bg-2); }

/* =========================================================
   FENÊTRE OUVERTE : LE FOND EST FIGÉ
   Aucun défilement de la page derrière, sur aucun navigateur.
   ========================================================= */
html.modal-open,
body.modal-open {
  overflow: hidden !important;
  overscroll-behavior: none;
  touch-action: none;
  /* Pas de « height: 100% » ici : cette hauteur forcée faisait perdre la
     position de défilement. À la fermeture, la page revenait en haut — on
     avait l'impression de « partir ailleurs » après un simple Annuler. */
}
/* La fenêtre elle-même garde son propre défilement si son contenu est long. */
dialog[open] {
  touch-action: auto;
  overscroll-behavior: contain;
}

/* En-tête de saisie : titre et compteur alignés, sans décalage. */
#zoneSaisieManuelle .notes-titre,
.notes-titre {
  font-size: calc(14px * var(--fs-scale));
  font-weight: 700;
  color: var(--ink);
}
.notes-compte {
  font-size: calc(12.5px * var(--fs-scale));
  font-weight: 700;
  color: var(--ink-3);
  white-space: nowrap;
}

/* Les deux sélecteurs (classe et évaluation) partagent exactement la même
   allure : nom à gauche, flèche à droite. */
.select-custom {
  justify-content: space-between;
  gap: 12px;
}
.select-custom > span:first-child,
.select-custom #labelSelectClasse,
.select-custom #labelSelectEval {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: left;
}
.select-custom svg {
  flex: 0 0 auto;
  margin-left: auto;
}

/* ==========================================================================
   ACCUEIL — le bandeau hors ligne ne décale plus la carte
   --------------------------------------------------------------------------
   L'accueil n'affiche ni barre du haut ni marge de corps (règle
   « body.accueil-actif { padding: 0 } ») : les 34 px réservés pour le bandeau
   s'ajoutaient donc par-dessus et poussaient la carte vers le bas.
   Le bandeau reste fixé au-dessus de l'écran : il flotte, il ne déplace rien.
   ========================================================================== */
body.accueil-actif.bandeau-actif { padding: 0; }

/* ==========================================================================
   PROFIL — la fiche se réveille
   --------------------------------------------------------------------------
   Aucun élément nouveau, aucun déplacement : uniquement des états qui
   répondent au doigt et à la saisie. Chaque règle est limitée à #dlgProfil,
   donc rien d'autre dans l'application ne peut être touché par erreur.
   ========================================================================== */

/* Ouverture de la fiche : elle se pose, elle ne surgit pas. */
#dlgProfil[open] {
  animation: profilIn .28s cubic-bezier(.2, .9, .25, 1.1) both;
}
@keyframes profilIn {
  from { opacity: 0; transform: translateY(14px) scale(.975); }
  to   { opacity: 1; transform: none; }
}

/* Le rond photo respire tant qu'aucune photo n'est choisie : une invitation,
   pas un clignotement. */
#dlgProfil .profil-avatar.sans-photo {
  animation: anneauProfil 3.4s ease-in-out infinite;
}
@keyframes anneauProfil {
  0%, 100% { box-shadow: 0 0 20px rgba(212, 175, 55, .16), inset 0 0 16px rgba(212, 175, 55, .10); }
  50%      { box-shadow: 0 0 34px rgba(212, 175, 55, .34), inset 0 0 22px rgba(212, 175, 55, .20); }
}
#dlgProfil .profil-avatar:hover {
  transform: scale(1.03);
  border-color: rgba(212, 175, 55, .75);
}
#dlgProfil .profil-avatar:active { transform: scale(.96); }

/* Étiquette du champ en cours de saisie : elle passe en or, son icône aussi. */
#dlgProfil .profil-label { transition: color .2s var(--ease); }
#dlgProfil .profil-label.actif { color: var(--gold); }
#dlgProfil .profil-label.actif svg {
  opacity: 1;
  filter: drop-shadow(0 0 6px rgba(212, 175, 55, .55));
}

/* Champ rempli : un filet d'or sur le bord gauche, discret, qui confirme
   d'un coup d'œil ce qui est déjà renseigné. */
#dlgProfil .profil-form .inp {
  transition: border-color .2s var(--ease), box-shadow .25s var(--ease),
              background .2s var(--ease);
}
#dlgProfil .profil-form .inp.rempli {
  border-color: rgba(212, 175, 55, .40);
  box-shadow: inset 3px 0 0 rgba(212, 175, 55, .55);
}
#dlgProfil .profil-form .inp.rempli:focus {
  border-color: var(--gold);
  box-shadow: inset 3px 0 0 var(--gold-2), 0 0 0 3px rgba(212, 175, 55, .16);
}

/* Bouton Enregistrer : il s'allume quand la fiche est complète. */
#dlgProfil .btn-profil-valider.pret {
  box-shadow: 0 10px 30px rgba(212, 175, 55, .45), inset 0 0 0 1px rgba(255, 248, 220, .35);
}
#dlgProfil .btn-profil-valider.pret:active { transform: scale(.98); }

@media (prefers-reduced-motion: reduce) {
  #dlgProfil[open],
  #dlgProfil .profil-avatar.sans-photo { animation: none !important; }
}

/* ==========================================================================
   PROFIL — jeu complet d'états (repos, survol, saisie, rempli, erreur, bloqué)
   Toutes les règles sont préfixées #dlgProfil : elles ne peuvent pas déteindre
   sur le reste de l'application.
   ========================================================================== */

/* Survol à la souris (téléphone : jamais déclenché, donc aucun effet parasite). */
#dlgProfil .profil-form .inp:hover:not(:focus):not(:disabled):not(.erreur) {
  border-color: rgba(212, 175, 55, .35);
}

/* Erreur : champ rouge, filet rouge, et courte secousse quand elle apparaît. */
#dlgProfil .profil-form .inp.erreur {
  border-color: rgba(239, 68, 68, .75);
  box-shadow: inset 3px 0 0 rgba(239, 68, 68, .65);
}
#dlgProfil .profil-form .inp.erreur:focus {
  border-color: rgba(239, 68, 68, .9);
  box-shadow: inset 3px 0 0 rgba(239, 68, 68, .8), 0 0 0 3px rgba(239, 68, 68, .15);
}
#dlgProfil .profil-form .inp.secousse {
  animation: secousseProfil .32s cubic-bezier(.36, .07, .19, .97);
}
@keyframes secousseProfil {
  0%, 100% { transform: translateX(0); }
  20%      { transform: translateX(-4px); }
  45%      { transform: translateX(4px); }
  70%      { transform: translateX(-2px); }
}

/* Une année scolaire correcte ne change rien : le champ garde l'or des autres,
   comme tous les champs remplis. Seule l'erreur se distingue (rouge). */

/* Rappel de format : il passe au rouge quand la valeur ne correspond pas. */
#dlgProfil .profil-hint { transition: color .2s var(--ease); }
#dlgProfil .profil-hint.erreur { color: #FCA5A5; font-weight: 700; }

/* Profil en lecture seule (classe verrouillée) : champs visibles mais inertes. */
#dlgProfil .profil-form .inp:disabled {
  opacity: .55;
  border-style: dashed;
  box-shadow: none;
}

/* Le rond photo se pose à l'ouverture de la fiche. */
#dlgProfil[open] .profil-avatar-wrap {
  animation: avatarIn .42s cubic-bezier(.2, .9, .25, 1.15) both;
}
@keyframes avatarIn {
  from { opacity: 0; transform: translateY(-8px) scale(.86); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  #dlgProfil[open] .profil-avatar-wrap,
  #dlgProfil .profil-form .inp.secousse { animation: none !important; }
}

/* ==========================================================================
   CHAMPS DE SAISIE — le dessin de la fiche Profil, appliqué partout
   --------------------------------------------------------------------------
   Le même vocabulaire sur tous les champs de l'application, sans exception :
   survol, saisie, rempli, erreur, bloqué. Ce sont les états mis au point dans
   la fiche Profil, généralisés aux éléments .inp (texte, liste, zone de texte).
   ========================================================================== */

.inp,
select.inp,
textarea.inp {
  transition: border-color .2s var(--ease), box-shadow .25s var(--ease),
              background .2s var(--ease);
}

/* Survol (souris uniquement). */
.inp:hover:not(:focus):not(:disabled):not(.erreur) {
  border-color: rgba(212, 175, 55, .35);
}

/* Champ rempli : filet doré sur le bord gauche. */
.inp.rempli {
  border-color: rgba(212, 175, 55, .40);
  box-shadow: inset 3px 0 0 rgba(212, 175, 55, .55);
}
.inp.rempli:focus {
  border-color: var(--gold);
  box-shadow: inset 3px 0 0 rgba(244, 215, 126, .9), 0 0 0 3px rgba(212, 175, 55, .16);
}

/* Erreur : contour rouge et filet rouge. */
.inp.erreur {
  border-color: rgba(239, 68, 68, .75);
  box-shadow: inset 3px 0 0 rgba(239, 68, 68, .65);
}
.inp.erreur:focus {
  border-color: rgba(239, 68, 68, .9);
  box-shadow: inset 3px 0 0 rgba(239, 68, 68, .8), 0 0 0 3px rgba(239, 68, 68, .15);
}

/* Champ bloqué (classe verrouillée, profil en lecture seule). */
.inp:disabled {
  border-style: dashed;
  box-shadow: none;
}

/* L'étiquette du champ en cours de saisie passe en or, où qu'elle soit. */
label { transition: color .2s var(--ease); }
label.actif { color: var(--gold); }
label.actif svg { opacity: 1; filter: drop-shadow(0 0 6px rgba(212, 175, 55, .55)); }

/* Le brouillon de suggestions du navigateur ne doit pas jurer. */
.inp:-webkit-autofill {
  -webkit-text-fill-color: var(--ink);
  -webkit-box-shadow: 0 0 0 40px var(--bg-2) inset;
}

/* ==========================================================================
   CHAMPS DE SAISIE — même dessin que la fiche Profil, partout
   (renforcement : l'effet doit se voir du premier coup d'œil)
   ========================================================================== */

/* Au repos, tous les champs ont exactement le dessin de la fiche Profil. */
.inp,
select.inp,
textarea.inp {
  background: var(--bg);
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  font-weight: 600;
}

/* En saisie : contour or, halo, et étiquette en or. */
.inp:focus,
select.inp:focus,
textarea.inp:focus {
  border-color: var(--gold);
  box-shadow: inset 3px 0 0 var(--gold-2), 0 0 0 3px rgba(212, 175, 55, .18);
  outline: none;
}

/* Rempli : filet doré franc sur le bord gauche. */
.inp.rempli,
select.inp.rempli,
textarea.inp.rempli {
  border-color: rgba(212, 175, 55, .55);
  box-shadow: inset 4px 0 0 var(--gold);
}

/* Erreur : tout passe au rouge, filet compris. */
.inp.erreur,
select.inp.erreur,
textarea.inp.erreur {
  border-color: rgba(239, 68, 68, .8);
  box-shadow: inset 4px 0 0 var(--danger);
}

/* Bloqué : contour pointillé, plus d'ombre. */
.inp:disabled,
select.inp:disabled,
textarea.inp:disabled {
  border-style: dashed;
  box-shadow: none;
  opacity: .55;
}

/* ==========================================================================
   CHAMP « CODE D'ACTIVATION » (fenêtre Pro) — même dessin que les autres
   --------------------------------------------------------------------------
   Ce champ n'est pas un .inp : c'est un cadre qui contient la saisie et le
   bouton « Activer ». Il faut donc styler le cadre, et lui donner les mêmes
   états que les champs de la fiche Profil : rempli, erreur, bloqué.
   ========================================================================== */

.pro-code-wrapper {
  background: var(--bg);
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  transition: border-color .2s var(--ease), box-shadow .25s var(--ease),
              background .2s var(--ease);
}

/* Saisie : contour or, filet doré, halo. */
.pro-code-wrapper:focus-within {
  border-color: var(--gold);
  box-shadow: inset 3px 0 0 var(--gold-2), 0 0 0 3px rgba(212, 175, 55, .18);
}

/* Rempli : filet doré franc à gauche. */
.pro-code-wrapper.rempli {
  border-color: rgba(212, 175, 55, .55);
  box-shadow: inset 4px 0 0 var(--gold);
}
.pro-code-wrapper.rempli:focus-within {
  border-color: var(--gold);
  box-shadow: inset 4px 0 0 var(--gold-2), 0 0 0 3px rgba(212, 175, 55, .18);
}

/* Refusé : contour rouge et filet rouge, comme les champs en erreur. */
.pro-code-wrapper.erreur {
  border-color: rgba(239, 68, 68, .8);
  box-shadow: inset 4px 0 0 var(--danger);
}

/* Étiquette du champ en or pendant la saisie. */
.pro-code-label { transition: color .2s var(--ease); }
.pro-code-label.actif { color: var(--gold-2); }

/* Le bouton « Activer » suit la même courbure que les champs. */
.pro-code-btn { border-radius: 10px; }

/* ==========================================================================
   CHAMPS DE SAISIE — copie exacte du dessin de la fiche Profil, partout
   --------------------------------------------------------------------------
   Référence : « .profil-form .inp » (fond --bg, contour --line-2, rayon 12 px,
   hauteur 50 px, padding 16 px, poids 600) et son focus or.
   Ces règles sont volontairement placées en fin de feuille : elles passent
   après toutes les autres et s'appliquent donc à chaque champ de l'app.
   ========================================================================== */

.inp,
select.inp,
textarea.inp {
  background: var(--bg);
  border: 1px solid var(--line-2);
  border-radius: 12px;
  min-height: 50px;
  font-weight: 600;
  font-size: calc(15px * var(--fs-scale));
  color: var(--ink);
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease),
              background .18s var(--ease), transform .12s var(--ease);
}

/* AVANT LE CLIC : l'arc est déjà là, en veille — visible, jamais appuyé. */
.inp:not(:focus):not(.erreur),
select.inp:not(:focus):not(.erreur),
textarea.inp:not(:focus):not(.erreur) {
  box-shadow: inset 4px 0 0 rgba(212, 175, 55, .30);
}

/* APRÈS LE CLIC : le champ s'allume franchement. */
.inp:focus,
select.inp:focus,
textarea.inp:focus {
  background: var(--bg-2);
  border-color: var(--gold);
  box-shadow:
    inset 4px 0 0 var(--gold-2),
    0 0 0 3px rgba(212, 175, 55, .20),
    0 6px 18px rgba(212, 175, 55, .12);
  outline: none;
}

/* Champ qui contient déjà quelque chose : le filet doré reste visible au repos. */
/* Rempli au repos : l'arc monte d'un cran, sans atteindre l'or pur du focus. */
.inp.rempli:not(:focus),
select.inp.rempli:not(:focus),
textarea.inp.rempli:not(:focus) {
  border-color: rgba(212, 175, 55, .45);
  box-shadow: inset 4px 0 0 rgba(212, 175, 55, .72);
}

/* Refusé : rouge, avant comme après le clic. */
.inp.erreur,
select.inp.erreur,
textarea.inp.erreur {
  border-color: rgba(239, 68, 68, .8);
  box-shadow: inset 4px 0 0 var(--danger);
}

/* ==========================================================================
   SYNCHRONISATION VISUELLE — cases de notes, boutons d'action, lisibilité
   --------------------------------------------------------------------------
   Objectif : le même vocabulaire partout, des cibles franches, un texte net.
   Trois familles seulement : les cases de chiffres, les boutons qui valident
   ou suppriment, et les textes secondaires.
   ========================================================================== */

/* 1. CASES DE NOTES — même arc que les champs, en veille puis en or pur. */
#listeNotes input {
  background: var(--bg);
  border: 1px solid var(--line-2);
  border-radius: 12px;
  color: var(--ink);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  box-shadow: inset 3px 0 0 rgba(212, 175, 55, .30);
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease),
              background .18s var(--ease);
}
#listeNotes input:focus {
  background: var(--bg-2);
  border-color: var(--gold);
  box-shadow: inset 3px 0 0 var(--gold-2), 0 0 0 3px rgba(212, 175, 55, .20);
  outline: none;
}
/* Une case refusée reste rouge, même focalisée. */
#listeNotes .note-input.note-invalide,
#listeNotes .note-input.note-invalide:focus {
  border-color: rgba(239, 68, 68, .85);
  box-shadow: inset 3px 0 0 var(--danger), 0 0 0 3px rgba(239, 68, 68, .16);
}

/* 2. BOUTONS QUI SUPPRIMENT — pleins, lisibles, sans transparence. */
.btn-r {
  color: #FFF;
  border-color: transparent;
  background: linear-gradient(135deg, #EF4444 0%, #B91C1C 100%);
  box-shadow: 0 8px 20px rgba(239, 68, 68, .30);
}
.btn-r:hover {
  color: #FFF;
  background: linear-gradient(135deg, #F87171 0%, #DC2626 100%);
  box-shadow: 0 10px 26px rgba(239, 68, 68, .50);
}

/* 3. BOUTONS QUI VALIDENT — pleins, avec une arête haute pour le relief. */
.btn-valide,
.btn-danger,
.btn-pdf,
.btn-profil-valider {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .28), 0 8px 22px rgba(0, 0, 0, .28);
}
.btn-valide { box-shadow: inset 0 1px 0 rgba(255, 255, 255, .35), 0 8px 22px rgba(16, 185, 129, .35); }
.btn-danger { box-shadow: inset 0 1px 0 rgba(255, 255, 255, .30), 0 8px 22px rgba(239, 68, 68, .38); }
.btn-pdf    { box-shadow: inset 0 1px 0 rgba(255, 255, 255, .35), 0 8px 22px rgba(212, 175, 55, .35); }

/* Le dessin des boutons grisés est défini plus bas, en un seul endroit :
   gris lisible, sans désaturation ni transparence. */

/* 4. LISIBILITÉ — textes secondaires plus francs, sans crier. */
:root {
  --ink-2: #A7AFBD;      /* était #9CA3AF : plus net sur fond nuit */
  --ink-3: #98A2B3;      /* était #8B93A1 : lisible sans devenir gris clair */
}
.petit { color: var(--ink-2); }
h1, h2, .cnt, .stats b, .rank td { text-rendering: optimizeLegibility; }

/* 5. ERGONOMIE — aucune cible sous 44 px. */
.btn-sm { min-height: 44px; }
.note-row-mic, #listeNotes input { min-height: 44px; }
.profil-avatar { min-height: 96px; }

/* ==========================================================================
   BOUTONS — tous pleins, tous en relief
   --------------------------------------------------------------------------
   Fin des boutons à bordure fine : chaque bouton porte un remplissage, une
   arête claire en haut, une ombre portée, et s'enfonce à l'appui.
   Les sélecteurs sont doublés (.btn.btn-s) pour passer devant les règles de
   survol déjà présentes dans la feuille.
   ========================================================================== */

/* Base commune : remplissage + arête + ombre. */
.btn,
.btn-accueil-top,
.note-row-mic,
.mode-btn,
.select-custom {
  border-width: 1px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .10), 0 6px 16px rgba(0, 0, 0, .30);
}

/* Bouton neutre : rempli d'un dégradé sombre, plus de fond plat. */
.btn {
  background: linear-gradient(180deg, #182136 0%, #111A2C 100%);
  border-color: #233049;
  color: var(--ink);
}
.btn:hover:not(.btn-p):not(.btn-v):not(.btn-r):not(.btn-b):not(.btn-danger):not(.btn-pdf):not(.overview-primary):not(.btn-valide):not(.btn-mention) {
  background: linear-gradient(180deg, #1E2A44 0%, #16203A 100%);
  border-color: #2E3D5C;
}

/* Secondaire : plein, gris bleuté. */
.btn.btn-s {
  background: linear-gradient(180deg, #1B2438 0%, #141C2E 100%);
  border-color: #26324A;
  color: var(--ink);
}
.btn.btn-s:hover { background: linear-gradient(180deg, #222E48 0%, #18223A 100%); color: var(--ink); }

/* Doré discret : plein, teinté or, texte or. */
.btn.btn-b {
  background: linear-gradient(180deg, rgba(212, 175, 55, .28) 0%, rgba(212, 175, 55, .14) 100%);
  border-color: rgba(212, 175, 55, .45);
  color: var(--gold-2);
  box-shadow: inset 0 1px 0 rgba(255, 248, 220, .28), 0 6px 16px rgba(212, 175, 55, .18);
}
.btn.btn-b:hover {
  background: linear-gradient(180deg, rgba(212, 175, 55, .38) 0%, rgba(212, 175, 55, .20) 100%);
  color: #FFF8DC;
}

/* Lien discret : rempli très légèrement, pour rester cliquable et visible. */
/* Bouton « lien » : le dessin opaque est défini en fin de feuille. */

/* Pilule d'accueil : remplie. */
.btn-accueil-top {
  background: linear-gradient(180deg, #1A2440 0%, #131C33 100%);
  border-color: rgba(212, 175, 55, .30);
  color: var(--ink);
}
.btn-accueil-top:hover,
.btn-accueil-top:active {
  background: linear-gradient(180deg, rgba(212, 175, 55, .22) 0%, rgba(212, 175, 55, .10) 100%);
  border-color: rgba(212, 175, 55, .55);
  color: var(--gold-2);
}

/* Micro des lignes de notes : rempli, doré à l'écoute. */
.note-row-mic {
  background: linear-gradient(180deg, #182136 0%, #111A2C 100%);
  border-color: #26324A;
  color: var(--gold);
}
.note-row-mic:hover {
  background: linear-gradient(180deg, rgba(212, 175, 55, .22) 0%, rgba(212, 175, 55, .10) 100%);
  border-color: rgba(212, 175, 55, .55);
  color: var(--gold-2);
}

/* Enfoncement commun : le bouton s'enfonce, l'arête claire disparaît. */
.btn:active,
.btn-accueil-top:active,
.note-row-mic:active,
.mode-btn:active {
  transform: translateY(1px) scale(.995);
  box-shadow: inset 0 2px 6px rgba(0, 0, 0, .45);
}

/* ==========================================================================
   COULEURS DE RÔLE — jaune pour agir, rouge pour supprimer, gris lisible
   ========================================================================== */

/* 1. « Ajouter », « Nouvelle évaluation » : jaune plein, comme les boutons
   principaux. Plus de bouton creux à bordure dorée. */
.btn.btn-b {
  color: #1A1200;
  border-color: transparent;
  background: linear-gradient(135deg, var(--gold-2) 0%, var(--gold) 55%, var(--gold-3) 100%);
  box-shadow: inset 0 1px 0 rgba(255, 248, 220, .45), 0 8px 22px rgba(212, 175, 55, .32);
}
.btn.btn-b:hover {
  color: #1A1200;
  background: linear-gradient(135deg, #FFEFB0 0%, var(--gold-2) 55%, var(--gold) 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .55), 0 10px 26px rgba(212, 175, 55, .45);
}

/* 2. Tous les boutons grisés : gris lisible, jamais du gris éteint.
   Même traitement que « Valider les notes » quand il est inactif. */
.btn:disabled,
.btn-valide:disabled,
.btn-r:disabled,
.btn-b:disabled,
.btn-profil-valider:disabled,
#btnValiderSaisieManuelle:disabled,
.vocal-big-btn:disabled {
  opacity: 1;
  filter: none;
  color: #A7AFBD;
  background: linear-gradient(180deg, #2E3A50 0%, #1D2536 100%);
  border-color: #3A465E;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06);
  cursor: not-allowed;
  transform: none;
}

/* 3. Micros : gris au repos, rouge pendant l'écoute — partout pareil. */
.note-row-mic {
  color: #8B93A1;
  background: linear-gradient(180deg, #22304A 0%, #182136 100%);
  border-color: #33415C;
}
.note-row-mic:hover {
  color: var(--gold-2);
  border-color: rgba(212, 175, 55, .55);
  background: linear-gradient(180deg, rgba(212, 175, 55, .20) 0%, rgba(212, 175, 55, .08) 100%);
}
.note-row-mic.listening {
  color: #FFF;
  background: linear-gradient(135deg, #EF4444 0%, #B91C1C 100%);
  border-color: #EF4444;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .28), 0 8px 20px rgba(239, 68, 68, .40);
}

/* Le bouton « Démarrer la dictée » suit la même logique. */
.btn.vocal-big-btn {
  color: var(--ink) !important;
  background: linear-gradient(180deg, #2E3A50 0%, #1D2536 100%) !important;
  border: 1px solid #3A465E;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .08), 0 8px 20px rgba(0, 0, 0, .30);
}
.btn.vocal-big-btn:hover {
  color: var(--ink);
  background: linear-gradient(180deg, #384663 0%, #232C41 100%);
}
.vocal-big-btn.listening {
  color: #FFF;
  background: linear-gradient(135deg, #EF4444 0%, #B91C1C 100%) !important;
  border-color: #EF4444;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .28), 0 8px 20px rgba(239, 68, 68, .40);
}

/* ==========================================================================
   COULEURS DES BOUTONS — une famille, une couleur franche
   --------------------------------------------------------------------------
   Chaque type d'action a sa couleur, sans dégradé timide ni fond presque noir :
   agir = or, supprimer = rouge, valider = vert, secondaire = bleu.
   Les déclarations sont prioritaires pour qu'aucune règle ancienne ne
   reprenne le dessus : c'est le point qui laissait des boutons ternes.
   ========================================================================== */

/* OR — enregistrer, créer, ajouter, générer le PDF, activer. */
.btn.btn-p,
.btn.btn-b,
.btn.btn-pdf,
button.btn-profil-valider,
.btn.overview-primary,
button.pro-code-btn {
  color: #1A1200 !important;
  background: linear-gradient(135deg, #FFE9AE 0%, #F4D77E 22%, #D4AF37 58%, #A88B2C 100%) !important;
  border: none !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .55), 0 8px 22px rgba(212, 175, 55, .38) !important;
}

/* ROUGE — supprimer, retirer, réinitialiser. */
.btn.btn-r,
.btn-danger {
  color: #FFFFFF !important;
  background: linear-gradient(135deg, #FF8080 0%, #EF4444 45%, #B91C1C 100%) !important;
  border: none !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .35), 0 8px 22px rgba(239, 68, 68, .38) !important;
}

/* VERT — valider un lot. */
.btn.btn-valide {
  color: #04240F !important;
  background: linear-gradient(135deg, #6EE7A8 0%, #22C55E 45%, #047857 100%) !important;
  border: none !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .45), 0 8px 22px rgba(16, 185, 129, .38) !important;
}

/* VERT WHATSAPP — contact. */
.btn.btn-v {
  color: #04240F !important;
  background: linear-gradient(135deg, #4ADE80 0%, #25D366 60%, #128C7E 100%) !important;
  border: none !important;
}

/* BLEU — annuler, fermer, actions secondaires. */
.btn.btn-s {
  color: #FFFFFF !important;
  background: linear-gradient(135deg, #4A7BE0 0%, #2A4A9C 55%, #1C3468 100%) !important;
  border: none !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .28), 0 8px 20px rgba(42, 74, 156, .35) !important;
}

/* OR DISCRET — actions légères (liens d'action). */
/* Bouton « lien » : version opaque en fin de feuille. */

/* BLEU NUIT — bouton neutre sans famille. */
.btn {
  color: #FFFFFF !important;
  background: linear-gradient(135deg, #3A5580 0%, #24354F 55%, #16233C 100%) !important;
  border: none !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .20), 0 8px 20px rgba(0, 0, 0, .35) !important;
}

/* Pilule « Accueil » : or sur fond bleu nuit. */
/* Pilule Accueil : version opaque en fin de feuille. */

/* INACTIF — gris lisible, et il gagne sur tout ce qui précède. */
.btn:disabled,
.btn.btn-p:disabled,
.btn.btn-b:disabled,
.btn.btn-s:disabled,
.btn.btn-l:disabled,
.btn.btn-r:disabled,
.btn.btn-valide:disabled,
.btn.btn-v:disabled,
.btn-profil-valider:disabled,
#btnValiderSaisieManuelle:disabled,
.vocal-big-btn:disabled {
  color: #B4BCCA !important;
  background: linear-gradient(180deg, #33405A 0%, #212B3E 100%) !important;
  border: 1px solid #46536D !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .07) !important;
  opacity: 1 !important;
  filter: none !important;
  cursor: not-allowed !important;
  transform: none !important;
}

/* ==========================================================================
   COULEURS PAR ACTION — dictée, mentions, réinitialisation
   --------------------------------------------------------------------------
   Une couleur par geste, décidée avec l'usage : bleu pour parler, bleu pour
   ajouter une mention, or pour revenir aux mentions par défaut, rouge pour
   effacer des notes. Écrit avec une spécificité supérieure à .btn pour ne
   jamais être repris par la règle générique.
   ========================================================================== */

/* 1. DICTÉE (saisie mixte) : bleue au repos, rouge pendant l'écoute. */
.btn.btn-v.vocal-big-btn,
button.btn.vocal-big-btn {
  color: #FFFFFF !important;
  background: linear-gradient(135deg, #4A7BE0 0%, #2A4A9C 55%, #1C3468 100%) !important;
  border: none !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .30), 0 8px 20px rgba(42, 74, 156, .38) !important;
}
.btn.btn-v.vocal-big-btn:hover,
button.btn.vocal-big-btn:hover {
  background: linear-gradient(135deg, #5C8BF0 0%, #3457B0 55%, #23407E 100%) !important;
}
.btn.btn-v.vocal-big-btn.listening,
button.btn.vocal-big-btn.listening {
  color: #FFFFFF !important;
  background: linear-gradient(135deg, #FF8080 0%, #EF4444 45%, #B91C1C 100%) !important;
  border-color: #EF4444 !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .30), 0 8px 20px rgba(239, 68, 68, .45) !important;
}

/* 2. AJOUTER UNE MENTION : bleu. */
.btn.btn-mention#addMention {
  color: #FFFFFF !important;
  background: linear-gradient(135deg, #4A7BE0 0%, #2A4A9C 55%, #1C3468 100%) !important;
  border: none !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .28), 0 6px 16px rgba(42, 74, 156, .32) !important;
}
.btn.btn-mention#addMention:hover {
  background: linear-gradient(135deg, #5C8BF0 0%, #3457B0 55%, #23407E 100%) !important;
}

/* 3. MENTIONS PAR DÉFAUT : or. */
.btn.btn-mention#resetMentions {
  color: #1A1200 !important;
  background: linear-gradient(135deg, #FFE9AE 0%, #F4D77E 22%, #D4AF37 58%, #A88B2C 100%) !important;
  border: none !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .50), 0 6px 16px rgba(212, 175, 55, .32) !important;
}
.btn.btn-mention#resetMentions:hover {
  background: linear-gradient(135deg, #FFF3C4 0%, #FFE08A 22%, #E3C04A 58%, #B89A35 100%) !important;
}

/* 4. RÉINITIALISER LES NOTES (Classement) : rouge. */
.btn.btn-danger#btnReinitClassement {
  color: #FFFFFF !important;
  background: linear-gradient(135deg, #FF8080 0%, #EF4444 45%, #B91C1C 100%) !important;
  border: none !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .32), 0 8px 22px rgba(239, 68, 68, .38) !important;
}
.btn.btn-danger#btnReinitClassement:hover {
  background: linear-gradient(135deg, #FF9A9A 0%, #F45A5A 45%, #C62828 100%) !important;
}

/* ==========================================================================
   MODE DE SAISIE — une couleur par mode, une couleur par état
   --------------------------------------------------------------------------
   Mixte = or, Dictée = vert. Le mode choisi s'allume franchement ; l'autre
   reste sombre mais lisible. Le bouton « Démarrer la dictée » suit le mode
   Dictée : vert pour lancer, rouge pour arrêter.
   ========================================================================== */

/* Mixte : or, actif comme inactif. */
#btnModeManuel {
  color: #1A1200 !important;
  background: linear-gradient(135deg, #FFE9AE 0%, #F4D77E 22%, #D4AF37 58%, #A88B2C 100%) !important;
  border: none !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .50), 0 6px 16px rgba(212, 175, 55, .30) !important;
}
#btnModeManuel.mode-actif {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .60),
              0 0 0 2px rgba(244, 215, 126, .55),
              0 8px 22px rgba(212, 175, 55, .48) !important;
}

/* Dictée : vert, actif comme inactif. */
#btnModeVocal {
  color: #04240F !important;
  background: linear-gradient(135deg, #6EE7A8 0%, #22C55E 45%, #047857 100%) !important;
  border: none !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .42), 0 6px 16px rgba(16, 185, 129, .30) !important;
}
#btnModeVocal.mode-actif {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .55),
              0 0 0 2px rgba(110, 231, 168, .55),
              0 8px 22px rgba(16, 185, 129, .48) !important;
}

/* Mode non choisi : on le laisse visible mais en retrait (opacité douce). */
#btnModeManuel:not(.mode-actif),
#btnModeVocal:not(.mode-actif) {
  opacity: .55;
}

/* « Démarrer la dictée » : vert pour lancer… */
.btn.btn-v.vocal-big-btn:not(.listening),
button.btn.vocal-big-btn:not(.listening) {
  color: #04240F !important;
  background: linear-gradient(135deg, #6EE7A8 0%, #22C55E 45%, #047857 100%) !important;
  border: none !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .45), 0 8px 22px rgba(16, 185, 129, .38) !important;
}

/* … et rouge pour arrêter. */
.btn.btn-v.vocal-big-btn.listening,
button.btn.vocal-big-btn.listening {
  color: #FFFFFF !important;
  background: linear-gradient(135deg, #FF8080 0%, #EF4444 45%, #B91C1C 100%) !important;
  border: none !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .32), 0 8px 22px rgba(239, 68, 68, .45) !important;
}

/* ==========================================================================
   CORRECTIFS UI/UX — textes francs, Fermer en rouge, palette harmonisée
   ========================================================================== */

/* 1. Modes de saisie : le texte reste net, même quand le mode n'est pas choisi.
   Plus d'opacité qui donnait l'impression d'un texte flou. */
#btnModeManuel:not(.mode-actif),
#btnModeVocal:not(.mode-actif) {
  opacity: 1;
}
#btnModeManuel .mode-libelle,
#btnModeVocal .mode-libelle {
  opacity: 1;
  font-weight: 800;
  letter-spacing: .01em;
}
/* Le mode non choisi se distingue par sa teinte, pas par un voile. */
#btnModeManuel:not(.mode-actif) { filter: saturate(.85); }
#btnModeVocal:not(.mode-actif) { filter: saturate(.85); }

/* 2. « Fermer » des fenêtres de choix (évaluation, classe) : rouge. */
#btnFermerSelectEval,
#btnFermerSelectClasse {
  color: #FFFFFF !important;
  background: linear-gradient(135deg, #FF8080 0%, #EF4444 45%, #B91C1C 100%) !important;
  border: none !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .32), 0 8px 22px rgba(239, 68, 68, .35) !important;
}
#btnFermerSelectEval:hover,
#btnFermerSelectClasse:hover {
  background: linear-gradient(135deg, #FF9A9A 0%, #F45A5A 45%, #C62828 100%) !important;
}

/* 3. Harmonisation : les boutons d'une même fenêtre ont la même hauteur et
   la même courbure, quel que soit leur rôle. */
dialog .btn { border-radius: 12px; }
.duo .btn { min-height: 50px; }

/* 4. Les libellés dans les boutons colorés restent nets : pas d'ombre de
   texte héritée qui salit le contour des lettres. */
.btn { text-shadow: none; }
.btn.btn-p, .btn.btn-b, .btn.btn-pdf, .btn.btn-s, .btn.btn-r,
.btn.btn-valide, .btn.btn-v, .btn.btn-l, .btn.btn-danger {
  text-shadow: none;
}

/* ==========================================================================
   CORRECTIF DE CONTRASTE — le rouge et le blanc
   --------------------------------------------------------------------------
   Mesure : #EF4444 avec du texte blanc ne donne que 3,76 de contraste, sous
   le minimum de 4,5 exigé pour du texte. Le rouge des boutons descend donc
   d'un cran (#DC2626 → 4,83 / #B91C1C → 6,47) : mêmes boutons, lisibles.
   ========================================================================== */

.btn.btn-r,
.btn-danger,
.btn.btn-danger#btnReinitClassement,
#btnFermerSelectEval,
#btnFermerSelectClasse,
/* Les micros en écoute gardent leur propre animation d'onde : leur ombre
   n'est donc pas figée ici (voir « ONDE D'ÉCOUTE » en fin de feuille). */

.btn.btn-r:hover,
.btn-danger:hover,
.btn.btn-danger#btnReinitClassement:hover,
#btnFermerSelectEval:hover,
#btnFermerSelectClasse:hover {
  background: linear-gradient(135deg, #E53935 0%, #D32F2F 45%, #A81B1B 100%) !important;
}

/* ==========================================================================
   RÉGLAGES FINS — 4 tuiles d'accueil plus opaques, bordures plus sombres,
   or légèrement plus soutenu
   ========================================================================== */

/* 1. Les quatre tuiles de la carte d'accueil : fond plus dense, bordure nette.
   L'ancien voile à 40-60 % laissait passer le fond et rendait les libellés
   mous ; la bordure claire les faisait flotter. */
#ecran-accueil .quick-card .box {
  background: linear-gradient(135deg, rgba(23, 44, 92, 0.72) 0%, rgba(10, 22, 51, 0.85) 100%);
  border: 1px solid rgba(6, 12, 26, 0.85);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .07), 0 10px 26px rgba(0, 0, 0, .45);
}
#ecran-accueil .quick-card.menu-open .box:hover {
  background: linear-gradient(135deg, rgba(32, 60, 120, 0.85) 0%, rgba(14, 28, 64, 0.92) 100%);
  border-color: rgba(212, 175, 55, 0.65);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .10), 0 14px 32px rgba(0, 0, 0, .5);
}

/* 2. La carte elle-même : bordure un peu plus sombre, pour asseoir les tuiles. */
#ecran-accueil .quick-card {
  border: 1px solid rgba(168, 139, 44, .38);
}

/* 3. L'or des boutons : un cran plus soutenu, sans perdre le contraste.
   Le texte brun sombre reste à 8,5:1 sur le nouveau ton. */
.btn.btn-p,
.btn.btn-b,
.btn.btn-pdf,
button.btn-profil-valider,
.btn.overview-primary,
button.pro-code-btn,
#btnModeManuel,
.btn.btn-mention#resetMentions {
  background: linear-gradient(135deg, #F6DE9E 0%, #E4C166 22%, #C39B31 58%, #8C7224 100%) !important;
}
.btn.btn-p:hover,
.btn.btn-b:hover,
.btn.btn-pdf:hover,
button.btn-profil-valider:hover,
button.pro-code-btn:hover,
#btnModeManuel:hover,
.btn.btn-mention#resetMentions:hover {
  background: linear-gradient(135deg, #FBEBBC 0%, #EDD07F 22%, #D0A93C 58%, #9A7E2A 100%) !important;
}

/* 4. Les chiffres dorés des tuiles de statistiques suivent le même ton. */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .stats b, .stats strong {
    background: linear-gradient(180deg, #FBEBBC 0%, #E4C166 48%, #C39B31 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
  }
}

/* ==========================================================================
   SURFACES OPAQUES — un seul niveau de matière partout
   --------------------------------------------------------------------------
   Plus aucun cadre laisse passer le fond : chaque surface a sa couleur pleine.
   Le rond doré du centre, la grande carte derrière, les quatre tuiles, le
   formulaire du profil et les fenêtres suivent la même règle.
   ========================================================================== */

/* 1. Le rond doré du centre de l'accueil (« cadre hexagonal ») : opaque. */
#ecran-accueil .quick-card .logo {
  background-color: #0B1812;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border: 1px solid rgba(196, 160, 48, .75);
  box-shadow: 0 12px 35px rgba(0, 0, 0, .75), inset 0 1px 0 rgba(255, 255, 255, .10);
}

/* 2. La grande carte derrière : fond plein, plus de transparence. */
#ecran-accueil .quick-card {
  background: radial-gradient(circle at 50% 42%, #16294F 0%, #0B1730 62%, #0A1633 100%);
  border: 1px solid rgba(168, 139, 44, .45);
}

/* 3. Les quatre tuiles : totalement opaques, même teinte que la carte. */
#ecran-accueil .quick-card .box {
  background: linear-gradient(135deg, #172B5C 0%, #0A1633 100%);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border: 1px solid rgba(6, 12, 26, .9);
}
#ecran-accueil .quick-card.menu-open .box:hover {
  background: linear-gradient(135deg, #20407A 0%, #0E1C40 100%);
}

/* 4. Le formulaire du profil : fond plein. */
.profil-form {
  background: #0C152A;
  border: 1px solid rgba(255, 255, 255, .07);
}

/* 5. Fenêtres et cartes de l'application : surface pleine, bordure définie. */
dialog {
  background: var(--surface);
  border: 1px solid rgba(255, 255, 255, .08);
}
.dlg-profil {
  background: linear-gradient(180deg, #131C33 0%, #0D152B 100%);
}
.carte {
  background: var(--surface);
}

/* 6. Bandeaux d'information : opaques eux aussi, pour rester lisibles au-
   dessus de n'importe quel contenu. */
.bandeau-hors-ligne {
  background: #6B3410;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

/* ==========================================================================
   LA BORDURE SIGNATURE — l'or de NoteScan, plein et net
   --------------------------------------------------------------------------
   Le grand cadre portait une bordure de 1 px à 20-45 % d'opacité, et
   l'animation « pulseGlow » la faisait osciller : la signature de l'app
   restait floue. Ici la bordure est un liseré d'or OPAQUE de 2 px, en dégradé,
   qui ne dépend plus de l'animation.
   Technique : bordure transparente + deux couches de fond (contenu à
   l'intérieur, or sur la bordure) — c'est ce qui donne un vrai liseré net.
   ========================================================================== */

/* Ancien liseré net : remplacé par le contour flouté, défini en fin de
   feuille. Conservé ici sous forme de note pour garder l'historique lisible. */

/* Le menu ouvert garde exactement la même bordure : rien ne se déforme. */
/* Menu ouvert : le contour est flouté comme au repos, voir la fin du fichier. */

/* Sur les écrans qui ne sont pas l'accueil, aucune règle ne s'applique :
   cette bordure est la signature de la carte d'entrée, pas un style global. */

/* ==========================================================================
   BOÎTES EMPILÉES — contours arrondis, relief de superposition
   --------------------------------------------------------------------------
   Les angles à 16-22 px se lisaient comme des rectangles. Ici chaque boîte a
   des angles plus doux et, surtout, une OMBRE DURE sous son bord bas : c'est
   elle qui donne l'impression que la boîte est posée sur celle du dessous.
   ========================================================================== */

/* 1. La grande carte d'accueil : angles plus doux, ombre de plateau. */
#ecran-accueil .quick-card {
  border-radius: 32px;
}
#ecran-accueil .quick-card .box,
#ecran-accueil .quick-card .logo {
  border-radius: 26px;
}

/* 2. Les quatre tuiles : posées sur le plateau, avec une arête nette. */
#ecran-accueil .quick-card .box {
  box-shadow:
    0 3px 0 0 rgba(3, 8, 18, .95),          /* épaisseur : la boîte a un socle */
    0 16px 30px rgba(0, 0, 0, .45),          /* ombre portée sur le plateau */
    inset 0 1px 0 rgba(255, 255, 255, .10);  /* lumière sur l'arête haute */
}
#ecran-accueil .quick-card.menu-open .box:hover {
  box-shadow:
    0 4px 0 0 rgba(3, 8, 18, .95),
    0 20px 38px rgba(0, 0, 0, .50),
    inset 0 1px 0 rgba(255, 255, 255, .14);
}

/* 3. Le rond central : même famille, socle plus marqué. */
#ecran-accueil .quick-card .logo {
  box-shadow:
    0 4px 0 0 rgba(3, 8, 18, .95),
    0 18px 34px rgba(0, 0, 0, .55),
    inset 0 1px 0 rgba(255, 255, 255, .12);
}

/* 4. Partout ailleurs : cartes, tuiles de statistiques, formulaires et
   fenêtres suivent la même rondeur et le même relief, pour rester uniformes. */
.carte,
.empty-state,
.stats .stat,
.workspace-overview {
  border-radius: 22px;
  box-shadow:
    0 2px 0 0 rgba(3, 8, 18, .55),
    0 14px 26px rgba(0, 0, 0, .30),
    inset 0 1px 0 rgba(255, 255, 255, .06);
}

.profil-form {
  border-radius: 22px;
}

dialog {
  border-radius: 26px;
  box-shadow:
    0 4px 0 0 rgba(3, 8, 18, .75),
    0 24px 48px rgba(0, 0, 0, .55),
    inset 0 1px 0 rgba(255, 255, 255, .07);
}

/* 5. Les champs reprennent la même rondeur : plus d'angles secs. */
.inp,
select.inp,
textarea.inp,
#listeNotes input {
  border-radius: 14px;
}

/* 6. Les boutons suivent : angles plus doux, socle discret. */
.btn {
  border-radius: 14px;
  box-shadow:
    0 2px 0 0 rgba(3, 8, 18, .55),
    0 10px 22px rgba(0, 0, 0, .30),
    inset 0 1px 0 rgba(255, 255, 255, .12);
}
.btn:active {
  box-shadow: 0 0 0 0 rgba(0, 0, 0, 0), inset 0 2px 6px rgba(0, 0, 0, .45);
}

/* ==========================================================================
   CONTOURS FLOUTÉS AU MAXIMUM — on doit à peine les sentir
   --------------------------------------------------------------------------
   Le liseré net est retiré : il ne reste qu'un trait de 1 px à 20 % d'opacité,
   et surtout un halo d'or très étalé (flou de 18 px) posé derrière la carte.
   Le contour devient une lumière diffuse : on le devine, on ne le voit pas.
   ========================================================================== */

#ecran-accueil .quick-card {
  isolation: isolate;
  border: 1px solid rgba(196, 160, 48, .30) !important;
  background: radial-gradient(circle at 50% 42%, #16294F 0%, #0B1730 62%, #0A1633 100%) !important;
  background-clip: border-box !important;
}

/* Menu ouvert : même contour, aucun halo. */
#ecran-accueil .quick-card.menu-open {
  border: 1px solid rgba(196, 160, 48, .22) !important;
}

/* Aucun halo derrière la carte : c'est ce voile flouté qui donnait l'effet
   pâteux. Le contour est net, fin, et se contente de tenir la forme. */
#ecran-accueil .quick-card::before {
  content: none !important;
}

/* ==========================================================================
   FIN DU SCINTILLEMENT DORÉ — l'arrière-plan redevient calme
   --------------------------------------------------------------------------
   La carte d'accueil portait l'animation « pulseGlow » : toutes les 4 secondes,
   une lueur dorée gonflait puis retombait autour d'elle (box-shadow de 0 à
   40 px, bordure de 20 % à 40 %). C'est ce battement continu qui donnait
   l'impression de scintillement et qui déstabilisait le design.
   L'animation est retirée : seule l'entrée en fondu subsiste.
   ========================================================================== */

#ecran-accueil .quick-card {
  animation: homeCardIn .65s cubic-bezier(.2, .7, .2, 1) both !important;
  /* L'ombre devient fixe : une ombre portée sobre, plus aucun halo pulsé. */
  box-shadow: 0 24px 70px rgba(0, 0, 0, .55) !important;
}

/* Rien d'autre ne doit scintiller derrière la carte. */
#ecran-accueil .quick-card .logo,
#ecran-accueil .quick-card .box {
  animation: none;
}

/* ==========================================================================
   BOUTONS OPAQUES — aucun fond translucide ne laisse passer la page
   --------------------------------------------------------------------------
   Deux boutons étaient encore en verre teinté : le bouton « lien » (or à 20 %)
   et la pilule « Accueil » (or + bleu en transparence). Les valeurs ci-dessous
   sont les MÊMES teintes, calculées comme si elles étaient posées sur le fond
   nuit — donc l'aspect ne change pas, mais plus rien ne traverse.
   ========================================================================== */

/* Bouton « lien » : or mat opaque. */
.btn.btn-l {
  color: var(--gold-2) !important;
  background: linear-gradient(135deg, #35342D 0%, #21242C 100%) !important;
  border: 1px solid rgba(196, 160, 48, .55) !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .07), 0 4px 12px rgba(0, 0, 0, .25) !important;
}
.btn.btn-l:hover {
  color: #FFF8DC !important;
  background: linear-gradient(135deg, #3D3A2E 0%, #262A33 100%) !important;
}

/* Pilule « Accueil » : or et bleu, opaques. */
.btn-accueil-top {
  color: var(--gold-2) !important;
  background: linear-gradient(135deg, #39372E 0%, #16254D 100%) !important;
  border: 1px solid rgba(196, 160, 48, .60) !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .14), 0 6px 16px rgba(0, 0, 0, .35) !important;
}
.btn-accueil-top:hover,
.btn-accueil-top:active {
  color: #FFF8DC !important;
  background: linear-gradient(135deg, #45412F 0%, #1B2E5C 100%) !important;
}

/* Bouton de fermeture des fenêtres Pro : fond plein, rouge au survol. */
.pro-close-x {
  background: #16233C !important;
}
.pro-close-x:hover {
  background: #7F1D1D !important;
  color: #FFFFFF !important;
}

/* Rappel de sécurité : plus aucun bouton ne doit rester en verre teinté. */
.btn.btn-l,
.btn.btn-b,
.btn.btn-p,
.btn.btn-s,
.btn.btn-r,
.btn.btn-v,
.btn.btn-valide,
.btn-accueil-top,
.mode-btn,
.note-row-mic,
.pro-close-x,
.pro-code-btn,
#btnModeManuel,
#btnModeVocal {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

/* ==========================================================================
   CADRES D'INFORMATION OPAQUES — aucun panneau ne laisse voir le fond
   --------------------------------------------------------------------------
   Derniers panneaux encore en verre teinté : le bandeau d'état de la classe,
   ses boutons secondaires, la pastille de dictée, l'avertissement de
   brouillon, le rond de la photo de profil et le bandeau d'accueil.
   Chaque valeur est la teinte d'origine composée sur le fond nuit : l'aspect
   ne change pas, la transparence disparaît.
   ========================================================================== */

/* 1. Bandeau d'état de la classe (haut de l'écran Classes). */
.workspace-overview {
  background: linear-gradient(135deg, #2A2418 0%, #111827 45%, #0D152B 100%) !important;
  border: 1px solid rgba(196, 160, 48, .35) !important;
}

/* 2. Boutons secondaires de ce bandeau / de l'aperçu. */
.overview-secondary {
  background: #1B2233 !important;
  border: 1px solid var(--line-2) !important;
  color: var(--ink) !important;
}

/* 3. Pastille de la zone de dictée. */
.vocal-icon {
  background: linear-gradient(135deg, #1B3B2C 0%, #123A2C 100%) !important;
  border: 1px solid rgba(16, 185, 129, .35) !important;
}

/* 4. Avertissement « modifications non validées ». */
#notesBrouillonInfo {
  background: #4A2410 !important;
  border: 1px solid rgba(212, 175, 55, .30) !important;
}

/* 5. Rond de la photo de profil : fond plein, l'or reste en dégradé opaque. */
.profil-avatar {
  background-color: #0E1B14 !important;
  background-image: linear-gradient(135deg, #2A2418 0%, #1B2412 100%) !important;
}

/* 6. Sélecteurs (classe, évaluation) : surface pleine. */
.select-custom {
  background: #16233C !important;
  border: 1px solid #2E3D5C !important;
}

/* 7. Barre d'état de la dictée et journal. */
.vocal-status,
.vocal-log {
  background: var(--bg-2) !important;
}

/* 8. Cartes vides et listes d'erreurs : déjà pleines, on verrouille. */
.empty-state,
.liste-erreurs {
  background: var(--surface) !important;
}

/* ==========================================================================
   COLLER DANS UN CHAMP NE DOIT RIEN CHANGER — fin du fond blanc
   --------------------------------------------------------------------------
   Quand on colle du texte, le navigateur peut marquer le champ comme
   « rempli automatiquement » : il peint alors son propre fond (blanc ou
   jaunâtre) et ignore la feuille de style. On neutralise cet état sur tous
   les champs de l'application, et on verrouille la couleur de fond pour que
   plus rien ne puisse la repeindre.
   ========================================================================== */

/* 1. Le fond des champs ne change plus, quoi qu'il arrive. */
.inp,
select.inp,
textarea.inp,
#listeNotes input,
.pro-code-input {
  background-color: var(--bg) !important;
}
.inp:focus,
select.inp:focus,
textarea.inp:focus,
#listeNotes input:focus {
  background-color: var(--bg-2) !important;
}

/* 2. État « rempli automatiquement » : on impose nos couleurs, dans tous ses
   états (survol, focus, actif). Le très long délai de transition empêche le
   navigateur de faire apparaître son propre fond. */
.inp:-webkit-autofill,
.inp:-webkit-autofill:hover,
.inp:-webkit-autofill:focus,
.inp:-webkit-autofill:active,
select.inp:-webkit-autofill,
textarea.inp:-webkit-autofill,
#listeNotes input:-webkit-autofill,
input:-webkit-autofill,
textarea:-webkit-autofill,
select:-webkit-autofill {
  -webkit-text-fill-color: var(--ink) !important;
  /* Complété par le verrou final des champs, qui conserve l'arc doré. */
}

/* 3. Même chose quand la saisie automatique a lieu pendant le focus. */
.inp:-webkit-autofill:focus,
#listeNotes input:-webkit-autofill:focus {
  -webkit-box-shadow:
    inset 4px 0 0 var(--gold-2),
    0 0 0 3px rgba(212, 175, 55, .20),
    0 0 0 1000px var(--bg-2) inset !important;
  box-shadow:
    inset 4px 0 0 var(--gold-2),
    0 0 0 3px rgba(212, 175, 55, .20),
    0 0 0 1000px var(--bg-2) inset !important;
}

/* 4. Le cadre du code d'activation est concerné aussi. */
.pro-code-wrapper:has(:autofill) {
  background-color: var(--bg) !important;
}

/* ==========================================================================
   VERROU DÉFINITIF DES CHAMPS DE SAISIE
   --------------------------------------------------------------------------
   Quatre états, écrits une seule fois, en fin de feuille, tous prioritaires :
   repos (arc en veille), rempli (arc plus franc), saisie (arc en or pur + halo),
   refusé (arc rouge). Et l'état « rempli automatiquement » du navigateur —
   celui du copier-coller — conserve l'arc au lieu de le faire disparaître.
   Aucune règle antérieure ne peut plus reprendre le dessus : la suite de tests
   vérifie que ces déclarations sont bien les dernières.
   ========================================================================== */

/* 1. REPOS — l'arc est toujours là, en veille. */
.inp,
select.inp,
textarea.inp {
  background-color: var(--bg) !important;
  box-shadow: inset 4px 0 0 rgba(212, 175, 55, .30) !important;
}
#listeNotes input {
  background-color: var(--bg) !important;
  box-shadow: inset 3px 0 0 rgba(212, 175, 55, .30) !important;
}

/* 2. REMPLI — l'arc monte d'un cran. */
.inp.rempli,
select.inp.rempli,
textarea.inp.rempli {
  box-shadow: inset 4px 0 0 rgba(212, 175, 55, .72) !important;
}

/* 3. SAISIE — arc en or pur, halo, fond légèrement plus clair. */
.inp:focus,
select.inp:focus,
textarea.inp:focus {
  background-color: var(--bg-2) !important;
  border-color: var(--gold) !important;
  box-shadow:
    inset 4px 0 0 var(--gold-2),
    0 0 0 3px rgba(212, 175, 55, .20) !important;
}
#listeNotes input:focus {
  background-color: var(--bg-2) !important;
  border-color: var(--gold) !important;
  box-shadow: inset 3px 0 0 var(--gold-2), 0 0 0 3px rgba(212, 175, 55, .20) !important;
}

/* 4. REFUSÉ — arc rouge, et il gagne sur le focus. */
.inp.erreur,
select.inp.erreur,
textarea.inp.erreur,
.inp.erreur:focus,
#listeNotes input.note-invalide,
#listeNotes input.note-invalide:focus {
  border-color: rgba(239, 68, 68, .85) !important;
  box-shadow: inset 4px 0 0 var(--danger) !important;
}

/* 5. COLLER / REMPLISSAGE AUTOMATIQUE — l'arc reste exactement le même. */
.inp:-webkit-autofill,
.inp:-webkit-autofill:hover,
.inp:-webkit-autofill:active,
select.inp:-webkit-autofill,
textarea.inp:-webkit-autofill,
#listeNotes input:-webkit-autofill {
  -webkit-text-fill-color: var(--ink) !important;
  background-color: var(--bg) !important;
  background-image: none !important;
  border-color: var(--line-2) !important;
  -webkit-box-shadow: inset 4px 0 0 rgba(212, 175, 55, .30), 0 0 0 1000px var(--bg) inset !important;
  box-shadow: inset 4px 0 0 rgba(212, 175, 55, .30), 0 0 0 1000px var(--bg) inset !important;
  transition: background-color 99999s ease-in-out 0s !important;
}
.inp:-webkit-autofill:focus,
select.inp:-webkit-autofill:focus,
textarea.inp:-webkit-autofill:focus,
#listeNotes input:-webkit-autofill:focus {
  background-color: var(--bg-2) !important;
  border-color: var(--gold) !important;
  -webkit-box-shadow:
    inset 4px 0 0 var(--gold-2),
    0 0 0 3px rgba(212, 175, 55, .20),
    0 0 0 1000px var(--bg-2) inset !important;
  box-shadow:
    inset 4px 0 0 var(--gold-2),
    0 0 0 3px rgba(212, 175, 55, .20),
    0 0 0 1000px var(--bg-2) inset !important;
}

/* ==========================================================================
   CADRES « CARTON » — surfaces pleines, mates, tangibles
   --------------------------------------------------------------------------
   Chaque cadre qui contient des informations à saisir reçoit une couleur
   PLEINE (aucun dégradé translucide), une bordure nette et une ombre courte :
   il se lit comme un morceau de carton posé sur la page, pas comme un voile.
   ========================================================================== */

:root {
  --carton: #151E33;          /* la surface du carton */
  --carton-haut: #1A2440;     /* son arête supérieure, un ton au-dessus */
  --carton-bord: #2B3A57;     /* le chant du carton */
}

/* 1. Toutes les cartes de contenu. */
.carte,
.empty-state,
.stats .stat,
.workspace-overview,
.vocal-status,
.vocal-log,
.liste-erreurs,
#notesBrouillonInfo,
.profil-form {
  background: var(--carton) !important;
  background-image: none !important;
  border: 1px solid var(--carton-bord) !important;
  box-shadow:
    0 2px 0 0 rgba(4, 8, 18, .95),
    0 12px 22px rgba(0, 0, 0, .30),
    inset 0 1px 0 rgba(255, 255, 255, .06) !important;
}

/* 2. Le bandeau d'état de la classe garde son accent doré, mais plein. */
.workspace-overview {
  background: #1A2338 !important;
  border-color: rgba(196, 160, 48, .40) !important;
}

/* 3. Les fenêtres : même matière, un ton au-dessus pour se détacher. */
dialog {
  background: var(--carton-haut) !important;
  background-image: none !important;
  border: 1px solid var(--carton-bord) !important;
}
.dlg-profil {
  background: var(--carton-haut) !important;
  background-image: none !important;
}

/* 4. La carte d'accueil et ses tuiles : déjà opaques, on confirme la matière. */
#ecran-accueil .quick-card {
  background: #131C33 !important;
  background-image: none !important;
  border-color: var(--carton-bord) !important;
}
#ecran-accueil .quick-card .box {
  background: #1A2440 !important;
  background-image: none !important;
  border-color: #0A1120 !important;
}

/* 5. L'avertissement de brouillon garde son brun, en plein. */
#notesBrouillonInfo {
  background: #3F2110 !important;
  border-color: rgba(212, 175, 55, .35) !important;
}

/* ==========================================================================
   BOUTONS COLORÉS ADOUCIS — moins de saturation, moins de halo
   --------------------------------------------------------------------------
   Les aplats or, rouge et vert étaient très saturés et projetaient une ombre
   de la même couleur : sur le fond nuit, cela formait une auréole qui se lit
   comme une tache. On baisse la saturation d'un cran et on réduit fortement
   l'ombre colorée — le bouton reste franc, il ne bave plus.
   ========================================================================== */

/* OR — ton légèrement plus mat, ombre discrète. */
.btn.btn-p,
.btn.btn-b,
.btn.btn-pdf,
button.btn-profil-valider,
.btn.overview-primary,
button.pro-code-btn,
#btnModeManuel,
.btn.btn-mention#resetMentions {
  background: linear-gradient(135deg, #E9CE8C 0%, #D9B85C 26%, #B8902C 58%, #8A7126 100%) !important;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .38),
    0 6px 14px rgba(212, 175, 55, .16) !important;
}

/* ROUGE — plus sombre, ombre très légère. */
.btn.btn-r,
.btn-danger,
.btn.btn-danger#btnReinitClassement,
#btnFermerSelectEval,
#btnFermerSelectClasse,
.btn.btn-v.vocal-big-btn.listening,
button.btn.vocal-big-btn.listening,
.note-row-mic.listening {
  background: linear-gradient(135deg, #C62828 0%, #A81E1E 46%, #8B1414 100%) !important;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .22),
    0 6px 14px rgba(198, 40, 40, .18) !important;
}

/* VERT — désaturé, ombre légère. */
.btn.btn-valide,
#btnModeVocal,
.btn.btn-v.vocal-big-btn:not(.listening),
button.btn.vocal-big-btn:not(.listening) {
  background: linear-gradient(135deg, #3FBF6E 0%, #16A34A 48%, #0B7A45 100%) !important;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .28),
    0 6px 14px rgba(22, 163, 74, .16) !important;
}

/* BLEU — idem, pour rester cohérent entre familles. */
.btn.btn-s,
.btn.btn-mention#addMention {
  background: linear-gradient(135deg, #3F6BC8 0%, #2F5FB8 55%, #1E3F80 100%) !important;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .22),
    0 6px 14px rgba(47, 95, 184, .18) !important;
}

/* Les survols restent un ton au-dessus, sans regagner de halo. */
.btn.btn-p:hover,
.btn.btn-b:hover,
.btn.btn-pdf:hover,
button.btn-profil-valider:hover,
button.pro-code-btn:hover,
#btnModeManuel:hover,
.btn.btn-mention#resetMentions:hover {
  background: linear-gradient(135deg, #F3DCA2 0%, #E4C671 26%, #C69E33 58%, #967C2C 100%) !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .45), 0 8px 16px rgba(212, 175, 55, .18) !important;
}
.btn.btn-r:hover,
.btn-danger:hover,
.btn.btn-danger#btnReinitClassement:hover,
#btnFermerSelectEval:hover,
#btnFermerSelectClasse:hover {
  background: linear-gradient(135deg, #D43535 0%, #B72525 46%, #971818 100%) !important;
}
.btn.btn-valide:hover,
.btn.btn-s:hover,
.btn.btn-mention#addMention:hover {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .32), 0 8px 16px rgba(0, 0, 0, .25) !important;
}

/* ==========================================================================
   HALOS RÉSIDUELS — on éteint les anciennes ombres colorées
   --------------------------------------------------------------------------
   Des blocs antérieurs projetaient encore une ombre de la couleur du bouton
   (jusqu'à 48 % d'opacité) : c'est elle qui laissait une tache autour des
   boutons or, rouge et vert. Une seule règle les remplace toutes.
   ========================================================================== */

.btn.btn-p,
.btn.btn-b,
.btn.btn-pdf,
.btn.btn-r,
.btn.btn-s,
.btn.btn-v,
.btn.btn-valide,
.btn.btn-danger,
.btn.btn-mention,
.btn-profil-valider,
.btn-accueil-top,
.mode-btn,
#btnModeManuel,
#btnModeVocal,
.pro-code-btn,
#btnFermerSelectEval,
#btnFermerSelectClasse {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .25),
    0 5px 12px rgba(0, 0, 0, .28) !important;
}

/* Les boutons d'or gardent une trace chaude, mais très légère. */
.btn.btn-p,
.btn.btn-b,
.btn.btn-pdf,
.btn-profil-valider,
.pro-code-btn,
#btnModeManuel,
.btn.btn-mention#resetMentions {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .35),
    0 5px 12px rgba(212, 175, 55, .14) !important;
}

/* En saisie, le halo doré reste mais reste sage. */
#btnModeManuel.mode-actif,
#btnModeVocal.mode-actif {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .40),
    0 0 0 2px rgba(212, 175, 55, .30),
    0 6px 14px rgba(0, 0, 0, .25) !important;
}

/* ==========================================================================
   MICRO OUVERT — une couleur, rien qui bouge
   --------------------------------------------------------------------------
   Aucune onde, aucun battement : quand l'enseignant voit le micro rouge, il
   sait que la dictée écoute. Quand il est gris, elle est fermée. C'est tout.
   ========================================================================== */

.note-row-mic.listening {
  color: #FFFFFF !important;
  background: linear-gradient(135deg, #C62828 0%, #A81E1E 46%, #8B1414 100%) !important;
  border-color: #EF4444 !important;
  animation: none !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .22), 0 5px 12px rgba(0, 0, 0, .28) !important;
  transform: none !important;
}

/* Le bouton de dictée garde lui aussi sa couleur, sans mouvement. */
.btn.vocal-big-btn.listening,
.btn.btn-v.vocal-big-btn.listening {
  color: #FFFFFF !important;
  background: linear-gradient(135deg, #C62828 0%, #A81E1E 46%, #8B1414 100%) !important;
  border-color: #EF4444 !important;
  animation: none !important;
  transform: none !important;
}

/* ==========================================================================
   BARRE DE DÉFILEMENT — masquée partout
   --------------------------------------------------------------------------
   L'application se parcourt au doigt : la barre du navigateur n'apportait rien
   et mangeait 10 px de largeur sur chaque écran. Elle est retirée partout.
   Le défilement, lui, reste intact : on monte et on descend normalement.
   ========================================================================== */

/* Chrome, Edge, WebView Android : largeur nulle plutôt que « display: none »,
   qui a déjà cassé le défilement de certaines WebView anciennes. */
::-webkit-scrollbar {
  width: 0;
  height: 0;
  background: transparent;
}

/* Firefox et navigateurs récents. */
html,
body,
dialog,
#listeEvalsModale,
#listeClassesModale,
.nav-menu,
#listeNotes,
#listeEleves {
  scrollbar-width: none;
  -ms-overflow-style: none;
}

/* ==========================================================================
   FICHE PROFIL COMPACTE — tout visible d'un coup, Enregistrer en bas
   --------------------------------------------------------------------------
   La fiche tient à l'écran sans défilement : la photo remonte, les espacements
   se resserrent, et le bouton Enregistrer reste collé au bas de la fenêtre.
   Rien n'est supprimé, seuls les blancs sont ajustés.
   ========================================================================== */

#dlgProfil {
  padding: 16px 20px 16px !important;
  max-height: calc(100dvh - 24px) !important;
  overflow-y: auto;
}

/* 1. La photo remonte : moins d'air au-dessus, moins d'air en dessous. */
#dlgProfil .profil-avatar-wrap {
  margin-bottom: 8px !important;
  margin-top: 0 !important;
}
#dlgProfil .profil-avatar {
  /* Les trois valeurs doivent être égales : une min-height plus grande que la
     largeur transformait le rond en ovale. */
  width: 84px !important;
  height: 84px !important;
  min-height: 84px !important;
  max-height: 84px !important;
  aspect-ratio: 1 / 1 !important;
  flex: none;
}

/* 2. Le titre suit la photo sans temps mort. */
#dlgProfil h2,
#dlgProfil h2#profilTitre {
  font-size: calc(20px * var(--fs-scale)) !important;
  margin: 0 0 10px !important;
}

/* 3. Le bloc des champs se resserre : même contenu, moins de blancs. */
#dlgProfil .profil-form {
  padding: 14px 16px !important;
  border-radius: 18px !important;
}
#dlgProfil .profil-label {
  margin: 0 0 6px !important;
  font-size: calc(11.5px * var(--fs-scale)) !important;
}
#dlgProfil .profil-label.mt { margin-top: 12px !important; }
#dlgProfil .profil-form .inp {
  height: 46px !important;
  min-height: 46px !important;
}
#dlgProfil .profil-hint {
  margin: 4px 0 0 !important;
  font-size: calc(11px * var(--fs-scale)) !important;
}

/* 4. Enregistrer reste en bas, visible, avec son socle. */
#dlgProfil .btn-profil-valider {
  height: 52px !important;
  margin-top: 12px !important;
  position: sticky;
  bottom: 0;
}

/* 5. Sur un écran très court, la fiche défile plutôt que de couper le bouton. */
@media (max-height: 640px) {
  #dlgProfil .profil-avatar {
    width: 68px !important; height: 68px !important;
    min-height: 68px !important; max-height: 68px !important;
  }
  #dlgProfil .profil-form .inp { height: 44px !important; min-height: 44px !important; }
  #dlgProfil .profil-label.mt { margin-top: 9px !important; }
}

/* ==========================================================================
   INSTALLATION — invitation discrète, et persistance des données
   ========================================================================== */

.invite-installation {
  position: fixed;
  left: 12px;
  right: 12px;
  bottom: calc(12px + var(--safe-b));
  z-index: 120;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 16px;
  background: #151E33;
  border: 1px solid var(--carton-bord, #2B3A57);
  border-radius: 16px;
  box-shadow: 0 2px 0 0 rgba(4, 8, 18, .95), 0 14px 30px rgba(0, 0, 0, .5);
  animation: inviteIn .35s cubic-bezier(.2, .7, .2, 1) both;
}
@keyframes inviteIn {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
.invite-texte b {
  display: block;
  font-size: calc(14.5px * var(--fs-scale));
  color: var(--gold-2);
  margin-bottom: 3px;
}
.invite-texte span {
  font-size: calc(12.5px * var(--fs-scale));
  color: var(--ink-2);
  line-height: 1.4;
}
.invite-actions {
  display: flex;
  gap: 8px;
}
.invite-actions .btn {
  flex: 1;
  margin: 0;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .22), 0 5px 12px rgba(0, 0, 0, .28);
}
@media (prefers-reduced-motion: reduce) {
  .invite-installation { animation: none !important; }
}
