/* ============================================================
   ASTRA GENESIS, DESIGN-SYSTEM.CSS
   v0.27.0, tokens et animations DA v2 "vivant & coloré".
   Portée volontairement limitée à l'écran Planète pour cette passe
   (PASSE 01 v2) : nouvelles variables --dv2-*, cartes .dv2-card,
   fond spatial animé, animations de la table hexagonale. N'écrase
   aucun token existant de css/01-tokens.css (zéro régression sur les
   autres écrans), garde les typos v0.14 (héritées, aucune redéfinition
   ici). Chargé après 01-tokens.css et avant 05-screens.css.
   v0.28.0 (PASSE 02) : section "BÂTIMENTS" ajoutée en fin de fichier,
   même méthode (nouvelles classes .bld-*, aucun token existant modifié).
   ============================================================ */

:root{
  /* ---------- catégories, DA v2 ---------- */
  --dv2-production: #4ADE80;
  --dv2-elec:        #FBBF24;
  --dv2-recherche:    #A78BFA;
  --dv2-defense:      #FB7185;
  --dv2-infra:        #38BDF8;
  --dv2-free:         #64748B;

  --dv2-card-bg:  #101826;
  --dv2-space:    #0B1020;

  --dv2-r-card: 14px;

  /* ---------- 8 couleurs de branche, écran Recherche (v0.52.0) ----------
     Réutilise les tokens existants là où la teinte demandée correspond
     déjà à une couleur du jeu (énergie=ambre, matériaux=vert/lime,
     bio=teal/cyan, xéno=violet, militaire=rose, diplomatie=ciel=
     --dv2-infra) ; seules 2 teintes n'existaient pas encore (cyber=bleu,
     logistique=orange), ajoutées ici. */
  --rs-blue:   #3B82F6;
  --rs-orange: #FB923C;
}

/* ================= cartes DA v2 (panneau droit, écran Planète) ================= */
.dv2-card{
  background:var(--dv2-card-bg);
  border:1px solid var(--line);
  border-top:3px solid var(--dv2-cat, var(--dv2-free));
  border-radius:var(--dv2-r-card);
  box-shadow:var(--shadow-deep);
  overflow:hidden;
  /* v0.27.0 : slide-in décalé de 60ms par carte au premier rendu de
     l'écran (voir .dv2-side .dv2-card:nth-child(n), css ci-dessous),
     jamais critique pour la lecture (état final = statique, cf. §7). */
  animation:dv2SlideIn .45s cubic-bezier(.2,.8,.2,1) both;
}
.dv2-side .dv2-card:nth-child(1){animation-delay:0ms;}
.dv2-side .dv2-card:nth-child(2){animation-delay:60ms;}
.dv2-side .dv2-card:nth-child(3){animation-delay:120ms;}
.dv2-side .dv2-card:nth-child(4){animation-delay:180ms;}
.dv2-side .dv2-card:nth-child(5){animation-delay:240ms;}
@keyframes dv2SlideIn{from{opacity:0;transform:translateX(14px);}to{opacity:1;transform:translateX(0);}}

.dv2-card.cat-production{--dv2-cat:var(--dv2-production);}
.dv2-card.cat-elec{--dv2-cat:var(--dv2-elec);}
.dv2-card.cat-recherche{--dv2-cat:var(--dv2-recherche);}
.dv2-card.cat-defense{--dv2-cat:var(--dv2-defense);}
.dv2-card.cat-infra{--dv2-cat:var(--dv2-infra);}
.dv2-card.cat-free{--dv2-cat:var(--dv2-free);}

/* ================= fond spatial + nébuleuse ================= */
.dv2-surface{
  position:relative;background:var(--dv2-space);border-radius:var(--r-lg);
  overflow:hidden;isolation:isolate;
}
.dv2-surface::before{
  /* nébuleuse douce, dérive très lente, purement décorative (jamais
     porteuse d'information, cf. §7 "lisible statique") */
  content:"";position:absolute;inset:-10%;z-index:0;pointer-events:none;
  background:
    radial-gradient(ellipse 50% 40% at 20% 25%, rgba(45,212,191,.16), transparent 70%),
    radial-gradient(ellipse 45% 35% at 80% 70%, rgba(217,70,239,.12), transparent 70%),
    radial-gradient(ellipse 40% 40% at 60% 15%, rgba(167,139,250,.10), transparent 70%);
  animation:dv2NebulaDrift 120s ease-in-out infinite alternate;
}
@keyframes dv2NebulaDrift{
  0%{transform:translate(0,0) scale(1);}
  100%{transform:translate(-3%,2%) scale(1.06);}
}

