/* ==========================================================================
   Socle de jetons — portail enseignant MARW
   ==========================================================================

   🔴 Trois défauts réparés dans ce bloc.

   1. La police venait de fonts.googleapis.com : deux preconnect et une feuille
      BLOQUANTE vers un tiers, sur chaque page d'un portail ministériel. Elle
      est désormais servie par le portail (voir @font-face plus bas) et la
      pile de repli nomme explicitement une police ARABE — Inter ne porte
      aucun glyphe arabe, et l'interface est lue en arabe.

   2. Aucun état de focus n'existait : `grep -c focus styles.css` rendait 0 sur
      563 lignes. Une saisie de notes se fait au clavier, en tabulant d'un
      élève au suivant — le portail était inutilisable ainsi.

   3. Aucun `prefers-color-scheme`, aucun `prefers-reduced-motion` : un fond
      clair imposé, en salle d'examen comme le soir.

   Les jetons sont volontairement neutres et réutilisables : ils sont destinés
   à devenir le socle commun des trois portails MARW.
   ========================================================================== */

:root {
  color-scheme: light dark;

  /* — Couleurs de fond et de texte — */
  --ink: #1f2a24;
  --ink-soft: #3c4a40;
  --muted: #6e6656;
  --line: #e7dcc4;
  --line-strong: #d6c7a4;
  --surface: #fffdf8;
  --surface-raised: #fffdf8;
  --wash: #f6f1e6;

  /* — Identité des Affaires religieuses : vert de zellige, or de stuc,
       crème de plâtre, faïence bleue et terre cuite pour les accents — */
  --brand: #2e6b4f;
  --brand-dark: #1d4a35;
  --brand-night: #143627;
  --brand-wash: #e6efe6;
  --gold: #b8914a;
  --gold-light: #e3cc94;
  --gold-wash: #f3e8cc;
  --blue: #2f5f7a;
  --blue-wash: #e4edf2;
  --orange: #a9542f;
  --orange-wash: #f6e4dd;
  --danger: #a33b2b;
  --danger-wash: #f6e0da;
  --ok: #2e6b4f;
  --ok-wash: #e6efe6;

  /* Étoile à huit branches (khatam) en tuile répétable : or sur vert pour
     les bandeaux, or éteint sur crème pour le fond de page. */
  --motif-sombre: url("data:image/svg+xml,%3Csvg xmlns='http%3A//www.w3.org/2000/svg' width='72' height='72' viewBox='0 0 72 72'%3E%3Cg fill='none' stroke='%23E3CC94' stroke-width='1' stroke-opacity='0.22'%3E%3Cpath d='M36.00 16.00 L41.86 21.86 L50.14 21.86 L50.14 30.14 L56.00 36.00 L50.14 41.86 L50.14 50.14 L41.86 50.14 L36.00 56.00 L30.14 50.14 L21.86 50.14 L21.86 41.86 L16.00 36.00 L21.86 30.14 L21.86 21.86 L30.14 21.86Z M0.00 -20.00 L5.86 -14.14 L14.14 -14.14 L14.14 -5.86 L20.00 0.00 L14.14 5.86 L14.14 14.14 L5.86 14.14 L0.00 20.00 L-5.86 14.14 L-14.14 14.14 L-14.14 5.86 L-20.00 0.00 L-14.14 -5.86 L-14.14 -14.14 L-5.86 -14.14Z M72.00 -20.00 L77.86 -14.14 L86.14 -14.14 L86.14 -5.86 L92.00 0.00 L86.14 5.86 L86.14 14.14 L77.86 14.14 L72.00 20.00 L66.14 14.14 L57.86 14.14 L57.86 5.86 L52.00 0.00 L57.86 -5.86 L57.86 -14.14 L66.14 -14.14Z M0.00 52.00 L5.86 57.86 L14.14 57.86 L14.14 66.14 L20.00 72.00 L14.14 77.86 L14.14 86.14 L5.86 86.14 L0.00 92.00 L-5.86 86.14 L-14.14 86.14 L-14.14 77.86 L-20.00 72.00 L-14.14 66.14 L-14.14 57.86 L-5.86 57.86Z M72.00 52.00 L77.86 57.86 L86.14 57.86 L86.14 66.14 L92.00 72.00 L86.14 77.86 L86.14 86.14 L77.86 86.14 L72.00 92.00 L66.14 86.14 L57.86 86.14 L57.86 77.86 L52.00 72.00 L57.86 66.14 L57.86 57.86 L66.14 57.86Z'/%3E%3Cpath d='M36.00 27.00 L38.64 29.64 L42.36 29.64 L42.36 33.36 L45.00 36.00 L42.36 38.64 L42.36 42.36 L38.64 42.36 L36.00 45.00 L33.36 42.36 L29.64 42.36 L29.64 38.64 L27.00 36.00 L29.64 33.36 L29.64 29.64 L33.36 29.64Z'/%3E%3Cpath d='M36.0 0V16.0 M36.0 72V56.0 M0 36.0H16.0 M72 36.0H56.0'/%3E%3C/g%3E%3C/svg%3E");
  --motif-clair: url("data:image/svg+xml,%3Csvg xmlns='http%3A//www.w3.org/2000/svg' width='72' height='72' viewBox='0 0 72 72'%3E%3Cg fill='none' stroke='%23B89553' stroke-width='1' stroke-opacity='0.2'%3E%3Cpath d='M36.00 16.00 L41.86 21.86 L50.14 21.86 L50.14 30.14 L56.00 36.00 L50.14 41.86 L50.14 50.14 L41.86 50.14 L36.00 56.00 L30.14 50.14 L21.86 50.14 L21.86 41.86 L16.00 36.00 L21.86 30.14 L21.86 21.86 L30.14 21.86Z M0.00 -20.00 L5.86 -14.14 L14.14 -14.14 L14.14 -5.86 L20.00 0.00 L14.14 5.86 L14.14 14.14 L5.86 14.14 L0.00 20.00 L-5.86 14.14 L-14.14 14.14 L-14.14 5.86 L-20.00 0.00 L-14.14 -5.86 L-14.14 -14.14 L-5.86 -14.14Z M72.00 -20.00 L77.86 -14.14 L86.14 -14.14 L86.14 -5.86 L92.00 0.00 L86.14 5.86 L86.14 14.14 L77.86 14.14 L72.00 20.00 L66.14 14.14 L57.86 14.14 L57.86 5.86 L52.00 0.00 L57.86 -5.86 L57.86 -14.14 L66.14 -14.14Z M0.00 52.00 L5.86 57.86 L14.14 57.86 L14.14 66.14 L20.00 72.00 L14.14 77.86 L14.14 86.14 L5.86 86.14 L0.00 92.00 L-5.86 86.14 L-14.14 86.14 L-14.14 77.86 L-20.00 72.00 L-14.14 66.14 L-14.14 57.86 L-5.86 57.86Z M72.00 52.00 L77.86 57.86 L86.14 57.86 L86.14 66.14 L92.00 72.00 L86.14 77.86 L86.14 86.14 L77.86 86.14 L72.00 92.00 L66.14 86.14 L57.86 86.14 L57.86 77.86 L52.00 72.00 L57.86 66.14 L57.86 57.86 L66.14 57.86Z'/%3E%3Cpath d='M36.00 27.00 L38.64 29.64 L42.36 29.64 L42.36 33.36 L45.00 36.00 L42.36 38.64 L42.36 42.36 L38.64 42.36 L36.00 45.00 L33.36 42.36 L29.64 42.36 L29.64 38.64 L27.00 36.00 L29.64 33.36 L29.64 29.64 L33.36 29.64Z'/%3E%3Cpath d='M36.0 0V16.0 M36.0 72V56.0 M0 36.0H16.0 M72 36.0H56.0'/%3E%3C/g%3E%3C/svg%3E");

  /* — Élévation, rayons, rythme — */
  --shadow: 0 12px 28px rgba(18, 34, 54, 0.11);
  --shadow-soft: 0 2px 8px rgba(18, 34, 54, 0.07);
  --radius: 14px;
  --radius-sm: 9px;
  --gap: 16px;
  --gap-sm: 10px;

  /* — Typographie — */
  --font-ui: "Inter Portail", "Segoe UI", "Noto Sans Arabic", Tahoma, Arial, sans-serif;
  --font-num: "Inter Portail", "Segoe UI", Tahoma, Arial, sans-serif;
  --font-titre: "Amiri Portail", "Amiri", "Noto Naskh Arabic", Georgia, serif;

  --focus-ring: 0 0 0 3px var(--brand-wash), 0 0 0 5px var(--brand);
  --motion: 160ms;

  font-family: var(--font-ui);
}

