/* ============================================================
   portail.css — Styles du Portail EDG
   Chargé uniquement sur les pages /portail/.
   Réutilise les variables de variables.css.
   ============================================================ */

/* ── Reset minimal ───────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }

/* ── Layout principal ────────────────────────────────────────── */
.portail-body {
  background: var(--bg-page);
  margin: 0;
  padding: 0;
  font-family: var(--font-main);
  color: var(--text);
  min-height: 100vh;
  overflow-x: hidden;
}

.portail-app {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  overflow-x: hidden;
}

/* ── Header ──────────────────────────────────────────────────── */
.portail-header {
  background: var(--sidebar-bg);
  border-bottom: 1px solid var(--sidebar-border);
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 200;
}

.portail-header-inner {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 var(--space-lg);
  height: 80px;
  display: flex;
  align-items: stretch;
  justify-content: space-between;
  gap: 0;
  width: 100%;
  box-sizing: border-box;
}

/* Logo */
.portail-logo {
  display: flex;
  align-items: stretch;
  gap: 0;
  text-decoration: none;
  flex-shrink: 1;
  min-width: 0;
  overflow: hidden;
}

.portail-logo-icon {
  width: 120px;
  height: 100%;
  background: rgba(255,255,255,0.08);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 32px;
  flex-shrink: 0;
}

.portail-logo-img {
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
  flex-shrink: 0;
}

.portail-logo-text {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
  padding: 0 var(--space-lg);
}

.portail-logo-name {
  font-size: var(--text-sm);
  font-weight: 600;
  font-size: 150%;
  color: var(--text-white);
  line-height: 1;
}

.portail-logo-sub {
  font-size: var(--text-xs);
  color: var(--sidebar-active);
  line-height: 1;
}

/* Droite header */
.portail-header-right {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: 0 var(--space-lg);
  flex-shrink: 0;
}

.portail-access-btn {
  background: rgba(127,212,160,0.15);
  border: 1px solid rgba(127,212,160,0.3);
  color: var(--sidebar-active);
  border-radius: var(--btn-radius);
  padding: 6px 14px;
  font-size: var(--btn-font-sm);
  font-weight: var(--btn-weight);
  text-decoration: none;
  transition: background var(--transition);
  white-space: nowrap;
}

.portail-access-btn:hover {
  background: rgba(127,212,160,0.25);
}

.portail-famille-badge {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

.portail-famille-nom {
  font-size: var(--text-sm);
  color: var(--sidebar-active);
  font-weight: 500;
}

.portail-logout {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  color: var(--sidebar-item);
  text-decoration: none;
  border-radius: 6px;
  transition: color var(--transition), background var(--transition);
  cursor: pointer;
}

.portail-logout svg {
  width: 18px;
  height: 18px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.portail-logout:hover {
  color: var(--text-white);
  background: rgba(255,255,255,0.12);
}

/* Bouton "Installer" (PWA) — masqué par défaut via l'attribut [hidden], affiché en JS
   uniquement quand le contexte s'y prête (voir assets/portail/js/pwa-install.js). Le
   sélecteur :not([hidden]) garantit que [hidden] gagne toujours, quel que soit l'ordre
   des règles CSS (l'attribut seul aurait la même spécificité qu'une règle de classe). */
.portail-install-btn {
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  color: var(--sidebar-item);
  background: none;
  border: none;
  border-radius: 6px;
  transition: color var(--transition), background var(--transition);
  cursor: pointer;
}

.portail-install-btn:not([hidden]) {
  display: inline-flex;
}

.portail-install-btn svg {
  width: 18px;
  height: 18px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.portail-install-btn:hover {
  color: var(--text-white);
  background: rgba(255,255,255,0.12);
}

/* Popup ponctuel d'installation (en plus du bouton header) — mobile/tablette uniquement,
   affiché une fois par navigateur (voir pwa-install.js, [hidden] contrôlé en JS). Comme
   .portail-install-btn : le display se pose uniquement via :not([hidden]), jamais sur la
   classe de base, sinon une règle auteur battrait toujours la règle [hidden] du navigateur
   (même origine de cascade, peu importe l'ordre) et l'attribut hidden n'aurait aucun effet. */
.portail-pwa-banner {
  position: fixed;
  left: var(--space-md);
  right: var(--space-md);
  bottom: calc(var(--space-md) + env(safe-area-inset-bottom, 0px));
  z-index: 100;
  align-items: center;
  gap: var(--space-md);
  /* Même traitement que .portail-insc-banner ("Inscriptions ouvertes") — se distingue des
     cartes blanches de la page (retour d'Evan : le fond blanc s'y fondait trop). */
  background: var(--green-xpale);
  border: 1.5px solid var(--green-main);
  border-radius: var(--card-radius);
  box-shadow: var(--card-shadow);
  padding: var(--space-md);
}

.portail-pwa-banner:not([hidden]) {
  display: flex;
}

.portail-pwa-banner-icon {
  font-size: 2.25rem;
  flex-shrink: 0;
}

.portail-pwa-banner-text {
  flex: 1;
  min-width: 0;
}

.portail-pwa-banner-title {
  font-size: var(--text-md);
  font-weight: 700;
  color: var(--text);
}

.portail-pwa-banner-sub {
  font-size: var(--text-sm);
  color: var(--text-muted);
}

.portail-pwa-banner-btn {
  flex-shrink: 0;
  background: var(--green-main);
  color: #fff;
  border: none;
  border-radius: var(--btn-radius);
  padding: 12px 20px;
  font-size: var(--text-base);
  font-weight: var(--btn-weight);
  cursor: pointer;
  white-space: nowrap;
}

.portail-pwa-banner-close {
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: 1.75rem;
  line-height: 1;
  cursor: pointer;
}

@media (min-width: 769px) {
  .portail-pwa-banner {
    left: auto;
    width: 400px;
  }
}

/* Hamburger mobile */
.portail-hamburger {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 36px;
  height: 36px;
  padding: 6px;
  background: none;
  border: none;
  cursor: pointer;
}

.portail-hamburger span {
  display: block;
  height: 2px;
  background: var(--sidebar-item);
  border-radius: 2px;
  transition: var(--transition);
}

/* ── Subnav ──────────────────────────────────────────────────── */
.portail-subnav {
  background: var(--bg-card);
  border-bottom: 1px solid var(--border);
  position: fixed;
  top: 80px;
  left: 0;
  right: 0;
  z-index: 199;
}

.portail-subnav-inner {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 var(--space-lg);
  display: flex;
  gap: 0;
}

.portail-subnav-item {
  padding: 10px 16px;
  font-size: var(--text-sm);
  color: var(--text-muted);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  transition: color var(--transition);
  white-space: nowrap;
}

.portail-subnav-item:hover {
  color: var(--text);
}

.portail-subnav-item.active {
  color: var(--green-main);
  border-bottom-color: var(--green-main);
  font-weight: 600;
}

/* ── Contenu principal ───────────────────────────────────────── */
.portail-main {
  flex: 1;
  padding-top: 122px; /* header 80px + subnav ~42px — ajusté par JS si subnav famille présent */
}

.portail-content {
  max-width: 1100px;
  margin: 0 auto;
  padding: var(--space-xl) var(--space-lg);
}

/* ── Footer ──────────────────────────────────────────────────── */
.portail-footer {
  background: var(--sidebar-bg);
  border-top: 1px solid var(--sidebar-border);
  padding: var(--space-md) var(--space-lg);
  margin-top: var(--space-2xl);
}

.portail-footer-inner {
  max-width: 1100px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  font-size: var(--text-xs);
  color: var(--sidebar-item);
}

.portail-footer-inner a {
  color: var(--sidebar-item);
  text-decoration: none;
  transition: color var(--transition);
}

.portail-footer-inner a:hover {
  color: var(--sidebar-active);
}

.portail-footer-sep {
  opacity: 0.4;
}

/* ── Composants spécifiques portail ──────────────────────────── */

/* Hero bannière */
.portail-hero {
  background: var(--sidebar-bg);
  border-radius: var(--card-radius);
  padding: var(--space-xl) var(--space-xl);
  margin-bottom: var(--space-lg);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-xl);
}

.portail-hero-text {}

.portail-hero-title {
  font-family: var(--font-title);
  font-size: var(--text-xl);
  font-weight: 700;
  color: var(--text-white);
  margin-bottom: var(--space-xs);
}

.portail-hero-sub {
  font-size: var(--text-sm);
  color: var(--sidebar-active);
  line-height: 1.5;
}

.portail-hero-action {
  flex-shrink: 0;
}

.portail-hero-btn {
  background: var(--green-main);
  color: var(--text-white);
  border-radius: var(--btn-radius);
  padding: 10px 20px;
  font-size: var(--text-sm);
  font-weight: var(--btn-weight);
  text-decoration: none;
  transition: background var(--transition);
  white-space: nowrap;
  display: inline-block;
}

.portail-hero-btn:hover {
  background: var(--green-mid);
}

/* Grille raccourcis */
.portail-shortcuts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: var(--space-md);
  margin-bottom: var(--space-lg);
}

.portail-shortcut {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--card-radius);
  padding: var(--space-md);
  text-decoration: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  transition: border-color var(--transition), box-shadow var(--transition);
}

.portail-shortcut:hover {
  border-color: var(--green-main);
  box-shadow: 0 2px 8px rgba(45,138,78,0.1);
}

.portail-shortcut-icon {
  width: 36px;
  height: 36px;
  background: var(--green-pale);
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  margin-bottom: var(--space-xs);
}

.portail-shortcut-label {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text);
}

.portail-shortcut-sub {
  font-size: var(--text-xs);
  color: var(--text-muted);
}

/* Grille bas de page (2 colonnes) */
.portail-bottom-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-md);
}

/* Card compétitions prochaines */
.portail-next-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--card-radius);
  padding: var(--space-lg);
}

/* Card planning horaires */
.portail-planning-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--card-radius);
  padding: var(--space-lg);
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.portail-planning-card-icon {
  font-size: 28px;
}

.portail-planning-card-sub {
  color: var(--text-muted);
  line-height: 1.5;
  flex: 1;
}

.portail-planning-card-btn {
  align-self: flex-start;
  margin-top: var(--space-xs);
}

.portail-next-title {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: var(--space-md);
}

.portail-next-item {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm) 0;
  border-bottom: 1px solid var(--border-light);
}

/* Ligne cliquable : ouvre l'événement dans le Calendrier (2026-10-20). */
.portail-next-link {
  color: inherit;
  text-decoration: none;
  cursor: pointer;
}
.portail-next-link:hover .portail-next-nom {
  color: var(--green-main);
}

.portail-next-item:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

.portail-next-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--green-main);
  flex-shrink: 0;
}

.portail-next-nom {
  font-size: var(--text-sm);
  color: var(--text);
  flex: 1;
}

.portail-next-date {
  font-size: var(--text-xs);
  color: var(--text-muted);
  white-space: nowrap;
}

/* Lien vert */
.portail-link-green {
  color: var(--green-main);
  text-decoration: none;
  transition: color var(--transition);
}

.portail-link-green:hover {
  color: var(--green-mid);
}

/* Texte pré-formaté (présentation, contacts, infos) */
.portail-text-pre {
  line-height: 1.7;
  white-space: pre-wrap;
}

/* Bloc document */
.portail-doc-link {
  text-decoration: none;
}

.portail-doc-icon {
  width: 36px;
  height: 36px;
  background: var(--green-pale);
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  flex-shrink: 0;
}

.portail-doc-title {
  flex: 1;
}

/* ── Commission jeunes ───────────────────────────────────────── */
.portail-commission-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: var(--space-lg);
}