/* ================= vue de surface (fond planète) ================= */
.dv2-surface-bg{
  position:absolute;inset:0;z-index:1;
  /* v0.27.0 : assets/images/planet-temperate.webp posé en couche AU-DESSUS
     du dégradé spatial de repli. Si le fichier est absent (404), cette
     couche reste transparente et laisse voir le dégradé en dessous :
     ne bloque jamais, aucun JS nécessaire pour détecter sa présence. */
  background:
    linear-gradient(180deg, rgba(6,14,24,.4), rgba(6,14,24,.58) 55%, rgba(6,14,24,.8)),
    url('../assets/images/planet-temperate.webp') center 42% / cover no-repeat,
    radial-gradient(ellipse 80% 60% at 50% 30%, #16233a, transparent 70%),
    linear-gradient(160deg, #0B1020, #101826 70%);
  animation:dv2SlowZoom 60s ease-in-out infinite alternate;
}
@keyframes dv2SlowZoom{from{transform:scale(1);}to{transform:scale(1.05);}}

.dv2-clouds{position:absolute;inset:-20% -40%;z-index:2;pointer-events:none;}
.dv2-cloud-a,.dv2-cloud-b{
  position:absolute;inset:0;opacity:.15;filter:blur(18px);
  background:
    radial-gradient(ellipse 18% 10% at 15% 30%, #fff, transparent 70%),
    radial-gradient(ellipse 22% 12% at 55% 60%, #fff, transparent 70%),
    radial-gradient(ellipse 16% 9% at 85% 20%, #fff, transparent 70%);
}
.dv2-cloud-a{animation:dv2CloudA 90s linear infinite;}
.dv2-cloud-b{animation:dv2CloudB 140s linear infinite;opacity:.12;transform:scale(1.3);}
@keyframes dv2CloudA{from{transform:translateX(-15%);}to{transform:translateX(15%);}}
@keyframes dv2CloudB{from{transform:translateX(10%) scale(1.3);}to{transform:translateX(-10%) scale(1.3);}}

.dv2-sweep{
  position:absolute;inset:0;z-index:3;pointer-events:none;opacity:.08;
  background:linear-gradient(100deg, transparent 40%, rgba(45,212,191,.9) 50%, transparent 60%);
  background-size:300% 100%;
  animation:dv2Sweep 8s linear infinite;
}
@keyframes dv2Sweep{from{background-position:100% 0;}to{background-position:-40% 0;}}

.dv2-ship{
  position:absolute;top:18%;left:-8%;z-index:4;pointer-events:none;
  width:26px;height:12px;opacity:0;
  animation:dv2Ship 25s linear infinite;
}
.dv2-ship svg{width:100%;height:100%;filter:drop-shadow(0 0 6px rgba(45,212,191,.6));}
@keyframes dv2Ship{
  0%{opacity:0;transform:translate(0,0);}
  4%{opacity:.85;}
  46%{opacity:.85;}
  50%{opacity:0;transform:translate(126vw,6vh);}
  100%{opacity:0;transform:translate(126vw,6vh);}
}

/* ================= en-tête surface (nom planète, biome, bonheur) ================= */
.dv2-surface-head{
  position:relative;z-index:5;display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:calc(14px*var(--scale)) calc(16px*var(--scale)) 0;
}
.dv2-planet-id{display:flex;align-items:center;gap:10px;flex-wrap:wrap;}
.dv2-planet-id b{font-family:var(--font-mono);letter-spacing:.04em;color:var(--ink-1);font-size:.92rem;}
.dv2-biome-badge{
  display:inline-flex;align-items:center;gap:5px;font-family:var(--font-mono);font-size:.62rem;
  color:var(--dv2-production);background:rgba(74,222,128,.12);border:1px solid rgba(74,222,128,.35);
  border-radius:999px;padding:2px 8px;
}
.dv2-biome-badge i{width:6px;height:6px;border-radius:50%;background:var(--dv2-production);animation:dv2BadgePulse 2.4s ease-in-out infinite;}
@keyframes dv2BadgePulse{0%,100%{opacity:.5;}50%{opacity:1;}}
.dv2-happy-gauge{display:flex;align-items:center;gap:6px;font-family:var(--font-mono);font-size:.68rem;color:var(--ink-2);}
.dv2-happy-gauge .bar{width:64px;}

/* ================= dock de production (v0.27.1) =================
   v0.60.1 : la rangée est ANCRÉE en bas du render et BORNÉE à la zone
   principale (elle s'arrête avant la colonne droite, jamais dessous),
   au-dessus de la barre de navigation translucide. Les variables
   --dv2-side-w / --dv2-safe-bottom sont posées sur .holo-stage (section
   "Colonie immersive" plus bas), un seul endroit à retoucher si la
   largeur de la colonne change. */
.dv2-dock{
  position:absolute;z-index:5;display:flex;gap:10px;
  left:calc(16px*var(--scale));
  right:calc(var(--dv2-side-w, 316px) + 28px*var(--scale));
  bottom:var(--dv2-safe-bottom, calc(var(--nav-h) + 6px));
}
.dv2-dock-block{
  flex:1 1 0;min-width:0;background:var(--glass-dark);border:1px solid var(--glass-border);border-top:3px solid var(--amber);
  border-radius:var(--dv2-r-card);padding:9px 12px;cursor:pointer;
  backdrop-filter:blur(var(--glass-blur));-webkit-backdrop-filter:blur(var(--glass-blur));
  animation:dv2SlideIn .4s cubic-bezier(.2,.8,.2,1) both;
}
.dv2-dock-block:nth-child(1){animation-delay:0ms;}
.dv2-dock-block:nth-child(2){animation-delay:60ms;}
.dv2-dock-block:nth-child(3){animation-delay:120ms;}
.dv2-dock-block:hover{border-color:var(--amber);box-shadow:0 0 14px rgba(245,158,11,.2);}
.dv2-dock-head{display:flex;align-items:center;gap:6px;margin-bottom:4px;}
.dv2-dock-title{font-family:var(--font-mono);font-size:.66rem;letter-spacing:.04em;color:var(--ink-2);text-transform:uppercase;flex:1;}
.dv2-dock-badge{width:7px;height:7px;border-radius:50%;background:var(--rose);flex:none;}
.dv2-dock-badge.pulse{animation:dv2DockBadgePulse 1s ease-in-out infinite;}
@keyframes dv2DockBadgePulse{0%,100%{box-shadow:0 0 0 0 rgba(248,113,113,.6);opacity:1;}50%{box-shadow:0 0 0 5px rgba(248,113,113,0);opacity:.7;}}
.dv2-dock-carousel{display:flex;align-items:center;gap:4px;font-family:var(--font-mono);font-size:.6rem;color:var(--ink-3);}
.dv2-dock-arrow{
  background:none;border:1px solid var(--line-strong);border-radius:5px;color:var(--ink-2);
  width:16px;height:16px;line-height:1;cursor:pointer;font-size:.7rem;padding:0;
}
.dv2-dock-arrow:hover{border-color:var(--amber);color:var(--amber);}
.dv2-dock-item{display:flex;flex-direction:column;gap:4px;}
.dv2-dock-lab{display:flex;justify-content:space-between;gap:8px;font-size:.72rem;color:var(--ink-1);}
.dv2-dock-lab span:first-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.dv2-dock-sub{color:var(--ink-3);font-size:.62rem;flex:none;}
.dv2-dock-progress{display:flex;align-items:center;gap:8px;}
.dv2-dock-progress .bar{flex:1;}
.dv2-dock-progress .bar i{background:linear-gradient(90deg,var(--amber-dim),var(--amber));transition:width .6s cubic-bezier(.2,.8,.2,1);}
.dv2-dock-time{font-family:var(--font-mono);font-size:.62rem;color:var(--ink-2);flex:none;}
.dv2-dock-rush{width:100%;justify-content:center;margin-top:2px;padding:4px 6px;font-size:.66rem;}
.dv2-dock-empty{color:var(--ink-3);font-size:.72rem;margin:2px 0 0;}
@media(max-width:1000px){.dv2-dock{position:static;margin-top:10px;flex-wrap:wrap;}}

/* ================= légende, pills colorées =================
   v0.60.1 : rendue à l'intérieur du panneau CONSTRUCTIONS du dock
   (AG.dockBlockHTML), plus en bloc séparé sous le render. */
.dv2-legend{
  position:relative;z-index:5;display:flex;gap:6px;flex-wrap:wrap;margin-top:8px;
}
.dv2-legend-pill{
  display:inline-flex;align-items:center;gap:6px;font-family:var(--font-mono);font-size:.62rem;color:var(--ink-2);
  background:rgba(16,24,38,.7);border:1px solid var(--line);border-radius:999px;padding:3px 9px;
}
.dv2-legend-pill i{width:8px;height:8px;border-radius:3px;background:var(--dv2-dot,var(--dv2-free));display:inline-block;}
.dv2-legend-pill.cat-production i{--dv2-dot:var(--dv2-production);}
.dv2-legend-pill.cat-elec i{--dv2-dot:var(--dv2-elec);}
.dv2-legend-pill.cat-recherche i{--dv2-dot:var(--dv2-recherche);}
.dv2-legend-pill.cat-defense i{--dv2-dot:var(--dv2-defense);}
.dv2-legend-pill.cat-infra i{--dv2-dot:var(--dv2-infra);}
.dv2-legend-pill.cat-free i{--dv2-dot:var(--dv2-free);}

/* ================= hexagones, DA v2 =================
   v0.60.1 : plus de fond opaque par catégorie (le terrain doit rester
   visible à travers la grille, demande explicite) ni de relief 3D. La
   couleur de catégorie ne vit plus que sur la TUILE d'icône (.hex-tile,
   css/05-screens.css) via --dv2-cat, et sur le contour au survol. */
.hex.dv2-cat-production:hover{--hex-stroke:var(--dv2-production);--hex-fill:color-mix(in srgb, var(--dv2-production) 12%, transparent);}
.hex.dv2-cat-elec:hover{--hex-stroke:var(--dv2-elec);--hex-fill:color-mix(in srgb, var(--dv2-elec) 12%, transparent);}
.hex.dv2-cat-recherche:hover{--hex-stroke:var(--dv2-recherche);--hex-fill:color-mix(in srgb, var(--dv2-recherche) 12%, transparent);}
.hex.dv2-cat-defense:hover{--hex-stroke:var(--dv2-defense);--hex-fill:color-mix(in srgb, var(--dv2-defense) 12%, transparent);}
.hex.dv2-cat-infra:hover{--hex-stroke:var(--dv2-infra);--hex-fill:color-mix(in srgb, var(--dv2-infra) 12%, transparent);}
/* un hexagone bâti garde un contour de sa catégorie, même au repos */
.hex.filled{--hex-stroke:color-mix(in srgb, var(--dv2-cat, var(--cyan)) 45%, transparent);}

/* anneau de progression (construction en cours), posé autour de la tuile */
.hex.dv2-constructing{cursor:default;}
.hex.dv2-constructing .dv2-ring{
  position:absolute;z-index:0;
  width:calc(54px*var(--scale));height:calc(54px*var(--scale));border-radius:50%;
  background:conic-gradient(var(--dv2-production) calc(var(--dv2-pct,0)*1%), rgba(255,255,255,.10) 0);
  -webkit-mask:radial-gradient(farthest-side, transparent calc(100% - 4px), #000 calc(100% - 3px));
  mask:radial-gradient(farthest-side, transparent calc(100% - 4px), #000 calc(100% - 3px));
  animation:dv2RingPulse 1.6s ease-in-out infinite;
}
@keyframes dv2RingPulse{0%,100%{opacity:.85;}50%{opacity:1;}}

/* célébration fin de construction (§6) */
.hex.dv2-celebrate .hex-tile{
  animation:dv2Pop .6s cubic-bezier(.34,1.56,.64,1) both;
}
@keyframes dv2Pop{0%{transform:scale(.8);}70%{transform:scale(1.08);}100%{transform:scale(1);}}
.hex.dv2-celebrate::after{
  content:"";position:absolute;inset:-10%;z-index:7;pointer-events:none;
  background:
    radial-gradient(circle 3px at 20% 30%, #fff, transparent),
    radial-gradient(circle 3px at 75% 20%, var(--dv2-production), transparent),
    radial-gradient(circle 3px at 60% 75%, #fff, transparent),
    radial-gradient(circle 3px at 30% 80%, var(--dv2-production), transparent),
    radial-gradient(circle 3px at 85% 65%, #fff, transparent);
  animation:dv2Sparkle .6s ease-out both;
}
@keyframes dv2Sparkle{0%{opacity:0;transform:scale(.4);}40%{opacity:1;}100%{opacity:0;transform:scale(1.3);}}

/* ================= carte Mission (façon carte de quête) ================= */
.dv2-mission-step{display:flex;align-items:flex-start;gap:8px;padding:6px 0;}
.dv2-mission-check{
  flex:none;width:16px;height:16px;border-radius:5px;margin-top:1px;
  border:1px solid var(--line-strong);display:flex;align-items:center;justify-content:center;
  font-size:.6rem;color:transparent;transition:background .2s ease,border-color .2s ease;
}
.dv2-mission-step.done .dv2-mission-check{
  background:var(--dv2-production);border-color:var(--dv2-production);color:#03210f;
  animation:dv2CheckPop .35s cubic-bezier(.34,1.56,.64,1) both;
}
@keyframes dv2CheckPop{from{transform:scale(.5);}to{transform:scale(1);}}
.dv2-mission-label{font-size:.8rem;color:var(--ink-2);line-height:1.35;}
.dv2-mission-step.done .dv2-mission-label{color:var(--ink-3);text-decoration:line-through;text-decoration-color:rgba(100,125,150,.5);}
.dv2-mission-step.current .dv2-mission-label{color:var(--ink-1);font-weight:600;}
.dv2-mission-reward{
  display:flex;align-items:center;gap:6px;margin-top:10px;padding-top:10px;border-top:1px dashed rgba(255,255,255,.08);
  font-family:var(--font-mono);font-size:.7rem;color:var(--amber);
}

/* ================= carte Signes vitaux (barres animées) ================= */
.dv2-vital-bar{margin:4px 0 10px;}
.dv2-vital-bar .bar{transition:none;} /* la transition vit sur .bar i (largeur), déjà .5s dans 03-components.css, proche des .6s demandés */
.dv2-vital-bar .bar i{transition:width .6s cubic-bezier(.2,.8,.2,1);}
.dv2-vital-bar.elec .bar i{background:linear-gradient(90deg, var(--amber-dim), var(--dv2-elec));}
.dv2-vital-bar.happy .bar i{background:linear-gradient(90deg, var(--rose), var(--amber), var(--dv2-production));}

/* ================= carte Conseiller ================= */
.dv2-advisor-dot{position:relative;}
.advisor-row.critique .dv2-advisor-dot{animation:dv2PulseCritical 1.4s ease-in-out infinite;}
@keyframes dv2PulseCritical{0%,100%{box-shadow:0 0 0 0 rgba(248,113,113,.55);}50%{box-shadow:0 0 0 5px rgba(248,113,113,0);}}
.advisor-row.alerte .dv2-advisor-dot{animation:dv2PulseAlert 2s ease-in-out infinite;}
@keyframes dv2PulseAlert{0%,100%{box-shadow:0 0 0 0 rgba(245,158,11,.4);}50%{box-shadow:0 0 0 4px rgba(245,158,11,0);}}

/* ================= carte Orbite ================= */
.dv2-orbit-visual{position:relative;width:100%;height:70px;margin-bottom:8px;display:flex;align-items:center;justify-content:center;}
.dv2-orbit-planet{width:34px;height:34px;border-radius:50%;background:radial-gradient(circle at 35% 30%, #8fd6c8, var(--cyan-dim) 70%);box-shadow:0 0 18px rgba(45,212,191,.35);}
.dv2-orbit-ring{position:absolute;width:64px;height:64px;border:1px dashed rgba(45,212,191,.3);border-radius:50%;animation:dv2OrbitRotate 12s linear infinite;}
.dv2-orbit-ring i{position:absolute;top:-3px;left:50%;width:6px;height:6px;margin-left:-3px;border-radius:50%;background:var(--cyan);box-shadow:0 0 6px rgba(45,212,191,.8);}
@keyframes dv2OrbitRotate{from{transform:rotate(0);}to{transform:rotate(360deg);}}
.dv2-orbit-locked{opacity:.5;}
.dv2-orbit-locked .k::before{content:"🔒 ";}

/* ================= carte Colonies (vignettes) ================= */
.dv2-colony-thumb{
  display:flex;align-items:center;gap:8px;padding:8px;border:1px solid var(--line);border-radius:10px;background:rgba(255,255,255,.02);
}
.dv2-colony-thumb .dv2-thumb-art{width:30px;height:30px;border-radius:7px;background:linear-gradient(160deg, var(--cyan-dim), var(--hull-2));flex:none;}
.dv2-colony-thumb .dv2-thumb-txt{flex:1;font-size:.76rem;color:var(--ink-2);}
.dv2-colony-thumb .dv2-thumb-txt b{color:var(--ink-1);display:block;font-size:.8rem;}

/* ============================================================
   ÉCRAN PLANÈTE, "Colonie immersive" (v0.60.0)
   Render plein cadre (plus de carte encadrée), panneaux flottants
   translucides, bloc d'identité de colonie + widgets cosmétiques.
   Charte inchangée (navy/teal), aucune nouvelle teinte bleue : la
   vignette et les dégradés de bord réutilisent --dv2-space/--void-2.
   ============================================================ */

/* ---------- plein cadre : le render occupe toute la zone de jeu ----------
   v0.60.1 : le render descend jusqu'au bas du viewport, DERRIÈRE la
   barre de navigation qui flotte dessus en translucide (plus de bande
   noire sous l'image). Les éléments posés dessus (dock, colonne droite)
   s'arrêtent, eux, au-dessus de la nav. */
.screen.dv2-fullbleed{padding:0;overflow:hidden;}
/* Les deux mesures partagées de l'écran sont déclarées sur l'ANCÊTRE
   COMMUN : la colonne droite est un frère du render, pas un enfant, et
   n'hériterait pas de variables posées sur .holo-stage (bug corrigé en
   cours de chantier : la colonne débordait alors de 172px sous le
   viewport, `bottom` étant invalide). */
.dv2-fullbleed .planet-wrap.dv2{
  position:relative;height:100%;display:block;
  /* v0.60.3 : la colonne suit la largeur de la fenêtre,
     clamp(min, %, max). La valeur réelle est posée en style inline par
     AG.applyColonyRender depuis AG.COLONY_RENDER.sideWidth
     (js/00n-colony-layout.js) : celle-ci n'est qu'un repli si le JS n'a
     pas encore tourné, et garde les mêmes bornes.
     La rangée de files remonte franchement au-dessus de la barre de
     navigation (marge nette d'environ 14px, plus aucun contact). */
  --dv2-side-w: clamp(300px, 22%, 420px);
  /* +19 et non +14 : la barre de navigation dessine un peu plus haut que
     --nav-h (elle a son propre padding), la marge NETTE mesurée à
     l'écran entre les files et la barre vaut donc environ 14px. */
  --dv2-safe-bottom: calc(var(--nav-h) + 19px*var(--scale));
}
.dv2-fullbleed .holo-stage{position:absolute;inset:0;border-radius:0;border:none;min-height:0;}
/* render NET : ni nuages flous, ni balayage, ni nébuleuse, ni voile
   global sur l'image (demande explicite v0.60.1). Seule la vignette de
   bord subsiste, pour la lisibilité du HUD et des panneaux. */
.dv2-fullbleed .dv2-clouds,
.dv2-fullbleed .dv2-sweep,
.dv2-fullbleed .stage-glow,
.dv2-fullbleed .ring-fx,
.dv2-fullbleed .dv2-surface::before{display:none;}
.dv2-fullbleed .dv2-surface-bg{
  animation:none;transform:none;
  /* v0.68.0 : --screen-bg = fond numéroté (js/00y-backgrounds.js) */
  background:
    var(--screen-bg, url('../assets/images/planet-temperate.webp')) center 45% / cover no-repeat,
    linear-gradient(160deg, #0B1020, #101826 70%);
}

/* ---------- éclairage : voile navy RADIAL (v0.60.2) ----------
   Deux couches superposées, jamais un assombrissement uniforme :
     1. le PROJECTEUR : voile léger au centre (--veil-center) qui monte
        jusqu'à --veil-edge sur les côtés, sur un rayon --spot-r centré
        en --spot-x/--spot-y (les dômes, pas le milieu géométrique) ;
     2. la VIGNETTE de bord, conservée, qui referme les quatre côtés.
   Les valeurs viennent d'AG.COLONY_RENDER (js/00n-colony-layout.js),
   posées par AG.applyColonyRender : aucun réglage n'est écrit ici, les
   repères ci-dessous ne sont que des replis si le JS n'a pas encore
   tourné. */
.dv2-spotlight{
  position:absolute;inset:0;z-index:3;pointer-events:none;
  background:radial-gradient(
    ellipse var(--spot-rx, 42%) var(--spot-ry, 58%) at var(--spot-x, 44%) var(--spot-y, 56%),
    rgba(6,10,18,var(--veil-center, .34)) 0%,
    rgba(6,10,18,calc((var(--veil-center, .34) + var(--veil-edge, .78)) / 2)) 64%,
    rgba(6,10,18,var(--veil-edge, .78)) 100%);
  opacity:var(--bg-veil, 1);
}
.dv2-vignette{
  position:absolute;inset:0;z-index:4;pointer-events:none;
  opacity:var(--bg-veil, 1);
  background:
    linear-gradient(180deg, rgba(6,10,18,.72) 0%, rgba(6,10,18,.22) 9%, transparent 22%, transparent 76%, rgba(6,10,18,.5) 96%, rgba(6,10,18,.7) 100%),
    linear-gradient(90deg, rgba(6,10,18,.55) 0%, rgba(6,10,18,.12) 10%, transparent 22%, transparent 78%, rgba(6,10,18,.3) 92%, rgba(6,10,18,.5) 100%);
}

/* ---------- colonne droite : panneaux flottants translucides ---------- */
.dv2-fullbleed .side-stack{
  position:absolute;top:calc(12px*var(--scale));right:calc(14px*var(--scale));
  bottom:var(--dv2-safe-bottom);
  width:var(--dv2-side-w, calc(316px*var(--scale)));z-index:30;overflow-y:auto;padding-right:2px;
  gap:calc(9px*var(--scale));
}
/* v0.61.1 : barres de défilement MASQUÉES sur les écrans Planète et
   Bâtiments (toutes zones), le défilement molette, glisser et clavier
   reste natif. Passe devant la règle globale de css/02-base.css par
   spécificité, sans !important. */
.screen.dv2-fullbleed, .screen.dv2-fullbleed *,
.screen.bld-fullbleed, .screen.bld-fullbleed *,
.screen.fgx-fullbleed, .screen.fgx-fullbleed *{scrollbar-width:none;}
.screen.dv2-fullbleed::-webkit-scrollbar, .screen.dv2-fullbleed *::-webkit-scrollbar,
.screen.bld-fullbleed::-webkit-scrollbar, .screen.bld-fullbleed *::-webkit-scrollbar,
.screen.fgx-fullbleed::-webkit-scrollbar, .screen.fgx-fullbleed *::-webkit-scrollbar{display:none;}

/* ---------- couches de contraste, couche 3 TEXTE (v0.62.3) ----------
   Les écrans à render plein cadre surchargent les jetons de texte
   et d'accent par les valeurs de couche (css/01-tokens.css) : aucun texte
   gris foncé (--ink-3 d'origine, 2.6:1 sur panneau) ne reste sur ces
   écrans, --ink-3 pointe le 3e niveau de couche --layer-ink-3 (v0.71.1,
   il retombait par erreur sur le secondaire). Seule source de cette
   surcharge, Quêtes compris (v0.71.1, plus de copie dans
   css/11-quests.css). Portée : l'écran seul, le HUD, la nav, les
   modales et les tooltips (hors .screen) ne changent pas. */
.screen.dv2-fullbleed, .screen.bld-fullbleed, .screen.fgx-fullbleed, .screen.qx-fullbleed{
  /* couleur héritée : sans elle, un texte sans couleur propre garde
     l'--ink-1 d'origine résolu sur <body> (contrôle navigateur) */
  color: var(--layer-ink-1);
  --ink-1: var(--layer-ink-1);
  --ink-2: var(--layer-ink-2);
  --ink-3: var(--layer-ink-3);
  --cyan:  var(--layer-accent);
  --rose:  var(--layer-alert);
}
.dv2-fullbleed .side-stack .dv2-card{
  background:var(--glass-dark);backdrop-filter:blur(var(--glass-blur));-webkit-backdrop-filter:blur(var(--glass-blur));
  animation:none; /* v0.60.1 : plus de slide-in décalé, l'écran s'ouvre déjà en fondu */
  /* v0.62.3, couche 2 : bordure fine partagée, le liseré de catégorie
     du haut (.dv2-card) est conservé. */
  border-left-color:var(--glass-border);border-right-color:var(--glass-border);border-bottom-color:var(--glass-border);
  /* La colonne est un conteneur flex : sans ça, les cartes se font
     ÉCRASER pour tenir dans la hauteur disponible, et leur
     `overflow:hidden` coupe le contenu en plein milieu (bouton tutoriel
     amputé, 2 lignes de Signes vitaux sur 6). Chacune garde donc sa
     hauteur naturelle, et c'est la COLONNE qui défile (D2 : jamais de
     troncature sèche). */
  flex:0 0 auto;
}
/* ---------- densité de la colonne droite (v0.60.1) ----------
   Cible : lignes compactes (~30px), valeurs monospace alignées à droite,
   les 5 cartes visibles d'un coup à 1080p sans troncature. Portée
   limitée à cet écran : aucun autre écran n'utilise .dv2-fullbleed. */
.dv2-fullbleed .side-stack{gap:calc(6px*var(--scale));}
.dv2-fullbleed .side-stack .panel-head{
  padding:calc(5px*var(--scale)) calc(12px*var(--scale));font-size:.72rem;
}
.dv2-fullbleed .side-stack .panel-body{padding:calc(5px*var(--scale)) calc(12px*var(--scale));}
.dv2-fullbleed .side-stack .panel-body > p{font-size:.76rem;line-height:1.35;}
.dv2-fullbleed .side-stack .mini-row{
  padding:calc(4px*var(--scale)) 0;font-size:.76rem;min-height:calc(28px*var(--scale));
  gap:10px;
}
/* la valeur ne passe jamais à la ligne : c'est elle qui faisait des
   lignes de 52px dans ORBITE ("verrouillée, palier IV"). */
.dv2-fullbleed .side-stack .mini-row .v{
  font-family:var(--font-mono);text-align:right;font-size:.72rem;white-space:nowrap;flex:none;
}
.dv2-fullbleed .side-stack .advisor-row{padding:calc(6px*var(--scale)) 0;}
.dv2-fullbleed .side-stack .advisor-msg{font-size:.75rem;line-height:1.3;}
.dv2-fullbleed .side-stack .dv2-mission-step{padding:calc(3px*var(--scale)) 0;}
.dv2-fullbleed .side-stack .dv2-mission-label{font-size:.76rem;}
.dv2-fullbleed .side-stack .dv2-mission-reward{font-size:.72rem;padding:calc(5px*var(--scale)) calc(8px*var(--scale));}
.dv2-fullbleed .side-stack .btn.sm{padding:calc(6px*var(--scale)) calc(10px*var(--scale));font-size:.72rem;}
.dv2-fullbleed .side-stack .dv2-orbit-visual{height:calc(34px*var(--scale));margin-bottom:2px;}
.dv2-fullbleed .side-stack .dv2-orbit-planet{width:24px;height:24px;}
.dv2-fullbleed .side-stack .dv2-orbit-ring{width:46px;height:46px;}
.dv2-fullbleed .side-stack .dv2-colony-thumb{padding:6px;}
.dv2-fullbleed .side-stack .dv2-colony-thumb .dv2-thumb-art{width:26px;height:26px;}

/* ---------- panneaux repliables (v0.60.2) ----------
   Chevron à droite de l'en-tête ; replié, le corps disparaît et seul
   l'en-tête reste. Voir AG.initPanelCollapse (js/04-screen-planet.js)
   et js/00o-ui-prefs.js pour la persistance. */
.dv2-fullbleed .side-stack .panel-head{display:flex;align-items:center;gap:8px;}
.dv2-fullbleed .side-stack .panel-head .eyebrow{margin-left:auto;}
.panel-collapse{
  flex:none;width:22px;height:22px;padding:0;margin-left:2px;
  display:flex;align-items:center;justify-content:center;
  background:transparent;border:1px solid transparent;border-radius:7px;
  color:var(--ink-3);cursor:pointer;transition:.15s;
}
.panel-collapse svg{width:13px;height:13px;transition:transform .18s ease;}
.panel-collapse:hover{color:var(--cyan);border-color:rgba(45,212,191,.35);background:rgba(45,212,191,.08);}
.dv2-card.collapsed .panel-collapse svg{transform:rotate(-90deg);}
.dv2-card.collapsed .panel-body{display:none;}

/* icône par ligne dans SIGNES VITAUX (cible) */
.vs-row .k{display:flex;align-items:center;gap:8px;}
.vs-ic{
  width:calc(16px*var(--scale));height:calc(16px*var(--scale));flex:none;
  display:inline-flex;align-items:center;justify-content:center;color:var(--cyan);opacity:.85;
}
.vs-ic svg{width:100%;height:100%;}
@media(max-width:1000px){
  .dv2-fullbleed .side-stack{position:static;width:auto;height:auto;overflow:visible;margin-top:10px;}
  .dv2-fullbleed .holo-stage{position:relative;min-height:calc(420px*var(--scale));}
  .dv2-fullbleed .planet-wrap.dv2{height:auto;}
  .screen.dv2-fullbleed{overflow-y:auto;padding:var(--pad-lg) var(--pad-lg) var(--nav-gap);}
  /* en dessous de 1000px, le panneau droit repasse sous le render (règle
     ci-dessus) : les widgets flottants doivent suivre le même repli,
     sinon ils se superposent à l'identité/au dock sur une largeur trop
     étroite pour --dv2-side-w. Rangés en ligne statique sous l'identité,
     rosace masquée (purement décorative). */
  .dv2-fullbleed .dv2-rosette{display:none;}
  .dv2-fullbleed .dv2-identity{position:static;margin-bottom:8px;}
  .dv2-fullbleed .dv2-render-widgets{position:static;margin:0 0 8px calc(16px*var(--scale));}
  .dv2-fullbleed .dv2-minglobe{
    position:static;width:calc(34px*var(--scale));height:calc(34px*var(--scale));
    margin:0 0 8px calc(16px*var(--scale));
  }
}

/* ---------- identité de colonie (haut-gauche) ---------- */
.dv2-rosette{
  position:absolute;top:calc(-40px*var(--scale));left:calc(-40px*var(--scale));z-index:2;pointer-events:none;
  width:calc(220px*var(--scale));height:calc(220px*var(--scale));opacity:.14;
  background:repeating-conic-gradient(var(--cyan-dim) 0deg 4deg, transparent 4deg 18deg);
  border-radius:50%;mask:radial-gradient(circle, #000 55%, transparent 78%);
  -webkit-mask:radial-gradient(circle, #000 55%, transparent 78%);
}
.dv2-identity{
  position:absolute;top:calc(16px*var(--scale));left:calc(16px*var(--scale));z-index:31;
  display:flex;flex-direction:column;gap:6px;max-width:calc(280px*var(--scale));
}
.dv2-id-card{
  display:flex;align-items:center;gap:10px;padding:calc(9px*var(--scale)) calc(12px*var(--scale));
  background:var(--glass-dark);backdrop-filter:blur(var(--glass-blur));-webkit-backdrop-filter:blur(var(--glass-blur));
  border:1px solid var(--glass-border);border-radius:var(--dv2-r-card);box-shadow:var(--shadow-deep);
}
.dv2-id-thumb{
  width:calc(40px*var(--scale));height:calc(40px*var(--scale));border-radius:50%;flex:none;
  background:radial-gradient(circle at 35% 30%, #8fd6c8, var(--cyan-dim) 70%);box-shadow:0 0 14px rgba(45,212,191,.35);
}
.dv2-id-txt{flex:1;min-width:0;}
.dv2-id-name{display:flex;align-items:center;gap:6px;font-family:var(--font-mono);font-weight:700;color:var(--ink-1);font-size:.92rem;}
.dv2-id-online{width:7px;height:7px;border-radius:50%;background:var(--dv2-production);box-shadow:0 0 6px var(--dv2-production);flex:none;}
.dv2-id-coord{font-family:var(--font-mono);font-size:.66rem;color:var(--ink-3);letter-spacing:.03em;}
.dv2-id-sub{font-size:.68rem;color:var(--ink-3);}
.dv2-id-sub b{color:var(--cyan);}

/* ---------- sélecteur de colonie (déroulant) ----------
   v0.60.1, forme cible : nom de la colonie courante + badge de tier +
   "Colonie" + chevron, sur une barre large sous la carte d'identité. */
.dv2-colony-select{
  display:flex;align-items:center;gap:10px;cursor:pointer;
  padding:calc(8px*var(--scale)) calc(14px*var(--scale));
  background:var(--glass-dark);backdrop-filter:blur(var(--glass-blur));-webkit-backdrop-filter:blur(var(--glass-blur));
  border:1px solid var(--glass-border);border-radius:calc(12px*var(--scale));
  font-family:var(--font-display);font-size:.8rem;letter-spacing:.08em;color:var(--ink-1);
  transition:border-color .15s,color .15s;
}
.dv2-colony-select .cs-ic{width:calc(16px*var(--scale));height:calc(16px*var(--scale));color:var(--cyan);flex:none;}
.dv2-colony-select .cs-name{flex:none;}
.dv2-colony-select .cs-kind{
  flex:1;font-family:var(--font-body);font-size:.72rem;letter-spacing:0;color:var(--ink-3);
}
.dv2-tier-badge{
  flex:none;font-family:var(--font-mono);font-size:.62rem;font-weight:700;letter-spacing:.04em;
  color:var(--cyan);background:rgba(45,212,191,.14);border:1px solid rgba(45,212,191,.4);
  border-radius:6px;padding:1px 6px;
}
.dv2-colony-select:hover,.dv2-colony-select.open{border-color:var(--cyan);color:var(--cyan);}
.dv2-colony-select .chev{transition:transform .15s;flex:none;}
.dv2-colony-select.open .chev{transform:rotate(180deg);}
.dv2-colony-menu{
  margin-top:4px;background:rgba(16,24,38,.94);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
  border:1px solid var(--line-strong);border-radius:10px;overflow:hidden;box-shadow:var(--shadow-deep);
}
.dv2-colony-opt{
  display:flex;align-items:center;gap:9px;padding:calc(8px*var(--scale)) calc(12px*var(--scale));
  font-size:.76rem;color:var(--ink-2);border-bottom:1px solid rgba(255,255,255,.05);cursor:default;
}
.dv2-colony-opt .co-txt{display:flex;flex-direction:column;line-height:1.2;flex:1;min-width:0;}
.dv2-colony-opt .co-name{font-family:var(--font-mono);font-size:.74rem;color:var(--ink-1);}
.dv2-colony-opt .co-state{font-size:.62rem;color:var(--ink-3);}
.dv2-colony-opt .dv2-tier-badge{font-size:.56rem;}
.dv2-colony-opt:last-child{border-bottom:none;}
.dv2-colony-opt.active{color:var(--ink-1);}
.dv2-colony-opt.active .dv2-id-thumb-sm{box-shadow:0 0 8px rgba(45,212,191,.6);}
.dv2-colony-opt.locked{opacity:.55;cursor:not-allowed;}
.dv2-id-thumb-sm{width:20px;height:20px;border-radius:50%;flex:none;background:radial-gradient(circle at 35% 30%, #8fd6c8, var(--cyan-dim) 70%);}

/* ---------- widgets cosmétiques sur le render (météo/altitude/mini-globe) ----------
   v0.60.1 : les deux chips forment un seul panneau sombre à deux
   compartiments (cible), et le mini-globe se place ENTIÈREMENT dans le
   render, juste à gauche de la colonne droite, cerclé d'un anneau teal. */
.dv2-render-widgets{
  position:absolute;top:calc(14px*var(--scale));z-index:20;
  right:calc(var(--dv2-side-w, 316px) + 96px*var(--scale));
  display:flex;align-items:stretch;
  background:var(--glass-dark);backdrop-filter:blur(var(--glass-blur));-webkit-backdrop-filter:blur(var(--glass-blur));
  border:1px solid var(--glass-border);border-radius:calc(14px*var(--scale));overflow:hidden;
  box-shadow:var(--shadow-deep);
}
.dv2-chip{
  display:flex;align-items:center;gap:9px;padding:calc(8px*var(--scale)) calc(14px*var(--scale));
  font-family:var(--font-mono);font-size:.72rem;color:var(--ink-1);white-space:nowrap;
}
.dv2-chip + .dv2-chip{border-left:1px solid var(--line);}
.dv2-chip svg{width:calc(17px*var(--scale));height:calc(17px*var(--scale));color:var(--cyan);flex:none;}
.dv2-chip .dv2-chip-txt{display:flex;flex-direction:column;line-height:1.15;}
.dv2-chip .dv2-chip-sub{font-size:.58rem;color:var(--ink-3);text-transform:lowercase;}
.dv2-minglobe{
  position:absolute;top:calc(10px*var(--scale));z-index:20;cursor:pointer;
  right:calc(var(--dv2-side-w, 316px) + 20px*var(--scale));
  width:calc(64px*var(--scale));height:calc(64px*var(--scale));border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:radial-gradient(circle at 35% 30%, #8fd6c8, var(--cyan-dim) 72%);
  border:1px solid rgba(45,212,191,.5);
  box-shadow:0 0 0 calc(4px*var(--scale)) rgba(11,17,28,.6), 0 0 calc(18px*var(--scale)) rgba(45,212,191,.3);
  transition:transform .15s,border-color .15s;
}
/* anneau teal orbital autour du globe (décor, jamais porteur d'info) */
.dv2-minglobe::after{
  content:"";position:absolute;inset:calc(-7px*var(--scale));border-radius:50%;
  border:1px solid rgba(45,212,191,.45);border-top-color:transparent;border-bottom-color:transparent;
}
.dv2-minglobe:hover{transform:scale(1.08);border-color:var(--cyan);}

/* ---------- HUD, débit net par ressource + horloge (v0.60.0) ---------- */
.res .rate{font-family:var(--font-mono);font-size:.6rem;color:var(--ink-3);line-height:1.2;}
.res .rate.up{color:var(--lime);}
.res .rate.down{color:var(--rose);}
.hud-clockday{
  display:flex;flex-direction:column;align-items:flex-end;line-height:1.15;
  padding:0 calc(12px*var(--text-scale));border-right:1px solid var(--line);font-family:var(--font-mono);
}
.hud-time{font-size:.78rem;color:var(--ink-1);}
.hud-day{font-size:.6rem;color:var(--ink-3);}

/* ================= performance (§7) ================= */
@media (prefers-reduced-motion: reduce){
  .dv2-surface::before,.dv2-surface-bg,.dv2-cloud-a,.dv2-cloud-b,.dv2-sweep,.dv2-ship,
  .dv2-biome-badge i,.hex.dv2-constructing .dv2-ring,
  .hex.dv2-celebrate .hex-tile,.hex.dv2-celebrate::after,
  .dv2-mission-step.done .dv2-mission-check,.dv2-advisor-dot,.advisor-row.critique .dv2-advisor-dot,
  .advisor-row.alerte .dv2-advisor-dot,.dv2-orbit-ring,.dv2-card,
  .dv2-dock-block,.dv2-dock-badge.pulse{
    animation:none !important;
  }
  .dv2-surface-bg{transform:none !important;}
}

/* ============================================================
   BÂTIMENTS v0.61.0, "CATALOGUE IMMERSIF"
   Portée : écran Bâtiments uniquement (#screen-buildings). Remplace la
   section "DA v2" (v0.28.0 à v0.38.0, layout 3 colonnes opaques sur
   fond d'écran neutre) : même grammaire que l'écran Planète, render de
   colonie plein cadre + panneaux translucides navy qui flottent dessus.
   Ce qui SURVIT de l'ancienne section, parce que d'autres écrans ou la
   fenêtre modale s'en servent encore : les 7 couleurs de catégorie,
   `.bcat-pill`, `.bld-cost-chip`, `.bld-badge`, `.bld-prod-pill`
   (réutilisée par l'écran Usines), `.bld-staff-dd*`, `.bld-sheet-*`,
   `.bld-ptable*`, `.bld-prereq-*`, `.bld-elec-line`, `.bld-prod-line`.
   Ce qui DISPARAÎT, sans appelant restant : `.bld-layout`,
   `.bld-sector-panel`, `.bld-detail-panel`, `.bld-grid-toolbar`,
   `.bld-toolbar`, `.bld-sheet-art` (morte depuis v0.32.0).
   Aucune classe `.dv2-*` de l'écran Planète n'est modifiée ici ; les
   deux seules réutilisées telles quelles sont `.dv2-spotlight` et
   `.dv2-vignette` (déjà globales, pilotées par variables CSS).
   ============================================================ */
:root{
  --bld-extraction: #4ADE80;
  --bld-energie:    #FBBF24;
  --bld-usine:      #FB923C;
  --bld-recherche:  #A78BFA;
  --bld-defense:    #FB7185;
  --bld-infra:      #38BDF8;
  --bld-orbital:    #818CF8;
}

/* ---------- plein cadre (même principe que .dv2-fullbleed) ----------
   Classe DISTINCTE de celle de la Planète, volontairement : les règles
   `.dv2-fullbleed *` portent des repères propres à cet écran-là
   (hexagones, dock, side-stack) qui n'ont rien à faire ici. */
.screen.bld-fullbleed{padding:0;overflow:hidden;}
.bldx-wrap{
  position:absolute;inset:0;
  /* v0.61.1 : en-tête pleine largeur puis zone des trois colonnes, en
     flux (plus de positionnement absolu par colonne) : les trois
     colonnes partagent le même sommet, quelle que soit la hauteur de
     l'en-tête (chips repliées sur deux lignes comprises). */
  display:flex;flex-direction:column;
  padding:calc(12px*var(--scale)) calc(14px*var(--scale)) var(--bldx-safe-bottom);
  /* valeurs de repli : AG.applyBuildingsRender (js/05-screen-buildings.js)
     pose les vraies depuis AG.BUILDINGS_SCREEN (js/00p-buildings-layout.js) */
  --bldx-left-w:  clamp(240px, 18%, 320px);
  --bldx-right-w: clamp(300px, 22%, 420px);
  --bldx-card-w:  240px;
  --bldx-card-max-w: 290px;
  --bldx-card-min-h: 150px;
  --bldx-thumb-ratio: 16 / 9;
  --bldx-safe-bottom: calc(var(--nav-h) + 19px*var(--scale));
  --bldx-gap: calc(14px*var(--scale));
}

/* ---------- fond plein cadre + éclairage ----------
   L'image vient d'une variable (--bldx-bg, posée par
   AG.applyBuildingsRender depuis AG.BUILDINGS_SCREEN.image) : fond propre
   à cet écran, l'écran Planète garde le sien. Si elle manque, le dégradé
   navy en dessous occupe l'espace, jamais de vide. */
.bldx-stage{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden;}
.bldx-stage-bg{
  position:absolute;inset:0;
  background:
    var(--bldx-bg, none) center / cover no-repeat,
    linear-gradient(160deg, #0B1020, #101826 70%);
}
/* .dv2-spotlight / .dv2-vignette sont réutilisées telles quelles : elles
   ne lisent que des variables CSS, posées ici sur .bldx-wrap. */

/* ---------- zone des trois colonnes ----------
   Grille à sommet commun : gauche, cartes et droite démarrent à la même
   ligne Y sous l'en-tête et s'arrêtent au-dessus de la nav (padding bas
   du wrap). align-items:stretch, jamais de centrage vertical. Les
   pourcentages des clamp() se rapportent à la largeur de cette zone. */
.bldx-body{
  position:relative;z-index:20;flex:1 1 auto;min-height:0;
  display:grid;grid-template-columns:var(--bldx-left-w) minmax(0,1fr) var(--bldx-right-w);
  gap:var(--bldx-gap);align-items:stretch;
}
.bldx-col{
  min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:calc(8px*var(--scale));
}
.bldx-colonies{display:flex;flex-direction:column;gap:calc(8px*var(--scale));flex:none;}
.bldx-center{display:flex;flex-direction:column;min-width:0;min-height:0;}

/* ---------- panneaux translucides (même recette que .dv2-card) ---------- */
.bldx-card{
  background:var(--glass-dark);backdrop-filter:blur(var(--glass-blur));-webkit-backdrop-filter:blur(var(--glass-blur));
  border:1px solid var(--glass-border);border-radius:var(--dv2-r-card);
  box-shadow:var(--shadow-deep);flex:0 0 auto;overflow:hidden;
}
.bldx-card .panel-head{
  display:flex;align-items:center;gap:8px;
  padding:calc(5px*var(--scale)) calc(12px*var(--scale));font-size:.72rem;
}
.bldx-card .panel-head .eyebrow{margin-left:auto;}
.bldx-card .panel-body{padding:calc(5px*var(--scale)) calc(12px*var(--scale)) calc(9px*var(--scale));}
.bldx-card .mini-row{padding:calc(4px*var(--scale)) 0;font-size:.76rem;min-height:calc(28px*var(--scale));gap:10px;}
.bldx-card .mini-row .v{font-family:var(--font-mono);text-align:right;font-size:.72rem;white-space:nowrap;flex:none;}
.bldx-card.collapsed .panel-body{display:none;}
.bldx-card.collapsed .panel-collapse svg{transform:rotate(-90deg);}
.bldx-hint{margin:8px 0 0;font-size:.72rem;line-height:1.35;color:var(--ink-3);}

/* colonie courante : anneau teal (jamais un fond différent, pour que
   les panneaux gardent la même densité visuelle) */
.bldx-card.current{box-shadow:var(--shadow-deep), 0 0 0 1px var(--cyan), 0 0 14px rgba(45,212,191,.22);}
.bldx-dot{
  width:8px;height:8px;border-radius:50%;flex:none;background:var(--ink-3);
  box-shadow:0 0 0 3px rgba(100,125,150,.12);
}
.bldx-dot.active{background:var(--lime);box-shadow:0 0 0 3px rgba(74,222,128,.16);}
.bldx-dot.busy{background:var(--amber);box-shadow:0 0 0 3px rgba(245,158,11,.16);}
.bldx-colony-name{font-family:var(--font-head);font-size:.82rem;color:var(--ink-1);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}

/* chantier d'une colonie (colonne gauche) */
.bld-sitework-list{display:flex;flex-direction:column;gap:8px;}
.bld-sitework-empty{color:var(--ink-3);font-size:.74rem;}
.bld-sitework-item{
  background:rgba(4,10,18,.45);border:1px solid var(--line);border-left:3px solid var(--amber);
  border-radius:9px;padding:calc(7px*var(--scale)) calc(9px*var(--scale));
}
.bld-sitework-name{display:flex;justify-content:space-between;align-items:baseline;gap:6px;font-size:.76rem;color:var(--ink-1);margin-bottom:6px;}
.bld-sitework-name b{font-family:var(--font-head);font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.bld-sitework-name span{font-family:var(--font-mono);font-size:.64rem;color:var(--ink-3);flex:none;}
.bld-sitework-time{font-family:var(--font-mono);font-size:.66rem;color:var(--ink-2);margin-top:5px;text-align:right;}

/* ---------- en-tête pleine largeur (v0.61.1) ---------- */
/* v0.61.2 : bloc empilé (titre, sous-titre, onglets) aligné sur la
   grille de cartes. Les paddings latéraux reprennent exactement les
   largeurs des colonnes + l'espacement de .bldx-body : les colonnes ne
   bougent pas, seul le contenu de l'en-tête se cale sur le centre. */
.bldx-head{
  position:relative;z-index:25;flex:none;
  display:flex;flex-direction:column;align-items:stretch;gap:calc(10px*var(--scale));
  padding:0 calc(var(--bldx-right-w) + var(--bldx-gap)) 0 calc(var(--bldx-left-w) + var(--bldx-gap));
  margin-bottom:calc(12px*var(--scale));
}
.bldx-head-txt{min-width:0;flex:none;}
.bldx-head-txt h1{
  margin:0;font-family:var(--font-display);font-weight:700;font-size:1.15rem;letter-spacing:.14em;
  color:var(--ink-1);text-transform:uppercase;text-shadow:0 2px 12px rgba(4,10,18,.9);
}
.bldx-head-txt p{
  margin:3px 0 0;color:var(--ink-2);font-size:.8rem;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-shadow:0 1px 8px rgba(4,10,18,.9);
}
.bldx-queue{
  flex:0 0 auto;
  background:var(--glass-dark);backdrop-filter:blur(var(--glass-blur));-webkit-backdrop-filter:blur(var(--glass-blur));
  border:1px solid var(--glass-border);border-radius:var(--dv2-r-card);
  padding:calc(7px*var(--scale)) calc(12px*var(--scale));box-shadow:var(--shadow-deep);
}
.bldx-queue-row{display:flex;align-items:baseline;justify-content:space-between;gap:10px;}
.bldx-queue-label{
  font-family:var(--font-mono);font-size:.68rem;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3);
}
.bldx-queue-count{font-family:var(--font-mono);font-size:.74rem;color:var(--cyan);}
.bldx-queue .bar{margin-top:6px;}
.bldx-queue-sub{font-family:var(--font-mono);font-size:.66rem;color:var(--ink-2);margin-top:5px;}

/* ---------- chips de catégorie ---------- */
.bldx-chips{flex:0 1 auto;margin:0;}
/* rangée chips + bouton Arbre techno (v0.62.2) */
.bldx-head-row{display:flex;align-items:center;gap:10px;min-width:0;}
.bldx-head-row .bldx-chips{flex:1 1 auto;min-width:0;}

/* ---------- grille auto-fill ----------
   `auto-fill` + `minmax(var(--bldx-card-w), 1fr)` : la grille pose
   d'elle-même autant de colonnes que la largeur disponible le permet,
   du 1366 au 3440, sans aucun media query par palier de largeur. */
.bldx-grid{
  flex:1 1 auto;overflow-y:auto;align-content:start;
  /* colonnes BORNÉES : une carte reste compacte (entre --bldx-card-w
     et --bldx-card-max-w) au lieu de s étirer jusqu à 400px sur un
     écran large, ce qui étirerait aussi sa vignette 16/9 et ferait
     grandir toute la carte. Le reste de la place va à des colonnes en
     plus, jamais à des cartes plus grosses. */
  display:grid;grid-template-columns:repeat(auto-fill, minmax(var(--bldx-card-w), var(--bldx-card-max-w)));justify-content:start;
  /* grid-auto-rows:max-content : sans lui, une grille à hauteur définie
     (elle défile) comprime les rangées quand la place manque, et les
     cartes, en overflow:hidden, perdaient leur rangée de boutons en bas
     (constaté en 1366x768). */
  grid-auto-rows:max-content;
  gap:calc(14px*var(--scale));padding:2px calc(6px*var(--scale)) calc(14px*var(--scale)) 0;
}

/* ---------- carte compacte ----------
   Même id de classe qu'avant (`.bld-card`, `data-building`) : la
   surbrillance du tutoriel (AG.applyTutorialHighlight) et les
   écouteurs existants continuent de la trouver, zéro régression. */
.bld-card{
  --bld-cat: var(--dv2-free);
  position:relative;display:flex;flex-direction:column;min-width:0;
  min-height:var(--bldx-card-min-h);
  background:var(--glass-dark);backdrop-filter:blur(var(--glass-blur));-webkit-backdrop-filter:blur(var(--glass-blur));
  border:1px solid var(--glass-border);border-top:2px solid var(--bld-cat);
  border-radius:var(--dv2-r-card);overflow:hidden;box-shadow:var(--shadow-deep);
  transition:transform .18s ease, border-color .18s ease;
}
.bld-card.cat-extraction{--bld-cat:var(--bld-extraction);}
.bld-card.cat-energie{--bld-cat:var(--bld-energie);}
.bld-card.cat-usine{--bld-cat:var(--bld-usine);}
.bld-card.cat-recherche{--bld-cat:var(--bld-recherche);}
.bld-card.cat-defense{--bld-cat:var(--bld-defense);}
.bld-card.cat-infra{--bld-cat:var(--bld-infra);}
.bld-card.cat-orbital{--bld-cat:var(--bld-orbital);}
.bld-card:hover{transform:translateY(-4px);border-color:var(--bld-cat);}

/* 4.1 vignette 16:9 */
.bld-card-art{
  position:relative;width:100%;aspect-ratio:var(--bldx-thumb-ratio);flex:none;
  overflow:hidden;background:var(--panel-soft);border-bottom:1px solid var(--line);
}
.bld-card-art::after{
  content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
  background:linear-gradient(180deg, transparent 52%, rgba(4,10,18,.6));
}
/* v0.65.1 : vignette = composant partagé .ag-art (css/03-components.css) */
.bld-card-art .ag-art{--art-tint:var(--bld-cat);--art-ph-size:1.7rem;}
.bld-card-art .bld-prod-pill{
  position:absolute;bottom:7px;left:7px;z-index:3;max-width:calc(100% - 14px);
  display:inline-flex;align-items:center;gap:5px;
  font-family:var(--font-mono);font-size:.64rem;font-weight:700;
  color:var(--bld-cat);background:color-mix(in srgb, var(--bld-cat) 24%, rgba(4,10,18,.72));
  border:1px solid color-mix(in srgb, var(--bld-cat) 45%, transparent);
  border-radius:999px;padding:2px 8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.bld-card-art .bld-prod-pill svg{width:10px;height:10px;flex:none;}
.bld-card-art .bld-prod-pill.neutral{color:var(--ink-2);background:rgba(4,10,18,.72);border-color:var(--line-strong);}
.bld-card-art .bld-prod-pill.elec{color:var(--dv2-elec);background:rgba(4,10,18,.72);border-color:rgba(251,191,36,.45);}
.bld-card-art .bld-prod-pill.elec.neg{color:var(--rose);border-color:rgba(248,113,113,.45);}

/* 4.2 corps : nom une ligne, description une ligne tronquée, coûts */
.bld-card-body{padding:calc(7px*var(--scale)) calc(9px*var(--scale)) 0;display:flex;flex-direction:column;gap:3px;min-width:0;}
.bld-card-name{
  margin:0;font-family:var(--font-head);font-size:.9rem;font-weight:600;color:var(--ink-1);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.bld-card-desc{
  margin:0;font-size:.72rem;color:var(--ink-3);line-height:1.35;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.bld-cost-row{display:flex;flex-wrap:nowrap;align-items:center;gap:5px;margin-top:2px;min-width:0;}
.bld-cost-row .bld-timer{margin-left:auto;flex:none;}
.bld-cost-chip{
  font-family:var(--font-mono);font-size:.66rem;padding:2px 7px;border-radius:8px;
  border:1px solid var(--line-strong);color:var(--ink-2);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;
}
.bld-cost-chip.ok{color:var(--lime);border-color:rgba(74,222,128,.4);background:rgba(74,222,128,.06);}
.bld-cost-chip.ko{color:var(--rose);border-color:rgba(248,113,113,.4);background:rgba(248,113,113,.06);}
.bld-cost-chip.more{color:var(--ink-3);flex:none;}
.bld-timer{font-family:var(--font-mono);font-size:.66rem;color:var(--ink-3);}

/* 4.3 rangée de boutons + 4.4 ligne d'ouvriers, ancrées en bas */
.bld-card-actions{
  margin-top:auto;display:flex;flex-direction:column;gap:4px;
  padding:calc(6px*var(--scale)) calc(9px*var(--scale)) calc(8px*var(--scale));
}
.bld-row1{display:flex;gap:5px;align-items:stretch;}
.bld-action-btn{flex:1 1 auto;justify-content:center;min-width:0;}
.bld-details-btn{flex:0 0 auto;justify-content:center;}
/* DÉMOLIR (v0.61.2) : petite icône en overlay sur la vignette, en bas à
   droite, fond rouge sombre plein et flèche claire. Au-dessus du dégradé
   (::after, z 2) et des chips (z 3). La confirmation reste celle
   d'AG.demolishBuilding, jamais dupliquée. */
/* v0.62.2 : icônes overlay génériques (carte Bâtiments ET vignette du
   cockpit Usines), plus scopées à .bld-card-art.
   v0.62.3 : flèches style OGame, ancrées dans les coins EXACTS de
   l'image (aucune marge externe, coin extérieur à ras, arrondi côté
   intérieur seulement) : verte montante bas gauche, rouge descendante
   bas droite. Mêmes flèches sur les cartes Bâtiments, le cockpit et les
   nœuds du graphe Usines. Jamais `disabled` : indisponible = estompée
   40% + tooltip riche avec le motif exact (bldArrowUp/bldArrowDown,
   js/05-screen-buildings.js), le clic affiche ce même motif. */
.bld-demolish-btn, .bld-upgrade-btn{
  position:absolute;bottom:0;z-index:5;
  width:22px;height:22px;padding:0;margin:0;border:none;
  display:inline-flex;align-items:center;justify-content:center;
  color:#FFFFFF;cursor:pointer;transition:filter .15s, opacity .15s;
}
.bld-demolish-btn svg, .bld-upgrade-btn svg{width:11px;height:11px;}
.bld-upgrade-btn{left:0;right:auto;background:rgba(34,197,94,.85);border-radius:0 6px 0 0;}
.bld-demolish-btn{right:0;left:auto;background:rgba(239,68,68,.85);border-radius:6px 0 0 0;}
.bld-demolish-btn:hover, .bld-upgrade-btn:hover{filter:brightness(1.15);}
.bld-demolish-btn:focus-visible, .bld-upgrade-btn:focus-visible{outline:2px solid var(--cyan);outline-offset:-2px;}
.bld-demolish-btn.is-disabled, .bld-upgrade-btn.is-disabled{opacity:.4;cursor:not-allowed;}
.bld-demolish-btn.is-disabled:hover, .bld-upgrade-btn.is-disabled:hover{filter:none;}
/* le chip de débit (bas gauche) démarre à droite de la flèche verte et
   s'arrête avant la flèche rouge */
.bld-card-art .bld-prod-pill{left:28px;bottom:3px;max-width:calc(100% - 56px);}

/* ---------- badge de niveau intégré à l'image (v0.62.3) ----------
   Coin supérieur gauche de l'image (3px de marge), fond teal, texte
   blanc "Nv.X". Remplace le badge doré flottant sur les cartes Bâtiments,
   les nœuds et le cockpit Usines, et la modale Arbre techno
   (AG.levelBadgeHTML, js/05-screen-buildings.js). */
.ag-lvl-badge{
  position:absolute;top:3px;left:3px;z-index:4;pointer-events:none;
  font-family:var(--font-mono);font-size:.58rem;font-weight:700;line-height:1;letter-spacing:.02em;
  color:#FFFFFF;background:var(--layer-accent);border-radius:5px;padding:3px 5px;
  box-shadow:0 1px 4px rgba(4,10,18,.5);
}

.bld-staff-row{display:flex;align-items:center;gap:6px;flex-wrap:wrap;}
.bld-staff-label{
  font-family:var(--font-mono);font-size:.66rem;color:var(--ink-3);
  display:inline-flex;align-items:center;gap:5px;min-width:0;
}
.bld-staff-label .v{color:var(--ink-1);}
.bld-staff-label .v.warn{color:var(--amber);}
.bld-staff-btn{margin-left:auto;justify-content:center;gap:5px;position:relative;}
.bld-staff-warn-dot{
  width:7px;height:7px;border-radius:50%;background:var(--rose);flex:none;
  animation:bldWarnPulse 1.3s ease-in-out infinite;
}
@keyframes bldWarnPulse{0%,100%{opacity:1;}50%{opacity:.35;}}

/* construction en cours : barre + temps + annuler, dans la carte */
.bld-card.constructing{border-color:var(--amber);}
.bld-card-progress{display:flex;flex-direction:column;gap:5px;}
.bld-card-progress .bld-lock-note{padding-top:0;border-top:none;}

/* 4.5 verrouillé : vignette en noir et blanc, voile, "PALIER XX" */
.bld-card.locked{opacity:.7;}
/* v0.61.2 : cartes verrouillées moins étouffées. 10px entre la vignette
   (voile + PALIER XX) et le nom, 10px entre les coûts et le message
   orange de verrouillage, 8px avant les boutons. */
.bld-card.locked .bld-card-body{padding-top:calc(10px*var(--scale));}
.bld-card.locked .bld-card-actions > .bld-chain-banner,
.bld-card.locked .bld-card-actions > .bld-lock-note{margin:calc(4px*var(--scale)) 0 calc(4px*var(--scale));}
.bld-card.locked:hover{transform:none;border-color:var(--line);}
.bld-card.locked .bld-card-art .ag-art{filter:grayscale(1) brightness(.6);}
.bld-lock-veil{
  position:absolute;inset:0;z-index:4;display:flex;align-items:center;justify-content:center;
  background:rgba(4,10,18,.55);
}
.bld-lock-label{
  display:inline-flex;align-items:center;gap:6px;
  font-family:var(--font-mono);font-size:.68rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-1);background:rgba(4,10,18,.72);border:1px solid var(--line-strong);
  border-radius:999px;padding:4px 11px;
}
.bld-lock-note{
  font-family:var(--font-mono);font-size:.66rem;color:var(--ink-3);letter-spacing:.03em;
  display:flex;align-items:center;gap:5px;
}
.bld-chain-banner{
  font-size:.7rem;color:var(--amber);background:rgba(245,158,11,.08);border:1px solid rgba(245,158,11,.3);
  border-radius:8px;padding:5px 8px;line-height:1.3;
}

/* ---------- badges ---------- */
.bld-badge{font-family:var(--font-mono);font-size:.63rem;padding:2px 7px;border-radius:8px;border:1px solid var(--line-strong);}
.bld-badge.count{color:var(--cyan);border-color:rgba(45,212,191,.4);background:rgba(4,10,18,.6);}
/* v0.62.3 : plus de doré (thème navy/teal). Ne reste utilisé que par
   l'en-tête de la fiche détaillée (modale), mêmes couleurs que
   .ag-lvl-badge. */
.bld-badge.lvl{color:#FFFFFF;border-color:transparent;background:var(--layer-accent);font-weight:700;}

/* ---------- célébration à la fin d'une construction ---------- */
.bld-card.bld-celebrate .bld-card-art .ag-art{animation:dv2Pop .6s cubic-bezier(.34,1.56,.64,1) both;}

/* ---------- pills de catégorie (inchangées depuis v0.28.0) ---------- */
.bcat-pill{
  --bld-cat: var(--ink-3);
  position:relative;display:inline-flex;align-items:center;gap:6px;
  font-family:var(--font-head);font-size:.78rem;letter-spacing:.05em;text-transform:uppercase;
  padding:calc(7px*var(--scale)) calc(14px*var(--scale));border-radius:20px;
  border:1px solid var(--line-strong);color:var(--ink-3);cursor:pointer;transition:.15s;
  background:rgba(16,24,38,.78);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  box-shadow:0 2px 0 rgba(0,0,0,.25), inset 0 1px 0 rgba(255,255,255,.04);
}
.bcat-pill i{width:7px;height:7px;border-radius:3px;background:var(--bld-cat);flex:none;display:inline-block;transition:.15s;}
.bcat-pill:hover{color:var(--ink-1);border-color:var(--bld-cat);background:color-mix(in srgb, var(--bld-cat) 14%, rgba(16,24,38,.8));box-shadow:0 0 14px color-mix(in srgb, var(--bld-cat) 45%, transparent);}
.bcat-pill.active{
  color:#04120c;border-color:var(--bld-cat);
  background:linear-gradient(180deg, color-mix(in srgb, var(--bld-cat) 75%, white 15%), var(--bld-cat));
  box-shadow:0 2px 0 rgba(0,0,0,.3), 0 0 0 3px color-mix(in srgb, var(--bld-cat) 25%, transparent);
}
.bcat-pill.active i{background:#04120c;}
.bcat-pill.locked{opacity:.5;cursor:not-allowed;filter:grayscale(.4);}
.bcat-pill.locked:hover{color:var(--ink-3);border-color:var(--line-strong);background:rgba(16,24,38,.78);box-shadow:0 2px 0 rgba(0,0,0,.25);}
.bcat-pill.cat-extraction{--bld-cat:var(--bld-extraction);}
.bcat-pill.cat-energie{--bld-cat:var(--bld-energie);}
.bcat-pill.cat-usine{--bld-cat:var(--bld-usine);}
.bcat-pill.cat-recherche{--bld-cat:var(--bld-recherche);}
.bcat-pill.cat-defense{--bld-cat:var(--bld-defense);}
.bcat-pill.cat-infra{--bld-cat:var(--bld-infra);}
.bcat-pill.cat-orbital{--bld-cat:var(--bld-orbital);}

/* ---------- widget main-d'oeuvre (colonne droite désormais) ---------- */
.bld-workforce-mini{
  display:flex;align-items:center;gap:8px;cursor:pointer;
  padding:calc(7px*var(--scale)) calc(10px*var(--scale));border-radius:12px;
  border:1px solid var(--line-strong);background:rgba(4,10,18,.45);transition:.15s;
}
.bld-workforce-mini:hover{border-color:var(--cyan);background:rgba(45,212,191,.08);}
.bld-wf-ic{width:15px;height:15px;flex:none;color:var(--ink-2);}
.bld-wf-ic svg{width:100%;height:100%;}
.bld-wf-label{font-family:var(--font-head);font-size:.76rem;color:var(--ink-2);}
.bld-wf-count{font-family:var(--font-mono);font-size:.74rem;color:var(--ink-1);white-space:nowrap;margin-left:auto;}
.bld-wf-segs{display:flex;align-items:center;gap:2px;}
.bld-wf-seg{width:5px;height:11px;border-radius:2px;background:var(--line-strong);flex:none;}
.bld-wf-seg.filled{background:var(--lime);box-shadow:0 0 5px rgba(74,222,128,.5);}

/* ---------- alertes / conseiller (colonne droite) ---------- */
#bld-alerts-body .advisor-row{padding:calc(6px*var(--scale)) 0;}
#bld-alerts-body .advisor-msg{font-size:.75rem;line-height:1.3;}
#bld-alerts-body .btn.sm{padding:calc(5px*var(--scale)) calc(9px*var(--scale));font-size:.7rem;}

/* ---------- électricité / production, lignes texte (modale) ---------- */
.bld-elec-line{display:flex;align-items:center;gap:5px;font-family:var(--font-mono);font-size:.72rem;margin-top:2px;}
.bld-elec-line svg{width:13px;height:13px;flex:none;}
.bld-elec-line.pos{color:var(--dv2-elec);}
.bld-elec-line.neg{color:var(--rose);}
.bld-prod-line{
  display:flex;align-items:center;gap:5px;font-family:var(--font-mono);font-size:.76rem;font-weight:600;
  color:var(--bld-cat, var(--cyan));margin-top:2px;
}
.bld-prod-line svg{width:14px;height:14px;flex:none;}

/* ---------- dropdown d'affectation directe (inchangé) ---------- */
.bld-staff-dd{
  flex-basis:100%;
  background:rgba(4,10,18,.6);border:1px solid var(--line-strong);border-radius:10px;
  padding:8px;margin-top:6px;max-height:180px;overflow-y:auto;
}
.bld-staff-dd-title{font-family:var(--font-mono);font-size:.62rem;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3);margin-bottom:6px;}
.bld-staff-dd-item{display:flex;align-items:center;gap:8px;padding:5px 6px;border-radius:7px;cursor:pointer;font-size:.78rem;color:var(--ink-1);}
.bld-staff-dd-item:hover{background:rgba(45,212,191,.1);}
.bld-staff-dd-item img{width:22px;height:22px;flex:none;}
.bld-staff-dd-item small{display:block;color:var(--ink-3);font-size:.64rem;}
.bld-staff-dd-empty{font-size:.78rem;color:var(--ink-3);margin-bottom:6px;}

/* ---------- fiche modale à onglets (inchangée depuis v0.38.0) ---------- */
.bld-sheet-bg{
  position:relative;height:calc(150px*var(--scale));
  margin:calc(-18px*var(--scale)) calc(-18px*var(--scale)) 0;
  background:
    linear-gradient(180deg, rgba(6,14,24,.35), rgba(6,14,24,.92)),
    radial-gradient(ellipse 70% 70% at 50% 35%, color-mix(in srgb, var(--bld-cat) 35%, transparent), transparent 75%);
  background-size:cover, cover;
  background-position:center;
}
.bld-sheet-bg.cat-extraction{--bld-cat:var(--bld-extraction);}
.bld-sheet-bg.cat-energie{--bld-cat:var(--bld-energie);}
.bld-sheet-bg.cat-usine{--bld-cat:var(--bld-usine);}
.bld-sheet-bg.cat-recherche{--bld-cat:var(--bld-recherche);}
.bld-sheet-bg.cat-defense{--bld-cat:var(--bld-defense);}
.bld-sheet-bg.cat-infra{--bld-cat:var(--bld-infra);}
.bld-sheet-bg.cat-orbital{--bld-cat:var(--bld-orbital);}
.bld-sheet-hero{
  position:relative;height:calc(48px*var(--scale));margin:calc(-48px*var(--scale)) 0 8px;
  display:flex;align-items:flex-end;justify-content:flex-end;padding:0 4px;
}
.bld-sheet-tabs{margin-top:4px;}
.bld-sheet-tab-body{display:flex;flex-direction:column;gap:2px;}
.bld-sheet-lore{font-style:italic;color:var(--ink-2);}

/* arbre de prérequis visuel */
.bld-prereq-chain{display:flex;align-items:center;gap:6px;flex-wrap:wrap;}
.bld-prereq-chip{
  font-family:var(--font-mono);font-size:.68rem;padding:4px 9px;border-radius:8px;
  border:1px solid var(--line-strong);color:var(--ink-3);background:var(--panel-soft);
}
.bld-prereq-chip.done{color:var(--lime);border-color:rgba(74,222,128,.4);background:rgba(74,222,128,.06);}
.bld-prereq-chip.pending{color:var(--amber);border-color:rgba(245,158,11,.4);}
.bld-prereq-arrow{color:var(--ink-3);font-size:.72rem;}

/* ---------- tableau de production façon OGame ---------- */
.bld-ptable-next{margin-bottom:10px;}
.bld-ptable-next .v{display:flex;align-items:center;gap:6px;flex-wrap:wrap;justify-content:flex-end;}
.bld-ptable-wrap{overflow-x:auto;border:1px solid var(--line);border-radius:10px;}
.bld-ptable{width:100%;border-collapse:collapse;font-family:var(--font-mono);font-size:.74rem;}
.bld-ptable th{
  text-align:left;padding:7px 9px;background:var(--panel-soft);color:var(--ink-3);
  font-size:.64rem;letter-spacing:.05em;text-transform:uppercase;border-bottom:1px solid var(--line);
}
.bld-ptable td{padding:6px 9px;border-bottom:1px dashed rgba(255,255,255,.06);color:var(--ink-2);}
.bld-ptable tr:last-child td{border-bottom:none;}
.bld-ptable td.pos{color:var(--dv2-elec);}
.bld-ptable td.neg{color:var(--rose);}
.bld-ptable-current{background:rgba(245,158,11,.08);}
.bld-ptable-current td{color:var(--ink-1);font-weight:700;}
.bld-ptable-locked td{color:var(--ink-3);opacity:.6;}

/* ---------- repli des colonnes sous 1100px ----------
   Hors périmètre demandé (1366 à 3440), mais un écran qui se casse en
   dessous resterait un bug : les trois colonnes repassent en flux
   vertical, le render devient un simple fond fixe. */
@media(max-width:1100px){
  .screen.bld-fullbleed{overflow-y:auto;padding:var(--pad-lg) var(--pad-lg) var(--nav-gap);}
  .bldx-wrap{position:relative;inset:auto;padding:0;gap:12px;}
  .bldx-head{padding:0;}
  .bldx-stage{position:fixed;inset:0;}
  .bldx-body{display:flex;flex-direction:column;gap:12px;}
  .bldx-col{overflow:visible;}
  .bldx-grid{overflow:visible;}
}

/* ---------- performance / accessibilité ---------- */
@media (prefers-reduced-motion: reduce){
  .bld-card,.bld-card:hover,
  .bld-card.bld-celebrate .bld-card-art .ag-art,
  .bcat-pill,.bld-staff-warn-dot{
    animation:none !important;transition:none !important;
  }
  .bld-card:hover{transform:none !important;}
}

/* ============================================================
   ÉCRAN USINES, graphe de flux (v0.39.0, rendu revu v0.62.0)
   Nœuds = petites cartes (même langage que le livre de recettes plus
   bas : fond plat, bordure, ombre, hover lift) avec bannière image,
   nom, niveau ; bordure d'état (catégorie construite/fantôme pointillé/
   verrouillé cadenas/goulot rouge pulsé/sous-alimentée ambre). Clic sur
   une carte construite = sélection (colonne droite, #fgx-cockpit, voir
   js/13-screen-factories.js) au lieu d'un accordéon déplié sous la
   carte (retiré en v0.62.0). Moteur/calculs inchangés depuis v0.39.0,
   uniquement le rendu.
   ============================================================ */
/* v0.62.0 : la photo de fond dédiée (assets/images/fond-usines.jpg,
   motif "arbre de compétence" ajouté en v0.44.0-v0.46.0) est retirée
   d'ici, remplacée par le fond plein cadre commun à tout l'écran
   (.fgx-stage-bg) : ce conteneur redevient un panneau translucide navy
   comme les autres (même recette que .bldx-grid), pour ne pas empiler
   deux photos différentes derrière le graphe. */
.fg-graph-scroll{
  background:rgba(5,10,18,var(--fgx-graph-alpha,.35));
  backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px);
  border:1px solid var(--line);border-radius:var(--dv2-r-card);
  padding:6px;overflow:auto;display:flex;
  /* v0.62.1 : rangée de grille bornée (.fgx-tab-overview) entre la
     toolbar et la rangée du bas, plus de hauteur fixe : le canevas ne
     peut plus déborder sous les panneaux du bas. */
  min-height:0;min-width:0;
}
/* centrage "sûr" : margin:auto plutôt que justify-content:center, qui
   rendrait la partie gauche d'un graphe plus large que la zone
   inaccessible au défilement. */
.fg-graph-scroll > .fg-graph-zoom{margin:auto;flex:none;}
/* couche liens (SVG, position absolue) + couche cartes (HTML, position
   absolue) superposées dans les mêmes coordonnées PAD/COL_W/ROW_H (voir
   AG.renderFlowGraphCanvas) : le lien ne bloque jamais le clic sur une
   carte (pointer-events limité au tracé du trait). */
.fg-graph-canvas{position:relative;flex:none;}
.fg-links-svg{position:absolute;left:0;top:0;pointer-events:none;}
.fg-links-svg .fg-link{pointer-events:stroke;}

/* ---------- cartes nœud (v0.41.0) ---------- */
/* v0.62.1 : --bld-cat posé en style inline par AG.renderFlowGraphCanvas
   depuis la catégorie d'affichage (AG.factoryCat, js/00q-factories-
   layout.js), même couleur que la pastille de la colonne gauche. */
.fg-node-card{
  --bld-cat: var(--dv2-free);
  position:absolute;background:var(--glass-dark);border:1.5px solid var(--line-strong);
  border-radius:10px;box-shadow:var(--shadow-deep);overflow:hidden;
  transition:border-color .15s ease, box-shadow .15s ease, transform .15s ease;
  z-index:1;
}
.fg-node-card:hover{transform:translateY(-2px);}
.fg-node-card:not(.ghost){border-color:color-mix(in srgb, var(--bld-cat) 75%, transparent);box-shadow:var(--shadow-deep), 0 0 10px color-mix(in srgb, var(--bld-cat) 30%, transparent);}
.fg-node-card.open{z-index:6;box-shadow:var(--shadow-deep), 0 0 0 1.5px var(--bld-cat), 0 0 18px color-mix(in srgb, var(--bld-cat) 45%, transparent);}
.fg-node-card.dim{opacity:.3;}
/* fantôme : silhouette estompée, bordure pointillée fine, invitant
   (icône marteau discrète), jamais effrayant : "Construire" n'apparaît
   qu'au survol (opacity pure, aucun JS de hover). */
.fg-node-card.ghost{border-style:dashed;border-color:var(--ink-3);box-shadow:none;opacity:.8;}
.fg-node-card.ghost .fg-node-thumb{opacity:.5;filter:grayscale(.6);}
.fg-node-card.ghost .fg-node-name{color:var(--ink-2);}
.fg-node-card.ghost:hover{border-color:var(--cyan);}
/* z-index 4 (v0.44.0) : au-dessus des scrims (2) et des lignes overlay
   nom/cadence (3) posées sur la bannière, sinon masqué derrière elles. */
.fg-node-hammer{position:absolute;inset:0;z-index:4;display:flex;align-items:center;justify-content:center;color:var(--ink-3);opacity:.7;transition:opacity .15s ease;}
.fg-node-hammer svg{width:20px;height:20px;}
.fg-node-ghost-cta{
  position:absolute;inset:0;z-index:4;display:flex;align-items:center;justify-content:center;
  background:rgba(4,10,18,.55);color:var(--cyan);font-family:var(--font-head);font-size:.72rem;
  letter-spacing:.05em;text-transform:uppercase;opacity:0;transition:opacity .15s ease;
}
.fg-node-card.ghost:hover .fg-node-hammer{opacity:0;}
.fg-node-card.ghost:hover .fg-node-ghost-cta{opacity:1;}
/* goulot réel (offre < demande) : bordure rouge pulsée (box-shadow
   seulement, jamais la largeur de bordure : pas de reflow/jank),
   prime sur la sous-alimentation si les deux sont vrais (AG.flowGraph). */
.fg-node-card.bottleneck{border-color:var(--rose);animation:fgCardPulse 1.4s ease-in-out infinite;}
@keyframes fgCardPulse{0%,100%{box-shadow:var(--shadow-deep), 0 0 6px rgba(248,113,113,.4);}50%{box-shadow:var(--shadow-deep), 0 0 16px rgba(248,113,113,.85);}}
/* sous-alimentée (budget électrique insuffisant, pas d'intrant
   manquant) : bordure ambre stable, aucune pulsation. */
.fg-node-card.underpowered{border-color:var(--amber);box-shadow:var(--shadow-deep), 0 0 8px rgba(245,158,11,.4);}

/* ---------- carte horizontale (v0.62.1, convergence maquette) ----------
   Vignette à gauche (image du bâtiment en auto-chargement, sinon
   placeholder navy + lettre, composant partagé .ag-art depuis v0.65.1),
   texte à droite : nom +
   badge niveau, cadence, chip de débit. Géométrie dans
   AG.FACTORIES_SCREEN.node (js/00q-factories-layout.js). */
.fg-node-head{display:flex;align-items:stretch;height:100%;cursor:pointer;}
/* v0.62.3 : vignette carrée pleine hauteur, largeur posée en ligne par
   AG.renderFlowGraphCanvas (= AG.FACTORIES_SCREEN.node.h). */
.fg-node-thumb{
  position:relative;flex:none;width:74px;overflow:hidden;background:var(--panel-soft);
  border-right:1px solid color-mix(in srgb, var(--bld-cat) 30%, transparent);
}
.fg-node-thumb .ag-art{--art-tint:var(--bld-cat);--art-ph-size:1.3rem;}
.fg-node-info{flex:1;min-width:0;padding:6px 10px;display:flex;flex-direction:column;justify-content:space-between;gap:2px;}
.fg-node-top{display:flex;align-items:center;gap:6px;min-width:0;}
.fg-node-name{
  font-family:var(--font-head);font-size:.86rem;color:var(--ink-1);line-height:1.2;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;flex:1;
}
.fg-node-sub{font-family:var(--font-mono);font-size:.68rem;color:var(--ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
/* pill de rendement : même classe que les cartes Bâtiments
   (`.bld-prod-pill`), simple item de flex ici. */
.fg-node-info .bld-prod-pill{
  position:static;align-self:flex-start;display:inline-flex;align-items:center;gap:4px;
  font-family:var(--font-mono);font-size:.64rem;font-weight:700;
  color:var(--bld-cat);background:color-mix(in srgb, var(--bld-cat) 18%, rgba(4,10,18,.6));
  border:1px solid color-mix(in srgb, var(--bld-cat) 45%, transparent);
  border-radius:999px;padding:1px 7px;
}
.fg-node-info .bld-prod-pill svg{width:10px;height:10px;flex:none;}

/* ---------- fiche de gestion (v0.62.0) ----------
   Vivait dans un accordéon déplié sous la carte jusqu'en v0.61.x
   (grille 0fr -> 1fr, voir historique CHANGELOG.md) : déplacée dans le
   cockpit de la colonne droite (#fgx-cockpit, js/13-screen-factories.js,
   fgCockpitBodyHTML), qui réutilise exactement les mêmes classes
   ci-dessous. La carte du graphe ne montre plus que sa bannière (nom,
   niveau, cadence, rendement), voir .fg-node-card.open plus haut
   (sélection, plus une ouverture). */
.fg-cadence-note{font-size:.78rem;color:var(--ink-3);margin-top:4px;}
/* chips entrée/sortie de la recette (v0.42.0) : hauteur/padding
   identiques entre le chip énergie et le chip ressource (grille alignée),
   icône de taille fixe plutôt que la taille intrinsèque du SVG (qui
   variait selon l'icône, d'où l'ancienne boîte haute et étroite du chip
   énergie). Étend `.cost-chip` (css/03-components.css) sans le dupliquer. */
.fg-io-chip{display:inline-flex;align-items:center;gap:4px;line-height:1;}
.fg-io-chip svg{width:12px;height:12px;flex:none;}

/* ---------- liens, connecteurs orthogonaux (v0.42.0) ----------
   Angles droits en "elbow" entre le port de sortie et le port d'entrée
   (AG.flowGraph inchangé, seul le tracé change). Survol d'un nœud =
   classe `.lit` sur ses liens (data-fg-from/data-fg-to, aucun rebuild
   DOM), épaisseur liée au débit via `--fg-sw`. */
/* v0.62.1 : les connecteurs gris pointillés au repos sont remplacés par
   des flux pleins colorés par TYPE de produit (demande explicite,
   convergence maquette) : teal = matière première (produite par un
   bâtiment d'extraction), orange = produit intermédiaire (sortie
   principale d'une usine), gris clair = sous-produit (sortie secondaire
   d'une recette). Type calculé au rendu (fgFlowType), couleurs dans
   AG.FACTORIES_SCREEN.flowColors. Un lien vers/depuis un nœud non
   construit reste visible mais estompé (.idle). */
.fg-link{
  --fg-flow: var(--fgx-flow-inter, #F59E0B);
  fill:none;stroke:var(--fg-flow);stroke-width:2px;stroke-linecap:round;stroke-linejoin:round;opacity:.9;
  filter:drop-shadow(0 0 3px color-mix(in srgb, var(--fg-flow) 55%, transparent));
  transition:opacity .15s ease, stroke-width .15s ease;
}
.fg-link.flow-raw{--fg-flow:var(--fgx-flow-raw, #2DD4BF);}
.fg-link.flow-inter{--fg-flow:var(--fgx-flow-inter, #F59E0B);}
.fg-link.flow-byproduct{--fg-flow:var(--fgx-flow-byproduct, #CBD5E1);}
.fg-link.idle{opacity:.3;filter:none;}
.fg-link.dim{opacity:.12;}
/* goulot réel : alerte active, rouge pulsé (opacité seule). */
.fg-link.bottleneck{stroke:var(--rose);animation:fgLinkPulse 1.4s ease-in-out infinite;filter:drop-shadow(0 0 4px rgba(248,113,113,.7));}
@keyframes fgLinkPulse{0%,100%{opacity:.55;}50%{opacity:1;}}
.fg-links-svg.fg-hover .fg-link:not(.lit):not(.bottleneck){opacity:.15;}
/* survol d'un nœud : ses flux s'épaississent (débit réel) et brillent. */
.fg-link.lit{stroke-width:var(--fg-sw, 3px);opacity:1;filter:drop-shadow(0 0 6px var(--fg-flow));}

/* ---------- modale "Gérer toutes les planètes" (v0.41.0) ----------
   Une seule vraie colonie existe aujourd'hui (voir js/13-screen-
   factories.js, fgColonies) : la liste reste une vraie boucle
   (AG.patchList) pour ne rien réécrire le jour où plusieurs
   secteurs/planètes existeront. */
.fg-colony-row{padding:calc(12px*var(--scale)) 0;border-bottom:1px solid var(--line);}
.fg-colony-row:last-child{border-bottom:none;}
.fg-colony-head{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:8px;}
.fg-colony-head b{font-family:var(--font-head);font-size:.92rem;color:var(--ink-1);}

/* ---------- performance (parité §7) ---------- */
@media (prefers-reduced-motion: reduce){
  .fg-link,.fg-link.lit,.fg-node-card,.fg-node-card:hover,.fg-node-card.bottleneck,
  .fg-node-hammer,.fg-node-ghost-cta,.fg-node-expand{
    animation:none !important;transition:none !important;
  }
}

/* ============================================================
   Livre de recettes, cartes techno (v0.40.0)
   ============================================================ */
/* largeur fixe (v0.42.0), strictement identique à CARD_W des cartes nœud
   du graphe (js/13-screen-factories.js, AG.renderFlowGraphCanvas) : plus
   de 1fr élastique, pour que les deux langages de carte partagent
   exactement la même largeur plutôt qu'une simple valeur minimale. */
.fg-recipe-grid{display:grid;grid-template-columns:repeat(auto-fill,240px);gap:16px;}
@media(max-width:640px){.fg-recipe-grid{grid-template-columns:1fr;}}
.fg-recipe-card{
  background:var(--dv2-card-bg);border:1px solid var(--line);border-radius:var(--dv2-r-card);
  padding:calc(12px*var(--scale));display:flex;flex-direction:column;gap:8px;
  box-shadow:var(--shadow-deep);transition:transform .18s ease, border-color .18s ease;
  animation:bldCardIn .38s cubic-bezier(.2,.8,.2,1) both;animation-delay:calc(var(--i,0)*40ms);
}
.fg-recipe-card:hover{transform:translateY(-4px);border-color:var(--cyan);}
.fg-recipe-card.locked{opacity:.6;}
.fg-recipe-card.locked:hover{transform:none;border-color:var(--line);}
.fg-recipe-card.equipped{border-color:var(--lime);box-shadow:var(--shadow-deep), 0 0 0 1px rgba(74,222,128,.25);}
.fg-recipe-head{display:flex;align-items:center;gap:8px;}
.fg-recipe-ic{width:22px;height:22px;flex:none;color:var(--cyan);}
.fg-recipe-ic svg{width:100%;height:100%;}
.fg-recipe-head h3{margin:0;flex:1;font-family:var(--font-head);font-size:.92rem;font-weight:600;color:var(--ink-1);}
.fg-recipe-lock{font-size:.8rem;flex:none;}
.fg-formula-row{display:flex;align-items:center;gap:6px;flex-wrap:wrap;}
.fg-formula-chip{
  display:inline-flex;align-items:center;gap:4px;padding:3px 8px;border-radius:20px;
  border:1px solid var(--line-strong);background:var(--panel-soft);color:var(--ink-1);
  font-family:var(--font-mono);font-size:.72rem;
}
.fg-formula-chip svg{width:12px;height:12px;color:var(--ink-2);}
.fg-formula-plus,.fg-formula-arrow{color:var(--ink-3);font-family:var(--font-mono);font-size:.78rem;flex:none;}
.fg-formula-text{font-family:var(--font-mono);color:var(--ink-2);font-size:.78rem;}
.fg-effect-row{display:flex;gap:6px;flex-wrap:wrap;}
.fg-effect-chip{
  padding:2px 8px;border-radius:20px;font-family:var(--font-mono);font-size:.68rem;
  border:1px solid var(--line-strong);
}
.fg-effect-chip.pos{color:var(--lime);border-color:rgba(74,222,128,.35);}
.fg-effect-chip.neg{color:var(--amber);border-color:rgba(245,158,11,.35);}
.fg-chain-missing{color:var(--ink-3);font-size:.78rem;margin:0;}
.fg-equipped-tag{color:var(--lime);font-family:var(--font-mono);font-size:.72rem;}
@media (prefers-reduced-motion: reduce){
  .fg-recipe-card{animation:none !important;}
}

/* ============================================================
   Écran Usines & Logistique, "cockpit d'usine" (v0.62.0)
   ------------------------------------------------------------
   Même squelette plein cadre que .bldx-* (Bâtiments) : en-tête pleine
   largeur puis trois colonnes en flux qui partagent le même sommet.
   Préfixe distinct (.fgx-) plutôt que de réutiliser .bldx- : deux
   écrans différents, deux responsabilités différentes (voir CLAUDE.md,
   "Responsabilités des écrans, ne pas déplacer"), un futur ajustement
   d'une colonne Bâtiments ne doit jamais pouvoir bouger l'écran Usines
   par accident. .dv2-spotlight/.dv2-vignette restent réutilisées telles
   quelles (ne lisent que des variables CSS posées ici sur .fgx-wrap,
   même recette que .bldx-wrap). ============================================================ */
.screen.fgx-fullbleed{padding:0;overflow:hidden;}
.fgx-wrap{
  position:absolute;inset:0;
  display:flex;flex-direction:column;
  padding:calc(12px*var(--scale)) calc(14px*var(--scale)) var(--fgx-safe-bottom);
  /* valeurs de repli : AG.applyFactoriesRender (js/13-screen-factories.js)
     pose les vraies depuis AG.FACTORIES_SCREEN (js/00q-factories-layout.js) */
  --fgx-left-w: clamp(240px, 18%, 320px);
  --fgx-right-w: clamp(300px, 22%, 420px);
  --fgx-safe-bottom: calc(var(--nav-h) + 19px*var(--scale));
  --fgx-gap: calc(14px*var(--scale));
  --spot-rx:52%; --spot-ry:64%; --spot-x:50%; --spot-y:48%;
  --fgx-vignette:.55; --fgx-graph-alpha:.35;
  --fgx-bottom-h: clamp(210px, 20vh, 250px);
  --fgx-flow-raw:#2DD4BF; --fgx-flow-inter:#F59E0B; --fgx-flow-byproduct:#CBD5E1;
}
.fgx-stage{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden;}
.fgx-stage .dv2-vignette{opacity:calc(var(--fgx-vignette, .55) * var(--bg-veil, 1));}
.fgx-stage-bg{
  position:absolute;inset:0;
  background:
    var(--fgx-bg, none) center / cover no-repeat,
    linear-gradient(160deg, #0B1020, #101826 70%);
}
/* v0.62.1 : en-tête dans la colonne centrale (index.html), les trois
   colonnes partagent donc le même sommet, juste sous le HUD. */
.fgx-head{
  position:relative;flex:none;
  display:flex;flex-direction:column;align-items:stretch;gap:calc(8px*var(--scale));
}
.fgx-head-top{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;min-width:0;}
.fgx-head-txt{min-width:0;flex:1 1 auto;}
.fgx-head-zone{flex:none;display:flex;flex-direction:column;align-items:flex-end;gap:5px;padding-top:2px;}
.fgx-head-planet{
  font-family:var(--font-display);font-size:.95rem;letter-spacing:.12em;text-transform:uppercase;
  color:var(--ink-1);text-shadow:0 2px 12px rgba(4,10,18,.9);
}
.fgx-head-zone .fgx-tb-zone{background:var(--glass-dark);}
.fgx-head-txt h1{
  margin:0;font-family:var(--font-display);font-weight:700;font-size:1.15rem;letter-spacing:.14em;
  color:var(--ink-1);text-transform:uppercase;text-shadow:0 2px 12px rgba(4,10,18,.9);
}
.fgx-head-txt p{
  margin:3px 0 0;color:var(--ink-2);font-size:.8rem;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-shadow:0 1px 8px rgba(4,10,18,.9);
}
.fgx-tabs{flex:0 1 auto;margin:0;}
/* rangée onglets + bouton Arbre techno (v0.62.2), même hauteur qu'avant */
.fgx-head-row{display:flex;align-items:center;gap:10px;min-width:0;}
.fgx-head-row .tt-open-btn{margin-left:auto;}

.fgx-body{
  position:relative;z-index:20;flex:1 1 auto;min-height:0;
  display:grid;grid-template-columns:var(--fgx-left-w) minmax(0,1fr) var(--fgx-right-w);
  gap:var(--fgx-gap, 14px);align-items:stretch;
}
.fgx-col{min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:calc(8px*var(--scale));}
.fgx-center{display:flex;flex-direction:column;min-width:0;min-height:0;gap:calc(12px*var(--scale));overflow:hidden;}
/* [hidden] doit gagner sur `display:flex/grid` (bug v0.62.0 trouvé en
   contrôle navigateur : les 3 onglets restaient visibles superposés). */
.fgx-tabpanel{flex:1 1 auto;display:flex;flex-direction:column;gap:calc(12px*var(--scale));min-height:0;overflow-y:auto;}
/* v0.62.1 : Vue globale = grille à 3 rangées dédiées (toolbar, graphe
   borné, rangée du bas de hauteur fixe) : graphe et panneaux du bas ne
   peuvent plus se chevaucher. */
.fgx-tabpanel.fgx-tab-overview{
  display:grid;grid-template-columns:minmax(0,1fr);
  grid-template-rows:auto minmax(240px,1fr) var(--fgx-bottom-h);
}
.fgx-tabpanel[hidden]{display:none !important;}
.fgx-bottom-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.5fr);gap:calc(12px*var(--scale));min-height:0;}
.fgx-bottom-panel{display:flex;flex-direction:column;min-height:0;overflow:hidden;}
.fgx-bottom-panel .panel-body{flex:1 1 auto;min-height:0;overflow:hidden;}
/* livre de recettes en rangée : défilement horizontal interne (molette
   convertie, voir fgRenderRecipeBookInto), carte compacte (description
   et source restent dans l'onglet RECETTES plein page). */
.fgx-bottom-recipes .panel-body{padding:0 calc(12px*var(--scale));}
.fgx-bottom-recipes .fg-recipe-grid{
  height:100%;grid-template-columns:none;grid-auto-flow:column;grid-auto-columns:240px;
  gap:12px;align-items:start;overflow-x:auto;overflow-y:hidden;padding:6px 0;
}
.fgx-bottom-recipes .fg-recipe-card{padding:9px 11px;gap:5px;}
.fgx-bottom-recipes .fg-recipe-card .desc,
.fgx-bottom-recipes .fg-recipe-card .foot{display:none;}
.fgx-bottom-recipes .fg-recipe-card .btn{margin-top:4px !important;}
/* une ligne par élément dans la rangée (hauteur fixe), texte complet
   dans l'onglet RECETTES et les tooltips de ressource. */
.fgx-bottom-recipes .fg-recipe-head h3,
.fgx-bottom-recipes .fg-formula-text{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.fgx-bottom-recipes .fg-formula-row,
.fgx-bottom-recipes .fg-effect-row{flex-wrap:nowrap;overflow:hidden;}

/* ---------- panneaux translucides (même recette que .bldx-card) ----------
   v0.62.2 : verre sombre partagé (--glass-dark, css/01-tokens.css),
   mêmes valeurs que les panneaux Planète et Bâtiments. */
.fgx-card, .fgx-card-static, .fgx-cockpit{
  background:var(--glass-dark);backdrop-filter:blur(var(--glass-blur));-webkit-backdrop-filter:blur(var(--glass-blur));
  border:1px solid var(--glass-border);border-radius:var(--dv2-r-card);box-shadow:var(--shadow-deep);
  flex:none;
}
/* v0.62.3 : titre de panneau = texte principal (couche 3), plus gris */
.fgx-card .panel-head, .fgx-card-static .panel-head, .fgx-cockpit .panel-head{
  display:flex;align-items:center;gap:8px;
  padding:calc(9px*var(--scale)) calc(12px*var(--scale));
  font-family:var(--font-head);font-size:.8rem;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-1);
  border-bottom:1px solid var(--glass-border);
}
.fgx-card .panel-head .eyebrow, .fgx-cockpit .panel-head .eyebrow{margin-left:auto;}
.fgx-card .panel-body, .fgx-card-static .panel-body{padding:calc(9px*var(--scale)) calc(12px*var(--scale)) calc(12px*var(--scale));}
.fgx-card.collapsed .panel-body{display:none;}
.fgx-card.collapsed .panel-collapse svg{transform:rotate(-90deg);}
.fgx-cockpit{flex:1 1 auto;min-height:0;overflow-y:auto;display:flex;flex-direction:column;}
/* v0.62.1 : rien de sélectionné = panneau compact, jamais un vide
   pleine hauteur. */
.fgx-cockpit.is-empty{flex:none;}
/* v0.62.3 : cockpit aéré, sections séparées par un trait fin
   (IMAGE + flèches | STATS | CONTRÔLE | RECETTE | OUVRIERS | GÉRER). */
.fgx-cockpit-body{padding:14px 16px 16px;display:flex;flex-direction:column;gap:12px;}
.fgx-cockpit-sec{display:flex;flex-direction:column;gap:6px;min-width:0;}
.fgx-cockpit-sec + .fgx-cockpit-sec{border-top:1px solid var(--glass-border);padding-top:12px;}
.fgx-cockpit-sec > .fgx-cockpit-section-title{border-top:none;padding-top:0;margin:0 0 2px;}
.fgx-cockpit-name{display:flex;align-items:center;gap:8px;min-width:0;}
.fgx-cockpit-name h3{margin:0;font-family:var(--font-head);font-size:1rem;color:var(--ink-1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.fgx-cockpit-sec .desc{margin:0;color:var(--ink-2);}
.fgx-cockpit-empty{display:flex;flex-direction:column;gap:3px;padding:calc(10px*var(--scale)) calc(12px*var(--scale)) calc(12px*var(--scale));}
.fgx-cockpit-empty b{font-family:var(--font-head);font-weight:600;font-size:.84rem;color:var(--ink-1);}
.fgx-cockpit-empty span{font-size:.72rem;color:var(--ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.fgx-cockpit-art{
  position:relative;width:100%;height:120px;flex:none;border-radius:10px;overflow:hidden;
  background:var(--panel-soft);border:1px solid var(--line);
}
.fgx-cockpit-art .ag-art{--art-tint:var(--bld-cat);--art-ph-size:2.2rem;}
.fgx-cockpit-section-title{
  font-family:var(--font-head);font-size:.72rem;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-1);
  margin:0 0 6px;padding-top:calc(10px*var(--scale));border-top:1px solid var(--glass-border);
}
.fgx-cockpit-section-title:first-child{padding-top:0;border-top:none;}

/* ---------- colonne gauche : Colonie / Planètes ---------- */
.fgx-colony-head{display:flex;align-items:center;gap:10px;}
.fgx-colony-thumb{width:44px;height:44px;border-radius:10px;overflow:hidden;flex:none;background:var(--panel-soft);border:1px solid var(--line);}
.fgx-colony-thumb img{width:100%;height:100%;object-fit:cover;}
.fgx-colony-name{font-family:var(--font-head);font-size:.9rem;color:var(--ink-1);}
.fgx-colony-sub{display:flex;align-items:center;gap:6px;font-size:.7rem;color:var(--ink-3);margin-top:2px;}
.fgx-colony-dot{width:7px;height:7px;border-radius:50%;background:var(--ink-3);flex:none;}
.fgx-colony-dot.active{background:var(--lime);box-shadow:0 0 0 3px rgba(74,222,128,.16);}
.fgx-colony-dot.busy{background:var(--amber);box-shadow:0 0 0 3px rgba(245,158,11,.16);}
.fgx-mini-row{display:flex;align-items:center;justify-content:space-between;padding:calc(4px*var(--scale)) 0;font-size:.76rem;gap:10px;}
.fgx-mini-row .k{color:var(--ink-3);display:flex;align-items:center;gap:6px;}
.fgx-mini-row .v{font-family:var(--font-mono);color:var(--ink-1);display:flex;align-items:center;gap:4px;flex-wrap:wrap;justify-content:flex-end;}
.fgx-mini-row .v svg{width:13px;height:13px;flex:none;}

.fgx-planet-row{
  display:flex;align-items:center;gap:10px;padding:calc(6px*var(--scale)) calc(4px*var(--scale));
  border-radius:8px;cursor:pointer;transition:background .15s ease;border:1px solid transparent;
}
.fgx-planet-row:hover{background:rgba(45,212,191,.08);}
.fgx-planet-row.current{border-color:var(--cyan);box-shadow:0 0 0 1px var(--cyan) inset;}
.fgx-planet-thumb{width:30px;height:30px;border-radius:50%;overflow:hidden;flex:none;background:var(--panel-soft);border:1px solid var(--line);}
.fgx-planet-thumb img{width:100%;height:100%;object-fit:cover;}
.fgx-planet-info{min-width:0;flex:1;}
.fgx-planet-name{font-family:var(--font-head);font-size:.82rem;color:var(--ink-1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.fgx-planet-status{font-size:.68rem;color:var(--ink-3);}
.fgx-planet-status.active{color:var(--lime);}

/* v0.62.2 : panneau Production globale retiré (la tuile du même nom vit
   dans les Statistiques globales de la rangée du bas). */

.fgx-cat-row{
  display:flex;align-items:center;gap:8px;padding:calc(6px*var(--scale)) calc(4px*var(--scale));
  border-radius:8px;cursor:pointer;font-size:.8rem;color:var(--ink-2);transition:background .15s ease, color .15s ease;
}
.fgx-cat-row:hover{background:rgba(45,212,191,.08);color:var(--ink-1);}
.fgx-cat-row.active{background:color-mix(in srgb, var(--cyan) 16%, transparent);color:var(--ink-1);}
.fgx-cat-dot{width:8px;height:8px;border-radius:2px;flex:none;background:var(--bld-cat, var(--cyan));}
.fgx-cat-name{flex:1;min-width:0;}
.fgx-cat-count{font-family:var(--font-mono);font-size:.72rem;color:var(--ink-3);}

/* ---------- toolbar de la Vue globale ---------- */
.fgx-toolbar{
  flex:none;display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  background:var(--glass-dark);backdrop-filter:blur(var(--glass-blur));-webkit-backdrop-filter:blur(var(--glass-blur));
  border:1px solid var(--glass-border);border-radius:var(--dv2-r-card);box-shadow:var(--shadow-deep);
  padding:calc(8px*var(--scale)) calc(12px*var(--scale));
}
.fgx-tb-select{
  background:#121C2B;border:1px solid #1E2E40;border-radius:8px;color:var(--ink-1);
  font-family:var(--font-head);font-size:.76rem;padding:6px 10px;cursor:pointer;
}
.fgx-tb-select:focus{outline:none;border-color:var(--cyan);}
.fgx-legend{display:flex;align-items:center;gap:8px;font-size:.66rem;color:var(--ink-3);flex-wrap:wrap;}
.fgx-legend-item{display:flex;align-items:center;gap:5px;}
.fgx-legend-dot{width:8px;height:8px;border-radius:2px;flex:none;}
.fgx-legend-dot.ghost{background:none;border:1.5px dashed var(--ink-3);}
.fgx-legend-line{width:16px;height:2px;border-radius:2px;flex:none;}
.fgx-legend-line.flow-raw{background:var(--fgx-flow-raw);box-shadow:0 0 4px var(--fgx-flow-raw);}
.fgx-legend-line.flow-inter{background:var(--fgx-flow-inter);box-shadow:0 0 4px var(--fgx-flow-inter);}
.fgx-legend-line.flow-byproduct{background:var(--fgx-flow-byproduct);box-shadow:0 0 4px var(--fgx-flow-byproduct);}
.fgx-legend-lock svg{width:11px;height:11px;flex:none;}
.fgx-tb-search{position:relative;flex:1 1 110px;min-width:110px;max-width:220px;}
.fgx-tb-search svg{position:absolute;left:9px;top:50%;transform:translateY(-50%);width:14px;height:14px;color:var(--ink-3);pointer-events:none;}
.fgx-tb-search input{
  width:100%;background:#121C2B;border:1px solid #1E2E40;border-radius:8px;color:var(--ink-1);
  font-size:.78rem;padding:7px 10px 7px 30px;
}
.fgx-tb-search input:focus{outline:none;border-color:var(--cyan);}
.fgx-tb-zoom{display:flex;align-items:center;gap:4px;margin-left:auto;}
.fgx-tb-btn{
  width:26px;height:26px;display:flex;align-items:center;justify-content:center;
  background:#121C2B;border:1px solid #1E2E40;border-radius:8px;color:var(--ink-2);cursor:pointer;transition:.15s;
}
.fgx-tb-btn:hover{color:var(--cyan);border-color:var(--cyan);}
.fgx-tb-btn svg{width:14px;height:14px;}
.fgx-tb-zoom-val{font-family:var(--font-mono);font-size:.72rem;color:var(--ink-2);min-width:34px;text-align:center;}
.fgx-tb-zone{
  font-family:var(--font-mono);font-size:.68rem;color:var(--ink-3);
  border:1px solid var(--line);border-radius:20px;padding:4px 10px;white-space:nowrap;
}

/* ---------- graphe : zoom (transform) + plein écran ----------
   .fg-graph-zoom porte la taille RÉELLE (mise à l'échelle) pour que le
   scroll de .fg-graph-scroll corresponde au rendu visuel ; .fg-graph-
   canvas garde sa taille naturelle et porte le `transform:scale()`
   (AG.renderFlowGraphCanvas, js/13-screen-factories.js). */
.fg-graph-zoom{position:relative;}
.fg-graph-scroll:fullscreen{background:#0B1020;padding:20px;overflow:auto;}

/* ---------- nœud verrouillé (v0.62.0) : 3e état, distinct du fantôme ----------
   Fantôme = débloqué, pas construit (CTA "Construire"). Verrouillé =
   palier/chaîne pas encore atteint (aucune action possible ici, motif
   dans le tooltip riche `fgNode`, même convention que les cartes
   verrouillées de Bâtiments). */
.fg-node-card.locked{border-style:dashed;border-color:var(--ink-3);box-shadow:none;opacity:.55;cursor:default;}
.fg-node-card.locked .fg-node-thumb{filter:grayscale(.8);opacity:.5;}
.fg-node-card.locked .fg-node-head{cursor:default;}
.fg-node-lock{position:absolute;inset:0;z-index:4;display:flex;align-items:center;justify-content:center;color:var(--ink-2);}
.fg-node-lock svg{width:20px;height:20px;}

/* ---------- statistiques globales ---------- */
/* v0.62.1 : 6 tuiles en 3x2 qui remplissent la rangée du bas. */
.fgx-stats-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));grid-auto-rows:minmax(0,1fr);gap:8px;height:100%;}
.fgx-stat-tile{
  background:rgba(18,28,43,.55);border:1px solid var(--line);border-radius:10px;padding:8px 10px;
  display:flex;flex-direction:column;justify-content:space-between;min-width:0;min-height:0;
}
.fgx-stat-label{font-size:.62rem;line-height:1.25;color:var(--ink-3);text-transform:uppercase;letter-spacing:.05em;}
.fgx-stat-value{font-family:var(--font-mono);font-size:.95rem;color:var(--ink-1);margin-top:3px;display:flex;align-items:center;gap:5px;flex-wrap:wrap;}
.fgx-stat-value svg{width:14px;height:14px;flex:none;}

/* ---------- onglet Liste des usines ---------- */
.fgx-table-wrap{overflow-x:auto;}
.fgx-table{width:100%;border-collapse:collapse;font-size:.8rem;}
.fgx-table th{
  text-align:left;font-family:var(--font-head);font-size:.68rem;text-transform:uppercase;letter-spacing:.05em;
  color:var(--ink-3);padding:8px 10px;border-bottom:1px solid var(--line-strong);white-space:nowrap;
}
.fgx-table td{padding:9px 10px;border-bottom:1px solid var(--line);color:var(--ink-2);white-space:nowrap;}
.fgx-table tbody tr{cursor:pointer;transition:background .15s ease;}
.fgx-table tbody tr:hover{background:rgba(45,212,191,.06);}
.fgx-table tbody tr.selected{background:rgba(45,212,191,.12);}
.fgx-table td.name{color:var(--ink-1);font-family:var(--font-head);}
.fgx-table td.num{font-family:var(--font-mono);text-align:right;}

@media (max-width:1300px){
  .screen.fgx-fullbleed{overflow-y:auto;padding:var(--pad-lg) var(--pad-lg) var(--nav-gap);}
  .fgx-wrap{position:relative;inset:auto;padding:0;gap:12px;}
  .fgx-head{padding:0;}
  .fgx-stage{position:fixed;inset:0;}
  .fgx-body{display:flex;flex-direction:column;gap:12px;}
  .fgx-col{overflow:visible;}
  .fgx-col-left, .fgx-col-right{flex-direction:row;flex-wrap:wrap;}
  .fgx-col-left > *, .fgx-col-right > *{flex:1 1 260px;}
  .fgx-center, .fgx-tabpanel{overflow:visible;}
  .fgx-tabpanel.fgx-tab-overview{grid-template-rows:auto 440px auto;}
  .fgx-bottom-grid{grid-template-columns:1fr;}
  .fgx-bottom-panel, .fgx-bottom-panel .panel-body{overflow:visible;}
  .fgx-bottom-recipes .fg-recipe-grid{height:auto;}
}

/* ================= RECHERCHE : modales (v0.52.0) =================
   v0.74.0 : l'écran lui-même vit dans css/17-research.css (refonte) ;
   ne restent ici que les cartes de la modale de comparaison des
   doctrines et la modale "Vue d'ensemble". */

/* ---------- doctrine, palier X (v0.52.0, point 5) ----------
   `.opt` : cartes de la modale de comparaison (`.rs-doc-compare`). */
.rs-doc-compare{display:flex;gap:14px;margin-top:8px;flex-wrap:wrap;}
.opt{
  --rs-doc: var(--amber);
  flex:1;min-width:calc(240px*var(--scale));padding:calc(16px*var(--scale));border-radius:var(--r-md);
  background:var(--dv2-card-bg);border:1px solid var(--line-strong);border-top:3px solid var(--rs-doc);
  cursor:pointer;transition:.15s;position:relative;
}
.opt.doc-b{--rs-doc: var(--rose);}
.opt:hover{box-shadow:0 0 14px -6px var(--rs-doc);}
.opt.picked{box-shadow:0 0 0 2px var(--rs-doc);cursor:default;}
.opt.dimmed{opacity:.4;cursor:not-allowed;}
.opt.dimmed:hover{box-shadow:none;}
.opt.locked{opacity:.55;cursor:not-allowed;}
.opt.locked:hover{box-shadow:none;}
.doctrine-fx{display:flex;flex-direction:column;gap:2px;margin-top:8px;font-family:var(--font-mono);font-size:.68rem;color:var(--ink-2);}
.rs-doc-compare{margin:10px 0;}
.rs-doc-compare .opt{cursor:default;}
.rs-doc-compare .opt:hover{box-shadow:none;}

/* ---------- arbre technologique, modale "Vue d'ensemble" (point 6) ----------
   Réutilise les mêmes cartes/états ci-dessus (miniature), aucune classe
   .tnode/.ttree-* dupliquée. #modal impose déjà des dimensions fixes
   (css/03-components.css), il ne reste qu'à styler le contenu. */
.rs-ttree-legend{display:flex;flex-wrap:wrap;gap:14px;font-size:.72rem;color:var(--ink-3);margin-bottom:12px;}
.rs-ttree-legend span{display:flex;align-items:center;gap:6px;}
.rs-ttree-dot{width:9px;height:9px;border-radius:50%;display:inline-block;background:var(--line-strong);}
.rs-ttree-dot.done{background:var(--cyan);}
.rs-ttree-dot.active{background:var(--amber);}
.rs-ttree-dot.queued{background:var(--violet);}
.rs-ttree-dot.available{background:var(--rs-cat);}
.rs-ttree-dot.locked{background:var(--ink-3);}
.rs-ttree-band{border:1px solid var(--line);border-radius:var(--r-md);padding:calc(12px*var(--scale));margin-bottom:12px;background:var(--panel-soft);}
.rs-ttree-band.band-locked{opacity:.55;}
.rs-ttree-band-head{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;margin-bottom:10px;padding-bottom:8px;border-bottom:1px solid var(--line);}
.rs-ttree-palier{font-family:var(--font-display);font-size:.8rem;color:var(--amber);letter-spacing:.06em;}
.rs-ttree-band-name{font-family:var(--font-head);font-size:.9rem;}
.rs-ttree-band-meta{font-family:var(--font-mono);font-size:.66rem;color:var(--ink-3);margin-left:auto;}
.rs-ttree-cols{display:flex;gap:10px;overflow-x:auto;padding-bottom:6px;}
.rs-ttree-col{--rs-cat: var(--ink-3); flex:none;width:calc(150px*var(--scale));display:flex;flex-direction:column;gap:6px;}
.rs-ttree-branch{display:flex;align-items:center;gap:5px;font-family:var(--font-mono);font-size:.6rem;letter-spacing:.06em;text-transform:uppercase;color:var(--rs-cat);min-height:2.4em;}
.rs-ttree-branch svg{width:12px;height:12px;flex:none;}
.rs-tnode{padding:calc(8px*var(--scale));border-radius:var(--r-sm);border:1px solid var(--line-strong);background:var(--dv2-card-bg);cursor:pointer;transition:.15s;display:flex;flex-direction:column;gap:3px;}
.rs-tnode:hover{border-color:var(--rs-cat);box-shadow:0 0 10px -4px var(--rs-cat);}
.rs-tnode-n{font-size:.76rem;line-height:1.25;color:var(--ink-1);}
.rs-tnode-fx{font-family:var(--font-mono);font-size:.62rem;color:var(--ink-3);}
.rs-tnode.done{border-color:rgba(45,212,191,.5);background:rgba(45,212,191,.06);}
.rs-tnode.done .rs-tnode-n{color:var(--cyan);}
.rs-tnode.active{border-color:var(--amber);background:rgba(245,158,11,.08);box-shadow:0 0 0 2px rgba(245,158,11,.14);}
.rs-tnode.queued{border-color:var(--violet);background:rgba(167,139,250,.07);}
.rs-tnode.available{border-color:var(--rs-cat);}
.rs-tnode.locked{opacity:.5;}
.rs-tnode.locked:hover{border-color:var(--line-strong);box-shadow:none;}


/* ================= HANGAR =================
   v0.75.0 : tout l'écran Hangar vit dans css/18-hangar.css (refonte). */
