  @import url('https://fonts.googleapis.com/css2?family=Cinzel:wght@500;700&family=Space+Mono:wght@400;700&display=swap');

  /* ---- Scroll partout, ascenseur jamais visible (demande utilisateur -
       "je voudrais qu'il y ait le scroll necessaire partout mais pas
       l'ascenseur visible", desktop/mobile/tablette) : masque la barre de
       defilement sur TOUT element scrollable de la page, sans jamais
       desactiver le scroll lui-meme (les overflow:auto/scroll deja en
       place ailleurs continuent de fonctionner normalement au clavier,
       souris, trackpad ou tactile - seul l'ascenseur visuel disparait). ---- */
  *{ scrollbar-width:none; -ms-overflow-style:none; }
  *::-webkit-scrollbar{ width:0; height:0; display:none; }

  :root{
    --iron: #211d19;
    --iron-2: #2c2620;
    --iron-3: #171410;
    --brass: #c99a3c;
    --brass-dark: #7d5e22;
    --brass-light: #e9c878;
    --copper: #a9613a;
    --fire: #ff7a29;
    --fire-deep: #d1330f;
    --glass: #ece6d6;
    --danger: #c0392b;
    --steam: #c7d3d6;
    --water: #3f8fa3;
    --ok: #5f9c5a;
    --gold: #d4af37;
    --silver: #b9bec4;
    --bronze: #b0703a;
  }

  *{ box-sizing:border-box; -webkit-tap-highlight-color:transparent; }
  html,body{
    margin:0; padding:0; width:100%; height:100%;
    background: var(--iron-3);
    font-family:'Cinzel', serif;
    overflow:hidden;
    touch-action: none;
    user-select:none;
  }

  #stage{
    width:100%; height:100dvh;
    display:flex; flex-direction:column; align-items:center;
    background:
      radial-gradient(ellipse at 50% -10%, #3a3025 0%, transparent 60%),
      repeating-linear-gradient(0deg, var(--iron) 0px, var(--iron) 3px, var(--iron-2) 3px, var(--iron-2) 6px);
  }
  #cab{
    width:100%; max-width:480px; height:100%;
    display:flex; flex-direction:column;
    position:relative;
  }
  @media (min-width: 720px){
    #cab{ max-width: 680px; }
  }
  @media (min-width: 1000px){
    #cab{ max-width: 820px; }
  }
  @media (min-width: 1400px){
    #cab{ max-width: 920px; }
  }
  #cab::after{
    content:"";
    position:absolute; inset:0; z-index:16; pointer-events:none;
    background: radial-gradient(ellipse at 50% 45%, transparent 55%, rgba(0,0,0,0.45) 100%);
  }
  #grainOverlay{
    position:absolute; inset:0; z-index:26; pointer-events:none;
    opacity:0.05; mix-blend-mode:overlay;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  }

  @keyframes camShake{
    0%{ transform: translate(0,0); }
    20%{ transform: translate(-4px,3px); }
    40%{ transform: translate(3px,-4px); }
    60%{ transform: translate(-3px,-2px); }
    80%{ transform: translate(4px,2px); }
    100%{ transform: translate(0,0); }
  }
  #cab.shake{ animation: camShake 0.4s ease; }

  .rivet-corners{ position:relative; }
  .rivet-corners::before{
    content:"";
    position:absolute; inset:3px;
    pointer-events:none; z-index:1;
    background:
      radial-gradient(circle 2.6px at 7px 7px, #6b5a38 92%, transparent 100%),
      radial-gradient(circle 2.6px at calc(100% - 7px) 7px, #6b5a38 92%, transparent 100%),
      radial-gradient(circle 2.6px at 7px calc(100% - 7px), #6b5a38 92%, transparent 100%),
      radial-gradient(circle 2.6px at calc(100% - 7px) calc(100% - 7px), #6b5a38 92%, transparent 100%);
  }

  #topbar{
    display:flex; justify-content:space-between; align-items:center;
    flex-wrap: wrap;
    row-gap: 3px;
    padding: 5px 10px;
    gap: 5px;
    background: rgba(44,38,32,0.65);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    border-bottom: 2px solid var(--brass-dark);
    position:relative; z-index:6;
  }
  /* ---- Indication scroll horizontal (demande utilisateur - "il faudrait
       indiquer au joueur qu'il doit scroller la ligne du haut
       horizontalement") : #topbar peut deborder et defiler horizontalement
       sur mobile/paysage etroit (cf. les media queries plus bas qui
       passent #topbar en overflow-x:auto) sans que rien ne le signale.
       Fondu + chevron colles au bord droit : position:absolute ancree
       directement sur #topbar (son conteneur de positionnement), donc fixe
       a l'ecran quel que soit le defilement horizontal (n'est PAS entraine
       par le scroll, contrairement a un enfant normal). Masque par defaut
       (desktop, ou #topbar tient sur une seule ligne sans avoir besoin de
       defiler) - reaffiche UNIQUEMENT dans les media queries mobile/
       paysage etroit ci-dessous, jamais visible quand #topbar ne defile
       pas. ---- */
  #topbar::after{
    content:"›"; display:none; align-items:center; justify-content:flex-end;
    position:absolute; top:0; right:0; bottom:0; width:22px; padding-right:2px;
    background: linear-gradient(90deg, transparent, rgba(23,20,16,0.88) 55%);
    color: var(--brass-light); font-size:15px; font-weight:bold;
    pointer-events:none; animation: topbarScrollHint 1.6s ease-in-out infinite;
  }
  @keyframes topbarScrollHint{
    0%,100%{ opacity:0.5; transform:translateX(0); }
    50%{ opacity:1; transform:translateX(3px); }
  }

  .plate{
    font-family:'Space Mono', monospace;
    font-size: 9.5px;
    color: var(--brass-light);
    letter-spacing: 0.5px;
    background: #171410;
    border: 1px solid var(--brass-dark);
    border-radius: 3px;
    padding: 2px 5px;
    white-space: nowrap;
    box-shadow: inset 0 1px 3px rgba(0,0,0,0.65), 0 1px 0 rgba(255,255,255,0.05);
  }
  .plate b{ color: var(--glass); font-size:11.5px; }
  /* ---- Boutons zoom in/out de la vue 3D (demande utilisateur), accoles a
       la plaque VUE : memes couleurs que .plate mais en carre compact,
       assez grand pour rester cliquable/touchable au doigt malgre la
       taille reduite du bandeau. ---- */
  .zoom-btn{
    font-family:'Space Mono', monospace;
    font-size: 13px;
    line-height: 1;
    color: var(--glass);
    background: #23201a;
    border: 1px solid var(--brass-dark);
    border-radius: 3px;
    width: 20px;
    height: 20px;
    padding: 0;
    cursor: pointer;
  }
  .zoom-btn:active{ background: #171410; }
  /* ---- Deplacement lateral camera (demande utilisateur - "met les
       fleches droite et gauche en haut a cote de +/-") : #lookLeftBtn/
       #lookRightBtn reutilisent .zoom-btn (meme plaque VUE) mais sont un
       appui MAINTENU (translation continue tant que presse) plutot qu'un
       simple clic - touch-action:none evite que le navigateur interprete
       l'appui maintenu comme un scroll, ce qui couperait sinon
       prematurement le pointerdown avant le pointerup/pointercancel
       attendu (cf. wiring dans machine231.html). ---- */
  #lookLeftBtn, #lookRightBtn{ touch-action:none; }

  .plate .delay-badge{
    font-weight:700; margin-left:4px; font-size:10.5px;
  }
  .delay-badge.ontime{ color: var(--ok); }
  .delay-badge.warn{ color: var(--brass-light); }
  .delay-badge.late{ color: var(--danger); }

  #alarmBanner{
    position:relative; z-index:1;
    /* ---- Corrige : "bandeau trop large, masque des informations" - c'etait
       un overlay position:absolute pleine largeur (left:0;right:0) fige a
       top:58px, qui recouvrait donc le topbar (PK/GARE/HORAIRE/SCORE) des
       que celui-ci passait sur 2 lignes (petits ecrans), ou la scene sinon.
       Passe en flux normal (enfant flex de #cab) : il pousse simplement le
       reste de la cabine vers le bas quand il apparait, sans jamais rien
       recouvrir, et il est nettement retreci (plus "toute la largeur") pour
       rester lisible sans dominer l'ecran. ---- */
    align-self:center;
    width:min(92%, 520px);
    margin:0 auto;
    text-align:center;
    font-family:'Space Mono', monospace;
    letter-spacing: 1px;
    color: var(--glass);
    background: rgba(192,57,43,0);
    border-radius: 0 0 8px 8px;
    padding: 0;
    max-height:0;
    overflow:hidden;
    transition: max-height 0.3s cubic-bezier(.2,.9,.3,1), padding 0.3s cubic-bezier(.2,.9,.3,1), background 0.25s ease, box-shadow 0.25s ease;
    z-index: 8;
    flex-shrink:0;
  }
  /* ---- Bug/demande utilisateur - "les messages d'alerte doivent
     s'afficher sans se masquer, utiliser deux lignes pour eviter les
     retards d'affichage" : plusieurs showAlarm() rapproches mettaient
     les messages suivants en file d'attente (deja corrige par le passe
     pour eviter qu'un message tout juste apparu soit ecrase avant
     d'avoir pu etre lu) - mais cette file restait invisible : le joueur
     ne voyait qu'un message a la fois et ignorait qu'un autre attendait
     deja, avec un delai avant de le voir apparaitre. Le bandeau affiche
     desormais deux lignes : la ligne 1 est le message actif (pleine
     taille), la ligne 2 (plus petite, attenuee) previsualise le
     prochain message en file des qu'il existe - rien n'est plus
     silencieusement retarde/masque. ---- */
  #alarmLine1{
    font-size: 12px;
  }
  #alarmLine2{
    font-size: 10px;
    opacity: 0.75;
    margin-top: 2px;
    display: none;
  }
  #alarmLine2.show{ display:block; }
  #alarmBanner.show{
    background: linear-gradient(180deg, rgba(216,72,58,0.95), rgba(150,40,30,0.95));
    border: 1px solid rgba(255,180,160,0.35);
    padding: 7px 12px;
    max-height: 60px;
    box-shadow: 0 3px 10px rgba(0,0,0,0.4), inset 0 1px 0 rgba(255,255,255,0.12);
  }
  #alarmBanner.info{ background: linear-gradient(180deg, var(--brass-light), var(--brass-dark)); border-color: rgba(255,230,180,0.4); color:#231c10; }

  /* ---- Demande utilisateur - "les messages en rouge doivent etre
     affiches sous les manometres" : meme apparence/mecanique que
     #alarmBanner (flux normal, agrandissement anime a l'apparition, 2
     lignes message actif + apercu du suivant), mais toujours en rouge (ce
     bandeau ne recoit jamais de messages danger=false) et place plus bas
     dans la cabine (juste apres #instruments dans le HTML) plutot qu'en
     haut. ---- */
  #alarmBannerRed{
    position:relative; z-index:1;
    align-self:center;
    width:min(92%, 520px);
    margin:0 auto;
    text-align:center;
    font-family:'Space Mono', monospace;
    letter-spacing: 1px;
    color: var(--glass);
    background: rgba(192,57,43,0);
    border-radius: 8px;
    padding: 0;
    max-height:0;
    overflow:hidden;
    transition: max-height 0.3s cubic-bezier(.2,.9,.3,1), padding 0.3s cubic-bezier(.2,.9,.3,1), background 0.25s ease, box-shadow 0.25s ease;
    z-index: 8;
    flex-shrink:0;
  }
  #alarmLine1Red{ font-size: 12px; }
  #alarmLine2Red{
    font-size: 10px;
    opacity: 0.75;
    margin-top: 2px;
    display: none;
  }
  #alarmLine2Red.show{ display:block; }
  #alarmBannerRed.show{
    background: linear-gradient(180deg, rgba(216,72,58,0.95), rgba(150,40,30,0.95));
    border: 1px solid rgba(255,180,160,0.35);
    padding: 7px 12px;
    max-height: 60px;
    box-shadow: 0 3px 10px rgba(0,0,0,0.4), inset 0 1px 0 rgba(255,255,255,0.12);
  }

  /* ---- Alerte visible dediee au risque de deraillement (demande
     utilisateur), distincte du bandeau d'alarme general #alarmBanner : ce
     dernier ne peut pas afficher un compte a rebours qui change chaque
     frame (son systeme de file/deduplication est fait pour du texte
     statique repete, pas pour du texte qui change en continu - un
     compte a rebours y provoquerait un engorgement de la file). Ce nouveau
     bandeau, mis a jour directement (voir updateDerailWarning()), reste
     toujours au-dessus du reste et pulse pour rester tres visible tant que
     le risque de deraillement est actif. ---- */
  #derailWarning{
    position:relative; z-index:1;
    align-self:center;
    width:min(92%, 520px);
    margin:2px auto 0;
    text-align:center;
    font-family:'Space Mono', monospace;
    font-size: 13px;
    font-weight:700;
    letter-spacing: 0.5px;
    color:#fff;
    background: rgba(192,57,43,0.95);
    border: 2px solid #ffdd55;
    border-radius: 8px;
    padding: 0;
    max-height:0;
    overflow:hidden;
    transition: max-height 0.15s ease, padding 0.15s ease;
    z-index: 9;
    flex-shrink:0;
  }
  #derailWarning.show{
    padding: 7px 12px;
    max-height: 60px;
    animation: derailPulse 0.6s ease-in-out infinite;
  }
  @keyframes derailPulse{
    0%,100%{ box-shadow: 0 0 6px 2px rgba(255,60,40,0.9), inset 0 1px 0 rgba(255,255,255,0.15); }
    50%{ box-shadow: 0 0 18px 7px rgba(255,220,80,0.95), inset 0 1px 0 rgba(255,255,255,0.25); }
  }

  #window{
    /* ---- Demande utilisateur : "la 3D en plein ecran et pleine page" -
         cette boite ne contient plus qu'un cadre reduit a rien : le canvas
         qu'elle contient couvre desormais TOUT le viewport (position
         fixed), independamment de la largeur bridee du reste de la
         cabine (#cab garde son max-width pour les jauges/panneaux, mais
         la 3D derriere, elle, remplit tout l'ecran). z-index le plus bas
         de la colonne #cab pour rester DERRIERE topbar/instruments/
         panels (qui gardent leurs propres z-index plus eleves). ---- */
    position:fixed; inset:0; z-index:0;
    margin:0; border:none; border-radius:0; box-shadow:none;
    overflow:hidden;
    background: #33454d;
  }
  #sceneCanvas{ display:block; width:100%; height:100%; }
  /* ---- Bug/demande utilisateur - indicateurs gare/pente/meteo deplaces
     de la fenetre 3D (overlay absolu, peu fiable sur petit ecran) vers
     cette rangee en flux normal, juste au-dessus des jauges. ---- */
  #statusRow{
    position:relative; z-index:1;
    display:flex; flex-wrap:wrap; justify-content:center; align-items:center;
    gap:6px;
    padding: 6px 10px 0 10px;
  }
  #gradientTag, #weatherTag, #nextStopTag{
    font-family:'Space Mono', monospace;
    font-size:11px;
    background: rgba(23,20,16,0.55);
    padding:3px 7px;
    border-radius:3px;
    letter-spacing:1px;
  }
  #gradientTag{ color: var(--glass); }
  #weatherTag{ color: var(--glass); }
  #weatherTag.hidden{ display:none; }
  /* ---- Demande utilisateur - "TUNNEL doit etre clairement affiche" :
       le badge PLUIE/ORAGE/TUNNEL partageait jusqu'ici le meme style
       discret (11px, fond gris translucide) que les autres petites
       etiquettes de la rangee de statut - facile a manquer alors que
       c'est l'information la plus importante en tunnel (plus rien
       d'autre n'est visible autour de la loco, cf. three-cab-view.js).
       Style dedie, nettement plus voyant, applique uniquement quand le
       badge affiche "TUNNEL" (classe .tag-tunnel, posee/retiree en JS). ---- */
  #weatherTag.tag-tunnel{
    font-size:16px; font-weight:700; letter-spacing:4px;
    color:#1a1613; background: var(--brass);
    padding:6px 16px; border-radius:4px;
    box-shadow: 0 0 12px 3px rgba(212,175,55,0.55);
    animation: tunnelTagPulse 1.4s ease-in-out infinite;
  }
  @keyframes tunnelTagPulse{
    0%,100%{ box-shadow: 0 0 12px 3px rgba(212,175,55,0.55); }
    50%{ box-shadow: 0 0 20px 6px rgba(212,175,55,0.85); }
  }
  #nextStopTag{
    color: var(--brass-light);
    letter-spacing:0.5px;
    max-width: 100%;
    white-space: nowrap;
    overflow:hidden;
    text-overflow: ellipsis;
  }

  /* ---- Demande utilisateur - "il faut un feu dans la cabine conducteur
       avec le feu actuel (vert/orange/rouge), pas uniquement sur la voie" :
       repetiteur de signal en cabine. Reprend a chaque frame l'etat du
       signal en voie (currentSignal), avec une pastille lumineuse coloree
       et un libelle. Rendu volontairement voyant (comme un vrai repetiteur
       de cabine), place dans la rangee de statut au-dessus des manometres,
       donc pleinement responsive comme le reste de la cabine. ---- */
  #cabSignal{
    display:flex; align-items:center; gap:6px;
    font-family:'Space Mono', monospace;
    font-size:11px; font-weight:700; letter-spacing:1px;
    background: rgba(23,20,16,0.55);
    padding:3px 9px 3px 6px;
    border-radius:12px;
    border:1px solid rgba(0,0,0,0.35);
  }
  #cabSignal .cab-signal-lamp{
    width:14px; height:14px; border-radius:50%;
    background:#333; flex:0 0 auto;
    border:1px solid rgba(0,0,0,0.6);
    box-shadow: inset 0 0 3px rgba(0,0,0,0.8);
    transition: background .15s linear, box-shadow .15s linear;
  }
  #cabSignal.sig-green .cab-signal-lamp{
    background:#39d353; box-shadow: 0 0 8px 2px rgba(57,211,83,0.8), inset 0 0 3px rgba(255,255,255,0.5);
  }
  #cabSignal.sig-yellow .cab-signal-lamp{
    background:#e0a030; box-shadow: 0 0 8px 2px rgba(224,160,48,0.85), inset 0 0 3px rgba(255,255,255,0.5);
  }
  #cabSignal.sig-red .cab-signal-lamp{
    background:#e0392b; box-shadow: 0 0 9px 3px rgba(224,57,43,0.9), inset 0 0 3px rgba(255,255,255,0.4);
    animation: cabSignalRedPulse 0.9s ease-in-out infinite;
  }
  @keyframes cabSignalRedPulse{
    0%,100%{ box-shadow: 0 0 9px 3px rgba(224,57,43,0.9), inset 0 0 3px rgba(255,255,255,0.4); }
    50%{ box-shadow: 0 0 14px 5px rgba(224,57,43,1), inset 0 0 3px rgba(255,255,255,0.4); }
  }
  #cabSignal .cab-signal-label{ color: var(--glass); }
  #cabSignal.sig-green .cab-signal-label{ color:#8fe6a0; }
  #cabSignal.sig-yellow .cab-signal-label{ color:#f0c674; }
  #cabSignal.sig-red .cab-signal-label{ color:#f0938a; }

  #instruments{
    display:flex; justify-content:space-around; align-items:flex-end;
    padding: 4px 10px 6px 10px;
    gap: 4px;
    position:relative; z-index:1;
  }
  .gauge-wrap{ display:flex; flex-direction:column; align-items:center; gap:3px; }
  .gauge-label{
    font-size:9.5px; letter-spacing:1.5px; color: var(--brass-light);
    text-transform:uppercase;
    transition: color 0.2s ease;
  }
  .gauge-label.combo-active{ color: var(--fire); }
  /* ---- Demande utilisateur - badge de limitation de vitesse persistant sur
     le tableau de bord (pas une simple alerte qui defile). Couleur ambre par
     defaut (limitation en vigueur, respectee) ; passe au rouge/pulse des que
     la vitesse AFFICHEE depasse reellement cette limite - meme code couleur
     que needleSpeed en survitesse, pour rester coherent avec le reste du
     tableau de bord. ---- */
  .speed-limit-badge{
    font-size:10px; letter-spacing:0.8px; font-weight:bold;
    color:#1a1206; background: linear-gradient(#e0a030,#a86c18);
    border:1px solid #6b4a10; border-radius:4px;
    padding:2px 7px; white-space:nowrap;
    box-shadow: 0 1px 3px rgba(0,0,0,0.5);
  }
  .speed-limit-badge.over{
    background: linear-gradient(#ff2200,#a10c00); color:#fff;
    animation: speedLimitPulse 0.9s ease-in-out infinite;
  }
  .speed-limit-badge.hidden{ display:none; }
  @keyframes speedLimitPulse{ 0%,100%{ opacity:1; } 50%{ opacity:0.55; } }
  .dial{
    position:relative;
    width: 68px; height:68px;
    border-radius:50%;
    background: radial-gradient(circle at 35% 30%, #f5f1e6, var(--glass) 55%, #cfc7ae 100%);
    border: 4px solid var(--brass);
    box-shadow: 0 0 0 2px var(--brass-dark), 0 3px 6px rgba(0,0,0,0.5), inset 0 0 10px rgba(0,0,0,0.25);
  }
  .dial.dial-small{
    width: 40px; height:40px; border-width:3px;
  }
  .dial.dial-small .needle{ height:14px; width:2px; }
  .dial.dial-small .pivot{ width:5px; height:5px; margin:-2.5px 0 0 -2.5px; }
  .dial::before{
    content:"";
    position:absolute; inset:-5px; border-radius:50%;
    pointer-events:none;
    background:
      radial-gradient(circle 2px at 50% 3px, #5b430f 85%, transparent 100%),
      radial-gradient(circle 2px at 50% calc(100% - 3px), #5b430f 85%, transparent 100%),
      radial-gradient(circle 2px at 3px 50%, #5b430f 85%, transparent 100%),
      radial-gradient(circle 2px at calc(100% - 3px) 50%, #5b430f 85%, transparent 100%);
  }
  .dial .ticks{
    position:absolute; inset:0; border-radius:50%; pointer-events:none;
    background: repeating-conic-gradient(from 30deg, rgba(35,28,16,0.6) 0deg 1.3deg, transparent 1.3deg 15deg);
    -webkit-mask: radial-gradient(circle, transparent 60%, #000 61%, #000 71%, transparent 72%);
    mask: radial-gradient(circle, transparent 60%, #000 61%, #000 71%, transparent 72%);
  }
  .dial .arc-danger{
    position:absolute; inset:0; border-radius:50%;
    background: conic-gradient(from 210deg, transparent 0deg 205deg, rgba(192,57,43,0.55) 205deg 245deg, transparent 245deg 360deg);
  }
  .dial .needle{
    position:absolute; left:50%; top:50%;
    width:3px; height:26px;
    background: linear-gradient(90deg, #7a1d13, #e05748 45%, #7a1d13);
    transform-origin: 50% 100%;
    transform: translate(-50%,-100%) rotate(0deg);
    border-radius:2px;
    box-shadow: 0 1px 3px rgba(0,0,0,0.6);
    transition: transform 0.12s ease-out;
  }
  .dial .pivot{
    position:absolute; left:50%; top:50%;
    width:8px; height:8px; margin:-4px 0 0 -4px;
    background: radial-gradient(circle at 35% 30%, var(--brass-light), var(--brass) 60%, var(--brass-dark));
    border-radius:50%;
    box-shadow: 0 0 0 1px var(--brass-dark), 0 1px 2px rgba(0,0,0,0.5);
  }
  /* ---- Le reflet de verre des cadrans n'est PAS defini ici : une regle
       `.dial::after` existe deja plus bas dans cette feuille (cf. "Reflet de
       verre sur les cadrans"). A specificite egale, c'est la derniere qui
       l'emporte - une seconde regle ici serait purement morte. Toute
       modification du reflet doit se faire sur CETTE regle-la. ---- */
  .dial .readout{
    position:absolute; left:0; right:0; bottom:9px;
    text-align:center;
    font-family:'Space Mono', monospace;
    font-size:10px; font-weight:700;
    color:#231c10;
  }

  .tube{
    width: 22px; height:68px;
    border-radius: 6px;
    background: #0e1416;
    border: 3px solid var(--brass);
    box-shadow: 0 0 0 2px var(--brass-dark), inset 0 0 6px rgba(0,0,0,0.6);
    position:relative;
    overflow:hidden;
  }
  .tube::after{
    content:"";
    position:absolute; inset:0; pointer-events:none;
    background: linear-gradient(90deg, rgba(255,255,255,0.16) 0%, transparent 22%, transparent 78%, rgba(0,0,0,0.28) 100%);
  }
  .tube .fill{
    position:absolute; left:0; right:0; bottom:0;
    background: linear-gradient(180deg, #6fc2d6, var(--water));
    transition: height 0.15s linear;
  }
  .tube .marks{
    position:absolute; inset:0;
    background-image: repeating-linear-gradient(0deg, rgba(255,255,255,0.18) 0 1px, transparent 1px 14px);
  }

  #panels{
    /* ---- Corrige (mobile) - "c'est fouilli, il faut reorganiser
         reproportionner" : les .panel se centraient verticalement
         (top:50%) par rapport a TOUT #cab, topbar+instruments compris.
         Sur ecran de telephone (etroit et haut), le contenu d'un panel
         depasse facilement la moitie de la hauteur ecran : centre sur
         100% de #cab, son bord haut remontait donc au-dessus du bandeau
         d'instruments et venait se superposer aux cadrans (Pression/
         Vitesse) et a leurs libelles - illisible.
         Corrige : #panels redevient un vrai enfant flex de #cab (flex:1,
         occupe tout l'espace RESTANT sous topbar/instruments/alarmes,
         quelle que soit leur hauteur reelle - y compris quand ils
         passent sur 2 lignes) et redevient le repere de positionnement
         (position:relative) pour les .panel, a la place de #cab. Les
         .panel, toujours centres verticalement, le sont donc desormais
         uniquement dans cet espace libre - jamais au-dessus des
         instruments. ---- */
    position:relative;
    flex:1 1 auto;
    min-height:0;
    z-index:1;
    /* ---- Bug corrige (rapport utilisateur, capture a l'appui - "on ne
         peut rien cliquer" sur le menu "Appeler le regulateur") : #panels
         occupe TOUTE la largeur/hauteur disponible de #cab (flex:1 1 auto)
         pour que ses DEUX enfants .panel puissent se positionner en
         absolute a gauche/droite - mais ce conteneur lui-meme reste une
         boite bien reelle, vide et invisible au centre, qui capte quand
         meme les clics faute de pointer-events:none. Inoffensif tant
         qu'aucune modale ne passe dessous... sauf que #assistanceMenuBackdrop
         (et #trainInfoBackdrop, meme structure) sont nichees a l'interieur
         de #window, qui a volontairement un z-index tres bas (0, cf. plus
         haut) pour rester derriere topbar/instruments/panels. Une fois
         DANS #window, le z-index interne de la modale (40) ne compte plus
         que par rapport aux AUTRES elements de #window (le canvas) - pas
         face a #panels (z-index 1), qui reste tout de meme au-dessus de
         TOUT le bloc #window, modale comprise, dans le contexte
         d'empilement de #cab. Visuellement la modale s'affichait bien (son
         propre z-index:40 la place au-dessus du canvas a l'interieur de
         #window), mais #panels captait quand meme le clic par-dessus dans
         sa zone centrale vide. Corrige a la source, sans deplacer les
         modales : #panels ne capte plus aucun clic lui-meme, seuls ses
         enfants .panel (qui, eux, reactivent pointer-events juste apres)
         restent cliquables - la zone centrale vide laisse desormais
         passer les clics vers ce qu'il y a en dessous (modale ou scene). ---- */
    pointer-events:none;
  }
  #panels .panel{ pointer-events:auto; }
  .panel::-webkit-scrollbar{ width:5px; }
  .panel::-webkit-scrollbar-track{ background:transparent; }
  .panel::-webkit-scrollbar-thumb{ background: var(--brass-dark); border-radius:3px; }
  .panel{
    /* ---- Demande utilisateur : "je les veux pas dans des boites sur les
         cotes mais dans l'image 3D comme les manometres" - plus de fond,
         plus de bordure, plus de flou : chaque bouton/jauge garde son
         propre habillage individuel (comme un cadran de manometre) mais
         il n'y a plus de boite englobante autour du groupe. Une ombre
         portee sur le texte remplace le fond opaque pour la lisibilite. ----
       ---- Bug corrige - "ca doit etre dedans sinon ca ne sera pas
       responsive" : position:fixed positionnait les panneaux par rapport
       au NAVIGATEUR ENTIER, alors que la vraie "fenetre" du jeu est #cab,
       qui garde son propre max-width responsive (480 a 920px selon la
       largeur d'ecran) et reste toujours centre. Sur un ecran large,
       #cab est bien plus etroit que le viewport - les panneaux en
       position:fixed+vw debordaient donc du cadre visuel du jeu. Passe en
       position:absolute (avec #cab, deja position:relative, comme repere)
       pour que les panneaux restent TOUJOURS a l'interieur de la fenetre
       centrale du jeu, quelle que soit la largeur d'ecran - donc
       vraiment responsive. ---- */
    position:absolute;
    top:50%; transform:translateY(-50%);
    width: min(26vw, 190px);
    /* ---- Repere desormais #panels (l'espace libre sous les
         instruments), plus #cab entier - la hauteur max suit donc
         naturellement l'espace vraiment disponible, sans jamais pouvoir
         chevaucher le bandeau d'instruments au-dessus. Une petite marge
         (8px) est gardee de chaque cote pour ne pas coller pile aux
         bords de cet espace. ---- */
    max-height: calc(100% - 16px);
    padding: 7px 4px;
    display:flex; flex-direction:column; gap:8px;
    min-height:0;
    overflow-y:auto; overflow-x:visible;
    touch-action: pan-y;
  }
  #panels .panel:first-child{ left: 10px; }
  #panels .panel:last-child{ right: 10px; }

  /* ---- Optimisation mobile/tablette (demande utilisateur - "les boutons
       de commande cachent la vue (...) il faut reduire la taille des
       boutons") : les panneaux sont deja dimensionnes en vw (min(26vw,
       190px)), mais sur un petit ecran de telephone, 26% de la largeur de
       chaque cote (52% a eux deux) masque une part disproportionnee de la
       scene 3D par rapport a un ecran large. Sous ce seuil uniquement
       (aucun effet sur tablette large/desktop, ou l'espace ne manque pas
       autant) : panneaux resserres (vw et plafond en px reduits, marges
       laterales diminuees) et boutons/textes plus compacts - la scene
       recupere ainsi une part nettement plus grande de l'ecran. ---- */
  /* ---- Question utilisateur - "sur une tablette en mode horizontal, ca
       s'affichera correctement ?" : oui, la vue 3D remplit tout le viewport
       (position:fixed) et les commandes tiennent dans un cadre central de
       largeur max, avec panneaux lateraux defilables - donc responsive quelle
       que soit la largeur. Seul cas un peu juste : un ecran LARGE mais PEU
       HAUT (tablette/telephone en paysage), ou la hauteur devient la
       contrainte. Sous ce seul profil, on compacte legerement le bandeau
       d'etat et les cadrans pour degager de la place au centre (vue +
       panneaux), sans rien changer en portrait ni sur desktop. ----
     ---- Bug corrige (rapport utilisateur - "sur mobile, quand on tourne
       l'ecran, on ne voit plus tous les boutons") : cette regle ne
       compactait jusqu'ici QUE le bandeau d'etat et les cadrans - jamais
       les boutons du panel "Conducteur" (Frein, Sifflet, Voie de service,
       Appeler le regulateur, Pilotage automatique, Technicentre, Course),
       qui restaient a leur taille pleine (min-height 40px + 8px d'ecart
       chacun, ~336px pour 7 boutons) alors que la hauteur DISPONIBLE en
       paysage telephone tombe couramment sous 400px une fois le bandeau
       d'instruments deduit. Le panel etait bien scrollable
       (overflow-y:auto, cf. .panel) mais rien ne le signalait ni ne
       compensait - plusieurs boutons du bas restaient donc hors champ sans
       indice qu'il fallait faire defiler. Desormais les boutons/le panel
       sont eux aussi compactes dans ce meme profil (paysage, peu haut) :
       boutons plus bas et plus resserres, ce qui suffit a faire rentrer
       les 7 boutons sans defilement sur la plupart des telephones ; le
       defilement reste disponible en filet de securite sur les ecrans
       encore plus contraints (tres petits telephones, barre d'adresse du
       navigateur visible...). ---- */
  @media (min-width: 700px) and (max-height: 620px){
    /* ---- Correctif utilisateur - "en paysage le haut ça doit être un
         bandeau à faire défiler comme en mode portrait" : #topbar
         (PK/GARE/HORAIRE/FRANCS/CARTE/VUE) et #statusRow (feu cabine/
         prochaine gare/pente/meteo) beneficiaient deja de ce traitement
         (flex-wrap:nowrap + defilement horizontal) en PORTRAIT
         (@media max-width:600px, plus bas) - jamais en paysage, ou ces
         deux bandeaux pouvaient donc encore passer sur 2 lignes et manger
         une hauteur precieuse, exactement le bug deja corrige une fois
         pour le portrait. Meme traitement ici. ---- */
    #topbar{
      flex-wrap:nowrap; justify-content:flex-start;
      overflow-x:auto; -webkit-overflow-scrolling:touch;
      padding:3px 8px; gap:4px;
    }
    #topbar::-webkit-scrollbar{ display:none; }
    #topbar::after{ display:flex; }
    #topbar > *{ flex:0 0 auto; }
    #statusRow{
      flex-wrap:nowrap; justify-content:flex-start;
      overflow-x:auto; -webkit-overflow-scrolling:touch;
      padding-top:2px; gap:4px;
    }
    #statusRow::-webkit-scrollbar{ display:none; }
    #statusRow > *{ flex:0 0 auto; }
    #instruments{ padding:2px 10px 4px 10px; gap:3px; }
    .dial{ width:56px; height:56px; }
    .dial .readout{ font-size:9px; bottom:7px; }
    .tube{ height:56px; }
    .gauge-label{ font-size:9px; letter-spacing:1px; }
    #cabSignal{ font-size:10px; padding:2px 7px 2px 5px; }
    .panel{ gap:4px; padding:4px 3px; }
    button.cab-btn{ min-height:28px; padding:4px 4px; font-size:10px; letter-spacing:0.5px; line-height:1.15; }
    /* ---- Ergonomie tactile (demande utilisateur - "il faut souvent cliquer
         cote mecanicien ou conducteur en jeu, si c'est pas facilement
         accessible c'est complique") : en paysage, TOUS les boutons du
         panneau Conducteur descendaient uniformement a 28px pour tenir sans
         defilement - bien en dessous du seuil tactile recommande (44px), au
         risque de rater sa cible en pleine action. Plutot que de tout
         regrossir (retour du defilement pour atteindre certains boutons) ou
         tout laisser petit, seuls les DEUX boutons vraiment utilises dans le
         feu de l'action (Frein, Sifflet) recuperent une cible fiable - les
         boutons secondaires (Voie de service, Appeler le regulateur,
         Pilotage automatique, Technicentre, Course), sollicites bien moins
         souvent et jamais dans l'urgence, restent compacts. ---- */
    #brakeBtn, #whistleBtn{ min-height:40px; font-size:11px; }
  }

  /* ---- Meme correctif, pour un telephone en paysage plus etroit que
       700px CSS (certains petits modeles) : la regle ci-dessus ne
       s'appliquait alors pas du tout, laissant les boutons pleine taille
       exactement dans le pire cas (le moins de hauteur ET de largeur). Le
       seuil de largeur descend ici a 480px - suffisant pour couvrir un
       telephone en paysage (toujours nettement plus large que haut une
       fois tourne), sans jamais se declencher en portrait (largeur
       inferieure a 480px sur un telephone). ---- */
  @media (min-width: 480px) and (max-width: 699px) and (max-height: 500px){
    #topbar{
      flex-wrap:nowrap; justify-content:flex-start;
      overflow-x:auto; -webkit-overflow-scrolling:touch;
      padding:3px 6px; gap:3px;
    }
    #topbar::-webkit-scrollbar{ display:none; }
    #topbar::after{ display:flex; width:18px; font-size:13px; }
    #topbar > *{ flex:0 0 auto; }
    #statusRow{
      flex-wrap:nowrap; justify-content:flex-start;
      overflow-x:auto; -webkit-overflow-scrolling:touch;
      padding-top:2px; gap:3px;
    }
    #statusRow::-webkit-scrollbar{ display:none; }
    #statusRow > *{ flex:0 0 auto; }
    #instruments{ padding:2px 8px 3px 8px; gap:2px; }
    .dial{ width:48px; height:48px; }
    .dial .readout{ font-size:8px; bottom:6px; }
    .tube{ height:48px; }
    .gauge-label{ font-size:8px; letter-spacing:0.5px; }
    #cabSignal{ font-size:9px; padding:2px 6px 2px 4px; }
    .panel{ gap:3px; padding:3px 2px; width:min(24vw, 150px); }
    button.cab-btn{ min-height:26px; padding:3px 3px; font-size:9px; letter-spacing:0.3px; line-height:1.1; }
    /* ---- Meme correctif ergonomie tactile que le bloc paysage ci-dessus,
         pour les telephones en paysage encore plus etroits/bas couverts par
         cette media query : Frein et Sifflet gardent une cible fiable,
         le reste du panneau reste compact. ---- */
    #brakeBtn, #whistleBtn{ min-height:38px; font-size:10px; }
  }

  @media (max-width:600px){
    /* ---- Bug corrige (rapport utilisateur mobile - "le bandeau en haut
         des ecrans mobiles occupe trop de place et gache le gameplay") :
         #topbar (PK/GARE/HORAIRE/FRANCS/CARTE/VUE) est en flex-wrap normal
         - sur un ecran etroit, ses 6 plaquettes ne tiennent pas sur une
         seule ligne et debordent sur une deuxieme, doublant sa hauteur et
         mangeant d'autant la vue 3D juste en dessous (#window). Meme
         traitement que #statusRow plus bas : une seule ligne compacte qui
         defile horizontalement si besoin, plutot que d'empiler une
         deuxieme rangee. ---- */
    #topbar{
      flex-wrap:nowrap; justify-content:flex-start;
      overflow-x:auto; -webkit-overflow-scrolling:touch;
      padding:4px 6px; gap:4px;
    }
    #topbar::-webkit-scrollbar{ display:none; }
    #topbar::after{ display:flex; }
    #topbar > *{ flex:0 0 auto; }
    .plate{ font-size:8.5px; padding:2px 4px; }
    .plate b{ font-size:10px; }
    /* ---- Bug corrige (rapport utilisateur mobile - "le bandeau indicateur
         au-dessus des manometres est mal organise et prend trop de place") :
         sur mobile, cette rangee (feu cabine + prochaine gare + pente +
         meteo) passait facilement sur 2-3 lignes, mangeant une hauteur
         precieuse au-dessus des jauges. On la resserre en UNE ligne compacte
         qui defile horizontalement si besoin, avec des puces plus petites -
         l'essentiel (feu, prochaine gare, meteo/tunnel) reste lisible sans
         empieter sur la vue ni les manometres. ---- */
    #statusRow{
      flex-wrap:nowrap; justify-content:flex-start;
      gap:4px; padding:3px 6px 0 6px;
      overflow-x:auto; -webkit-overflow-scrolling:touch;
    }
    #statusRow::-webkit-scrollbar{ display:none; }
    #statusRow > *{ flex:0 0 auto; }
    #gradientTag, #weatherTag, #nextStopTag{ font-size:9.5px; padding:2px 5px; letter-spacing:0.5px; }
    #nextStopTag{ max-width:44vw; }
    #cabSignal{ font-size:9.5px; padding:2px 6px 2px 4px; gap:4px; }
    #cabSignal .cab-signal-lamp{ width:11px; height:11px; }
    #weatherTag.tag-tunnel{ font-size:12px; letter-spacing:2px; padding:3px 9px; }
    .panel{ width: min(21vw, 128px); padding:5px 3px; gap:5px; }
    /* ---- Bug corrige (rapport utilisateur mobile - "la partie gauche
         mecanicien legerement plus large car elle est coupee") : le
         panneau Mecanicien contient plus de contenu horizontal serre que
         le Conducteur (foyer + cadran d'entartrage cote a cote, labels de
         jauges plus longs comme "Injecteur (maintenir)" ou "Usure
         essieux") - la meme largeur generique que le Conducteur le
         rendait trop etroit sur mobile, coupant du texte. Elargi
         legerement, UNIQUEMENT pour ce panneau (:first-child), sans
         toucher au Conducteur (right, deja bien proportionne). ---- */
    #panels .panel:first-child{ left: 5px; width: min(25vw, 148px); }
    #panels .panel:last-child{ right: 5px; }
    /* ---- Les surcharges mobiles de button.cab-btn / .panel-title /
         .slider-row label / #sidingInfo ne sont PAS ici : leurs regles de
         base sont declarees plus bas dans la feuille. Une media query
         n'ajoute aucune specificite, donc a egalite la regle la plus
         tardive gagne et ces surcharges seraient mortes. Elles ont ete
         deplacees dans un second bloc @media (max-width:600px), place
         APRES ces regles de base. ---- */
  }

  /* ---- Compaction des controles A L'INTERIEUR des panneaux uniquement
       (demande utilisateur - "petits groupes compacts comme les jauges,
       pas une liste qui remplit toute la hauteur") : surcharge locale, ne
       touche pas au style de .go/.cab-btn utilise ailleurs dans le jeu
       (ecran de depart, modales...).
       ---- Corrige (2e passe) - "aucun changement" : les ajustements
       precedents (quelques px de padding/gap en moins sur une dizaine de
       lignes empilees) etaient bien appliques mais beaucoup trop discrets
       pour etre visibles a l'oeil. Remplaces par un zoom global du bloc
       entier - une seule regle, effet radical et immediat garanti,
       plutot que de chasser chaque sous-regle une par une. ---- */
  #panels .panel{ gap:5px; }
  .panel-title{
    font-size:11px; letter-spacing:2px; text-transform:uppercase;
    color: var(--brass-light);
    text-align:center;
    text-shadow: 0 1px 3px rgba(0,0,0,0.9), 0 0 8px rgba(0,0,0,0.7);
    padding-bottom:3px;
  }

  .bar-row{ display:flex; flex-direction:column; gap:2px; }
  .bar-label{
    display:flex; justify-content:space-between;
    font-family:'Space Mono', monospace; font-size:8.5px; color: var(--steam);
    letter-spacing:0.5px;
    text-shadow: 0 1px 3px rgba(0,0,0,0.9), 0 0 6px rgba(0,0,0,0.6);
  }
  .bar{
    height:10px; border-radius:5px; background:#0e1416;
    border:1px solid var(--brass-dark); overflow:hidden;
  }
  .bar .fill{ height:100%; transition: width 0.15s linear; }
  .bar.coal .fill{ background: linear-gradient(90deg,#4a4a4a,#1a1a1a); }
  .bar.tank .fill{ background: linear-gradient(90deg,#6fc2d6,var(--water)); }
  .bar.oil .fill{ background: linear-gradient(90deg,#4a3a1a,#8a6a26); }
  .bar.wear .fill{ background: linear-gradient(90deg,#5f9c5a,#5f9c5a); }

  #firebox{
    height: 38px;
    border-radius: 8px;
    border: 3px solid #1a1512;
    background: radial-gradient(circle, var(--fire) 0%, var(--fire-deep) 55%, #2a0d05 100%);
    box-shadow: inset 0 0 18px rgba(0,0,0,0.55), inset 0 0 30px 4px rgba(255,122,41,0.25);
    display:flex; align-items:center; justify-content:center;
    font-family:'Space Mono', monospace;
    color: rgba(0,0,0,0.55); font-size:10px; letter-spacing:1px;
    transition: filter 0.2s ease, opacity 0.2s ease;
    animation: fireboxFlicker 2.4s ease-in-out infinite;
  }
  @keyframes fireboxFlicker{
    0%,100%{ box-shadow: inset 0 0 18px rgba(0,0,0,0.55), inset 0 0 30px 4px rgba(255,122,41,0.25); }
    50%{ box-shadow: inset 0 0 22px rgba(0,0,0,0.5), inset 0 0 42px 9px rgba(255,140,60,0.42); }
  }

  button.cab-btn{
    font-family:'Cinzel', serif;
    font-weight:700;
    font-size: 12px;
    letter-spacing:1px;
    color:#231c10;
    background: linear-gradient(180deg, var(--brass-light), var(--brass) 60%, var(--brass-dark));
    border: none;
    border-radius: 6px;
    padding: 8px 6px;
    min-height: 40px;
    display:flex; align-items:center; justify-content:center; text-align:center;
    cursor:pointer;
    position:relative;
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;
    box-shadow: 0 3px 0 #5b430f, 0 5px 9px rgba(0,0,0,0.35), inset 0 1px 0 rgba(255,255,255,0.55), inset 0 -6px 8px rgba(0,0,0,0.12);
    transition: transform 0.08s ease, box-shadow 0.08s ease, filter 0.15s ease;
  }
  button.cab-btn:active{ transform: translateY(3px); box-shadow: 0 0 0 #5b430f, inset 0 1px 0 rgba(255,255,255,0.3), inset 0 3px 6px rgba(0,0,0,0.25); filter:brightness(0.96); }
  @media (hover:hover){
    button.cab-btn:hover{ filter:brightness(1.07); }
  }
  button.cab-btn.active-hold{
    background: linear-gradient(180deg, #7fd0e6, var(--water) 70%, #235a68);
    box-shadow: 0 3px 0 #17414d;
  }
  button.cab-btn.parking-active{
    background: linear-gradient(180deg, #ff8a6a, var(--danger) 70%, #7a1d13);
    box-shadow: 0 3px 0 #5c150d;
  }
  button.cab-btn.whistle-btn{
    background: linear-gradient(180deg, #e8e3d8, var(--steam) 60%, #6a7a7e);
  }
  button.cab-btn.oil-btn{
    background: linear-gradient(180deg, #8a7040, #5a4626 60%, #3a2c16);
    color: var(--glass);
  }
  button.cab-btn.purge-btn{
    background: linear-gradient(180deg, #5a7a8a, #345266 60%, #1c333f);
    color: var(--glass);
  }
  button.cab-btn.siding-btn{
    background: linear-gradient(180deg, #6a7a5a, #445238 60%, #2a3320);
    color: var(--glass);
  }
  button.cab-btn.siding-btn:disabled{
    opacity: 0.4;
  }
  /* ---- #sidingInfo / #wagonInfo n'ont plus de style propre : ce ne sont
       plus des lignes de texte mais les chiffres de deux cadrans, habilles
       par .stat-num (cf. .stat-strip plus bas). ---- */

  .slider-row{ display:flex; flex-direction:column; align-items:center; gap:4px; flex:1; min-width:0; }
  .slider-row label{
    font-size:9.5px; letter-spacing:1.5px; color: var(--brass-light); text-transform:uppercase;
    max-width:100%; text-align:center; overflow-wrap:break-word; line-height:1.2;
  }
  input[type=range]{
    writing-mode: vertical-lr;
    direction: rtl;
    width: 26px;
    height: 66px;
    accent-color: var(--brass);
    background: transparent;
  }
  input[type=range].slider-h{
    writing-mode: horizontal-tb;
    width: 100%;
    height: 20px;
  }
  .slider-val{
    font-family:'Space Mono', monospace; font-size:11px; color:var(--glass);
  }
  /* ---- Demande utilisateur - "le nombre de wagons et depannages a revoir
       en plus joli, pas en simple ligne de texte" : ces deux infos etaient
       deux phrases brutes ("Wagons atteles : 3 (poids +120)"). Elles
       deviennent de vrais petits cadrans d'instrument, dans le meme langage
       visuel que le reste de la cabine (corps fonte, cerclage laiton, ombre
       interne, Space Mono) : pastille + valeur en gros chiffre + libelle
       grave, avec le poids en sous-titre et les voies de service en pastilles
       (pleines = restantes). Empiles en colonne pleine largeur plutot qu'en
       2 colonnes : le panneau ne fait que 128px sur mobile, deux colonnes
       laissaient ~59px chacune et tronquaient tout. ---- */
  .stat-strip{ display:flex; flex-direction:column; gap:5px; margin-top:1px; }
  /* ---- Attention : il n'existe pas de regle `.hidden` globale dans cette
       feuille (seulement des variantes ciblees comme .overlay.hidden), d'ou
       cette regle locale - sans elle, les elements masques par JS via
       classList.add('hidden') resteraient visibles. ---- */
  .stat-strip .hidden{ display:none; }
  .stat-gauge{
    display:flex; align-items:center; gap:6px;
    background: linear-gradient(180deg, var(--iron-2), var(--iron-3));
    border: 1px solid var(--brass-dark);
    border-radius: 6px;
    padding: 5px 7px;
    box-shadow: inset 0 1px 4px rgba(0,0,0,0.55), 0 1px 0 rgba(255,255,255,0.05);
  }
  .stat-icon{
    flex:0 0 auto; font-size:14px; line-height:1;
    filter: drop-shadow(0 1px 1px rgba(0,0,0,0.6));
  }
  .stat-body{ display:flex; flex-direction:column; gap:1px; min-width:0; flex:1; }
  .stat-top{ display:flex; align-items:baseline; gap:4px; min-width:0; }
  .stat-num{
    font-family:'Space Mono', monospace; font-weight:700;
    font-size:15px; line-height:1; color: var(--glass);
    text-shadow: 0 0 6px rgba(233,200,120,0.35);
    flex:0 0 auto;
  }
  .stat-lbl{
    font-family:'Space Mono', monospace; font-size:7.5px;
    letter-spacing:1px; text-transform:uppercase; color: var(--brass);
    white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  }
  .stat-sub{
    font-family:'Space Mono', monospace; font-size:8px;
    letter-spacing:0.3px; color: var(--brass-light); opacity:0.85;
  }
  .stat-pips{ display:flex; flex-wrap:wrap; gap:2px; }
  .stat-pips i{
    width:5px; height:5px; border-radius:50%;
    background: var(--brass);
    box-shadow: 0 0 3px rgba(201,154,60,0.7), inset 0 1px 0 rgba(255,255,255,0.3);
  }
  .stat-pips i.spent{
    background: #3a3128;
    box-shadow: inset 0 1px 2px rgba(0,0,0,0.8);
  }
  /* ---- Voyants d'etat : remplacent le compteur "Depannages : N" (cf. le
       commentaire dans updateHud). Ils n'apparaissent que lorsqu'ils ont
       quelque chose a dire, au lieu d'occuper une ligne en permanence. ---- */
  .stat-lamp{
    display:flex; align-items:center; gap:4px;
    font-family:'Space Mono', monospace; font-size:7.5px;
    letter-spacing:0.5px; text-transform:uppercase;
    border-radius:5px; padding:3px 5px;
    border:1px solid transparent;
    line-height:1.25;
  }
  .stat-lamp::before{
    content:""; flex:0 0 auto;
    width:6px; height:6px; border-radius:50%;
    background: currentColor;
    box-shadow: 0 0 5px currentColor;
  }
  .stat-lamp.warn{ color: var(--brass-light); background: rgba(125,94,34,0.3); border-color: var(--brass-dark); }
  .stat-lamp.danger{ color: #f0a89e; background: rgba(150,40,30,0.35); border-color: rgba(192,57,43,0.7); }

  /* ---- Bug corrige - surcharges mobiles sans effet : ces quatre regles
       vivaient dans le bloc @media (max-width:600px) plus haut, AVANT les
       regles de base qu'elles sont censees surcharger. Une media query
       n'ajoute aucune specificite : a specificite egale c'est l'ordre du
       source qui tranche, donc les regles de base (declarees plus bas)
       l'emportaient et le mobile gardait les valeurs "desktop" (boutons a
       12px / min-height 40px, titres a 11px...). Deplacees ici, apres
       toutes les regles de base concernees, elles s'appliquent enfin. ---- */
  @media (max-width:600px){
    button.cab-btn{ font-size:10.5px; padding:7px 4px; min-height:44px; border-radius:5px; letter-spacing:0.5px; line-height:1.25; }
    .panel-title{ font-size:9.5px; letter-spacing:1px; }
    .slider-row label{ font-size:8.5px; }
    .stat-gauge{ padding:4px 5px; gap:5px; }
    .stat-icon{ font-size:12px; }
    .stat-num{ font-size:13px; }
    .stat-lbl{ font-size:7px; letter-spacing:0.5px; }
  }

  .overlay{
    /* ---- Bug corrige - "toujours pareil, les panneaux restent affiches
         sur l'ecran de choix de ligne" : .overlay etait en position:
         absolute, donc positionne relativement a #cab (la colonne etroite
         bridee en largeur, ex. 480-920px), alors que les panneaux
         Mecanicien/Conducteur sont desormais en position:fixed (relatif
         au VIEWPORT entier, cf. demande "sur les cotes du viewport").
         Sur un ecran large, #cab est plus etroit que le viewport : les
         panneaux (colles aux VRAIS bords de l'ecran) debordaient donc
         toujours des cotes de l'overlay (colle lui aux bords de #cab
         seulement), quel que soit son z-index. Passe en position:fixed
         (relatif au viewport, comme les panneaux) pour les couvrir
         effectivement partout ou un menu plein ecran doit les masquer. ----
       ---- Bug corrige - "les boutons En route/Carnet de bord sont
       coupes" : overflow-y:auto etait deja present mais html/body ont
       touch-action:none (global, pour bloquer les gestes navigateur
       pendant le jeu) - ce qui bloquait AUSSI le scroll tactile a
       l'interieur de cette overlay sur mobile, rendant le bas de l'ecran
       (les boutons) inaccessible au toucher meme si le CSS "permettait"
       de scroller. touch-action:pan-y reautorise explicitement le scroll
       vertical tactile a l'interieur de cette overlay. ---- */
    position:fixed; inset:0;
    display:flex; flex-direction:column; align-items:center; justify-content:flex-start;
    background: rgba(23,20,16,0.95);
    z-index:20; text-align:center; padding:22px; gap:12px;
    overflow-y:auto; overflow-x:hidden;
    touch-action: pan-y;
  }
  .overlay::before{
    content:"";
    margin:auto 0 0 0;
  }
  .overlay::after{
    content:"";
    margin:0 0 auto 0;
  }
  .overlay.hidden{ display:none; }

  /* ---- Onglets du magasin du technicentre (plan §5). Reprend la palette
       laiton/creme des autres modales. Les onglets non encore actifs
       (.shop-tab-soon) sont grises et desactives. ---- */
  .shop-tabs{ display:flex; flex-wrap:wrap; gap:6px; justify-content:center; width:100%; max-width:520px; margin:2px 0 4px; }
  .shop-tab{
    flex:1 1 auto; min-width:96px; padding:8px 10px; cursor:pointer;
    background: rgba(60,52,40,0.6); color:#efe4cf;
    border:1px solid rgba(200,162,74,0.35); border-radius:8px;
    font: inherit; font-size:14px;
  }
  .shop-tab.active{ background: linear-gradient(180deg, var(--brass-light), var(--brass-dark)); color:#231c10; border-color: rgba(255,230,180,0.5); font-weight:600; }
  .shop-tab-soon{ opacity:0.45; cursor:not-allowed; }
  .shop-loco-row{
    display:flex; align-items:center; gap:10px; text-align:left;
    background: rgba(40,35,28,0.55); border:1px solid rgba(200,162,74,0.25);
    border-radius:10px; padding:10px 12px; margin:8px 0;
  }
  .shop-loco-row.equipped{ border-color: rgba(120,200,120,0.6); box-shadow:0 0 0 1px rgba(120,200,120,0.35) inset; }
  .shop-loco-swatch{ width:34px; height:34px; border-radius:7px; flex:0 0 auto; border:1px solid rgba(0,0,0,0.4); }
  .shop-loco-info{ flex:1 1 auto; min-width:0; }
  .shop-loco-title{ font-weight:600; color:#f4ead6; }
  .shop-loco-sub{ font-size:12px; opacity:0.8; }
  .shop-loco-actions{ display:flex; flex-direction:column; gap:5px; flex:0 0 auto; }
  .shop-loco-actions button{ white-space:nowrap; }
  /* ---- Rond a cocher de confirmation avant de pouvoir valider un bouton du
       technicentre (demande utilisateur - "pour eviter les clics
       involontaires sur mobile et tablette... les boutons du technicentre
       comportent des rond a cocher avant de pouvoir valider") : meme
       principe que .line-radio/.loco-radio - les boutons d'action (Acheter,
       Equiper, Vendre, Installer, Retirer, Appliquer, Deposer...) restent
       desactives tant que ce rond, distinct d'eux, n'est pas coche. ---- */
  .shop-radio{
    flex:0 0 auto; width:26px; height:26px; margin:0; accent-color: var(--brass-light); cursor:pointer;
  }

  /* ---- Compte joueur (creation/connexion, demande utilisateur - "la
       creation, connexion etc de comptes doit etre responsive") : classes
       partagees plutot que des styles inline fixes (qui n'avaient ni
       width:100% ni box-sizing, et debordaient/restaient minuscules sur
       petit ecran) - reutilisees aussi par le formulaire de depot du
       depot-vente pour la meme raison. min-height:44px sur les champs
       reprend la meme cible tactile que button.cab-btn ailleurs dans le
       jeu (recommandation Apple/Google pour un doigt, pas juste une
       souris). ---- */
  .account-panel{
    width:100%; max-width:420px;
    display:flex; flex-direction:column; gap:8px;
  }
  .account-input{
    width:100%; box-sizing:border-box; min-height:44px;
    padding:8px 10px; background:#1a1712; color:#e9c878;
    border:1px solid rgba(255,255,255,0.2); border-radius:4px;
    font-family:'Space Mono', monospace; font-size:14px;
  }
  .account-input::placeholder{ color:rgba(233,200,120,0.5); }
  .account-hint{ font-size:10.5px; opacity:0.75; }
  @media (max-width:600px){
    .account-input{ font-size:16px; } /* >=16px : evite le zoom automatique de Safari/Chrome mobile au focus */
    .account-hint{ font-size:10px; }
  }

  /* ---- Boite du code de recuperation (demande utilisateur - "il faut un
       truc mot de passe oublie") : affichee UNE SEULE FOIS juste apres la
       creation d'un compte, jamais recuperable ensuite - mise en evidence
       forte (bordure laiton, fond legerement teinte) pour qu'elle ne passe
       pas inapercue au milieu du reste du formulaire. user-select:all sur
       le code lui-meme : un simple clic/tap selectionne tout le code d'un
       coup, plus facile a copier a la main que de faire glisser une
       selection sur mobile. ---- */
  .account-recovery-box{
    width:100%; max-width:420px; box-sizing:border-box;
    border:2px solid var(--brass-light); border-radius:8px;
    padding:12px; margin-bottom:4px;
    /* ---- Bug corrige (rapport utilisateur - "on sait pas lire ton
         message pour le code de recuperation") : fond a 8% d'opacite
         seulement - le titre de l'ecran d'accueil, derriere, transparaissait
         assez fort pour rendre l'avertissement illisible. Fond sombre
         proche de celui de l'overlay parent (quasi opaque), le liseret
         dore suffit a distinguer la boite sans laisser rien transparaitre. ---- */
    background: rgba(15,12,9,0.94);
  }
  .account-recovery-box.hidden{ display:none; }
  .account-recovery-label{ font-size:11.5px; opacity:0.9; margin-bottom:6px; }
  .account-recovery-code{
    font-family:'Space Mono', monospace; font-size:20px; letter-spacing:2px;
    color:#e9c878; text-align:center; padding:8px 0; user-select:all;
    word-break:break-all;
  }
  @media (max-width:380px){
    .account-recovery-code{ font-size:16px; letter-spacing:1px; }
  }

  /* ---- Mini-carte cabine (version sommaire du schema du regulateur) ---- */
  #miniMapPanel{
    position:relative; z-index:1;
    width:100%; box-sizing:border-box;
    background: linear-gradient(180deg, var(--iron-2), var(--iron));
    border-bottom: 2px solid var(--brass-dark);
    padding: 8px 12px 6px;
  }
  #miniMapPanel.hidden{ display:none; }
  #miniMapSvg{ width:100%; height:54px; display:block; }
  #miniMapLegend{
    display:flex; gap:14px; justify-content:center; margin-top:4px;
    font-family:'Space Mono', monospace; font-size:9px; color: var(--brass-light);
  }
  #miniMapLegend span{ display:inline-flex; align-items:center; gap:4px; }
  .mmap-dot{ width:7px; height:7px; border-radius:50%; display:inline-block; }
  /* ---- Repere technicentre de la mini-carte (trait tirete bleu-acier,
       identique aux schemas regulateur/superuser). ---- */
  .mmap-tick{ width:0; height:9px; border-left:2px dashed #6fb8cc; display:inline-block; }

  /* ---- Carte postale historique de gare (Wikimedia Commons) : cadre
     "laiton" cohérent avec le reste de la cabine, image en sépia léger pour
     évoquer une photo d'époque, légende + crédit en petit dessous.
     Effet "Ken Burns" (leger zoom/travelling automatique et continu) sur la
     photo elle-meme, pour un rendu presque anime sans dependre d'un fichier
     video - la photo reste nette et fixe pour la legende/l'attribution,
     seul le cadrage a l'interieur du cache (station-photo-frame) bouge. ---- */
  .station-photo{
    width:min(92%, 420px);
    border:2px solid var(--brass-dark);
    border-radius:6px;
    background: var(--iron-3);
    padding:6px;
    box-shadow: 0 4px 14px rgba(0,0,0,0.5);
  }
  .station-photo.hidden{ display:none; }
  .station-photo-frame{
    overflow:hidden; border-radius:3px; aspect-ratio: 4 / 3;
  }
  .station-photo img{
    width:100%; height:100%; object-fit:cover; display:block;
    filter: sepia(0.35) contrast(1.05);
    transform-origin: 50% 50%;
    animation: stationKenBurns 16s ease-in-out infinite alternate;
  }
  @keyframes stationKenBurns{
    0%{ transform: scale(1) translate(0, 0); }
    100%{ transform: scale(1.14) translate(-2.5%, -1.5%); }
  }
  @media (prefers-reduced-motion: reduce){
    .station-photo img{ animation: none; }
  }
  .station-photo-caption{
    font-family:'Space Mono', monospace; font-size:10px; letter-spacing:0.5px;
    color: var(--brass-light); opacity:0.85; margin-top:5px; line-height:1.4;
  }
  .station-photo-caption a{ color:inherit; }

  /* ---- En-tete responsive de l'ecran de demarrage (topRow) : le bouton
     d'aide flotte a droite du titre sur ecran large, et repasse dans le
     flux normal (centre, sous le titre) sur petit ecran pour ne jamais
     chevaucher le texte. Meme principe que index.html. ---- */
  .topRow{ position:relative; width:100%; display:flex; flex-direction:column; align-items:center; gap:6px; }
  .startHelpBtn{
    position:absolute; top:0; right:0;
    font-family:'Space Mono', monospace; font-size:11px; letter-spacing:0.5px;
    color:var(--brass-light); background:linear-gradient(180deg, var(--iron-2), var(--iron));
    border:1px solid var(--brass-dark); border-radius:999px; padding:7px 13px;
    cursor:pointer; white-space:nowrap;
  }
  .startHelpBtn:hover{ border-color:var(--brass); color:var(--glass); }
  .startHelpBtn:active{ transform:translateY(1px); }

  /* ---- Ecran de demarrage sur petit telephone : titre en taille fluide,
     bouton d'aide qui repasse sous le titre au lieu de flotter en absolu
     (chevaucherait le texte sur un ecran etroit), paddings resserres. ---- */
  @media (max-width:380px){
    .overlay{ padding:16px; gap:9px; }
    h1.title{ font-size:clamp(22px, 7.5vw, 30px); padding:8px 10px; letter-spacing:1.5px; }
    .topRow{ position:static; }
    .startHelpBtn{ position:static; margin-top:2px; }
  }

  /* ---- Modale d'aide (ecran de demarrage conducteur) : meme gabarit
     visuel que #trainInfoBackdrop/#trainInfoCard deja utilises ailleurs
     dans cette page, agrandi et rendu defilant pour du texte explicatif. ---- */
  #startHelpBackdrop{
    position:absolute; inset:0; z-index:45;
    background: rgba(10,8,6,0.78);
    display:flex; align-items:center; justify-content:center;
    padding:18px;
  }
  #startHelpBackdrop.hidden{ display:none; }
  #startHelpCard{
    background: linear-gradient(180deg, var(--iron-2), var(--iron-3));
    border: 1px solid var(--brass-dark);
    border-radius:10px;
    box-shadow: 0 14px 40px rgba(0,0,0,0.55);
    max-width: 560px; width:100%; max-height:84vh; max-height:84dvh; overflow-y:auto;
    padding: 18px 20px 20px;
    position:relative; text-align:left;
  }
  #startHelpCard .close-x{
    position:absolute; top:8px; right:10px;
    background:none; border:none; color:var(--steam);
    font-size:18px; line-height:1; cursor:pointer; padding:4px;
  }
  #startHelpCard .close-x:hover{ color: var(--glass); }
  #startHelpCard h2{
    font-family:'Cinzel', serif; font-weight:700; letter-spacing:1px;
    font-size:17px; margin:0 26px 12px 0; color:var(--brass-light);
  }
  #startHelpCard h3{
    font-family:'Cinzel', serif; color:var(--brass-light); font-size:11.5px;
    letter-spacing:0.5px; margin:16px 0 5px; text-transform:uppercase;
  }
  #startHelpCard h3:first-of-type{ margin-top:0; }
  #startHelpCard p, #startHelpCard li{
    font-family:'Space Mono', monospace; font-size:11.5px; color:var(--steam); line-height:1.65;
  }
  #startHelpCard ul{ margin:5px 0; padding-left:16px; }
  #startHelpCard b{ color:var(--glass); }
  #startHelpCard .tip{
    margin-top:14px; padding:10px 12px; border-radius:6px;
    background:var(--iron-3); border:1px solid var(--brass-dark); font-size:11px;
    color:var(--glass); text-transform:none; letter-spacing:normal;
    font-family:'Space Mono', monospace; line-height:1.55;
  }
  @media (max-width:380px){
    #startHelpBackdrop{ padding:0; }
    #startHelpCard{ max-width:100%; max-height:100%; height:100%; border-radius:0; border-width:0; }
  }

  /* ---- Onglets de la modale d'aide (une section par grande partie du
       jeu) : reprend le gabarit visuel de .shop-tabs/.shop-tab deja
       utilise au technicentre, en plus compact et colle en haut de la
       carte (sticky) pour rester accessible meme apres avoir defile un
       panneau long. ---- */
  #helpTabs{
    max-width:none; margin:0 0 10px; gap:5px;
    position:sticky; top:0; z-index:2;
    background: linear-gradient(180deg, var(--iron-2), var(--iron-2) 80%, transparent);
    padding-top:2px; padding-bottom:6px;
  }
  #helpTabs .shop-tab{ min-width:0; flex:1 1 auto; padding:7px 6px; font-size:10.5px; font-family:'Space Mono', monospace; letter-spacing:0.2px; text-align:center; }
  .help-panel{ display:none; }
  .help-panel.active{ display:block; }
  @media (max-width:380px){
    #helpTabs{ gap:4px; }
    #helpTabs .shop-tab{ font-size:9.5px; padding:6px 4px; }
  }

  /* ---- Bouton d'aide flottant reutilisable, accessible depuis la gare
     (#stationHub) et le technicentre (#technicentreShop) en plus de
     l'ecran de demarrage - ouvre exactement la meme modale #startHelpBackdrop.
     Les overlays parentes sont en position:fixed (cf. .overlay), ce qui
     etablit deja le referentiel de positionnement pour top/right ici. ---- */
  .helpFab{
    position:absolute; top:14px; right:14px; z-index:5;
    font-family:'Space Mono', monospace; font-size:11px; letter-spacing:0.5px;
    color:var(--brass-light); background:linear-gradient(180deg, var(--iron-2), var(--iron));
    border:1px solid var(--brass-dark); border-radius:999px; padding:7px 13px;
    cursor:pointer; white-space:nowrap;
  }
  .helpFab:hover{ border-color:var(--brass); color:var(--glass); }
  .helpFab:active{ transform:translateY(1px); }
  @media (max-width:380px){
    .helpFab{ top:8px; right:8px; padding:6px 10px; font-size:10px; }
  }


  /* ---- Modale d'informations sur un autre train (bot ou joueur), ouverte
     au clic depuis la scene graphique. Remplace l'ancienne info-bulle
     epinglee dans le canevas, qui pouvait deborder du cadre de la scene
     et etre tronquee. ---- */
  /* ---- Bug corrige - "fenetre mal proportionnee" : cette modale est nichee
     dans #window (le cadre de la scene graphique, seulement 18% de la
     hauteur de la cabine et en overflow:hidden) plutot qu'au niveau de #cab.
     Avec position:absolute, elle etait donc positionnee et DECOUPEE par
     rapport a ce petit cadre au lieu de toute la fenetre du jeu - le
     contenu (notamment plusieurs lignes d'info) pouvait deborder et etre
     tronque en bas, invisible. position:fixed la positionne desormais par
     rapport a la fenetre du navigateur entiere (aucun ancetre ici n'a de
     transform/perspective qui redefinirait ce referentiel), comme un vrai
     modal plein ecran. ---- */
  #trainInfoBackdrop{
    position:fixed; inset:0; z-index:40;
    background: rgba(10,8,6,0.72);
    display:flex; align-items:center; justify-content:center;
    padding:16px;
  }
  #trainInfoBackdrop.hidden{ display:none; }
  #trainInfoCard{
    background: linear-gradient(180deg, var(--iron-2), var(--iron-3));
    border: 1px solid var(--brass-dark);
    border-radius:8px;
    box-shadow: 0 10px 34px rgba(0,0,0,0.55);
    max-width: 340px; width:100%;
    padding: 16px 18px 18px;
    position:relative;
  }
  #trainInfoCard .close-x{
    position:absolute; top:8px; right:10px;
    background:none; border:none; color:var(--steam);
    font-size:18px; line-height:1; cursor:pointer; padding:4px;
  }
  #trainInfoCard .close-x:hover{ color: var(--glass); }
  #trainInfoTitle{
    font-family:'Cinzel', serif; font-weight:700; letter-spacing:1px;
    font-size:16px; margin:0 0 2px; padding-right:20px;
  }
  #trainInfoSub{
    font-family:'Space Mono', monospace; font-size:11px; color:var(--steam);
    margin:0 0 12px;
  }
  .train-info-rows{
    display:flex; flex-direction:column; gap:7px;
  }
  .train-info-row{
    display:flex; justify-content:space-between; gap:14px;
    font-family:'Space Mono', monospace; font-size:12px;
    border-bottom: 1px solid rgba(201,154,60,0.18);
    padding-bottom:6px;
  }
  .train-info-row span:first-child{ color: var(--steam); }
  .train-info-row span:last-child{ color: var(--glass); text-align:right; font-weight:600; }
  .train-info-row.warn span:last-child{ color: var(--danger); }

  /* ---- Menu "Appeler le régulateur" (demande utilisateur) : reprend le
     style de #trainInfoBackdrop/#trainInfoCard, avec une liste verticale
     de boutons d'action plutot que des lignes d'information. ---- */
  /* ---- Mode course (demande utilisateur) : meme gabarit de modale que
     #trainInfoBackdrop/#assistanceMenuBackdrop (voir les commentaires de
     correctif juste au-dessus) - position:fixed des la creation, pour ne
     pas reproduire le bug "fenetre ecrasee dans le petit cadre de la
     scene". ---- */
  #raceBackdrop{
    position:fixed; inset:0; z-index:42;
    background: rgba(10,8,6,0.78);
    display:flex; align-items:center; justify-content:center;
    padding:16px;
  }
  #raceBackdrop.hidden{ display:none; }
  /* ---- Bug corrige - "modale course mal proportionnee / pas responsive" :
     les sous-panneaux (#raceSearchingPane, #raceCountdownPane, et a
     l'epoque #raceRunningPane/#raceResultPane, retires depuis lors par la
     refonte "vraie simulation" - cf. CORRECTIONS) portent tous
     class="hidden" en HTML, mais aucune regle CSS ne definissait
     ".hidden{display:none}" de facon generique, ni de regle scopee
     #raceXxxPane.hidden - seuls des selecteurs specifiques a d'autres
     composants existaient (#raceBackdrop.hidden, .overlay.hidden, etc).
     Consequence : tous les panneaux de la course s'affichaient empiles
     simultanement, d'ou une carte demesuree qui debordait de l'ecran. On
     ajoute ici une regle .hidden generique qui masque n'importe quel
     element portant cette classe a l'interieur de #raceCard, plus un
     max-height/overflow-y et une media query mobile (meme gabarit que
     #startHelpCard) pour que la carte reste contenue et scrollable sur
     petit ecran. ---- */
  #raceCard .hidden{ display:none !important; }
  #raceCard{
    background: linear-gradient(180deg, var(--iron-2), var(--iron-3));
    border: 1px solid var(--brass-dark);
    border-radius:8px;
    box-shadow: 0 10px 34px rgba(0,0,0,0.55);
    max-width: 380px; width:100%; max-height:88vh; max-height:88dvh; overflow-y:auto;
    padding: 16px 18px 18px;
    position:relative; text-align:center;
  }
  @media (max-width:380px){
    #raceBackdrop{ padding:0; }
    #raceCard{ max-width:100%; max-height:100%; height:100%; border-radius:0; border-width:0; }
  }
  #raceCard h3{
    font-family:'Cinzel', serif; font-weight:700; letter-spacing:1px;
    font-size:16px; margin:0 0 4px; padding-right:20px;
  }
  #raceCard .assistance-menu-sub{ text-align:left; }
  /* ---- Reutilisees par #raceHud (indicateur pendant une vraie course) -
     l'ancienne mini-simulation (accelerateur/frein, resultat dans la
     modale) a ete retiree, cf. commentaire HTML de #raceHud. ---- */
  .race-lane{ text-align:left; margin-bottom:8px; }
  .race-lane-label{
    font-family:'Space Mono', monospace; font-size:11px; color:var(--steam);
    margin-bottom:4px;
  }
  .race-lane-track{
    height:14px; border-radius:7px; background: rgba(0,0,0,0.4);
    border:1px solid var(--brass-dark); overflow:hidden;
  }
  .race-lane-fill{ height:100%; width:0%; transition: width 0.4s linear; }
  .race-lane-me{ background: linear-gradient(90deg, var(--ok), #9be89b); }
  .race-lane-opp{ background: linear-gradient(90deg, #8a8a8a, #b8b8b8); }
  #raceHud{
    position:fixed; z-index:38; top:10px; right:10px; width:220px;
    background: linear-gradient(180deg, var(--iron-2), var(--iron-3));
    border:1px solid var(--brass-dark); border-radius:8px;
    box-shadow: 0 8px 26px rgba(0,0,0,0.5); padding:10px 12px;
  }
  #raceHud.hidden{ display:none; }
  #raceHudTitle{
    font-family:'Cinzel', serif; font-weight:700; font-size:11.5px;
    color: var(--brass-light); margin-bottom:8px; letter-spacing:0.3px;
  }
  @media (max-width:760px){
    #raceHud{ top:auto; bottom:8px; right:8px; width:170px; padding:8px 10px; }
    #raceHudTitle{ font-size:10px; }
  }

  /* ---- Meme bug/correction que #trainInfoBackdrop ci-dessus (voir le
     commentaire detaille la-bas) : cette modale est elle aussi nichee dans
     #window, d'ou le rendu ecrase/tronque observe (le 3e bouton "Equipe de
     depannage" coupe en bas du cadre de la scene). position:fixed au lieu
     de position:absolute. ---- */
  #assistanceMenuBackdrop{
    position:fixed; inset:0; z-index:40;
    background: rgba(10,8,6,0.72);
    display:flex; align-items:center; justify-content:center;
    padding:16px;
  }
  #assistanceMenuBackdrop.hidden{ display:none; }
  #assistanceMenuCard{
    background: linear-gradient(180deg, var(--iron-2), var(--iron-3));
    border: 1px solid var(--brass-dark);
    border-radius:8px;
    box-shadow: 0 10px 34px rgba(0,0,0,0.55);
    max-width: 340px; width:100%;
    padding: 16px 18px 18px;
    position:relative;
  }
  #assistanceMenuCard h3{
    font-family:'Cinzel', serif; font-weight:700; letter-spacing:1px;
    font-size:16px; margin:0 0 4px; padding-right:20px;
  }

  /* ---- Invitation de course (demande utilisateur) : meme gabarit visuel
       que #assistanceMenuBackdrop juste au-dessus, z-index legerement
       superieur pour rester au-dessus d'une eventuelle autre modale deja
       ouverte (rare mais possible - ex. fiche d'un autre train). ---- */
  #raceInviteBackdrop{
    position:fixed; inset:0; z-index:41;
    background: rgba(10,8,6,0.78);
    display:flex; align-items:center; justify-content:center;
    padding:16px;
  }
  #raceInviteBackdrop.hidden{ display:none; }
  #raceInviteCard{
    background: linear-gradient(180deg, var(--iron-2), var(--iron-3));
    border: 1px solid var(--brass-dark);
    border-radius:8px;
    box-shadow: 0 10px 34px rgba(0,0,0,0.55);
    max-width: 340px; width:100%;
    padding: 16px 18px 18px;
    position:relative; text-align:center;
  }
  #raceInviteCard h3{
    font-family:'Cinzel', serif; font-weight:700; letter-spacing:1px;
    font-size:16px; margin:0 0 8px;
  }

  /* ---- Decompte de course (demande utilisateur - "decompte pour commencer
       a rouler") : plein ecran, au-dessus de tout (z-index superieur meme a
       #raceInviteBackdrop) - les deux coureurs viennent d'etre teleportes a
       la gare de rendez-vous, le levier est verrouille a 0 (cf.
       raceCountdownLockUpdate) tant que ce panneau est visible. ---- */
  #raceCountdownBackdrop{
    position:fixed; inset:0; z-index:45;
    background: rgba(10,8,6,0.82);
    display:flex; align-items:center; justify-content:center;
    flex-direction:column; gap:6px; padding:16px; text-align:center;
    pointer-events:none;
  }
  #raceCountdownBackdrop.hidden{ display:none; }
  #raceCountdownTitle{
    font-family:'Cinzel', serif; font-weight:700; letter-spacing:1px;
    font-size:15px; color: var(--brass-light);
  }
  #raceCountdownNumber{
    font-family:'Cinzel', serif; font-weight:700; font-size:72px;
    color: var(--glass); text-shadow: 0 0 24px rgba(233,200,120,0.6);
  }

  /* ---- Pastille "toujours en file d'attente" (demande utilisateur) :
       petit badge fixe, cliquable, rappelant discretement qu'une file
       d'attente tourne en arriere-plan une fois sa modale fermee. ---- */
  #driverQueueBadge{
    position:fixed; top:10px; right:10px; z-index:39;
    background: linear-gradient(180deg, var(--iron-2), var(--iron-3));
    border: 1px solid var(--brass-dark); border-radius:6px;
    box-shadow: 0 6px 18px rgba(0,0,0,0.5);
    padding:8px 12px; cursor:pointer;
    font-family:'Space Mono', monospace; font-size:11.5px; color:var(--brass-light);
  }
  #driverQueueBadge.hidden{ display:none; }
  #driverQueueBadge:hover{ border-color:var(--brass); color:var(--glass); }
  @media (max-width:760px){
    #driverQueueBadge{ top:auto; bottom:8px; right:8px; font-size:10.5px; padding:7px 10px; }
  }
  .assistance-menu-sub{
    font-family:'Space Mono', monospace; font-size:11px; color:var(--steam);
    margin:0 0 14px;
  }
  .assistance-menu-btn{
    display:block; width:100%; margin-bottom:8px; text-align:left;
    font-size:13px;
  }
  .assistance-menu-btn:last-child{ margin-bottom:0; }

  .eyebrow{
    font-family:'Space Mono', monospace; font-size:11px; letter-spacing:3px;
    color: var(--brass-light); text-transform:uppercase;
  }
  h1.title{
    font-size: 32px; margin:0; color: var(--glass); letter-spacing:3px;
    text-transform:uppercase; border-top:3px solid var(--fire); border-bottom:3px solid var(--fire);
    padding: 10px 16px;
  }
  .subtitle{
    font-family:'Space Mono', monospace; color: var(--steam); font-size:12.5px;
    max-width:320px; line-height:1.65;
  }
  .final-score{
    font-family:'Space Mono', monospace; font-size:30px; color:var(--glass); font-weight:700;
  }
  button.go{
    font-family:'Cinzel', serif; font-weight:700; font-size:16px; letter-spacing:2px;
    text-transform:uppercase; color:#231c10; background:var(--brass);
    border:none; padding:13px 30px; border-radius:4px; cursor:pointer;
    box-shadow: 0 4px 0 var(--brass-dark);
    touch-action: manipulation;
    /* ---- Demande utilisateur - "les textes dans les boutons doivent
         etre centres hauteur comme largeur" : un <button> aligne son
         contenu au centre horizontalement par defaut, mais pas forcement
         verticalement une fois que le texte passe sur plusieurs lignes
         (white-space:normal, cf. .overlay button.go plus bas) - le
         padding symetrique (13px haut/bas) ne suffit pas toujours a
         center visuellement un contenu multi-lignes. Passage en flex
         (centre sur les deux axes) : solution robuste, valable quel que
         soit le nombre de lignes du libelle. ---- */
    display:flex; align-items:center; justify-content:center; text-align:center;
  }
  button.go:active{ transform: translateY(3px); box-shadow:0 1px 0 var(--brass-dark); }
  button.go-secondary{
    background: linear-gradient(180deg, var(--iron-2), var(--iron));
    color: var(--glass);
    border: 2px solid var(--brass-dark);
    box-shadow: none;
    font-size: 13px;
    padding: 10px 22px;
  }
  button.go-secondary:active{ transform: translateY(2px); }
  /* ---- Bug corrige (rapport utilisateur - "on ne voit pas tout le
       texte" des boutons du hub de gare) : opacite remontee (0.4 -> 0.6)
       - a 0.4, le texte clair (var(--glass)) sur fond sombre (var(--iron))
       devenait quasiment illisible une fois attenue en plus par l'etat
       desactive, donnant l'impression que le libelle etait tronque/
       manquant alors qu'il etait juste trop pale pour etre lu. ---- */
  button.go-secondary:disabled{ opacity: 0.6; }

  /* ---- Selecteur de voie de depart (demande utilisateur - "attente
       hyper longue alors qu'il y a 3 voies et des places de garage") :
       le conducteur peut desormais choisir lui-meme sur laquelle des 3
       voies (principale/evitement/service) il souhaite partir, plutot que
       de rester fige sur sa seule voie "habituelle" en attendant le
       sifflet. Trois boutons compacts cote a cote, la voie actuellement
       choisie mise en evidence (bordure laiton pleine + fond legerement
       eclairci) plutot qu'un simple <select>, pour rester coherent avec le
       style "manette/levier" du reste de la cabine. ---- */
  .voieChoiceRow{
    display:flex; gap:8px; width:100%; max-width:340px; margin:2px 0 4px;
  }
  button.voieChoiceBtn{
    flex:1; font-family:'Space Mono', monospace; font-size:11px; letter-spacing:0.5px;
    color: var(--steam); background: linear-gradient(180deg, var(--iron-2), var(--iron));
    border: 2px solid var(--brass-dark); border-radius:5px; padding:9px 4px;
    cursor:pointer; text-align:center; line-height:1.3;
  }
  button.voieChoiceBtn:active{ transform: translateY(1px); }
  button.voieChoiceBtn.active{
    border-color: var(--brass); color: var(--brass-light); background: rgba(201,154,60,0.14);
  }
  button.voieChoiceBtn:disabled{ opacity:0.5; cursor:default; }
  /* ---- Demande utilisateur - "on doit voir les 3 voies proposées avec une
     couleur verte ou rouge selon leur occupation" : petit pastille de statut
     avant le libellé, cf. updateVoieChoiceUI() qui bascule ces classes selon
     le nombre de trains deja presents sur le troncon (0 libre, 1-2 partagee,
     3 = complete, meme seuil que le poste de regulation). N'affecte jamais
     l'etat .active (voie choisie), qui reste prioritaire visuellement via
     la bordure/couleur du texte deja geree ci-dessus. ---- */
  button.voieChoiceBtn .voieOccupDot{ display:inline-block; width:8px; height:8px; border-radius:50%; margin-right:5px; vertical-align:middle; }
  button.voieChoiceBtn.occ-free .voieOccupDot{ background:#3ecf6a; box-shadow:0 0 4px #3ecf6a; }
  button.voieChoiceBtn.occ-partial .voieOccupDot{ background:#e0b23e; box-shadow:0 0 4px #e0b23e; }
  button.voieChoiceBtn.occ-full .voieOccupDot{ background:#e05a3e; box-shadow:0 0 4px #e05a3e; }

  /* ---- Bug corrige (capture a l'appui - "les boutons du panneau des
       gares sont mal affiches") : button.go/button.go-secondary n'avaient
       aucune largeur commune - chaque bouton se dimensionnait uniquement
       sur son propre texte (padding + longueur du libelle), d'ou un
       empilement en dents de scie ("Roulage" tres etroit a cote de
       "Demander la voie de service" tres large, texte touchant presque le
       bord de son bouton) au lieu d'une colonne de boutons bien alignes.
       Le panneau de gare (#stationHub) est le plus touche car il empile
       le plus de libelles de longueurs tres differentes. Largeur commune
       fixee ici, sur TOUS les boutons .go/.go-secondary a l'interieur
       d'une .overlay (pas seulement la gare) pour une coherence globale. ---- */
  .overlay button.go, .overlay button.go-secondary{
    width:100%; max-width:340px; box-sizing:border-box;
    white-space:normal; line-height:1.3; height:auto;
  }

  /* ---- Demande utilisateur - "les boutons En route et carnet de bord
       doivent etre fixes en bas de page" : le "position:sticky" precedent
       ne restait colle qu'au bas de SA PROPRE overlay scrollable
       (#startOverlay) - correct dans l'absolu, mais pas ce qui etait
       demande ici. Passe en "position:fixed" (relatif au VIEWPORT entier,
       comme .overlay elle-meme) : la barre reste desormais figee en bas
       de l'ECRAN, quel que soit le defilement du contenu au-dessus.
       Centree horizontalement via left:50%/translateX(-50%) puisqu'un
       element fixed sort du flux et ne peut plus etre centre par le
       parent flex. z-index superieur a .overlay (20) pour rester
       au-dessus du contenu qui defile derriere. ---- */
  /* ---- Demande utilisateur - "en route et carnet de bord, ca doit etre
     des boutons fixes, pas flottants, en fin de page" : la barre n'est
     plus en position:fixed collee au bas du viewport (avec un degrade
     semi-transparent qui masquait le contenu derriere elle et forcait un
     padding-bottom de 170px sur l'overlay). Elle est desormais dans le
     flux normal, visible apres le dernier element de la page, comme un
     simple bloc en bas du scroll. ---- */
  #startActionBar{
    width: 100%; max-width: 420px;
    display: flex; flex-direction: column; align-items: center; gap: 10px;
    padding: 18px 0 10px;
  }

  #startOverlay{ padding-bottom: 30px; }

  .chief-signal{
    display:flex; align-items:center; gap:8px; margin: 2px 0 4px 0;
    font-family:'Space Mono', monospace; font-size:11.5px; color: var(--steam);
  }
  .chief-lamp{
    width:14px; height:14px; border-radius:50%; flex:0 0 auto;
    background: radial-gradient(circle at 35% 30%, #7a1f18, #3a0d0a);
    border: 1px solid #1a0806;
    box-shadow: inset 0 0 3px #000;
  }
  .chief-lamp.wait{
    background: radial-gradient(circle at 35% 30%, #ff5c3a, #8a1f0e);
    box-shadow: 0 0 8px 2px rgba(255,90,40,0.65), inset 0 0 3px #300;
    animation: chiefWaitPulse 1s ease-in-out infinite;
  }
  .chief-lamp.ready{
    background: radial-gradient(circle at 35% 30%, #7dffa0, #1c8a3e);
    box-shadow: 0 0 10px 3px rgba(90,255,140,0.75), inset 0 0 3px #030;
    animation: none;
  }
  @keyframes chiefWaitPulse{
    0%,100%{ opacity:1; } 50%{ opacity:0.45; }
  }

  .mp-panel{ width:100%; max-width:320px; display:flex; flex-direction:column; gap:7px; margin: 4px 0; }
  .mp-check{ display:flex; align-items:center; gap:8px; font-family:'Space Mono',monospace; font-size:12px; color:var(--glass); }
  .mp-check input{ width:16px; height:16px; accent-color: var(--brass); }
  .mp-panel input[type="text"]{
    font-family:'Space Mono',monospace; font-size:12px; color:var(--glass);
    background: var(--iron-3); border:1px solid var(--brass-dark); border-radius:4px;
    padding:8px 9px; width:100%;
  }
  .mp-panel input[type="text"]:disabled{ opacity:0.35; }
  #mpStatus{ font-family:'Space Mono',monospace; font-size:10.5px; min-height:14px; }
  #mpStatus.ok{ color: var(--ok); }
  #mpStatus.err{ color: var(--danger); }
  .medal-or{ color: var(--gold) !important; border-color: var(--gold) !important; }
  .medal-argent{ color: var(--silver) !important; border-color: var(--silver) !important; }
  .medal-bronze{ color: var(--bronze) !important; border-color: var(--bronze) !important; }

  #locoPicker{
    display:flex; gap:8px; width:100%; max-width:340px; justify-content:center; flex-wrap:wrap;
  }
  #linePicker{
    display:flex; flex-direction:column; gap:10px; width:100%; max-width:420px;
    box-sizing:border-box;
  }
  .line-cards-grid{
    display:flex; flex-direction:column; gap:6px;
  }
  .line-card{
    background: linear-gradient(180deg, var(--iron-2), var(--iron));
    border: 2px solid var(--brass-dark);
    border-radius: 8px;
    padding: 9px 12px;
    cursor:pointer;
    text-align:left;
    display:flex; align-items:center; gap:10px;
    transition: border-color 0.15s, box-shadow 0.15s;
    min-width:0; overflow:hidden;
    box-sizing:border-box;
  }
  .line-card:hover:not(.locked){ border-color: var(--brass-light); }
  .line-thumb{
    width:48px; height:48px; flex:0 0 48px; border-radius:6px;
    object-fit:cover; border:1px solid var(--brass-dark);
    filter: sepia(0.3) contrast(1.05);
  }
  .line-card-text{ flex:1 1 auto; min-width:0; overflow:hidden; }
  .line-card.selected{ border-color: var(--brass-light); box-shadow: 0 0 0 2px var(--brass-light) inset; }
  .line-card.locked{ opacity:0.45; cursor:default; }
  .line-radio{
    flex:0 0 26px; width:26px; height:26px; margin:0; accent-color: var(--brass-light); cursor:pointer;
  }
  .line-card.locked .line-radio{ cursor:default; }
  #linePicker.lineFullHighlight{ animation: lineFullPulse 0.8s ease-in-out 4; border-radius: 10px; }
  @keyframes lineFullPulse{
    0%,100%{ box-shadow: 0 0 0 0 rgba(224,102,90,0); }
    50%{ box-shadow: 0 0 0 6px rgba(224,102,90,0.45); }
  }
  .line-name{
    font-family:'Space Mono', monospace; font-size:11.5px; color: var(--glass); letter-spacing:0.5px;
    /* ---- Demande utilisateur - "on ne voit pas toujours la gare de
       destination ou pas entierement" : le nom de ligne (Origine ->
       Destination) etait tronque a l'ellipse (nowrap) dans les cartes a 2
       colonnes, coupant la gare d'arrivee. On laisse desormais le libelle
       passer a la ligne (le " -> " offre un point de coupure naturel) pour
       que la destination reste toujours entierement lisible. ---- */
    white-space:normal; overflow-wrap:break-word; line-height:1.25;
  }
  .line-meta{
    display:flex; gap:6px; flex-wrap:wrap; margin-top:3px;
  }
  .line-tag{
    font-family:'Space Mono', monospace; font-size:9px; color: var(--brass-light);
    background: rgba(200,162,74,0.1); border-radius:3px; padding:1px 5px;
    white-space:nowrap;
  }
  .line-req{
    font-family:'Space Mono', monospace; font-size:9px; color: var(--brass-light); margin-top:2px;
  }
  /* ---- Demande utilisateur - "les cartes de lignes dans deux boutons,
     lignes et liaison, qui ouvrent une modale a cocher et valider" : le
     picker n'affiche plus les grilles de cartes directement, seulement ces
     deux boutons (un par groupe), avec un resume de la selection en cours.
     La grille complete ne s'affiche que dans #lineModalBackdrop. ---- */
  .line-group-btn{
    display:flex; flex-direction:column; align-items:flex-start; gap:3px;
    width:100%; box-sizing:border-box; text-align:left; cursor:pointer;
    background: linear-gradient(180deg, var(--iron-2), var(--iron));
    border: 2px solid var(--brass-dark); border-radius:8px; padding:10px 13px;
    font-family:'Space Mono', monospace; transition: border-color 0.15s;
  }
  .line-group-btn:hover{ border-color: var(--brass-light); }
  .line-group-btn.has-selection{ border-color: var(--brass-light); }
  .line-group-btn-head{
    font-size:11px; color: var(--brass-light); letter-spacing:1px; text-transform:uppercase;
  }
  .line-group-btn-sub{
    font-size:12.5px; color: var(--glass); letter-spacing:0.3px;
    white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:100%;
  }
  @media (min-width: 1000px){
    #linePicker{ flex-direction:row; }
    .line-group-btn{ flex:1 1 0; min-width:0; }
  }
  /* ---- Modale de choix (ligne ou locomotive) : gabarit partage (classes
     .picker-modal-*), meme principe que #startHelpBackdrop/#startHelpCard -
     colonne unique par defaut, 2 colonnes des 560px pour la grille de
     lignes (#lineModalGrid), plein ecran sous 380px. ---- */
  .picker-modal-backdrop{
    position:absolute; inset:0; z-index:46;
    background: rgba(10,8,6,0.78);
    display:flex; align-items:center; justify-content:center;
    padding:18px;
  }
  .picker-modal-backdrop.hidden{ display:none; }
  .picker-modal-card{
    background: linear-gradient(180deg, var(--iron-2), var(--iron-3));
    border: 1px solid var(--brass-dark);
    border-radius:10px;
    box-shadow: 0 14px 40px rgba(0,0,0,0.55);
    max-width: 640px; width:100%; max-height:84vh; max-height:84dvh; overflow-y:auto;
    padding: 18px 20px 20px;
    position:relative; text-align:left;
    display:flex; flex-direction:column; gap:12px;
  }
  .picker-modal-card .close-x{
    position:absolute; top:8px; right:10px;
    background:none; border:none; color:var(--steam);
    font-size:18px; line-height:1; cursor:pointer; padding:4px;
  }
  .picker-modal-card .close-x:hover{ color: var(--glass); }
  .picker-modal-card h2{
    font-family:'Cinzel', serif; font-weight:700; letter-spacing:1px;
    font-size:17px; margin:0 26px 0 0; color:var(--brass-light);
  }
  .picker-modal-card .picker-modal-validate{ align-self:center; min-width:160px; }
  #locoModalGrid{
    display:flex; gap:8px; flex-wrap:wrap; justify-content:center;
  }
  @media (min-width: 560px){
    #lineModalGrid{ display:grid; grid-template-columns: repeat(2, 1fr); gap:8px; }
  }
  @media (max-width:380px){
    .picker-modal-backdrop{ padding:0; }
    .picker-modal-card{ max-width:100%; max-height:100%; height:100%; border-radius:0; border-width:0; }
  }
  /* ---- Mention "faites defiler et cliquez" pour la carte des lignes
       (demande utilisateur - "pareil pour la carte des lignes, il faut une
       mention" / "attention, que pour la version mobile") : masquee par
       defaut, reaffichee UNIQUEMENT sous le seuil mobile de ce fichier
       (600px, deja utilise par les autres @media (max-width:600px)
       ci-dessous) - jamais visible sur tablette/desktop, ou la carte reste
       assez grande pour que l'interaction (petit rond a cocher, cf.
       .line-radio) soit deja evidente. ---- */
  .pickerHint{ display:none; }
  @media (max-width:600px){
    .pickerHint{ display:block; }
  }


  /* ---- Ecran de demarrage responsive (demande utilisateur - "la page de
     choix des lignes est fouillie, il faut la reorganiser et veiller a ce
     qu'elle soit toujours responsive") : layout en grille adaptative, avec
     2 colonnes pour les lignes principales des 820px, 3 colonnes a 1200px.
     Les liaisons restent en colonne simple (peu de cartes, pas besoin de
     grille). Le reste du contenu (locomotive, multijoueur, missions)
     s'elargit proportionnellement. ---- */
  @media (min-width: 1000px){
    .subtitle{ max-width:580px; }
    #linePicker{
      max-width:720px;
    }
    #linePicker .line-cards-grid{
      display:grid;
      grid-template-columns: repeat(2, 1fr);
      gap:8px;
    }
    #locoPicker{ max-width:680px; }
    .mp-panel{ max-width:460px; }
    .leaderboard-panel{ max-width:460px; }
    #startActionBar{ max-width:420px; }
  }
  @media (min-width: 1500px){
    .subtitle{ max-width:780px; }
    #linePicker{
      max-width:1080px;
    }
    #linePicker .line-cards-grid{
      grid-template-columns: repeat(3, 1fr);
    }
    #locoPicker{ max-width:900px; }
  }

  .leaderboard-panel{
    width:100%; max-width:340px;
    background: linear-gradient(180deg, var(--iron-2), var(--iron));
    border: 1px solid var(--brass-dark);
    border-radius: 8px;
    padding: 7px 10px;
    text-align:left;
  }
  .leaderboard-panel .lb-title{
    font-family:'Space Mono', monospace; font-size:9px; color: var(--brass-light);
    letter-spacing:1px; text-transform:uppercase; margin-bottom:4px;
  }
  .leaderboard-panel .lb-empty{
    font-family:'Space Mono', monospace; font-size:10px; color: var(--steam);
  }
  .lb-row{
    display:flex; justify-content:space-between; gap:8px;
    font-family:'Space Mono', monospace; font-size:10.5px; color: var(--glass);
    padding:2px 0;
  }
  .lb-row .lb-rank{ color: var(--brass-light); width:16px; flex:0 0 auto; }
  .lb-row .lb-name{ flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .lb-row .lb-score{ color: var(--brass-light); font-weight:700; flex:0 0 auto; }
  .lb-row .lb-line{ color: var(--steam); font-size:9px; opacity:0.7; flex:0 0 auto; max-width:120px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

  .lb-tabs{ display:flex; gap:5px; margin-bottom:6px; }
  .lb-tab{
    flex:1; font-family:'Space Mono', monospace; font-size:9px; letter-spacing:0.5px; text-transform:uppercase;
    background: var(--iron-3); border: 1px solid var(--brass-dark); color: var(--steam);
    border-radius:4px; padding:4px 6px; cursor:pointer; text-align:center;
  }
  .lb-tab.active{ background: var(--brass-dark); color: var(--glass); border-color: var(--brass); }

  #logbookAchievements{
    display:flex; flex-direction:column; gap:5px; width:100%; max-width:320px;
    max-height: 220px; overflow-y:auto;
  }
  #logbookHistory{
    display:flex; flex-direction:column; gap:5px; width:100%; max-width:320px;
    max-height: 220px; overflow-y:auto;
  }
  .history-row{
    font-family:'Space Mono', monospace; font-size:11px; color: var(--steam);
    background: var(--iron-2); border: 1px solid var(--brass-dark); border-radius:5px;
    padding: 6px 10px; text-align:left; display:flex; justify-content:space-between; gap:8px;
  }
  .history-row .history-line{ flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color: var(--glass); }
  .history-row .history-score{ color: var(--brass-light); font-weight:700; flex:0 0 auto; }
  .achv-row{
    font-family:'Space Mono', monospace; font-size:11.5px; color: var(--steam);
    background: var(--iron-2); border: 1px solid var(--brass-dark); border-radius:5px;
    padding: 7px 10px; text-align:left;
  }
  .achv-row.unlocked{ color: var(--gold); border-color: var(--gold); }
  .loco-card{
    flex:1; min-width:96px;
    background: linear-gradient(180deg, var(--iron-2), var(--iron));
    border: 2px solid var(--brass-dark);
    border-radius: 8px;
    padding: 8px 6px;
    cursor:pointer;
    text-align:center;
    touch-action: manipulation;
  }
  .loco-card.selected{ border-color: var(--brass-light); box-shadow: 0 0 0 2px var(--brass-light) inset; }
  .loco-card.locked{ cursor:default; }
  .loco-card.locked.unaffordable{ opacity:0.45; }
  /* ---- Rond a cocher de selection de locomotive (demande utilisateur -
       "pour eviter les clics involontaires sur mobile et tablette, il faut
       que comme pour le choix des lignes, les options pour les locos...
       comportent des rond a cocher avant de pouvoir valider") : meme
       principe que .line-radio - seul ce petit rond est cliquable pour
       CHOISIR la machine, la carte entiere ne l'est plus (un simple contact
       pour arreter un defilement momentum ne selectionne donc plus rien par
       accident). ---- */
  .loco-radio{
    display:block; width:26px; height:26px; margin:0 auto 6px auto; accent-color: var(--brass-light); cursor:pointer;
  }
  .loco-card.locked .loco-radio{ cursor:default; }
  .loco-swatch{
    width:36px; height:20px; margin:0 auto 6px auto; border-radius:3px; border:1px solid rgba(0,0,0,0.4);
  }
  .loco-name{
    font-family:'Space Mono', monospace; font-size:10.5px; color: var(--glass); letter-spacing:0.5px;
  }
  .loco-req{
    font-family:'Space Mono', monospace; font-size:9px; color: var(--brass-light); margin-top:3px;
  }

  #wagonChoices, #loadChoices{
    display:flex; flex-direction:column; gap:10px; width:100%; max-width:320px;
  }
  .wagon-card{
    background: linear-gradient(180deg, var(--iron-2), var(--iron));
    border: 2px solid var(--brass-dark);
    border-radius: 8px;
    padding: 12px;
    text-align:left;
    /* ---- Demande utilisateur - "cocher avant de valider" : seul le petit
       rond (.wagon-radio) selectionne, plus la carte entiere - le curseur
       par defaut (pas pointer sur toute la carte) le rappelle visuellement,
       comme les cartes de ligne/loco. ---- */
    display:flex; align-items:center; gap:12px;
    font-family:'Cinzel', serif;
    touch-action: manipulation;
  }
  .wagon-radio{
    flex:0 0 26px; width:26px; height:26px; margin:0; accent-color: var(--brass-light); cursor:pointer;
  }
  .wagon-card-text{ flex:1 1 auto; min-width:0; }
  .wagon-card.selected{ border-color: var(--brass-light); box-shadow: 0 0 0 2px var(--brass-light) inset; }
  .wagon-card.wagon-rare{ border-color: var(--gold); box-shadow: 0 0 8px rgba(212,175,55,0.5); }
  .wagon-card.wagon-rare.selected{ box-shadow: 0 0 0 2px var(--gold) inset, 0 0 8px rgba(212,175,55,0.5); }
  .wagon-card.wagon-rare .wagon-name{ color: var(--gold); }
  .wagon-name{
    font-weight:700; color: var(--glass); font-size:15px; letter-spacing:1px;
  }
  .wagon-detail{
    font-family:'Space Mono', monospace; font-size:11px; color: var(--steam); margin-top:4px;
  }

  /* ---- Grille des missions : colonnes qui apparaissent naturellement
       des que la largeur disponible le permet (auto-fit), sans media
       query dediee pour le nombre de colonnes lui-meme.
       ---- Bug corrige (rapport utilisateur - "les cartes de mission
       sont decalees a gauche, [devraient etre] plus au centre les unes a
       cote des autres") : contrairement a TOUS ses freres/soeurs du
       meme ecran de demarrage (#linePicker, #locoPicker, .mp-panel,
       .leaderboard-panel - chacun plafonne a 340px de base, puis
       elargi progressivement via les memes seuils 1000px/1400px), cette
       grille n'avait ABSOLUMENT AUCUNE limite de largeur (juste
       `width:100%`) - elle s'etirait donc sur toute la largeur de
       `.overlay` (position:fixed, quasi toute la largeur de l'ecran),
       bien plus large que les autres blocs. Avec seulement 1 ou 2
       missions disponibles, la grille CSS (`auto-fit`) les calait alors
       au debut de cette tres large rangee plutot que de les centrer -
       d'ou l'impression de cartes "decalees a gauche" au lieu d'etre
       cote a cote, bien centrees, comme le reste de l'ecran. Meme
       plafond que #linePicker (740px puis 840px) applique ici. ---- */
  #missionsPoolList, #startMissionsList{
    display:grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap:10px;
    width:100%;
    max-width:340px;
    box-sizing:border-box;
  }
  @media (min-width: 1000px){
    #missionsPoolList, #startMissionsList{ max-width:720px; }
  }
  @media (min-width: 1500px){
    #missionsPoolList, #startMissionsList{ max-width:1080px; }
  }
  .mission-card{
    background: linear-gradient(180deg, var(--iron-2), var(--iron));
    border: 2px solid var(--brass-dark);
    border-radius: 8px;
    padding: 12px;
    text-align:left;
    font-family:'Cinzel', serif;
    width: 100%;
    box-sizing:border-box;
    display:flex;
    flex-direction:column;
    touch-action: manipulation;
  }
  /* ---- Le message d'aide ("Choisis une mission a reserver...") et le
       message "aucune mission" prennent toujours toute la largeur de la
       grille, jamais partages avec une carte sur la meme rangee. ---- */
  #missionsPoolList .mission-empty, #startMissionsList .mission-empty{
    grid-column: 1 / -1;
  }
  /* ---- Option "Aucune mission" (rond a cocher, coche par defaut) : prend
       toute la largeur de la grille, au-dessus des missions reelles. ---- */
  #startMissionsList .mission-none-option{ grid-column: 1 / -1; }
  .mission-card.mission-regulateur{ border-color: var(--gold); }
  .mission-card.mission-selected{ border-color: var(--brass-light); box-shadow: 0 0 8px rgba(212,175,55,0.4); }
  .mission-card.mission-locked-out{ opacity: 0.45; }
  /* ---- Rond a cocher des missions (demande utilisateur - "les missions
       aussi doivent etre cochees") : seul ce rond selectionne, comme les
       cartes de ligne/loco/wagon - un simple contact sur la carte ne reserve
       plus rien par accident. ---- */
  .mission-radio{
    display:block; width:26px; height:26px; margin:0 auto 6px auto; accent-color: var(--brass-light); cursor:pointer;
  }
  .mission-title{ font-weight:700; color: var(--glass); font-size:14px; letter-spacing:0.5px; }
  .mission-detail{ font-family:'Space Mono', monospace; font-size:11px; color: var(--steam); margin-top:4px; }
  .mission-accept-btn{ margin-top:auto; padding-top:8px; width:100%; }
  .mission-empty{ font-family:'Space Mono', monospace; font-size:12px; color: var(--steam); text-align:center; padding:10px; }
  .mission-active-banner{
    font-family:'Space Mono', monospace; font-size:11px; color: var(--gold);
    border:1px solid var(--brass-dark); border-radius:6px; padding:8px; margin:6px 0; text-align:center;
  }
  .mission-active-banner.mission-warn{ color:#e07a4f; border-color:#e07a4f; }
  /* ---- Bug corrige (rapport utilisateur - capture d'un petit cadre dore
       vide dans le hub de gare, entre les ressources et le bouton "Faire
       le plein") : `.hidden` est un utilitaire SCOPE dans ce fichier
       (ex. `.overlay.hidden`, `#raceCard .hidden`...), jamais une regle
       generique `.hidden{display:none}` - `#missionActiveBanner` porte
       bien la classe `hidden` par defaut (cf. HTML), mais sans regle
       `.mission-active-banner.hidden` dediee, cette classe n'avait
       strictement AUCUN EFFET : la div restait affichee en permanence,
       simplement vide de texte la plupart du temps (aucune mission
       active) - ne laissant visible que son cadre (bordure + padding),
       soit exactement ce petit rectangle dore sans contenu remonte en
       capture. ---- */
  .mission-active-banner.hidden{ display:none; }
  /* ================= FINITIONS VISUELLES (demande utilisateur - "plus
       beaux graphismes, par petites touches CSS") : purement additif, ne
       touche a aucun id ni a la structure existante - juste plus de
       matiere/profondeur sur ce qui existe deja. ================= */

  /* ---- Vignette de cabine : assombrit legerement les bords de la scene
       de conduite pour un effet plus "habitacle", sans jamais gener la
       lecture des elements (z-index bas, pointer-events desactives). ---- */
  #stage{
    position:relative;
  }
  #stage::after{
    content:"";
    position:absolute; inset:0; pointer-events:none; z-index:1;
    box-shadow: inset 0 0 90px rgba(0,0,0,0.55);
  }

  /* ---- Grain metallique tres subtil sur les panneaux iron (topbar,
       overlays, cartes) : casse le plat uniforme sans jamais nuire a la
       lisibilite du texte. ---- */
  #topbar, .overlay, .mission-card, .wagon-card, .loco-card, .leaderboard-panel{
    background-image:
      radial-gradient(circle at 20% 20%, rgba(255,255,255,0.025) 0%, transparent 45%),
      radial-gradient(circle at 80% 80%, rgba(0,0,0,0.12) 0%, transparent 50%);
    background-blend-mode: overlay;
  }

  /* ---- Cartes (mission/wagon/loco) : liseré brillant en haut + leger
       soulevement au survol/tap, pour une sensation plus tactile. ---- */
  .mission-card, .wagon-card, .loco-card{
    position:relative; overflow:hidden;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
  }
  .mission-card::before, .wagon-card::before, .loco-card::before{
    content:""; position:absolute; top:0; left:0; right:0; height:1px;
    background: linear-gradient(90deg, transparent, rgba(255,255,255,0.35), transparent);
  }
  .mission-card:active, .wagon-card:active, .loco-card:active{
    transform: translateY(1px) scale(0.995);
  }
  .loco-card.selected{ box-shadow: 0 0 0 2px var(--brass-light) inset, 0 0 14px rgba(212,175,55,0.35); }

  /* ---- Boutons plus tactiles : liseré brillant en haut du bouton "go"
       (effet bombe/laiton poli) en plus de l'ombre deja existante. ---- */
  button.go{ position:relative; overflow:hidden; }
  button.go::before{
    content:""; position:absolute; top:0; left:6%; right:6%; height:45%;
    background: linear-gradient(180deg, rgba(255,255,255,0.4), transparent);
    border-radius: 4px 4px 50% 50% / 4px 4px 12px 12px;
    pointer-events:none;
  }
  button.go-secondary{ position:relative; overflow:hidden; }
  button.go-secondary::before{
    content:""; position:absolute; top:0; left:0; right:0; height:1px;
    background: linear-gradient(90deg, transparent, rgba(255,255,255,0.25), transparent);
    pointer-events:none;
  }

  /* ---- Reflet de verre sur les cadrans : une fine bande diagonale
       claire, comme un reflet de vitre bombee, en plus du degrade radial
       deja en place. ---- */
  .dial::after{
    content:""; position:absolute; inset:0; border-radius:50%; pointer-events:none;
    background: linear-gradient(115deg, rgba(255,255,255,0.55) 0%, transparent 22%, transparent 100%);
    mix-blend-mode: soft-light;
  }

  /* ---- Gauges lineaires (charbon/eau/huile/usure) : liseré brillant
       assorti au theme laiton. ---- */
  .bar{ position:relative; overflow:hidden; }
  .bar::after{
    content:""; position:absolute; top:0; left:0; right:0; height:35%;
    background: linear-gradient(180deg, rgba(255,255,255,0.25), transparent);
    pointer-events:none;
  }

  /* ---- Scrollbars aux couleurs du theme (au lieu du gris par defaut du
       navigateur) sur toutes les listes deroulantes existantes. ---- */
  #logbookAchievements::-webkit-scrollbar, #logbookHistory::-webkit-scrollbar,
  .overlay::-webkit-scrollbar, #missionsPoolList::-webkit-scrollbar, #startMissionsList::-webkit-scrollbar{
    width: 8px;
  }
  #logbookAchievements::-webkit-scrollbar-track, #logbookHistory::-webkit-scrollbar-track,
  .overlay::-webkit-scrollbar-track, #missionsPoolList::-webkit-scrollbar-track, #startMissionsList::-webkit-scrollbar-track{
    background: var(--iron-3);
  }
  #logbookAchievements::-webkit-scrollbar-thumb, #logbookHistory::-webkit-scrollbar-thumb,
  .overlay::-webkit-scrollbar-thumb, #missionsPoolList::-webkit-scrollbar-thumb, #startMissionsList::-webkit-scrollbar-thumb{
    background: var(--brass-dark); border-radius: 4px;
  }
  #logbookAchievements::-webkit-scrollbar-thumb:hover, #logbookHistory::-webkit-scrollbar-thumb:hover,
  .overlay::-webkit-scrollbar-thumb:hover, #missionsPoolList::-webkit-scrollbar-thumb:hover, #startMissionsList::-webkit-scrollbar-thumb:hover{
    background: var(--brass);
  }

  /* ---- Titres (h1.title) : leger halo chaud assorti au fire, pour un
       rendu plus "enseigne gravee" que du texte plat. ---- */
  h1.title{
    text-shadow: 0 0 14px rgba(255, 122, 41, 0.18);
  }

  /* ---- Plaque signaletique (topbar) : legere lueur ambre sur le texte,
       comme un vieux cadran retro-eclaire. ---- */
  .plate b{ text-shadow: 0 0 6px rgba(233, 200, 120, 0.25); }

  /* ---- Bug corrige (rapport utilisateur - "c'est sur les deux premieres
  page que ça fonctionne pas plein ecran") : cette page avait DEJA son
  propre systeme de plein ecran, integre au HUD de cabine (plaquette
  "#fullscreenToggle" ci-dessus, aux cotes de CARTE/VUE/AIDE - demande
  utilisateur anterieure "on peut pas forcer le plein ecran, comme sur
  mobile ?"). Le bouton flottant generique ajoute ensuite sur les 3 pages
  faisait doublon AVEC CE SYSTEME EXISTANT sur cette page precise (jamais
  sur poste-regulation.html, qui n'avait rien de preexistant) - source de
  confusion. Le bouton flottant est retire d'ICI, seul subsiste
  #fullscreenToggle (deja fonctionnel). Le masquage de l'ascenseur en
  plein ecran (:fullscreen) reste utile quel que soit le bouton qui
  declenche la demande, donc conserve. ---- */
  html:fullscreen{ scrollbar-width:none; -ms-overflow-style:none; }
  html:fullscreen::-webkit-scrollbar{ width:0; height:0; display:none; }
  html:-webkit-full-screen{ scrollbar-width:none; -ms-overflow-style:none; }
  html:-webkit-full-screen::-webkit-scrollbar{ width:0; height:0; display:none; }
  html:-ms-fullscreen{ -ms-overflow-style:none; }