/* Thème sombre : redéfinition des SEULS jetons, jamais des composants — un
   composant qui définirait sa couleur dans ce bloc serait invisible dans
   l'autre thème. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ink: #f2eee3;
    --ink-soft: #d5d0c2;
    --muted: #a9b3a8;
    --line: #2b3d33;
    --line-strong: #3b5144;
    --surface: #172720;
    --surface-raised: #1c2e26;
    --wash: #0f1a15;
    --brand: #5aa383;
    --brand-dark: #e3cc94;
    --brand-wash: #1d3a2d;
    --gold-wash: #2a2a1c;
    --blue: #7fb0cc;
    --blue-wash: #16283f;
    --orange: #e0996f;
    --orange-wash: #3a2419;
    --danger: #f08a7a;
    --danger-wash: #3a1c1c;
    --ok: #7cc39f;
    --ok-wash: #173226;
    --motif-clair: var(--motif-sombre);
    --shadow: 0 14px 30px rgba(0, 0, 0, 0.45);
    --shadow-soft: 0 2px 10px rgba(0, 0, 0, 0.35);
  }
}

:root[data-theme="dark"] {
  --ink: #f2eee3;
  --ink-soft: #d5d0c2;
  --muted: #a9b3a8;
  --line: #2b3d33;
  --line-strong: #3b5144;
  --surface: #172720;
  --surface-raised: #1c2e26;
  --wash: #0f1a15;
  --brand: #5aa383;
  --brand-dark: #e3cc94;
  --brand-wash: #1d3a2d;
  --gold-wash: #2a2a1c;
  --blue: #7fb0cc;
  --blue-wash: #16283f;
  --orange: #e0996f;
  --orange-wash: #3a2419;
  --danger: #f08a7a;
  --danger-wash: #3a1c1c;
  --ok: #7cc39f;
  --ok-wash: #173226;
  --motif-clair: var(--motif-sombre);
  --shadow: 0 14px 30px rgba(0, 0, 0, 0.45);
  --shadow-soft: 0 2px 10px rgba(0, 0, 0, 0.35);
}

/* La police est servie par le portail : plus aucun aller-retour vers un tiers,
   et le rendu ne dépend plus de la joignabilité d'un CDN. `swap` garantit que
   le texte s'affiche immédiatement dans la police de repli. */