.portail-commission-role {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: var(--space-sm);
  padding-bottom: var(--space-xs);
  border-bottom: 1px solid var(--border-light);
}

.portail-commission-membre {
  padding: var(--space-xs) 0;
}

.portail-commission-nom {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text);
}

.portail-commission-tel {
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin-top: 2px;
}

/* ── Page titre ──────────────────────────────────────────────── */

/* ── Formulaire code famille ──────────────────────────────────── */
.portail-auth-wrap {
  max-width: 440px;
  margin: var(--space-2xl) auto;
}

.portail-auth-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--card-radius);
  padding: var(--space-xl);
}

.portail-auth-icon {
  font-size: 40px;
  text-align: center;
  margin-bottom: var(--space-md);
}

.portail-auth-title {
  font-family: var(--font-title);
  font-size: var(--text-lg);
  font-weight: 700;
  color: var(--text);
  text-align: center;
  margin-bottom: var(--space-xs);
}

.portail-auth-sub {
  font-size: var(--text-sm);
  color: var(--text-muted);
  text-align: center;
  margin-bottom: var(--space-xl);
  line-height: 1.5;
}

.portail-code-input {
  font-family: monospace;
  font-size: 22px;
  font-weight: 700;
  letter-spacing: 4px;
  text-align: center;
  text-transform: uppercase;
  width: 100%;
  height: 56px;
  border: 2px solid var(--border);
  border-radius: var(--input-radius);
  background: var(--bg-input);
  color: var(--green-deep);
  transition: border-color var(--transition);
}

.portail-code-input:focus {
  outline: none;
  border-color: var(--green-main);
}

/* ── Timeline drapeaux ───────────────────────────────────────── */
.portail-drapeau-timeline {
  display: flex;
  align-items: center;
  padding: var(--space-md) 0 var(--space-sm);
  overflow-x: auto;
  gap: 0;
}

.portail-drapeau-step {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex: 1;
  min-width: 52px;
  position: relative;
}

/* Ligne de connexion */
.portail-drapeau-step::before {
  content: '';
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  left: calc(-50% + 24px);
  right: calc(50% + 24px);
  height: 2px;
  background: var(--border);
  z-index: 0;
}

.portail-drapeau-step:first-child::before {
  display: none;
}

.portail-drapeau-step.valide::before {
  background: var(--green-light);
}

.portail-drapeau-step.actuel::before {
  right: calc(50% + 32px);
}

.portail-drapeau-step.actuel + .portail-drapeau-step::before {
  left: calc(-50% + 32px);
}

.portail-drapeau-flag {
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  z-index: 1;
  flex-shrink: 0;
}

.portail-drapeau-step.actuel .portail-drapeau-flag {
  width: 56px;
  height: 56px;
}

.portail-drapeau-img {
  width: 100%;
  height: 100%;
  display: block;
}

/* Icône SVG inline (couleur réelle du Drapeau via currentColor) — remplace les fichiers
   image du PHP, voir portail_badges.py::drapeau_icon_portail. Pas encore validé =
   couleur neutre, jamais la vraie couleur fédérale. */
.portail-drapeau-svg-inactif {
  color: var(--border-strong);
}

.portail-drapeau-date {
  font-size: 9px;
  color: var(--text-light);
  margin-top: 6px;
  text-align: center;
  white-space: nowrap;
}

/* ── Fiche famille ───────────────────────────────────────────── */
.portail-eleve-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--card-radius);
  margin-bottom: var(--space-md);
  overflow: hidden;
}

.portail-eleve-header {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  padding: var(--space-lg);
  background: var(--green-pale);
  border-bottom: 1px solid var(--border);
}

.portail-eleve-avatar {
  width: var(--avatar-size);
  height: var(--avatar-size);
  border-radius: var(--avatar-radius);
  background: var(--bg-card);
  color: var(--green-mid);
  font-size: var(--avatar-font);
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  border: 2px solid var(--green-light);
}

.portail-eleve-name {
  font-size: var(--text-md);
  font-weight: 700;
  color: var(--green-deep);
}

.portail-eleve-name-nom {
  color: var(--green-mid);
  font-weight: 400;
}

.portail-eleve-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-xs);
  margin-top: var(--space-xs);
}

.portail-eleve-header-body {
  flex: 1;
  min-width: 0;
}

/* Corps de la fiche */
.portail-eleve-body {
  padding: var(--space-lg);
  display: flex;
  flex-direction: column;
  gap: 0;
}

.portail-eleve-section {
  padding-bottom: var(--space-md);
  margin-bottom: var(--space-md);
  border-bottom: 1px solid var(--border-light);
}

.portail-eleve-section:last-child {
  padding-bottom: 0;
  margin-bottom: 0;
  border-bottom: none;
}

.portail-eleve-section-title {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: var(--space-sm);
}

/* Pill groupe */
.portail-groupe-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-sm);
  background: var(--green-xpale);
  border: 1px solid var(--green-light);
  border-radius: var(--badge-radius);
  padding: 6px 12px;
}

.portail-groupe-pill-jour {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--green-deep);
}

.portail-groupe-pill-sep {
  color: var(--green-light);
  font-size: var(--text-xs);
}

.portail-groupe-pill-detail {
  font-size: var(--text-xs);
  color: var(--green-mid);
}

/* Licence */
.portail-eleve-licence {
  font-family: monospace;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text);
  background: var(--bg-subtle);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 3px 10px;
  letter-spacing: 1px;
}

/* Grille de blocs info (saison, licence, règlement...) */
.portail-eleve-info-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-md);
}

.portail-eleve-info-bloc {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  padding: var(--space-md);
  background: var(--bg-subtle);
  border: 1px solid var(--border-light);
  border-radius: var(--card-radius);
}

@media (max-width: 768px) {
  .portail-eleve-info-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 480px) {
  .portail-eleve-info-grid {
    grid-template-columns: 1fr;
  }
}

/* Règlement */
.portail-reglement-detail {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.portail-reglement-ligne {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
}

.portail-reglement-ligne-right {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
}

.portail-reglement-mode-pill {
  font-size: 10px;
  font-weight: 600;
  color: var(--text-muted);
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 1px 5px;
  letter-spacing: 0.03em;
}

/* Compétition épinglée */
.portail-comp-epingle {
  background: var(--bg-subtle);
  border: 1px solid var(--border);
  border-left-width: 4px;
  border-radius: 0 var(--list-card-radius) var(--list-card-radius) 0;
  padding: 10px var(--space-md);
  display: flex;
  align-items: center;
  gap: var(--space-md);
}

.portail-comp-epingle-body {
  flex: 1;
}

.portail-comp-epingle-nom {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text);
}

.portail-comp-epingle-date {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex-shrink: 0;
}

.portail-comp-epingle-jour {
  font-size: 22px;
  font-weight: 700;
  color: var(--text);
  line-height: 1;
}

.portail-comp-epingle-mois {
  font-size: var(--text-xs);
  color: var(--text-muted);
  text-transform: capitalize;
}

/* Items historique (légèrement atténués) */
.portail-next-item-past {
  opacity: 0.65;
}

/* Hero blanc */
.portail-hero-white {
  background: var(--bg-card);
  border: 1px solid var(--border);
}

.portail-hero-title-dark {
  color: var(--text);
}

.portail-hero-sub-dark {
  color: var(--text-muted);
}

/* ── Bandeau inscription (remplace le hero quand ouvert) ────── */
.portail-insc-banner {
  background: var(--green-xpale);
  border: 1.5px solid var(--green-main);
  border-radius: var(--card-radius);
  padding: var(--space-lg) var(--space-xl);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-xl);
}

.portail-insc-banner-left {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.portail-insc-banner-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  font-size: var(--text-xs);
  font-weight: 600;
  color: #166534;
}

.portail-insc-banner-title {
  font-family: var(--font-title);
  font-size: var(--text-lg);
  font-weight: 700;
  color: var(--green-deep);
}

.portail-insc-banner-sub {
  font-size: var(--text-sm);
  color: var(--green-mid);
}

.portail-insc-banner-btn {
  flex-shrink: 0;
  white-space: nowrap;
}

@media (max-width: 768px) {
  .portail-insc-banner {
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-md);
    padding: var(--space-lg);
  }
  .portail-insc-banner-btn {
    width: 100%;
    text-align: center;
  }
}

/* ── Bloc inscription (card bas de page) ─────────────────────── */
/* Point de statut (bandeau inscription) */
.portail-insc-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #22c55e;
  flex-shrink: 0;
}

/* Card formulaire inscription */
.portail-insc-form-card {
  max-width: 560px;
  margin-top: var(--space-lg);
}

/* Bouton pleine largeur avec label à gauche et icône à droite */
.btn-between {
  justify-content: space-between;
}

/* Hint sous un label */
.label-hint {
  font-weight: 400;
  color: var(--text-light);
}

/* Utilitaire espacement top xs */
.mt-xs {
  margin-top: var(--space-xs);
}
.portail-comps-month {
  margin-bottom: var(--space-xl);
}

.portail-comps-month-title {
  font-family: var(--font-title);
  font-size: var(--text-md);
  font-weight: 700;
  color: var(--text);
  margin-bottom: var(--space-md);
  padding-bottom: var(--space-sm);
  border-bottom: 2px solid var(--border);
  text-transform: capitalize;
}

.portail-comp-item {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-left-width: 4px;
  border-radius: var(--list-card-radius);
  margin-bottom: var(--space-sm);
  display: block;
  overflow: hidden;
}

.portail-comp-header {
  padding: var(--list-card-padding);
  display: flex;
  align-items: center;
  gap: var(--space-md);
}

.portail-comp-dates {
  display: flex;
  align-items: center;
  gap: 4px;
}

.portail-comp-date-arrow {
  font-size: var(--text-xs);
  color: var(--text-muted);
}

.portail-comp-date {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--text-muted);
  min-width: 50px;
  text-align: center;
}

.portail-comp-day-label {
  font-size: var(--text-xs);
  color: var(--text-muted);
}

.portail-comp-date-day {
  font-size: 22px;
  font-weight: 700;
  color: var(--text);
  line-height: 1;
}

.portail-comp-body {
  flex: 1;
}

.portail-comp-nom {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text);
}

.portail-comp-lieu {
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin-top: 2px;
}

.portail-comp-limite {
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin-top: 3px;
}

.portail-comp-clickable {
  cursor: pointer;
}

.portail-comp-chevron {
  font-size: 11px;
  color: var(--text-muted);
  transition: transform var(--transition);
  flex-shrink: 0;
}

.portail-comp-chevron.open {
  transform: rotate(180deg);
}

.portail-comp-badges {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  margin-top: 6px;
}

.portail-comp-detail {
  display: none;
  border-top: 1px solid var(--border-light);
  padding: var(--space-md) var(--space-md) var(--space-md) 66px;
  flex-direction: column;
  gap: var(--space-sm);
}

.portail-comp-detail.open {
  display: flex;
}

.portail-comp-detail-sep {
  height: 1px;
  background: var(--border-light);
}

.portail-comp-detail-row {
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
  font-size: var(--text-sm);
}

.portail-comp-detail-icon {
  flex-shrink: 0;
  font-size: 14px;
  margin-top: 1px;
}

.portail-comp-detail-label {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--text-muted);
  margin-bottom: 2px;
}

.portail-comp-detail-value {
  color: var(--text);
  font-size: var(--text-sm);
}

.portail-comp-detail-box {
  font-size: var(--text-sm);
  color: var(--text-muted);
  background: var(--bg-subtle);
  border-radius: var(--input-radius);
  padding: var(--space-sm) var(--space-md);
  line-height: 1.6;
}

