/* ==========================================================================
   Oui Oui Car's — mouvement (lot MOUVEMENT)
   Moments signature du brief §8 : 1 le feu à deux oui (js/motion/intro.js),
   4 le radar de lecture (radar.js), 5 allumer les phares (phares.js),
   6 le créneau qui fait un créneau (creneau.js).
   Uniquement des jetons de tokens.css. Animations : transform, opacity, clip-path.
   Mode calme (html[data-calme="on"]) et prefers-reduced-motion : les JS
   vérifient mouvementAutorise() avant toute animation Web Animations et
   base.css neutralise les transitions CSS ; tout arrive à son état final.
   Chargé sur toutes les pages (SPEC §4) : rien ne s'affiche sans son JS.
   ========================================================================== */

/* Propriété animable : l'éclat des pépites (0 → 1) peut ainsi être transitionné. */
@property --eclat {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}

/* --------------------------------------------------------------------------
   1. Le feu à deux oui (intro.js)
   Les lampes suivent la convention de base.css ([data-pilotee], [data-allumee]).
   2e page vue de la session : tier.js pose html[data-intro="vue"] avant la
   première peinture, les lampes sont donc allumées d'emblée (brief §5).
   :where() garde une spécificité basse : le survol (halo 1 → 1,4) reste prioritaire.
   -------------------------------------------------------------------------- */
:where(:root[data-intro="vue"]) .lampe:not([data-allumee="0"])::before { opacity: 1; }
:where(:root[data-intro="vue"]) .lampe:not([data-allumee="0"])::after { opacity: 1; transform: scale(1); }

/* --------------------------------------------------------------------------
   2. Le radar de lecture (radar.js)
   -------------------------------------------------------------------------- */

/* 2.1 Flash : un seul, blanc, 30 % au plus, 160 ms (jamais rouge). */
.radar-flash {
  position: fixed;
  inset: 0;
  z-index: var(--z-flash);
  background: var(--blanc);
  opacity: 0;
  pointer-events: none;
}

/* 2.2 Panneau rond de limitation (aria-hidden), redessiné aux couleurs de la route du oui :
   cercle orange « radar », jamais de rouge. Toutes les cotes suivent --radar-taille (36 px par défaut).
   Deux régimes, choisis par radar.js selon la marge droite réellement libre :
   - « marge » (ordinateur) : panneau fixe, centré verticalement dans la marge droite, réduit jusqu'à
     24 px pour ne jamais toucher les cartes (--radar-taille et --radar-droite posés par radar.js) ;
   - « borne » (mobile, tablette) : panneaux sur mât plantés au bord droit des vitres, visibles en fondu
     seulement pendant un défilement rapide (.radar-borne[data-visible]). */
.radar-panneau {
  --radar-taille: 36px;
  display: grid;
  place-items: center;
  width: var(--radar-taille);
  height: var(--radar-taille);
  border-radius: 50%;
  background: var(--blanc);
  color: var(--asphalte);
  box-shadow:
    inset 0 0 0 calc(var(--radar-taille) * .11) var(--orange-clignotant),
    0 0 0 1.5px var(--asphalte-a12),
    0 6px 14px -6px var(--asphalte-a70);
  font-family: var(--police-texte);
  font-weight: 800;
  font-size: calc(var(--radar-taille) * .42);
  line-height: 1;
  letter-spacing: -.03em;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
  user-select: none;
  transition: box-shadow var(--d-moyen) ease;
}
.radar-panneau[data-chiffres="3"] { font-size: calc(var(--radar-taille) * .35); letter-spacing: -.06em; }
.radar-panneau__valeur { display: block; transform: translateY(.5px); }
/* Juste après un flash : le cercle s'embrase une seconde. */
.radar-panneau[data-flashe] {
  box-shadow:
    inset 0 0 0 calc(var(--radar-taille) * .11) var(--orange-clignotant),
    0 0 0 5px var(--orange-a25),
    0 0 22px 4px var(--orange-a25),
    0 6px 14px -6px var(--asphalte-a70);
}

/* Régime « marge » : fixe, dans la marge droite (jamais sur les cartes ni rogné). */
body > .radar-panneau {
  position: fixed;
  top: 50%;
  right: max(var(--radar-droite, 12px), env(safe-area-inset-right, 0px));
  z-index: calc(var(--z-entete) - 2);
  translate: 0 -50%;
  transition: opacity var(--d-court) ease, box-shadow var(--d-moyen) ease;
}
/* Un contenu déborde dans la marge (carrousel horizontal…) et traverse sa bande : il s'efface. */
body > .radar-panneau[data-evite] { opacity: 0; }