@font-face {
  font-family: "Inter Portail";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: local("Inter"), local("Inter Variable"), local("Segoe UI"), local("Roboto");
}

/* Le focus, partout et visible. */
:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
  border-radius: var(--radius-sm);
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Contenu réservé aux technologies d'assistance. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--wash);
  color: var(--ink);
}

button,
input,
select {
  font: inherit;
}

.app-shell {
  min-height: 100vh;
}

.topbar {
  position: sticky;
  top: 0;
  z-index: 5;
  background: var(--brand);
  color: #fff;
  box-shadow: 0 8px 22px rgba(0, 103, 86, 0.22);
}

.topbar-inner {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 16px;
  align-items: center;
  width: min(1120px, 100%);
  margin: 0 auto;
  padding: 18px 20px;
}

.identity {
  min-width: 0;
}

.eyebrow {
  margin: 0 0 4px;
  font-size: 0.78rem;
  letter-spacing: 0;
  opacity: 0.78;
}

.identity h1 {
  margin: 0;
  font-size: clamp(1.35rem, 3vw, 2.1rem);
  font-weight: 800;
}

.identity p {
  margin: 6px 0 0;
  color: rgba(255, 255, 255, 0.84);
}

.toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
}

.language-switch {
  display: inline-flex;
  border: 1px solid rgba(255, 255, 255, 0.34);
  border-radius: 999px;
  padding: 3px;
  background: rgba(255, 255, 255, 0.12);
}

.language-switch button,
.icon-button {
  min-width: 38px;
  min-height: 38px;
  border: 0;
  border-radius: 999px;
  color: #fff;
  background: transparent;
  cursor: pointer;
}

.language-switch button.active {
  color: var(--brand-dark);
  background: #fff;
}

.icon-button {
  border: 1px solid rgba(255, 255, 255, 0.3);
  font-weight: 700;
}

.page {
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr);
  gap: 20px;
  width: min(1120px, 100%);
  margin: 0 auto;
  padding: 20px;
}

.side-nav {
  position: sticky;
  top: 104px;
  align-self: start;
  display: grid;
  gap: 8px;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface);
  box-shadow: var(--shadow);
}