.portail-comp-detail-box a {
  color: var(--green-deep);
  text-decoration: underline;
  word-break: break-all;
}

.portail-comp-detail-notes {
  border-left: 2px solid var(--border-strong);
}

/* ── Planning groupes ────────────────────────────────────────── */
.portail-planning-jour {
  margin-bottom: var(--space-xl);
}

.portail-planning-jour-title {
  font-family: var(--font-title);
  font-size: var(--text-md);
  font-weight: 700;
  color: var(--text);
  margin-bottom: var(--space-md);
  padding-bottom: var(--space-sm);
  border-bottom: 2px solid var(--border);
  text-transform: capitalize;
}

.portail-groupe-item {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--list-card-radius);
  padding: 14px var(--space-md);
  margin-bottom: var(--space-sm);
  display: flex;
  align-items: center;
  gap: var(--space-md);
}

.portail-groupe-horaire {
  font-size: var(--text-md);
  font-weight: 700;
  color: var(--green-main);
  min-width: 60px;
}

.portail-groupe-body { flex: 1; }

.portail-groupe-nom {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text);
}

.portail-groupe-meta {
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin-top: 2px;
}

.portail-groupe-duree {
  font-size: 0.85em;
  color: var(--text-light);
}

/* Image planning */
.portail-planning-img-card {
  padding: var(--space-md);
}

.portail-planning-img {
  width: 100%;
  height: auto;
  display: block;
  border-radius: 8px;
}

/* ── Planning réel — grille (mode_planning="reel", posé le 2026-07-15) ──────────
   Réplique visuellement la grille de l'écran Affectation/Mon planning côté pro
   (planning/grille_affectation.py::construire_grille_affectation, réutilisée telle
   quelle) — demande explicite d'Evan ("un planning semblable à celui qu'on utilise"),
   seule exception à la règle "design identique au PHP" de cette rubrique puisque ce
   moteur de planning n'a jamais existé côté PHP. Lecture seule, sans glisser-déposer,
   sans popover — chaque pastille affiche la vraie couleur du prof assigné (pas de
   notion de "moi" côté portail, contrairement à Mon planning côté pro qui grise les
   autres profs). */
.portail-grille-onglets {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  margin-bottom: var(--space-md);
}

.portail-grille-onglet {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--text-muted);
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 4px 12px;
  text-decoration: none;
}

.portail-grille-onglet.active {
  color: #fff;
  background: var(--green-main);
  border-color: var(--green-main);
}

.portail-grille-jour {
  margin-bottom: var(--space-lg);
}

.portail-grille-jour-title {
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--text-light);
  margin-bottom: var(--space-sm);
  padding-left: 2px;
}

/* overflow-y: hidden explicite (2026-09-08) : quand un seul axe est en `auto`, la
   spec CSS force l'autre à `auto` aussi — `overflow-x: auto` seul rendait donc le
   bloc scrollable verticalement, et le moindre dépassement sub-pixel (arrondi des
   hauteurs de ligne) suffisait à afficher une barre verticale sur chaque bloc-jour
   alors que tout le contenu tient déjà. La hauteur reste `auto` : plus de groupes
   font simplement grandir le conteneur, la page globale reste seule à défiler. */
.portail-grille-wrap {
  overflow-x: auto;
  overflow-y: hidden;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--list-card-radius);
}

/* Largeur des cases de date : un MINIMUM (même règle que l'espace pro, décision d'Evan
   du 2026-10-11) : 100px sur ordinateur, 80px sur téléphone. Les colonnes de date n'ont
   pas de largeur propre et se partagent la place restante ; le min-width de la table
   (depuis --nb-dates / --nb-vacances posés par le gabarit) garantit leur minimum. */
