/* ═══════════ SGC MOBILE — Restyle portrait des sections (Phase 3) ═══════════
   Tout est scopé body.dev-phone.shell-on → n'affecte QUE la coquille mobile
   active (dark-launch), jamais le bureau ni les joueurs tant que le flag n'est
   pas basculé. Organisé par zone puis par section via [data-section].
   ───────────────────────────────────────────────────────────────────────── */

/* ════════ Chrome haute : récupérer de l'espace vertical ════════ */

/* NB : on NE masque PAS le rendu 3D de l'en-tête (#secHdr3D) — il affiche la
   planète, et l'utilisateur veut la voir quand le réglage « Planètes 3D » est
   activé. (Masquage retiré le 01/06 suite retour user.) */

/* Sélecteur de planète plus compact (gagne ~14px). */
body.dev-phone.shell-on .mob-planet-bar {
  padding: 3px 8px !important;
  min-height: 0 !important;
}

/* Barre de ressources resserrée (gagne ~8px) sans perdre la lisibilité. */
body.dev-phone.shell-on #resBar { padding-top: 2px; padding-bottom: 2px; }
body.dev-phone.shell-on .tb-resources { gap: 4px; }

/* ════════ Confort tactile global ════════ */

/* Cibles d'action confortables au doigt (≥44px) sur les boutons d'action
   courants des sections, sans toucher au bureau. */
body.dev-phone.shell-on .bld-upgrade-btn,
body.dev-phone.shell-on .res-upgrade-btn,
body.dev-phone.shell-on .ut-rec-btn-main,
body.dev-phone.shell-on .qty-max-btn,
body.dev-phone.shell-on .ut-qty-btn {
  min-height: 44px;
  touch-action: manipulation;
}

/* ════════ Modales → bottom sheets (ressenti natif) ════════ */

/* Pattern : l'overlay (fixed flex centré) ancre son contenu en bas, la boîte
   passe pleine largeur + coins arrondis en haut. Contenu (overflow-y:auto)
   scrollable. IMPORTANT : PAS d'animation pour positionner — une anim
   from{translateY(100%)} mise en pause (lowfx / idle-pause) laisserait la
   modale coincée hors écran. Position correcte SANS animation (cf. leçon
   lesson_css_animation_fill_mode_both_opacity_0). */
body.dev-phone.shell-on .cfm-overlay,
body.dev-phone.shell-on .cmd-detail-overlay,
body.dev-phone.shell-on .race-popup-overlay { align-items: flex-end; padding: 0; }
body.dev-phone.shell-on .cfm-modal,
body.dev-phone.shell-on .cmd-detail-box,
body.dev-phone.shell-on .race-popup {
  width: 100%; max-width: 100%; max-height: 88vh;
  border-radius: 18px 18px 0 0;
  animation: none !important;
  padding-bottom: env(safe-area-inset-bottom, 0px);
}

/* ════════ Tier C — Porte des Étoiles ════════ */

/* Débordement horizontal corrigé : les panneaux empilés gardaient une
   margin-left:8px (résidu du layout 3 colonnes) + width fixe → bord droit à
   401px sur 393. On les met pleine largeur sans marge latérale. */
body.dev-phone.shell-on #sf_gate { overflow-x: hidden; }
body.dev-phone.shell-on #sf_gate > .gpanel,
body.dev-phone.shell-on #sf_gate > .gate-center {
  width: 100% !important;
  max-width: 100% !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
}
/* NB : la barre des 7 modes reste en grille enroulée (tous les modes visibles).
   Un défilement horizontal cacherait des modes → moins bon UX, donc on garde. */

/* ════════ Cibles tactiles — Porte & Galaxie (design mobile, pas portage) ════════ */
/* Filtres/chips passés sous la cible confort de 44px → agrandis + centrés.
   Préfixe #sf_* pour battre les règles ID du jeu (cf. leçon spécificité). */
body.dev-phone.shell-on #sf_gate .gf-chip,
body.dev-phone.shell-on #sf_galaxy .gal-chip {
  min-height: 44px !important;
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  touch-action: manipulation;
}
body.dev-phone.shell-on #sf_galaxy .gal-coord-row input,
body.dev-phone.shell-on #sf_galaxy input[type="number"],
body.dev-phone.shell-on #sf_galaxy input[type="text"] {
  min-height: 44px !important;
  touch-action: manipulation;
}

/* ════════ Compactage du chrome galaxie (la LISTE doit primer sur mobile) ════════
   Audit prod iPhone : la 1ʳᵉ ligne démarrait à ~633px/852 (74% de chrome). Deux
   gros postes compactés ci-dessous. (Rework galaxie « app 2026 » 01/06.) */

/* Barre de filtres : 7 chips qui s'enroulaient sur ~4 rangées (158px) → une seule
   rangée à défilement horizontal (scroll-snap). Gagne ~114px. */
body.dev-phone.shell-on #galFilterBar {
  flex-wrap: nowrap !important;
  overflow-x: auto !important;
  overflow-y: hidden !important;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
body.dev-phone.shell-on #galFilterBar::-webkit-scrollbar { display: none; }
body.dev-phone.shell-on #galFilterBar .gal-chip {
  flex: 0 0 auto !important;
  scroll-snap-align: start;
  white-space: nowrap;
}

/* Banner Raid Mondial : 154px (sigil 46 + bloc 3 lignes) = trop sur la galaxie.
   Compacté en strip (~90px) : sigil réduit, padding serré, titre 1 ligne. */
body.dev-phone.shell-on #worldRaidBanner .wr-banner {
  padding: 8px 12px !important;
  gap: 10px !important;
  align-items: center !important;
}
body.dev-phone.shell-on #worldRaidBanner .wr-sigil {
  width: 40px !important; height: 40px !important;
  font-size: 22px !important; flex: 0 0 auto !important;
}
body.dev-phone.shell-on #worldRaidBanner .wr-banner-tag {
  font-size: 11px !important; line-height: 1.2 !important; margin-bottom: 1px !important;
}
body.dev-phone.shell-on #worldRaidBanner .wr-banner-name { font-size: 15px !important; }
body.dev-phone.shell-on #worldRaidBanner .wr-banner-cta { flex: 0 0 auto !important; }

/* Lignes de la liste galaxie : le reflow table en flex-wrap empilait chaque champ
   (nom plein largeur force-wrap → joueur → menace → actions) = ~158px/planète,
   ~1,5 planète/écran. Refonte en GRID 2 lignes (carte propre type app jeu) :
   ligne 1 = icône | nom | coords ; ligne 2 = icône | joueur+tier | menace | actions.
   → ~87px/planète (~2,5/écran). (Rework galaxie « app 2026 » 01/06.) */