/* Régime « borne » : un panneau sur mât au bord droit de la vitre, aligné sur la colonne de contenu.
   La vitre est une zone décorative sans texte (aria-hidden) : la borne ne masque jamais rien à lire. */
:where([data-vitre]):has(> .radar-borne) { position: relative; }
.radar-borne {
  --radar-taille: 40px;
  position: absolute;
  top: 50%;
  right: calc(max(var(--gouttiere), env(safe-area-inset-right, 0px)) + max(0px, (100% - var(--largeur-max) - 2 * var(--gouttiere)) / 2));
  z-index: 1;
  display: grid;
  justify-items: center;
  translate: 0 -50%;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity var(--d-court) ease, visibility 0s linear var(--d-court);
}
.radar-borne[hidden], .radar-borne[data-trop-petite] { display: none; }
.radar-borne[data-visible] {
  opacity: 1;
  visibility: visible;
  transition: opacity var(--d-micro) ease, visibility 0s;
}
.radar-borne__mat {
  display: block;
  width: 4px;
  height: var(--radar-mat, calc(var(--radar-taille) * .9));
  margin-top: -2px;
  border-radius: 0 0 2px 2px;
  background: linear-gradient(90deg, var(--beton), var(--gris-glissiere) 60%, var(--beton));
  box-shadow: 0 2px 6px -2px var(--asphalte-a70);
}
.radar-panneau--borne { --radar-taille: inherit; position: relative; z-index: 1; }

/* 2.3 L'avis : un ticket de radar qui sort du bas de l'écran (non modal). */
.radar-avis {
  position: fixed;
  left: 50%;
  bottom: calc(var(--s-4) + var(--zone-sure-bas));
  z-index: calc(var(--z-toast) + 2);
  width: min(560px, calc(100vw - 24px));
  translate: -50% 0;
  filter: drop-shadow(0 22px 26px var(--asphalte-a45)) drop-shadow(0 2px 1px var(--asphalte-a12));
  outline: none;
  border-radius: var(--r-bouton);
}
html[data-barre-bas="1"] .radar-avis { bottom: calc(var(--h-barre-bas) + var(--zone-sure-bas) + var(--s-3)); }
.radar-avis:focus-visible { outline: 3px solid var(--vert-oui); outline-offset: 3px; }

.radar-avis__ticket {
  /* Le ticket reste en papier crème, de jour comme de nuit : variables locales pour les .btn */
  --texte: var(--asphalte);
  --texte-2: var(--asphalte-a70);
  --lien: var(--vert-profond);
  --trait: var(--asphalte-a12);
  --survol: var(--asphalte-a06);
  position: relative;
  display: grid;
  overflow: hidden;
  border-radius: 3px 3px var(--r-bouton) var(--r-bouton);
  background-color: var(--creme);
  background-image: var(--grain-marquage);
  background-size: 160px;
  color: var(--asphalte);
  color-scheme: light;
  /* Bord supérieur perforé, comme un ticket arraché à l'imprimante du radar */
  -webkit-mask: radial-gradient(circle 4.5px at 50% 0, transparent 94%, var(--asphalte) 100%) 0 0 / 13px 100% repeat-x;
  mask: radial-gradient(circle 4.5px at 50% 0, transparent 94%, var(--asphalte) 100%) 0 0 / 13px 100% repeat-x;
}

/* Bandeau : panneau à messages variables (points orange sur matrice sombre, brief §6 PK 2) */
.radar-avis__bandeau {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  padding: 16px 18px 12px;
  background-color: var(--matrice);
  background-image: radial-gradient(circle, var(--creme-a06) .9px, transparent 1.3px);
  background-size: 4px 4px;
  color: var(--orange-clignotant);
}
.radar-avis__etiquette {
  display: grid;
  gap: 2px;
  font-family: var(--police-texte);
  font-weight: 800;
  font-size: 11px;
  line-height: 1.15;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--gris-glissiere);
}
.radar-avis__etiquette strong { color: var(--creme); font-weight: 800; }
.radar-avis__matrice {
  display: inline-flex;
  align-items: baseline;
  gap: .28em;
  font-family: var(--police-texte);
  font-weight: 800;
  font-size: clamp(26px, 8vw, 36px);
  line-height: 1;
  letter-spacing: .05em;
  text-transform: uppercase;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  /* le texte n'existe que sur la grille de points : une vraie matrice de LED */
  -webkit-mask-image: radial-gradient(circle, var(--asphalte) 1.1px, transparent 1.5px);
  -webkit-mask-size: 3px 3px;
  mask-image: radial-gradient(circle, var(--asphalte) 1.1px, transparent 1.5px);
  mask-size: 3px 3px;
}
.radar-avis__matrice small { font-size: .5em; letter-spacing: .12em; }

