/* ── Reset ── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
  --chrome-inset: 14px;
  --nav-clearance: 112px;
  --page-gutter: 1.5rem;
  --sticky-clearance: var(--nav-clearance);
  --content-rail-width: 720px;
  --side-rail-width: 190px;
  --layout-rail-gap: 10px;
  --layout-grid-width: calc((2 * var(--side-rail-width)) + var(--content-rail-width) + (2 * var(--layout-rail-gap)));
  --ui-frame-space: 2px;
  --ui-frame-pad: var(--ui-frame-space);
  --ui-frame-gap: var(--ui-frame-space);
  --ui-panel-gap: calc(var(--ui-frame-space) * 3);
  --ui-band-pad: 2px 5px;
  --ui-band-font-size: 0.66rem;
  --ui-band-line-height: 1.15;
  /* Hauteur reelle d'un bandeau : ligne de texte + 2x2px de --ui-band-pad + 2x1px de cadre. */
  --ui-band-height: calc((var(--ui-band-font-size) * var(--ui-band-line-height)) + 6px);
  --ui-text-pad: 3px 5px;
  --ui-control-height: 22px;
  /* Exception assumee a l'echelle des controles : la barre basse de l'Atlas se
     lit au-dessus de la visualisation, a distance du texte, donc sa case carree
     est plus grande que le champ courant. Elle est ecrite ici, une seule fois,
     et le pictogramme garde sa proportion dans la case. Le meme ecart separe
     ses trois groupes : recadrage, visuels, actions. */
  --ui-dock-control-size: 27px;
  --ui-dock-gap: 12px;
  --ui-button-height: 18px;
  --ui-button-pad: 0 7px;
  --ui-button-line-height: calc(var(--ui-button-height) - 2px);
  --ui-action-width: 136px;
  --ui-action-attach-gap: calc(var(--ui-frame-space) * 2);
  --ui-action-section-gap: var(--ui-panel-gap);
  --ui-list-row-height: 16px;
  --ui-list-row-pad: 0 4px;
  --ui-list-row-font-size: 0.74rem;
  --ui-list-row-line-height: 1.1;
  --ui-icon-action-size: var(--ui-button-height);
  --ui-dialog-width: 440px;
  --ui-control-pad-x: 6px;
  --ui-control-pad-y: 2px;
  --ui-control-line-height: 1;
  --form-checkbox-size: 13px;
  --edit-compact-button-width: 126px;
  --edit-compact-action-height: 18px;
  /* ── Contrat de mouvement ──
     Le site avait treize durees et deux courbes eparpillees dans ses modules.
     Il en a desormais trois et une, declarees ici avec le reste du contrat :
     une duree n'est pas moins structurante qu'une hauteur de ligne. Les regles
     qui les consomment vivent dans 95-motion.css ; aucun autre module ne
     redeclare ces jetons ni n'ecrit de duree en dur.
       --motion-state   : un etat qui change sous le doigt (survol, focus, actif)
       --motion-surface : une surface que la personne ouvre (modale, tiroir)
       --motion-long    : un trace qui s'ecrit (canvas)
     La courbe est une sortie franche suivie d'un long freinage : aucune reprise,
     aucun rebond, c'est la courbe d'une machine et non d'un ressort.

     Il n'y a volontairement AUCUN jeton de retard. Le site n'echelonne rien :
     l'arrivee des blocs page par page a ete retiree le 20.08.2026, et un jeton
     de retard serait la premiere piece de son retour. */
  --motion-state: 140ms;
  --motion-surface: 420ms;
  --motion-long: 900ms;
  --motion-ease: cubic-bezier(0.2, 0, 0, 1);
  /* Le fondu de palette est plus lent que le reste : il repeint toute la page,
     et c'est le seul amorti de la bascule jour / nuit depuis le retrait du
     balayage. Il garde donc sa propre duree, ecrite ici et nulle part ailleurs. */
  --motion-palette: 320ms;
}