body.dev-phone.shell-on #sf_galaxy .gal-tr:not(.empty) {
  display: grid !important;
  grid-template-columns: auto auto 1fr auto !important;
  grid-template-areas: "icon name name pos" "icon player threat actions" !important;
  align-items: center !important;
  column-gap: 8px !important; row-gap: 1px !important;
  padding: 7px 24px 7px 10px !important;
}
body.dev-phone.shell-on #sf_galaxy .gal-tr:not(.empty) .gal-td[data-label]::before { display: none !important; }
body.dev-phone.shell-on #sf_galaxy .gal-tr:not(.empty) > .gal-td.gal-pos { grid-area: pos !important; justify-self: end !important; font-size: 12px !important; }
body.dev-phone.shell-on #sf_galaxy .gal-tr:not(.empty) > .gal-td:nth-child(2) { grid-area: icon !important; }
body.dev-phone.shell-on #sf_galaxy .gal-tr:not(.empty) > .gal-td:nth-child(3) { grid-area: name !important; min-width: 0 !important; }
body.dev-phone.shell-on #sf_galaxy .gal-tr:not(.empty) > .gal-td:nth-child(4) { grid-area: player !important; min-width: 0 !important; }
body.dev-phone.shell-on #sf_galaxy .gal-tr:not(.empty) > .gal-td:nth-child(5) { display: none !important; }
body.dev-phone.shell-on #sf_galaxy .gal-tr:not(.empty) > .gal-td:nth-child(6) { grid-area: threat !important; }
body.dev-phone.shell-on #sf_galaxy .gal-tr:not(.empty) > .gal-td:last-child { grid-area: actions !important; justify-self: end !important; }
/* Lignes vides / colonisables : 1 ligne propre (icône | coords | actions) pour
   rester cohérent avec les cartes 2 lignes ci-dessus. */
body.dev-phone.shell-on #sf_galaxy .gal-tr.empty {
  display: grid !important;
  grid-template-columns: auto 1fr auto !important;
  grid-template-areas: "icon pos actions" !important;
  align-items: center !important; column-gap: 8px !important;
  padding: 8px 24px 8px 10px !important;
}
body.dev-phone.shell-on #sf_galaxy .gal-tr.empty > .gal-td:nth-child(2) { grid-area: icon !important; }
body.dev-phone.shell-on #sf_galaxy .gal-tr.empty > .gal-td.gal-pos { grid-area: pos !important; justify-self: start !important; }
body.dev-phone.shell-on #sf_galaxy .gal-tr.empty > .gal-td:last-child { grid-area: actions !important; justify-self: end !important; }

/* ════════ Galaxie TABLETTE — mêmes cartes que le tél ════════
   En split-view le tableau bureau (600px) était écrasé dans le conteneur liste
   (~380px) → colonnes Menace/Actions rognées. On passe la liste en pleine largeur
   (gal-layout en block) et on réutilise les cartes grid 2 lignes. (01/06) */
body.dev-tablet #sf_galaxy .gal-layout { display: block !important; }
body.dev-tablet #sf_galaxy .gal-table colgroup,
body.dev-tablet #sf_galaxy .gal-table thead { display: none !important; }
body.dev-tablet #sf_galaxy .gal-table,
body.dev-tablet #sf_galaxy .gal-table tbody { display: block !important; width: 100% !important; box-sizing: border-box !important; }
body.dev-tablet #sf_galaxy .gal-tr:not(.empty) {
  display: grid !important; width: 100% !important; box-sizing: border-box !important;
  grid-template-columns: auto auto 1fr auto !important;
  grid-template-areas: "icon name name pos" "icon player threat actions" !important;
  align-items: center !important; column-gap: 8px !important; row-gap: 2px !important;
  padding: 8px 14px !important; margin-bottom: 6px !important;
  border: 1px solid var(--tint-4) !important; border-radius: 8px !important;
}
body.dev-tablet #sf_galaxy .gal-tr .gal-td[data-label]::before { display: none !important; }
body.dev-tablet #sf_galaxy .gal-tr:not(.empty) > .gal-td.gal-pos { grid-area: pos !important; justify-self: end !important; }
body.dev-tablet #sf_galaxy .gal-tr:not(.empty) > .gal-td:nth-child(2) { grid-area: icon !important; }
body.dev-tablet #sf_galaxy .gal-tr:not(.empty) > .gal-td:nth-child(3) { grid-area: name !important; min-width: 0 !important; }
body.dev-tablet #sf_galaxy .gal-tr:not(.empty) > .gal-td:nth-child(4) { grid-area: player !important; min-width: 0 !important; }
body.dev-tablet #sf_galaxy .gal-tr:not(.empty) > .gal-td:nth-child(5) { display: none !important; }
body.dev-tablet #sf_galaxy .gal-tr:not(.empty) > .gal-td:nth-child(6) { grid-area: threat !important; }
body.dev-tablet #sf_galaxy .gal-tr:not(.empty) > .gal-td:last-child { grid-area: actions !important; justify-self: end !important; }
body.dev-tablet #sf_galaxy .gal-tr.empty {
  display: grid !important; grid-template-columns: auto 1fr auto !important;
  grid-template-areas: "icon pos actions" !important;
  align-items: center !important; column-gap: 8px !important; padding: 8px 14px !important;
}
body.dev-tablet #sf_galaxy .gal-tr.empty > .gal-td:nth-child(2) { grid-area: icon !important; }
body.dev-tablet #sf_galaxy .gal-tr.empty > .gal-td.gal-pos { grid-area: pos !important; }
body.dev-tablet #sf_galaxy .gal-tr.empty > .gal-td:last-child { grid-area: actions !important; justify-self: end !important; }

/* La barre d'action fixe de la Porte (dial/lancement de mission) doit rester
   au-dessus de la barre d'onglets, jamais collée dessous. La barre d'onglets
   fait ~64px → on dégage 72px (8px de marge), sinon le bas de la barre Porte
   passait sous les onglets (clip de ~4px à bottom:60px). */
body.dev-phone.shell-on .gate-btns {
  bottom: calc(72px + env(safe-area-inset-bottom, 0px)) !important;
}

/* Marge de défilement : quand on saute à un ancrage, on dégage la barre. */
body.dev-phone.shell-on { scroll-padding-bottom: 64px; }

/* ════════ Opérations ════════ */
/* Le glow du titre déborde légèrement à droite (fine ligne colorée au bord).
   On confine le débordement horizontal de la section. */
body.dev-phone.shell-on #sf_operations { overflow-x: hidden; }
body.dev-phone.shell-on #sf_operations .ops-hero { overflow: hidden; }
/* En-tête de section (Expéditions / Campagnes) : était un flex ROW
   [titre+description | badges] → les badges écrasaient le texte en colonne d'un
   mot par ligne ET débordaient. On empile en colonne : texte pleine largeur,
   badges dessous (avec wrap). */
body.dev-phone.shell-on #sf_operations .ops-sec-header {
  flex-direction: column !important;
  align-items: flex-start !important;
  gap: 8px;
}
body.dev-phone.shell-on #sf_operations .ops-sec-headline { width: 100% !important; }
body.dev-phone.shell-on #sf_operations .ops-sec-badges,
body.dev-phone.shell-on #sf_operations .ops-sec-header > *:last-child {
  flex-wrap: wrap !important;
  max-width: 100% !important;
}