.nav-button {
  display: grid;
  grid-template-columns: 34px 1fr;
  gap: 10px;
  align-items: center;
  min-height: 48px;
  border: 0;
  border-radius: 8px;
  padding: 8px 10px;
  color: var(--ink);
  background: transparent;
  text-align: start;
  cursor: pointer;
}

.nav-button.active {
  color: #fff;
  background: var(--brand);
}

/* .nav-link is a real <a> (the concours entry points at its own route, not at a
   JS panel) : it inherits .nav-button but must not carry the browser underline. */
.nav-link {
  text-decoration: none;
}

.nav-icon {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 8px;
  background: rgba(0, 143, 120, 0.12);
  font-weight: 800;
}

.nav-button.active .nav-icon {
  color: var(--brand-dark);
  background: #fff;
}

.content {
  min-width: 0;
}

.summary-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
  margin-bottom: 20px;
}

.metric {
  min-width: 0;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 14px;
  background: var(--surface);
  box-shadow: var(--shadow);
}

.metric span {
  display: block;
  color: var(--muted);
  font-size: 0.82rem;
}

.metric strong {
  display: block;
  margin-top: 6px;
  font-size: 1.45rem;
}

.panel {
  display: none;
}

.panel.active {
  display: block;
}

.panel-header {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  align-items: end;
  margin: 0 0 14px;
}

.panel-header h2 {
  margin: 0;
  font-size: 1.2rem;
}

.panel-header p {
  margin: 4px 0 0;
  color: var(--muted);
}

.grid-list {
  display: grid;
  gap: 12px;
}

.item-card {
  display: grid;
  gap: 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 16px;
  background: var(--surface);
  box-shadow: var(--shadow);
}

.item-card .row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  align-items: center;
}

.item-card h3 {
  margin: 0;
  font-size: 1rem;
}

.item-card p {
  margin: 0;
  color: var(--muted);
}

.tag-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.tag {
  display: inline-flex;
  align-items: center;
  min-height: 28px;
  border-radius: 999px;
  padding: 4px 10px;
  color: var(--brand-dark);
  background: rgba(0, 143, 120, 0.12);
  font-size: 0.82rem;
  font-weight: 700;
}

.tag.blue {
  color: #1559a8;
  background: rgba(43, 125, 233, 0.12);
}

.tag.orange {
  color: #91410d;
  background: rgba(241, 120, 45, 0.14);
}

.tag.danger {
  color: #a21e28;
  background: rgba(215, 55, 63, 0.12);
}

.grade-table {
  width: 100%;
  border-collapse: collapse;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface);
  box-shadow: var(--shadow);
}

.grade-table th,
.grade-table td {
  padding: 12px 10px;
  border-bottom: 1px solid var(--line);
  text-align: start;
}

.grade-table th {
  color: var(--muted);
  font-size: 0.82rem;
  font-weight: 700;
}

.grade-table tr:last-child td {
  border-bottom: 0;
}

.grade-exam-card {
  gap: 14px;
}

.grade-exam-card > .row {
  align-items: flex-start;
}

.grade-exam-card .row > div {
  min-width: 0;
}

.grade-table-compact {
  box-shadow: none;
}

.grade-table-compact th,
.grade-table-compact td {
  padding: 10px;
}

.score {
  font-weight: 800;
  color: var(--brand-dark);
}

.score.low {
  color: var(--danger);
}

.grade-input,
.attendance-select {
  width: 100%;
  min-width: 112px;
  min-height: 38px;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 8px 10px;
  color: var(--ink);
  background: #fff;
}

.grade-input {
  max-width: 120px;
  font-weight: 800;
}

.attendance-select {
  max-width: 210px;
}

.grade-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 10px;
  align-items: center;
}

.grade-message {
  flex: 1 1 220px;
  min-height: 20px;
  color: var(--muted);
  font-weight: 700;
}

.grade-message.error {
  color: var(--danger);
}