.portail-grille-wrap { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { .portail-grille-wrap { scroll-behavior: auto; } }

.portail-grille { --col-creneau-w: 148px; --col-date-min: 100px; --col-vac-w: 24px; }

table.portail-grille {
  border-collapse: separate;
  border-spacing: 0;
  width: 100%;
  table-layout: fixed;
  min-width: calc(var(--col-creneau-w) + var(--nb-dates, 0) * var(--col-date-min) + var(--nb-vacances, 0) * var(--col-vac-w));
}

.portail-grille col.col-creneau { width: var(--col-creneau-w); }
.portail-grille col.col-vacances { width: var(--col-vac-w); }
.portail-grille th, .portail-grille td { padding: 0; }

/* Ligne des mois au-dessus des dates */
.portail-grille thead tr.ligne-mois th {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--green-deep);
  text-align: left;
  padding: 6px 8px 0;
  border-bottom: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Dates passées : affichées, pastilles pâlies (couleur du pro gardée), la grille se cale sur la prochaine séance */
.portail-grille thead th.passee { color: var(--text-light); }
.portail-grille td.grille-cell.passee .portail-pastille { opacity: 0.3; }

/* Barre au-dessus des grilles : raccourcis de mois (période longue) */
.grille-outils {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: var(--space-md);
}
.grille-mois {
  display: flex;
  gap: 4px;
  overflow-x: auto;
  scrollbar-width: none;
  min-width: 0;
  flex: 1 1 auto;
}
.grille-mois::-webkit-scrollbar { display: none; }
.grille-mois-chip {
  font: inherit;
  font-size: var(--text-xs);
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  border: 1px solid var(--border);
  background: var(--bg-card);
  color: var(--text-muted);
  border-radius: 999px;
  padding: 5px 11px;
}
.grille-mois-chip.on {
  background: var(--green-pale);
  border-color: var(--green-main);
  color: var(--green-deep);
}

/* Pastille enfant (famille connectée) : initiale au repos, prénom déroulé par-dessus au
   survol ou au toucher. Le bouton est en position absolue : la case ne change jamais de
   taille (décision d'Evan du 2026-10-11, deux enfants peuvent avoir la même initiale). */
.portail-grille .ini {
  position: relative;
  display: inline-block;
  width: 18px;
  height: 18px;
  flex: none;
  margin-left: 3px;
  vertical-align: middle;
}
.portail-grille .ini button {
  position: absolute;
  left: 0;
  top: 0;
  height: 18px;
  min-width: 18px;
  padding: 0 5px;
  border-radius: 999px;
  border: none;
  background: var(--green-main);
  color: #fff;
  font: inherit;
  font-size: 0.66rem;
  font-weight: 800;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  cursor: pointer;
  z-index: 1;
  transition: box-shadow 160ms ease;
}
.portail-grille .ini button .reste {
  display: inline-block;
  max-width: 0;
  overflow: hidden;
  transition: max-width 180ms ease;
}
.portail-grille .ini button:hover,
.portail-grille .ini button:focus-visible,
.portail-grille .ini.ouvert button { z-index: 6; box-shadow: 0 2px 6px rgba(0,0,0,0.18); }
.portail-grille .ini button:hover .reste,
.portail-grille .ini button:focus-visible .reste,
.portail-grille .ini.ouvert button .reste { max-width: 150px; }
@media (prefers-reduced-motion: reduce) {
  .portail-grille .ini button, .portail-grille .ini button .reste { transition: none; }
}
.portail-grille td.col-creneau:has(.ini.ouvert),
.portail-grille td.col-creneau:has(.ini button:hover) { z-index: 7; }

.portail-grille thead th {
  font-size: 0.72rem;
  color: var(--text-muted);
  font-weight: 600;
  text-align: center;
  padding: var(--space-xs);
  border-bottom: 1px solid var(--border);
  background: var(--bg-card);
}

.portail-grille thead th.vacances-h { background: var(--green-xpale); }

.portail-grille td.col-creneau, .portail-grille th.col-creneau-h {
  position: sticky;
  left: 0;
  z-index: 2;
  background: var(--bg-card);
  border-bottom: 1px solid var(--border);
  border-right: 1px solid var(--border);
  padding: var(--space-xs) var(--space-sm);
  vertical-align: middle;
}
/* Hauteur fixe de l'étiquette, prévue pour un nom sur 2 lignes (tronqué au-delà) : toutes
   les lignes de la grille ont la même hauteur quel que soit le nom du groupe (retour
   d'Evan du 2026-10-11). Pas d'overflow:hidden ici, il couperait le prénom déroulé de la
   pastille enfant. */
.portail-grille .grille-creneau {
  display: flex;
  flex-direction: column;
  justify-content: center;
  height: calc(var(--text-sm) * 1.3 * 2 + max(var(--text-xs) * 1.4, 18px));
}
.portail-grille .grille-creneau-nom {
  font-weight: 600;
  font-size: var(--text-sm);
  color: var(--text);
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Horaire du groupe sous son nom. Le type de groupe n'est plus affiché (décision d'Evan
   du 2026-10-11 : le nom, l'horaire et la pastille enfant suffisent aux parents). */
.portail-grille .grille-creneau-horaire {
  color: var(--text-muted);
  font-size: var(--text-xs);
  line-height: 1.4;
  min-height: 18px;
}

/* Étiquette d'en-tête "Groupe" — masquée par défaut (desktop : la colonne montre déjà
   nom + type, une étiquette serait redondante), affichée seulement en mobile ci-dessous
   pour clarifier ce que représente la colonne une fois le nom retiré (retour d'Evan). */
.portail-grille .col-creneau-h-label { display: none; }

/* Mobile (posé 2026-08-03, retour d'Evan) : la colonne créneau sticky mangeait trop de
   largeur sur la zone scrollable (pastilles) — nom et type de groupe retirés de
   l'affichage par défaut (l'horaire seul suffit au premier coup d'œil), récupérables au
   clic/tap sur la cellule (portailCreneauInfo, même popover que les pastilles). Une
   icône avait été essayée comme signal visuel puis retirée (Evan : prenait de la place
   qu'on cherchait justement à récupérer) — l'étiquette d'en-tête "Groupe" fait office
   d'indice à la place. Les deux bornes de l'horaire passent en display:block (pas de
   flex-direction ici) pour s'empiler sur 2 lignes ("14h00" / "15h30") sans changer le
   flux desktop. Colonne resserrée à 58px (92px laissait du vide après "14h00"). */
/* Téléphone, refait le 2026-10-11 (décision d'Evan, deux groupes le samedi 10h30 chez
   Lyon Verger) : la colonne montre l'heure de début (+ pastilles enfants) puis le nom du
   groupe, sur deux lignes au plus. Le type et l'heure de fin restent au toucher. */
@media (max-width: 768px) {
  .portail-grille { --col-creneau-w: 104px; --col-date-min: 80px; --col-vac-w: 26px; }
  .portail-grille td.col-creneau, .portail-grille th.col-creneau-h {
    padding: 6px 7px;
  }
  .portail-grille .col-creneau-h-label { display: inline; }
  .portail-grille .grille-creneau { height: calc(20px + 0.72rem * 1.25 * 2); }
  .portail-grille .grille-creneau-horaire {
    order: -1;
    display: flex;
    align-items: center;
    gap: 3px;
    line-height: 20px;
    min-height: 20px;
    color: var(--text);
    font-weight: 700;
    font-size: 0.82rem;
  }
  .portail-grille .grille-creneau-horaire .h-sep,
  .portail-grille .grille-creneau-horaire .h-fin {
    display: none;
  }
  .portail-grille .ini { margin-left: 0; }
  .portail-grille .grille-creneau-nom {
    font-size: 0.72rem;
    font-weight: 400;
    color: var(--text-muted);
    line-height: 1.25;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .portail-grille td.col-creneau {
    cursor: pointer;
  }
  .grille-mois-chip { font-size: 0.85rem; padding: 7px 12px; }
}

.portail-grille td.grille-cell {
  border-bottom: 1px solid var(--border);
  padding: 3px;
  height: 2.5rem;
}

.portail-grille tbody tr:last-child td { border-bottom: none; }

/* Lecture seule — jamais de retour visuel au survol d'une ligne (la règle générique
   `tr:hover td` du reste du portail, pensée pour d'autres tableaux, grisait chaque
   ligne de la grille alors qu'aucune interaction n'y est possible). */
.portail-grille tr:hover td.col-creneau { background: var(--bg-card); }
.portail-grille tr:hover td.grille-cell { background: transparent; }
.portail-grille tr:hover td.vacances-cell { background: var(--green-xpale); }

.portail-grille td.vacances-cell {
  background: var(--green-xpale);
  border-left: 1px dashed var(--border-strong);
  border-right: 1px dashed var(--border-strong);
  text-align: center;
  vertical-align: middle;
}

.portail-grille td.vacances-cell span {
  writing-mode: vertical-rl;
  text-orientation: mixed;
  font-size: 0.68rem;
  font-weight: 700;
  color: var(--green-mid);
  letter-spacing: 0.02em;
}

.portail-pastille {
  width: 100%;
  height: 100%;
  border-radius: 4px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  font-size: 0.76rem;
  font-weight: 600;
  padding: 0 4px;
  position: relative;
}

/* Libellé de séance (ex. "Parcours"), posé le 2026-08-03 — même principe que
   .pastille-libelle côté pro, mirroré ici dans le CSS du portail (namespace séparé).
   Taille réduite en JS (portailAjusterLibelles) jusqu'à tenir sur une ligne — cette
   valeur/l'ellipsis restent le plancher si le JS n'a pas encore tourné ou échoue. */
.portail-pastille-libelle {
  font-size: 0.58rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  line-height: 1;
  opacity: 0.85;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}

/* Icône "cette pastille a des infos" (libellé/horaire modifié/message aux familles) —
   posée le 2026-08-03, mirror de .pastille-info-icon côté pro. Le clic/tap se fait sur
   toute la pastille (voir portailPastilleInfo), l'icône n'est qu'un signal visuel — mais
   `cursor:pointer` est posé sur la pastille elle-même dès qu'elle porte data-info. */
/* Horaire réel d'une séance modifiée, À LA PLACE du prénom (option C de la maquette
   https://claude.ai/artifact/PRSn6jE68oSnJtVggHbhM7 ; l'option B, étiquette sous le
   prénom, était trop serrée à l'usage, 2026-09-29). Le pro reste identifiable par la
   couleur de la pastille et dans le détail au toucher. */
.portail-pastille-horaire {
  color: #9A6400;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.portail-pastille[data-info] { cursor: pointer; }
.portail-pastille-info-icon {
  /* Bas-droite (pas haut-droite comme côté pro) : le libellé de séance occupe déjà le
     haut de la pastille ici (.portail-pastille-libelle, en premier dans le flex-column),
     un chevauchement retour d'Evan le 2026-08-03. */
  position: absolute; bottom: 3px; right: 1px; width: 11px; height: 11px; opacity: 0.6;
  pointer-events: none;
}
.portail-pastille-info-icon svg { width: 100%; height: 100%; }

/* Popover d'info au clic (mirror de .pastille-info-pop côté pro, namespace portail). */
.portail-pastille-info-pop {
  position: fixed; z-index: 60; background: var(--card-bg, #fff); border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18); padding: 0.35rem; min-width: 172px; max-width: 260px;
}
.portail-pastille-info-pop .portail-pip-libelle {
  font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.02em;
  padding: 0.3rem 0.5rem 0.15rem; color: var(--text-muted);
}
.portail-pastille-info-pop .portail-pip-ligne {
  font-size: 0.82rem; padding: 0.2rem 0.5rem; white-space: normal; line-height: 1.35; color: var(--text);
}
.portail-pastille-info-pop .portail-pip-cadre {
  background: var(--bg-subtle, rgba(0, 0, 0, 0.04)); border-radius: 6px; margin: 0.2rem 0.35rem;
  padding: 0.4rem 0.5rem; font-size: 0.82rem; line-height: 1.35; color: var(--text);
}
.portail-pastille-info-pop .portail-pip-cadre strong {
  display: block; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.02em;
  color: var(--text-muted); margin-bottom: 0.15rem; font-weight: 700;
}
.portail-legend-icon { width: 0.85rem; height: 0.85rem; flex-shrink: 0; }

.portail-pastille.assignee {
  background: color-mix(in oklab, var(--pro-hex, var(--green-main)) 20%, white);
  border-left: 3px solid var(--pro-hex, var(--green-main));
  color: var(--text);
}

.portail-pastille.vide {
  background: rgba(0, 0, 0, 0.025);
  border: 1.5px dashed var(--border-strong);
}

.portail-pastille.annulee {
  background: rgba(0, 0, 0, 0.04);
  color: var(--text-light);
  text-decoration: line-through;
}

.portail-pastille.remplacant {
  background: rgba(0, 0, 0, 0.06);
  font-style: italic;
  color: var(--text-muted);
}

.portail-pastille .txt {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Téléphone : cases plus hautes (après les règles de base de la case et de la pastille,
   qui gagneraient sinon à spécificité égale). */
@media (max-width: 768px) {
  .portail-grille td.grille-cell { height: 52px; }
  .portail-pastille { border-radius: 6px; font-size: 0.78rem; }
}

.portail-grille-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
  font-size: var(--text-xs);
  color: var(--text-muted);
  margin-top: var(--space-sm);
}

.portail-grille-legend span { display: inline-flex; align-items: center; gap: 6px; }

.portail-grille-legend .sw {
  width: 11px;
  height: 11px;
  border-radius: 3px;
  flex-shrink: 0;
}

/* Empty state générique */
.portail-empty-state {
  padding: var(--space-xl) 0;
}

/* Accordéon groupes */
.portail-groupe-accordion {
  flex-direction: column;
  align-items: stretch;
  gap: 0;
  padding: 0;
  cursor: pointer;
}

.portail-groupe-accordion-header {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  padding: 14px var(--space-md);
}

.portail-groupe-accordion-right {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  flex-shrink: 0;
  margin-left: auto;
}

.portail-groupe-accordion-icon {
  color: var(--text-muted);
  font-size: var(--text-xs);
}

.portail-groupe-inscrits {
  border-top: 1px solid var(--border-light);
  padding: var(--space-sm) var(--space-md) var(--space-md);
}

.portail-groupe-inscrits-empty {
  margin: var(--space-sm) 0 0;
}

.portail-groupe-inscrits-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  margin-top: var(--space-sm);
}

.portail-groupe-inscrit-pill {
  background: var(--green-pale);
  color: var(--green-mid);
  border-radius: 20px;
  padding: 3px 10px;
  font-size: var(--text-xs);
  font-weight: 500;
}

/* ── Responsive ──────────────────────────────────────────────── */
@media (max-width: 768px) {
  .portail-hamburger { display: flex; }

  .portail-header-inner {
    height: 60px;
    padding: 0;
  }

  .portail-main {
    padding-top: 101px; /* header 60px + subnav ~41px — ajusté par JS */
  }

  .portail-header-right {
    padding: 0 var(--space-sm);
  }

  .portail-logo-name {
    font-size: var(--text-sm);
  }

  .portail-subnav {
    top: 60px;
  }

  .portail-header-right .portail-access-btn,
  .portail-famille-badge { display: none; }

  .portail-subnav:not(.portail-subnav-famille) {
    display: none;
    flex-direction: column;
    padding: var(--space-sm) 0;
    top: 60px;
  }

  .portail-subnav.open {
    display: flex;
  }

  .portail-subnav-inner {
    flex-direction: column;
    padding: 0;
  }

  .portail-subnav-item {
    padding: 12px var(--space-lg);
    border-bottom: none;
    border-left: 3px solid transparent;
    color: var(--text-muted);
  }

  .portail-subnav-item.active {
    border-left-color: var(--green-main);
    border-bottom: none;
    color: var(--green-main);
  }

  .portail-content {
    padding: var(--space-lg) var(--space-md);
  }

  .portail-hero {
    flex-direction: column;
    gap: var(--space-md);
    padding: var(--space-lg);
  }

  .portail-hero-action { width: 100%; }
  .portail-hero-btn { width: 100%; text-align: center; }

  .portail-bottom-grid {
    grid-template-columns: 1fr;
  }

  .portail-eleve-grid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 480px) {
  .portail-shortcuts {
    grid-template-columns: 1fr 1fr;
  }
}

/* ── Page header portail ─────────────────────────────────────── */
.portail-page-header {
  margin-bottom: var(--space-lg);
}

.portail-page-title {
  font-family: var(--font-title);
  font-size: var(--text-xl);
  font-weight: 700;
  color: var(--text);
  margin-bottom: var(--space-xs);
}

.portail-page-sub {
  font-size: var(--text-sm);
  color: var(--text-muted);
}

.portail-back-link {
  color: var(--text-muted);
  text-decoration: none;
  font-size: var(--text-sm);
  transition: color var(--transition);
}

.portail-back-link:hover {
  color: var(--green-main);
}

/* ── Récap compétition (page inscription) ────────────────────── */
.portail-comp-recap {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-left-width: 4px;
  border-radius: var(--list-card-radius);
  padding: var(--list-card-padding);
  display: flex;
  align-items: flex-start;
  gap: var(--space-md);
  max-width: 560px;
}

.portail-comp-recap-date {
  text-align: center;
  min-width: 50px;
  flex-shrink: 0;
}

.portail-comp-recap-jour {
  font-size: 28px;
  font-weight: 700;
  color: var(--text);
  line-height: 1;
}

.portail-comp-recap-mois {
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-weight: 600;
  text-transform: capitalize;
  margin-top: 2px;
}

.portail-comp-recap-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.portail-comp-recap-nom {
  font-size: var(--text-md);
  font-weight: 700;
  color: var(--text);
}

.portail-comp-recap-lieu,
.portail-comp-recap-criteres,
.portail-comp-recap-limite {
  font-size: var(--text-xs);
  color: var(--text-muted);
}

/* ── Liste élèves à sélectionner ─────────────────────────────── */
.portail-eleves-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  margin-top: var(--space-xs);
}

.portail-eleve-radio {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  padding: 12px var(--space-md);
  border: 1px solid var(--border);
  border-radius: var(--card-radius);
  cursor: pointer;
  transition: border-color var(--transition), background var(--transition);
}

.portail-eleve-radio:hover {
  border-color: var(--green-main);
  background: var(--green-xpale);
}

.portail-eleve-radio input[type="radio"] {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  accent-color: var(--green-main);
}

.portail-eleve-radio-disabled {
  opacity: 0.6;
  cursor: default;
  pointer-events: none;
}

.portail-eleve-radio-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* Élève unique (pas de radio) */
.portail-eleve-ligne {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  padding: 12px var(--space-md);
  border: 1px solid var(--border);
  border-radius: var(--card-radius);
  background: var(--bg-subtle);
}

.portail-eleve-avatar-sm {
  width: var(--avatar-sm-size);
  height: var(--avatar-sm-size);
  border-radius: var(--avatar-radius);
  background: var(--avatar-bg);
  color: var(--avatar-color);
  font-size: var(--avatar-sm-font);
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.portail-eleve-ligne-nom {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text);
}

.portail-eleve-ligne-statut {
  margin-top: 3px;
}

/* ── Confirmation succès ─────────────────────────────────────── */
.portail-insc-success {
  max-width: 480px;
  margin: var(--space-2xl) auto;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-md);
}

.portail-insc-success-icon {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: var(--badge-success-bg);
  color: var(--badge-success-text);
  font-size: 28px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}

.portail-insc-success-title {
  font-family: var(--font-title);
  font-size: var(--text-lg);
  font-weight: 700;
  color: var(--text);
}

.portail-insc-success-sub {
  font-size: var(--text-sm);
  color: var(--text-muted);
  line-height: 1.6;
}

/* Colonne droite compétition (badge statut + bouton) */
.portail-comp-side {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-xs);
  flex-shrink: 0;
  white-space: nowrap;
}

/* ── Statuts par élève sur la liste des compétitions ─────────── */
.portail-comp-statuts {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: var(--space-xs);
}

/* ── Checkbox élève (remplace radio pour la fratrie) ─────────── */
.portail-eleve-checkbox {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  padding: 12px var(--space-md);
  border: 1px solid var(--border);
  border-radius: var(--card-radius);
  cursor: pointer;
  transition: border-color var(--transition), background var(--transition);
}

.portail-eleve-checkbox:hover {
  border-color: var(--green-main);
  background: var(--green-xpale);
}

.portail-eleve-checkbox input[type="checkbox"] {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  accent-color: var(--green-main);
}

.portail-eleve-checkbox-disabled {
  opacity: 0.6;
  cursor: default;
  pointer-events: none;
}

/* ── Coéquipier extérieur (inscrire_competition) ─────────────── */
.portail-coequipier-wrap {
  margin-top: var(--space-xs);
  padding-left: calc(18px + var(--space-md) + var(--avatar-sm-size) + var(--space-md));
}

.portail-coequipier-input {
  width: 100%;
  font-size: var(--text-sm);
}

/* ============================================================
   TARIFS (portail/tarifs.php)
   ============================================================ */

/* Table tarifaire */
.portail-tarifs-table {
  width: 100%;
  border-collapse: collapse;
}

.portail-tarifs-table th {
  font-size: var(--text-xs);
  font-weight: 700;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: var(--space-xs) 0;
  border-bottom: 1px solid var(--border);
  text-align: left;
}

.portail-tarifs-table th:last-child {
  text-align: right;
}

.portail-tarifs-table td {
  padding: 10px 0;
  border-bottom: 1px solid var(--border-light);
  font-size: var(--text-sm);
  vertical-align: middle;
}

.portail-tarifs-table tbody tr:last-child td {
  border-bottom: none;
}

.portail-tarifs-profil {
  color: var(--text-muted);
}

.portail-tarifs-statut {
  padding: 0 var(--space-md);
}

.portail-tarifs-montant {
  text-align: right;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
}

.portail-tarifs-footnote {
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-style: italic;
  margin-top: var(--space-sm);
  padding-top: var(--space-sm);
  border-top: 1px solid var(--border-light);
}

/* Réductions */
.portail-tarifs-reductions {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.portail-tarifs-reduction-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  padding: 10px 0;
  border-bottom: 1px solid var(--border-light);
}

.portail-tarifs-reductions .portail-tarifs-reduction-item:last-child {
  border-bottom: none;
}

.portail-tarifs-reduction-nom {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text);
}