/* Bouton vue « 3D » masqué sur téléphone : la carte 3D (THREE.js fullview) est
   trop lourde et rend mal sur tél → réservée bureau/tablette. La vue Liste est
   l'interface mobile (galSetView force 'list' sur phone). Scopé dev-phone (tous
   les téléphones, pas que la coquille). */
body.dev-phone .galcb-view[data-view="3d"] { display: none !important; }

/* ════════ Galaxie — menus/panneaux en bottom sheets (rework mobile) ════════ */
/* Le menu d'actions par ligne (⚡ ACTIONS → Porte/Flotte/Espionner) était un
   popover ancré sous l'icône → mal positionné/superposé sur mobile. On le
   transforme en bottom sheet plein largeur, ancré en bas (le JS pose left/top
   inline → on les écrase en !important). animation:none = pas de piège
   opacity:0 figé (lowfx/idle). */
body.dev-phone.shell-on .gal-actions-menu {
  position: fixed !important;
  left: 0 !important; right: 0 !important; bottom: 0 !important; top: auto !important;
  width: 100% !important; min-width: 0 !important; max-width: 100% !important;
  border-radius: 18px 18px 0 0 !important;
  z-index: 9800 !important;
  padding: 10px 12px calc(14px + env(safe-area-inset-bottom, 0px)) !important;
  animation: none !important;
  box-shadow: 0 -10px 40px var(--shade-5) !important;
}
body.dev-phone.shell-on .gal-actions-menu .gal-menu-item { min-height: 48px; }

/* LE bug racine : le sheet de détail galaxie (Apple Maps) a une animation
   d'entrée galSheetSpring (translateY(100%)→0). Mise en PAUSE par le mode
   Endurance/idle, elle reste figée à translateY(100%) → sheet HORS écran +
   backdrop visible = « bazar » illisible. On retire l'animation : le sheet
   repose directement bottom-anchored, toujours visible (le drag reste OK, il
   pilote la HAUTEUR pas le transform). Même piège que la modale de confirm. */
body.dev-phone.shell-on .gal-detail-panel.active {
  animation: none !important;
}
/* En mode plein écran (sélection de troupes), le « full » était bridé à ~60vh
   par une règle responsive → on débride pour vraiment occuper l'écran. */
body.dev-phone.shell-on .gal-detail-panel.active.full {
  max-height: 90dvh !important;
  height: 90dvh !important;
}

/* ════════ SÉLECTION DE TROUPES = MODALE PLEIN ÉCRAN PROPRE ════════
   Quand on clique attaque/flotte/espionnage, le panneau de troupes s'ouvre en
   vraie modale plein écran (classe gal-combat-modal posée par galShowBottomSheet)
   qui COUVRE toute la galaxie — fini le sheet draggable tangué. Header en haut,
   liste scrollable au milieu, barre Annuler/LANCER collée en bas. */
/* La section galaxie a un transform (translateY 3px) qui casse le position:fixed
   de la modale (piège connu : un ancêtre transformé rend le fixed relatif à lui).
   Quand la modale combat est ouverte, on neutralise ce transform → la modale
   couvre vraiment tout l'écran (topbar incluse). */
body.gal-combat-open.dev-phone.shell-on #sf_galaxy { transform: none !important; }

body.dev-phone.shell-on #galDetail.gal-combat-modal {
  position: fixed !important;
  inset: 0 !important; top: 0 !important; bottom: 0 !important; left: 0 !important; right: 0 !important;
  width: 100% !important; height: auto !important;
  max-height: none !important;
  margin: 0 !important; border: none !important; border-radius: 0 !important;
  z-index: 9900 !important;
  background: linear-gradient(180deg, #0b1426 0%, #070b16 100%) !important;
  padding: 0 !important;
  display: flex !important; flex-direction: column !important;
  animation: none !important; transform: none !important; transition: none !important;
}
body.dev-phone.shell-on #galDetail.gal-combat-modal::before { display: none !important; }
body.dev-phone.shell-on #galDetail.gal-combat-modal .atk-panel {
  flex: 1 1 auto !important; min-height: 0 !important;
  max-height: none !important; height: auto !important;
  overflow-y: auto !important; -webkit-overflow-scrolling: touch;
  padding: calc(16px + env(safe-area-inset-top, 0px)) 14px 0 14px !important;
  display: flex !important; flex-direction: column !important;
  background: none !important; border: none !important;
}
/* Titre de la cible en haut, bien visible */
body.dev-phone.shell-on #galDetail.gal-combat-modal .atk-panel-title {
  font-size: 18px !important; text-align: center; margin-bottom: 6px;
}
/* Barre d'action (Annuler / LANCER) collée en bas, toujours accessible */
body.dev-phone.shell-on #galDetail.gal-combat-modal .atk-actions,
body.dev-phone.shell-on #galDetail.gal-combat-modal .atk-actions-sticky,
body.dev-phone.shell-on #galDetail.gal-combat-modal .atk-btn-row {
  position: sticky !important; bottom: 0 !important; z-index: 2;
  margin: 10px -14px 0 -14px !important;
  padding: 12px 14px calc(12px + env(safe-area-inset-bottom, 0px)) 14px !important;
  background: rgba(6,10,20,0.97) !important;
  border-top: 1px solid rgba(120,170,255,0.25) !important;
  display: flex !important; gap: 10px !important;
}
body.dev-phone.shell-on #galDetail.gal-combat-modal .atk-btn { flex: 1 1 auto !important; min-height: 50px !important; }
/* Barre d'action empilée : résumé Flotte au-dessus, boutons en ligne pleine
   largeur en dessous. Avant : [résumé | boutons] sur une ligne → le conteneur
   boutons trop étroit faisait passer « LANCER L'ATTAQUE » sur 3 lignes (barre
   ~305px) et « Annuler » coupé en « Annul er ». Fond opaque pour ne plus laisser
   transparaître les cartes d'unité derrière. (Fix polish 01/06.) */
body.dev-phone.shell-on #galDetail.gal-combat-modal .atk-actions-sticky {
  flex-direction: column !important; align-items: stretch !important;
  background: #060a14 !important;
}
body.dev-phone.shell-on #galDetail.gal-combat-modal .atk-actions-sticky .atk-power {
  text-align: center !important; margin: 0 0 2px 0 !important;
}
body.dev-phone.shell-on #galDetail.gal-combat-modal .atk-actions-sticky .atk-actions {
  display: flex !important; gap: 10px !important; width: 100% !important;
  margin: 0 !important; padding: 0 !important; background: none !important; border: none !important;
}
body.dev-phone.shell-on #galDetail.gal-combat-modal .atk-actions-sticky .atk-actions > button {
  white-space: nowrap !important; min-height: 50px !important;
  font-size: 13.5px !important; letter-spacing: 0 !important;
}
body.dev-phone.shell-on #galDetail.gal-combat-modal .atk-actions-sticky .atk-actions > button:first-child {
  flex: 0 0 auto !important; padding-left: 18px !important; padding-right: 18px !important;
}
body.dev-phone.shell-on #galDetail.gal-combat-modal .atk-actions-sticky .atk-actions > button:last-child {
  flex: 1 1 auto !important;
}
/* Le backdrop du sheet est inutile (la modale couvre tout) — masqué. */
body.dev-phone.shell-on #galDetail.gal-combat-modal ~ .gal-detail-backdrop { display: none !important; }
/* ── Lignes d'unité (sélection de troupes) refaites pour mobile ──
   Avant : .atk-unit-left en flex:1 1 100% + controls → noms qui débordaient
   ET se chevauchaient sur les boutons. Maintenant : carte empilée propre —
   ligne 1 = icône + nom (tronqué) + stats ; ligne 2 = −/saisie/MAX à droite. */
