/* Rupteur - habillage écran de bord, langage visuel Tesla : monochrome,
   blanc le jour, noir la nuit, hairlines discrètes, rouge réservé à la
   zone rouge et aux erreurs. Aucun décor, aucune couleur d'accent.
   Cible unique : le navigateur de la Model 3 (fenêtre 773x601, tactile). */

/* ---------- Police, auto-hébergée ----------
   Le service worker ne met en cache que l'origine : une fonte Google
   disparaîtrait hors ligne, donc dans la voiture. Elle vit ici.
   Montserrat est le clone libre du Gotham de l'interface Tesla ;
   fichier variable, une seule ressource pour 400 à 600. */

@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('fonts/montserrat-var-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('fonts/montserrat-var-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ---------- Thèmes ----------
   Nuit par défaut : au volant, un écran blanc imprévu éblouit, l'inverse
   ne fait que manquer de contraste. Le jour arrive par la préférence
   système de la voiture, ou par le réglage Apparence qui force. Le canvas
   du compte-tours lit les jetons --gauge-* à la reconstruction du cadran. */

:root {
  --bg: #0e0e0e;              /* noir neutre, aucune composante bleutée */
  --surface: #1a1a1a;         /* panneaux et cartes */
  --raised: rgba(255, 255, 255, 0.06);   /* contrôles au repos */
  --raised-2: rgba(255, 255, 255, 0.14); /* contrôles pressés */
  --line: rgba(255, 255, 255, 0.08);
  --text: #eaeaea;
  --muted: #9a9a9a;
  --faint: #616161;
  --primary: #eaeaea;         /* bouton principal : pilule blanche la nuit */
  --primary-text: #0e0e0e;
  --pill: #eaeaea;            /* segment actif */
  --pill-text: #0e0e0e;
  --pill-shadow: none;
  --red: #e82127;             /* zone rouge, erreurs, rien d'autre */
  --red-text: #ff7377;
  --warn: #f0b64c;            /* attentes et indications */
  --ok: #4caf50;
  --overlay: rgba(0, 0, 0, 0.6);
  --gauge-rail: rgba(255, 255, 255, 0.1);
  --gauge-tick: rgba(255, 255, 255, 0.28);
  --gauge-tick-min: rgba(255, 255, 255, 0.12);
  --gauge-red-rail: rgba(232, 33, 39, 0.35);
  --gauge-red-tick: rgba(232, 33, 39, 0.7);
  --gauge-red-text: #ff5a5f;
  --r: 8px;
  --r-lg: 12px;
  --font: 'Montserrat', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
}

/* Jour : mêmes jetons, valeurs claires. Deux blocs identiques parce que
   le CSS ne sait pas encore factoriser "média OU attribut". */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --bg: #f4f4f4;
    --surface: #ffffff;
    --raised: rgba(0, 0, 0, 0.05);
    --raised-2: rgba(0, 0, 0, 0.14);
    --line: rgba(0, 0, 0, 0.08);
    --text: #0e0e0e;
    --muted: #5c5c5c;
    --faint: #9a9a9a;
    --primary: #0e0e0e;
    --primary-text: #ffffff;
    --pill: #ffffff;
    --pill-text: #0e0e0e;
    --pill-shadow: 0 1px 4px rgba(0, 0, 0, 0.18);
    --red-text: #c4181d;
    --warn: #a8791f;
    --ok: #2e7d32;
    --overlay: rgba(125, 125, 130, 0.4);
    --gauge-rail: rgba(0, 0, 0, 0.08);
    --gauge-tick: rgba(0, 0, 0, 0.35);
    --gauge-tick-min: rgba(0, 0, 0, 0.14);
    --gauge-red-rail: rgba(232, 33, 39, 0.25);
    --gauge-red-tick: rgba(232, 33, 39, 0.6);
    --gauge-red-text: #d31a20;
  }
}
:root[data-theme="light"] {
  --bg: #f4f4f4;
  --surface: #ffffff;
  --raised: rgba(0, 0, 0, 0.05);
  --raised-2: rgba(0, 0, 0, 0.14);
  --line: rgba(0, 0, 0, 0.08);
  --text: #0e0e0e;
  --muted: #5c5c5c;
  --faint: #9a9a9a;
  --primary: #0e0e0e;
  --primary-text: #ffffff;
  --pill: #ffffff;
  --pill-text: #0e0e0e;
  --pill-shadow: 0 1px 4px rgba(0, 0, 0, 0.18);
  --red-text: #c4181d;
  --warn: #a8791f;
  --ok: #2e7d32;
  --overlay: rgba(125, 125, 130, 0.4);
  --gauge-rail: rgba(0, 0, 0, 0.08);
  --gauge-tick: rgba(0, 0, 0, 0.35);
  --gauge-tick-min: rgba(0, 0, 0, 0.14);
  --gauge-red-rail: rgba(232, 33, 39, 0.25);
  --gauge-red-tick: rgba(232, 33, 39, 0.6);
  --gauge-red-text: #d31a20;
}