/* ── TouchDesigner-style form reset : tout carré, compact, dense ── */
body {
  --area-btn-bg:        color-mix(in srgb, var(--profile-secondary) 18%, var(--surface) 82%);
  --area-btn-border:    var(--profile-secondary);
  --area-btn-grad:      var(--profile-grad-reverse);
  --area-btn-grad-hi:   color-mix(in srgb, var(--profile-secondary) 74%, var(--fg) 26%);
  --area-submit-bg:     color-mix(in srgb, var(--profile-primary) 18%, var(--surface) 82%);
  --area-submit-border: var(--profile-primary);
  --area-submit-grad:   var(--profile-grad);
  --area-side-grad:     linear-gradient(90deg, var(--profile-secondary-soft) 0%, transparent 100%);
  --area-frame:         var(--profile-secondary);
  --area-frame-soft:    var(--profile-secondary-soft);
}
body {
  --profile-primary:    var(--user-color, #7c9eff);
  --profile-secondary:  var(--user-color-secondary, #d4a8ff);
  --profile-primary-soft: color-mix(in srgb, var(--profile-primary) 28%, transparent);
  --profile-secondary-soft: color-mix(in srgb, var(--profile-secondary) 28%, transparent);
  --profile-grad:       linear-gradient(
                          90deg,
                          color-mix(in srgb, var(--profile-primary) 44%, var(--surface) 56%) 0%,
                          color-mix(in srgb, var(--profile-primary) 28%, var(--surface) 72%) 48%,
                          color-mix(in srgb, var(--profile-secondary) 38%, var(--surface) 62%) 100%
                        );
  --profile-grad-reverse: linear-gradient(
                          90deg,
                          color-mix(in srgb, var(--profile-secondary) 44%, var(--surface) 56%) 0%,
                          color-mix(in srgb, var(--profile-secondary) 28%, var(--surface) 72%) 48%,
                          color-mix(in srgb, var(--profile-primary) 38%, var(--surface) 62%) 100%
                        );
  --ui-accent:          var(--profile-primary);
  --ui-frame:           var(--ui-accent);
  --ui-frame-strong:    color-mix(in srgb, var(--ui-accent) 74%, var(--fg-muted) 26%);
  --ui-frame-soft:      color-mix(in srgb, var(--ui-accent) 28%, transparent);
  --ui-bg:              color-mix(in srgb, var(--ui-accent) 16%, var(--surface) 84%);
  /* Deuxieme niveau de la hierarchie bicolore. Un bloc porte la couleur
     primaire du profil sur son cadre exterieur et sur son bandeau de titre ;
     les sous-blocs encadres qu'il contient reprennent exactement la meme
     grammaire, mais sur la couleur secondaire. Le gris (--border-soft,
     --neutral-grad) reste le troisieme niveau, reserve a ce qui doit passer en
     arriere-plan : champs, lignes de liste inertes, pastilles, exemples. */
  --ui-sub-accent:      var(--profile-secondary);
  --ui-sub-frame:       var(--ui-sub-accent);
  --ui-sub-frame-strong: color-mix(in srgb, var(--ui-sub-accent) 74%, var(--fg-muted) 26%);
  --ui-sub-frame-soft:  color-mix(in srgb, var(--ui-sub-accent) 28%, transparent);
  --ui-sub-bg:          color-mix(in srgb, var(--ui-sub-accent) 16%, var(--surface) 84%);
  --ui-sub-grad:        var(--profile-grad-reverse);
  --neutral-grad:       linear-gradient(
                          90deg,
                          color-mix(in srgb, var(--border) 24%, var(--surface) 76%) 0%,
                          color-mix(in srgb, var(--border-soft) 10%, var(--surface) 90%) 52%,
                          rgba(var(--surface-rgb), 0.9) 100%
                        );
  /* Fond commun a tous les compteurs de statistiques du site : la couleur
     secondaire du profil, pour que chaque page reste bicolore avec son cadre. */
  --stat-grad:          linear-gradient(
                          90deg,
                          color-mix(in srgb, var(--profile-secondary) 34%, var(--surface)) 0%,
                          color-mix(in srgb, var(--profile-secondary) 12%, var(--surface)) 52%,
                          rgba(var(--surface-rgb), 0.9) 100%
                        );
  --ui-grad:            var(--profile-grad);
  --ui-side-grad:       linear-gradient(
                          90deg,
                          color-mix(in srgb, var(--ui-accent) 36%, transparent) 0%,
                          color-mix(in srgb, var(--ui-accent) 12%, transparent) 60%,
                          transparent 100%
                        );
}

input, select, textarea, button,
input[type="file"]::file-selector-button,
dialog, fieldset {
  border-radius: 0;
  font-family: inherit;
}
.ui-compact-dialog {
  background: transparent;
  border: 0;
  color: var(--fg);
  left: 50%;
  margin: 0;
  overflow: visible;
  padding: 0;
  position: fixed;
  top: 50%;
  transform: translate(-50%, -50%);
  width: min(var(--ui-dialog-width), calc(100vw - (2 * var(--page-gutter))));
}
.ui-compact-dialog::backdrop {
  background: rgba(var(--shadow-rgb), 0.28);
  backdrop-filter: blur(1px);
}

/* ── Bandeau de messages ──────────────────────────────────────────────
   Canal unique de retour utilisateur, rendu une seule fois par nav.php.
   Il est fixe et son bord bas se cale a --ui-panel-gap au-dessus de l'arete
   haute du bloc central : il grandit vers le haut dans la bande libre sous
   la nav, sans jamais pousser la page. Sa largeur est celle du rail central.
   Aucune page ne redefinit cette geometrie. */
.flash-banner {
  display: grid;
  gap: var(--ui-frame-gap);
  left: 50%;
  pointer-events: none;
  position: fixed;
  top: calc(var(--nav-clearance) - var(--ui-panel-gap));
  transform: translate(-50%, -100%);
  width: min(var(--content-rail-width), calc(100vw - (2 * var(--page-gutter))));
  z-index: 150;
}
.flash-banner[hidden] {
  display: none;
}
.flash-banner-message {
  background: var(--surface);
  border: 1px solid var(--border-soft);
  color: var(--fg);
  cursor: pointer;
  font-size: 0.68rem;
  line-height: 1.25;
  margin: 0;
  padding: var(--ui-text-pad);
  pointer-events: all;
}
/* Succes et neutre restent entierement gris : le bandeau flotte au-dessus de
   l'interface, il ne doit pas se confondre avec les cadres colores des blocs.
   Seule l'erreur garde le rouge, qui n'appartient a aucun duo de compte. */
.flash-banner-message-error {
  border-color: var(--danger);
  color: var(--danger);
}

/* Tout controle actionnable annonce son clic : le doigt appartient au bouton
   lui-meme, jamais a une regle locale ajoutee page par page. */
button,
input[type="button"],
input[type="submit"],
input[type="file"]::file-selector-button,
label:has(> input[type="checkbox"]),
label:has(> input[type="radio"]),
summary {
  cursor: pointer;
}
button:disabled,
input[type="button"]:disabled,
input[type="submit"]:disabled,
button[aria-disabled="true"] {
  cursor: not-allowed;
}
button,
input[type="button"],
input[type="submit"],
input[type="file"]::file-selector-button {
  appearance: none;
  -webkit-appearance: none;
  line-height: var(--ui-button-line-height);
  white-space: nowrap;
}
/* Forcer le rendu carré sur les selects natifs (Safari/Chrome arrondissent par défaut) */
select {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path fill='none' stroke='%23686860' stroke-width='1.2' d='M1 1.4l4 3.4 4-3.4'/></svg>");
  background-repeat: no-repeat;
  background-position: right 6px center;
  padding-right: 20px !important;
}
input[type="file"] {
  font-size: 0.72rem;
  color: var(--fg-soft);
  padding: 0;
  background: transparent;
  border: 0;
}
input[type="file"]::file-selector-button {
  border: 1px solid var(--area-btn-border);
  background: var(--area-btn-bg);
  color: var(--fg);
  font-size: 0.66rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  height: var(--ui-button-height);
  padding: var(--ui-button-pad);
  margin-right: 8px;
  cursor: pointer;
}
input[type="file"]::file-selector-button:hover {
  background: var(--area-btn-grad);
  border-color: var(--area-btn-grad-hi);
}
/* Placeholder gris clair quand l'option vide est sélectionnée */
select:has(option[value=""]:checked) {
  color: var(--fg-faint);
}
select option {
  color: var(--fg);
}
select option[value=""] {
  color: var(--fg-faint);
}
html {
  font-size: 14px;
  scrollbar-width: none;
  background:
    linear-gradient(var(--bg-grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--bg-grid) 1px, transparent 1px),
    var(--bg);
  background-attachment: fixed;
  background-size: var(--bg-grid-size, 28px) var(--bg-grid-size, 28px);
  transition: background-color var(--motion-palette) var(--motion-ease);
}
html::-webkit-scrollbar { display: none; }
body {
  font-family: Helvetica, Arial, sans-serif;
  min-height: 100vh;
  background:
    linear-gradient(var(--bg-grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--bg-grid) 1px, transparent 1px),
    var(--bg);
  background-attachment: fixed;
  background-size: var(--bg-grid-size, 28px) var(--bg-grid-size, 28px);
  color: var(--fg);
  transition:
    background-color var(--motion-palette) var(--motion-ease),
    color var(--motion-palette) var(--motion-ease);
}
body.references-area {
  background:
    linear-gradient(var(--bg-grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--bg-grid) 1px, transparent 1px),
    var(--bg);
  background-attachment: fixed;
  background-size: var(--bg-grid-size, 28px) var(--bg-grid-size, 28px);
}
/* Modes de visualisation : on retire la grille pour laisser respirer la viz. */
html:has(body.atlas-area),
body.atlas-area {
  background: var(--bg);
}

/* Voile sous la nav : le contenu qui remonte se fond dans le fond avant
   de passer derrière les boutons du menu (évite les icônes qui leakent
   entre les frames des boutons). */
body::before {
  content: '';
  position: fixed;
  inset: 0 0 auto 0;
  height: var(--nav-clearance);
  z-index: 49;
  pointer-events: none;
  background:
    linear-gradient(var(--bg-grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--bg-grid) 1px, transparent 1px),
    var(--bg);
  background-size: var(--bg-grid-size, 28px) var(--bg-grid-size, 28px);
  -webkit-mask: linear-gradient(to bottom, #000 0%, #000 68%, transparent 100%);
          mask: linear-gradient(to bottom, #000 0%, #000 68%, transparent 100%);
}
body.atlas-area::before {
  display: none;
}
a { color: inherit; text-decoration: none; }
.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ── Custom font ── */
@font-face {
  font-family: 'AdvercaseFont';
  src: url('/assets/fonts/AdvercaseFont-Regular.otf') format('opentype');
  font-weight: normal;
  font-style: normal;
}
