/* ============================================================================
   Drag(*)nBall Z: Fighter's Edition — WEB CLIENT chrome (css/client.css)
   ----------------------------------------------------------------------------
   Styles for the /play terminal's client features (js/views/play.js): themes,
   font/size vars, the settings drawer, scouter HUD, macro row, scroll pill,
   command palette, highlight rules. Loaded AFTER app.css so overrides win by
   order — app.css itself is never touched.

   DEFAULT POSTURE: with a virgin settings blob no --term-* var and no
   [data-theme] is set, so every rule below falls back to app.css's exact
   values — the terminal is pixel-identical to before this file existed.
   ========================================================================= */

/* [hidden] must beat the display:flex on these rows/overlays */
.play-hud[hidden], .play-macros[hidden], .play-drawer[hidden],
.play-palette[hidden], .play-pill[hidden] { display: none !important; }

/* ---- the terminal instrument: extra grid rows + themable vars ------------- */
.play {
  grid-template-rows: auto 1fr auto auto auto; /* bar / out / hud / macros / in */
  background: var(--term-bg, var(--bg-well));
}
.play-out {
  font-family: var(--term-font, var(--mono));
  font-size: var(--term-size, clamp(14px, 1.15vw, 16px));
  line-height: var(--term-lh, 1.5);
  color: var(--term-fg, #f4f7fb);
}
.play-in input {
  font-family: var(--term-font, var(--mono));
  color: var(--term-fg, var(--fg));
  caret-color: var(--term-accent, var(--green));
}
.play-in .ps { color: var(--term-accent, var(--green)); }
.play-bar.connected .lamp {
  background: var(--term-accent, var(--green));
  box-shadow: 0 0 0.5em var(--term-accent, var(--green));
}
/* bar buttons ([log] [aliases:N] [gear]) reuse the .x language from app.css */
.play-bar .x { user-select: none; }

/* ---- terminal color themes -------------------------------------------------
   A theme re-tints ONLY the chrome + default fg/bg; the in-game ANSI colors
   arrive as inline hex from term.js and stay authoritative. No data-theme
   attribute (the default "scouter") = zero overridden vars = today's look. */
.play[data-theme='amber']    { --term-bg: #050302; --term-fg: #ffdcae; --term-accent: #ffb454; --term-dim: #8a6d4a; }
.play[data-theme='classic']  { --term-bg: #000000; --term-fg: #e8e8e8; --term-accent: #9a9a9a; --term-dim: #6f6f6f; }
.play[data-theme='namek']    { --term-bg: #021208; --term-fg: #d8ffe9; --term-accent: #46f5b8; --term-dim: #3f8a68; }
.play[data-theme='contrast'] { --term-bg: #000000; --term-fg: #ffffff; --term-accent: #ffffff; --term-dim: #bbbbbb; }

/* ---- line-per-div scrollback ---------------------------------------------- */
/* an empty finalized line must keep its height (pre-wrap divs collapse) */
.play-out .tline:empty::before { content: '\200B'; }
/* optional [HH:MM:SS] stamps — every finalized line carries data-ts; the
   .show-ts class (Display > timestamps) reveals them, including on old lines */
.play.show-ts .tline[data-ts]::before {
  content: attr(data-ts) '  ';
  color: var(--term-dim, var(--fg-faint));
  font-size: 0.82em;
}
/* local echo: the EXPANDED outbound line, dim */
.play-out .tline.echo { color: var(--term-dim, var(--fg-dim)); }

/* highlight rules: 2px left rule + a translucent wash of the rule's color;
   the game's own colored spans inside the line are untouched */
.play-out .tline.hl {
  box-shadow: inset 2px 0 0 var(--hl-c, var(--gold));
  background: color-mix(in srgb, var(--hl-c, #ffc24b) 12%, transparent);
}
@keyframes dbzHlFlash {
  0%   { background: color-mix(in srgb, var(--hl-c, #ffc24b) 45%, transparent); }
  100% { background: color-mix(in srgb, var(--hl-c, #ffc24b) 12%, transparent); }
}
.play-out .tline.hl-flash { animation: dbzHlFlash 900ms ease-out 1; }

/* ---- "N new lines" pill (split-scrollback) --------------------------------- */
.play-pill {
  position: absolute; right: 1.1rem; z-index: 6;
  font-family: var(--mono); font-size: 0.78em; letter-spacing: 0.06em;
  padding: 0.2rem 0.7rem; cursor: pointer; user-select: none;
  color: #03170d; background: var(--term-accent, var(--green));
  border: none; box-shadow: 0 0 0.7em rgba(0, 0, 0, 0.55);
}

/* ---- scouter HUD row (Extras > HUD) ---------------------------------------- */
.play-hud {
  display: flex; align-items: center; gap: 0.7ch; flex-wrap: wrap;
  padding: 0.25rem 0.9rem; border-top: 1px solid var(--line);
  font-family: var(--term-font, var(--mono)); font-size: 0.8em; letter-spacing: 0.04em;
  color: var(--term-dim, var(--fg-dim));
}
.play-hud .hud-k { color: var(--term-dim, var(--fg-faint)); letter-spacing: 0.18em; }
.play-hud .hud-pl { margin-left: 1.4ch; }
.play-hud .hud-meter { display: inline-flex; gap: 2px; }
.play-hud .hud-meter i { width: 0.7ch; height: 0.62em; background: var(--line-hot); }
.play-hud .hud-meter i.on.g { background: var(--green); }
.play-hud .hud-meter i.on.y { background: var(--amber); }
.play-hud .hud-meter i.on.r { background: var(--red); }
.play-hud .hud-meter i.on.c { background: #6fe9f0; }
.play-hud .hud-v { color: var(--term-fg, var(--fg)); }
.play-hud .hud-v.g { color: var(--green); }
.play-hud .hud-v.y { color: var(--amber); }
.play-hud .hud-v.r { color: var(--red); }
.play-hud .hud-v.c { color: #6fe9f0; }
.play-hud .plm { height: 0.55em; margin-right: 0.2ch; }

/* ---- macro-button row (Keys > macros) --------------------------------------- */
.play-macros {
  display: flex; flex-wrap: wrap; gap: 0.35rem;
  padding: 0.3rem 0.7rem; border-top: 1px solid var(--line);
}
.play-macros button {
  font-family: var(--term-font, var(--mono)); font-size: 0.78em; letter-spacing: 0.06em;
  padding: 0.18rem 0.6rem; cursor: pointer;
  color: var(--term-accent, var(--green)); background: transparent;
  border: 1px solid var(--line-hot); border-radius: 0;
}
.play-macros button:hover {
  background: var(--bg-raise);
  border-color: var(--term-accent, var(--green));
}

/* ---- settings drawer --------------------------------------------------------
   Slides in from the right, between the status bar and the input row (JS sets
   top/bottom to the live bar/input heights). Scouter-native: corner ticks like
   .modal-win, accent trim from the active theme. */
.play-drawer {
  position: absolute; right: 0; z-index: 10;
  width: min(340px, 88%);
  display: flex; flex-direction: column;
  background: var(--bg-win);
  border-left: 1px solid var(--line-lock);
  transform: translateX(105%);
  transition: transform 180ms ease-out;
  box-shadow: -0.6em 0 1.6em rgba(0, 0, 0, 0.55);
}
.play-drawer.open { transform: translateX(0); }
.play-drawer::before {
  content: ''; position: absolute; inset: -1px;
  pointer-events: none; z-index: 3;
  --tk: var(--term-accent, var(--green));
  background-image:
    linear-gradient(var(--tk), var(--tk)), linear-gradient(var(--tk), var(--tk)),
    linear-gradient(var(--tk), var(--tk)), linear-gradient(var(--tk), var(--tk));
  background-repeat: no-repeat;
  background-position: left top, left top, left bottom, left bottom;
  background-size: 8px 1px, 1px 8px, 8px 1px, 1px 8px;
}
.pd-tabs {
  display: flex; gap: 0.3rem; flex-wrap: wrap;
  padding: 0.5rem 0.6rem 0.4rem;
  border-bottom: 1px solid var(--line);
}
.pd-tab {
  font-family: var(--mono); font-size: 0.72em; letter-spacing: 0.08em;
  padding: 0.22rem 0.55rem; cursor: pointer;
  color: var(--green); background: transparent;
  border: 1px solid var(--line-lock); border-radius: 0;
}
.pd-tab:hover { color: #03170d; background: var(--green); border-color: var(--green); }
.pd-tab.on { color: #1a0e00; background: var(--orange); border-color: var(--orange); }
.pd-body { flex: 1; overflow-y: auto; padding: 0.6rem 0.7rem; font-size: 0.88em; }
.pd-foot {
  display: flex; align-items: center; gap: 0.6ch;
  padding: 0.4rem 0.7rem; border-top: 1px solid var(--line);
  font-size: 0.75em; color: var(--fg-faint);
}
.pd-foot .grow { flex: 1; }
.pd-foot .sled { width: 0.5rem; height: 0.5rem; background: var(--fg-faint); display: inline-block; border-radius: 1px; }
.pd-foot .sled.on { background: var(--green); box-shadow: 0 0 0.4em var(--green); }
.pd-foot .act { color: var(--fg-dim); cursor: pointer; white-space: nowrap; }
.pd-foot .act:hover { color: var(--orange); }

/* drawer form primitives */
.pd-h {
  color: var(--amber); font-family: var(--ui); font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase; font-size: 0.76em;
  margin: 0.8rem 0 0.3rem;
}
.pd-row { display: flex; align-items: center; gap: 0.8ch; margin: 0.45rem 0; }
.pd-lbl {
  color: var(--fg-faint); text-transform: uppercase;
  letter-spacing: 0.12em; font-size: 0.72em; min-width: 7ch; flex-shrink: 0;
}
.pd-in, .pd-select {
  background: var(--bg-well); color: var(--fg);
  border: 1px solid var(--line-hot); border-radius: 0;
  font-family: var(--mono); font-size: 0.9em; padding: 0.25rem 0.45rem;
  min-width: 0;
}
.pd-in { flex: 1; }
.pd-in-name { flex: 0 1 9ch; }
.pd-in:focus, .pd-select:focus { outline: none; border-color: var(--line-lock); }
.pd-check {
  display: flex; align-items: center; gap: 0.5ch;
  margin: 0.4rem 0; cursor: pointer; color: var(--fg-dim); font-size: 0.9em;
}
.pd-check input { accent-color: var(--green); }
.pd-slider { display: inline-flex; align-items: center; gap: 0.8ch; flex: 1; }
.pd-slider input[type='range'] { flex: 1; accent-color: var(--green); min-width: 0; }
.pd-val { color: var(--amber); font-size: 0.85em; min-width: 4.5ch; text-align: right; }
.pd-btn {
  font-family: var(--mono); font-size: 0.78em; letter-spacing: 0.05em;
  padding: 0.22rem 0.6rem; cursor: pointer;
  color: var(--green); background: transparent;
  border: 1px solid var(--line-lock); border-radius: 0; white-space: nowrap;
}
.pd-btn:hover { color: #03170d; background: var(--green); border-color: var(--green); }
.pd-help { color: var(--fg-dim); font-size: 0.82em; margin: 0.2rem 0 0.5rem; line-height: 1.45; }
.pd-help b { color: var(--amber); font-weight: 400; }
.pd-err { color: var(--red); font-size: 0.82em; min-height: 1.1em; margin: 0.15rem 0; }
.pd-prev {
  color: var(--amber); font-size: 0.85em; min-height: 1.2em; margin-top: 0.25rem;
  white-space: pre-wrap; word-break: break-word;
}
.pd-note { color: var(--fg-faint); font-size: 0.78em; margin: 0.3rem 0; }

/* live display sample — rendered through the REAL ansi renderer + term vars */
.pd-sample {
  border: 1px solid var(--line); background: var(--term-bg, var(--bg-well));
  padding: 0.4rem 0.6rem; margin-bottom: 0.55rem;
  font-family: var(--term-font, var(--mono));
  font-size: var(--term-size, 1em);
  line-height: var(--term-lh, 1.5);
  color: var(--term-fg, #f4f7fb);
  white-space: pre-wrap; word-break: break-word;
}

/* theme swatch grid */
.pd-themes { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.pd-theme {
  display: inline-flex; align-items: center; gap: 0.5ch;
  background: transparent; border: 1px solid var(--line-hot); border-radius: 0;
  padding: 0.2rem 0.45rem; cursor: pointer;
  color: var(--fg-dim); font-family: var(--mono); font-size: 0.76em;
}
.pd-theme:hover { border-color: var(--line-lock); color: var(--fg); }
.pd-theme.on { border-color: var(--orange); color: var(--fg); }
.pd-sw {
  width: 1.7rem; height: 0.95rem;
  display: inline-flex; align-items: center; justify-content: center; gap: 2px;
  border: 1px solid var(--line);
}
.pd-sw i { width: 4px; height: 60%; display: inline-block; }

/* list rows (aliases / macros / highlight rules) */
.pd-list { margin: 0.4rem 0; border: 1px solid var(--line); }
.pd-item {
  display: flex; align-items: center; gap: 0.6ch;
  padding: 0.26rem 0.5rem; border-bottom: 1px solid var(--line); font-size: 0.9em;
}
.pd-item:last-child { border-bottom: none; }
.pd-item .k { color: var(--green); white-space: nowrap; }
.pd-item .arrow { color: var(--fg-faint); }
.pd-item .b { color: var(--fg-dim); flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.pd-item .act { color: var(--fg-faint); cursor: pointer; white-space: nowrap; user-select: none; }
.pd-item .act:hover { color: var(--orange); }
.pd-item input[type='checkbox'] { accent-color: var(--green); }
.pd-item.off .k, .pd-item.off .b { opacity: 0.45; }
.pd-item .chip { width: 0.85em; height: 0.85em; display: inline-block; border: 1px solid var(--line); flex-shrink: 0; }
.pd-empty { padding: 0.35rem 0.5rem; color: var(--fg-faint); font-style: italic; font-size: 0.88em; }

/* numpad diagram (Keys tab) */
.pd-pad { display: grid; grid-template-columns: repeat(3, 3.1rem); gap: 2px; margin: 0.4rem 0; }
.pd-pad span {
  border: 1px solid var(--line-hot); text-align: center;
  padding: 0.22rem 0; font-size: 0.76em; color: var(--fg-faint);
}
.pd-pad span b { color: var(--green); font-weight: 400; margin-left: 0.4ch; }

/* ---- command palette (Ctrl+K) ----------------------------------------------- */
.play-palette {
  position: absolute; inset: 0; z-index: 20;
  background: rgba(2, 4, 3, 0.62);
  display: flex; align-items: flex-start; justify-content: center;
  padding-top: 7%;
}
.pal-card {
  width: min(30rem, 92%);
  background: var(--bg-win); border: 1px solid var(--line-lock);
  box-shadow: 0 0.8em 2em rgba(0, 0, 0, 0.6);
}
.pal-in {
  width: 100%; box-sizing: border-box;
  background: var(--bg-well); color: var(--fg);
  border: none; border-bottom: 1px solid var(--line);
  font-family: var(--mono); font-size: 0.95em;
  padding: 0.45rem 0.7rem; outline: none; caret-color: var(--green);
}
.pal-list { max-height: 16rem; overflow-y: auto; }
.pal-item {
  display: flex; align-items: baseline; gap: 1ch;
  padding: 0.28rem 0.7rem; cursor: pointer; font-size: 0.9em;
}
.pal-item.sel { background: var(--bg-raise); box-shadow: inset 2px 0 0 var(--green); }
.pal-item .pal-name { color: var(--green); min-width: 10ch; }
.pal-item .pal-usage {
  color: var(--fg-dim); flex: 1;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
.pal-item .pal-cat { color: var(--fg-faint); font-size: 0.76em; white-space: nowrap; }
.pal-hint { padding: 0.3rem 0.7rem; border-top: 1px solid var(--line); color: var(--fg-faint); font-size: 0.74em; }
.pal-none { padding: 0.4rem 0.7rem; color: var(--fg-faint); font-style: italic; font-size: 0.88em; }

/* ---- reduced motion ---------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .play-drawer { transition: none; }
  .play-out .tline.hl-flash { animation: none; }
}

/* ============================================================================
   COCKPIT LAYOUT (client Phase 2) — the multi-pane HUD around the terminal.
   EVERYTHING below is scoped under .play.cockpit / .play.fx (or element
   classes that only exist in cockpit): CLASSIC mode (no .cockpit class) is
   pixel-identical Phase-1 — the rail element renders display:none and none
   of these rules apply.
   ========================================================================= */

/* master switch chrome — the always-visible [cockpit]/[classic] bar control */
.play-bar .x.mode.on { color: var(--term-accent, var(--green)); }

/* ---- the cockpit grid -------------------------------------------------------- */
.play-rail { display: none; }
.play.cockpit {
  display: grid;
  /* Owner (2026-07-03): RAIL ON THE LEFT. The map/scouter/nearby/chat sit in the primary (left) field
     of view, while the text stream + input stay grouped as one contiguous read/type zone on the right —
     no more diagonal split (text far-left, panels far-right) across a wide screen. */
  grid-template-columns: clamp(300px, 26vw, 380px) minmax(0, 1fr);
  grid-template-rows: auto minmax(0, 1fr) auto auto auto;
  grid-template-areas: "bar bar" "rail out" "rail hud" "rail macros" "rail in";
}
.play.cockpit > .play-bar { grid-area: bar; }
.play.cockpit > .play-out { grid-area: out; min-width: 0; }
.play.cockpit > .play-hud { display: none !important; } /* re-homed as the STATS pane */
.play.cockpit > .play-macros { grid-area: macros; }
.play.cockpit > .play-in { grid-area: in; }
.play.cockpit > .play-rail {
  grid-area: rail;
  display: flex; flex-direction: column; gap: 6px;
  padding: 6px; min-height: 0; overflow-y: auto; position: relative;
  border-right: 1px solid var(--line); /* rail now on the LEFT — divider on its right edge */
  background: var(--bg-pane, var(--bg-win));
}

/* ---- pane cards (the drawer's corner-tick language) --------------------------- */
.pr-card {
  position: relative; display: flex; flex-direction: column; min-height: 0;
  border: 1px solid var(--line-hot); background: var(--bg-win); flex: none;
}
.pr-card::before {
  content: ''; position: absolute; inset: -1px; pointer-events: none; z-index: 3;
  --tk: var(--term-accent, var(--green));
  background-image:
    linear-gradient(var(--tk), var(--tk)), linear-gradient(var(--tk), var(--tk)),
    linear-gradient(var(--tk), var(--tk)), linear-gradient(var(--tk), var(--tk));
  background-repeat: no-repeat;
  background-position: left top, left top, right bottom, right bottom;
  background-size: 8px 1px, 1px 8px, 8px 1px, 1px 8px;
}
.pr-card.off { display: none !important; }
.pr-hd {
  display: flex; align-items: baseline; gap: 0.6ch; flex: none;
  padding: 0.24rem 0.55rem; border-bottom: 1px solid var(--line);
  font-family: var(--mono); font-size: 0.7em; letter-spacing: 0.14em;
  color: var(--fg-faint); text-transform: uppercase; user-select: none;
}
.pr-hd .t { color: var(--amber); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pr-hd .sub { color: var(--fg-faint); letter-spacing: 0.05em; text-transform: none; white-space: nowrap; }
.pr-hd .grow { flex: 1; }

/* standby (pre-game) / offline (link lost) pane states */
.pr-card.standby > :not(.pr-hd) { opacity: 0.22; }
.pr-card.standby::after {
  content: 'AWAITING SIGNAL'; position: absolute; left: 0; right: 0; top: 42%;
  text-align: center; letter-spacing: 0.3em; font-size: 0.6em;
  color: var(--fg-faint); font-family: var(--mono); pointer-events: none;
}
.play-rail.offline .pr-card { opacity: 0.55; filter: saturate(0.4); }

/* ---- MAP pane ------------------------------------------------------------------ */
.pr-map .pr-env { display: flex; flex-wrap: wrap; gap: 3px; padding: 4px 6px 2px; flex: none; }
.env-chip {
  font-family: var(--mono); font-size: 0.62em; letter-spacing: 0.06em;
  padding: 1px 6px; border: 1px solid var(--line); color: var(--fg-dim);
  white-space: nowrap; user-select: none;
}
.env-chip.hot { color: var(--amber); border-color: var(--line-hot); }
.pr-gridwrap { position: relative; overflow: hidden; margin: 4px 6px; flex: none; }
.pr-grid {
  font-family: var(--term-font, var(--mono)); white-space: pre; line-height: 1.12;
  overflow: auto; max-height: 40vh; font-size: 13px;
  color: var(--term-fg, #f4f7fb);
}
/* timestamps would wreck the grid alignment — never inside the map */
.pr-grid .tline::before { content: none !important; }
.pr-grid .tline:empty::before { content: none; }
.pr-fx { position: absolute; inset: 0; pointer-events: none; z-index: 2; overflow: hidden; }
.pr-empty { color: var(--fg-faint); font-style: italic; font-size: 0.75em; padding: 2px 4px; }
.pr-compass {
  display: grid; grid-template-columns: repeat(3, 2.3rem); gap: 2px;
  justify-content: center; padding: 2px 0 6px; flex: none;
}
.pr-compass button {
  font-family: var(--mono); font-size: 0.68em; letter-spacing: 0.05em;
  height: 1.35rem; cursor: pointer; border-radius: 0; padding: 0;
  color: var(--fg-faint); background: transparent; border: 1px solid var(--line);
}
.pr-compass button.lit { color: var(--term-accent, var(--green)); border-color: var(--line-hot); }
.pr-compass button.lit:hover { background: var(--bg-raise); border-color: var(--term-accent, var(--green)); }
.pr-compass button:disabled { opacity: 0.3; cursor: default; }

/* ---- STATS pane (the Phase-1 HUD grown into a panel) --------------------------- */
.pr-stats .stat-rows { padding: 6px 9px 7px; display: flex; flex-direction: column; gap: 6px; }
.stat-row { display: flex; align-items: center; gap: 0.7ch; font-family: var(--mono); font-size: 0.78em; }
.stat-row .k { color: var(--fg-faint); letter-spacing: 0.18em; font-size: 0.85em; flex: none; }
.stat-bar { flex: 1; height: 0.66em; background: var(--bg-well); border: 1px solid var(--line-hot); position: relative; overflow: hidden; }
.stat-fill { position: absolute; top: 0; bottom: 0; left: 0; width: 0; background: var(--green); }
.play.fx .stat-fill { transition: width 250ms ease-out, background-color 200ms linear; }
.stat-fill.warn { background: var(--amber); }
.stat-fill.crit { background: var(--red); }
.stat-fill.over { background: #6fe9f0; }
.play.fx .stat-fill.crit { animation: dbzStatCrit 900ms ease-in-out infinite; }
@keyframes dbzStatCrit { 50% { opacity: 0.55; } }
.stat-row .stat-val { color: var(--term-fg, var(--fg)); min-width: 5.5ch; text-align: right; }
.stat-val.warn { color: var(--amber); }
.stat-val.crit { color: var(--red); }
.stat-val.over { color: #6fe9f0; }
.stat-row .stat-ki { color: var(--term-fg, var(--fg)); flex: 1; text-align: right; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pr-stats .plm { height: 0.55em; flex: none; }

/* ---- NEARBY pane ---------------------------------------------------------------- */
.pr-nearby .nb-wrap { padding: 6px 8px; display: flex; flex-wrap: wrap; gap: 4px; min-height: 1.7em; align-content: flex-start; }
.nb-chip {
  display: inline-flex; align-items: baseline; gap: 0.2ch;
  font-family: var(--mono); font-size: 0.72em; letter-spacing: 0.04em;
  padding: 2px 8px; cursor: pointer; user-select: none; border-radius: 0;
  border: 1px solid var(--line-hot); color: var(--fg-dim); background: transparent;
}
.nb-chip .ct { color: var(--fg-faint); }
.nb-chip.player { color: var(--green); border-color: color-mix(in srgb, var(--green) 45%, transparent); }
.nb-chip.staff { color: #ffc24b; border-color: color-mix(in srgb, #ffc24b 45%, transparent); }
.nb-chip.npc { color: #ff8a7a; border-color: rgba(255, 90, 90, 0.35); }
.nb-chip:hover { background: var(--bg-raise); }
.nb-none { color: var(--fg-faint); font-style: italic; font-size: 0.75em; }

/* nearby quick menu (look / sense / punch — TYPES into the input, never sends) */
.qmenu {
  position: absolute; z-index: 8; min-width: 11rem;
  background: var(--bg-win); border: 1px solid var(--line-lock);
  box-shadow: 0 0.5em 1.4em rgba(0, 0, 0, 0.6);
  font-family: var(--mono); font-size: 0.78em;
}
.qmenu .qm-name { padding: 0.3rem 0.6rem; color: var(--amber); border-bottom: 1px solid var(--line); letter-spacing: 0.06em; }
.qmenu .qm-pl { padding: 0.24rem 0.6rem; color: var(--green); border-bottom: 1px solid var(--line); font-size: 0.9em; }
.qmenu .qm-it { padding: 0.28rem 0.6rem; color: var(--fg-faint); cursor: pointer; }
.qmenu .qm-it:hover { background: var(--bg-raise); color: var(--fg-dim); }
.qmenu .qm-it b { color: var(--term-accent, var(--green)); font-weight: 400; }

/* ---- CHAT pane -------------------------------------------------------------------- */
.pr-chat { flex: 1 1 auto; min-height: 6rem; }
.pr-ctabs { display: flex; gap: 2px; padding: 3px 6px 0; border-bottom: 1px solid var(--line); flex: none; }
.pr-ctab {
  display: inline-flex; align-items: center; gap: 0.6ch;
  font-family: var(--mono); font-size: 0.66em; letter-spacing: 0.1em; text-transform: uppercase;
  padding: 2px 8px; cursor: pointer; border-radius: 0;
  color: var(--fg-faint); background: transparent; border: 1px solid transparent; border-bottom: none;
}
.pr-ctab:hover { color: var(--fg-dim); }
.pr-ctab.on { color: var(--term-accent, var(--green)); border-color: var(--line); }
.ct-badge {
  display: none; min-width: 1.4em; padding: 0 3px; font-size: 0.85em; text-align: center;
  background: var(--orange); color: #1a0e00;
}
.ct-badge.show { display: inline-block; }
.pr-chatlog {
  flex: 1; overflow-y: auto; padding: 4px 8px; min-height: 0;
  font-family: var(--term-font, var(--mono)); font-size: 0.8em; line-height: 1.4;
  white-space: pre-wrap; word-break: break-word; color: var(--term-fg, #f4f7fb);
}
.pr-chatlog[data-tab='ooc'] .tline:not([data-chan='ooc']),
.pr-chatlog[data-tab='say'] .tline:not([data-chan='say']),
.pr-chatlog[data-tab='tell'] .tline:not([data-chan='tell']) { display: none; }
.pr-chatlog .cempty { color: var(--fg-faint); font-style: italic; font-size: 0.85em; }

/* ============================================================================
   COCKPIT EFFECTS — all one-shots 100-300ms, transforms/opacity/box-shadow
   only, every rule gated on .play.fx (cockpit + effects toggle + no
   reduced-motion; JS enforces, the media query below is the second belt).
   ========================================================================= */

/* 1 — scouter boot: staggered pane power-on + one scan-line sweep */
.play.fx .play-rail.boot .pr-card { animation: dbzPrBoot 240ms ease-out backwards; }
.play.fx .play-rail.boot .pr-stats { animation-delay: 70ms; }
.play.fx .play-rail.boot .pr-nearby { animation-delay: 140ms; }
.play.fx .play-rail.boot .pr-chat { animation-delay: 210ms; }
@keyframes dbzPrBoot { from { opacity: 0; transform: translateY(4px); } }
.boot-scan { display: none; }
.play.fx .boot-scan {
  display: block; position: absolute; left: 0; right: 0; top: 0; height: 26%;
  pointer-events: none; z-index: 5;
  background: linear-gradient(180deg, transparent,
    color-mix(in srgb, var(--term-accent, #4df2a2) 14%, transparent), transparent);
  animation: dbzBootScan 300ms ease-out 1 forwards;
}
@keyframes dbzBootScan { from { transform: translateY(-100%); opacity: 1; } to { transform: translateY(420%); opacity: 0; } }

/* 2 — directional map wipe: terrain slides in from the traveled direction */
.play.fx .pr-grid.wipe-n  { animation: dbzWipeN 160ms ease-out; }
.play.fx .pr-grid.wipe-s  { animation: dbzWipeS 160ms ease-out; }
.play.fx .pr-grid.wipe-e  { animation: dbzWipeE 160ms ease-out; }
.play.fx .pr-grid.wipe-w  { animation: dbzWipeW 160ms ease-out; }
.play.fx .pr-grid.wipe-ne { animation: dbzWipeNE 160ms ease-out; }
.play.fx .pr-grid.wipe-nw { animation: dbzWipeNW 160ms ease-out; }
.play.fx .pr-grid.wipe-se { animation: dbzWipeSE 160ms ease-out; }
.play.fx .pr-grid.wipe-sw { animation: dbzWipeSW 160ms ease-out; }
@keyframes dbzWipeN  { from { transform: translateY(-10px); opacity: 0.55; } }
@keyframes dbzWipeS  { from { transform: translateY(10px); opacity: 0.55; } }
@keyframes dbzWipeE  { from { transform: translateX(10px); opacity: 0.55; } }
@keyframes dbzWipeW  { from { transform: translateX(-10px); opacity: 0.55; } }
@keyframes dbzWipeNE { from { transform: translate(7px, -7px); opacity: 0.55; } }
@keyframes dbzWipeNW { from { transform: translate(-7px, -7px); opacity: 0.55; } }
@keyframes dbzWipeSE { from { transform: translate(7px, 7px); opacity: 0.55; } }
@keyframes dbzWipeSW { from { transform: translate(-7px, 7px); opacity: 0.55; } }

/* 4 — damage edge flash (red = you were hit / died; gold = kill line) */
.play.fx .play-out.edge-red { animation: dbzEdgeR 220ms ease-out; }
.play.fx .play-out.edge-gold { animation: dbzEdgeG 260ms ease-out; }
@keyframes dbzEdgeR {
  from { box-shadow: inset 0 0 0 2px rgba(255, 90, 90, 0.85), inset 0 0 22px rgba(255, 90, 90, 0.28); }
  to { box-shadow: none; }
}
@keyframes dbzEdgeG {
  from { box-shadow: inset 0 0 0 2px rgba(255, 194, 75, 0.85), inset 0 0 22px rgba(255, 194, 75, 0.25); }
  to { box-shadow: none; }
}

/* 5 — transformation surge (SSJ gold / Legendary green / accent) */
.play.fx.surge .play-bar, .play.fx.surge .play-rail { animation: dbzSurge 300ms ease-out; }
@keyframes dbzSurge {
  from { box-shadow: inset 0 -1px 0 var(--fx-accent, #ffc24b), 0 0 14px var(--fx-accent, #ffc24b); }
}

/* 6 — nearby chip fades + hostile pulse */
.play.fx .nb-chip.chip-in { animation: dbzChipIn 150ms ease-out backwards; }
@keyframes dbzChipIn { from { opacity: 0; transform: scale(0.92); } }
.play.fx .nb-chip.chip-out { animation: dbzChipOut 180ms ease-out forwards; pointer-events: none; }
@keyframes dbzChipOut { to { opacity: 0; transform: scale(0.9); } }
.play.fx .nb-chip.hostile { animation: dbzChipHot 1.6s ease-in-out infinite; }
@keyframes dbzChipHot { 0%, 100% { opacity: 1; } 50% { opacity: 0.72; } }

/* 7 — area stamp: border pulse + the area name over the map */
.play.fx .pr-map.stamp { animation: dbzStampB 300ms ease-out; }
@keyframes dbzStampB {
  from { box-shadow: 0 0 0 1px var(--term-accent, #4df2a2),
         0 0 16px color-mix(in srgb, var(--term-accent, #4df2a2) 45%, transparent); }
}
.pr-stamp { display: none; }
.play.fx .pr-stamp {
  display: block; position: absolute; left: 0; right: 0; top: 40%; z-index: 4;
  text-align: center; pointer-events: none;
  font-family: var(--mono); letter-spacing: 0.3em; text-transform: uppercase; font-size: 0.85em;
  color: var(--term-accent, #4df2a2); text-shadow: 0 0 10px rgba(0, 0, 0, 0.9);
  animation: dbzStampT 1400ms ease-out 1 forwards;
}
@keyframes dbzStampT {
  0% { opacity: 0; transform: scale(1.06); }
  12% { opacity: 0.92; transform: none; }
  80% { opacity: 0.92; }
  100% { opacity: 0; }
}

/* 8 — weather micro-effects on the map pane (barely-there, pointer-inert) */
.play.fx .pr-map.wx-rain .pr-fx::before {
  content: ''; position: absolute; left: 0; right: 0; top: -60%; bottom: -60%;
  background: repeating-linear-gradient(105deg, transparent 0 6px, rgba(91, 140, 255, 0.06) 6px 7px);
  animation: dbzWxRain 2.2s linear infinite;
}
@keyframes dbzWxRain { to { transform: translateY(30%); } }
.play.fx .pr-map.wx-snow .pr-fx::before,
.play.fx .pr-map.wx-snow .pr-fx::after {
  content: ''; position: absolute; left: 0; right: 0; top: -55%; bottom: 0;
  background-image:
    radial-gradient(rgba(255, 255, 255, 0.30) 1px, transparent 1.6px),
    radial-gradient(rgba(255, 255, 255, 0.18) 1px, transparent 1.6px);
  background-size: 34px 34px, 57px 57px;
  background-position: 3px 7px, 19px 23px;
  opacity: 0.32;
  animation: dbzWxSnow 3.4s linear infinite;
}
.play.fx .pr-map.wx-snow .pr-fx::after { animation-duration: 5s; opacity: 0.2; background-position: 12px 1px, 5px 40px; }
@keyframes dbzWxSnow { to { transform: translateY(38%); } }
.play.fx .pr-map.wx-heat .pr-fx::before {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(255, 140, 26, 0.05), rgba(255, 80, 40, 0.09));
  animation: dbzWxHeat 2.4s ease-in-out infinite;
}
@keyframes dbzWxHeat { 0%, 100% { opacity: 0.45; } 50% { opacity: 1; } }
/* night dimming is a STATIC tint (survives reduced-motion by design) */
.play.fx .pr-map.wx-night .pr-fx { background-color: rgba(2, 6, 20, 0.22); }

/* 9 — otherworld mode: death desaturation + pale halo until the respawn redraw */
.play.cockpit { transition: filter 300ms ease; }
.play.otherworld { filter: saturate(0.35) brightness(0.92); --term-accent: #cfd8ff; }

/* 10 — scouter readout: targeting-bracket scan around the chip quick menu */
.play.fx .qmenu.scan { animation: dbzScanIn 280ms ease-out; }
@keyframes dbzScanIn { from { transform: scale(1.25); opacity: 0; } }
.play.fx .qmenu.scan::before, .play.fx .qmenu.scan::after {
  content: ''; position: absolute; width: 10px; height: 10px; pointer-events: none;
}
.play.fx .qmenu.scan::before {
  top: -4px; left: -4px;
  border-top: 1px solid var(--term-accent, #4df2a2); border-left: 1px solid var(--term-accent, #4df2a2);
}
.play.fx .qmenu.scan::after {
  bottom: -4px; right: -4px;
  border-bottom: 1px solid var(--term-accent, #4df2a2); border-right: 1px solid var(--term-accent, #4df2a2);
}

/* 11 — Dragon Radar map theme (pane-scoped skin; MAIN/chat colors untouched) */
.play.cockpit .pr-map.radar .pr-grid {
  background: radial-gradient(circle at 50% 45%, rgba(24, 255, 140, 0.07), rgba(2, 18, 8, 0.85));
  filter: sepia(1) hue-rotate(90deg) saturate(1.6);
}
.play.cockpit .pr-map.radar .pr-fx {
  background:
    linear-gradient(rgba(24, 255, 140, 0.05) 1px, transparent 1px) 0 0 / 100% 25%,
    linear-gradient(90deg, rgba(24, 255, 140, 0.05) 1px, transparent 1px) 0 0 / 25% 100%,
    radial-gradient(circle at 50% 50%, transparent 55%, rgba(2, 4, 3, 0.85) 96%);
}

/* 12 — idle radar sweep (5 idle minutes; any key kills it) */
.pr-sweep { display: none; }
.play.fx .pr-sweep {
  display: block; position: absolute; inset: -30%; z-index: 3; pointer-events: none;
  background: conic-gradient(from 0deg, transparent 0 340deg, rgba(70, 245, 184, 0.5) 355deg, transparent 360deg);
  opacity: 0;
  animation: dbzSweepIn 300ms ease-out forwards, dbzSweepRot 3.5s linear infinite;
}
@keyframes dbzSweepIn { to { opacity: 0.12; } }
@keyframes dbzSweepRot { to { transform: rotate(1turn); } }

/* ============================================================================
   COCKPIT MOBILE (both required test sizes collapse: 390x844 + 768x1024)
   ========================================================================= */
.pr-strip { display: none; }
.play-dpad { display: none; }
.play-dpad[hidden] { display: none !important; }

@media (max-width: 900px) {
  .play.cockpit {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto minmax(0, 1fr) auto auto auto;
    grid-template-areas: "bar" "rail" "out" "hud" "macros" "in";
  }
  .play.cockpit > .play-rail {
    border-left: none; border-bottom: 1px solid var(--line);
    overflow: visible; padding: 4px; gap: 4px;
  }
  .play.cockpit .pr-strip {
    display: flex; gap: 4px; overflow-x: auto; -webkit-overflow-scrolling: touch;
    padding-bottom: 2px; flex: none;
  }
  .play.cockpit .pr-strip button {
    flex: none; min-height: 44px; min-width: 72px; padding: 0 12px;
    display: inline-flex; align-items: center; justify-content: center; gap: 0.6ch;
    font-family: var(--mono); font-size: 0.72em; letter-spacing: 0.1em;
    color: var(--fg-dim); background: transparent; border: 1px solid var(--line-hot);
    border-radius: 0; cursor: pointer; position: relative;
  }
  .play.cockpit .pr-strip button.on { color: var(--term-accent, var(--green)); border-color: var(--term-accent, var(--green)); }
  .play.cockpit .pr-strip button.off { display: none; }
  .play.cockpit .pr-strip button.ping::after {
    content: ''; position: absolute; top: 5px; right: 5px; width: 6px; height: 6px;
    background: var(--orange);
  }
  /* the top sheet: exactly ONE pane, never overlaying the input */
  .play.cockpit .pr-card { display: none !important; max-height: 42vh; max-height: 42dvh; overflow: hidden; }
  .play.cockpit .play-rail[data-sheet='map'] .pr-map:not(.off),
  .play.cockpit .play-rail[data-sheet='stats'] .pr-stats:not(.off),
  .play.cockpit .play-rail[data-sheet='nearby'] .pr-nearby:not(.off),
  .play.cockpit .play-rail[data-sheet='chat'] .pr-chat:not(.off) { display: flex !important; }
  .play.cockpit .pr-grid { max-height: 24vh; max-height: 24dvh; }
  .play.cockpit .play-rail[data-sheet='chat'] .pr-chat { height: 36vh; height: 36dvh; }
  .play.cockpit .pr-nearby .nb-wrap { max-height: 30vh; overflow-y: auto; }
  /* >=16px game input under the breakpoint: prevents the iOS focus zoom */
  .play.cockpit .play-in input { font-size: max(16px, 0.95em); }
}

/* touch D-pad: only ever rendered on small screens / coarse pointers */
@media (max-width: 900px), (pointer: coarse) {
  .play.cockpit .play-dpad {
    display: grid; position: absolute; z-index: 6;
    right: calc(0.6rem + env(safe-area-inset-right, 0px));
    bottom: calc(3.4rem + env(safe-area-inset-bottom, 0px));
    grid-template-columns: repeat(3, 48px); grid-auto-rows: 48px; gap: 5px;
  }
  .play.cockpit .play-dpad button {
    font-family: var(--mono); font-size: 0.85em; border-radius: 0; cursor: pointer;
    color: var(--term-accent, var(--green)); background: rgba(7, 10, 9, 0.55);
    border: 1px solid var(--line-hot); opacity: 0.55; touch-action: manipulation; padding: 0;
  }
  .play.cockpit .play-dpad button:active { opacity: 1; background: var(--bg-raise); }
}

/* ---- reduced motion: the second belt — kills every cockpit animation ---------- */
@media (prefers-reduced-motion: reduce) {
  .play.fx *, .play.fx *::before, .play.fx *::after { animation: none !important; }
  .play.fx .stat-fill { transition: none; }
  .play.cockpit { transition: none; }
}

/* ---- FULLSCREEN (the [⛶] button; F11-style) ------------------------------------
   When .play is the browser fullscreen element, override the app.css height cap so it
   fills the ENTIRE viewport (not the min(...,calc) desktop size), with no outer border. */
.play.is-fs,
.play:fullscreen,
.play:-webkit-full-screen {
  height: 100vh !important;
  width: 100vw !important;
  max-width: none !important;
  border: 0 !important;
  border-radius: 0 !important;
}
/* the browser paints the fullscreen backdrop black by default — keep our well bg instead */
.play:fullscreen { background: var(--bg-well); }
.play:-webkit-full-screen { background: var(--bg-well); }