.profile-layout {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.empty-state,
.loading-state,
.login-shell {
  display: grid;
  place-items: center;
  min-height: 100vh;
  padding: 20px;
}

.empty-box,
.login-card {
  width: min(460px, 100%);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 20px;
  background: var(--surface);
  box-shadow: var(--shadow);
}

.login-card h1 {
  margin: 0 0 6px;
}

.login-card p {
  margin: 0 0 16px;
  color: var(--muted);
}

.form-grid {
  display: grid;
  gap: 12px;
}

.form-grid label {
  display: grid;
  gap: 6px;
  color: var(--muted);
  font-size: 0.9rem;
}

.form-grid input {
  width: 100%;
  min-height: 44px;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 10px 12px;
  color: var(--ink);
  background: #fff;
}

.primary-button {
  min-height: 46px;
  border: 0;
  border-radius: 8px;
  color: #fff;
  background: var(--brand);
  font-weight: 800;
  cursor: pointer;
}

.primary-button.compact,
.secondary-button {
  min-height: 40px;
  padding: 8px 12px;
}

.secondary-button {
  border: 1px solid var(--brand);
  border-radius: 8px;
  color: var(--brand-dark);
  background: #fff;
  font-weight: 800;
  cursor: pointer;
}

button:disabled,
input:disabled,
select:disabled {
  cursor: wait;
  opacity: 0.65;
}

.error-message {
  min-height: 20px;
  color: var(--danger);
  font-weight: 700;
}

.spinner {
  width: 42px;
  height: 42px;
  border: 4px solid rgba(0, 143, 120, 0.18);
  border-top-color: var(--brand);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

[dir="rtl"] .nav-button,
[dir="rtl"] .grade-table th,
[dir="rtl"] .grade-table td {
  text-align: right;
}

@media (max-width: 860px) {
  .topbar-inner {
    grid-template-columns: 1fr;
  }

  .toolbar {
    justify-content: space-between;
  }

  .page {
    grid-template-columns: 1fr;
    padding: 14px;
  }

  .side-nav {
    position: sticky;
    top: 0;
    /* 🔴 `repeat(5, …)` était figé alors que la navigation compte SIX entrées
       — sept avec le concours : la dernière sortait de l'écran, atteignable
       par un défilement que rien ne signalait. */
    grid-auto-flow: column;
    grid-auto-columns: minmax(74px, 1fr);
    grid-template-columns: none;
    overflow-x: auto;
    border-radius: 0;
    margin: 0 -14px;
    box-shadow: none;
  }

  .nav-button {
    grid-template-columns: 1fr;
    justify-items: center;
    min-width: 82px;
    font-size: 0.8rem;
    text-align: center;
  }

  .summary-grid,
  .profile-layout {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 560px) {
  .summary-grid,
  .profile-layout {
    grid-template-columns: 1fr;
  }

  .panel-header {
    display: block;
  }

  .item-card .row {
    display: grid;
  }

  .grade-table {
    display: block;
    overflow-x: auto;
    white-space: nowrap;
  }
}

/* ==========================================================================
   Composants ajoutés le 23/08/2026 — et les défauts qu'ils réparent
   ========================================================================== */

/* — Navigation ————————————————————————————————————————————————————
   🔴 La grille était figée à cinq colonnes (`repeat(5, …)`) sous 860 px alors
   que la navigation compte SIX entrées — sept avec le concours. La sixième
   sortait de l'écran, atteignable seulement par un défilement que rien ne
   signalait. `auto-fit` s'adapte au nombre réel d'entrées. */
.side-nav {
  display: grid;
  gap: 4px;
}

.nav-button {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: var(--gap-sm);
  padding: 10px 12px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--ink-soft);
  text-decoration: none;
  font-weight: 600;
  transition: background var(--motion), color var(--motion);
}

.nav-button:hover {
  background: var(--wash);
  color: var(--ink);
}

.nav-button.active {
  background: var(--brand-wash);
  color: var(--brand-dark);
  border-color: var(--brand);
}

/* 🔴 Les « icônes » étaient les lettres H/P/E/N/M/I — des mnémoniques
   françaises, muettes en arabe et en anglais. */
.nav-icon {
  width: 20px;
  height: 20px;
  flex: none;
}

/* — Sélecteur de langue ————————————————————————————————————————————
   Ce sont désormais des LIENS : la langue est décidée par le serveur et
   survit au rechargement. */
.language-switch {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
}

.lang-link {
  min-width: 40px;
  padding: 5px 12px;
  border-radius: 999px;
  color: var(--muted);
  font-weight: 700;
  font-size: 0.86rem;
  text-align: center;
  text-decoration: none;
  transition: background var(--motion), color var(--motion);
}

.lang-link:hover {
  color: var(--ink);
}

.lang-link.active {
  background: var(--brand);
  color: #fff;
}

/* — Outils de panneau : recherche élève ————————————————————————————
   🔴 Retrouver un élève dans une promotion de deux cents se faisait au Ctrl+F
   du navigateur. */
.panel-tools {
  display: flex;
  align-items: center;
  gap: var(--gap-sm);
  flex-wrap: wrap;
}

.search-field {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  min-width: min(280px, 100%);
}

.search-field:focus-within {
  border-color: var(--brand);
  box-shadow: var(--focus-ring);
}

.search-field input {
  border: 0;
  outline: none;
  background: transparent;
  color: var(--ink);
  width: 100%;
}

.search-icon {
  width: 17px;
  height: 17px;
  color: var(--muted);
  flex: none;
}

.filter-count {
  margin: 0;
  color: var(--muted);
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
}

/* — Retour de sauvegarde ————————————————————————————————————————————
   🔴 Le message d'échec était le littéral anglais « Error », sans cause ni
   geste à faire. Il a maintenant un statut, une couleur et une phrase. */
.grade-message {
  flex: 1;
  min-height: 1.2em;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--muted);
}

.grade-message.ok {
  color: var(--ok);
}

.grade-message.error {
  color: var(--danger);
}

.grade-message.pending {
  color: var(--blue);
}

/* Une carte dont les saisies ne sont pas enregistrées se voit. */
.grade-exam-card.is-dirty {
  border-color: var(--orange);
  box-shadow: inset 3px 0 0 0 var(--orange), var(--shadow-soft);
}

[dir="rtl"] .grade-exam-card.is-dirty {
  box-shadow: inset -3px 0 0 0 var(--orange), var(--shadow-soft);
}

.grade-exam-card.is-submitted {
  opacity: 0.75;
}

/* Une note hors barème se signale sur SA ligne, jamais dans un message global. */
tr.row-invalid {
  background: var(--danger-wash);
}

tr.row-invalid .grade-input {
  border-color: var(--danger);
}

.grade-input,
.attendance-select {
  padding: 7px 10px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

/* — Confirmation de soumission ————————————————————————————————————
   🔴 « Soumettre l'examen » verrouille les notes définitivement et partait au
   premier clic. Le dialogue est in-page : un window.confirm natif fige aussi
   le pilotage navigateur de la recette. */
.confirm-sheet {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: grid;
  place-items: center;
  padding: var(--gap);
  background: rgba(9, 16, 26, 0.55);
}

.confirm-sheet[hidden] {
  display: none;
}

.confirm-box {
  width: min(420px, 100%);
  padding: 22px;
  border-radius: var(--radius);
  background: var(--surface-raised);
  color: var(--ink);
  box-shadow: var(--shadow);
}

.confirm-box h4 {
  margin: 0 0 8px;
  font-size: 1.05rem;
}

.confirm-box p {
  margin: 0 0 18px;
  color: var(--ink-soft);
  line-height: 1.5;
}

.confirm-actions {
  display: flex;
  gap: var(--gap-sm);
  justify-content: flex-end;
}

.ghost-button {
  padding: 9px 16px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--ink);
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
  display: inline-block;
}

.ghost-button:hover {
  background: var(--wash);
}

/* — Accueil « à faire » ————————————————————————————————————————————
   🔴 L'accueil affichait quatre compteurs et la moyenne du premier examen de
   la liste, sans qu'aucun n'ouvre sur une action. */
.action-card {
  display: grid;
  gap: var(--gap-sm);
  align-content: start;
}

.action-card .primary-button,
.action-card .ghost-button {
  justify-self: start;
}

/* — Saisie au TÉLÉPHONE ————————————————————————————————————————————
   🔴 Sous 560 px, la table passait en `white-space: nowrap` + défilement
   horizontal : le geste principal du produit — saisir une note — exigeait de
   faire glisser la table sur un téléphone. Chaque ligne devient une carte,
   étiquetée par l'en-tête de sa colonne. */
@media (max-width: 560px) {
  .grade-table,
  .grade-table thead,
  .grade-table tbody,
  .grade-table tr,
  .grade-table td {
    display: block;
    white-space: normal;
    overflow: visible;
  }

  .grade-table thead {
    display: none;
  }

  .grade-table tr {
    margin-bottom: var(--gap-sm);
    padding: 12px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface);
  }

  .grade-table td {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--gap-sm);
    padding: 5px 0;
    border: 0;
  }

  .grade-table td::before {
    content: attr(data-label);
    color: var(--muted);
    font-size: 0.82rem;
    font-weight: 600;
  }

  /* Le nom de l'élève est le titre de la carte, pas une paire étiquette-valeur. */
  .grade-table td:first-child {
    display: block;
    margin-bottom: 4px;
    font-weight: 700;
    font-size: 1rem;
  }

  .grade-table td:first-child::before {
    content: none;
  }

  .grade-input,
  .attendance-select {
    width: 100%;
    min-height: 42px; /* cible tactile confortable */
  }
}

