/* =========================================================================
   POTOS — BATAILLE NAVALE : les deux grilles sur la table (js/navale-game.js, socle css/jeu-socle.css).
   Téléphone : une grille à la fois (l'autre en mini-carte dans l'onglet), bascule par fondu + glissé (transform,
   opacity) ; paysage bas : onglets à gauche ; grand écran (table ≥ 640 px) : les deux grilles côte à côte.
   Une grille = une « feuille » posée sur le tapis (lettres A…, chiffres 1…) ; ses couleurs viennent du style de
   grille équipé (cosmétique navale.table : Océan, Cahier d'écolier, Écran radar, Mer d'étoiles) via --nv-*.
   Couleurs d'interface : jetons de la charte uniquement ; couleurs d'objets (mer, papier, radar) : permises.
   Fluidité : seuls transform et opacity sont animés (Web Animations dans la vue) ; aucune boucle décorative.
   ========================================================================= */
.jx-navale { --g: #2A6FB0; }
.jx-navale .jx-zone { container-type: size; padding: 8px; }

.nv-stage {
  position: relative; width: 100%; height: 100%; display: grid; gap: 8px;
  grid-template: "side" auto "boards" minmax(0, 1fr) / minmax(0, 1fr);
  --nv-frame: #12355C; --nv-label: var(--nv-ink, #F5F2EB);
}
.nv-stage[data-grid="cahier"] { --nv-frame: #FBF8F1; }
.nv-stage[data-grid="radar"] { --nv-frame: #06180E; }
.nv-stage[data-grid="espace"] { --nv-frame: #070921; }

/* ---------- Colonne d'outils : onglets, armes / placement, chantier ---------- */
.nv-side { grid-area: side; display: grid; gap: 6px; min-width: 0; }
.nv-tabs { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.nv-stage[data-phase="place"] .nv-tabs { display: none; }
.nv-tab {
  display: flex; align-items: center; gap: 8px; min-height: 52px; padding: 4px 10px 4px 4px; text-align: left; cursor: pointer;
  color: var(--text); background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md, 12px);
}
.nv-tab[aria-selected="true"] { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); background: color-mix(in srgb, var(--accent) 12%, var(--surface)); }
.nv-tab:active { transform: scale(.97); transition-duration: 0s; }
.nv-mini { width: 44px; height: 44px; flex: none; border-radius: 6px; background: #12355C; }
.nv-tl { display: grid; min-width: 0; line-height: 1.15; }
.nv-tl b { font: 600 .95rem/1.15 var(--font-display); white-space: nowrap; }
.nv-tc { font: 500 .75rem/1.2 var(--font-ui); color: var(--muted); font-variant-numeric: tabular-nums; }

/* Mêlée (3–4 joueurs) : un onglet par flotte adverse + le mien, en colonnes ; mini-carte en haut, nom, bateaux à flot.
   Toucher l'onglet d'un adversaire = le viser. À son tour : point jaune ; coulée : grisée ; interdite ce tour : pointillés. */
.nv-tabs.is-m { grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 4px; }
.nv-tabs.is-m .nv-tab { position: relative; flex-direction: column; justify-content: center; gap: 2px; min-height: 64px; padding: 4px 2px; text-align: center; }
.nv-tabs.is-m .nv-mini { width: 34px; height: 34px; }
.nv-tabs.is-m .nv-tl { justify-items: center; width: 100%; }
.nv-tabs.is-m .nv-tl b { max-width: 100%; overflow: hidden; text-overflow: ellipsis; font-size: .82rem; }
.nv-tabs.is-m .nv-tc { white-space: nowrap; font-size: .72rem; }
.nv-tab.is-tour::after { content: ''; position: absolute; top: 5px; right: 5px; width: 9px; height: 9px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 2px var(--surface); }
.nv-tab.is-out { opacity: .55; }
.nv-tab.is-ban { border-style: dashed; }
.nv-tab.is-ban .nv-tc { color: var(--text); }
.nv-badge.is-out { color: var(--muted); }

.nv-tools { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 6px; min-height: 36px; }
.nv-tools:empty { display: none; }
.nv-tool { min-height: 36px; }
.nv-arm {
  min-height: 36px; padding: 0 12px; border-radius: var(--r-pill, 999px); cursor: pointer;
  font: 600 .85rem/1 var(--font-display); color: var(--text); background: var(--surface); border: 1px solid var(--line-2);
}
.nv-arm.is-on { color: var(--on-accent); background: var(--accent); border-color: var(--accent); }
.nv-arm[aria-disabled="true"] { opacity: .55; }
.nv-arm:active { transform: scale(.95); transition-duration: 0s; }
.nv-hint { font: 600 .78rem/1 var(--font-ui); color: #F5F2EB; padding: 6px 10px; border-radius: var(--r-pill, 999px); background: rgba(0, 0, 0, .28); }

.nv-yard { display: none; }
.nv-stage.has-yard .nv-yard {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 8px 12px; min-height: 30px;
  padding: 6px 8px; border-radius: var(--r-md, 12px); background: rgba(0, 0, 0, .22); border: 1px dashed rgba(255, 255, 255, .3);
}
.nv-yship { position: relative; display: block; width: calc(var(--n) * 24px); height: 24px; cursor: grab; touch-action: none; }
.nv-yship svg { width: 100%; height: 100%; display: block; overflow: visible; }
.nv-yship.is-lifted { opacity: .3; }
.nv-yhint { flex-basis: 100%; text-align: center; font: 500 .75rem/1.2 var(--font-ui); color: rgba(245, 242, 235, .85); }

/* ---------- Les grilles (empilées sur téléphone, côte à côte sur grand écran) ---------- */
.nv-boards { grid-area: boards; position: relative; min-height: 0; display: grid; grid-template: minmax(0, 1fr) / minmax(0, 1fr); }
.nv-board {
  grid-area: 1 / 1; min-height: 0; min-width: 0; display: grid; grid-template-rows: minmax(0, 1fr);
  transition: opacity .22s ease, transform .22s var(--ease-out, ease-out), visibility 0s .22s;
}
.nv-stage[data-focus="target"] .nv-board.is-mine, .nv-stage[data-focus="mine"] .nv-board.is-target { opacity: 0; visibility: hidden; pointer-events: none; }
.nv-stage[data-focus="target"] .nv-board.is-mine { transform: translateX(6%) scale(.96); }
.nv-stage[data-focus="mine"] .nv-board.is-target { transform: translateX(-6%) scale(.96); }
.nv-stage[data-focus="target"] .nv-board.is-target, .nv-stage[data-focus="mine"] .nv-board.is-mine { transition-delay: 0s; }
.nv-bh { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 0 4px; color: #F5F2EB; min-width: 0; }
.nv-bt { font: 600 .95rem/1.2 var(--font-display); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nv-bs { font: 500 .78rem/1.2 var(--font-ui); opacity: .85; white-space: nowrap; font-variant-numeric: tabular-nums; }
.nv-fit { position: relative; min-height: 0; container-type: size; display: grid; place-items: center; }
/* Carte = titre + feuille, centrée ; la feuille prend la plus grande taille qui tient (titre de 28 px compris) */
.nv-card { --side: min(100cqw, calc((100cqh - 28px) * var(--ratio)), 620px); width: var(--side); display: grid; grid-template-rows: 24px auto; gap: 4px; }

/* La feuille : marge des lettres et chiffres + la mer quadrillée */
.nv-sheet {
  --cell: calc(var(--side) / (var(--w) + .75));
  position: relative; width: 100%; aspect-ratio: var(--ratio);
  display: grid; grid-template-columns: .75fr repeat(var(--w), 1fr); grid-template-rows: .75fr repeat(var(--h), 1fr);
  padding: 0 calc(var(--cell) * .12) calc(var(--cell) * .12) 0; box-sizing: border-box;
  background: var(--nv-frame); border-radius: 12px; box-shadow: var(--ombre-objet, 0 6px 12px -4px rgba(0, 0, 0, .5)), inset 0 0 0 1px rgba(255, 255, 255, .08);
}
/* Tailles FIXES (pas proportionnelles à la case) : peu de fontes à préchauffer (FX.warm, docs/fluidite.md §10) */
.nv-cols, .nv-rows { display: grid; color: var(--nv-label); font: 700 .75rem/1 var(--font-display); opacity: .9; }
.nv-cols { grid-column: 2 / -1; grid-row: 1; grid-template-columns: repeat(var(--w), 1fr); align-items: center; text-align: center; }
.nv-rows { grid-column: 1; grid-row: 2 / -1; grid-template-rows: repeat(var(--h), 1fr); align-items: center; text-align: center; }
.nv-grid {
  grid-column: 2 / -1; grid-row: 2 / -1; position: relative; border-radius: 4px;
  background-color: var(--nv-sea);
  background-image: linear-gradient(var(--nv-line) 1px, transparent 1px), linear-gradient(90deg, var(--nv-line) 1px, transparent 1px),
    radial-gradient(120% 90% at 30% 20%, rgba(255, 255, 255, .12), transparent 60%);
  background-size: calc(100% / var(--w)) calc(100% / var(--h)), calc(100% / var(--w)) calc(100% / var(--h)), 100% 100%;
  box-shadow: inset 0 0 0 1px var(--nv-line);
  touch-action: manipulation; -webkit-tap-highlight-color: transparent;
}
.nv-stage[data-grid="cahier"] .nv-grid {
  background-image: linear-gradient(var(--nv-line) 1px, transparent 1px), linear-gradient(90deg, var(--nv-line) 1px, transparent 1px),
    linear-gradient(90deg, rgba(229, 56, 59, .7) 0 2px, transparent 2px);
  background-size: calc(100% / var(--w)) calc(100% / var(--h)), calc(100% / var(--w)) calc(100% / var(--h)), 100% 100%;
}
.nv-stage[data-grid="cahier"] .nv-sheet { box-shadow: var(--ombre-objet, 0 6px 12px -4px rgba(0, 0, 0, .5)), inset 0 0 0 1px rgba(30, 31, 38, .12); }
.nv-stage[data-grid="radar"] .nv-grid {
  background-image: linear-gradient(var(--nv-line) 1px, transparent 1px), linear-gradient(90deg, var(--nv-line) 1px, transparent 1px),
    repeating-radial-gradient(circle at 50% 50%, transparent 0 18%, rgba(63, 224, 122, .22) 18% calc(18% + 1.5px));
  background-size: calc(100% / var(--w)) calc(100% / var(--h)), calc(100% / var(--w)) calc(100% / var(--h)), 100% 100%;
}
.nv-stage[data-grid="espace"] .nv-grid {
  background-image: linear-gradient(var(--nv-line) 1px, transparent 1px), linear-gradient(90deg, var(--nv-line) 1px, transparent 1px),
    radial-gradient(1.5px 1.5px at 12% 18%, #fff 50%, transparent 51%), radial-gradient(1px 1px at 63% 32%, #fff 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 38% 71%, #fff 50%, transparent 51%), radial-gradient(1px 1px at 84% 84%, #fff 50%, transparent 51%),
    radial-gradient(90% 70% at 70% 30%, rgba(122, 140, 255, .25), transparent 70%);
  background-size: calc(100% / var(--w)) calc(100% / var(--h)), calc(100% / var(--w)) calc(100% / var(--h)), 100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%;
}
.nv-l { position: absolute; inset: 0; pointer-events: none; }
.nv-l-ships { pointer-events: none; }
.nv-board.is-mine .nv-l-ships { pointer-events: auto; }
.nv-l-ships > i { pointer-events: none; }
.nv-ship.is-drag { pointer-events: auto; cursor: grab; touch-action: none; }

/* Bateaux, îles */
.nv-ship, .nv-isle { position: absolute; display: block; padding: calc(var(--cell) * .06); box-sizing: border-box; }
.nv-ship svg, .nv-isle svg { width: 100%; height: 100%; display: block; overflow: visible; }
.nv-ship.is-ghost { opacity: .55; }
.nv-ship.is-lifted { opacity: .3; }
.nv-ship.is-shaking { animation: nv-shake .35s ease-in-out; }
@keyframes nv-shake { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-4px); } 75% { transform: translateX(4px); } }
.nv-ghost { position: fixed; left: 0; top: 0; z-index: 60; pointer-events: none; opacity: .92; will-change: transform; }
.nv-ghost svg { width: 100%; height: 100%; display: block; overflow: visible; }
.nv-drop { position: absolute; z-index: 3; border-radius: 6px; border: 3px dashed var(--ok, #3FD18A); background: rgb(var(--ok-rgb, 63 209 138) / .22); pointer-events: none; }
.nv-drop.is-bad { border-color: var(--danger, #FF5A6E); background: rgb(var(--danger-rgb, 255 90 110) / .22); }
.nv-drop[hidden] { display: none; }

/* Marques : à l'eau, touché, déduit (style de la grille) */
.nv-mk { position: absolute; display: block; pointer-events: none; }
.nv-mk.is-miss::before { content: ''; position: absolute; inset: 37%; border-radius: 50%; background: var(--nv-miss); }
.nv-stage[data-grid="cahier"] .nv-mk.is-miss::before { inset: 28%; background: none; border: calc(var(--cell) * .07) solid var(--nv-miss); }
.nv-mk.is-near::before { content: ''; position: absolute; inset: 43%; border-radius: 50%; background: var(--nv-near); }
.nv-mk.is-hit { background: rgb(229 56 59 / .18); }
.nv-mk.is-hit::before, .nv-mk.is-hit::after {
  content: ''; position: absolute; left: 18%; right: 18%; top: calc(50% - var(--cell) * .07); height: calc(var(--cell) * .14);
  border-radius: 4px; background: var(--nv-hit); transform: rotate(45deg);
}
.nv-mk.is-hit::after { transform: rotate(-45deg); }

/* Viseur(s), zone d'arme, sonar */
.nv-aim { position: absolute; z-index: 2; border-radius: 6px; border: 3px solid var(--accent, #FFC233); box-shadow: 0 0 0 2px rgba(0, 0, 0, .35); pointer-events: none; }
.nv-aim::before, .nv-aim::after { content: ''; position: absolute; background: var(--accent, #FFC233); }
.nv-aim::before { left: 50%; top: 18%; bottom: 18%; width: 2px; margin-left: -1px; }
.nv-aim::after { top: 50%; left: 18%; right: 18%; height: 2px; margin-top: -1px; }
.nv-aim.is-cur { border-style: dashed; border-color: #FBF8F1; }
.nv-aim.is-cur::before, .nv-aim.is-cur::after { content: none; }
.nv-sel-zone { position: absolute; z-index: 1; border-radius: 8px; border: 3px dashed #FF8A1F; background: rgba(255, 138, 31, .16); pointer-events: none; }
.nv-sel-zone.is-sonar { border-color: #3FE07A; background: rgba(63, 224, 122, .16); }
.nv-sel-zone[hidden] { display: none; }
.nv-grid.is-armed { cursor: crosshair; }
.nv-sonar { position: absolute; border-radius: 8px; border: 2px solid #3FE07A; background: rgba(63, 224, 122, .1); pointer-events: none; }
.nv-sonar b {
  position: absolute; right: -8px; top: -8px; min-width: 22px; height: 22px; display: grid; place-items: center; border-radius: 50%;
  font: 700 .8rem/1 var(--font-display); color: #0B2A1A; background: #3FE07A;
}

/* Effets (transitoires, animés en transform / opacity par la vue) */
.nv-l-fx { z-index: 4; }
.nv-fx { position: absolute; display: block; pointer-events: none; }
.nv-shell::before { content: ''; position: absolute; inset: 28%; border-radius: 50%; background: radial-gradient(circle at 35% 30%, #6B7280, #1E1F26 70%); }
.nv-shell.k-laser::before { background: #22F2FF; inset: 36%; }
.nv-shell.k-encre::before { background: #2C4FA8; inset: 38%; }
.nv-boom svg { position: absolute; inset: -20%; width: 140%; height: 140%; overflow: visible; }
.nv-ping { border-radius: 10px; border: 3px solid #3FE07A; background: rgba(63, 224, 122, .2); }

/* Annonce « À l'eau / Touché / Coulé » au centre de la grille */
.nv-callout {
  position: absolute; left: 50%; top: 50%; z-index: 6; margin: 0; padding: .35em .8em; opacity: 0; pointer-events: none;
  transform: translate(-50%, -50%); white-space: nowrap; border-radius: var(--r-pill, 999px);
  font: 700 1.25rem/1.1 var(--font-display); color: #FBF8F1; background: rgba(15, 20, 30, .78);
}
.nv-callout.is-touche { color: #FFD43B; }
.nv-callout.is-coule { color: #FF6B6B; }
.nv-callout.is-gros { font-size: 1.6rem; color: #FFC233; }
.nv-veil {
  position: absolute; inset: 0; z-index: 5; margin: 0; display: grid; place-items: center; text-align: center; padding: 12px;
  font: 600 1rem/1.3 var(--font-display); color: #F5F2EB; background: rgba(8, 20, 40, .55); border-radius: 4px;
}
.nv-veil[hidden] { display: none; }

/* Pastilles des joueurs */
.nv-badge { font: 600 .72rem/1 var(--font-ui); color: var(--muted); white-space: nowrap; }
.nv-badge.is-ok { color: var(--ok-text, var(--ok, #3FD18A)); }

/* ---------- Paysage bas (téléphone couché) : outils à gauche, une grande grille ---------- */
@container (min-aspect-ratio: 6/5) and (max-width: 639.9px) {
  .nv-stage { grid-template: "side boards" minmax(0, 1fr) / minmax(118px, 34%) minmax(0, 1fr); }
  .nv-side { align-content: start; overflow-y: auto; }
  .nv-tabs { grid-template-columns: 1fr; }
  .nv-tab { min-height: 48px; flex-direction: column; justify-content: center; gap: 4px; padding: 6px 4px; text-align: center; }
  .nv-tl b { font-size: .85rem; }
  .nv-tools { justify-content: flex-start; }
  .nv-yship { width: calc(var(--n) * 18px); height: 18px; }
  .nv-tabs.is-m { grid-auto-flow: row; grid-template-columns: 1fr 1fr; }
  .nv-tabs.is-m .nv-tab { min-height: 56px; }
}
/* ---------- Grand écran : les deux grilles côte à côte ---------- */
@container (min-width: 640px) {
  .nv-tabs { display: none; }
  .nv-boards { grid-template: minmax(0, 1fr) / minmax(0, 1fr) minmax(0, 1fr); gap: 18px; }
  .nv-board, .nv-stage[data-focus] .nv-board.is-target, .nv-stage[data-focus] .nv-board.is-mine { opacity: 1; visibility: visible; transform: none; pointer-events: auto; transition: none; }
  .nv-board.is-mine { grid-area: 1 / 1; }
  .nv-board.is-target { grid-area: 1 / 2; }
  .nv-yship { width: calc(var(--n) * 30px); height: 30px; }
  .nv-cols, .nv-rows { font-size: .95rem; }
  .nv-callout { font-size: 1.6rem; }
  /* Mêlée : les onglets des flottes adverses restent au-dessus des grilles (choisir sa cible) ; ma flotte est déjà à gauche */
  .nv-stage[data-mode="melee"]:not([data-phase="place"]) .nv-tabs { display: grid; max-width: 720px; justify-self: center; width: 100%; }
  .nv-stage[data-mode="melee"] .nv-tab[data-to="mine"] { display: none; }
  .nv-tabs.is-m .nv-tab { flex-direction: row; min-height: 48px; gap: 8px; }
  .nv-tabs.is-m .nv-tl { justify-items: start; text-align: left; }
}

/* Mouvement réduit / perf-lite : pas de glissé entre les grilles (l'information reste : fondu court) */
@media (prefers-reduced-motion: reduce) { .nv-board { transition: opacity .1s, visibility 0s .1s; transform: none !important; } .nv-ship.is-shaking { animation: none; } }
.perf-lite .nv-board { transform: none !important; }

/* Lancement plus léger : pendant le placement sur téléphone, la grille de tir (cachée, voilée) n'est ni mise en page ni
   peinte (content-visibility) ; elle l'est au début de la bataille. Grand écran : les deux sont visibles (voir plus haut). */
.nv-stage[data-phase="place"][data-focus="mine"] .nv-board.is-target .nv-fit { content-visibility: hidden; }
@container (min-width: 640px) { .nv-stage[data-phase="place"][data-focus="mine"] .nv-board.is-target .nv-fit { content-visibility: visible; } }
/* Bataille sur téléphone : les deux grilles restent sur leur propre calque (déjà peintes) → la bascule ne fait que
   composer opacity / transform, sans repeindre la grille qui apparaît (mesuré : images > 32 ms à CPU ÷ 4 sinon). */
.nv-stage[data-phase="fire"] .nv-board { will-change: transform, opacity; }