body.dev-phone.shell-on .gal-detail-panel .atk-unit-row {
  display: flex !important;
  flex-direction: column !important;
  align-items: stretch !important;
  gap: 6px;
  padding: 8px 10px;
}
body.dev-phone.shell-on .gal-detail-panel .atk-unit-left {
  width: 100% !important; flex: none !important; min-width: 0 !important;
  align-items: center;
}
body.dev-phone.shell-on .gal-detail-panel .atk-unit-left > div { min-width: 0 !important; flex: 1 1 auto; }
body.dev-phone.shell-on .gal-detail-panel .atk-unit-name {
  white-space: nowrap !important; overflow: hidden !important;
  text-overflow: ellipsis !important; max-width: 100% !important;
}
body.dev-phone.shell-on .gal-detail-panel .atk-unit-controls {
  width: 100% !important; flex: none !important;
  justify-content: flex-end !important; gap: 8px;
}
body.dev-phone.shell-on .gal-detail-panel .atk-unit-input { min-height: 40px; width: 64px !important; }
body.dev-phone.shell-on .gal-detail-panel .gts-pm,
body.dev-phone.shell-on .gal-detail-panel .qty-max-btn { min-height: 40px; min-width: 40px; }

/* ════════ Vue planète (panneau flottant 🪐) ════════ */
/* Retire la vieille illustration Gemini (IconesPlanetes/planet_XX.png) ET le
   rendu 3D défaillant de cette bannière (canvas noir vide ≠ celui de l'overview
   qui marche). Bannière spatiale propre + compacte. Le vrai planète 3D reste
   visible sur l'overview. (Retour user 01/06 : « pas digne d'une app ».) */
/* On masque la vieille illustration Gemini (rpHeroImg) — le rendu 3D la
   remplace (remonté à l'ouverture du panneau par sgc-3d-overview-bridge). Si le
   3D échoue, le gradient propre ci-dessous sert de fond (jamais la vieille illu). */
body.dev-phone.shell-on #rpHeroImg,
body.dev-phone.shell-on .rp-hero-banner .rp-hero-img { display: none !important; }
body.dev-phone.shell-on .rp-hero-banner {
  height: 132px !important; min-height: 132px !important;
  border: 1px solid rgba(120,170,255,0.22) !important;
  background:
    radial-gradient(ellipse at 50% 38%, rgba(80,120,210,0.30), transparent 70%),
    linear-gradient(160deg, #0f1a36 0%, #0a1020 60%, #070b16 100%) !important;
}
/* Bouclier actif : lueur subtile au lieu d'un cadre orange dur (le statut reste
   indiqué par le badge texte « Bouclier planétaire : actif » dessous). */
body.dev-phone.shell-on .rp-hero-shield {
  border: none !important;
  box-shadow: none !important;
  background: radial-gradient(ellipse at 50% 50%, rgba(255,150,50,0.12), transparent 70%) !important;
}

/* ════════ Mode Destinée — header mobile (anti-chevauchement) ════════
   Le header du hub est en position absolue calibrée pour le BUREAU (titre à
   gauche, badge de phase centré, SORTIR à droite). Sur 393px, le badge de phase
   chevauchait les jauges karma + texte tronqué « FTL EN C… ». Empilement propre
   sur dev-phone (le hub vit hors de la coquille → pas de .shell-on). (01/06) */
body.dev-phone #destinyHubClose { top: 10px !important; right: 10px !important; padding: 8px 14px !important; }
body.dev-phone #destinyHubHeader { top: 10px !important; left: 12px !important; right: 92px !important; }
body.dev-phone #destinyHubHeader .dst-h1 { font-size: 16px !important; letter-spacing: 3px !important; }
/* Jauges karma mini masquées sur tél : trop hautes (3 mini-bars = 56px) → elles
   chevauchaient le badge de phase. Le karma reste accessible via l'icône ⌖ du dock. */
body.dev-phone #destinyHubKarmaGauges { display: none !important; }
body.dev-phone #destinyHubPhaseBadge {
  top: 58px !important; bottom: auto !important;
  left: 12px !important; right: 12px !important;
  transform: none !important;
  text-align: center !important;
  font-size: 9.5px !important; letter-spacing: 1.5px !important;
  line-height: 1.35 !important; padding: 6px 10px !important;
  white-space: normal !important;
}
/* Le contenu interne du badge = flex row [phase | label | compte à rebours] qui
   ne tenait pas sur 369px (texte tronqué « FTL EN CO… »). On l'autorise à passer
   sur 2 lignes centrées. */
body.dev-phone #destinyHubPhaseBadge > div {
  flex-wrap: wrap !important;
  justify-content: center !important;
  gap: 2px 8px !important;
}
/* Titre des sous-panneaux Destinée (hero) : 38px → le titre sur 3 lignes était
   plus haut que la bannière hero, centré verticalement donc rogné en haut
   (« QUARTIERS » coupé). Réduit pour tenir dans la bannière sur mobile. */
body.dev-phone .dst-panel-hero .dst-h1 { font-size: 21px !important; line-height: 1.12 !important; }
body.dev-tablet .dst-panel-hero .dst-h1 { font-size: 28px !important; line-height: 1.12 !important; }
/* Bouton FERMER des sous-panneaux Destinée : fond transparent + couvert par
   .dst-panel-hero-overlay (bannière) → invisible ET non cliquable sur mobile
   (« impossible de fermer les menus »). On le remonte au-dessus (z-index) avec
   un fond visible, et on laisse passer les clics à travers l'overlay déco. */