/* ==========================================================================
   Identité moresque des Affaires religieuses (29/09/2026)
   ==========================================================================

   Même famille que le portail d'admission (vert, or, crème, géométrie), avec
   son vocabulaire propre : étoile à huit branches plutôt que losange, arc
   outrepassé du mihrab pour les cadres, calligraphie Amiri pour les titres.
   Cette couche ne touche que l'apparence : aucun composant n'y change de
   comportement. */

/* L'Amiri (licence OFL) est servie par le portail, sans tiers : seule la
   graisse des titres, en deux découpes (arabe, latin). */
@font-face {
  font-family: "Amiri Portail";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/static/polices/amiri-700-arabe.woff2") format("woff2");
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-08FF, U+200C-200E, U+FB50-FDFF, U+FE70-FEFC;
}

@font-face {
  font-family: "Amiri Portail";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/static/polices/amiri-700-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+20AC;
}

body {
  background-color: var(--wash);
  background-image: var(--motif-clair);
  background-size: 72px 72px;
  background-attachment: fixed;
}

/* — Bandeau : vert à étoiles, filet d'or, emblème en médaillon — */
.topbar {
  background-color: var(--brand-dark);
  background-image: var(--motif-sombre), linear-gradient(160deg, var(--brand-dark), var(--brand-night));
  background-size: 72px 72px, auto;
  border-bottom: 3px solid var(--gold);
  box-shadow: 0 1px 0 var(--gold-light) inset, 0 10px 24px rgba(20, 54, 39, 0.24);
}