.portail-tarifs-reduction-valeur {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--badge-success-text);
  white-space: nowrap;
}

/* Options */
.portail-tarifs-options {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.portail-tarifs-option-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 0;
  border-bottom: 1px solid var(--border-light);
}

.portail-tarifs-options .portail-tarifs-option-item:last-child {
  border-bottom: none;
}

.portail-tarifs-option-nom {
  font-size: var(--text-sm);
  color: var(--text);
}

.portail-tarifs-option-montant {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
}

/* ============================================================
   ESPACE FAMILLE — Sous-nav + Cards dashboard + Règlements
   ============================================================ */

/* ── Sous-nav famille (2e barre, sous le subnav principal) ── */
.portail-subnav-famille {
  position: fixed;
  top: 122px; /* header 80px + subnav 42px — ajusté par JS */
  left: 0;
  right: 0;
  z-index: 198;
  border-top: none;
  border-bottom: 1px solid var(--border);
  background: var(--green-xpale);
  box-shadow: none;
}

/* Items plus compacts dans le subnav famille */
.portail-subnav-famille .portail-subnav-item {
  padding: 6px 14px;
  font-size: var(--text-xs);
}

/* Select mobile sous-nav famille — masqué par défaut */
.portail-famille-subnav-mobile {
  display: none;
  padding: var(--space-sm) var(--space-md);
}

.portail-famille-select {
  width: 100%;
  height: var(--btn-h-sm);
  font-size: var(--text-sm);
  border: 1px solid var(--input-border);
  border-radius: var(--input-radius);
  background: var(--bg-card);
  padding: 0 var(--space-sm);
}

/* ── Cards dashboard famille ─────────────────────────────── */
.portail-famille-card {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--card-radius);
  padding: var(--space-md) var(--space-lg);
  text-decoration: none;
  color: var(--text);
  transition: box-shadow var(--transition), border-color var(--transition);
  cursor: pointer;
}

.portail-famille-card:hover {
  box-shadow: var(--card-shadow);
  border-color: var(--green-light);
}

.portail-famille-card-left {
  flex-shrink: 0;
}

.portail-famille-card-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.portail-famille-card-nom {
  font-weight: 600;
  font-size: var(--text-base);
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  flex-wrap: wrap;
}

.portail-famille-card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.portail-famille-card-info {
  color: var(--text-muted);
}

.portail-famille-card-right {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-xs);
}

.portail-famille-card-chevron {
  font-size: 20px;
  color: var(--text-light);
  line-height: 1;
}

.portail-avatar-regl {
  font-size: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* ── Règlements — tableau ────────────────────────────────── */
.portail-regl-section-title {
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: var(--space-xs);
}

.portail-regl-total-row td {
  border-top: 1px solid var(--border);
  padding-top: 8px;
  font-size: var(--text-sm);
}

/* ── Bandeau connexion compétitions ──────────────────────── */
.portail-connexion-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  background: var(--alert-info-bg);
  border: 1px solid var(--alert-info-border);
  border-radius: var(--alert-radius);
  padding: var(--alert-padding);
  font-size: var(--alert-font);
  color: var(--alert-info-text);
  flex-wrap: wrap;
}

/* ── Responsive mobile ───────────────────────────────────── */
@media (max-width: 768px) {
  .portail-subnav-famille .portail-subnav-inner {
    display: none;
  }
  .portail-famille-subnav-mobile {
    display: block;
  }
  .portail-subnav-famille {
    /* top géré par JS ajusterPaddingTop() */
  }
  .portail-famille-card {
    padding: var(--space-sm) var(--space-md);
  }
  .portail-connexion-banner {
    flex-direction: column;
    align-items: flex-start;
  }
  .portail-connexion-banner .btn {
    width: 100%;
    text-align: center;
  }
}

/* Icône "Partager" iOS dans le tuto d'installation (installer_iphone.html) — repère visuel
   à côté du titre de l'étape, demande explicite d'Evan après avoir eu du mal à la retrouver
   dans Safari. */
.portail-tuto-title-icon {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

.portail-tuto-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 4px;
  border-radius: 6px;
  background: var(--green-xpale);
  color: var(--green-deep);
  flex-shrink: 0;
}

.portail-tuto-icon svg {
  width: 20px;
  height: 20px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ── Messagerie interne (2026-08-16) — icône header + panneau flottant desktop + pages
   plein format mobile. Rubrique entièrement nouvelle (aucun équivalent PHP), namespace
   dédié `.portail-msg-*` pour ne jamais entrer en collision avec le reste du CSS copié
   du PHP. Mirror du côté pro (design system Tailwind, classes .mp-*) mais entièrement
   réécrit avec les tokens portail — le portail n'a pas accès aux tokens --accent/--surface
   du pro. Pages plein format (liste/fil) gardent le chrome portail normal (header/subnav/
   footer) pour l'instant — pas encore demandé par Evan de les rendre "vraiment plein
   écran" comme côté pro, à revoir une fois testé côté portail. */

.portail-messagerie-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  color: var(--sidebar-item);
  text-decoration: none;
  border-radius: 6px;
  transition: color var(--transition), background var(--transition);
  cursor: pointer;
}