.radar-avis__corps {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--s-3) var(--s-4);
  padding: var(--s-4) 18px var(--s-2);
}

/* La « photo » du radar : Hoche surpris dans le viseur, bandeau de données horodaté en dessous */
.radar-avis__photo {
  position: relative;
  display: grid;
  grid-template-rows: 1fr auto;
  width: 108px;
  height: 132px;
  overflow: hidden;
  border-radius: var(--r-panneau);
  background: var(--asphalte);
  box-shadow: inset 0 0 0 1px var(--asphalte-a45);
}
.radar-avis__cliche {
  position: relative;
  display: grid;
  place-items: end center;
  background:
    radial-gradient(120% 80% at 50% 10%, var(--creme-a20), transparent 62%),
    linear-gradient(to top, var(--lampe-eteinte) 0 26%, transparent 26%);
}
.radar-avis__cliche::after {
  /* ligne de rive sur la chaussée de la photo */
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 26%;
  height: 2px;
  background: var(--creme-a40);
}
.radar-avis__hoche { position: relative; z-index: 1; margin-bottom: 7px; }
.radar-avis__viseur {
  position: absolute;
  inset: 7px;
  z-index: 2;
  --c: var(--orange-clignotant);
  background:
    linear-gradient(var(--c), var(--c)) 0 0 / 11px 2px no-repeat,
    linear-gradient(var(--c), var(--c)) 0 0 / 2px 11px no-repeat,
    linear-gradient(var(--c), var(--c)) 100% 0 / 11px 2px no-repeat,
    linear-gradient(var(--c), var(--c)) 100% 0 / 2px 11px no-repeat,
    linear-gradient(var(--c), var(--c)) 0 100% / 11px 2px no-repeat,
    linear-gradient(var(--c), var(--c)) 0 100% / 2px 11px no-repeat,
    linear-gradient(var(--c), var(--c)) 100% 100% / 11px 2px no-repeat,
    linear-gradient(var(--c), var(--c)) 100% 100% / 2px 11px no-repeat;
  opacity: .9;
}
.radar-avis__zone {
  position: absolute;
  right: 12px;
  top: 12px;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--blanc);
  box-shadow: inset 0 0 0 3px var(--orange-clignotant);
  color: var(--asphalte);
  font-family: var(--police-texte);
  font-weight: 800;
  font-size: 10px;
  letter-spacing: -.04em;
}
.radar-avis__horodatage {
  display: block;
  padding: 5px 6px 6px;
  background: var(--matrice);
  color: var(--orange-clignotant);
  font-family: var(--police-texte);
  font-weight: 800;
  font-size: 11px;
  line-height: 1;
  letter-spacing: .03em;
  font-variant-numeric: tabular-nums;
  text-align: center;
  white-space: nowrap;
}

.radar-avis__texte { display: grid; align-content: start; gap: 6px; min-width: 0; }
.radar-avis__surtitre {
  font-size: var(--fs-mention);
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--asphalte-a70);
}
.radar-avis__titre {
  font-family: var(--police-affichage);
  font-weight: 700;
  font-size: clamp(19px, 5vw, 23px);
  line-height: 1.12;
  letter-spacing: -.01em;
  text-wrap: balance;
}
/* Le titre reçoit le focus à l'ouverture (non interactif) : pas d'anneau, le dialogue est déjà annoncé. */
.radar-avis__titre:focus, .radar-avis__titre:focus-visible { outline: none; box-shadow: none; }
.radar-avis__details { display: grid; gap: 8px; font-size: var(--fs-base); line-height: 1.4; }
.radar-avis__amende strong { font-weight: 800; }
.radar-avis__demi-tours {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 0;
  list-style: none;
}
.radar-avis__demi-tour {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  max-width: 100%;
  padding: 6px 14px 6px 6px;
  border-radius: var(--r-panneau);
  background: var(--asphalte);
  color: var(--creme);
  text-decoration: none;
  box-shadow: 0 2px 0 var(--asphalte-a45);
  transition: transform var(--d-micro) var(--e-sortie);
}
.radar-avis__demi-tour:hover { transform: translateY(-1px); text-decoration: none; }
.radar-avis__demi-tour:active { transform: translateY(1px); box-shadow: none; }
.radar-avis__demi-tour-icone {
  display: grid;
  place-items: center;
  flex: none;
  width: 32px;
  height: 32px;
  border-radius: 5px;
  background: var(--vert-oui);
  color: var(--asphalte);
}
.radar-avis__demi-tour-icone .i { width: 22px; height: 22px; }
.radar-avis__demi-tour-texte { display: grid; min-width: 0; line-height: 1.2; }
.radar-avis__demi-tour-label {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--gris-glissiere);
}
.radar-avis__demi-tour-titre {
  overflow: hidden;
  font-size: var(--fs-s);
  font-weight: 700;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.radar-avis__stage {
  color: var(--vert-profond);
  font-weight: 800;
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}
.radar-avis__stage:hover { text-decoration-thickness: 3px; }

.radar-avis__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2) var(--s-3);
  padding: var(--s-3) 18px 18px;
}
.radar-avis__actions .btn--fantome { --btn-texte: var(--asphalte-a70); font-weight: 700; }

