/* PLAYER VS PLAYER (owner challenges; Oct 22 2026) */
.pvm { position: fixed; inset: 0; z-index: 10000; background: rgba(8,10,18,.78); display: flex; align-items: center; justify-content: center; padding: 18px; }
.pvbox { background: #fffdf8; color: #1b2133; border-radius: 16px; max-width: 360px; width: 100%; padding: 22px 20px 18px; text-align: center; box-shadow: 0 18px 50px rgba(0,0,0,.5); }
.pvbox h2 { margin: 0 0 8px; font-size: 1.25rem; line-height: 1.25; }
.pvbox p { margin: 0 0 16px; font-size: .95rem; line-height: 1.4; color: #4a5168; }
.pvbtn2, .pvbtn { appearance: none; border: 0; border-radius: 999px; padding: 12px 22px; font: 700 1rem/1 inherit; background: #1f8a4c; color: #fff; cursor: pointer; min-height: 44px; }
.pvbtn2.alt { background: #e9e5da; color: #1b2133; } .pvbtn2.red { background: #c23a3a; }
.pvbtn2:disabled, .pvbtn:disabled { opacity: .5; cursor: default; }
#hzcard .pvbtn { width: 100%; margin-top: 7px; padding: 9px 10px; font-size: .85rem; min-height: 38px; background: #7a1f2b; }
#hzcard .pvwhy { color: #8a2f2f; font-size: 12px; margin-top: 4px; }
.pvbar { position: fixed; left: 8px; right: 8px; bottom: 8px; z-index: 9990; background: #2a1017; color: #fff; border: 1px solid #7a1f2b; border-radius: 14px; padding: 10px 12px; display: flex; gap: 10px; align-items: center; font-size: .9rem; box-shadow: 0 6px 24px rgba(0,0,0,.45); }
.pvbar span { flex: 1; line-height: 1.3; } .pvbar button { appearance: none; border: 0; border-radius: 999px; padding: 8px 14px; background: #e9e5da; color: #1b2133; font-weight: 700; min-height: 38px; }
#pvp { position: fixed; inset: 0; z-index: 9995; background: #14171f; color: #f2efe6; display: flex; flex-direction: column; align-items: center; padding: 8px 8px calc(8px + env(safe-area-inset-bottom)); overflow: auto; -webkit-overflow-scrolling: touch; }
#pvp .pvhead { width: min(100%, var(--pvs)); display: flex; justify-content: space-between; align-items: center; font-size: .85rem; color: #b9b4a6; margin: 2px 0 6px; }
#pvp .pvplate { width: min(100%, var(--pvs)); display: flex; justify-content: space-between; align-items: center; padding: 6px 4px; gap: 8px; }
#pvp .pvname { font-weight: 700; font-size: 1rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#pvp .pvclk { font: 700 1.5rem/1 ui-monospace, Menlo, Consolas, monospace; background: #232837; padding: 7px 12px; border-radius: 10px; min-width: 5.2ch; text-align: center; }
#pvp .pvclk.on { background: #f2efe6; color: #14171f; } #pvp .pvclk.low { background: #8e1f1f; color: #fff; }
#pvp .pvb { flex: none; position: relative; width: var(--pvs); height: var(--pvs); display: grid; grid-template-columns: repeat(8, 1fr); grid-template-rows: repeat(8, 1fr); border-radius: 6px; overflow: hidden; touch-action: none; user-select: none; -webkit-user-select: none; }
#pvp .pvsq { position: relative; display: flex; align-items: center; justify-content: center; padding: 0; border: 0; background: #b58863; cursor: pointer; }
#pvp .pvsq.l { background: #f0d9b5; }
#pvp .pvsq img { width: 92%; height: 92%; pointer-events: none; -webkit-user-drag: none; }
#pvp .pvsq.last::before { content: ""; position: absolute; inset: 0; background: rgba(255,226,90,.45); }
#pvp .pvsq.sel::before { content: ""; position: absolute; inset: 0; background: rgba(80,170,255,.55); }
#pvp .pvsq.chk::before { content: ""; position: absolute; inset: 0; background: radial-gradient(circle, rgba(230,40,40,.85) 0, rgba(230,40,40,.0) 75%); }
#pvp .pvsq.mv::after { content: ""; position: absolute; width: 28%; height: 28%; border-radius: 50%; background: rgba(20,60,30,.45); }
#pvp .pvsq.cap::after { content: ""; position: absolute; inset: 4%; border-radius: 50%; border: 4px solid rgba(20,60,30,.5); background: none; width: auto; height: auto; }
#pvp .pvco { position: absolute; font-size: 10px; line-height: 1; opacity: .7; color: #5b4630; pointer-events: none; } #pvp .pvsq.l .pvco { color: #8a6a47; }
#pvp .pvco.r { top: 2px; left: 2px; } #pvp .pvco.f { bottom: 2px; right: 3px; }
#pvp .pvmsg { width: min(100%, var(--pvs)); min-height: 2.6em; text-align: center; margin: 8px 0 4px; font-size: 1rem; line-height: 1.3; }
#pvp .pvbtns { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; margin: 6px 0; }
#pvp .pvlist { width: min(100%, var(--pvs)); font-size: .8rem; color: #9aa0b0; text-align: center; margin-top: 4px; word-break: break-word; }
.pvpromo { position: absolute; inset: 0; z-index: 3; display: flex; align-items: center; justify-content: center; background: rgba(0,0,0,.55); gap: 6px; }
.pvpromo button { width: 20%; aspect-ratio: 1; border: 0; border-radius: 10px; background: #f0d9b5; padding: 4px; } .pvpromo img { width: 100%; height: 100%; }

/* Eye powers (owner buttons; opponent effects). The flicker is a slow fade (about 1.2 flashes per second, well under the 3/s limit); reduced motion gets a gentle dim instead of flicker. */
#pvp .pvpwwrap { width: min(100%, var(--pvs)); }
#pvp .pvpw { display: flex; gap: 8px; margin: 2px 0 6px; }
#pvp .pvpwi { flex: 1; min-width: 0; text-align: center; } #pvp .pvpwi small { display: block; min-height: 1.2em; font-size: .72rem; color: #ff9aa4; }
#pvp .pvbtn2.pwr { width: 100%; padding: 9px 6px; font-size: .78rem; background: #1d3f6e; min-height: 40px; }
#pvp .pvb.zap { animation: pvflick var(--pvbcy, 1.2s) ease-in-out infinite; box-shadow: 0 0 18px 4px rgba(120,190,255,.75); }
#pvp .pvbolts { position: absolute; inset: 0; pointer-events: none; animation: pvzap var(--pvbcy, 1.2s) ease-in-out infinite; filter: drop-shadow(0 0 3px #4aa8ff) drop-shadow(0 0 7px #2a7bff); }
#pvp .pvbolts svg { width: 100%; height: 100%; }
#pvp .pvclk.zapc { animation: pvclkz .8s ease-in-out infinite; box-shadow: 0 0 12px 3px rgba(120,190,255,.85); color: #bfe4ff; }
@keyframes pvflick { 0%, 100% { opacity: 1; } 50% { opacity: var(--pvbmin, .6); } }   /* bb-pvpforce 2: dims only to pvpBdMinOp */
@keyframes pvzap { 0%, 100% { opacity: 0; } 50% { opacity: .95; } }
@keyframes pvclkz { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-2px); } 75% { transform: translateX(2px); } }
@media (prefers-reduced-motion: reduce) {
  #pvp .pvb.zap { animation: pvdim 3s ease-in-out infinite; } @keyframes pvdim { 0%, 100% { opacity: 1; } 50% { opacity: var(--pvbrm, .7); } }
  #pvp .pvbolts { animation: none; opacity: .5; } #pvp .pvclk.zapc { animation: none; }
}
#pvp .pvsq.pm::before { content: ""; position: absolute; inset: 0; background: rgba(255,150,40,.5); }
#pvp .pvarrow { position: absolute; inset: 0; pointer-events: none; z-index: 2; } #pvp .pvarrow svg { width: 100%; height: 100%; }

/* ---- the Eye approaches INSIDE the Horizon strip (#horizon, the hills band above the board). The game screen sits below the strip; the rest of the page is untouched. ---- */
#horizon .pvhzcv { position: absolute; left: 0; top: 0; width: 100%; height: 100%; z-index: 4; pointer-events: none; display: block; transition: opacity .3s ease; }
#horizon.eyeseq > *:not(svg):not(.pvhzcv):not(.pvhzskip) { opacity: 0 !important; pointer-events: none !important; transition: opacity .4s ease; }  /* players, figures, labels, markers vanish; the strip's own sky + hills (the svg scene) stay exactly as they are */
#horizon .pvhzskip { position: absolute; right: 8px; top: 8px; z-index: 6; font: 600 13px/1 "Segoe UI", Helvetica, Arial, sans-serif; color: #fff; background: rgba(20,28,60,.8); border: 1px solid #6fb4ff; border-radius: 8px; min-height: 44px; min-width: 64px; cursor: pointer; }

/* the resident Eye + far tower live inside the strip, between the scene and the players; hidden while the attack sequence runs and in boss/gatekeeper fights */
#horizon .pvres { position: absolute; left: 0; top: 0; width: 100%; height: 100%; z-index: 0; pointer-events: none; display: block; transition: opacity .4s ease; }
#horizon.eyeseq .pvres, #horizon.fightv .pvres, #horizon.bossin .pvres { opacity: 0; }
#pvp .pvclk.frz::after { content: " \26A1"; color: #9fd8ff; text-shadow: 0 0 6px #4aa8ff; }   /* bb-eye2: frozen clock marker */

/* bb-pvpforce 2: the game board sits exactly where the page board was (same size); everything else is in a panel under it (portrait) or beside it (landscape) */
#pvp.pvpin { display: block; overflow: hidden; padding: 0; }
#pvp.pvpin .pvb { position: absolute; margin: 0; }
#pvp.pvpin .pvside { position: absolute; overflow-x: hidden; overflow-y: auto; -webkit-overflow-scrolling: touch; display: flex; flex-direction: column; align-items: center; box-sizing: border-box; padding: 0 2px calc(8px + env(safe-area-inset-bottom)); }
#pvp .pvside { display: contents; } #pvp .pvplates { display: contents; }
#pvp.pvpin .pvside { display: flex; } #pvp.pvpin .pvplates { display: flex; width: 100%; gap: 8px; flex: none; }
#pvp.pvpin .pvplates .pvplate { flex: 1 1 0; min-width: 0; width: auto; padding: 4px 2px; }
#pvp.pvpin .pvside .pvhead, #pvp.pvpin .pvside .pvmsg, #pvp.pvpin .pvside .pvlist, #pvp.pvpin .pvside .pvpwwrap { flex: none; }
#pvp.pvpin .pvside .pvmsg { min-height: 1.3em; margin: 4px 0 2px; }
#pvp.pvpin .pvside .pvhead { margin: 6px 0 0; opacity: .8; }
/* bb-pvpforce 3: the resting Eye in the strip is a button (record + game log) */
#horizon .hzeyebtn { position: absolute; left: 15%; top: 30%; width: 64px; height: 64px; transform: translate(-50%, -50%); z-index: 4; border: 0; padding: 0; margin: 0; background: transparent; border-radius: 50%; cursor: pointer; -webkit-tap-highlight-color: transparent; }
#horizon .hzeyebtn:focus-visible { outline: 3px solid #8ab4ff; outline-offset: 2px; }
#horizon.eyeseq .hzeyebtn, #horizon.fightv .hzeyebtn, #horizon.bossin .hzeyebtn, html.hzc #horizon .hzeyebtn { display: none; }
/* bb-clockfix (Oct 25 2026): the clock row never overflows. Cause: the 'flex: none' rule above also caught .pvplate (same specificity,
   later), so both plates kept their full content width and the second clock ran off the panel on phones. The two plates are now a 2-column
   grid: each column is its natural width when both fit (same look as before), otherwise the space is shared so the short plate keeps its
   natural width and the long one gives way. The name shrinks with an ellipsis; the clock never shrinks. */
#pvp .pvname { flex: 0 1 auto; min-width: 0; }
#pvp .pvclk { flex: none; white-space: nowrap; }
#pvp.pvpin .pvplates { display: grid; grid-template-columns: minmax(0, max-content) minmax(0, max-content); column-gap: 8px; }
#pvp.pvpin .pvplates .pvplate { min-width: 0; width: auto; }
/* bb-clockfix 2 (Howard 10:39): each clock wears its player's colour - White = light clock, dark digits; Black = near-black clock, light digits
   (thin light edge so it shows on the dark panel). Whose turn: a green ring INSIDE the clock (no layout shift, never clipped). Under 20 s: red digits,
   and the ring turns red when it is that clock's turn. Works the same on both tones and for both viewers. */
#pvp .pvplate .pvclk.cw { background: #f2efe6; color: #14171f; }
#pvp .pvplate .pvclk.ck { background: #06070b; color: #f2efe6; }
#pvp .pvplate .pvclk.ck:not(.zapc) { box-shadow: inset 0 0 0 1px #6b7288; }
#pvp .pvplate .pvclk.on { outline: 3px solid #35c46a; outline-offset: -3px; }
#pvp .pvplate .pvclk.cw.low { color: #b3141b; }
#pvp .pvplate .pvclk.ck.low { color: #ff7070; }
#pvp .pvplate .pvclk.on.low { outline-color: #ff3b3b; }