* { box-sizing: border-box; }

html, body {
  height: 100%;
  margin: 0;
}

body {
  background: var(--bg);
  color: var(--text);
  font: 15px/1.45 var(--font);
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
  overscroll-behavior: none;
  display: flex;
  flex-direction: column;
  padding-bottom: env(safe-area-inset-bottom);
}

/* Un sélecteur de classe portant display: bat l'attribut [hidden] de la
   feuille navigateur. Sans ce garde, .panel et .pedals restent visibles. */
[hidden] { display: none !important; }

button, select, input { font: inherit; color: inherit; }
button { cursor: pointer; -webkit-tap-highlight-color: transparent; }
.muted { color: var(--muted); }
.small { font-size: 13px; }

/* Barres de défilement discrètes, assorties au fond. */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--raised-2); border-radius: 3px; }

/* ---------- Barre supérieure ---------- */

.bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 5px 16px;
  border-bottom: 1px solid var(--line);
  flex: 0 0 auto;
}

.brand { display: flex; align-items: center; gap: 14px; min-width: 0; }

/* Marque en capitales espacées, comme le lettrage T E S L A. */
.logo {
  font-weight: 500;
  font-size: 15px;
  letter-spacing: 0.42em;
  margin-right: -0.42em; /* compense l'espacement après la dernière lettre */
  color: var(--text);
}

.status {
  font-size: 12px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.status::before {
  content: "";
  display: inline-block;
  width: 7px; height: 7px;
  border-radius: 50%;
  margin-right: 8px;
  background: var(--faint);
  vertical-align: middle;
}
.status.ok::before { background: var(--ok); }
.status.wait::before { background: var(--warn); animation: pulse 1.4s ease-in-out infinite; }
.status.bad { color: var(--red-text); }
.status.bad::before { background: var(--red); }

/* Version réellement en service (celle du service worker qui contrôle la
   page) : le seul moyen, depuis la voiture, de savoir si une mise à jour
   est passée ou si l'écran rejoue encore l'ancienne. */
.version {
  font-size: 11px;
  color: var(--muted);
  opacity: 0.65;
  white-space: nowrap;
}

/* Pastille de mise à jour : une nouvelle version a pris le contrôle pendant
   que la page tournait, le code en mémoire est en retard. On le DIT, on ne
   recharge jamais tout seul : pas en roulant. */
.maj {
  position: fixed;
  left: 16px;
  bottom: 16px;
  z-index: 80;
  padding: 11px 16px;
  border: 0;
  border-radius: var(--r);
  background: var(--primary);
  color: var(--primary-text);
  font-weight: 600;
  font-size: 13px;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.35);
}
.maj:active { filter: brightness(0.85); }

/* ---------- Nouvelle version : la fenêtre ----------
   Au-dessus de la pastille (80), qui se cache pendant qu'elle est ouverte.
   Le numéro de version en grand, comme le rapport engagé du compte-tours :
   c'est la seule chose qu'on doit lire d'un coup d'œil. Tout tient dans
   773x601 sans défiler, quatre nouveautés sur deux lignes comprises. */