/* Compte à rebours de la fermeture automatique (10 s) : une jauge orange qui se vide. */
.radar-avis__compte {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 4px;
  background: var(--orange-clignotant);
  transform-origin: 0 50%;
  transform: scaleX(0);
}
html[data-calme="on"] .radar-avis__compte { display: none; }
@media (prefers-reduced-motion: reduce) { .radar-avis__compte { display: none; } }

@media (max-width: 419px) {
  .radar-avis__bandeau { padding: 14px 14px 10px; }
  .radar-avis__corps { gap: var(--s-2) var(--s-3); padding: var(--s-3) 14px var(--s-2); }
  .radar-avis__photo { width: 88px; height: 112px; }
  .radar-avis__horodatage { font-size: 10px; letter-spacing: 0; }
  .radar-avis__actions { padding: var(--s-2) 14px 16px; }
  .radar-avis__actions .btn--primaire { flex: 1 1 auto; }
}

/* --------------------------------------------------------------------------
   3. Allumer les phares (phares.js)
   -------------------------------------------------------------------------- */

/* 3.1 Faisceau : calque fixe entre le canvas (z 0) et le contenu (z 2).
   Il n'assombrit que la couche décorative visible par les vitres ; les cartes, opaques
   et au-dessus, restent pleinement lisibles. Le cône (radial-gradient de 280 px) suit
   --x / --y ; il est déplacé en transform (composité), une seule boucle rAF. */
.faisceau {
  position: fixed;
  inset: 0;
  z-index: var(--z-faisceau);
  overflow: hidden;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--d-long) ease;
  contain: strict;
}
.faisceau[data-actif] { opacity: 1; }
.faisceau__cone {
  position: absolute;
  left: 0;
  top: 0;
  width: 200vw;
  height: 200vh;
  background:
    radial-gradient(circle 280px at 50% 50%,
      var(--creme-a20) 0%,
      var(--creme-a06) 30%,
      transparent 58%,
      var(--nuit-a80) 100%);
  will-change: transform;
}

/* 3.2 Pépites rétroréfléchissantes : posées dans les vitres par la page,
   visibles seulement phares allumés (html[data-pepites], posé par phares.js).
   L'élément est une ancre de taille nulle au point (--pepite-x ; --pepite-y) de sa vitre. */