.portail-messagerie-btn svg {
  width: 18px;
  height: 18px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.portail-messagerie-btn:hover {
  color: var(--text-white);
  background: rgba(255,255,255,0.12);
}

.portail-messagerie-badge {
  position: absolute;
  top: 1px;
  right: 1px;
  min-width: 15px;
  height: 15px;
  padding: 0 3px;
  border-radius: 999px;
  background: #d6483f;
  color: #fff;
  font-size: 9.5px;
  font-weight: 700;
  align-items: center;
  justify-content: center;
}
/* [hidden] posé/retiré en JS (messagerie.js) après coup — une règle display: auteur
   bat toujours [hidden] (style user-agent) quelle que soit la spécificité, même piège
   que .portail-install-btn (déjà gardé par :not([hidden]) plus haut dans ce fichier). */
.portail-messagerie-badge:not([hidden]) { display: flex; }

.portail-msg-page { max-width: 640px; margin: 0 auto; }
.portail-msg-page-title { font-family: var(--font-title); font-size: var(--text-xl); margin: 0 0 var(--space-md); color: var(--text); }
.portail-msg-back { display: inline-block; margin-bottom: var(--space-md); color: var(--text-muted); font-size: var(--text-sm); text-decoration: none; }
.portail-msg-back:hover { color: var(--text); }

/* Enveloppe logique (2026-08-17, "Qui écrit" déplacé sur cette page) — display:contents
   pour ne rien changer au layout existant : .portail-msg-list reste directement le
   flex:1/overflow-y:auto ciblé par les règles scopées panel-body/chromeless ci-dessous,
   comme avant ; le sélecteur ajouté juste après reste pinné en bas puisqu'il devient lui
   aussi un enfant flex direct de ce même conteneur (parent réel de la shell), avec sa
   taille naturelle (pas de flex:1). */
.portail-msg-list-shell { display: contents; }
.portail-msg-qui-ecrit-global { flex: none; display: flex; align-items: center; gap: 6px; padding: 8px 12px; border-top: 1px solid var(--border-light); font-size: var(--text-xs); color: var(--text-light); }
.portail-msg-qui-ecrit-global select { flex: 1; min-width: 0; border: 1px solid var(--border); border-radius: 8px; padding: 4px 8px; font-size: var(--text-xs); font-family: var(--font-main); color: var(--text); background: var(--bg-card); }
.portail-msg-list { display: flex; flex-direction: column; overflow: hidden; }
.portail-msg-row { display: flex; gap: var(--space-sm); padding: var(--space-sm) var(--space-md); border-bottom: 1px solid var(--border-light); text-decoration: none; color: inherit; }
.portail-msg-row:last-child { border-bottom: none; }
.portail-msg-row:hover { background: var(--green-xpale); }
.portail-msg-row-icon { width: 32px; height: 32px; border-radius: 8px; background: var(--green-pale); color: var(--green-main); display: flex; align-items: center; justify-content: center; flex: none; }
.portail-msg-row-icon svg { width: 15px; height: 15px; stroke: currentColor; fill: none; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.portail-msg-row-icon-diffusion { background: #f1e9d8; color: #96742c; }
.portail-msg-row-body { min-width: 0; flex: 1; }
.portail-msg-row-top { display: flex; align-items: center; gap: var(--space-xs); }
.portail-msg-row-name { font-size: var(--text-sm); font-weight: 700; color: var(--text); flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.portail-msg-row-badge { background: #d6483f; color: #fff; font-size: 10px; font-weight: 700; border-radius: 999px; min-width: 16px; height: 16px; line-height: 16px; text-align: center; padding: 0 3px; }
.portail-msg-row-preview { font-size: var(--text-xs); color: var(--text-light); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.portail-msg-empty { padding: var(--space-lg) var(--space-md); text-align: center; font-size: var(--text-sm); color: var(--text-light); }

/* Conversations privées (2026-08-19) — bouton "Contacter un responsable" au-dessus de la
   liste + résultats de recherche dans la modale, même famille visuelle que .portail-msg-row. */
.portail-msg-list-header { flex: none; padding: var(--space-sm) var(--space-md); border-bottom: 1px solid var(--border-light); }
/* Rappel d'activation push (2026-08-19) — mirror pro (styles.css .mp-notif-banner), un
   seul bandeau compact tout en haut de la messagerie, visible à chaque ouverture. */
.portail-msg-notif-banner {
  display: flex; align-items: center; gap: 6px; padding: 8px 12px; flex: none;
  background: #FDF0DC; color: #8A5A00; font-size: var(--text-xs); font-weight: 600; text-decoration: none;
}
.portail-msg-notif-banner:hover { background: #FBE6C4; }
.portail-msg-notif-banner svg { width: 14px; height: 14px; flex: none; }
.portail-msg-recherche-resultats { max-height: 40vh; overflow-y: auto; margin-top: var(--space-sm); }
.portail-msg-recherche-row + .portail-msg-recherche-row { border-top: 1px solid var(--border-light); }
.portail-msg-recherche-item { display: block; width: 100%; text-align: left; padding: var(--space-sm) var(--space-xs); font-size: var(--text-sm); font-weight: 600; color: var(--text); background: none; border: none; cursor: pointer; border-radius: 8px; }
.portail-msg-recherche-item:hover { background: var(--green-xpale); }
.portail-msg-recherche-vide { padding: var(--space-sm) var(--space-xs); font-size: var(--text-sm); color: var(--text-light); }
/* X de fermeture en haut à droite (2026-08-19, remplace le bouton "Fermer" en bas de la
   modale "Contacter un responsable") — .modal (style.css, hérité du PHP) n'a jamais eu
   besoin de position:relative jusqu'ici, posé ici plutôt que dans style.css (règle du
   projet : tout nouveau composant portail vit dans ce fichier). Clic en dehors de la
   modale ferme déjà (voir assets/portail/js/messagerie.js), ce bouton est un 2e chemin. */
.modal { position: relative; }
.modal-close { position: absolute; top: var(--space-sm); right: var(--space-sm); width: 28px; height: 28px; display: flex; align-items: center; justify-content: center; background: none; border: none; border-radius: 999px; color: var(--text-light); cursor: pointer; }
.modal-close:hover { background: var(--bg-subtle); color: var(--text); }
.modal-close svg { width: 16px; height: 16px; }
/* Séparateur discret entre Groupes et Discussions privées (2026-08-19) — mirror pro. */
.portail-msg-list-separator { border-top: 1px solid var(--border-light); margin: 4px 0; }

.portail-msg-archives { border-top: 1px solid var(--border-light); }
.portail-msg-archives-summary { padding: var(--space-sm) var(--space-md); font-size: var(--text-xs); font-weight: 700; color: var(--text-light); cursor: pointer; }
.portail-msg-row-archive { opacity: 0.6; }

.portail-msg-fil { display: flex; flex-direction: column; overflow: hidden; }
.portail-msg-thread { display: flex; flex-direction: column; gap: 6px; padding: var(--space-md); max-height: 60vh; overflow-y: auto; }
/* Séparateur de date (2026-08-17) — mirror pro (.mp-date-divider). */
.portail-msg-date-divider { display: flex; justify-content: center; margin: 2px 0; }
.portail-msg-date-divider span { font-size: 11px; color: var(--text-light); background: var(--bg-subtle); padding: 2px 10px; border-radius: 999px; }
.portail-msg-wrap { display: flex; flex-direction: column; max-width: 82%; min-width: 0; }
.portail-msg-wrap.mine { align-self: flex-end; align-items: flex-end; }
.portail-msg-wrap.theirs { align-self: flex-start; align-items: flex-start; }
/* Style façon WhatsApp (2026-08-17) — mirror exact du côté pro (styles.css, mêmes
   commentaires détaillés sur le fantôme d'heure). .portail-msg-bubble-row (pas
   .portail-msg-row) : ce nom était déjà pris par la ligne de canal cliquable de la
   liste messagerie (_canal_row.html, padding/bordure/survol vert hérités par erreur —
   bug réel signalé par Evan, 2026-08-17). */
.portail-msg-bubble-row { display: flex; align-items: flex-end; gap: 4px; min-width: 0; }
.portail-msg-wrap.mine .portail-msg-bubble-row { flex-direction: row-reverse; }
.portail-msg-bubble { position: relative; padding: 7px 11px 6px; border-radius: 13px; font-size: var(--text-sm); line-height: 1.4; min-width: 0; }
/* Blanc + bordure par défaut (mirror pro, styles.css .mp-msg-wrap.theirs .mp-msg — même
   raison : body:background:var(--bg-page) rendait la bulle invisible en gris sur gris).
   Desktop (.portail-msg-panel, fond blanc) repasse en gris sans bordure juste en
   dessous, rendu qu'Evan préfère spécifiquement là. */
.portail-msg-wrap.theirs .portail-msg-bubble { background: var(--bg-card); color: var(--text); border: 1px solid var(--border-light); border-bottom-left-radius: 4px; }
.portail-msg-panel .portail-msg-wrap.theirs .portail-msg-bubble { background: var(--bg-subtle); border: none; }
.portail-msg-wrap.mine .portail-msg-bubble { background: var(--green-main); color: #fff; border-bottom-right-radius: 4px; }
.portail-msg-author-inline { font-weight: 700; font-size: 10px; margin-bottom: 2px; }
.portail-msg-text { margin: 0; white-space: pre-wrap; word-break: break-word; }
.portail-msg-time-ghost { visibility: hidden; display: inline-block; font-size: 10px; padding-left: 10px; }
.portail-msg-time { position: absolute; right: 11px; bottom: 5px; font-size: 10px; color: var(--text-light); }
.portail-msg-wrap.mine .portail-msg-time { color: rgba(255, 255, 255, 0.75); }
.portail-msg-attachment-time { text-align: right; font-size: 10px; color: var(--text-light); margin-top: 3px; }
.portail-msg-wrap.mine .portail-msg-attachment-time { color: rgba(255, 255, 255, 0.75); }
/* Suppression au tap sur sa propre bulle (2026-08-17, remplace la petite corbeille
   permanente jugée "tâche" par Evan une fois le design épuré) — voir
   assets/portail/js/messagerie.js::portailOuvrirMenuMessage. */
.portail-msg-bubble-actionable { cursor: pointer; }
.portail-msg-menu {
  position: fixed; z-index: 300; background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 10px; box-shadow: 0 8px 24px -6px rgba(0, 0, 0, 0.25); padding: 4px; min-width: 140px;
}
.portail-msg-menu-item {
  display: block; width: 100%; text-align: left; border: none; background: none; cursor: pointer;
  padding: 8px 10px; border-radius: 6px; font-size: var(--text-sm); color: #c0392b; font-family: var(--font-main);
}
.portail-msg-menu-item:hover { background: var(--bg-subtle); }

/* Message supprimé (2026-08-17) — la bulle reste, grisée, "Message supprimé" en
   italique, visible uniquement pour la famille qui l'a supprimé (voir _fil_contexte). */
.portail-msg-deleted { opacity: 0.75; font-style: italic; }

/* Pièce jointe dans un message (2026-08-17) — mirror exact du côté pro (.mp-msg-attachment-*). */
.portail-msg-attachment-img { display: block; max-width: 200px; max-height: 200px; border-radius: 8px; margin-top: 3px; }
.portail-msg-attachment-file {
  display: flex; align-items: center; gap: 6px; margin-top: 3px; padding: 5px 9px; max-width: 180px;
  border-radius: 8px; background: rgba(0, 0, 0, 0.08); text-decoration: none; color: inherit; font-size: var(--text-xs); overflow: hidden;
}
.portail-msg-wrap.theirs .portail-msg-attachment-file { background: rgba(0, 0, 0, 0.06); }
.portail-msg-attachment-file svg { width: 13px; height: 13px; flex: none; }
/* min-width:0 — sans lui l'ellipsis n'a aucun effet dans un item flex (mirror du bug
   pro trouvé le 2026-08-17, voir styles.css .mp-msg-attachment-file span). */
.portail-msg-attachment-file span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.portail-msg-diffusion-note { padding: var(--space-sm) var(--space-md); font-size: var(--text-xs); color: var(--text-light); text-align: center; border-top: 1px solid var(--border-light); }
.portail-msg-composer { display: flex; flex-direction: column; gap: 6px; padding: var(--space-sm) var(--space-md); border-top: 1px solid var(--border-light); }
/* align-items: flex-end (pas center) — posé le 2026-08-20 avec le passage de
   .portail-msg-input à un <textarea> qui grandit, mirror pro (styles.css
   .mp-composer-row) : les boutons ronds pièce-jointe/envoi doivent rester calés en bas
   de la zone de texte au fil de son agrandissement. */
.portail-msg-composer-row { display: flex; align-items: flex-end; gap: var(--space-xs); }

/* :not([hidden]) — mirror du bug pro trouvé le 2026-08-17 (styles.css .mp-attach-preview) :
   sans lui, cette règle gagne toujours sur [hidden]{display:none} et le bandeau reste
   visible en permanence, même vide. */
.portail-msg-attach-preview:not([hidden]) { display: flex; align-items: center; gap: 6px; padding: 5px 10px; background: var(--bg-subtle); border-radius: 8px; font-size: var(--text-xs); color: var(--text); }
.portail-msg-attach-preview svg { width: 13px; height: 13px; flex: none; }
.portail-msg-attach-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.portail-msg-attach-remove { border: none; background: none; padding: 0; cursor: pointer; color: var(--text-light); flex: none; display: flex; }
.portail-msg-attach-remove svg { width: 12px; height: 12px; }
.portail-msg-attach-remove:hover { color: var(--text); }
.portail-msg-attach-btn {
  border: none; background: var(--bg-subtle); color: var(--text); width: 32px; height: 32px; border-radius: 999px;
  display: flex; align-items: center; justify-content: center; cursor: pointer; flex: none;
}
.portail-msg-attach-btn svg { width: 14px; height: 14px; }
.portail-msg-attach-btn:hover { background: var(--border-light); }
/* textarea.portail-msg-input (pas juste .portail-msg-input) — même piège que l'ancien
   input.portail-msg-input (spécificité élément+classe nécessaire pour battre une règle
   générique de style.css) mais pour une raison différente cette fois : style.css a une
   règle "textarea { height:auto; min-height:80px; resize:vertical; }" — sans l'élément
   explicite ici, le textarea garderait ce min-height bien trop grand et sa poignée de
   redimensionnement native, alors que la hauteur doit être pilotée par
   mpAutoResizePortail (messagerie.js). Passé de <input type="text"> à <textarea> le
   2026-08-20 (retour à la ligne réel — un textarea ne soumet jamais le formulaire sur
   Entrée, contrairement à un input simple ligne, gratuit avec ce changement de balise). */
textarea.portail-msg-input {
  flex: 1; border: 1px solid var(--border); border-radius: 18px; padding: 7px 12px;
  font-size: var(--text-sm); font-family: var(--font-main); color: var(--text); background: var(--bg-card);
  resize: none; min-height: 32px; max-height: 6.5rem; overflow-y: auto; line-height: 1.35;
  /* Scrollbar masquée (2026-08-20, retour d'Evan, mirror pro) — la zone reste
     scrollable normalement une fois le plafond atteint, juste sans piste/curseur. */
  scrollbar-width: none;
}
.portail-msg-input::-webkit-scrollbar { display: none; }
.portail-msg-input:focus { outline: none; border-color: var(--green-main); }
.portail-msg-send-btn { border: none; background: var(--green-main); color: #fff; width: 32px; height: 32px; border-radius: 999px; display: flex; align-items: center; justify-content: center; cursor: pointer; flex: none; }
.portail-msg-send-btn svg { width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.portail-msg-send-btn:hover { background: var(--green-mid); }

/* Panneau flottant desktop (widget) — même mécanique que le côté pro (fetch +
   sessionStorage), sans htmx qui n'est jamais chargé côté portail (voir
   assets/portail/js/messagerie.js). Pas de --z-* nommée côté portail (contrairement au
   pro) : 150, sous le header (200)/subnav (199) au cas improbable où ils se
   chevaucheraient, largement au-dessus de tout contenu de page normal. */
#portail-messagerie-widget { position: fixed; right: 20px; bottom: 20px; z-index: 150; }
.portail-msg-bubble-btn {
  width: 50px; height: 50px; border-radius: 999px; border: none; cursor: pointer;
  background: var(--green-main); color: #fff; display: flex; align-items: center; justify-content: center;
  box-shadow: 0 12px 26px -8px rgba(0,0,0,0.35);
}
.portail-msg-bubble-btn svg { width: 20px; height: 20px; stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.portail-msg-panel {
  width: 336px; height: 440px; max-height: calc(100vh - 40px);
  background: var(--bg-card); border-radius: 14px; box-shadow: 0 24px 48px -14px rgba(0,0,0,0.35);
  display: flex; flex-direction: column; overflow: hidden; border: 1px solid var(--border);
}
.portail-msg-panel-head { display: flex; align-items: center; gap: var(--space-xs); padding: 10px 10px 10px 12px; border-bottom: 1px solid var(--border-light); background: var(--bg-subtle); flex: none; }
.portail-msg-panel-title { display: flex; align-items: center; gap: var(--space-xs); font-size: var(--text-sm); font-weight: 700; color: var(--text); }
.portail-msg-panel-title svg { width: 15px; height: 15px; stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.portail-msg-panel-spacer { flex: 1; }
.portail-msg-icon-btn { border: none; background: transparent; color: var(--text-muted); width: 28px; height: 28px; border-radius: 7px; display: flex; align-items: center; justify-content: center; cursor: pointer; }
.portail-msg-icon-btn svg { width: 15px; height: 15px; stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.portail-msg-icon-btn:hover { background: var(--green-xpale); color: var(--text); }
.portail-msg-panel-body { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.portail-msg-panel-body .portail-msg-list,
.portail-msg-panel-body .portail-msg-fil { border: none; border-radius: 0; flex: 1; min-height: 0; }
.portail-msg-panel-body .portail-msg-list { overflow-y: auto; }
.portail-msg-panel-body .portail-msg-thread { max-height: none; flex: 1; }

@media (max-width: 768px) {
  /* Même seuil que le JS (messagerie.js, matchMedia) et que la bascule desktop/mobile
     des icônes ci-dessus — sous 480px l'ancien seuil laissait une zone 481-768px où
     l'icône visible était la "mobile" mais le clic ouvrait quand même le panneau desktop. */
  #portail-messagerie-widget { display: none; }
}

/* Icône messagerie mobile (header) — masquée sur desktop par défaut, l'unique instance
   affichée là-bas est celle dans .portail-famille-badge, juste avant Déconnexion (demande
   explicite d'Evan 2026-08-16 : "à gauche de Déconnexion"). Voir aussi la règle qui masque
   .portail-famille-badge <=768px, ligne ~1730 — les deux se relaient exactement au même
   point de rupture, jamais les deux visibles en même temps. */
.portail-messagerie-btn-mobile { display: none; }
@media (max-width: 768px) {
  .portail-messagerie-btn-mobile { display: inline-flex; }
}

/* ── Pages "chromeless" (messagerie_liste/messagerie_fil) — mirror EXACT du côté pro
   (templates/base.html .mp-chromeless-shell, templates/messagerie/{liste,fil}.html),
   demande explicite d'Evan 2026-08-16 ("tout doit être reproduit à l'identique, à part
   la couleur de la topbar") : plus de header/subnav/footer normaux, plus de conteneur
   .portail-content boxé (max-width/margin/padding) — toute la page est dédiée à la
   messagerie, en-tête minimal + fil qui occupe le reste de l'écran, composer épinglé en
   bas au-dessus du clavier virtuel (--portail-keyboard-offset, voir fil.html). */
.portail-app-chromeless {
  height: 100dvh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.portail-main-chromeless {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding-top: 0 !important; /* écrase le padding-top JS (ajusterPaddingTop) pensé pour le header fixed normal, absent ici */
}
.portail-content-chromeless {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  max-width: none;
  margin: 0;
  padding: 0;
  padding-bottom: var(--portail-keyboard-offset, 0px);
}
.portail-content-chromeless .portail-msg-list,
.portail-content-chromeless .portail-msg-fil {
  flex: 1;
  min-height: 0;
}
.portail-content-chromeless .portail-msg-thread { max-height: none; flex: 1; }
/* Police agrandie en plein écran mobile (2026-08-20, retour réel d'Evan, mirror pro) —
   .portail-msg-panel (widget desktop) garde sa taille compacte d'origine, seul le
   contexte plein écran change. Plafond du textarea élargi pour la même raison (bien
   plus de hauteur disponible que dans un panneau flottant de 440px). */
.portail-content-chromeless .portail-msg-bubble { font-size: var(--text-md); }
.portail-content-chromeless .portail-msg-input { font-size: var(--text-md); min-height: 2.4rem; max-height: 9rem; }
/* Bouton envoyer agrandi en plein écran mobile (2026-09-09, mirror pro) — 32px restait
   petit pour un pouce, le widget desktop (souris) garde sa taille compacte. */
.portail-content-chromeless .portail-msg-send-btn { width: 38px; height: 38px; }
.portail-content-chromeless .portail-msg-send-btn svg { width: 16px; height: 16px; }

.portail-mobile-header {
  display: flex; align-items: center; gap: var(--space-sm); padding: var(--space-sm) var(--space-md);
  background: var(--sidebar-bg); color: #fff; flex: none;
}
.portail-mobile-logo { height: 28px; width: auto; flex: none; }
.portail-mobile-title { font-family: var(--font-title); font-weight: 700; font-size: var(--text-md); color: #fff; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.portail-mobile-close, .portail-mobile-back {
  width: 40px; height: 40px; border-radius: 8px; flex: none;
  display: flex; align-items: center; justify-content: center; color: #fff; text-decoration: none;
}
.portail-mobile-close svg, .portail-mobile-back svg { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.portail-mobile-close:hover, .portail-mobile-back:hover { background: rgba(255,255,255,0.15); }

/* ── Espace bénévole (2026-09-15) ────────────────────────────────
   Maquette validée https://claude.ai/artifact/3PQcqJhJJJLiDQ4Q9SvXoS : cartes d'appel sur le
   modèle des compétitions (.portail-comp-*), fiche d'un appel, page Connexion à deux cartes,
   noms et déconnexion en bas du menu sur téléphone. */
.portail-benev-item { border-left-color: var(--green-main); }
.portail-benev-item.clos { border-left-color: var(--border-strong); }
.portail-benev-lien {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  flex: 1;
  min-width: 0;
  color: inherit;
  text-decoration: none;
}
.portail-benev-cta { flex-shrink: 0; }
.portail-benev-cta form { margin: 0; }

.portail-benev-fiche-titre { margin: var(--space-sm) 0; }
.portail-benev-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs) var(--space-md);
  font-size: var(--text-sm);
  color: var(--text-muted);
  margin-bottom: var(--space-md);
}
.portail-benev-description { margin-bottom: var(--space-lg); }
.portail-benev-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 280px;
  gap: var(--space-lg);
  align-items: start;
}
.portail-benev-poste + .portail-benev-poste {
  border-top: 1px solid var(--border-light);
  margin-top: var(--space-md);
  padding-top: var(--space-md);
}
.portail-benev-poste-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--space-sm);
}
.portail-benev-poste-nom { font-family: var(--font-title); font-size: var(--text-md); font-weight: 700; }
.portail-benev-places { font-size: var(--text-xs); font-weight: 600; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.portail-benev-places.complet { color: var(--badge-success-text); }
.portail-benev-personne,
.portail-benev-libre {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  min-height: 40px;
  font-size: var(--text-base);
}
.portail-benev-libre { flex-wrap: wrap; color: var(--text-light); }
.portail-benev-libre form { margin: 0 0 0 auto; }
.portail-benev-avatar {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--green-pale);
  color: var(--green-deep);
  font-size: var(--text-xs);
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.portail-benev-creux {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: 1.5px dashed var(--border-strong);
  flex-shrink: 0;
}
.portail-benev-side { padding: var(--space-md) var(--space-lg); }
.portail-benev-ligne {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-md);
  font-size: var(--text-sm);
  padding: var(--space-sm) 0;
}
.portail-benev-ligne + .portail-benev-ligne { border-top: 1px solid var(--border-light); }
.portail-benev-ligne-k { color: var(--text-muted); }
.portail-benev-ligne-v { font-weight: 600; text-align: right; }
.portail-benev-side .btn { width: 100%; margin-top: var(--space-md); }

/* Messages du club (2026-10-18, maquette https://claude.ai/artifact/HjAc3hbirFdx6fgZkYK5Yv) */
.portail-benev-message { padding: var(--list-card-padding); border-left-width: 1px; color: inherit; text-decoration: none; }
.portail-benev-message-ligne { display: flex; align-items: center; gap: var(--space-sm); flex-wrap: wrap; }
.portail-benev-message-date { margin-left: auto; font-size: var(--text-xs); color: var(--text-muted); white-space: nowrap; }
.portail-benev-message-extrait { margin-top: 2px; font-size: var(--text-sm); color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.portail-benev-message-corps { line-height: 1.55; }
.portail-benev-message-signature { margin-top: var(--space-md); padding-top: var(--space-md); border-top: 1px solid var(--border-light); color: var(--text-muted); }
.portail-benev-message-pj { margin-top: var(--space-md); }

/* Case cochée non modifiable (mail des nouveaux appels). */
.toggle-switch-verrou { cursor: default; }
.toggle-switch-verrou .toggle-slider { opacity: 0.5; }

.portail-auth-duo {
  max-width: 900px;
  margin: var(--space-xl) auto;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-lg);
  align-items: start;
}
.portail-auth-duo-plein { grid-column: 1 / -1; text-align: center; }

.portail-famille-nom + .portail-famille-nom {
  padding-left: var(--space-sm);
  border-left: 1px solid rgba(255,255,255,0.2);
}
.portail-subnav-identite,
.portail-logout-mobile { display: none; }

@media (max-width: 768px) {
  .portail-benev-item .portail-comp-header { flex-wrap: wrap; }
  .portail-benev-cta { flex-basis: 100%; padding-left: 66px; }
  .portail-benev-cta .btn { width: 100%; }
  .portail-benev-split { grid-template-columns: minmax(0, 1fr); gap: var(--space-md); }
  .portail-auth-duo { grid-template-columns: minmax(0, 1fr); margin: var(--space-md) auto; }
  .portail-subnav-identite {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
    margin-top: var(--space-sm);
    padding: var(--space-md) var(--space-lg) var(--space-xs);
    border-top: 1px solid var(--border-light);
    font-size: var(--text-sm);
    color: var(--text-muted);
  }
  .portail-subnav-identite a { padding: var(--space-sm) 0; color: var(--text); font-weight: 600; text-decoration: none; }
  .portail-logout-mobile { display: inline-flex; }
}

/* ── Candidatures et départs bénévoles (2026-09-15) ─────────────── */
.portail-lien-fort {
  color: var(--text);
  font-weight: 600;
  text-decoration: underline;
  text-decoration-color: var(--border-strong);
  text-underline-offset: 3px;
}
.portail-zone-danger { border-color: var(--btn-danger-border); }
.portail-champ-erreur {
  font-size: var(--text-sm);
  color: var(--badge-error-text);
  margin-top: var(--space-xs);
}
/* Champ piège du formulaire de candidature : hors écran, jamais focusable au clavier. */
.portail-champ-cache {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Absences (2026-10-02) : séance épinglée et séances suivantes de la fiche enfant. */
.portail-seance-epingle { border-left-color: var(--green-main); }
.portail-seances-suite summary { cursor: pointer; list-style: none; display: flex; align-items: center; justify-content: space-between; margin-bottom: 0; }
.portail-seances-suite summary::-webkit-details-marker { display: none; }
.portail-seances-suite[open] summary { margin-bottom: var(--space-sm); }
.portail-seances-suite[open] .portail-seances-chevron { transform: rotate(180deg); }
.portail-next-dot-inactif { background: var(--text-light); }

/* Calendrier EDG (2026-10-11) : pastilles de filtre par type d'événement, pastille du type
   sur la carte, ligne d'infos sous le lieu. La couleur vient du type (--type-couleur). */
.portail-type-chips {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  scrollbar-width: none;
  margin-bottom: var(--space-md);
  padding-bottom: 2px;
}
.portail-type-chips::-webkit-scrollbar { display: none; }
.portail-type-chip {
  font: inherit;
  font-size: var(--text-xs);
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 1px solid var(--border);
  background: var(--bg-card);
  color: var(--text);
  border-radius: 999px;
  padding: 5px 11px;
}
.portail-type-chip i { width: 9px; height: 9px; border-radius: 50%; background: var(--type-couleur); display: block; }
.portail-type-chip[aria-pressed="false"] { background: transparent; color: var(--text-muted); }
.portail-type-chip[aria-pressed="false"] i { background: transparent; box-shadow: inset 0 0 0 1.5px var(--type-couleur); }
.portail-type-pill {
  background: color-mix(in oklab, var(--type-couleur) 22%, white);
  color: color-mix(in oklab, var(--type-couleur) 45%, black);
}
.portail-comp-infos {
  font-size: var(--text-xs);
  color: var(--text);
  margin-top: 2px;
}
@media (max-width: 768px) {
  .portail-type-chip { font-size: 0.85rem; padding: 7px 12px; }
}
/* `display: block` posé sur la carte battrait l'attribut hidden du filtre. */
.portail-comp-item[hidden], .portail-comps-month[hidden] { display: none; }

/* ============================================================
   Page Coordonnées de l'espace famille (2026-10-12, maquette
   https://claude.ai/artifact/NSoLRnP5CZoAQRYbwtSzq8). Téléphone : app.css.
   ============================================================ */
.portail-coord-section { display: flex; flex-direction: column; gap: var(--space-sm); margin-bottom: var(--space-xl); }
.portail-coord-titre { font-size: var(--text-xs); font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-muted); margin: 0 4px; }
.portail-coord-lien { font-weight: 500; }
.portail-coord-email { overflow-wrap: anywhere; }
.portail-coord-bouton { align-self: flex-start; }
.portail-coord-retour { display: inline-block; font-size: var(--text-sm); color: var(--text-muted); text-decoration: none; margin-bottom: 6px; }
.portail-coord-retour:hover { color: var(--text); }
.portail-coord-pile { display: flex; flex-direction: column; gap: var(--space-lg); }
.portail-coord-carte { display: flex; flex-direction: column; gap: var(--space-md); max-width: 640px; }
.portail-coord-carte-titre { font-weight: 700; font-size: var(--text-md); }
.portail-coord-form { display: flex; flex-direction: column; gap: var(--space-md); }
.portail-coord-cp-ville { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); gap: var(--form-gap); }
.portail-coord-interrupteur { display: flex; align-items: center; justify-content: space-between; gap: var(--space-md); padding: 12px 14px; border-radius: 10px; background: var(--bg-page); font-weight: 600; cursor: pointer; }
.portail-coord-actions { display: flex; justify-content: flex-end; align-items: center; gap: var(--space-sm); }
.portail-coord-retirer { margin-right: auto; color: var(--btn-danger-text); }
.portail-coord-lu { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 6px 16px; margin: 0; }
.portail-coord-lu dt { color: var(--text-muted); }
.portail-coord-lu dd { margin: 0; font-weight: 600; }
.portail-coord-demande { display: flex; flex-direction: column; gap: 2px; margin: 0; }
.portail-coord-lien-bouton { margin-top: 6px; padding: 0; border: none; background: none; font: inherit; font-weight: 600; color: inherit; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.form-error { font-size: var(--text-xs); color: var(--btn-danger-text); }
.portail-app-retour { display: none; }

/* Date en tuiles jour/mois (components/date_tiles.html), même format que les tableaux
   datés de l'espace pro (modèle Ligue AURA). */
.date-tiles { display: inline-flex; align-items: center; gap: 6px; vertical-align: middle; }
.date-tile {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: 8px; background: rgba(0, 0, 0, 0.04);
  line-height: 1.1; flex-shrink: 0;
}
.date-tile-day { font-size: 15px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.date-tile-mon { font-size: 9px; font-weight: 650; letter-spacing: 0.03em; text-transform: uppercase; color: var(--text-muted); }
.date-tiles:not(.date-tiles-single) .date-tile { background: var(--green-pale); }
.date-tiles:not(.date-tiles-single) .date-tile-day { color: var(--green-deep); }
.date-tiles:not(.date-tiles-single) .date-tile-mon { color: var(--green-mid); }
.date-tiles-arrow { color: var(--text-muted); font-size: 12px; }
.date-tiles-year, .date-tiles-time { font-size: 12px; color: var(--text-muted); margin-left: 2px; font-variant-numeric: tabular-nums; }

/* Certificat médical / QS sur la fiche enfant (2026-10-18) : mêmes teintes que les
   pastilles d'état de l'espace pro. Maquette https://claude.ai/artifact/3axZTH515o5izdCC1QJ1cv */
.portail-sante-pill {
  display: inline-block;
  border-radius: 999px;
  padding: 3px 10px;
  font-size: var(--text-sm);
  font-weight: 600;
}
.portail-sante-success { background: #E3F2E8; color: #1E7B3B; }
.portail-sante-warning { background: #FDF1DC; color: #9A6400; }
.portail-sante-danger { background: #FBE9E7; color: #B3261E; }
.portail-sante-liste {
  list-style: none;
  margin: var(--space-sm, 8px) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: var(--text-base);
}
.portail-sante-licence {
  font-family: ui-monospace, monospace;
  background: var(--bg-subtle);
  padding: 1px 6px;
  border-radius: 4px;
}
.portail-sante-btn { margin-top: var(--space-md, 12px); }

/* ── Stages (2026-10-19) : inscription jour par jour et récap ─────────────── */
.portail-stage-largeur { max-width: 560px; }
.portail-stage-form { display: flex; flex-direction: column; gap: var(--space-md); margin-top: var(--space-lg); max-width: 560px; }
.portail-stage-carte { display: flex; flex-direction: column; gap: var(--space-sm); }
.portail-stage-sous { font-size: var(--text-xs); font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-muted); }
.portail-stage-rangee { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-sm); }
.portail-stage-jours { display: flex; flex-direction: column; border: 1px solid var(--border); border-radius: var(--card-radius); overflow: hidden; }
.portail-stage-jour { display: flex; align-items: center; gap: var(--space-sm); padding: 10px 12px; min-height: 48px; }
.portail-stage-jour + .portail-stage-jour { border-top: 1px solid var(--border); }
.portail-stage-jour.complet { color: var(--text-muted); }
.portail-stage-jour-texte { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.portail-stage-jour-texte b { font-weight: 600; }
.portail-stage-jour-texte small { font-size: var(--text-xs); color: var(--text-muted); }
.portail-stage-jour input[type="checkbox"] { width: 22px; height: 22px; flex-shrink: 0; accent-color: var(--green-main); }
.portail-stage-seg { display: inline-flex; border: 1px solid var(--border); border-radius: 10px; overflow: hidden; flex-shrink: 0; }
.portail-stage-seg label { position: relative; padding: 7px 10px; font-size: var(--text-xs); font-weight: 600; color: var(--text-muted); cursor: pointer; background: var(--bg-card); }
.portail-stage-seg label + label { border-left: 1px solid var(--border); }
.portail-stage-seg input { position: absolute; opacity: 0; pointer-events: none; }
.portail-stage-seg label:has(input:checked) { background: var(--green-xpale); color: var(--green-main); }
.portail-stage-check { display: flex; align-items: center; gap: var(--space-sm); font-size: var(--text-sm); }
.portail-stage-check input { width: 18px; height: 18px; accent-color: var(--green-main); }
.portail-stage-total { display: flex; justify-content: space-between; align-items: baseline; font-weight: 700; font-size: var(--text-md); padding: 0 2px; }
.portail-stage-recap-ligne { display: flex; justify-content: space-between; gap: var(--space-sm); }
.portail-stage-recap-ligne > span:first-child { display: flex; flex-direction: column; min-width: 0; }
.portail-stage-recap-ligne small { color: var(--text-muted); font-size: var(--text-xs); }
.portail-stage-paiement { background: var(--bg-page); border-radius: 10px; padding: 10px 12px; font-size: var(--text-sm); line-height: 1.45; }
.portail-stage-form .num, .portail-stage-carte .num { font-variant-numeric: tabular-nums; }

/* ── Junior Pass ffgolf (2026-10-19) : carte de l'accueil de Mon espace, texte de la fiche enfant ── */
.portail-jp-carte { display: flex; align-items: flex-start; gap: 12px; background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--card-radius); padding: 14px; margin-bottom: var(--space-md); }
.portail-jp-carte-icone { width: 38px; height: 38px; border-radius: 10px; background: var(--green-pale); color: var(--green-deep); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.portail-jp-carte-icone svg { width: 20px; height: 20px; }
.portail-jp-carte-corps { flex: 1; min-width: 0; }
.portail-jp-carte-titre { font-weight: 700; font-size: var(--text-md); }
.portail-jp-carte-sous { color: var(--text-muted); font-size: var(--text-sm); margin-top: 2px; }
.portail-jp-carte-lien { display: inline-block; margin-top: 8px; font-weight: 600; font-size: var(--text-sm); color: var(--green-deep); text-decoration: none; }
.portail-jp-carte-fermer { background: transparent; border: 0; color: var(--text-muted); width: 32px; height: 32px; border-radius: 8px; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.portail-jp-carte-fermer svg { width: 18px; height: 18px; }
.portail-jp-texte { margin: var(--space-sm) 0 0; font-size: var(--text-sm); }

/* Pastille de nouveauté d'un onglet (2026-10-20, portail/nouveautes.py). */
.portail-nouveau-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-left: 6px;
  border-radius: 50%;
  background: #d6483f;
  vertical-align: 2px;
}