.maj-fond { z-index: 90; }
/* Double classe : `.panel-inner`, déclaré plus bas, imposerait sinon ses 880 px. */
.panel-inner.maj-carte {
  width: min(660px, 100%);
  padding: 28px 30px 22px;
  animation: maj-entree 0.32s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.maj-titre { margin: 0; display: grid; gap: 4px; font-weight: 600; }
.maj-sur {
  font-size: 11px;
  letter-spacing: 2.2px;
  text-transform: uppercase;
  color: var(--muted);
}
.maj-numero {
  font-size: 56px;
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.maj-intro { margin: 20px 0 8px; font-size: 13px; color: var(--muted); }
.maj-liste { list-style: none; margin: 0; padding: 0; }
.maj-liste li {
  display: grid;
  grid-template-columns: 22px 1fr;
  gap: 8px;
  padding: 10px 0;
  border-top: 1px solid var(--line);
  font-size: 15px;
  line-height: 1.4;
}
.maj-liste li:last-child { border-bottom: 1px solid var(--line); }
/* Une coche tracée en bordures : elle prend la couleur du thème, là où une
   image aurait figé un blanc ou un noir. */
.maj-liste li::before {
  content: '';
  width: 6px;
  height: 11px;
  margin: 3px 0 0 6px;
  border: solid var(--text);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.maj-actions { display: flex; gap: 10px; margin-top: 22px; }
/* Moteur en route, `.primary.big` passe au gris (bouton Arrêter) : ici le
   rechargement reste l'action principale, en blanc la nuit, noir le jour. */
#majpanel .primary.big {
  flex: 1 1 auto;
  background: var(--primary);
  color: var(--primary-text);
}
.maj-secondaire {
  flex: 0 0 auto;
  border: 0;
  border-radius: var(--r);
  padding: 14px 20px;
  background: var(--raised);
  color: var(--text);
  font-weight: 600;
  font-size: 16px;
}
.maj-secondaire:active { background: var(--raised-2); }
.maj-pied { margin: 12px 0 0; text-align: center; }
@keyframes maj-entree {
  from { opacity: 0; transform: translateY(12px) scale(0.98); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .maj-carte { animation: none; }
}

@keyframes pulse { 50% { opacity: 0.25; } }

.bar-actions { display: flex; gap: 4px; flex: 0 0 auto; }

/* Icônes de barre : glyphe seul, sans boîte, comme la barre Tesla. */
.icon {
  width: 44px; height: 44px;
  border: 0;
  border-radius: var(--r);
  background: transparent;
  color: var(--muted);
  font-size: 20px;
  line-height: 1;
  display: grid;
  place-items: center;
}
.icon svg { display: block; }
.icon:active { background: var(--raised); color: var(--text); }

/* ---------- Rampe de passage de rapport ---------- */

/* Discrète au repos, elle se remplit dans la couleur du texte puis en
   rouge à l'approche de la zone rouge. Pas de halo. */
.shiftlights {
  display: flex;
  justify-content: center;
  gap: clamp(4px, 1vw, 8px);
  padding: 6px 16px 1px;
  flex: 0 0 auto;
}
.shiftlights i {
  width: clamp(18px, 3vw, 30px);
  height: 5px;
  border-radius: 3px;
  background: var(--gauge-rail);
  transition: background 0.05s;
}
.shiftlights i.on { background: var(--text); }
.shiftlights i.on:nth-child(n+9) { background: var(--red); }
/* Rupteur : tout clignote. */
.shiftlights.lim i { animation: limiter 0.14s steps(2, end) infinite; }
@keyframes limiter { 50% { opacity: 0.2; } }

/* ---------- Scène ---------- */

/* Calé sur la fenêtre du navigateur Tesla : 773x601. La colonne de droite
   prend environ 300 px là-dessus, et respire si la fenêtre grandit. */
.stage {
  flex: 1 1 auto;
  min-height: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(280px, 39vw, 380px);
  gap: 16px;
  padding: 6px 16px 12px;
}

/* Zone gauche : le cadran prend toute la hauteur disponible ; en boîte
   manuelle, le bouton Rétrograder s'installe dessous, près du volant. */
.dial-wrap {
  position: relative;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

#tacho {
  flex: 1 1 0;
  min-height: 0;
  max-width: 100%;
  max-height: 100%;
  aspect-ratio: 1;
}

/* ---------- Colonne latérale ---------- */

/* La colonne se découpe en deux : une zone qui défile, et un pied fixe.
   Le bouton principal ne doit jamais recouvrir un réglage : sur un écran de
   voiture, un contrôle masqué est un contrôle inutilisable. */
.side {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 0;
}

.side-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-right: 4px;
}

.field { display: flex; flex-direction: column; gap: 4px; }
/* Ligne label + commande. Si la commande ne tient pas à côté du label dans
   la colonne Tesla, elle passe dessous, pleine largeur, sans déborder. */
.field.row { flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 5px 10px; }
.field.row .seg { flex: 1 1 auto; }
.field label {
  font-size: 12px;
  font-weight: 500;
  color: var(--muted);
}

select {
  appearance: none;
  background: var(--raised) url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8'><path d='M1 1l5 5 5-5' stroke='%239a9a9a' stroke-width='1.8' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>") no-repeat right 12px center;
  border: 0;
  border-radius: var(--r);
  padding: 10px 34px 10px 12px;
  width: 100%;
  font-weight: 500;
  font-size: 14px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
select:disabled { opacity: 0.5; }

/* Commande segmentée : rail discret, segment actif en pilule claire.
   Le motif Tesla, sans couleur par mode. */
.seg {
  display: flex;
  background: var(--raised);
  border-radius: var(--r);
  padding: 2px;
  gap: 2px;
}
.seg button {
  border: 0;
  background: transparent;
  color: var(--muted);
  padding: 6px 10px;
  border-radius: 6px;
  font-weight: 500;
  font-size: 13px;
  min-height: 34px;
  white-space: nowrap;
  flex: 1 1 auto;
}
.seg button.on { background: var(--pill); color: var(--pill-text); font-weight: 600; box-shadow: var(--pill-shadow); }

.modes .seg { flex: 1 1 auto; }
.modes .seg button { flex: 1 1 0; padding: 10px 6px; }

input[type=range] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 34px;
  background: transparent;
}
input[type=range]::-webkit-slider-runnable-track { height: 4px; background: var(--raised-2); border-radius: 2px; }
input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 26px; height: 26px;
  margin-top: -11px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
}
input[type=range]::-moz-range-track { height: 4px; background: var(--raised-2); border-radius: 2px; }
input[type=range]::-moz-range-thumb { width: 26px; height: 26px; border-radius: 50%; background: #fff; border: 0; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4); }

/* Bouton principal : pilule pleine, monochrome. Blanche la nuit, anthracite
   le jour, comme les boutons de premier plan de l'écran Tesla. */
.primary {
  background: var(--primary);
  color: var(--primary-text);
  border: 0;
  border-radius: var(--r);
  padding: 12px 18px;
  font-weight: 600;
  font-size: 15px;
}
.primary:active { filter: brightness(0.85); }
.primary:disabled { opacity: 0.35; }

.primary.big {
  padding: 14px;
  font-size: 16px;
  flex: 0 0 auto;
}
/* En route, le même bouton devient Arrêter : gris neutre, jamais rouge,
   pour ne pas ressembler à une alerte permanente. */
body.running .primary.big {
  background: var(--raised);
  color: var(--text);
}

/* Rétrogradage du mode manuel : TOUTE la zone gauche est la cible, cadran
   compris. Au volant on tape large, on ne vise pas un bouton. Tuile grise
   arrondie visible au repos, comme les pédales : la zone se lit d'un coup
   d'oeil comme une commande. Le fond est translucide, le cadran reste
   lisible au travers. La montée, elle, vit sur la molette du volant. */
.retro-big {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 0 0 6px;
  background: var(--raised);
  border: 0;
  border-radius: var(--r-lg);
  color: var(--muted);
  font-weight: 600;
  font-size: 14px;
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
}
.retro-big:active { background: var(--raised-2); color: var(--text); }

/* ---------- Pédales du mode démo ---------- */

.pedals {
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: 10px;
  padding: 0 16px 10px;
  flex: 0 0 auto;
}
.pedal {
  border: 0;
  border-radius: var(--r-lg);
  background: var(--raised);
  color: var(--text);
  padding: 12px;
  font-weight: 500;
  font-size: 15px;
  touch-action: none;
  user-select: none;
  transition: background 0.06s;
}
.pedal.gas.down { background: var(--raised-2); }
/* Le frein s'allume en rouge : réflexe feux stop, lisible sans lire. */
.pedal.brake.down { background: rgba(232, 33, 39, 0.3); }

/* ---------- Panneaux ---------- */

.panel {
  position: fixed;
  inset: 0;
  background: var(--overlay);
  backdrop-filter: blur(16px);
  z-index: 20;
  display: grid;
  place-items: center;
  padding: 20px;
  /* LE CLAVIER DE LA VOITURE MASQUE LE BAS DE L'ECRAN, et le champ de code
     vit justement en bas du panneau : il etait litteralement invisible
     pendant qu'on le remplissait. `--clavier` est pose par paywall.js depuis
     visualViewport ; a zero, rien ne change. La grille recentre alors le
     panneau dans ce qui reste visible. */
  padding-bottom: calc(20px + var(--clavier, 0px));
}
.panel-inner {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  width: min(880px, 100%);
  max-height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 20px;
  border-bottom: 1px solid var(--line);
  flex: 0 0 auto;
}
.panel-head h2 {
  margin: 0;
  font-size: 17px;
  font-weight: 600;
}
.panel-body { padding: 20px; overflow-y: auto; }
.panel-body h3 {
  font-size: 15px;
  margin: 24px 0 10px;
  font-weight: 600;
}
/* ---------- Panneau de réglages ---------- */

.panel-head-actions { display: flex; gap: 8px; align-items: center; }
.panel-head-actions > button:not(.icon) {
  background: var(--raised);
  border: 0;
  border-radius: var(--r);
  padding: 10px 14px;
  color: var(--muted);
  font-size: 13px;
  font-weight: 500;
}
.panel-head-actions > button:not(.icon):active { background: var(--raised-2); color: var(--text); }

.tn-group { margin-bottom: 26px; }
.tn-group h3 { font-size: 15px; margin: 0 0 4px; font-weight: 600; color: var(--text); }
.tn-group > p { margin: 0 0 12px; }

.tn-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 190px 82px;
  gap: 14px;
  align-items: center;
  padding: 9px 0;
  border-bottom: 1px solid var(--line);
}
.tn-row:last-child { border-bottom: 0; }
.tn-label { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.tn-label span { font-size: 14px; }
.tn-label small { font-size: 11px; color: var(--muted); line-height: 1.35; }
.tn-val { font-variant-numeric: tabular-nums; font-size: 13px; font-weight: 500; color: var(--muted); text-align: right; }
.tn-range { width: 100%; height: 30px; }

.tn-toggle {
  grid-column: 2 / 4;
  justify-self: end;
  background: var(--raised);
  border: 0;
  border-radius: var(--r);
  padding: 10px 22px;
  color: var(--muted);
  font-weight: 500;
  min-width: 84px;
}
.tn-toggle.on { background: var(--pill); color: var(--pill-text); font-weight: 600; box-shadow: var(--pill-shadow); }

/* Bloc d'essai d'écoute : une consigne, un bouton, une ligne d'état. Détaché
   des curseurs par un fond, parce qu'on ne le règle pas, on le déclenche. */
.tn-essai {
  margin-top: 14px;
  padding: 14px;
  background: var(--raised);
  border-radius: var(--r);
}
.tn-essai > p { margin: 0; font-size: 11px; color: var(--muted); line-height: 1.45; }
.tn-essai-go {
  margin: 12px 0 0;
  background: var(--pill);
  color: var(--pill-text);
  border: 0;
  border-radius: var(--r);
  padding: 11px 22px;
  font-weight: 600;
  box-shadow: var(--pill-shadow);
}
.tn-essai-go:disabled { opacity: 0.55; }
/* L'état ne réserve sa place que lorsqu'il parle : vide, il ne creuse pas
   un blanc sous le bouton. */
.tn-essai-etat:empty { display: none; }
.tn-essai-etat { margin-top: 10px !important; font-weight: 600; color: var(--text) !important; }

/* Apparence : Auto suit le jour/nuit de la voiture, Clair et Sombre
   forcent. Rangé ici, avec les réglages, comme sur l'écran Tesla. */
.tn-apparence {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 20px;
  border-top: 1px solid var(--line);
  flex: 0 0 auto;
}
.tn-apparence label {
  font-size: 13px;
  font-weight: 500;
  color: var(--muted);
}
.tn-apparence .seg { flex: 0 1 320px; }
/* Le sélecteur de langue tient la même colonne que la commande segmentée
   d'à côté : `select` est en largeur 100 %, ce qui ferait déborder la ligne
   d'un conteneur en espacement réparti. */
.tn-langue { flex: 0 1 320px; width: auto; }

.tn-foot { padding: 12px 20px; border-top: 1px solid var(--line); margin: 0; flex: 0 0 auto; }

/* Attribution du pack courant. Obligatoire pour les licences CC BY / CC BY-SA. */
.credit { margin: 2px 0 0; font-size: 11px; line-height: 1.35; color: var(--faint); }
.credit a { color: var(--faint); text-decoration: underline; text-underline-offset: 2px; }
.credit a:hover { color: var(--muted); }

/* ---------- Adaptations ---------- */

/* Tout est calé sur la fenêtre du navigateur Tesla (773x601). Si le
   navigateur passe en plein écran, on respire un peu plus, c'est tout. */
@media (min-height: 700px) and (min-width: 1100px) {
  .stage { gap: 32px; padding: 18px 28px 24px; }
  .side { gap: 16px; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}

/* ---------- Rupteur Premium ----------
   Le panneau d'achat suit le langage des autres panneaux : surface, hairlines,
   monochrome. Seul écart : le fond du QR reste blanc dans les deux thèmes,
   parce que c'est l'appareil photo du téléphone qui le lit, pas l'oeil. */

.premium-cta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  background: var(--raised);
  border: 1px solid var(--line);
  border-radius: var(--r);
  color: var(--text);
  padding: 12px 14px;
  font-weight: 600;
  font-size: 14px;
}
.premium-cta:active { background: var(--raised-2); }
.premium-prix { color: var(--muted); font-weight: 400; font-size: 13px; }

.panel-inner.pw { width: min(720px, 100%); }
/* ---------- Aide de la boîte manuelle ---------- */

/* Le dessin à gauche, le texte à droite, lisibles ensemble sans faire défiler
   dans une voiture. La fenêtre du navigateur Tesla fait 773 px de large : le
   panneau tient dedans avec ses marges. */
.panel-inner.aide { width: min(700px, 100%); }
.aide .panel-body {
  display: grid;
  grid-template-columns: 300px 1fr;
  gap: 18px 26px;
  align-items: center;
}
.aide-fig { margin: 0; display: grid; justify-items: center; gap: 8px; }
.aide-image {
  position: relative;
  width: 100%;
  border-radius: var(--r-lg);
  overflow: hidden;
  /* Le même gris que le fond de l'image : les coins arrondis ne laissent
     apparaître aucun liseré, dans les deux thèmes. */
  background: #1a1a1a;
}
.aide-image img { display: block; width: 100%; height: auto; }
.aide-fig figcaption { font-size: 12px; color: var(--muted); text-align: center; }
.aide-liste {
  margin: 0;
  padding: 0 0 0 20px;
  display: grid;
  gap: 12px;
  font-size: 14px;
  line-height: 1.45;
  color: var(--muted);
}
.aide-liste li::marker { color: var(--faint); }
.aide-liste b { color: var(--text); font-weight: 600; }
/* Le bouton tient la largeur des deux colonnes : c'est la seule action. */
.aide #aide-ok { grid-column: 1 / -1; }

/* L'ONDE SUR LA MOLETTE ET LE RAPPORT QUI PASSE, au même rythme, trois secondes.
   La position de l'onde est celle de la molette dans l'image (46 % en x, 52 %
   en y) : l'image ne bouge pas, ce sont les seules pièces animées. Sur l'image
   sombre, tout est blanc quel que soit le thème. */
.aide-onde {
  position: absolute;
  left: 46%; top: 52%;
  width: 34px; height: 34px;
  margin: -17px 0 0 -17px;
  border: 2px solid #fff;
  border-radius: 50%;
  opacity: 0;
  animation: aide-onde 3s ease-out infinite;
}
.aide-rapport {
  position: absolute;
  right: 12px; bottom: 10px;
  display: grid; justify-items: end; line-height: 1;
  color: #fff;
}
.aide-rapport-titre { font-size: 10px; letter-spacing: 1.5px; text-transform: uppercase; opacity: 0.55; margin-bottom: 4px; }
.aide-rapport-avant, .aide-rapport-apres { font-size: 30px; font-weight: 600; grid-area: 2 / 1; }
.aide-rapport-avant { animation: aide-avant 3s steps(1, end) infinite; }
.aide-rapport-apres { animation: aide-apres 3s steps(1, end) infinite; }

@keyframes aide-onde {
  0%, 30%   { opacity: 0;   transform: scale(0.55); }
  36%       { opacity: 0.9; transform: scale(0.7); }
  70%, 100% { opacity: 0;   transform: scale(1.6); }
}
@keyframes aide-avant { 0%, 37% { opacity: 1; } 38%, 100% { opacity: 0; } }
@keyframes aide-apres { 0%, 37% { opacity: 0; } 38%, 100% { opacity: 1; } }

/* Sans animation : l'onde reste posée sur la molette, le rapport est passé. */
@media (prefers-reduced-motion: reduce) {
  .aide-onde, .aide-rapport-avant, .aide-rapport-apres { animation: none; }
  .aide-onde { opacity: 0.8; transform: scale(0.7); }
  .aide-rapport-avant { opacity: 0; }
  .aide-rapport-apres { opacity: 1; }
}

@media (max-width: 640px) {
  .panel-inner.aide { width: 100%; }
  .aide .panel-body { grid-template-columns: 1fr; }
}

.pw-raison { margin: 0 0 14px; font-size: 15px; color: var(--muted); }
.pw-attente { display: grid; gap: 10px; max-width: 520px; }
.pw-attente p { margin: 0; }
.pw-attente-titre { font-size: 22px; font-weight: 600; }
.pw-attente-code { font-size: 15px; letter-spacing: 1px; color: var(--text); }
.pw-attente-texte { font-size: 14px; color: var(--muted); }
.pw-attente-aide { font-size: 13px; color: var(--faint); }
.pw-cols {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 24px;
  align-items: start;
}
.pw-prix { margin: 0; display: flex; align-items: baseline; gap: 10px; }
.pw-prix strong { font-size: 34px; font-weight: 600; letter-spacing: 0.5px; }
.pw-prix s { color: var(--faint); font-size: 18px; }
.pw-vie { margin: 2px 0 14px; color: var(--muted); font-size: 13px; }
.pw-liste { margin: 0; padding: 0 0 0 18px; display: grid; gap: 8px; font-size: 14px; }
.pw-liste li::marker { color: var(--faint); }
/* Écouter avant d'acheter : une pastille par moteur payant, sous la liste. */
.pw-ecoute { margin-top: 14px; }
.pw-ecoute-titre { margin: 0 0 8px; font-size: 13px; color: var(--muted); }
.pw-ecoute-liste { display: flex; flex-wrap: wrap; gap: 8px; }
.pw-extrait {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: var(--raised);
  border: 1px solid var(--line);
  border-radius: var(--r);
  color: var(--text);
  padding: 8px 12px;
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
}
.pw-extrait:active, .pw-extrait.joue { background: var(--raised-2); }
/* Lecture : un triangle ; en cours : un carré. Dessinés, pas de glyphe. */
.pw-extrait-icone {
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 5px 0 5px 8px;
  border-color: transparent transparent transparent currentColor;
}
.pw-extrait.joue .pw-extrait-icone { width: 9px; height: 9px; border: 0; background: currentColor; }
.pw-achat { display: grid; justify-items: center; gap: 8px; align-content: start; }
/* Le bouton d'achat occupe la place du QR tant qu'on n'a pas cliqué : même
   colonne, même largeur, pour que le panneau ne saute pas quand le QR le
   remplace. 210 px, c'est la taille du QR dessiné. */
.pw-acheter { width: 210px; }
.pw-quand {
  margin: 0;
  text-align: center;
  font-size: 12px;
  color: var(--muted);
  max-width: 210px;
}
.pw-qrbloc { display: grid; justify-items: center; gap: 8px; }
.pw-achat canvas {
  border-radius: var(--r);
  /* Zone de silence supplémentaire : le blanc vient du dessin lui-même. */
  box-shadow: 0 0 0 1px var(--line);
}
.pw-scan { margin: 0; text-align: center; font-size: 12px; color: var(--muted); }
.pw-codeph {
  margin: 0;
  font-size: 12px;
  color: var(--faint);
  letter-spacing: 1px;
  min-height: 16px;
}
.pw-deja {
  display: flex;
  gap: 10px;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
}
/* Le prefixe RUPT- vit DANS le cadre, a gauche du champ : le client voit le
   code entier se former, sans avoir a le taper. */
.pw-champ {
  flex: 1;
  display: flex;
  align-items: center;
  background: var(--raised);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 0 12px;
}
.pw-champ:focus-within { border-color: var(--text); }
.pw-prefixe {
  font: 500 14px var(--font);
  letter-spacing: 1px;
  color: var(--muted);
  padding-right: 1px;
  user-select: none;
}
.pw-deja input {
  flex: 1;
  min-width: 0;
  background: none;
  border: 0;
  color: var(--text);
  padding: 10px 0;
  font: 500 14px var(--font);
  letter-spacing: 1px;
  text-transform: uppercase;
}
.pw-deja input:focus { outline: none; }
.pw-deja input::placeholder { color: var(--faint); letter-spacing: 1px; }
.pw-deja button {
  background: var(--raised);
  border: 1px solid var(--line);
  border-radius: var(--r);
  color: var(--text);
  padding: 10px 14px;
  font-weight: 600;
  font-size: 13px;
  white-space: nowrap;
}
.pw-deja button:active { background: var(--raised-2); }
/* .hint portait ces trois proprietes ; elle vivait dans le CSS du gestionnaire
   de packs, parti avec l'import. Le min-height compte : sans lui le panneau
   sautait de 20 px a chaque apparition du message. */
.pw-statut { margin: 10px 0 0; font-size: 13px; color: var(--warn); min-height: 20px; }
.pw-statut.ok { color: var(--ok); }
.pw-statut.bad { color: var(--red-text); }

/* La fenêtre Tesla fait 773x601 : les deux colonnes tiennent, mais si un
   jour le panneau s'ouvre sur plus étroit, le QR passe dessous. */
@media (max-width: 640px) {
  .pw-cols { grid-template-columns: 1fr; }
  .pw-achat { justify-items: start; }
  .pw-qrbloc { justify-items: start; }
  .pw-quand { text-align: left; }
}

/* Le E du logotype : trois barres horizontales, sans fût, à la manière du
   lettrage du tableau de bord. Dessiné en SVG pour suivre currentColor
   dans les deux thèmes ; la marge droite rejoue le letter-spacing que
   l'élément remplacé ne reçoit pas. */
.logo-e {
  height: 0.68em;
  width: auto;
  fill: currentColor;
  margin-right: 0.42em;
}