body.dev-phone .dst-modal-overlay [class*="-close"],
body.dev-tablet .dst-modal-overlay [class*="-close"] {
  position: absolute !important; top: 10px !important; right: 10px !important; z-index: 60 !important;
  background: rgba(8,12,20,0.92) !important;
  border: 1px solid var(--dst-gold, #d4b483) !important; border-radius: 8px !important;
  color: var(--dst-gold, #d4b483) !important; padding: 8px 14px !important;
}
body.dev-phone .dst-panel-hero-overlay,
body.dev-tablet .dst-panel-hero-overlay { pointer-events: none !important; }

/* QTE (mini-jeu de timing au lancement de mission Porte) : pas de délai/zoom tactile. */
body.dev-phone .dst-qte-ring, body.dev-tablet .dst-qte-ring { touch-action: manipulation !important; }

/* Titre des chapitres/briefings (.dst-evt-title / briefing) : trop grand → débordait
   sur les tuiles spécialistes et interceptait les taps. Réduit sur mobile/tablette. */
body.dev-phone .dst-evt-title, body.dev-phone .dst-win-brief .dst-h1 { font-size: 20px !important; line-height: 1.15 !important; }
body.dev-tablet .dst-evt-title, body.dev-tablet .dst-win-brief .dst-h1 { font-size: 24px !important; line-height: 1.15 !important; }

/* Journal de Bord : en-tête flex [titre large | FERMER] en nowrap → FERMER poussé
   hors écran à droite (« bouton fermer coupé »). On rend le titre rétrécissable
   (ellipsis) et on fige FERMER pour qu'il reste visible. */
body.dev-phone .dst-journal-panel > div:first-child,
body.dev-tablet .dst-journal-panel > div:first-child { min-width: 0 !important; gap: 8px !important; }
body.dev-phone .dst-journal-panel > div:first-child > *:not(button),
body.dev-tablet .dst-journal-panel > div:first-child > *:not(button) {
  min-width: 0 !important; overflow: hidden !important; text-overflow: ellipsis !important; white-space: nowrap !important;
}
body.dev-phone .dst-journal-panel > div:first-child > button,
body.dev-tablet .dst-journal-panel > div:first-child > button { flex: 0 0 auto !important; }

/* ════════ Mode Destinée — header TABLETTE ════════
   820px est plus étroit que le bureau : le badge de phase centré chevauchait le
   titre DESTINÉE. On le descend sous le bloc titre (centré). Les jauges karma
   restent visibles (place dispo sur tablette). (01/06) */
body.dev-tablet #destinyHubPhaseBadge { top: 160px !important; }

/* ════════════ Sous-onglets de section — STYLE MOBILE UNIFIÉ (01/06) ════════════
   Harmonise TOUS les systèmes d'onglets (infra, alliance, rapports, marché, cité,
   ascension, codex, commandants, chat, quêtes, classement, apothéose, guerres,
   pont, messages, simulateur) en une barre de pilules à défilement horizontal ;
   onglet actif = accent de faction rempli. dev-phone + dev-tablet. */
body.dev-phone :is(.bld-tabs-main,.al-tab-bar,.alhq-subtab-bar,.ap-tabs,.asc-tabs,.brd-tabs,.chat-tab-bar,.city-tabs,.cmd-tab-bar,.rnk-tab-bar,.mkt-tabs,.quest-tabs,.cdx-tabs,.sim-mode-tabs),
body.dev-tablet :is(.bld-tabs-main,.al-tab-bar,.alhq-subtab-bar,.ap-tabs,.asc-tabs,.brd-tabs,.chat-tab-bar,.city-tabs,.cmd-tab-bar,.rnk-tab-bar,.mkt-tabs,.quest-tabs,.cdx-tabs,.sim-mode-tabs) {
  display: flex !important; flex-wrap: nowrap !important;
  /* flex-start OBLIGATOIRE : la base .al-tab-bar (sgc-sections.css) pose
     justify-content:center. Sur un scroller horizontal, centrer du contenu qui
     déborde rejette les 1ers onglets à GAUCHE du point 0 → scrollLeft ne peut pas
     être négatif → onglet(s) de gauche INACCESSIBLES (bug paysage : « Aperçu »
     coincé avant « Membres »). flex-start ancre le contenu au départ. */
  justify-content: flex-start !important;
  overflow-x: auto !important; overflow-y: hidden !important;
  gap: 8px !important; padding: 6px 8px !important; margin: 0 0 10px !important;
  border: 0 !important; background: none !important;
  scrollbar-width: none !important; -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
}
body.dev-phone :is(.bld-tabs-main,.al-tab-bar,.alhq-subtab-bar,.ap-tabs,.asc-tabs,.brd-tabs,.chat-tab-bar,.city-tabs,.cmd-tab-bar,.rnk-tab-bar,.mkt-tabs,.quest-tabs,.cdx-tabs,.sim-mode-tabs)::-webkit-scrollbar,
body.dev-tablet :is(.bld-tabs-main,.al-tab-bar,.alhq-subtab-bar,.ap-tabs,.asc-tabs,.brd-tabs,.chat-tab-bar,.city-tabs,.cmd-tab-bar,.rnk-tab-bar,.mkt-tabs,.quest-tabs,.cdx-tabs,.sim-mode-tabs)::-webkit-scrollbar { display: none !important; }

/* Pilules (items) — état inactif */
body.dev-phone :is(.bld-tab-main,.al-tab-pill,.al-nt-pill,.alhq-subtab-pill,.ap-tab,.asc-tab,.war-sub-pill,.brd-tab,.chat-tab-pill,.city-tab,.msg-tab,.rnk-tab-btn,.rep-tab,.mkt-tab,.quest-tab,.cdx-tab,.cmd-tab,.sim-mode-tab),
body.dev-tablet :is(.bld-tab-main,.al-tab-pill,.al-nt-pill,.alhq-subtab-pill,.ap-tab,.asc-tab,.war-sub-pill,.brd-tab,.chat-tab-pill,.city-tab,.msg-tab,.rnk-tab-btn,.rep-tab,.mkt-tab,.quest-tab,.cdx-tab,.cmd-tab,.sim-mode-tab) {
  flex: 0 0 auto !important; scroll-snap-align: start;
  min-height: 44px !important;
  display: inline-flex !important; align-items: center !important; justify-content: center !important; gap: 6px !important;
  padding: 8px 14px !important; margin: 0 !important;
  border-radius: 999px !important;
  border: 1px solid rgba(140,170,220,0.22) !important;
  background: var(--tint-4) !important;
  color: var(--textsoft, #c3cee0) !important;
  font-size: 12px !important; font-weight: 600 !important; white-space: nowrap !important;
  letter-spacing: 0.3px !important; box-shadow: none !important; opacity: 1 !important;
}
/* Pilule ACTIVE = accent de faction rempli */
body.dev-phone :is(.bld-tab-main,.al-tab-pill,.al-nt-pill,.alhq-subtab-pill,.ap-tab,.asc-tab,.war-sub-pill,.brd-tab,.chat-tab-pill,.city-tab,.msg-tab,.rnk-tab-btn,.rep-tab,.mkt-tab,.quest-tab,.cdx-tab,.cmd-tab,.sim-mode-tab).active,
body.dev-tablet :is(.bld-tab-main,.al-tab-pill,.al-nt-pill,.alhq-subtab-pill,.ap-tab,.asc-tab,.war-sub-pill,.brd-tab,.chat-tab-pill,.city-tab,.msg-tab,.rnk-tab-btn,.rep-tab,.mkt-tab,.quest-tab,.cdx-tab,.cmd-tab,.sim-mode-tab).active {
  background: linear-gradient(135deg, rgba(var(--accent-rgb,255,138,61),0.95), rgba(var(--accent-rgb,255,138,61),0.66)) !important;
  color: #fff !important;
  border-color: rgba(var(--accent-rgb,255,138,61),0.9) !important;
  box-shadow: 0 2px 12px rgba(var(--accent-rgb,255,138,61),0.4) !important;
  font-weight: 800 !important;
}

/* ════════════ SYSTÈME DE BOUTONS MOBILE — design unifié (02/06) ════════════
   Élève les boutons d'ACTION en tiers visuels cohérents (« vraie app » au lieu
   de boutons fantômes plats à 8% d'opacité). Les ONGLETS sont déjà harmonisés
   plus haut — ici ce sont les CTA, danger, steppers, secondaires.
   • dev-phone + dev-tablet, jamais le bureau (pointeur fin).
   • Réutilise var(--accent-rgb) → conserve la couleur de faction.
   • On NE touche PAS les boutons déjà fortement thématisés : Destinée (dst-*),
     dons (don-*), Pass (pass-* et pdaily-*), Battle Pass premium (bp-*), ni les
     boutons d'état riches (qa-btn), ni les cartes/lignes (qa-card, *-item…).
   • États préservés : .building (chantier orange), btn-no-prereq/res (bloqué),
     cmd-btn-ascend (or). Variantes danger placées après la base (cascade). */

/* ── TIER PRIMAIRE — CTA principal rempli (AMÉLIORER, LANCER, RÉCLAMER, …) ── */
body.dev-phone :is(.cmdc-action,.ov-empty-event-cta,.rep-empty-cta,.bld-upgrade-btn,.rp-upgrade-btn,.ut-rec-btn-main,.uc-train,.sc-build,.cmd-btn:not(.cmd-btn-ascend),.gal-action-btn,.atk-btn,.atk-btn-go,.atk-btn-launch,.gap-launch-btn,.gbtn-e,.mkt-accept-btn,.mkt-submit-btn,.quest-claim-btn,.quest-claimall-btn,.dist-claim-btn,.dist-claimall-btn,.camp-btn,.asc-btn,.ap-btn-primary,.gj-claim,.gj-recover-btn,.sos-accept-btn,.art-frag-craft-btn,.cfm-btn-confirm,.msg-compose-btn,.al-chat-send,.fr-btn-accept,.peEdit-btn-save,.auth-btn,.al-submit-btn,.al-join-btn,.al-motd-btn-primary,.alhq-found-btn,.alhq-upgrade-btn,.alhq-fill-btn,.alhq-fund-btn,.alhq-train-btn,.alhq-action-btn,.war-atk-btn,.war-roster-btn,.al-diplo-btn-nap,.city-tech-btn,.city-relique-btn,.surv-act-btn,.ops-card-btn,.evt-engage-btn),
body.dev-tablet :is(.cmdc-action,.ov-empty-event-cta,.rep-empty-cta,.bld-upgrade-btn,.rp-upgrade-btn,.ut-rec-btn-main,.uc-train,.sc-build,.cmd-btn:not(.cmd-btn-ascend),.gal-action-btn,.atk-btn,.atk-btn-go,.atk-btn-launch,.gap-launch-btn,.gbtn-e,.mkt-accept-btn,.mkt-submit-btn,.quest-claim-btn,.quest-claimall-btn,.dist-claim-btn,.dist-claimall-btn,.camp-btn,.asc-btn,.ap-btn-primary,.gj-claim,.gj-recover-btn,.sos-accept-btn,.art-frag-craft-btn,.cfm-btn-confirm,.msg-compose-btn,.al-chat-send,.fr-btn-accept,.peEdit-btn-save,.auth-btn,.al-submit-btn,.al-join-btn,.al-motd-btn-primary,.alhq-found-btn,.alhq-upgrade-btn,.alhq-fill-btn,.alhq-fund-btn,.alhq-train-btn,.alhq-action-btn,.war-atk-btn,.war-roster-btn,.al-diplo-btn-nap,.city-tech-btn,.city-relique-btn,.surv-act-btn,.ops-card-btn,.evt-engage-btn) {
  min-height: 46px !important;
  border-radius: 12px !important;
  border: 1px solid rgba(var(--accent-rgb,255,138,61),0.92) !important;
  background: linear-gradient(135deg, rgba(var(--accent-rgb,255,138,61),0.96), rgba(var(--accent-rgb,255,138,61),0.60)) !important;
  color: #fff !important;
  text-shadow: 0 1px 2px rgba(0,0,0,0.40) !important;
  font-weight: 800 !important;
  letter-spacing: 0.4px !important;
  box-shadow: 0 3px 14px rgba(var(--accent-rgb,255,138,61),0.38), inset 0 1px 0 rgba(255,255,255,0.22) !important;  transition: transform 0.12s ease, filter 0.12s ease, box-shadow 0.12s ease !important;
  touch-action: manipulation;
}
body.dev-phone :is(.cmdc-action,.bld-upgrade-btn,.rp-upgrade-btn,.ut-rec-btn-main,.uc-train,.sc-build,.cmd-btn:not(.cmd-btn-ascend),.gal-action-btn,.atk-btn,.atk-btn-go,.atk-btn-launch,.gap-launch-btn,.gbtn-e,.mkt-accept-btn,.mkt-submit-btn,.quest-claim-btn,.quest-claimall-btn,.dist-claim-btn,.dist-claimall-btn,.camp-btn,.asc-btn,.ap-btn-primary,.gj-claim,.gj-recover-btn,.sos-accept-btn,.cfm-btn-confirm,.msg-compose-btn,.al-chat-send,.fr-btn-accept,.peEdit-btn-save,.al-submit-btn,.al-join-btn,.al-motd-btn-primary,.alhq-found-btn,.alhq-upgrade-btn,.alhq-fill-btn,.alhq-fund-btn,.alhq-train-btn,.alhq-action-btn,.war-atk-btn,.war-roster-btn,.al-diplo-btn-nap,.city-tech-btn,.surv-act-btn,.ops-card-btn):active,
body.dev-tablet :is(.cmdc-action,.bld-upgrade-btn,.rp-upgrade-btn,.ut-rec-btn-main,.uc-train,.sc-build,.cmd-btn:not(.cmd-btn-ascend),.gal-action-btn,.atk-btn,.atk-btn-go,.atk-btn-launch,.gap-launch-btn,.gbtn-e,.mkt-accept-btn,.mkt-submit-btn,.quest-claim-btn,.quest-claimall-btn,.dist-claim-btn,.dist-claimall-btn,.camp-btn,.asc-btn,.ap-btn-primary,.gj-claim,.gj-recover-btn,.sos-accept-btn,.cfm-btn-confirm,.msg-compose-btn,.al-chat-send,.fr-btn-accept,.peEdit-btn-save,.al-submit-btn,.al-join-btn,.al-motd-btn-primary,.alhq-found-btn,.alhq-upgrade-btn,.alhq-fill-btn,.alhq-fund-btn,.alhq-train-btn,.alhq-action-btn,.war-atk-btn,.war-roster-btn,.al-diplo-btn-nap,.city-tech-btn,.surv-act-btn,.ops-card-btn):active {
  transform: scale(0.97) !important;
  filter: brightness(1.10) !important;
}
/* États préservés du bouton bâtiment : chantier en cours = ambre, pas accent */
body.dev-phone .bld-upgrade-btn.building, body.dev-tablet .bld-upgrade-btn.building,
body.dev-phone .rp-upgrade-btn.building, body.dev-tablet .rp-upgrade-btn.building {
  background: linear-gradient(135deg, rgba(240,170,60,0.92), rgba(200,120,30,0.58)) !important;
  border-color: rgba(240,170,60,0.9) !important;
  box-shadow: 0 3px 14px rgba(240,170,60,0.34), inset 0 1px 0 rgba(255,255,255,0.18) !important;
}
/* Prérequis/ressources manquants = aspect bloqué (pas un CTA brillant) */
body.dev-phone :is(.rp-upgrade-btn.btn-no-prereq,.rp-upgrade-btn.btn-no-res,.bld-upgrade-btn.btn-no-prereq,.bld-upgrade-btn.btn-no-res),
body.dev-tablet :is(.rp-upgrade-btn.btn-no-prereq,.rp-upgrade-btn.btn-no-res,.bld-upgrade-btn.btn-no-prereq,.bld-upgrade-btn.btn-no-res) {
  background: rgba(255,90,90,0.10) !important;
  border-color: rgba(255,90,90,0.45) !important;
  color: #ffb3b3 !important;
  text-shadow: none !important;
  box-shadow: none !important;
}

/* ── TIER DANGER — actions destructives (ANNULER, STOP, QUITTER, SUPPRIMER) ── */
body.dev-phone :is(.og-cancel-btn,.mkt-cancel-btn,.msg-del,.fr-btn-danger,.prof2-btn-atk,.al-leave-btn,.al-diplo-btn-cancel,.alhq-recall-btn,.gbtn-a,.banner-btn.danger,.gal-action-btn.attack,.ops-card-btn--warn),
body.dev-tablet :is(.og-cancel-btn,.mkt-cancel-btn,.msg-del,.fr-btn-danger,.prof2-btn-atk,.al-leave-btn,.al-diplo-btn-cancel,.alhq-recall-btn,.gbtn-a,.banner-btn.danger,.gal-action-btn.attack,.ops-card-btn--warn) {
  min-height: 44px !important;
  border-radius: 12px !important;
  border: 1px solid rgba(255,92,92,0.85) !important;
  background: linear-gradient(135deg, rgba(255,86,86,0.92), rgba(176,38,38,0.62)) !important;
  color: #fff !important;
  text-shadow: 0 1px 2px rgba(0,0,0,0.40) !important;
  font-weight: 800 !important;
  box-shadow: 0 3px 14px rgba(220,50,50,0.34), inset 0 1px 0 rgba(255,255,255,0.16) !important;  touch-action: manipulation;
}
body.dev-phone :is(.og-cancel-btn,.mkt-cancel-btn,.msg-del,.al-leave-btn,.al-diplo-btn-cancel,.gbtn-a,.gal-action-btn.attack,.ops-card-btn--warn):active,
body.dev-tablet :is(.og-cancel-btn,.mkt-cancel-btn,.msg-del,.al-leave-btn,.al-diplo-btn-cancel,.gbtn-a,.gal-action-btn.attack,.ops-card-btn--warn):active {
  transform: scale(0.97) !important; filter: brightness(1.10) !important;
}

/* ── TIER STEPPER — contrôles de quantité (− + MAX) compacts et lisibles ── */
body.dev-phone :is(.ut-qty-btn,.qty-max-btn,.gts-pm,.gts-card-max-btn,.gts-toolbar-max,.gap-max-btn,.tal-add,.tal-add-sm,.alhq-max-btn),
body.dev-tablet :is(.ut-qty-btn,.qty-max-btn,.gts-pm,.gts-card-max-btn,.gts-toolbar-max,.gap-max-btn,.tal-add,.tal-add-sm,.alhq-max-btn) {
  min-height: 42px !important; min-width: 42px !important;
  border-radius: 10px !important;
  border: 1px solid rgba(var(--accent-rgb,255,138,61),0.45) !important;
  background: rgba(var(--accent-rgb,255,138,61),0.12) !important;
  color: #eaf2ff !important;
  font-weight: 700 !important; font-size: 13px !important;
  display: inline-flex !important; align-items: center !important; justify-content: center !important;
  touch-action: manipulation;
}
body.dev-phone :is(.ut-qty-btn,.qty-max-btn,.gts-pm,.gts-card-max-btn,.gts-toolbar-max,.gap-max-btn,.tal-add,.tal-add-sm,.alhq-max-btn):active,
body.dev-tablet :is(.ut-qty-btn,.qty-max-btn,.gts-pm,.gts-card-max-btn,.gts-toolbar-max,.gap-max-btn,.tal-add,.tal-add-sm,.alhq-max-btn):active {
  background: rgba(var(--accent-rgb,255,138,61),0.28) !important; transform: scale(0.94) !important;
}

/* ── TIER SECONDAIRE — boutons neutres (Annuler, Plus tard, Compact) ── */
body.dev-phone :is(.cfm-btn-cancel,.atk-btn-cancel,.peEdit-btn-cancel,.al-motd-btn-ghost,.ops-card-btn--dim,.aec-btn-ghost),
body.dev-tablet :is(.cfm-btn-cancel,.atk-btn-cancel,.peEdit-btn-cancel,.al-motd-btn-ghost,.ops-card-btn--dim,.aec-btn-ghost) {
  min-height: 44px !important;
  border-radius: 12px !important;
  border: 1px solid rgba(var(--accent-rgb,255,138,61),0.32) !important;
  background: var(--tint-4) !important;
  color: var(--textbright, #e3ecfb) !important;
  font-weight: 700 !important;
  box-shadow: none !important;
  touch-action: manipulation;
}
body.dev-phone :is(.cfm-btn-cancel,.atk-btn-cancel,.peEdit-btn-cancel,.al-motd-btn-ghost,.ops-card-btn--dim,.aec-btn-ghost):active,
body.dev-tablet :is(.cfm-btn-cancel,.atk-btn-cancel,.peEdit-btn-cancel,.al-motd-btn-ghost,.ops-card-btn--dim,.aec-btn-ghost):active {
  background: rgba(255,255,255,0.10) !important; transform: scale(0.97) !important;
}

/* ── Onglets/boutons de mode de la Porte (gmt/gmf/gprt-tab) : coins arrondis +
   police lisible, pour s'aligner sur le langage « pilule » du reste du jeu
   (ils étaient en border-radius:0 = rectangles secs, incohérents). ── */
body.dev-phone :is(.gmt,.gmf,.gprt-tab),
body.dev-tablet :is(.gmt,.gmf,.gprt-tab) {
  border-radius: 10px !important;
  font-size: 11px !important;
  min-height: 44px !important;
}

/* ── États désactivés (maxé / coût insuffisant) : atténués, jamais brillants.
   (On a retiré opacity:1 des tiers pour ne pas écraser le rendu désactivé ; ce
   bloc garantit que tout CTA désactivé reste lisiblement « inactif ». ── */
body.dev-phone :is(.cmdc-action,.ov-empty-event-cta,.rep-empty-cta,.bld-upgrade-btn,.rp-upgrade-btn,.ut-rec-btn-main,.uc-train,.sc-build,.cmd-btn,.gal-action-btn,.atk-btn,.atk-btn-go,.atk-btn-launch,.gap-launch-btn,.gbtn-e,.mkt-accept-btn,.mkt-submit-btn,.quest-claim-btn,.quest-claimall-btn,.dist-claim-btn,.dist-claimall-btn,.camp-btn,.asc-btn,.ap-btn-primary,.gj-claim,.gj-recover-btn,.sos-accept-btn,.art-frag-craft-btn,.cfm-btn-confirm,.msg-compose-btn,.al-chat-send,.fr-btn-accept,.peEdit-btn-save,.auth-btn,.al-submit-btn,.al-join-btn,.al-motd-btn-primary,.alhq-found-btn,.alhq-upgrade-btn,.alhq-fill-btn,.alhq-fund-btn,.alhq-train-btn,.alhq-action-btn,.war-atk-btn,.war-roster-btn,.al-diplo-btn-nap,.city-tech-btn,.city-relique-btn,.surv-act-btn,.ops-card-btn,.og-cancel-btn,.mkt-cancel-btn,.al-leave-btn,.gbtn-a):is(:disabled,[disabled],.disabled),
body.dev-tablet :is(.cmdc-action,.ov-empty-event-cta,.rep-empty-cta,.bld-upgrade-btn,.rp-upgrade-btn,.ut-rec-btn-main,.uc-train,.sc-build,.cmd-btn,.gal-action-btn,.atk-btn,.atk-btn-go,.atk-btn-launch,.gap-launch-btn,.gbtn-e,.mkt-accept-btn,.mkt-submit-btn,.quest-claim-btn,.quest-claimall-btn,.dist-claim-btn,.dist-claimall-btn,.camp-btn,.asc-btn,.ap-btn-primary,.gj-claim,.gj-recover-btn,.sos-accept-btn,.art-frag-craft-btn,.cfm-btn-confirm,.msg-compose-btn,.al-chat-send,.fr-btn-accept,.peEdit-btn-save,.auth-btn,.al-submit-btn,.al-join-btn,.al-motd-btn-primary,.alhq-found-btn,.alhq-upgrade-btn,.alhq-fill-btn,.alhq-fund-btn,.alhq-train-btn,.alhq-action-btn,.war-atk-btn,.war-roster-btn,.al-diplo-btn-nap,.city-tech-btn,.city-relique-btn,.surv-act-btn,.ops-card-btn,.og-cancel-btn,.mkt-cancel-btn,.al-leave-btn,.gbtn-a):is(:disabled,[disabled],.disabled) {
  opacity: 0.45 !important;
  box-shadow: none !important;
  filter: saturate(0.6);
}

/* ════════════ CORRECTIFS CIBLÉS (02/06) ════════════ */

/* ── Porte : la barre Lancer mission / Stop « tremble » au scroll ──
   3 causes cumulées, 3 parades :
   (a) ROOT : #sf_gate est figé à transform:translateY(3px) — l'anim d'entrée
       (sgc-animations.css from{translateY(3px)}) est mise en pause par idle-paused
       et reste sur sa frame de départ → ancêtre transformé qui casse le
       position:fixed de la barre (résolue contre lui, en sous-pixel). On annule
       ce transform sur mobile → la barre se résout enfin contre le viewport.
   (b) on PROMEUT la barre en couche composite (translateZ) → le compositeur la
       déplace d'un bloc, snappée à l'entier, sans re-layout par frame.
   (c) on retire la transition de `transform` + l'ombre floue des boutons DE LA
       BARRE (amplificateur ajouté par le tier primaire, repeint chaque frame).
   Le scale d'appui reste (instantané, sans easing → aucun jitter animé). */
body.dev-phone #sf_gate,
body.dev-tablet #sf_gate { transform: none !important; }
body.dev-phone .gate-btns,
body.dev-tablet .gate-btns {
  transform: translateZ(0) !important;
  will-change: transform;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}
body.dev-phone .gate-btns :is(.gbtn,.gbtn-e,.gbtn-a),
body.dev-tablet .gate-btns :is(.gbtn,.gbtn-e,.gbtn-a) {
  transition: filter 0.12s ease !important;
  box-shadow: none !important;
}
/* Barre Porte reparentée dans <body> (cf sgc-shell.js _reparentGateBar, qui la
   sort des conteneurs à scroll pour qu'elle soit un VRAI fixed sans tremblement) :
   on la masque hors Porte, et on rétablit sa largeur via les insets (la base
   .gate-btns a width:100% → déborderait avec left/right:8px). */
body.dev-phone.shell-on:not([data-section="gate"]) > .gate-btns { display: none !important; }
/* Largeur EXPLICITE (pas width:auto) : iOS Safari rétrécit un flex fixed à son
   contenu malgré left+right → bouton STOP coupé en sliver. calc(100vw-16px) force
   la pleine largeur insérée de 8px de chaque côté sur tous les moteurs. */
body.dev-phone.shell-on > .gate-btns {
  left: 8px !important; right: 8px !important;
  width: calc(100vw - 16px) !important;
  max-width: calc(100vw - 16px) !important;
  box-sizing: border-box !important;
}
/* STOP (.gbtn-a) a flex-grow:0 dans sgc-gate.css (déco bureau) → seul dans la
   barre mobile il se réduisait à ~18px (texte « ✕ STOP » plié verticalement =
   « bouton coupé »). On force les ACTIONS principales (Lancer/Engager/Stop) à
   remplir ; les boutons icône (⚡🔊 gbtn-icon) gardent leur largeur fixe. */
body.dev-phone .gate-btns :is(.gbtn-e,.gbtn-a),
body.dev-tablet .gate-btns :is(.gbtn-e,.gbtn-a) { flex: 1 1 auto !important; }

/* ── Rapports : l'en-tête de ligne (icône+titre+résultat+date+butin) ne tenait
   pas à 344px → le butin (« 18 000 10 800 ») était coupé à droite. On autorise le
   retour à la ligne : butin + date passent proprement sous le titre. (QA pré-go-live) */
body.dev-phone #sf_reports .rep-row-head { flex-wrap: wrap !important; }
body.dev-phone #sf_reports .rep-loot-inline { margin-left: auto !important; }

/* ── Commandants : la médaille 🎖 du pack « Réaffectation » chevauchait le titre.
   `.cmd-reassign-medal` est position:absolute (déco bureau hors carte à gauche) ;
   au breakpoint étroit elle est recentrée en haut MAIS le contenu coule SOUS elle
   → chevauchement « icône sur l'écriture ». On la remet dans le flux (bloc centré
   au-dessus du titre) et on empile la rangée en colonne sur mobile/tablette. */
body.dev-phone .cmd-reassign-row,
body.dev-tablet .cmd-reassign-row {
  flex-direction: column !important;
  align-items: center !important;
}
body.dev-phone .cmd-reassign-medal,
body.dev-tablet .cmd-reassign-medal {
  position: static !important;
  left: auto !important; top: auto !important; right: auto !important;
  transform: none !important;
  margin: 0 auto 4px !important;
}