:where([data-vitre]):has(> [data-pepite]) { position: relative; }
[data-pepite] {
  position: absolute;
  left: var(--pepite-x, 50%);
  top: var(--pepite-y, 50%);
  z-index: 1;
  display: none;
  width: 0;
  height: 0;
  pointer-events: none;
}
:root[data-phares="on"][data-pepites] [data-pepite] { display: block; }
.pepite__oeil {
  position: absolute;
  left: -10px;
  top: -10px;
  width: 20px;
  height: 20px;
  border-radius: 5px;
  rotate: 45deg;
  background: var(--lampe-eteinte);
  box-shadow: inset 0 0 0 2px var(--asphalte), 0 0 0 1px var(--creme-a12);
}
.pepite__oeil::before,
.pepite__oeil::after {
  content: "";
  position: absolute;
  border-radius: 3px;
}
.pepite__oeil::before {
  /* le catadioptre renvoie la lumière : cœur blanc, halo crème */
  inset: 4px;
  background: var(--blanc);
  opacity: var(--eclat);
  box-shadow: 0 0 10px 3px var(--creme-a70), 0 0 26px 8px var(--creme-a20);
}
.pepite__oeil::after {
  /* reflet discret, même éteint : on devine qu'il y a quelque chose */
  inset: 5px 9px 9px 5px;
  background: var(--creme-a20);
  opacity: calc(.7 - var(--eclat) * .7);
}
.pepite__texte {
  position: absolute;
  left: 22px;
  top: 0;
  width: max-content;
  max-width: min(260px, var(--pepite-max, 62vw));
  padding: 8px 12px 9px;
  border-radius: var(--r-panneau);
  background: var(--asphalte-a85);
  color: var(--creme);
  box-shadow: 0 0 0 1px var(--creme-a20), 0 10px 24px -12px var(--asphalte);
  font-family: var(--police-texte);
  font-weight: 700;
  font-size: var(--fs-s);
  line-height: 1.35;
  opacity: var(--eclat);
  transform: translate(calc((1 - var(--eclat)) * -8px), -50%);
}
[data-pepite][data-cote="gauche"] .pepite__texte {
  left: auto;
  right: 22px;
  transform: translate(calc((1 - var(--eclat)) * 8px), -50%);
}
/* Au doigt : la pépite s'allume, centrée à l'écran, en fondu (phares de Hoche). */
:root[data-pepites="centre"] [data-pepite] { transition: --eclat var(--d-long) var(--e-sortie); }
:root[data-pepites="souris"] [data-pepite] { transition: --eclat var(--d-micro) linear; }

/* --------------------------------------------------------------------------
   4. Le créneau qui fait un créneau (creneau.js)
   -------------------------------------------------------------------------- */
.creneau-calque {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: block;
  overflow: visible;
  pointer-events: none;
  border-radius: inherit;
}
.creneau-repere {
  position: absolute;
  left: 0;
  top: 0;
  display: block;
  transform-origin: 0 0;
}
.creneau-voiture {
  position: absolute;
  left: 0;
  top: 0;
  display: block;
  transform-origin: 50% 50%;
  line-height: 0;
}
.creneau-voiture ooc-hoche { display: block; }
/* La place s'éclaire en vert quand Hoche y est rangé. */
.creneau-halo {
  position: absolute;
  inset: 2px;
  display: block;
  border-radius: inherit;
  box-shadow: inset 0 0 0 2px var(--vert-oui), inset 0 0 18px var(--vert-oui-a25);
  opacity: 0;
}
[data-creneau="gare"] > .creneau-calque .creneau-halo { opacity: .85; }
.creneau-coche {
  position: absolute;
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--vert-oui);
  color: var(--asphalte);
  box-shadow: 0 0 0 2px var(--asphalte);
  translate: -50% -50%;
}
.creneau-coche .i { width: 16px; height: 16px; }
/* Bulle de Hoche (brief §3.1) : crème, rayon 6, pointe en bas à gauche, Unbounded 700 vert profond */
.creneau-bulle {
  position: absolute;
  display: block;
  padding: .5em .7em .46em;
  border-radius: 6px;
  background: var(--creme);
  color: var(--vert-profond);
  box-shadow: 0 1px 0 var(--asphalte-a06), 0 8px 18px -8px var(--asphalte-a45);
  font-family: var(--police-affichage);
  font-weight: 700;
  font-size: var(--creneau-bulle-fs, 13px);
  line-height: 1.12;
  letter-spacing: .005em;
  white-space: nowrap;
  transform: translateY(calc(-100% - .55em));
  transform-origin: 0 100%;
}
.creneau-bulle::after {
  content: "";
  position: absolute;
  left: .5em;
  top: calc(100% - 1px);
  width: .7em;
  height: .55em;
  background: inherit;
  clip-path: polygon(0 0, 100% 0, 0 100%);
}
.creneau-bulle > span { display: block; }
.creneau-bulle--gauche { transform: translate(-100%, calc(-100% - .55em)); transform-origin: 100% 100%; }
.creneau-bulle--gauche::after { left: auto; right: .5em; clip-path: polygon(0 0, 100% 0, 100% 100%); }
html[data-persona="passager"] .creneau-bulle { display: none; }
/* Déboîter : le Hoche « à moi » de la page s'efface le temps que le nôtre quitte la place. */
[data-creneau="deboite"] ooc-hoche:not(.creneau-hoche) { visibility: hidden; }

/* --------------------------------------------------------------------------
   5. Impression
   -------------------------------------------------------------------------- */
@media print {
  .radar-flash, .radar-panneau, .radar-borne, .radar-avis, .faisceau, [data-pepite], .creneau-bulle { display: none !important; }
}
