:root {
  --bg: #0f1117; --bg-soft: #161923; --card: #1a1e2b; --card-hover: #212636; --line: #2a3042;
  --text: #e8eaf0; --muted: #969db4; --accent: #6ea8fe; --warm: #f0b354;
  --good: #4cc38a; --bad: #ef6461;
  --sea1: #11263a; --sea2: #0d1d2e; --seaLine: rgba(110,168,254,.14);
  --lab: 16px;
}
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; height: 100%; background: var(--bg); color: var(--text); overflow-x: clip; }
body { font: 15px/1.4 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; -webkit-font-smoothing: antialiased; overflow: hidden; touch-action: manipulation; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; padding: 0; }
[hidden] { display: none !important; }
a { color: var(--accent); }
.muted { color: var(--muted); }

#app { height: 100vh; height: 100dvh; display: flex; flex-direction: column; }
.top { flex: 0 0 auto; height: 44px; display: flex; align-items: center; gap: 8px; padding: 0 12px; border-bottom: 1px solid var(--line); padding-top: env(safe-area-inset-top); box-sizing: content-box; }
.top h1 { font-size: 16px; margin: 0; font-weight: 700; letter-spacing: -.01em; white-space: nowrap; }
.top .home { text-decoration: none; color: var(--muted); font-size: 26px; line-height: 1; padding: 0 4px 3px 0; }
.top .status { margin-left: auto; color: var(--muted); font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.status b { color: var(--warm); font-weight: 600; }
main { flex: 1 1 auto; min-height: 0; position: relative; }
.tab { position: absolute; inset: 0; overflow: hidden; }
.scroll { position: absolute; inset: 0; overflow-y: auto; padding: 14px 14px 28px; -webkit-overflow-scrolling: touch; }

.tabs { order: 3; flex: 0 0 auto; display: flex; border-top: 1px solid var(--line); background: var(--bg-soft); padding-bottom: env(safe-area-inset-bottom); }
.tabs button { flex: 1; height: 52px; color: var(--muted); font-size: 13px; font-weight: 600; }
.tabs button.on { color: var(--text); }
.tabs .hubtab { flex: 1.3; }
.tabs .hubtab span { display: inline-block; padding: 6px 16px; border-radius: 99px; background: var(--card); transition: background .2s, color .2s; }
.tabs .hubtab.on span { background: var(--accent); color: #0f1117; }

/* ---------- play layout (phone) ---------- */
#tab-play, #tab-paper { display: flex; flex-direction: column; }
.playmain { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; padding: 6px 8px 4px; background: radial-gradient(110% 70% at 50% 40%, #12202e 0%, var(--bg) 75%); }
.pbar { flex: 0 0 30px; display: flex; align-items: center; gap: 6px; min-width: 0; font-size: 13px; color: var(--muted); }
.pbar .grow { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pbar b { color: var(--text); }
.gwrap { flex: 1 1 auto; min-height: 0; container-type: size; display: flex; align-items: center; justify-content: center; }
.pside { flex: 0 0 172px; display: grid; grid-template-columns: 150px 1fr; gap: 10px; padding: 6px 10px 8px; border-top: 1px solid var(--line); min-height: 0; }
#tab-paper .pside { grid-template-columns: 1fr; }
.mine { display: flex; flex-direction: column; min-height: 0; }
.minehead { font-size: 11px; color: var(--muted); font-weight: 600; height: 16px; white-space: nowrap; overflow: hidden; }
.gwrap.small { flex: 1 1 auto; }
.logbox { display: none; }
.sidehead { font-size: 12px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; margin: 10px 0 6px; display: flex; align-items: center; gap: 6px; }

/* ---------- grid ---------- */
.grid { position: relative; width: min(100cqw, 100cqh); height: min(100cqw, 100cqh); --lab: 16px; user-select: none; -webkit-user-select: none; }
.grid.small { --lab: 10px; }
.grid .cols, .grid .rows { position: absolute; display: grid; color: var(--muted); font-size: 10px; font-weight: 600; }
.grid.small .cols, .grid.small .rows { font-size: 7px; }
.grid .cols { left: var(--lab); right: 0; top: 0; height: var(--lab); grid-template-columns: repeat(10, 1fr); align-items: center; text-align: center; }
.grid .rows { top: var(--lab); bottom: 0; left: 0; width: var(--lab); grid-template-rows: repeat(10, 1fr); align-items: center; text-align: center; }
.sea { position: absolute; left: var(--lab); top: var(--lab); right: 0; bottom: 0; border-radius: 6px; overflow: hidden;
  background:
    linear-gradient(var(--seaLine) 1px, transparent 1px) 0 0 / 10% 10%,
    linear-gradient(90deg, var(--seaLine) 1px, transparent 1px) 0 0 / 10% 10%,
    radial-gradient(120% 120% at 30% 20%, var(--sea1), var(--sea2));
  box-shadow: inset 0 0 0 1px rgba(110,168,254,.22), 0 6px 20px rgba(0,0,0,.35); }
.sea svg.ships { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; }
.sea .cells { position: absolute; inset: 0; display: grid; grid-template-columns: repeat(10, 1fr); grid-template-rows: repeat(10, 1fr); }
.cell { position: relative; display: flex; align-items: center; justify-content: center; border-radius: 3px; transition: background-color .35s; min-width: 0; min-height: 0; }
.grid.firing .cell.open { cursor: crosshair; }
.cell.sel { box-shadow: inset 0 0 0 2.5px var(--accent); background-color: rgba(110,168,254,.22) !important; }
.cell.best::after { content: ""; position: absolute; inset: 14%; border-radius: 50%; border: 2px dashed var(--good); animation: bestIn .6s ease-out both; }
.grid.small .cell.best::after { display: none; }
.cell.last { box-shadow: inset 0 0 0 1.5px var(--warm); }
.cell .pct { font-size: 9px; color: rgba(255,255,255,.75); font-weight: 600; pointer-events: none; }
/* one-shot, not an endless spin: an infinite animation over the heatmap repainted the grid every frame (seconds per frame in headless WebKit) */
@keyframes bestIn { from { transform: scale(1.6) rotate(-120deg); opacity: 0; } to { transform: none; opacity: 1; } }
.peg { width: 38%; height: 38%; border-radius: 50%; pointer-events: none; }
.peg.hit { background: radial-gradient(circle at 35% 30%, #ffd0cc 0 12%, #ef6461 30%, #9c2a2e 100%); box-shadow: 0 1px 3px rgba(0,0,0,.6), 0 0 8px rgba(239,100,97,.45); }
.peg.miss { width: 30%; height: 30%; background: radial-gradient(circle at 35% 30%, #fff 0 15%, #d9dde7 45%, #8a91a3 100%); box-shadow: 0 1px 2px rgba(0,0,0,.5); opacity: .9; }
.peg.new { animation: pegIn .45s cubic-bezier(.2,1.4,.4,1) both; }
.cell.splash::before, .cell.boom::before { content: ""; position: absolute; inset: 10%; border-radius: 50%; pointer-events: none; animation: ring .7s ease-out both; }
.cell.splash::before { border: 2px solid rgba(220,235,255,.8); }
.cell.boom::before { background: radial-gradient(circle, rgba(255,214,120,.95), rgba(239,100,97,.6) 45%, transparent 70%); }
@keyframes pegIn { from { transform: scale(2.2); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes ring { from { transform: scale(.3); opacity: 1; } to { transform: scale(1.6); opacity: 0; } }
.ship { transition: opacity .3s; }
.ship.sunk { opacity: .55; filter: saturate(.3); }
.ship.wreck { opacity: .95; }
.ship.pick { filter: drop-shadow(0 0 14px rgba(110,168,254,.95)); }
.ship.bad { filter: drop-shadow(0 0 14px rgba(239,100,97,.95)); }
.ship.ghost { opacity: .45; }
.ship.reveal { opacity: .7; }
.ship.fadein { animation: fadeIn .6s ease-out both; }
@keyframes fadeIn { from { opacity: 0; } }
.grid.placing .sea { touch-action: none; cursor: grab; }

/* ---------- info panel ---------- */
.info { min-width: 0; display: flex; flex-direction: column; gap: 6px; min-height: 0; }
.msg { font-size: 14px; font-weight: 700; min-height: 20px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.msg .sub { font-weight: 500; color: var(--muted); font-size: 12px; }
.msg.hit { color: var(--bad); } .msg.miss { color: var(--muted); } .msg.sunk { color: var(--warm); }
.aim { display: flex; align-items: baseline; gap: 8px; min-height: 40px; }
.aim .cellname { font-size: 26px; font-weight: 800; letter-spacing: -.02em; }
.aim .chance { font-size: 15px; font-weight: 700; }
.aim .of { font-size: 12px; color: var(--muted); }
.row { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.btn { height: 40px; padding: 0 14px; border-radius: 10px; background: var(--card); border: 1px solid var(--line); font-weight: 650; font-size: 14px; transition: transform .1s, background .2s, opacity .2s; white-space: nowrap; }
.btn:active { transform: scale(.97); }
.btn.primary { background: var(--accent); color: #0f1117; border-color: var(--accent); }
.btn.fire { background: var(--bad); border-color: var(--bad); color: #fff; }
.btn.small { height: 32px; padding: 0 10px; font-size: 13px; border-radius: 8px; }
.btn[disabled] { opacity: .4; pointer-events: none; }
.btn.grow { flex: 1 1 auto; }
.tog { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--muted); }
.switch { width: 40px; height: 24px; border-radius: 99px; background: var(--line); position: relative; transition: background .2s; flex: 0 0 auto; }
.switch::after { content: ""; position: absolute; left: 3px; top: 3px; width: 18px; height: 18px; border-radius: 50%; background: #fff; transition: transform .2s; }
.switch.on { background: var(--good); }
.switch.on::after { transform: translateX(16px); }
.switch.dis { opacity: .35; pointer-events: none; }
.q { width: 18px; height: 18px; border-radius: 50%; border: 1px solid var(--line); color: var(--muted); font-size: 11px; font-weight: 700; line-height: 16px; text-align: center; padding: 0; flex: 0 0 auto; }
.chip { display: inline-flex; align-items: center; gap: 4px; padding: 2px 7px; border-radius: 99px; font-size: 12px; font-weight: 700; color: #0f1117; white-space: nowrap; }

/* fleet chips (top bar) */
.fleet { display: flex; gap: 4px; align-items: center; min-width: 0; flex: 1 1 auto; }
.fchip { display: flex; flex-direction: column; align-items: center; gap: 1px; min-width: 0; flex: 0 1 auto; padding: 1px 3px; border-radius: 6px; }
.fchip .shipicon { height: 10px; width: auto; display: block; }
.fchip span { font-size: 9px; color: var(--muted); line-height: 1; white-space: nowrap; }
.fchip.sunk .shipicon { opacity: .3; filter: grayscale(1); }
.fchip.sunk span { text-decoration: line-through; color: var(--bad); }
button.fchip { border: 1px solid var(--line); }
button.fchip.on { border-color: var(--accent); background: rgba(110,168,254,.12); }

/* tray (placement) */
.tray { display: flex; gap: 4px; flex-wrap: wrap; }
.tray button { height: 28px; padding: 0 6px; border-radius: 7px; border: 1px solid var(--line); display: flex; align-items: center; gap: 4px; font-size: 11px; color: var(--muted); }
.tray button .shipicon { height: 9px; width: auto; }
.tray button.on { border-color: var(--accent); color: var(--text); background: rgba(110,168,254,.12); }

/* ---------- sheet / cover / tip / toast ---------- */
.sheet { position: absolute; inset: 0; background: rgba(8,10,14,.7); display: flex; align-items: flex-end; justify-content: center; z-index: 30; animation: fadeIn .2s; }
.panel { width: 100%; max-width: 520px; background: var(--card); border: 1px solid var(--line); border-radius: 14px 14px 0 0; padding: 14px 16px calc(16px + env(safe-area-inset-bottom)); animation: up .25s ease-out; max-height: 100%; overflow-y: auto; }
@keyframes up { from { transform: translateY(40px); opacity: 0; } }
.panel h2 { margin: 0 0 8px; font-size: 20px; letter-spacing: -.01em; }
.panel h3 { margin: 12px 0 6px; font-size: 13px; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.panel .stats { display: grid; grid-template-columns: 1fr auto; gap: 4px 12px; font-size: 14px; margin: 8px 0 12px; }
.panel .stats b { text-align: right; }
.panel .actions { display: flex; gap: 8px; margin-top: 12px; }
.panel .actions .btn { flex: 1; }
.opp3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.opp3 button { border: 1px solid var(--line); border-radius: 10px; padding: 8px 4px; font-size: 13px; font-weight: 650; background: var(--bg-soft); }
.opp3 button.on { border-color: var(--accent); background: rgba(110,168,254,.14); }
.code { font-family: ui-monospace, Menlo, monospace; letter-spacing: .14em; color: var(--warm); font-size: 34px; font-weight: 800; }
.seatrow { display: flex; align-items: center; gap: 8px; padding: 6px 0; border-bottom: 1px solid var(--line); font-size: 14px; }
.seatrow .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--muted); }
.seatrow .dot.on { background: var(--good); }
.cover { position: absolute; inset: 0; z-index: 40; background: var(--bg); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px; text-align: center; padding: 20px; animation: fadeIn .25s; }
.cover .big { font-size: 24px; font-weight: 800; }
.tip { position: fixed; z-index: 50; max-width: 290px; background: #222838; border: 1px solid var(--line); color: var(--text); font-size: 13px; padding: 10px 12px; border-radius: 10px; box-shadow: 0 8px 24px rgba(0,0,0,.5); }
.toast { pointer-events: none; position: fixed; left: 50%; top: calc(52px + env(safe-area-inset-top)); transform: translateX(-50%); z-index: 60; background: #222838; border: 1px solid var(--warm); color: var(--text); font-size: 13px; padding: 8px 12px; border-radius: 10px; max-width: min(92vw, 420px); text-align: center; box-shadow: 0 8px 24px rgba(0,0,0,.5); animation: fadeIn .2s; }
input[type=text] { -webkit-appearance: none; appearance: none; background: var(--bg-soft); color: var(--text); border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; font: inherit; font-size: 16px; min-width: 0; }
input.codein { width: 110px; text-transform: uppercase; letter-spacing: .12em; font-family: ui-monospace, Menlo, monospace; }

/* ---------- log ---------- */
.log { list-style: none; margin: 0; padding: 0; overflow-y: auto; font-size: 13px; min-height: 0; flex: 1 1 auto; }
.log li { padding: 3px 0; border-bottom: 1px solid rgba(42,48,66,.6); color: var(--muted); }
.log li b { color: var(--text); }
.log li .h { color: var(--bad); font-weight: 700; }
.log li .k { color: var(--warm); font-weight: 700; }

/* ---------- settings / lab / rules ---------- */
.set { max-width: 620px; margin: 0 auto; }
.set h2, .lab h2, .rules h2 { font-size: 18px; margin: 4px 0 10px; }
.set h3 { font-size: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: .05em; margin: 18px 0 4px; }
.setrow { display: flex; align-items: center; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--line); min-height: 48px; }
.setrow .lbl { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 6px; }
.seg { display: inline-flex; background: var(--bg-soft); border: 1px solid var(--line); border-radius: 9px; padding: 2px; flex: 0 0 auto; }
.seg button { padding: 5px 9px; border-radius: 7px; font-size: 13px; color: var(--muted); white-space: nowrap; }
.seg button.on { background: var(--accent); color: #0f1117; font-weight: 700; }
.seg.dis { opacity: .35; pointer-events: none; }
.ver { color: var(--muted); font-size: 12px; margin-top: 18px; }
.rules { max-width: 680px; margin: 0 auto; right: 0; left: 0; }
.rules p { color: #cfd3de; }
.rules h3 { font-size: 15px; margin: 18px 0 4px; }
.ftab { border-collapse: collapse; width: 100%; font-size: 14px; margin: 8px 0; }
.ftab th, .ftab td { text-align: left; padding: 6px 8px; border-bottom: 1px solid var(--line); }
.ftab th { color: var(--muted); font-weight: 600; font-size: 12px; }
.ftab td.n, .ftab th.n { text-align: right; font-variant-numeric: tabular-nums; }
.lab { max-width: 1100px; margin: 0 auto; display: grid; grid-template-columns: 1fr; gap: 14px; }
.lab section { background: var(--card); border-radius: 12px; padding: 12px 14px; min-width: 0; }
.lab h2 { display: flex; align-items: center; gap: 8px; margin: 0 0 8px; font-size: 16px; }
.lab .note { color: var(--muted); font-size: 13px; margin: 6px 0 0; }
.lab svg { display: block; width: 100%; height: auto; }
.lab .mini { display: grid; grid-template-columns: 150px 1fr; gap: 12px; align-items: start; }
.lab .mini .gbox { width: 150px; height: 150px; container-type: size; display: flex; }
.bar2 { height: 8px; border-radius: 4px; background: var(--line); position: relative; overflow: hidden; }
.bar2 i { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 4px; }

/* ---------- laptop ---------- */
@media (min-width: 900px) {
  #app { max-width: 1400px; margin: 0 auto; width: 100%; }
  .tabs { order: 0; border-top: 0; border-bottom: 1px solid var(--line); background: transparent; justify-content: flex-start; padding: 0 12px; }
  .tabs button { flex: 0 0 auto; height: 40px; padding: 0 16px; }
  .tabs .hubtab { flex: 0 0 auto; }
  #tab-play, #tab-paper { flex-direction: row; }
  .playmain { padding: 10px 18px 14px; }
  .pbar { flex-basis: 36px; font-size: 14px; }
  .fchip .shipicon { height: 14px; }
  .fchip span { font-size: 11px; }
  .grid { --lab: 20px; }
  .grid .cols, .grid .rows { font-size: 12px; }
  .grid.small { --lab: 14px; }
  .grid.small .cols, .grid.small .rows { font-size: 9px; }
  .pside { flex: 0 0 360px; display: flex; flex-direction: column; gap: 10px; border-top: 0; border-left: 1px solid var(--line); padding: 12px 16px; }
  .mine { flex: 0 0 auto; }
  .info { flex: 0 0 auto; } /* never shrink under the log (it hid Best/Fire when two message lines showed) */
  .gwrap.small { flex: 0 0 300px; height: 300px; }
  .minehead { font-size: 13px; height: 20px; }
  .logbox { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
  .msg { font-size: 16px; white-space: normal; }
  .lab { grid-template-columns: 1fr 1fr; }
  .lab section.wide { grid-column: 1 / -1; }
  .sheet { align-items: center; }
  .panel { border-radius: 14px; max-width: 460px; }
}
@media (max-height: 620px) and (max-width: 899px) { .pside { flex-basis: 156px; grid-template-columns: 134px 1fr; } }
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; } }
/* placing: the fleet is already on the big grid, so the tray gets the whole width (phone) */
@media (max-width: 899px) {
  #tab-play.placing .mine { display: none; }
  #tab-play.placing .pside { grid-template-columns: 1fr; }
}
.tray button { flex: 1 1 auto; justify-content: center; }
.tray button .shipicon { height: 10px; flex: 0 0 auto; }
@media (max-width: 899px) { .tray button .shipicon { display: none; } } /* keeps the phone tray on one row */

/* ---------- design pass (2026-10-20) ---------- */
/* fleet tally: ships big enough to read; sunk ones dimmed but still visible */
.fchip .shipicon { height: 13px; }
.fchip span { font-size: 10px; }
.fchip.sunk .shipicon { opacity: .45; filter: grayscale(1) brightness(.8); }
/* turn feedback: the status reads as a pill, the target board lights up when it's your shot */
.top .status { font-size: 14px; font-weight: 600; }
.status b { display: inline-block; padding: 2px 10px; border-radius: 99px; background: rgba(240,179,84,.16); }
.grid .sea { transition: box-shadow .35s ease; }
.grid.firing .sea { box-shadow: inset 0 0 0 1px rgba(110,168,254,.22), 0 0 0 2px rgba(110,168,254,.55), 0 6px 22px rgba(110,168,254,.18); }
/* markers: best ring holds up on a red heat cell; desktop heat numbers recede except the ones that matter */
.cell.best::after { border-width: 2.5px; filter: drop-shadow(0 0 1.5px rgba(0,0,0,.85)); }
.cell .pct { color: rgba(255,255,255,.55); }
.cell.best .pct, .cell.sel .pct { color: #fff; font-size: 11px; font-weight: 800; }
/* Fire stays neutral until a square is picked, then arms red */
.btn.fire { transition: transform .1s, background-color .25s, border-color .25s, color .25s; }
.btn.fire[disabled] { background: var(--card); border-color: var(--line); color: var(--muted); opacity: 1; }
/* end sheet: win/lose colour */
.panel h2.wintitle { color: var(--good); }
.panel h2.losetitle { color: var(--bad); }
/* tap targets: small controls keep their look but get a 40px+ invisible hit area */
.q, .switch, .btn.small, .seg button, .tray button { position: relative; }
.q::before { content: ""; position: absolute; inset: -11px; }
.switch::before { content: ""; position: absolute; inset: -8px -4px; }
.btn.small::before, .seg button::before, .tray button::before { content: ""; position: absolute; inset: -5px 0; }
.lab section.wide svg { max-height: 280px; }
@media (min-width: 900px) {
  .fchip .shipicon { height: 18px; }
  .fchip span { font-size: 12px; }
  .peg { width: 42%; height: 42%; }
  .peg.miss { width: 32%; height: 32%; }
  .top .status { font-size: 15px; }
  #tab-play.placing .logbox { visibility: hidden; }
}
.fchip .hitn { color: var(--bad); font-weight: 700; }
.msg.sub.hit { color: #e9a3a1; } .msg.sub.sunk { color: var(--warm); } .msg.sub.miss { color: var(--muted); }
/* phone turned sideways: grid on the left, controls on the right */
@media (orientation: landscape) and (max-height: 520px) and (max-width: 999px) {
  .top { height: 36px; }
  .tabs button { height: 40px; }
  #tab-play, #tab-paper { flex-direction: row; }
  .playmain { padding: 4px 6px; }
  .pbar { flex-basis: 24px; }
  .pside { flex: 0 0 50%; border-top: 0; border-left: 1px solid var(--line); grid-template-columns: 118px 1fr; padding: 6px 10px; }
  .msg { font-size: 13px; }
}
/* Sound & effects block (rendered by the shared fx.js): match the Settings rows above */
.set .fx-set .fx-row { border-top: 0; border-bottom: 1px solid var(--line); padding: 9px 0; min-height: 48px; gap: 10px; }
.set .fx-set .fx-lab { gap: 6px; }
.set .fx-set .fx-row.dim { opacity: .35; }
.set .fx-set .switch { display: block; width: 40px; height: 24px; }
.set .fx-set .switch span { display: none; } /* our .switch draws its own knob from the .on class */
.set .fx-set .q { display: inline-block; font-size: 11px; line-height: 16px; }
.set .fx-set .seg { display: inline-flex; gap: 0; padding: 2px; border-radius: 9px; }
.set .fx-set .seg button { padding: 5px 9px; border-radius: 7px; font-size: 13px; font-weight: inherit; }
.set .fx-set .seg button[aria-pressed="true"] { background: var(--accent); color: #0f1117; font-weight: 700; }
.set .fx-set .fx-test { background: var(--card); }
.set .fx-set .fx-vol { accent-color: var(--accent); }
/* the Animations / Speed settings drive the game's own peg and ring animations too */
.fx-noanim .peg.new, .fx-noanim .cell.best::after, .fx-noanim .ship.fadein { animation: none !important; }
.fx-noanim .cell.splash::before, .fx-noanim .cell.boom::before { display: none; }
.fx-fast .peg.new { animation-duration: .25s; }
.fx-fast .cell.splash::before, .fx-fast .cell.boom::before { animation-duration: .4s; }
.fx-fast .cell.best::after, .fx-fast .ship.fadein { animation-duration: .33s; }

/* ---------- real table (2026-10-20): the game as it sits on a wooden table, seen from your seat ----------
   Your case is open in front of you: the target grid is the upright lid, the ocean grid is the base lying
   flat (tilted away), the peg tray runs along its front edge. The opponent sits across, behind their lid. */
#tab-play .playmain, #tab-paper .playmain { background: none; }
#tab-play .pside, #tab-paper .pside { border-top: 0; }
/* the back of the opponent's raised lid, with their name plate */
.pbar { margin: 0 4px 6px; padding: 0 8px; border-radius: 10px 10px 3px 3px; color: #c3c9d6;
  background: linear-gradient(#3a4252, #262c38 70%, #1d222c);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.16), inset 0 -2px 0 rgba(0,0,0,.4), 0 4px 8px rgba(0,0,0,.45); }
.pbar b { color: #fff; }
.oppseat { flex: 0 0 auto; min-width: 0; max-width: 30%; }
.oppseat .tbl-plate { font-size: 10px; line-height: 15px; padding: 1px 5px; }
/* moulded plastic case around every grid: labels raised on the rim, the sea panel set into it */
.grid { --rim: 5px; border-radius: 9px;
  background: linear-gradient(165deg, #7c8696, #5a6372 50%, #454d5a);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.32), inset 0 -2px 1px rgba(0,0,0,.35), 0 2px 3px rgba(0,0,0,.45), 0 10px 18px rgba(0,0,0,.4); }
.grid.small { --rim: 3px; border-radius: 6px; }
.grid .cols { right: var(--rim); color: #eef1f6; text-shadow: 0 1px 0 rgba(0,0,0,.45); }
.grid .rows { bottom: var(--rim); color: #eef1f6; text-shadow: 0 1px 0 rgba(0,0,0,.45); }
.sea { right: var(--rim); bottom: var(--rim); border-radius: 4px;
  background:
    linear-gradient(rgba(170,200,235,.16) 1px, transparent 1px) 0 0 / 10% 10%,
    linear-gradient(90deg, rgba(170,200,235,.16) 1px, transparent 1px) 0 0 / 10% 10%,
    radial-gradient(120% 120% at 30% 20%, #102438, #07111c);
  box-shadow: inset 0 2px 4px rgba(0,0,0,.7), inset 0 0 0 1px rgba(0,0,0,.6); }
/* a peg hole in every square */
.sea .cell { background-image: radial-gradient(circle closest-side, #03070c 0 17%, rgba(255,255,255,.16) 21%, transparent 27%); }
/* the ocean grid (base) is lighter, with waves moulded in */
#smallGrid .sea { background:
    linear-gradient(rgba(220,240,255,.2) 1px, transparent 1px) 0 0 / 10% 10%,
    linear-gradient(90deg, rgba(220,240,255,.2) 1px, transparent 1px) 0 0 / 10% 10%,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='12'%3E%3Cpath d='M0 8q6-5 12 0t12 0' fill='none' stroke='%23fff' stroke-opacity='.13' stroke-width='1.3'/%3E%3C/svg%3E") 0 0 / 12px 6px,
    radial-gradient(120% 120% at 30% 20%, #23679c, #133f66); }
/* it lies flat on the table, so it leans away from you */
#smallWrap { perspective: 560px; perspective-origin: 50% 100%; }
#smallWrap .grid { transform: rotateX(24deg); transform-origin: 50% 100%; }
.grid.firing .sea { box-shadow: inset 0 2px 4px rgba(0,0,0,.7), 0 0 0 2px rgba(110,168,254,.6), 0 0 18px rgba(110,168,254,.28); }
/* pegs: plastic pins seen end-on, round head with a dimple, same size red and white */
.peg { position: relative; width: 42%; height: 42%; border-radius: 50%; }
.peg::after { content: ""; position: absolute; inset: 30%; border-radius: 50%; box-shadow: inset 0 1px 1px rgba(0,0,0,.28), 0 1px 0 rgba(255,255,255,.25); }
.peg.hit { background: radial-gradient(circle at 36% 30%, #ffc2bc 0 9%, #e8423b 30%, #b01c20 68%, #6d0d10 100%);
  box-shadow: 0 2px 2px rgba(0,0,0,.6), 0 3px 6px rgba(0,0,0,.35); }
.peg.miss { width: 42%; height: 42%; opacity: 1; background: radial-gradient(circle at 36% 30%, #fff 0 14%, #eef0f4 40%, #c3c8d2 76%, #8d94a3 100%);
  box-shadow: 0 2px 2px rgba(0,0,0,.6), 0 3px 6px rgba(0,0,0,.35); }
/* a peg is pressed in from above: it comes down, its shadow tightens */
@keyframes pegIn { from { transform: translateY(-40%) scale(1.9); opacity: 0; box-shadow: 0 14px 14px rgba(0,0,0,.25); } 60% { opacity: 1; } to { transform: none; opacity: 1; } }
/* ships: grey plastic pieces */
.grid .ship.sunk { opacity: .75; filter: saturate(.4) brightness(.85); }
/* peg tray moulded into the front of the base */
.pegtray { flex: 0 0 auto; height: 15px; display: grid; grid-template-columns: 1.4fr 1fr; grid-template-rows: minmax(0, 1fr); gap: 3px; padding: 2px 3px; margin-top: 3px; border-radius: 5px;
  background: linear-gradient(#59626f, #454d5a); box-shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 2px 4px rgba(0,0,0,.45); }
.pegtray .comp { position: relative; border-radius: 3px; background: #1f242d; box-shadow: inset 0 2px 3px rgba(0,0,0,.75); overflow: hidden; }
.pegtray i { position: absolute; width: 5px; height: 5px; border-radius: 50%; box-shadow: 0 1px 1px rgba(0,0,0,.7); }
.pegtray i.w { background: radial-gradient(circle at 35% 30%, #fff, #c3c8d2 70%, #8d94a3); }
.pegtray i.r { background: radial-gradient(circle at 35% 30%, #ff9b94, #d0302b 55%, #6d0d10); }
.minehead { position: relative; z-index: 1; color: #e7dccb; text-shadow: 0 1px 1px rgba(0,0,0,.6); }
/* helpers and buttons sit on the wood: give text a lift */
#tab-play .info, #tab-paper .info { text-shadow: 0 1px 2px rgba(0,0,0,.55); }
#tab-play .info .muted, #tab-play .aim .of, #tab-paper .info .muted, #tab-paper .aim .of { color: #cdc3b4; }
.msg.miss { color: #d6ccbd; }
@media (min-width: 900px) {
  /* laptop: your case in the middle of the table (lid behind, base in front), the helpers in a slim side panel */
  #tab-play { display: grid; grid-template-columns: minmax(0, 1fr) 340px; grid-template-rows: auto minmax(0, 1fr) 30%; }
  #tab-play::before { content: ""; grid-column: 2; grid-row: 1 / 4; background: rgba(15,17,23,.9); border-left: 1px solid var(--line); }
  #tab-play .playmain { grid-column: 1; grid-row: 1 / 3; padding-bottom: 4px; }
  #tab-play .pside { display: contents; }
  #tab-play .mine { grid-column: 1; grid-row: 3; align-items: center; padding: 0 18px 10px; min-height: 0; }
  #tab-play .minehead { align-self: stretch; text-align: center; }
  #tab-play .gwrap.small { flex: 1 1 auto; height: auto; width: 100%; align-items: flex-end; }
  /* the base is drawn a little bigger than its row and leans back 38deg, so it reads as a board lying on the table */
  #tab-play #smallGrid { width: min(100cqw, 132cqh); height: min(100cqw, 132cqh); flex: none; }
  #tab-play .info { grid-column: 2; grid-row: 1; padding: 12px 16px 0; }
  #tab-play .logbox { grid-column: 2; grid-row: 2 / 4; padding: 0 16px 12px; }
  #tab-play .pegtray { height: 24px; width: min(460px, 70%); }
  .pegtray i { width: 8px; height: 8px; }
  #smallWrap { perspective: 900px; }
  #smallWrap .grid { transform: rotateX(38deg); }
  #tab-paper .pside { background: rgba(15,17,23,.9); }
  .oppseat .tbl-plate { font-size: 12px; line-height: 18px; }
}
@media (orientation: landscape) and (max-height: 520px) and (max-width: 999px) {
  .pegtray, .oppseat { display: none; }
}
.playmain { min-width: 0; }
.pbar { overflow: hidden; }
/* very narrow phones: the fleet tally needs the whole lid; the opponent's name is in the status and messages already */
@media (max-width: 379px) { .oppseat { display: none; } }
/* setting up: in the real game you press your ships into the flat ocean base, so the big board shows the base while you place */
.grid.big.placing .sea { background:
    linear-gradient(rgba(220,240,255,.2) 1px, transparent 1px) 0 0 / 10% 10%,
    linear-gradient(90deg, rgba(220,240,255,.2) 1px, transparent 1px) 0 0 / 10% 10%,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='12'%3E%3Cpath d='M0 8q6-5 12 0t12 0' fill='none' stroke='%23fff' stroke-opacity='.13' stroke-width='1.3'/%3E%3C/svg%3E") 0 0 / 16px 8px,
    radial-gradient(120% 120% at 30% 20%, #23679c, #133f66); }
/* on your lid you only ever see pegs: a sunk enemy ship is a faint outline under its red pegs */
.grid.big .ship.wreck, #paperGrid .ship.wreck { opacity: .42; }
.cell .peg { z-index: 1; }
@media (min-width: 900px) { #tab-play .pegtray { width: min(300px, 70%); } }
/* 320px phones: the aim line stays on one row so its ? never lands on Fire */
@media (max-width: 379px) {
  .pside { grid-template-columns: 124px 1fr; }
  .aim { gap: 5px; }
  .aim .cellname { flex: none; white-space: nowrap; font-size: 21px; }
  .aim .chance { font-size: 13px; white-space: nowrap; }
  .aim .of { min-width: 0; font-size: 11px; white-space: nowrap; }
}

/* ---------- edge pass (2026-10-20) ---------- */
/* fleet tally: a chip never runs into its neighbour; on a phone a hit ship shows its count instead of its name */
.fchip span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; }
.fchip .nm { font-style: normal; }
@media (max-width: 899px) { .fchip.hashit .nm { display: none; } }
/* laptop: WebKit draws the 38deg lean without perspective (the base is only squashed to cos 38 = 0.79 of its height),
   so the base may be at most 1/0.79 = 1.27x its row; 1.26x fills the row there and leaves a little room in Chrome/Safari 3-D */
@media (min-width: 900px) { #tab-play #smallGrid { width: min(100cqw, 126cqh); height: min(100cqw, 126cqh); } }
/* 320px phones: Best, Fire and the Heatmap switch all fit above the tab bar */
@media (max-width: 379px) { .info { gap: 4px; } .aim { min-height: 30px; } .msg { min-height: 18px; } }
/* online on a phone: Leave shares the Heatmap row; keep that row the switch's height so it stays above the tab bar */
@media (max-width: 899px) { #info .row .btn.small[data-act=leave] { height: 24px; padding: 0 9px; font-size: 12px; } }
/* very narrow phones: keep Leave on the Heatmap row instead of wrapping under the tab bar */
@media (max-width: 379px) { #info .row:has(> [data-act=leave]) { flex-wrap: nowrap; gap: 4px; } #info .row:has(> [data-act=leave]) .tog { gap: 4px; min-width: 0; } #info .row .btn.small[data-act=leave] { padding: 0 7px; flex: none; } }

/* ---------- visibility pass (2026-10-21): the boards as big as the screen allows ---------- */
/* tap your fleet to see it as big as the lid; tap again to put it back */
#mineBox { cursor: zoom-in; }
#tab-play.placing #mineBox { cursor: default; }
#tab-play.placing .minehead::after { content: none; }
.minehead::after { content: " \2922"; opacity: .7; font-weight: 700; }
#tab-play.mine-zoom .mine { position: absolute; grid-column: auto; grid-row: auto; z-index: 25; cursor: zoom-out; display: flex; flex-direction: column; align-items: stretch; padding: 6px 8px 4px;
  background-color: var(--tbl-base); background-image: radial-gradient(ellipse 120% 95% at 50% 42%, transparent 52%, var(--tbl-vig) 100%), var(--tbl-tex); background-size: 100% 100%, var(--tbl-tex-size);
  box-shadow: 0 8px 24px rgba(0,0,0,.55); }
/* the fleet box leaves its grid cell while it is big: pin the helpers to their own column so nothing moves */
@media (max-width: 899px) { #tab-play .info { grid-column: 2; grid-row: 1; } #tab-play.placing .info { grid-column: 1; } }
#tab-play.mine-zoom .minehead { flex: 0 0 auto; height: auto; font-size: 15px; line-height: 30px; text-align: center; }
#tab-play.mine-zoom .minehead::after { content: "  \2715"; }
#tab-play.mine-zoom .gwrap.small { flex: 1 1 auto; width: 100%; height: auto; min-height: 0; aspect-ratio: auto; align-items: center; perspective: none; }
#tab-play.mine-zoom #smallGrid { width: min(100cqw, 100cqh); height: min(100cqw, 100cqh); transform: none; --lab: 16px; --rim: 5px; border-radius: 9px; }
#tab-play.mine-zoom #smallGrid .cols, #tab-play.mine-zoom #smallGrid .rows { font-size: 10px; }
#tab-play.mine-zoom .pegtray { display: none; }
/* heat numbers on the laptop lid grow with the squares (they were 9 px on 40-70 px squares) */
@media (min-width: 900px) {
  #tab-play.mine-zoom #smallGrid { --lab: 20px; }
  #tab-play.mine-zoom #smallGrid .cols, #tab-play.mine-zoom #smallGrid .rows { font-size: 12px; }
  .grid.big .cell .pct { font-size: max(9px, calc(min(100cqw, 100cqh) * .021)); }
  .grid.big .cell.best .pct, .grid.big .cell.sel .pct { font-size: max(11px, calc(min(100cqw, 100cqh) * .025)); }
  /* laptop: the lid fills the table's height; your base lies on the table beside it, in the room the lid leaves;
     helpers stay in the side panel. Base column = what is left after the lid (lid ~ tab height - 82 px). */
  #tab-play { grid-template-columns: minmax(0, 1fr) clamp(220px, calc(100% - 208px - 100dvh), 420px) 340px; grid-template-rows: auto minmax(0, 1fr); }
  #tab-play::before { grid-column: 3; grid-row: 1 / 3; }
  #tab-play .playmain { grid-column: 1; grid-row: 1 / 3; }
  #tab-play .mine { grid-column: 2; grid-row: 1 / 3; justify-content: flex-end; padding: 0 12px 14px 0; }
  #tab-play .gwrap.small { flex: 0 0 auto; width: 100%; height: auto; aspect-ratio: 5 / 4; } /* the base leans back to ~0.79 of its height, so its box is wider than tall */
  #tab-play #smallGrid { width: min(100cqw, 126cqh); height: min(100cqw, 126cqh); }
  #tab-play .pegtray { width: min(300px, 90%); }
  #tab-play .info { grid-column: 3; grid-row: 1; }
  #tab-play .logbox { grid-column: 3; grid-row: 2; }
}
/* sideways phone: the lid column is only as wide as the lid; the rest goes to your fleet */
@media (orientation: landscape) and (max-height: 520px) and (max-width: 999px) {
  #tab-play .playmain, #tab-paper .playmain { flex: 0 0 min(calc(100dvh - 104px), 60%); }
  .pside { flex: 1 1 auto; grid-template-columns: minmax(0, 1fr) 180px; }
}