.topbar-inner {
  grid-template-columns: auto 1fr auto;
}

.topbar-embleme {
  width: 64px;
  height: 64px;
  padding: 5px;
  border-radius: 50%;
  background: #fffdf8;
  box-shadow: 0 0 0 2px var(--gold), 0 0 0 5px rgba(227, 204, 148, 0.3);
  object-fit: contain;
}

.eyebrow {
  color: var(--gold-light);
  opacity: 1;
  font-weight: 600;
}

.identity h1 {
  font-family: var(--font-titre);
  font-weight: 700;
  line-height: 1.3;
}

.topbar .language-switch {
  border-color: rgba(227, 204, 148, 0.4);
  background: rgba(20, 54, 39, 0.35);
}

.topbar .lang-link {
  color: rgba(255, 255, 255, 0.82);
}

.topbar .lang-link.active {
  background: var(--gold-light);
  color: var(--brand-night);
}

.topbar .icon-button {
  border-color: rgba(227, 204, 148, 0.45);
}

/* — Navigation : un mihrab de plâtre, l'entrée courante en vert filetée d'or — */
.side-nav {
  padding: 28px 10px 12px;
  border: 1px solid var(--gold);
  border-radius: 50% 50% var(--radius) var(--radius) / 44px 44px var(--radius) var(--radius);
  background: var(--surface);
  box-shadow: 0 0 0 4px var(--surface), 0 0 0 5px var(--gold-light), var(--shadow-soft);
}

.nav-button.active {
  background: var(--brand-dark);
  border-color: var(--brand-dark);
  color: #fff;
  box-shadow: inset 4px 0 0 var(--gold-light);
}

[dir="rtl"] .nav-button.active {
  box-shadow: inset -4px 0 0 var(--gold-light);
}

/* — Compteurs : niches à l'arc outrepassé, chiffres calligraphiés — */
.metric {
  position: relative;
  padding-top: 18px;
  border: 1px solid var(--line);
  border-top: 3px solid var(--gold);
  border-radius: 40% 40% var(--radius-sm) var(--radius-sm) / 22px 22px var(--radius-sm) var(--radius-sm);
  background: var(--surface);
  box-shadow: var(--shadow-soft);
  text-align: center;
}

.metric strong {
  font-family: var(--font-titre);
  font-size: 1.9rem;
  font-weight: 700;
  line-height: 1.1;
  color: var(--brand-dark);
}

/* — Titres de panneau : calligraphie et filet d'or à étoile — */
.panel-header h2 {
  font-family: var(--font-titre);
  font-size: 1.6rem;
  font-weight: 700;
  color: var(--brand-dark);
}

.panel-header h2::after {
  content: "";
  display: block;
  width: 72px;
  height: 2px;
  margin-top: 6px;
  background: linear-gradient(90deg, var(--gold), var(--gold-light));
}

.item-card {
  border-color: var(--line);
  border-inline-start: 3px solid var(--gold-light);
  background: var(--surface);
}

.action-card {
  border-inline-start-color: var(--gold);
}

.primary-button {
  background: var(--brand-dark);
  box-shadow: inset 0 -3px 0 var(--gold);
  text-decoration: none;
}

.primary-button:hover {
  background: var(--brand);
}

.secondary-button,
.ghost-button {
  border-color: var(--gold);
  color: var(--brand-dark);
  background: var(--surface);
}

/* — Connexion : fond vert à étoiles, carte en arc de mihrab, emblème en clé — */
.login-shell {
  padding-top: 80px;
  background-color: var(--brand-dark);
  background-image: var(--motif-sombre), linear-gradient(160deg, var(--brand-dark), var(--brand-night));
  background-size: 72px 72px, auto;
}

.login-card {
  position: relative;
  padding: 26px 26px 24px;
  border: 0;
  border-radius: 50% 50% var(--radius) var(--radius) / 80px 80px var(--radius) var(--radius);
  box-shadow: 0 0 0 5px rgba(255, 253, 248, 0.12), 0 0 0 6px var(--gold), 0 20px 48px rgba(0, 0, 0, 0.3);
  text-align: center;
}

/* Le sélecteur de langue quitte la carte : l'emblème occupe la clé de l'arc. */
.login-card .toolbar {
  position: fixed;
  top: 16px;
  inset-inline-end: 16px;
  z-index: 2;
}

.login-card .language-switch {
  border-color: rgba(227, 204, 148, 0.4);
  background: rgba(20, 54, 39, 0.45);
}

.login-card .lang-link {
  color: rgba(255, 255, 255, 0.85);
}

.login-card .lang-link.active {
  background: var(--gold-light);
  color: var(--brand-night);
}

.login-brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  margin: -84px 0 14px;
}

.login-embleme {
  width: 96px;
  height: 96px;
  padding: 7px;
  border-radius: 50%;
  background: var(--surface);
  box-shadow: 0 0 0 3px var(--gold), 0 0 0 8px var(--surface), 0 0 0 9px var(--gold-light);
}

.login-embleme img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.login-ministere {
  margin-top: 8px;
  font-family: var(--font-titre);
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--brand-dark);
}

/* Or foncé : l'or du stuc sur crème reste sous 4,5:1 en petit corps. */
.login-portail {
  font-size: 0.8rem;
  font-weight: 700;
  color: #8a6d33;
}

.login-card h1 {
  font-family: var(--font-titre);
  font-size: 1.7rem;
  color: var(--brand-dark);
}

.login-card .form-grid {
  text-align: start;
}

.form-grid input {
  background: var(--surface);
}

.form-grid input:focus {
  border-color: var(--gold);
}

.login-aux a {
  color: var(--brand-dark);
  font-weight: 700;
}

/* Sous 860 px, la navigation devient une bande horizontale : l'arc du mihrab
   n'y a plus de sens, elle reprend un filet d'or droit. Le bandeau passe sur
   deux rangs — emblème et identité, puis les outils. */
@media (max-width: 860px) {
  .topbar-inner {
    grid-template-columns: auto 1fr;
    padding: 12px 14px;
  }

  .topbar .toolbar {
    grid-column: 1 / -1;
  }

  .topbar-embleme {
    width: 48px;
    height: 48px;
    padding: 3px;
  }

  .identity h1 {
    font-size: 1.35rem;
  }

  .side-nav {
    padding: 8px;
    border: 0;
    border-bottom: 2px solid var(--gold-light);
    border-radius: 0;
    box-shadow: none;
  }

  .nav-button.active,
  [dir="rtl"] .nav-button.active {
    box-shadow: inset 0 -3px 0 var(--gold-light);
  }

  .metric {
    padding-top: 12px;
  }
}

/* Séance déjà terminée de l'emploi du temps (fenêtre de sept jours passés). */
.item-card.past {
  opacity: 0.6;
}
