/* Cross My Heart — web build styles. Parchment / ink / gold, Arena-mapped layout. */
:root{
  --ink:#1d1508; --ink2:#3a2c14; --parch:#f6f1e7; --parch2:#efe5cf;
  --gold:#c9a227; --gold2:#e8c877; --play:#2fe673; --red:#a02c22; --teal:#1f5f5b;
  --cardw:118px; --cardh:164px;
}
*{box-sizing:border-box}
/* No text selection anywhere in the game UI (Jace, Nov 5, 2026): on
   Android, scrolling or long-pressing over words selects them and pops
   the system search dialog mid-game. The whole UI is unselectable and
   the long-press callout is suppressed — real text fields (auth,
   chat, search, deck names, room codes) stay fully editable below. */
body{-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}
input,textarea,select,[contenteditable="true"]{-webkit-user-select:text;user-select:text;-webkit-touch-callout:default}
html,body{margin:0;padding:0}
body{font-family:Georgia,'Times New Roman',serif;color:var(--ink);background:#0d1420;min-height:100vh}
body #screen-home, body .screen:not(#screen-match){background:#0d1420 var(--theme-img) center/cover fixed}
button{font-family:inherit}
.hidden{display:none !important}

/* ---------- screens & panels ---------- */
.screen{display:none;min-height:100vh;padding:14px}
.screen.active{display:block}
#screen-loading{display:none;align-items:center;justify-content:center;text-align:center}
#screen-loading.active{display:flex}
.loading-bg{position:fixed;inset:0;background:#0d1420 url('assets/bg-dawn-harbour.webp') center/cover;opacity:.85}
.loading-card{position:relative;background:rgba(246,241,231,.94);border:2px solid var(--gold);border-radius:14px;padding:28px 30px;max-width:560px;box-shadow:0 12px 40px rgba(0,0,0,.5)}
.brand-logo{display:block;width:118px;height:auto;margin:2px auto 10px}
.brand-logo.small{width:82px;margin-bottom:6px}
.game-title{font-size:42px;margin:0 0 4px;letter-spacing:1px;color:var(--ink)}
.game-title.small{font-size:30px}
.game-sub{font-style:italic;color:var(--ink2);margin:0 0 16px}
.tidbit-box{border-top:1px solid var(--gold);border-bottom:1px solid var(--gold);padding:12px 6px;min-height:96px}
.tidbit-title{font-variant:small-caps;letter-spacing:2px;color:var(--red);font-weight:bold}
.tidbit-text{font-style:italic;line-height:1.45;margin:6px 0 0}
.loading-note{color:var(--ink2);font-size:13px}
.panel{background:rgba(246,241,231,.97);border:2px solid var(--gold);border-radius:12px;padding:18px;max-width:640px;margin:24px auto;box-shadow:0 10px 30px rgba(0,0,0,.45)}
.wide-panel{max-width:1060px}
.panel h2,.panel h3{margin-top:0}
.fine{font-size:14px;line-height:1.45;color:var(--ink2)}
.fine.dim{opacity:.75;font-size:12.5px}
.fld{display:block;margin:10px 0;font-size:14px}
.fld input,.fld select{width:100%;padding:9px;border:1px solid var(--ink2);border-radius:6px;background:#fff;font-size:15px;margin-top:4px}
.or-row{text-align:center;border-top:1px solid #cbbf9f;margin:16px 0 4px;position:relative}
.or-row span{background:var(--parch);padding:0 10px;position:relative;top:-10px;font-style:italic;color:var(--ink2)}

/* ---------- buttons ---------- */
.btn{background:var(--parch2);border:1.5px solid var(--ink2);color:var(--ink);border-radius:8px;padding:8px 16px;font-size:15px;cursor:pointer;transition:transform .08s, box-shadow .15s}
.btn:hover{box-shadow:0 2px 10px rgba(0,0,0,.25)}
.btn:active{transform:scale(.97)}
.btn.primary{background:linear-gradient(180deg,var(--gold2),var(--gold));border-color:#7a5f10;font-weight:bold}
.btn.ghost{background:transparent;border-color:rgba(120,100,50,.5)}
.btn.small{padding:4px 10px;font-size:13px}
.btn.big{padding:12px 22px;font-size:17px}
.btn.wide{width:100%;margin:6px 0}
.btn.danger{background:#f3d9d4;border-color:var(--red);color:var(--red)}
.btn:disabled{opacity:.45;cursor:default;box-shadow:none}
.badge{background:var(--red);color:#fff;border-radius:10px;padding:0 7px;font-size:12px}

/* ---------- topbar / home ---------- */
.topbar{display:flex;align-items:center;gap:14px;background:rgba(13,20,32,.82);color:var(--parch);padding:10px 14px;border-radius:10px;max-width:1060px;margin:0 auto 14px}
.topbar h3{margin:0;flex:0 0 auto}
.topbar .btn.ghost{color:var(--parch);border-color:rgba(246,241,231,.4)}
.brand{font-variant:small-caps;letter-spacing:1px;font-size:18px;display:flex;align-items:center;gap:9px}
.brand-mark{width:27px;height:26px;flex:0 0 auto}
.wallet{margin-left:auto;font-size:14px;display:flex;gap:12px;flex-wrap:wrap}
.wallet b{color:var(--gold2)}
.home-hero{max-width:860px;margin:30px auto;background:rgba(246,241,231,.60);backdrop-filter:blur(9px) saturate(1.08);-webkit-backdrop-filter:blur(9px) saturate(1.08);border:2px solid var(--gold);border-radius:14px;padding:26px;text-align:center;box-shadow:0 12px 34px rgba(0,0,0,.45),inset 0 1px 0 rgba(255,255,255,.55)}
.home-actions{display:flex;gap:14px;justify-content:center;flex-wrap:wrap;margin:16px 0 22px}
.home-hero .home-actions .btn{box-shadow:0 3px 10px rgba(31,24,8,.20)}
.home-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:12px}
.tile{background:linear-gradient(180deg,rgba(255,253,247,.96),rgba(243,234,214,.92));border:1.5px solid rgba(146,118,54,.55);border-radius:14px;padding:14px 8px 12px;font-size:26px;cursor:pointer;display:flex;flex-direction:column;gap:5px;align-items:center;box-shadow:0 2px 6px rgba(31,24,8,.14);transition:transform .15s ease,box-shadow .15s ease,border-color .15s ease}
.tile:hover{transform:translateY(-2px);border-color:var(--gold);box-shadow:0 7px 16px rgba(31,24,8,.22)}
.tile:active{transform:translateY(0)}
.tile-icon{width:56px;height:56px;border-radius:50%;object-fit:cover;box-shadow:0 3px 9px rgba(20,16,4,.35);background:#0d1420}
.tile span{font-size:15px;font-weight:600}
.tile small{font-size:11.5px;color:var(--ink2)}
.tile:hover{border-color:var(--gold);box-shadow:0 3px 12px rgba(0,0,0,.2)}

/* ---------- cards ---------- */
.mini-card{position:relative;width:var(--cardw);min-height:var(--cardh);background:linear-gradient(180deg,#fdfaf2,#f3ead2);border:2px solid var(--ink2);border-radius:9px;padding:5px;font-size:11px;display:flex;flex-direction:column;cursor:pointer;flex:0 0 auto;transition:transform .15s, box-shadow .15s;user-select:none}
.mini-card .art{height:62px;border-radius:5px;background-size:cover;background-position:center;border:1px solid rgba(60,44,20,.4);margin-bottom:4px}
.mini-card .cname{font-weight:bold;font-size:11.5px;line-height:1.15}
.mini-card .ctype{font-variant:small-caps;font-size:9.5px;color:var(--ink2);letter-spacing:.4px}
.mini-card .ctext{font-size:9.8px;line-height:1.25;overflow:hidden;display:-webkit-box;-webkit-line-clamp:5;-webkit-box-orient:vertical}
.mini-card .crow{display:flex;justify-content:space-between;align-items:center}
.mini-card .cost{background:var(--gold2);border:1px solid #7a5f10;border-radius:50%;width:19px;height:19px;display:inline-flex;align-items:center;justify-content:center;font-weight:bold;font-size:11px}
.mini-card .pow{background:var(--ink);color:var(--gold2);border-radius:5px;padding:1px 6px;font-weight:bold}
.mini-card .mark{font-size:10px}
.mini-card .rar{font-size:9px;font-variant:small-caps}
.rar-Common{color:#5c5342}.rar-Uncommon{color:#2c6e49}.rar-Rare{color:#2456a6}.rar-Mythic{color:var(--red)}
.mini-card.rested{transform:rotate(7deg);opacity:.62}
.mini-card.host-attached{outline:2px dashed var(--teal);outline-offset:-5px}
/* cmh-v119: the tag is a one-line strip, never a balloon — unbounded,
   at table size it wrapped over the host's whole face and the
   attachment's name became the unit's identity (Jace's blocker-picker
   catch, Nov 6). Full attachment truth lives in the inspect panel. */
.mini-card .attached-tag{position:absolute;bottom:4px;left:4px;max-width:calc(100% - 8px);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;background:var(--teal);color:#fff;border-radius:4px;font-size:9px;padding:1px 4px}
.mini-card.legal{box-shadow:0 0 0 2px var(--play),0 0 16px 4px rgba(47,230,115,.75);animation:glowpulse 1.6s ease-in-out infinite}
.mini-card.selected{box-shadow:0 0 0 3px var(--red),0 0 18px rgba(160,44,34,.5)}
.mini-card.targetable{box-shadow:0 0 0 2px var(--red)}
.mini-card.fresh{animation:deployin .45s ease-out}
@keyframes glowpulse{0%,100%{box-shadow:0 0 0 2px var(--play),0 0 10px 2px rgba(47,230,115,.55)}50%{box-shadow:0 0 0 2px var(--play),0 0 20px 7px rgba(47,230,115,.9)}}
@keyframes deployin{from{transform:translateY(-26px) scale(1.12);opacity:0}to{transform:none;opacity:1}}
.card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(122px,1fr));gap:10px;margin-top:10px;grid-auto-rows:min-content}
.card-grid .mini-card{width:100%}
/* Grid cards are whole cards in their true portrait shape — never a
   landscape slice. (The fixed --cardh height against a wide grid cell
   was cropping faces to a strip and clipping text cards.) */
.card-grid .mini-card,.card-grid .mini-card.face-card{height:auto;min-height:0;aspect-ratio:5/7}
.count-chip{position:absolute;bottom:4px;left:4px;background:var(--ink);color:var(--gold2);border-radius:9px;font-size:10.5px;padding:1px 6px;font-weight:bold}

/* ---------- match table ---------- */
#screen-match{padding:0}
#table{position:relative;min-height:100vh;padding:10px 12px 8px;background:#10161d var(--theme-img) center/cover}
.match-top{display:flex;align-items:center;gap:12px;max-width:1180px;margin:0 auto}
.phase-ladder{display:flex;gap:5px}
.phase-ladder .ph{background:rgba(13,20,32,.72);color:#b9ac8d;border:1px solid rgba(232,200,119,.35);border-radius:14px;padding:3px 11px;font-size:12.5px;font-variant:small-caps;letter-spacing:1px}
.phase-ladder .ph.now{background:var(--gold);color:var(--ink);font-weight:bold;box-shadow:0 0 12px rgba(232,200,119,.8)}
.phase-ladder .ph.done{opacity:.45}
/* Whose turn it is, stated on the progress bar itself (Jace, Nov 4, 2026). */
.phase-ladder .ph.owner{font-variant:normal;font-weight:800;letter-spacing:1.2px;border-width:1.5px}
.phase-ladder .ph.owner.mine{background:#2f9e5f;color:#fff;border-color:#57c785;box-shadow:0 0 10px rgba(70,200,120,.55)}
.phase-ladder .ph.owner.foe{background:#a33338;color:#fff;border-color:#d77a7e;box-shadow:0 0 10px rgba(220,80,80,.5)}
.phase-ladder .ph.owner.setup{background:rgba(13,20,32,.72);color:#b9ac8d}
.phase-ladder.foe .ph.now{background:#a33338;color:#fff;border-color:#d77a7e;box-shadow:0 0 12px rgba(220,80,80,.65)}
.turn-banner{color:var(--parch);font-style:italic;font-size:14.5px;text-shadow:0 1px 3px #000}
#btn-gear{margin-left:auto;color:var(--parch);border-color:rgba(246,241,231,.4)}
.board{max-width:1180px;margin:6px auto;background:rgba(246,241,231,.13);border:1px solid rgba(232,200,119,.30);border-radius:12px;padding:8px 10px;backdrop-filter:blur(1.5px)}
.player-strip{display:flex;align-items:center;gap:12px;color:var(--parch)}
.portrait{width:44px;height:44px;border-radius:50%;background:radial-gradient(circle at 35% 30%,#5a4632,#241a0c);border:2px solid var(--gold);display:flex;align-items:center;justify-content:center;font-size:21px;color:var(--gold2)}
.pname{font-variant:small-caps;letter-spacing:1px;font-size:15px}
.hearts{font-size:15px}
.hearts .hnum{font-weight:bold;font-size:19px;color:#ffb3a6}
.hearts .hnum.bump{animation:hbump .5s}
@keyframes hbump{30%{transform:scale(1.45);color:#fff}}
/* cmh-v92 (Jace, Nov 5, 2026): your Hearts live in the table's top-left
   corner for the whole match — both board views, every phase — instead of
   only on your side of the mat. */
.hud-hearts{flex:0 0 auto;background:rgba(13,20,32,.88);border:1.5px solid rgba(232,200,119,.55);border-radius:999px;padding:3px 13px 4px;font-size:17px;color:#ff5347;white-space:nowrap;box-shadow:0 2px 8px rgba(0,0,0,.35)}
.hud-hearts .hnum{font-weight:bold;font-size:20px;color:#ffb3a6}
.hud-hearts .hnum.bump{animation:hbump .5s}
/* The block dialog's hearts math, big and graphical: now -> if it lands. */
.hearts-flow{display:flex;align-items:flex-start;justify-content:center;gap:18px;width:100%;padding:8px 0 2px}
.hearts-flow .hf-side{display:flex;flex-direction:column;align-items:center;gap:1px;min-width:96px}
.hearts-flow .hf-top{display:flex;align-items:center;gap:7px}
.hearts-flow .hf-heart{font-size:42px;line-height:1;color:#e0392c;text-shadow:0 2px 6px rgba(224,57,44,.35)}
.hearts-flow .hf-num{font-size:40px;font-weight:800;color:var(--ink);line-height:1}
.hearts-flow .hf-label{font-size:11.5px;font-variant:small-caps;letter-spacing:1.2px;color:#7a6a4d}
.hearts-flow .hf-arrow{font-size:32px;color:#b98a2e;line-height:1;padding-top:8px}
.hearts-flow .hf-side.danger .hf-num{color:#c22e21}
.hearts-flow .hf-side.danger .hf-heart{color:#c22e21}
.pile-info{margin-left:auto;display:flex;gap:8px}
.pile{background:rgba(13,20,32,.72);color:var(--parch);border:1px solid rgba(232,200,119,.4);border-radius:8px;padding:4px 10px;font-size:11.5px;cursor:pointer;text-align:center;display:inline-flex;align-items:center;gap:7px}
.pile-art{width:19px;height:27px;border-radius:3px;flex:0 0 auto;background-size:cover;background-position:center;border:1px solid rgba(232,200,119,.55);box-shadow:0 1px 3px rgba(0,0,0,.45);position:relative;overflow:hidden}
.pile-backart{background-image:url('assets/cmh-card-back.png')}
.pile-topart{background-image:url('assets/cmh-card-back.png');opacity:.38}
.pile-topart .pile-top{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.pile.static{cursor:default}
.field-row{display:flex;gap:9px;min-height:172px;align-items:flex-start;padding:6px 2px;overflow-x:auto}
.berth-row{display:flex;gap:9px;min-height:0;padding:2px}
.berth-row .mini-card{--cardw:96px;--cardh:132px;width:96px;min-height:132px;opacity:.92}
.berth-label{color:var(--parch);font-size:12px;font-style:italic;align-self:center}
.energy-row{display:flex;gap:7px;min-height:54px;align-items:center;padding:2px}
/* Energy is a card set face down; spent Energy turns sideways (Jace, Nov 4, 2026). */
.energy-card{width:34px;height:48px;flex:0 0 auto;margin:0 2px;transition:transform .25s}
.energy-card .ec-back{width:100%;height:100%;border-radius:5px;background:#0b101f url('assets/cmh-card-back.png') center/cover;border:1.5px solid var(--gold);box-shadow:0 2px 6px rgba(0,0,0,.4)}
.energy-card.rested{transform:rotate(90deg) scale(.86);opacity:.55}
.hand .mini-card.cant-afford{filter:grayscale(.5) brightness(.68)}
/* The Energy step's settable glow (cmh-v122): in the step, hand cards are
   chooseable — a pulsing gold ring; the chosen card burns steadier. */
.hand .mini-card.settable{box-shadow:0 0 0 2px var(--gold),0 0 14px 3px rgba(232,200,119,.55);animation:glowpulse 1.6s ease-in-out infinite}
.hand .mini-card.energy-picked{box-shadow:0 0 0 3px var(--gold),0 0 20px 6px rgba(232,200,119,.85);animation:none}
.midline{max-width:1180px;margin:2px auto;display:flex;justify-content:flex-end}
.resolution-rail{width:300px;max-width:44vw;max-height:104px;overflow-y:auto;background:rgba(13,20,32,.66);border:1px solid rgba(232,200,119,.30);border-radius:8px;color:#e9e0c8;font-size:12px;padding:6px 9px}
.resolution-rail div{padding:1.5px 0;border-bottom:1px dotted rgba(232,200,119,.18)}
.resolution-rail div:last-child{border-bottom:none}
#arrows{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible}
.hand-zone{max-width:1180px;margin:4px auto 0;display:flex;align-items:flex-end;gap:14px}
.hand{display:flex;gap:6px;flex:1;justify-content:flex-start;min-height:150px;align-items:flex-end;padding-top:16px}
.hand .mini-card:first-child{margin-left:auto}
.hand .mini-card:last-child{margin-right:auto}
/* (cmh-v120: the old :hover raise is gone — hover lifts the peek
   clone instead; see the fan block by the gesture rules.) */
.action-dock{display:flex;flex-direction:column;gap:7px;align-items:stretch;min-width:190px}
.hint{color:var(--parch);font-size:13px;font-style:italic;text-shadow:0 1px 3px #000;min-height:32px}
.float-delta{position:absolute;font-weight:bold;font-size:21px;color:#ffb3a6;text-shadow:0 1px 4px #000;animation:floatup 1.15s ease-out forwards;pointer-events:none;z-index:40}
.float-delta.gain{color:#b7f0b0}
@keyframes floatup{from{transform:translateY(0);opacity:1}to{transform:translateY(-44px);opacity:0}}

/* ---------- chat ---------- */
#chat-toggle{position:fixed;left:14px;bottom:14px;z-index:30;color:var(--parch);border-color:rgba(246,241,231,.45);background:rgba(13,20,32,.8)}
/* cmh-v126: build stamp — tiny parchment label in the match screen's
   bottom-right corner (clear of the centred primary button, whose
   dock ends well short of the corner), so the running build can be
   read off any screenshot. Never interactive, never over play. */
#build-stamp{position:fixed;right:10px;bottom:8px;z-index:29;pointer-events:none;font-size:10.5px;letter-spacing:.06em;color:var(--parch);opacity:.45;text-shadow:0 1px 2px #000}
.build-stamp-line{text-align:center;margin:10px 0 0;opacity:.75}
/* cmh-v127: tap event recorder panel — diagnostic overlay toggled
   from the Ship's Menu ("Tap log"). Fixed top-left, under the HUD
   row: at phone size it clears the hand (bottom) and the primary
   button (bottom-centre), and it sits below the inspect overlay
   (z-85), so an open preview covers it rather than the other way
   round. Monospace, pre-line, never interactive. */
#tap-log{position:fixed;left:8px;top:54px;z-index:60;pointer-events:none;width:318px;max-width:72vw;max-height:46vh;overflow:hidden;background:rgba(8,10,18,.86);border:1px solid rgba(216,183,106,.4);border-radius:8px;padding:6px 8px;font:10px/1.55 ui-monospace,Menlo,Consolas,monospace;color:#e8dfc8;white-space:pre-line;word-break:break-word;text-shadow:0 1px 1px #000}
/* cmh-v127: raise-hand control — pinned to the hand strip's top-right
   corner, clear of the centred fan; styled like the strip's nudge
   buttons. Always offered (the raised view is an option, not an
   overflow rescue). */
#btn-raise-hand{position:absolute;top:0;right:2px;z-index:7;padding:3px 10px;border-radius:9px;border:1.5px solid var(--gold);background:rgba(13,20,32,.85);color:var(--gold2);font-size:12px;font-variant:small-caps;letter-spacing:.06em;cursor:pointer}
#btn-raise-hand:hover{background:rgba(13,20,32,.97)}
/* cmh-v127: the raised hand — whole hand at once, large, over the
   DIMMED board (translucent, never opaque: the board stays present
   behind it). z-70: above the table, below the toast (80) and the
   card preview (85) — a press inside opens the preview ABOVE it,
   and closing the preview returns here. The grid scrolls if a very
   large hand needs a second look; face cards keep their aspect via
   the fixed --cardh height. */
#hand-view{position:fixed;inset:0;z-index:70;background:rgba(5,8,14,.78);display:flex;flex-direction:column;padding:44px 12px calc(10px + env(safe-area-inset-bottom))}
.hv-bar{display:flex;align-items:center;justify-content:space-between;gap:10px;flex:0 0 auto;padding:2px 2px 8px}
#hv-close{background:rgba(13,20,32,.92);border:1.5px solid var(--gold);color:var(--gold2)}
.hv-title{color:var(--parch);font-variant:small-caps;letter-spacing:.08em;font-size:15px;text-shadow:0 1px 2px #000}
.hv-grid{flex:1;display:flex;flex-wrap:wrap;gap:12px;align-content:center;justify-content:center;overflow-y:auto;padding:6px 2px}
.hv-grid .mini-card{--cardw:150px;--cardh:209px;box-shadow:0 10px 26px rgba(0,0,0,.55)}
@media (max-height:500px){
  .hv-grid{gap:9px}
  .hv-grid .mini-card{--cardw:118px;--cardh:164px}
}
#chat-panel{position:fixed;left:14px;bottom:56px;width:330px;max-width:92vw;background:rgba(246,241,231,.98);border:2px solid var(--gold);border-radius:10px;z-index:31;padding:10px;box-shadow:0 12px 30px rgba(0,0,0,.5)}
.chat-head{display:flex;justify-content:space-between;align-items:center;font-variant:small-caps;letter-spacing:1px}
#chat-log{height:180px;overflow-y:auto;font-size:13.5px;padding:6px 2px}
#chat-log .msg{margin:3px 0}
#chat-log .who{font-weight:bold}
#chat-log .sys{font-style:italic;color:var(--ink2)}
#chat-form{display:flex;gap:6px}
#chat-form input{flex:1;padding:7px;border:1px solid var(--ink2);border-radius:6px}

/* ---------- overlays & modals ---------- */
.overlay{position:fixed;inset:0;background:rgba(8,10,18,.72);display:flex;align-items:center;justify-content:center;z-index:50;padding:14px}
.modal-card{background:var(--parch);border:2px solid var(--gold);border-radius:12px;padding:20px;max-width:520px;width:100%;max-height:88vh;overflow-y:auto;box-shadow:0 16px 44px rgba(0,0,0,.55)}
.modal-card.wide{max-width:860px}
.modal-card h3{margin-top:0}
/* cmh-v123: inspect is the FULL-SCREEN view again (Jace's ruling,
   Nov 7, 2026 — tapping a card should pull the card up, not open a
   side panel; the cmh-v120 right-side floating panel is retired).
   The base .overlay dim (.72) covers the table, the big card sits
   centered, the attachment panel (inspect-extra) and any actions
   stack beneath it, and the entry is a centered pop. One
   presentation for every caller — hand, field, captain, collection,
   builder — exactly as it was before v120. */
/* cmh-v124: the inspect sits ABOVE the toast (z-80) — a toast must
   never paint over an open preview. Only the online-wait veil (75)
   stays below it; nothing else lives above 85. */
#inspect{z-index:85;flex-direction:column;gap:10px;overflow-y:auto;align-items:center;justify-content:safe center}
#inspect .inspect-card .mini-card{box-shadow:0 18px 48px rgba(0,0,0,.6)}
#inspect .inspect-extra{box-shadow:0 14px 38px rgba(0,0,0,.55)}
#inspect #inspect-close{background:rgba(13,20,32,.85);color:var(--parch);border-color:rgba(246,241,231,.4);box-shadow:0 8px 22px rgba(0,0,0,.45)}
@keyframes inspectIn{from{opacity:0;transform:scale(.93) translateY(10px)}to{opacity:1;transform:none}}
#inspect:not(.hidden) .inspect-card{animation:inspectIn .27s cubic-bezier(.2,.9,.3,1.05) backwards}
#inspect:not(.hidden) .inspect-actions{animation:inspectIn .27s .05s cubic-bezier(.2,.9,.3,1.05) backwards}
#inspect:not(.hidden) .inspect-extra:not(.hidden){animation:inspectIn .27s .05s cubic-bezier(.2,.9,.3,1.05) backwards}
#inspect:not(.hidden) #inspect-close{animation:inspectIn .27s .1s cubic-bezier(.2,.9,.3,1.05) backwards}
/* cmh-v81: actions under the inspect preview (the deck-view gild
   option). Empty on every other surface, so nothing else moves. */
.inspect-actions{display:flex;flex-direction:column;align-items:center;gap:6px}
.inspect-actions:empty{display:none}
.inspect-actions .gilded-label{color:var(--gold2);font-size:17px}
.inspect-actions .fine{color:var(--parch)}
#modal-body{display:flex;flex-wrap:wrap;gap:9px;margin:12px 0}
/* cmh-v119: unit-picker captions — the candidate's own name as real
   text under its face (its face's baked-in name is unreadable at
   table size), with its effective Power beneath. */
.pick-wrap{display:flex;flex-direction:column;align-items:center;gap:3px;cursor:pointer}
.pick-caption{max-width:118px;text-align:center;line-height:1.2}
.pick-name{display:block;font-weight:700;font-size:12px;color:var(--ink)}
.pick-pow{display:block;font-size:11px;color:var(--ink2)}
.pick-printed{opacity:.75}
/* cmh-v119: the whole-unit inspect panel — per-attachment attributed
   contributions under the inspected card. Empty/hidden for every
   unattached card, so a plain inspect is unchanged. */
.inspect-extra{width:min(340px,92vw);background:linear-gradient(180deg,#fdfaf2,#f3ead2);border:2px solid var(--ink2);border-radius:10px;padding:9px 11px;font-size:13px;color:var(--ink);display:flex;flex-direction:column;gap:7px}
.inspect-extra.hidden{display:none}
.inspect-extra .ix-eff{font-size:14px}
.inspect-extra .ix-dim{opacity:.7;font-weight:400}
.inspect-extra .ix-att{border-top:1px solid rgba(60,45,25,.25);padding-top:6px}
.inspect-extra .ix-att:first-child{border-top:none;padding-top:0}
.inspect-extra .ix-att-head{font-weight:600}
.inspect-extra .ix-mod{background:var(--teal);color:#fff;border-radius:4px;font-size:11px;padding:1px 5px;font-weight:700;white-space:nowrap}
.inspect-extra .ix-text{margin-top:2px;line-height:1.35}
.inspect-card .pow-badge{width:42px;height:42px;font-size:20px}
#modal-body.big-cards{flex-wrap:nowrap;overflow-x:auto;padding-bottom:6px}
#modal-body.big-cards .mini-card{width:112px;min-height:157px;flex:0 0 auto}
#modal-body.big-cards .mini-card.face-card{width:112px;height:157px;min-height:157px}
#modal-actions{display:flex;gap:9px;flex-wrap:wrap;margin-top:10px}
/* cmh-v76: the mark wheel is #modal-body's only child in the Call the
   Shot dialog and #modal-body packs flex items to the left, so the
   icons hugged the dialog's left edge — center the wheel (Jace, Nov 5). */
.mark-wheel{display:flex;gap:10px;margin-inline:auto;flex-wrap:nowrap;justify-content:center}
.mark-ic{width:1.2em;height:1.2em;border-radius:50%;vertical-align:-.22em}
.mark-btn{display:flex;flex-direction:column;align-items:center;gap:2px;flex:1 1 0;min-width:0;max-width:118px;padding:10px 8px 8px;border-radius:14px;border:2.5px solid var(--ink2);background:#fff;cursor:pointer;color:var(--ink)}
.mark-btn-img{width:100%;max-width:56px;height:auto;aspect-ratio:1;border-radius:50%}
.mark-btn-name{font-weight:700;font-size:15px}
.mark-btn-count{font-size:11px;color:#6b6353;font-weight:600}
.mark-btn.sel{border-color:var(--gold);background:var(--gold2);box-shadow:0 0 14px rgba(232,200,119,.9)}
.inspect-card{transform:none;display:flex;justify-content:center;max-width:94vw}
.inspect-card .mini-card{width:210px;min-height:294px}
.inspect-card .mini-card.face-card{width:auto;height:min(86dvh,540px);aspect-ratio:5/7;min-height:0}
.overlay-close{position:absolute;top:16px;right:16px;color:var(--parch);border-color:rgba(246,241,231,.5)}

/* ---------- flip theatre ---------- */
#flip-theatre{background:rgba(8,10,18,.88);z-index:60}
.flip-stage{perspective:1100px;text-align:center}
.flip-inner{width:230px;height:320px;margin:0 auto;position:relative;transform-style:preserve-3d}
.flip-inner.spin{animation:flipspin 1.9s cubic-bezier(.2,.7,.3,1) forwards}
/* 5.5 turns: lands FRONT-up (the front face is pre-rotated 180deg; the old 1800 landed back-up — Jace's catch, Nov 4, 2026) */
@keyframes flipspin{from{transform:rotateY(0)}to{transform:rotateY(1980deg)}}
.flip-face{position:absolute;inset:0;backface-visibility:hidden;border-radius:12px;display:flex;align-items:center;justify-content:center}
.flip-back{background:#0b101f;border:3px solid var(--gold);padding:0;overflow:hidden}
.flip-back-img{width:100%;height:100%;object-fit:cover;display:block}
.flip-front{transform:rotateY(180deg)}
.flip-front .mini-card{width:230px;min-height:320px;font-size:14px}
.flip-front .mini-card .art{height:130px}
.flip-front .mini-card .ctext{font-size:12.5px;-webkit-line-clamp:8}
.flip-verdict{margin-top:18px;font-size:30px;font-variant:small-caps;letter-spacing:3px;color:var(--gold2);min-height:40px;text-shadow:0 2px 8px #000}
.flip-caption{margin-bottom:16px;font-size:16.5px;color:var(--parch);text-align:center;max-width:520px;text-shadow:0 2px 8px #000;line-height:1.45}
.flip-verdict.miss{color:#b9ac8d}

/* ---------- builder / shop / cosmetics ---------- */
.builder-wrap{display:grid;grid-template-columns:1fr 380px;gap:14px;max-width:1180px;margin:0 auto}
.builder-left,.builder-right{margin:0}
.deck-stats{font-size:13.5px;background:#fff;border:1px solid #cbbf9f;border-radius:8px;padding:9px;margin:8px 0;line-height:1.5}
.deck-list{font-size:13.5px;max-height:220px;overflow-y:auto}
.deck-list .row{display:flex;justify-content:space-between;padding:2.5px 0;border-bottom:1px dotted #cbbf9f}
.deck-list .deck-card-name{-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;cursor:default}
.deck-list .deck-card-name .mark-ic{width:1.15em;height:1.15em}
.suggestions{font-size:13.5px}
.sugg{background:#fff;border:1px solid #cbbf9f;border-left:4px solid var(--gold);border-radius:6px;padding:7px 9px;margin:6px 0}
.sugg .why{color:var(--ink2);font-style:italic}
.filterbar{display:flex;gap:6px;flex-wrap:wrap}
.filterbar .btn.sel{background:var(--gold2);border-color:#7a5f10;font-weight:bold}
.shop-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:12px;margin-top:12px}
.shop-item{background:#fff;border:1.5px solid var(--ink2);border-radius:10px;padding:14px;text-align:center}
.shop-item .ico{font-size:34px}
.cosmetic-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:12px;margin:10px 0 18px}
.cosmetic-item{border:1.5px solid var(--ink2);border-radius:10px;overflow:hidden;background:#fff;text-align:center}
.cosmetic-item img{width:100%;height:96px;object-fit:cover;display:block}
.cosmetic-item .meta{padding:8px;font-size:13.5px}
.cosmetic-item.equipped{border-color:var(--gold);box-shadow:0 0 0 2px var(--gold)}
.pack-results{display:flex;flex-wrap:wrap;gap:9px;margin-top:14px}
.starter-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px;margin-top:12px}
.starter-item{background:#fff;border:1.5px solid var(--ink2);border-radius:10px;padding:12px;text-align:center}
.starter-item img{width:100%;height:110px;object-fit:cover;border-radius:6px}
.friend-row,.invite-row{display:flex;align-items:center;gap:10px;background:#fff;border:1px solid #cbbf9f;border-radius:8px;padding:8px 11px;margin:6px 0;font-size:14.5px}
.presence{width:10px;height:10px;border-radius:50%;background:#bbb;flex:0 0 auto}
.presence.on{background:#2c9e4f;box-shadow:0 0 6px #2c9e4f}
.friend-add{display:flex;gap:8px;margin:10px 0}
.friend-add input{flex:1;padding:9px;border:1px solid var(--ink2);border-radius:6px;font-size:15px}
.result-card{text-align:center}
#toast{position:fixed;left:50%;bottom:22px;transform:translateX(-50%) translateY(80px);background:var(--ink);color:var(--gold2);padding:10px 20px;border-radius:20px;font-size:14.5px;z-index:80;transition:transform .3s;max-width:92vw;text-align:center}
#toast.show{transform:translateX(-50%) translateY(0)}

/* ---------- phone ---------- */
@media (max-width:760px){
  :root{--cardw:88px;--cardh:126px}
  .mini-card .art{height:44px}
  .mini-card .ctext{-webkit-line-clamp:4;font-size:9px}
  .builder-wrap{grid-template-columns:1fr}
  .resolution-rail{display:none}
  .action-dock{min-width:140px}
  .btn.big{padding:10px 14px;font-size:15px}
  .game-title{font-size:32px}
  .phase-ladder .ph{padding:2px 7px;font-size:11px}
}

.coach{position:fixed;left:50%;transform:translateX(-50%);bottom:86px;z-index:60;
 background:var(--parch,#f3e9d2);color:#2a2320;border:2px solid #8a6d3b;border-radius:12px;
 padding:12px 16px;max-width:520px;width:calc(100% - 32px);box-shadow:0 8px 30px rgba(0,0,0,.45)}
.coach.hidden{display:none}
.coach-head{display:flex;justify-content:space-between;align-items:center;font-weight:700;margin-bottom:4px}
.coach p{margin:4px 0 10px;line-height:1.45}
.tutorial-badge{position:fixed;top:8px;left:50%;transform:translateX(-50%);z-index:55;
 background:#20405c;color:#eaf2f8;padding:4px 12px;border-radius:999px;font-size:13px}
.tutorial-badge.hidden{display:none}
.bot-setup{display:flex;gap:16px;justify-content:center;flex-wrap:wrap;margin:10px 0}
.bot-setup label{display:flex;flex-direction:column;gap:4px;font-size:13px;text-align:left}
/* Home dropdowns, dressed (Nov 5, 2026): custom chevron and parchment
   finish instead of the native OS select chrome. */
.bot-setup select{appearance:none;-webkit-appearance:none;background-color:rgba(255,253,247,.94);background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%23926f22' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 10px center;border:1.5px solid rgba(146,118,54,.55);border-radius:9px;padding:7px 30px 7px 11px;font:inherit;font-size:13.5px;color:var(--ink);box-shadow:inset 0 1px 3px rgba(31,24,8,.10),0 1px 2px rgba(31,24,8,.08);cursor:pointer}
.bot-setup select:hover{border-color:var(--gold)}
.bot-setup select:focus{outline:2px solid var(--gold);outline-offset:1px}
/* Home action buttons as generated art banners (Nov 5, 2026): real
   button elements (the pack badge and handlers are untouched) with the
   art as the face, a left-weighted shade for the label, and the label
   set in the game's own type over it. */
.art-btn{position:relative;overflow:hidden;border:1.5px solid rgba(232,200,119,.75);border-radius:12px;color:#fdf6e0;font-weight:700;letter-spacing:.02em;text-shadow:0 1px 3px rgba(0,0,0,.9),0 0 14px rgba(0,0,0,.55);background-color:#0d1420;background-size:cover;background-position:center right;min-height:64px;display:inline-flex;align-items:center;justify-content:flex-start;padding:10px 18px;text-align:left;transition:filter .15s ease,border-color .15s ease}
.art-btn::before{content:"";position:absolute;inset:0;background:linear-gradient(90deg,rgba(6,10,18,.74) 0%,rgba(6,10,18,.46) 46%,rgba(6,10,18,.04) 78%);pointer-events:none}
.art-btn .art-label{position:relative;z-index:1}
.art-btn .badge{position:relative;z-index:1;margin-left:8px}
.art-btn:hover{border-color:var(--gold);filter:brightness(1.08)}
.art-btn:active{transform:translateY(1px)}
.art-play{background-image:url("assets/banners/btn-play.webp")}
.art-packs{background-image:url("assets/banners/btn-packs.webp")}
.art-tutorial{background-image:url("assets/banners/btn-tutorial.webp")}
.home-actions .art-btn{flex:1 1 215px;max-width:305px}
/* Deck chooser (Nov 5, 2026): art tiles in sideways-scrolling rows,
   favourites first. */
.deck-chooser{width:100%}
.deck-sec-label{font-size:12px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:var(--ink2);margin:10px 0 6px}
.deck-sec-label:first-child{margin-top:0}
.deck-row{display:flex;gap:10px;overflow-x:auto;padding:2px 2px 8px;scroll-snap-type:x proximity}
.deck-tile{position:relative;flex:0 0 auto;width:148px;background:linear-gradient(180deg,#fffdf7,#f3ead6);border:1.5px solid rgba(146,118,54,.55);border-radius:12px;overflow:hidden;cursor:pointer;scroll-snap-align:start;box-shadow:0 2px 6px rgba(31,24,8,.16);transition:transform .13s ease,border-color .13s ease,box-shadow .13s ease}
.deck-tile:hover{transform:translateY(-2px);border-color:var(--gold);box-shadow:0 7px 16px rgba(31,24,8,.24)}
.deck-tile img{width:100%;height:92px;object-fit:cover;display:block;background:#20180c}
.deck-tile .dt-name{display:block;font-weight:700;font-size:14px;line-height:1.2;padding:7px 9px 0;color:var(--ink)}
.deck-tile .dt-sub{display:block;font-size:11.5px;color:var(--ink2);padding:2px 9px 9px}
.deck-tile.last-sailed{border-color:var(--gold);box-shadow:0 0 0 1.5px var(--gold),0 3px 8px rgba(31,24,8,.2)}
.deck-tile .dt-last{position:absolute;top:6px;left:6px;background:rgba(13,20,32,.82);color:var(--gold2);font-size:10px;font-weight:700;letter-spacing:.05em;padding:2px 7px;border-radius:8px}
.deck-tile .dt-star{position:absolute;top:5px;right:5px;width:30px;height:30px;display:flex;align-items:center;justify-content:center;font-size:17px;color:#fff;background:rgba(10,14,22,.55);border:1px solid rgba(232,200,119,.5);border-radius:50%;cursor:pointer;text-shadow:0 1px 2px rgba(0,0,0,.6)}
.deck-tile .dt-star.on{color:var(--gold2);background:rgba(10,14,22,.78)}
.deck-tile .dt-star:hover{border-color:var(--gold)}
/* Bot setup as a modal (Nov 5, 2026): the .bot-setup select styling
   above applies; here it just stacks full-width. */
.bot-setup-modal{flex-direction:column;align-items:stretch;gap:12px;width:100%}
.bot-setup-modal select{width:100%;margin-top:4px}

/* ---------- real card faces (Jace's ruling, Nov 4, 2026) ---------- */
.mini-card.face-card{height:var(--cardh);padding:0;border:none;background:none;overflow:hidden;box-shadow:0 2px 8px rgba(0,0,0,.35)}
.mini-card.face-card .face-img{width:100%;height:100%;object-fit:cover;display:block}
.mini-card.face-card.legal{box-shadow:0 0 0 2px var(--play),0 0 16px 4px rgba(47,230,115,.75)}
.mini-card.face-card.selected{box-shadow:0 0 0 3px var(--red),0 0 18px rgba(160,44,34,.5)}
.pow-badge{position:absolute;bottom:4px;right:4px;top:auto;background:var(--ink);color:var(--gold2);border:1.5px solid var(--gold);border-radius:50%;width:26px;height:26px;display:flex;align-items:center;justify-content:center;font-weight:bold;font-size:13.5px;z-index:3;box-shadow:0 1px 5px rgba(0,0,0,.5)}
.mini-card .crow .cost{margin-left:auto;background:#f3ead2;color:var(--ink);border:1.5px solid var(--ink2);border-radius:50%;width:21px;height:21px;display:inline-flex;align-items:center;justify-content:center;font-weight:bold;font-size:12.5px}
.mini-card .crow .pow{background:var(--ink);color:var(--gold2);border-radius:50%;width:21px;height:21px;display:inline-flex;align-items:center;justify-content:center;font-weight:bold;font-size:12.5px}

.flip-front .mini-card.face-card{width:230px;height:322px;min-height:322px}

/* ---------- landscape app frame (Jace's ruling, Nov 4, 2026) ---------- */
html,body{height:100%}
body{overflow:hidden}
#app{height:100dvh}
.screen{height:100dvh;min-height:0;overflow:hidden}
.panel{max-height:calc(100dvh - 30px);overflow-y:auto}
.google-wrap{display:flex;justify-content:center;min-height:44px;margin:6px 0 2px}
#board-banner{flex:0 0 auto;max-width:1180px;width:100%;margin:0 auto;padding:4px 12px;border-radius:8px;font-variant:small-caps;letter-spacing:1.2px;font-size:14.5px;text-align:center;transition:background .3s,color .3s}
#board-banner.mine{background:rgba(47,158,95,.22);color:#a9e6c3;border:1px solid rgba(87,199,133,.45)}
#board-banner.opp{background:rgba(160,44,34,.25);color:#f0b8ae;border:1px solid rgba(217,138,126,.5)}
@keyframes boardIn{from{opacity:.25;transform:translateY(7px)}to{opacity:1;transform:none}}
.board-in{animation:boardIn .38s ease}

/* ---------- battle targeting bar ---------- */
#target-bar{position:relative;z-index:30;flex:0 0 auto;display:flex;flex-direction:column;gap:5px;background:rgba(13,20,32,.88);border:1.5px solid var(--gold);border-radius:10px;padding:7px 10px;margin:2px auto;width:100%;max-width:1180px}
#target-bar.hidden{display:none}
.tb-row{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.tb-who{color:var(--parch);font-variant:small-caps;letter-spacing:.6px;font-size:15px}
/* cmh-v123: during the Energy step the bar wears the step's colours
   and its line reads gold — the step's law (a card set here becomes
   Energy; it is not played) is the loudest text on the table. */
#target-bar.energy-step{background:linear-gradient(180deg,rgba(46,35,12,.95),rgba(13,20,32,.93));box-shadow:0 0 18px rgba(232,200,119,.35)}
#target-bar.energy-step .tb-who{color:var(--gold2)}
.tb-chip{color:var(--parch);border-color:rgba(246,241,231,.35)}
.tb-hearts{background:#a02c22;color:#fff;border:1.5px solid #d98a7e;font-size:16.5px;font-weight:bold;padding:8px 16px;border-radius:9px;cursor:pointer}
.tb-hearts:hover{background:#bb3628}
.tb-note{color:#b9ac8d;font-size:13px}
.tb-marks{display:inline-flex;align-items:center;gap:5px;margin-left:10px}
.tb-mark{background:rgba(246,241,231,.12);color:var(--parch);border:1px solid rgba(232,200,119,.4);border-radius:14px;padding:3px 10px;cursor:pointer;font-size:13px}
.tb-mark.armed{background:var(--gold);color:var(--ink);font-weight:bold;border-color:var(--gold2)}

/* ---------- the fanned hand + peek (cmh-v120, Jace, Nov 6, 2026) ----------
   The tray is gone. Hand cards rest overlapped in a gentle arc —
   rotation (--rf) and droop (--ty) are per-card vars set at render,
   the overlap (--ov) is the strip's own var, compressed as the hand
   grows. Reading a card is the .hand-peek: a full-size floating
   clone on a gold ring, pointer-transparent, that springs up over
   the strip's edge. Only the peek ever leaves the strip, so the
   board is never covered. */
.hand .mini-card{transform:rotate(var(--rf,0deg)) translateY(var(--ty,0px));transform-origin:50% 140%;transition:transform .19s cubic-bezier(.3,1.35,.4,1),box-shadow .15s,margin .18s ease}
.hand .mini-card + .mini-card{margin-left:calc(var(--cardw) * var(--ov,-0.34))}
.hand .mini-card.lifted{transform:rotate(0deg) translateY(-13px) scale(1.045);z-index:40 !important;box-shadow:0 12px 26px rgba(0,0,0,.5)}
.hand-peek{position:fixed;z-index:44;pointer-events:none;margin:0;border-radius:10px;box-shadow:0 0 0 2.5px var(--gold),0 0 22px rgba(232,200,119,.45),0 20px 46px rgba(0,0,0,.6)}
.hand-peek .attached-tag,.hand-peek .pow-badge{pointer-events:none}
/* The opening deal: cards flip/slide in from the deck side, staggered
   by the inline animation-delay renderMatch stamps. `to` resolves the
   card's own fan vars, so a dealt card lands exactly at rest. */
@keyframes dealIn{from{transform:translate(46px,30px) rotate(11deg) scale(.72);opacity:0}to{transform:rotate(var(--rf,0deg)) translateY(var(--ty,0px));opacity:1}}
.hand .mini-card.deal-in{animation:dealIn .5s cubic-bezier(.22,.9,.3,1.05) backwards}
/* Gesture hand (cmh-v65): drag ghost, source dim, drop glow/target, refusal shake.
   cmh-v125: hand cards claim their OWN gestures (touch-action:none).
   Under pan-x the browser could arbitrate a real finger's press into
   a scroll claim — pointercancel, no pointerup, a tap that silently
   never happened (Jace's S26, Nov 7, 2026; the hold survived because
   its timer fires from pointerdown). The strip itself keeps pan-x
   for presses that land on its ground, and the gesture layer now
   scrolls the strip itself when a card press goes horizontal. */
#my-hand .mini-card{touch-action:none}
.mini-card.drag-src{opacity:.35}
.mini-card.drag-ghost{position:fixed;z-index:60;pointer-events:none;margin:0;box-shadow:0 14px 34px rgba(0,0,0,.55);transition:none}
.mat-stage.drop-glow{box-shadow:inset 0 0 0 3px var(--play),inset 0 0 70px rgba(47,230,115,.28)}
#my-field .mini-card.drop-target{outline:3px solid var(--play);outline-offset:2px;box-shadow:0 0 22px rgba(47,230,115,.65)}
@keyframes cmh-shake{0%,100%{transform:translateX(0)}25%{transform:translateX(-5px)}75%{transform:translateX(5px)}}
.mini-card.shake{animation:cmh-shake .3s ease}
/* cmh-v120 board animation dressing: the dying grey out as they sink;
   the Deep ticks when the slain land; damage numbers float off a unit;
   an Energy flip is a real two-sided card. */
.anim-ghost.ghost-dying{filter:grayscale(.85) brightness(.72)}
.pile.deep-tick{animation:deepTick .6s ease-out}
@keyframes deepTick{0%{box-shadow:0 0 0 0 rgba(232,200,119,0)}30%{box-shadow:0 0 0 2.5px var(--gold),0 0 18px rgba(232,200,119,.75)}100%{box-shadow:0 0 0 0 rgba(232,200,119,0)}}
.float-dmg{position:fixed;transform:translateX(-50%);font-weight:800;font-size:23px;color:#ff9d8a;text-shadow:0 1px 5px #000,0 0 14px rgba(160,44,34,.55);animation:floatup 1.2s ease-out forwards;pointer-events:none;z-index:65}
.energy-flip{box-shadow:none;overflow:visible;background:none;border:none}
.energy-flip .ef-inner{position:relative;width:100%;height:100%;transform-style:preserve-3d}
.energy-flip .ef-face{position:absolute;inset:0;backface-visibility:hidden;-webkit-backface-visibility:hidden;border-radius:8px;overflow:hidden}
.energy-flip .ef-face .mini-card{width:100%;height:100%;min-height:0}
.energy-flip .ef-face .mini-card.face-card{height:100%;min-height:0}
.energy-flip .ef-face .face-img{width:100%;height:100%;object-fit:cover;display:block}
.energy-flip .ef-back{transform:rotateY(180deg)}

/* Screens are a column: the top bar keeps its height, the panel takes
   whatever room is LEFT and scrolls inside it. (Before this, the panel
   was sized from the full screen height while sitting below the bar,
   so its bottom — menu tiles and all — fell off short phone screens
   with no way to reach it. Jace's S26 shot, Nov 4, 2026.) */
.screen.active:not(#screen-match){display:flex;flex-direction:column}
.screen .panel,.screen .home-hero{flex:1 1 auto;min-height:0;max-height:none;width:100%}
.screen .home-hero{overflow-y:auto}
.home-hero{margin:0 auto}
.topbar{flex:0 0 auto;flex-wrap:wrap}
.wchip{white-space:nowrap}
#table{display:flex;flex-direction:column;height:100dvh;min-height:0;gap:4px}
#table .board{width:100%;margin:0 auto;flex:0 1 auto;min-height:0}
.hand-zone{flex:0 0 auto}
#btn-view-toggle{color:var(--parch);border-color:rgba(246,241,231,.4)}
/* Your table fills the screen; the enemy board rides as a slim status strip until opened. */
#table.view-mine .opp-board .energy-row,#table.view-mine .opp-board .field-row,#table.view-mine .opp-board .berth-row{display:none}
#table.view-opp .my-board,#table.view-opp .midline{display:none}
#table.view-opp .hand{display:none}
#table.view-opp .hand-zone{justify-content:flex-end;height:auto;min-height:0}
/* Card rows scroll sideways with a finger swipe when they overflow —
   only the row scrolls, never the page (Jace, Nov 4, 2026). */
.field-row{overflow-x:auto;overflow-y:hidden;min-height:0;height:calc(var(--cardh) + 10px);touch-action:pan-x;scrollbar-width:none}
.berth-row{overflow-x:auto;overflow-y:hidden;touch-action:pan-x;scrollbar-width:none}
.energy-row{overflow-x:auto;overflow-y:hidden;touch-action:pan-x;scrollbar-width:none}
/* cmh-v125: field and berth CARDS claim their gestures too — their
   taps are plain clicks through onFieldClick, and a drifted tap on
   a pan-x card can be eaten by row-scroll arbitration exactly like
   the hand's. The ROWS keep pan-x and still scroll from their
   ground; a swipe starting on a card no longer scrolls the row. */
.field-row .mini-card,.berth-row .mini-card{touch-action:none}
.field-row .mini-card,.berth-row .mini-card{touch-action:none}
.field-row::-webkit-scrollbar,.berth-row::-webkit-scrollbar,.energy-row::-webkit-scrollbar,.hand::-webkit-scrollbar{display:none}
.hand{min-height:0;height:calc(var(--cardh) + 15px);padding:6px 12px 9px;overflow-x:auto;overflow-y:hidden;touch-action:pan-x;scrollbar-width:none;min-width:0}
.midline .resolution-rail{max-height:58px}
#rotate-prompt{display:none}
@media (orientation:portrait){
  #screen-match.active #rotate-prompt{display:flex;position:fixed;inset:0;z-index:65;background:rgba(8,12,20,.93);color:var(--parch);align-items:center;justify-content:center;text-align:center;font-size:19px;padding:24px}
}
@media (orientation:landscape) and (max-height:560px){
  /* Card size is a pure function of the VISIBLE height (dvh), so the whole
     table fits by construction on short phone screens (Jace, Nov 4, 2026). */
  :root{--cardw:clamp(44px,14.5dvh,104px);--cardh:calc(var(--cardw)*1.4);--berthw:calc(var(--cardw)*0.76);--berthh:calc(var(--cardh)*0.78)}
  #table{gap:2px}
  .midline{display:none}
  .board{padding:3px 8px}
  .portrait{width:30px;height:30px;font-size:15px}
  .player-strip{gap:8px}
  .energy-row{min-height:34px}
  .energy-card{width:24px;height:34px}
  .field-row{height:calc(var(--cardh) + 6px)}
  .hand{height:calc(var(--cardh) + 4px);padding:2px 12px 2px}
  .berth-row .mini-card{--cardw:var(--berthw);--cardh:var(--berthh);width:var(--berthw);min-height:var(--berthh)}
  .phase-ladder .ph{padding:2px 8px;font-size:11px}
  .turn-banner{font-size:12.5px}
  .hint{font-size:12px;min-height:24px}
  .btn.big{padding:8px 14px;font-size:14.5px}
  .home-hero{margin:4px auto;padding:12px 16px}
  .panel{margin:6px auto;padding:12px}
  .coach{bottom:10px}
}
.sortwrap{margin-left:auto;color:var(--dim);font-size:13px;display:inline-flex;align-items:center;gap:5px}
.sortsel{background:var(--panel2);color:var(--parch);border:1px solid var(--ink2);border-radius:7px;padding:4px 6px;font-size:13px}
/* Call the Shot must be unmissable in the target bar (Jace, Nov 4):
   while the turn's call is unspent and unarmed, the mark buttons glow
   in turns; once a shot is spent, the bar says so in plain words. */
@keyframes callpulse{0%,100%{box-shadow:0 0 0 0 rgba(240,201,106,0)}50%{box-shadow:0 0 10px 2px rgba(240,201,106,.75)}}
#target-bar.call-ready .tb-mark{animation:callpulse 1.5s ease-in-out infinite;border-color:var(--gold)}
#target-bar .tb-marks .tb-note{font-weight:700;color:var(--gold);letter-spacing:.02em}
.tb-spent{color:var(--dim);font-style:italic;font-size:.92em;padding:2px 2px}
.tb-spent.banked{color:#e8c268;font-style:normal;font-weight:600}
#target-bar .tb-mark.armed{animation:none}
/* Phone-landscape fit, second pass (Jace's S26 Ultra report, Nov 4):
   when the table column ran short, board content spilled out of its
   board and lay OVER the dock — his Finish Attacks taps were landing
   on the spill, not the button. Boards now clip their own spill, the
   inert hand row folds away during Battle, and short screens scale
   cards a step smaller so the whole table fits by construction. */
.board{overflow:hidden}
#table[data-phase="Battle"] .hand{display:none}
@media (orientation:landscape) and (max-height:560px){
  :root{--cardw:clamp(40px,12dvh,104px)}
  .player-strip{padding:1px 2px}
  .pname{font-size:13.5px}
  .hearts{font-size:13.5px}
  .hearts .hnum{font-size:16.5px}
  #board-banner{padding:2px 10px;font-size:13px}
}

/* Deck Builder entry flow + screen fit (Jace, Nov 4): the builder opens
   on a New/Edit choice; the editor's two columns scroll INSIDE the
   screen instead of the screen running off the bottom of the tablet. */
#screen-builder .builder-wrap{flex:1 1 auto;min-height:0;width:100%}
.builder-left{display:flex;flex-direction:column;min-height:0;min-width:0}
#builder-grid{flex:1 1 auto;min-height:0;overflow-y:auto}
.builder-right{overflow-y:auto;min-height:0}
.builder-crumb{flex:0 0 auto;max-width:1180px;width:100%;margin:0 auto 6px}
.builder-home,.builder-pick{flex:0 1 auto;width:100%}
/* Builder top spacing + Deck-menu button (cmh-v107, Jace's S26 report,
   Nov 6, 2026): the ← Deck menu button rides IN the builder topbar now,
   wearing the topbar's own ghost treatment — parchment on the dark
   bar, legible like ← Harbour — instead of alone in a crumb row on the
   dark ground, where its ink-coloured text all but vanished. And the
   builder panels lose their stacked vertical margins, so content
   starts right under the header instead of below a dead band (in the
   tall-viewport regime the band measured ~70px: topbar margin + crumb
   row + the panels' own 24px top margin). Scoped to #screen-builder;
   the dead .builder-crumb rules above/below match nothing now and are
   left as fossils of the old row. */
#screen-builder .panel{margin-top:0;margin-bottom:0}
.builder-choice{display:flex;gap:12px;flex-wrap:wrap;margin:12px 0}
.pick-list{display:flex;flex-direction:column;gap:8px;margin-top:8px}
.pick-row{display:flex;flex-direction:column;align-items:flex-start;gap:2px;text-align:left;background:rgba(122,95,16,.10);border:1.5px solid var(--ink2);border-radius:9px;padding:10px 12px;cursor:pointer;color:var(--ink);font:inherit}
.pick-row:hover{background:rgba(122,95,16,.20)}
.pick-name{font-weight:bold;font-size:15.5px}
.pick-meta{font-size:13px;opacity:.75}
.sortsel{background:#22304d;color:#f6f1e7}
.sort-toggle{margin-left:6px}
/* Card search + filters (cmh-v86): one slim input + one Filters button
   in the list header; the grouped chip sheet drops from the bar (a
   sheet on phone widths). Minimal by Jace's design law. */
#collection-filters,#builder-filters,.card-search-bar{position:relative}
.card-search{display:inline-flex;align-items:center;gap:6px;margin-left:6px}
.card-search-input{background:#10161d;color:var(--parch);border:1px solid rgba(232,200,119,.4);border-radius:999px;padding:4px 11px;font-size:13px;width:150px}
.card-search-input::placeholder{color:var(--dim)}
.filter-badge{background:var(--gold);color:#231a08;border-radius:999px;padding:0 6px;font-size:11px;font-weight:700;margin-left:2px}
.card-count{margin-left:2px;white-space:nowrap}
.card-filter-panel{position:absolute;top:calc(100% + 6px);left:0;z-index:40;width:min(600px,94vw);background:rgba(13,18,28,.97);border:1px solid rgba(232,201,132,.55);border-radius:12px;padding:10px 12px;box-shadow:0 14px 40px rgba(0,0,0,.55);display:flex;flex-direction:column;gap:7px}
.card-filter-panel.hidden{display:none}
.cfp-row{display:flex;align-items:center;flex-wrap:wrap;gap:5px}
.cfp-label{min-width:58px;font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--gold);opacity:.85}
.cfp-costval{font-size:12.5px;color:var(--parch);min-width:44px;text-align:center}
.cfp-clear{align-self:flex-end}
.card-search-bar{margin:8px 0}
@media (max-width:760px){
  .card-filter-panel{position:fixed;left:8px;right:8px;top:56px;width:auto;max-height:72dvh;overflow-y:auto}
  .card-search-input{width:118px}
}
@media (max-width:760px){
  #screen-builder .builder-wrap{overflow-y:auto;display:flex;flex-direction:column}
  .builder-left,.builder-right{overflow:visible;flex:none}
  #builder-grid{overflow:visible;flex:none}
}
.sugg .copies{display:inline-block;font-size:12px;font-weight:bold;color:#7a5f10;background:rgba(122,95,16,.14);border-radius:6px;padding:1px 6px}
.optimizer .opt-cmds{display:flex;gap:6px;flex-wrap:wrap;margin:6px 0}
.optimizer .opt-focus{display:flex;gap:6px;flex-wrap:wrap;margin:6px 0}
.optimizer .opt-focus .fine{flex-basis:100%;margin:2px 0}
.opt-plan{margin-top:8px;border-top:1px dashed var(--ink2);padding-top:6px}
.plan-line{font-size:13.5px;margin:4px 0}
.plan-line.cut b{color:#8c2f1b}
.plan-line.add b{color:#2e5d1e}
.opt-apply{display:flex;gap:8px;margin-top:8px}
.coll-views{display:flex;gap:8px;margin-bottom:10px}
.deck-panel{border:1.5px solid var(--ink2);border-radius:10px;padding:10px 12px;margin-bottom:12px;background:rgba(122,95,16,.06)}
.deck-panel-head{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.deck-panel-head .btn{margin-left:auto}
.deck-panel-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(215px,1fr));gap:4px;margin-top:8px}
.deck-card-row{display:flex;justify-content:space-between;gap:8px;background:none;border:1px solid rgba(58,44,20,.25);border-radius:6px;padding:4px 8px;cursor:pointer;color:var(--ink);font:inherit;font-size:13px;text-align:left}
.deck-card-row:hover{background:rgba(122,95,16,.12)}
.friend-deck-line{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-bottom:10px;font-size:14.5px}
/* Selected state must read EVERYWHERE, not only inside filter bars —
   the optimizer's commands, its synergy chips and the Collection view
   toggle all use .btn.sel (Jace, Nov 4: the optimizer button did not
   light up). */
.btn.sel{background:var(--gold2);border-color:#7a5f10;font-weight:bold}

/* ---- midnight harbour (Jace, Nov 4): the home screen's whole
   background is a night scene — a midnight sky of twinkling stars
   with shooting stars now and then, over water whose gentle waves
   ebb and flow. Transform/opacity only. */
body[data-theme] #screen-home,#screen-home{position:relative;background:radial-gradient(90% 42% at 50% 54%, rgba(140,190,240,.16), transparent 60%),linear-gradient(180deg,#01040c 0%,#04101f 22%,#071a30 40%,#0a2440 52%,#0d3560 54%,#0b3a5e 68%,#082c49 84%,#061f36 100%)!important}
.scene{position:absolute;inset:0;overflow:hidden;pointer-events:none;z-index:0}
#screen-home>*:not(.scene){position:relative;z-index:1}
.stars{position:absolute;left:0;top:0;width:2px;height:2px;border-radius:50%;background:transparent;box-shadow:519px 153px 0 0 #dfeeff, 1934px 168px 0 0 #dfeeff, 213px 135px 0 0 #dfeeff, 1691px 478px 0 0 #dfeeff, 651px 36px 0 0 #dfeeff, 788px 132px 0 0 #dfeeff, 1202px 166px 0 0 #dfeeff, 906px 94px 0 0 #dfeeff, 1215px 108px 0 0 #dfeeff, 19px 166px 0 0 #dfeeff, 596px 54px 0 0 #dfeeff, 1138px 44px 0 0 #dfeeff, 1862px 187px 0 0 #dfeeff, 121px 141px 0 0 #dfeeff, 605px 227px 0 0 #dfeeff, 781px 368px 0 0 #dfeeff, 966px 47px 0 0 #dfeeff, 816px 138px 0 0 #dfeeff, 1185px 75px 0 0 #dfeeff, 99px 117px 0 0 #dfeeff, 1172px 418px 0 0 #dfeeff, 1160px 454px 0 0 #dfeeff, 675px 390px 0 0 #dfeeff, 1583px 11px 0 0 #dfeeff, 235px 127px 0 0 #dfeeff, 293px 8px 0 0 #dfeeff, 1436px 156px 0 0 #dfeeff, 460px 278px 0 0 #dfeeff, 159px 99px 0 0 #dfeeff, 357px 63px 0 0 #dfeeff, 47px 334px 0 0 #dfeeff, 1281px 222px 0 0 #dfeeff, 310px 174px 0 0 #dfeeff, 304px 461px 0 0 #dfeeff, 1062px 266px 0 0 #dfeeff, 527px 415px 0 0 #dfeeff, 1227px 25px 0 0 #dfeeff, 1672px 272px 0 0 #dfeeff, 1117px 212px 0 0 #dfeeff, 950px 417px 0 0 #dfeeff, 1058px 290px 0 0 #dfeeff, 1187px 406px 0 0 #dfeeff;animation:twinkleA 3.4s ease-in-out infinite alternate}
.stars::before,.stars::after{content:"";position:absolute;left:0;top:0;width:2px;height:2px;border-radius:50%;background:transparent}
.stars::before{box-shadow:1489px 279px 0 0 #dfeeff, 685px 412px 0 0 #dfeeff, 94px 6px 0 0 #dfeeff, 524px 87px 0 0 #dfeeff, 720px 359px 0 0 #dfeeff, 1720px 331px 0 0 #dfeeff, 179px 271px 0 0 #dfeeff, 1909px 116px 0 0 #dfeeff, 1405px 41px 0 0 #dfeeff, 1843px 419px 0 0 #dfeeff, 956px 87px 0 0 #dfeeff, 258px 293px 0 0 #dfeeff, 441px 61px 0 0 #dfeeff, 926px 408px 0 0 #dfeeff, 706px 476px 0 0 #dfeeff, 937px 399px 0 0 #dfeeff, 154px 52px 0 0 #dfeeff, 395px 101px 0 0 #dfeeff, 1852px 302px 0 0 #dfeeff, 1092px 344px 0 0 #dfeeff, 889px 71px 0 0 #dfeeff, 218px 206px 0 0 #dfeeff, 849px 256px 0 0 #dfeeff, 1249px 114px 0 0 #dfeeff, 352px 120px 0 0 #dfeeff, 1284px 424px 0 0 #dfeeff, 635px 467px 0 0 #dfeeff, 770px 329px 0 0 #dfeeff, 698px 418px 0 0 #dfeeff, 1256px 279px 0 0 #dfeeff, 889px 458px 0 0 #dfeeff, 717px 3px 0 0 #dfeeff, 1593px 144px 0 0 #dfeeff, 1836px 325px 0 0 #dfeeff;animation:twinkleB 5.1s ease-in-out infinite alternate}
.stars::after{width:3px;height:3px;box-shadow:561px 225px 0 0 #dfeeff, 521px 422px 0 0 #dfeeff, 1675px 441px 0 0 #dfeeff, 1682px 418px 0 0 #dfeeff, 1298px 414px 0 0 #dfeeff, 885px 358px 0 0 #dfeeff, 436px 227px 0 0 #dfeeff, 1241px 32px 0 0 #dfeeff, 266px 300px 0 0 #dfeeff, 1753px 302px 0 0 #dfeeff, 1758px 88px 0 0 #dfeeff, 1781px 319px 0 0 #dfeeff, 1790px 0px 0 0 #dfeeff, 1695px 38px 0 0 #dfeeff, 103px 189px 0 0 #dfeeff, 1330px 1px 0 0 #dfeeff, 1622px 288px 0 0 #dfeeff, 255px 461px 0 0 #dfeeff, 907px 151px 0 0 #dfeeff, 425px 224px 0 0 #dfeeff, 1358px 233px 0 0 #dfeeff, 654px 52px 0 0 #dfeeff, 394px 231px 0 0 #dfeeff, 486px 127px 0 0 #dfeeff, 1441px 426px 0 0 #dfeeff, 1969px 309px 0 0 #dfeeff;animation:twinkleA 6.7s ease-in-out infinite alternate-reverse}
@keyframes twinkleA{from{opacity:.35}to{opacity:1}}
@keyframes twinkleB{from{opacity:1}to{opacity:.3}}
.meteor{position:absolute;width:110px;height:2px;border-radius:2px;background:linear-gradient(90deg, rgba(255,255,255,.95), rgba(255,255,255,0));opacity:0;transform:rotate(-24deg)}
.meteor.m1{left:64%;top:9%;animation:meteorFly 11s linear infinite}
.meteor.m2{left:22%;top:4%;animation:meteorFly 17s linear infinite;animation-delay:6s}
@keyframes meteorFly{0%{transform:rotate(-24deg) translateX(0);opacity:0}2%{opacity:1}9%{transform:rotate(-24deg) translateX(-46vw);opacity:0}100%{transform:rotate(-24deg) translateX(-46vw);opacity:0}}
.sea{position:absolute;left:0;bottom:0;width:100%;height:57%;overflow:hidden;background:#04101f url('assets/sea-poster.jpg') center 32%/cover no-repeat;-webkit-mask-image:linear-gradient(180deg,transparent 0,#000 24%);mask-image:linear-gradient(180deg,transparent 0,#000 24%)}
.sea-video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.screen.active:not(#screen-match){display:flex;flex-direction:column}
.screen .panel,.screen .home-hero{flex:1 1 auto;min-height:0;max-height:none;width:100%}
.screen .home-hero{overflow-y:auto}
.home-hero{margin:0 auto}
.topbar{flex:0 0 auto;flex-wrap:wrap}
.wchip{white-space:nowrap}
#table{display:flex;flex-direction:column;height:100dvh;min-height:0;gap:4px}
#table .board{width:100%;margin:0 auto;flex:0 1 auto;min-height:0}
.hand-zone{flex:0 0 auto}
#btn-view-toggle{color:var(--parch);border-color:rgba(246,241,231,.4)}
/* Your table fills the screen; the enemy board rides as a slim status strip until opened. */
#table.view-mine .opp-board .energy-row,#table.view-mine .opp-board .field-row,#table.view-mine .opp-board .berth-row{display:none}
#table.view-opp .my-board,#table.view-opp .midline{display:none}
#table.view-opp .hand{display:none}
#table.view-opp .hand-zone{justify-content:flex-end;height:auto;min-height:0}
/* Card rows scroll sideways with a finger swipe when they overflow —
   only the row scrolls, never the page (Jace, Nov 4, 2026). */
.field-row{overflow-x:auto;overflow-y:hidden;min-height:0;height:calc(var(--cardh) + 10px);touch-action:pan-x;scrollbar-width:none}
.berth-row{overflow-x:auto;overflow-y:hidden;touch-action:pan-x;scrollbar-width:none}
.energy-row{overflow-x:auto;overflow-y:hidden;touch-action:pan-x;scrollbar-width:none}
.field-row .mini-card,.berth-row .mini-card{touch-action:none}
.field-row::-webkit-scrollbar,.berth-row::-webkit-scrollbar,.energy-row::-webkit-scrollbar,.hand::-webkit-scrollbar{display:none}
.hand{min-height:0;height:calc(var(--cardh) + 15px);padding:6px 12px 9px;overflow-x:auto;overflow-y:hidden;touch-action:pan-x;scrollbar-width:none;min-width:0}
.midline .resolution-rail{max-height:58px}
#rotate-prompt{display:none}
@media (orientation:portrait){
  #screen-match.active #rotate-prompt{display:flex;position:fixed;inset:0;z-index:65;background:rgba(8,12,20,.93);color:var(--parch);align-items:center;justify-content:center;text-align:center;font-size:19px;padding:24px}
}
@media (orientation:landscape) and (max-height:560px){
  /* Card size is a pure function of the VISIBLE height (dvh), so the whole
     table fits by construction on short phone screens (Jace, Nov 4, 2026). */
  :root{--cardw:clamp(44px,14.5dvh,104px);--cardh:calc(var(--cardw)*1.4);--berthw:calc(var(--cardw)*0.76);--berthh:calc(var(--cardh)*0.78)}
  #table{gap:2px}
  .midline{display:none}
  /* cmh-v120: fan overlap governs hand margins at every size */
  .board{padding:3px 8px}
  .portrait{width:30px;height:30px;font-size:15px}
  .player-strip{gap:8px}
  .energy-row{min-height:34px}
  .energy-card{width:24px;height:34px}
  .field-row{height:calc(var(--cardh) + 6px)}
  .hand{height:calc(var(--cardh) + 4px);padding:2px 12px 2px}
  .berth-row .mini-card{--cardw:var(--berthw);--cardh:var(--berthh);width:var(--berthw);min-height:var(--berthh)}
  .phase-ladder .ph{padding:2px 8px;font-size:11px}
  .turn-banner{font-size:12.5px}
  .hint{font-size:12px;min-height:24px}
  .btn.big{padding:8px 14px;font-size:14.5px}
  .home-hero{margin:4px auto;padding:12px 16px}
  .panel{margin:6px auto;padding:12px}
  .coach{bottom:10px}
}
.sortwrap{margin-left:auto;color:var(--dim);font-size:13px;display:inline-flex;align-items:center;gap:5px}
.sortsel{background:var(--panel2);color:var(--parch);border:1px solid var(--ink2);border-radius:7px;padding:4px 6px;font-size:13px}
/* Call the Shot must be unmissable in the target bar (Jace, Nov 4):
   while the turn's call is unspent and unarmed, the mark buttons glow
   in turns; once a shot is spent, the bar says so in plain words. */
@keyframes callpulse{0%,100%{box-shadow:0 0 0 0 rgba(240,201,106,0)}50%{box-shadow:0 0 10px 2px rgba(240,201,106,.75)}}
#target-bar.call-ready .tb-mark{animation:callpulse 1.5s ease-in-out infinite;border-color:var(--gold)}
#target-bar .tb-marks .tb-note{font-weight:700;color:var(--gold);letter-spacing:.02em}
.tb-spent{color:var(--dim);font-style:italic;font-size:.92em;padding:2px 2px}
.tb-spent.banked{color:#e8c268;font-style:normal;font-weight:600}
#target-bar .tb-mark.armed{animation:none}
/* Phone-landscape fit, second pass (Jace's S26 Ultra report, Nov 4):
   when the table column ran short, board content spilled out of its
   board and lay OVER the dock — his Finish Attacks taps were landing
   on the spill, not the button. Boards now clip their own spill, the
   inert hand row folds away during Battle, and short screens scale
   cards a step smaller so the whole table fits by construction. */
.board{overflow:hidden}
#table[data-phase="Battle"] .hand{display:none}
@media (orientation:landscape) and (max-height:560px){
  :root{--cardw:clamp(40px,12dvh,104px)}
  .player-strip{padding:1px 2px}
  .pname{font-size:13.5px}
  .hearts{font-size:13.5px}
  .hearts .hnum{font-size:16.5px}
  #board-banner{padding:2px 10px;font-size:13px}
}

/* Deck Builder entry flow + screen fit (Jace, Nov 4): the builder opens
   on a New/Edit choice; the editor's two columns scroll INSIDE the
   screen instead of the screen running off the bottom of the tablet. */
#screen-builder .builder-wrap{flex:1 1 auto;min-height:0;width:100%}
.builder-left{display:flex;flex-direction:column;min-height:0;min-width:0}
#builder-grid{flex:1 1 auto;min-height:0;overflow-y:auto}
.builder-right{overflow-y:auto;min-height:0}
.builder-crumb{flex:0 0 auto;max-width:1180px;width:100%;margin:0 auto 6px}
.builder-home,.builder-pick{flex:0 1 auto;width:100%}
.builder-choice{display:flex;gap:12px;flex-wrap:wrap;margin:12px 0}
.pick-list{display:flex;flex-direction:column;gap:8px;margin-top:8px}
.pick-row{display:flex;flex-direction:column;align-items:flex-start;gap:2px;text-align:left;background:rgba(122,95,16,.10);border:1.5px solid var(--ink2);border-radius:9px;padding:10px 12px;cursor:pointer;color:var(--ink);font:inherit}
.pick-row:hover{background:rgba(122,95,16,.20)}
.pick-name{font-weight:bold;font-size:15.5px}
.pick-meta{font-size:13px;opacity:.75}
.sortsel{background:#22304d;color:#f6f1e7}
.sort-toggle{margin-left:6px}
@media (max-width:760px){
  #screen-builder .builder-wrap{overflow-y:auto;display:flex;flex-direction:column}
  .builder-left,.builder-right{overflow:visible;flex:none}
  #builder-grid{overflow:visible;flex:none}
}
.sugg .copies{display:inline-block;font-size:12px;font-weight:bold;color:#7a5f10;background:rgba(122,95,16,.14);border-radius:6px;padding:1px 6px}
.optimizer .opt-cmds{display:flex;gap:6px;flex-wrap:wrap;margin:6px 0}
.optimizer .opt-focus{display:flex;gap:6px;flex-wrap:wrap;margin:6px 0}
.optimizer .opt-focus .fine{flex-basis:100%;margin:2px 0}
.opt-plan{margin-top:8px;border-top:1px dashed var(--ink2);padding-top:6px}
.plan-line{font-size:13.5px;margin:4px 0}
.plan-line.cut b{color:#8c2f1b}
.plan-line.add b{color:#2e5d1e}
.opt-apply{display:flex;gap:8px;margin-top:8px}
.coll-views{display:flex;gap:8px;margin-bottom:10px}
.deck-panel{border:1.5px solid var(--ink2);border-radius:10px;padding:10px 12px;margin-bottom:12px;background:rgba(122,95,16,.06)}
.deck-panel-head{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.deck-panel-head .btn{margin-left:auto}
.deck-panel-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(215px,1fr));gap:4px;margin-top:8px}
.deck-card-row{display:flex;justify-content:space-between;gap:8px;background:none;border:1px solid rgba(58,44,20,.25);border-radius:6px;padding:4px 8px;cursor:pointer;color:var(--ink);font:inherit;font-size:13px;text-align:left}
.deck-card-row:hover{background:rgba(122,95,16,.12)}
.friend-deck-line{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-bottom:10px;font-size:14.5px}
/* Selected state must read EVERYWHERE, not only inside filter bars —
   the optimizer's commands, its synergy chips and the Collection view
   toggle all use .btn.sel (Jace, Nov 4: the optimizer button did not
   light up). */
.btn.sel{background:var(--gold2);border-color:#7a5f10;font-weight:bold}

/* ---- midnight harbour (Jace, Nov 4): the home screen's whole
   background is a night scene — a midnight sky of twinkling stars
   with shooting stars now and then, over water whose gentle waves
   ebb and flow. Transform/opacity only. */
body[data-theme] #screen-home,#screen-home{position:relative;background:radial-gradient(90% 42% at 50% 54%, rgba(140,190,240,.16), transparent 60%),linear-gradient(180deg,#01040c 0%,#04101f 22%,#071a30 40%,#0a2440 52%,#0d3560 54%,#0b3a5e 68%,#082c49 84%,#061f36 100%)!important}
.scene{position:absolute;inset:0;overflow:hidden;pointer-events:none;z-index:0}
#screen-home>*:not(.scene){position:relative;z-index:1}
.stars{position:absolute;left:0;top:0;width:2px;height:2px;border-radius:50%;background:transparent;box-shadow:519px 153px 0 0 #dfeeff, 1934px 168px 0 0 #dfeeff, 213px 135px 0 0 #dfeeff, 1691px 478px 0 0 #dfeeff, 651px 36px 0 0 #dfeeff, 788px 132px 0 0 #dfeeff, 1202px 166px 0 0 #dfeeff, 906px 94px 0 0 #dfeeff, 1215px 108px 0 0 #dfeeff, 19px 166px 0 0 #dfeeff, 596px 54px 0 0 #dfeeff, 1138px 44px 0 0 #dfeeff, 1862px 187px 0 0 #dfeeff, 121px 141px 0 0 #dfeeff, 605px 227px 0 0 #dfeeff, 781px 368px 0 0 #dfeeff, 966px 47px 0 0 #dfeeff, 816px 138px 0 0 #dfeeff, 1185px 75px 0 0 #dfeeff, 99px 117px 0 0 #dfeeff, 1172px 418px 0 0 #dfeeff, 1160px 454px 0 0 #dfeeff, 675px 390px 0 0 #dfeeff, 1583px 11px 0 0 #dfeeff, 235px 127px 0 0 #dfeeff, 293px 8px 0 0 #dfeeff, 1436px 156px 0 0 #dfeeff, 460px 278px 0 0 #dfeeff, 159px 99px 0 0 #dfeeff, 357px 63px 0 0 #dfeeff, 47px 334px 0 0 #dfeeff, 1281px 222px 0 0 #dfeeff, 310px 174px 0 0 #dfeeff, 304px 461px 0 0 #dfeeff, 1062px 266px 0 0 #dfeeff, 527px 415px 0 0 #dfeeff, 1227px 25px 0 0 #dfeeff, 1672px 272px 0 0 #dfeeff, 1117px 212px 0 0 #dfeeff, 950px 417px 0 0 #dfeeff, 1058px 290px 0 0 #dfeeff, 1187px 406px 0 0 #dfeeff;animation:twinkleA 3.4s ease-in-out infinite alternate}
.stars::before,.stars::after{content:"";position:absolute;left:0;top:0;width:2px;height:2px;border-radius:50%;background:transparent}
.stars::before{box-shadow:1489px 279px 0 0 #dfeeff, 685px 412px 0 0 #dfeeff, 94px 6px 0 0 #dfeeff, 524px 87px 0 0 #dfeeff, 720px 359px 0 0 #dfeeff, 1720px 331px 0 0 #dfeeff, 179px 271px 0 0 #dfeeff, 1909px 116px 0 0 #dfeeff, 1405px 41px 0 0 #dfeeff, 1843px 419px 0 0 #dfeeff, 956px 87px 0 0 #dfeeff, 258px 293px 0 0 #dfeeff, 441px 61px 0 0 #dfeeff, 926px 408px 0 0 #dfeeff, 706px 476px 0 0 #dfeeff, 937px 399px 0 0 #dfeeff, 154px 52px 0 0 #dfeeff, 395px 101px 0 0 #dfeeff, 1852px 302px 0 0 #dfeeff, 1092px 344px 0 0 #dfeeff, 889px 71px 0 0 #dfeeff, 218px 206px 0 0 #dfeeff, 849px 256px 0 0 #dfeeff, 1249px 114px 0 0 #dfeeff, 352px 120px 0 0 #dfeeff, 1284px 424px 0 0 #dfeeff, 635px 467px 0 0 #dfeeff, 770px 329px 0 0 #dfeeff, 698px 418px 0 0 #dfeeff, 1256px 279px 0 0 #dfeeff, 889px 458px 0 0 #dfeeff, 717px 3px 0 0 #dfeeff, 1593px 144px 0 0 #dfeeff, 1836px 325px 0 0 #dfeeff;animation:twinkleB 5.1s ease-in-out infinite alternate}
.stars::after{width:3px;height:3px;box-shadow:561px 225px 0 0 #dfeeff, 521px 422px 0 0 #dfeeff, 1675px 441px 0 0 #dfeeff, 1682px 418px 0 0 #dfeeff, 1298px 414px 0 0 #dfeeff, 885px 358px 0 0 #dfeeff, 436px 227px 0 0 #dfeeff, 1241px 32px 0 0 #dfeeff, 266px 300px 0 0 #dfeeff, 1753px 302px 0 0 #dfeeff, 1758px 88px 0 0 #dfeeff, 1781px 319px 0 0 #dfeeff, 1790px 0px 0 0 #dfeeff, 1695px 38px 0 0 #dfeeff, 103px 189px 0 0 #dfeeff, 1330px 1px 0 0 #dfeeff, 1622px 288px 0 0 #dfeeff, 255px 461px 0 0 #dfeeff, 907px 151px 0 0 #dfeeff, 425px 224px 0 0 #dfeeff, 1358px 233px 0 0 #dfeeff, 654px 52px 0 0 #dfeeff, 394px 231px 0 0 #dfeeff, 486px 127px 0 0 #dfeeff, 1441px 426px 0 0 #dfeeff, 1969px 309px 0 0 #dfeeff;animation:twinkleA 6.7s ease-in-out infinite alternate-reverse}
@keyframes twinkleA{from{opacity:.35}to{opacity:1}}
@keyframes twinkleB{from{opacity:1}to{opacity:.3}}
.meteor{position:absolute;width:110px;height:2px;border-radius:2px;background:linear-gradient(90deg, rgba(255,255,255,.95), rgba(255,255,255,0));opacity:0;transform:rotate(-24deg)}
.meteor.m1{left:64%;top:9%;animation:meteorFly 11s linear infinite}
.meteor.m2{left:22%;top:4%;animation:meteorFly 17s linear infinite;animation-delay:6s}
@keyframes meteorFly{0%{transform:rotate(-24deg) translateX(0);opacity:0}2%{opacity:1}9%{transform:rotate(-24deg) translateX(-46vw);opacity:0}100%{transform:rotate(-24deg) translateX(-46vw);opacity:0}}
.screen.active:not(#screen-match){display:flex;flex-direction:column}
.screen .panel,.screen .home-hero{flex:1 1 auto;min-height:0;max-height:none;width:100%}
.screen .home-hero{overflow-y:auto}
.home-hero{margin:0 auto}
.topbar{flex:0 0 auto;flex-wrap:wrap}
.wchip{white-space:nowrap}
#table{display:flex;flex-direction:column;height:100dvh;min-height:0;gap:4px}
#table .board{width:100%;margin:0 auto;flex:0 1 auto;min-height:0}
.hand-zone{flex:0 0 auto}
#btn-view-toggle{color:var(--parch);border-color:rgba(246,241,231,.4)}
/* Your table fills the screen; the enemy board rides as a slim status strip until opened. */
#table.view-mine .opp-board .energy-row,#table.view-mine .opp-board .field-row,#table.view-mine .opp-board .berth-row{display:none}
#table.view-opp .my-board,#table.view-opp .midline{display:none}
#table.view-opp .hand{display:none}
#table.view-opp .hand-zone{justify-content:flex-end;height:auto;min-height:0}
/* Card rows scroll sideways with a finger swipe when they overflow —
   only the row scrolls, never the page (Jace, Nov 4, 2026). */
.field-row{overflow-x:auto;overflow-y:hidden;min-height:0;height:calc(var(--cardh) + 10px);touch-action:pan-x;scrollbar-width:none}
.berth-row{overflow-x:auto;overflow-y:hidden;touch-action:pan-x;scrollbar-width:none}
.energy-row{overflow-x:auto;overflow-y:hidden;touch-action:pan-x;scrollbar-width:none}
.field-row .mini-card,.berth-row .mini-card{touch-action:none}
.field-row::-webkit-scrollbar,.berth-row::-webkit-scrollbar,.energy-row::-webkit-scrollbar,.hand::-webkit-scrollbar{display:none}
.hand{min-height:0;height:calc(var(--cardh) + 15px);padding:6px 12px 9px;overflow-x:auto;overflow-y:hidden;touch-action:pan-x;scrollbar-width:none;min-width:0}
.midline .resolution-rail{max-height:58px}
#rotate-prompt{display:none}
@media (orientation:portrait){
  #screen-match.active #rotate-prompt{display:flex;position:fixed;inset:0;z-index:65;background:rgba(8,12,20,.93);color:var(--parch);align-items:center;justify-content:center;text-align:center;font-size:19px;padding:24px}
}
@media (orientation:landscape) and (max-height:560px){
  /* Card size is a pure function of the VISIBLE height (dvh), so the whole
     table fits by construction on short phone screens (Jace, Nov 4, 2026). */
  :root{--cardw:clamp(44px,14.5dvh,104px);--cardh:calc(var(--cardw)*1.4);--berthw:calc(var(--cardw)*0.76);--berthh:calc(var(--cardh)*0.78)}
  #table{gap:2px}
  .midline{display:none}
  /* cmh-v120: fan overlap governs hand margins at every size */
  .board{padding:3px 8px}
  .portrait{width:30px;height:30px;font-size:15px}
  .player-strip{gap:8px}
  .energy-row{min-height:34px}
  .energy-card{width:24px;height:34px}
  .field-row{height:calc(var(--cardh) + 6px)}
  .hand{height:calc(var(--cardh) + 4px);padding:2px 12px 2px}
  .berth-row .mini-card{--cardw:var(--berthw);--cardh:var(--berthh);width:var(--berthw);min-height:var(--berthh)}
  .phase-ladder .ph{padding:2px 8px;font-size:11px}
  .turn-banner{font-size:12.5px}
  .hint{font-size:12px;min-height:24px}
  .btn.big{padding:8px 14px;font-size:14.5px}
  .home-hero{margin:4px auto;padding:12px 16px}
  .panel{margin:6px auto;padding:12px}
  .coach{bottom:10px}
}
.sortwrap{margin-left:auto;color:var(--dim);font-size:13px;display:inline-flex;align-items:center;gap:5px}
.sortsel{background:var(--panel2);color:var(--parch);border:1px solid var(--ink2);border-radius:7px;padding:4px 6px;font-size:13px}
/* Call the Shot must be unmissable in the target bar (Jace, Nov 4):
   while the turn's call is unspent and unarmed, the mark buttons glow
   in turns; once a shot is spent, the bar says so in plain words. */
@keyframes callpulse{0%,100%{box-shadow:0 0 0 0 rgba(240,201,106,0)}50%{box-shadow:0 0 10px 2px rgba(240,201,106,.75)}}
#target-bar.call-ready .tb-mark{animation:callpulse 1.5s ease-in-out infinite;border-color:var(--gold)}
#target-bar .tb-marks .tb-note{font-weight:700;color:var(--gold);letter-spacing:.02em}
.tb-spent{color:var(--dim);font-style:italic;font-size:.92em;padding:2px 2px}
.tb-spent.banked{color:#e8c268;font-style:normal;font-weight:600}
#target-bar .tb-mark.armed{animation:none}
/* Phone-landscape fit, second pass (Jace's S26 Ultra report, Nov 4):
   when the table column ran short, board content spilled out of its
   board and lay OVER the dock — his Finish Attacks taps were landing
   on the spill, not the button. Boards now clip their own spill, the
   inert hand row folds away during Battle, and short screens scale
   cards a step smaller so the whole table fits by construction. */
.board{overflow:hidden}
#table[data-phase="Battle"] .hand{display:none}
@media (orientation:landscape) and (max-height:560px){
  :root{--cardw:clamp(40px,12dvh,104px)}
  .player-strip{padding:1px 2px}
  .pname{font-size:13.5px}
  .hearts{font-size:13.5px}
  .hearts .hnum{font-size:16.5px}
  #board-banner{padding:2px 10px;font-size:13px}
}

/* Deck Builder entry flow + screen fit (Jace, Nov 4): the builder opens
   on a New/Edit choice; the editor's two columns scroll INSIDE the
   screen instead of the screen running off the bottom of the tablet. */
#screen-builder .builder-wrap{flex:1 1 auto;min-height:0;width:100%}
.builder-left{display:flex;flex-direction:column;min-height:0;min-width:0}
#builder-grid{flex:1 1 auto;min-height:0;overflow-y:auto}
.builder-right{overflow-y:auto;min-height:0}
.builder-crumb{flex:0 0 auto;max-width:1180px;width:100%;margin:0 auto 6px}
.builder-home,.builder-pick{flex:0 1 auto;width:100%}
.builder-choice{display:flex;gap:12px;flex-wrap:wrap;margin:12px 0}
.pick-list{display:flex;flex-direction:column;gap:8px;margin-top:8px}
.pick-row{display:flex;flex-direction:column;align-items:flex-start;gap:2px;text-align:left;background:rgba(122,95,16,.10);border:1.5px solid var(--ink2);border-radius:9px;padding:10px 12px;cursor:pointer;color:var(--ink);font:inherit}
.pick-row:hover{background:rgba(122,95,16,.20)}
.pick-name{font-weight:bold;font-size:15.5px}
.pick-meta{font-size:13px;opacity:.75}
.sortsel{background:#22304d;color:#f6f1e7}
.sort-toggle{margin-left:6px}
@media (max-width:760px){
  #screen-builder .builder-wrap{overflow-y:auto;display:flex;flex-direction:column}
  .builder-left,.builder-right{overflow:visible;flex:none}
  #builder-grid{overflow:visible;flex:none}
}
.sugg .copies{display:inline-block;font-size:12px;font-weight:bold;color:#7a5f10;background:rgba(122,95,16,.14);border-radius:6px;padding:1px 6px}
.optimizer .opt-cmds{display:flex;gap:6px;flex-wrap:wrap;margin:6px 0}
.optimizer .opt-focus{display:flex;gap:6px;flex-wrap:wrap;margin:6px 0}
.optimizer .opt-focus .fine{flex-basis:100%;margin:2px 0}
.opt-plan{margin-top:8px;border-top:1px dashed var(--ink2);padding-top:6px}
.plan-line{font-size:13.5px;margin:4px 0}
.plan-line.cut b{color:#8c2f1b}
.plan-line.add b{color:#2e5d1e}
.opt-apply{display:flex;gap:8px;margin-top:8px}
.coll-views{display:flex;gap:8px;margin-bottom:10px}
.deck-panel{border:1.5px solid var(--ink2);border-radius:10px;padding:10px 12px;margin-bottom:12px;background:rgba(122,95,16,.06)}
.deck-panel-head{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.deck-panel-head .btn{margin-left:auto}
.deck-panel-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(215px,1fr));gap:4px;margin-top:8px}
.deck-card-row{display:flex;justify-content:space-between;gap:8px;background:none;border:1px solid rgba(58,44,20,.25);border-radius:6px;padding:4px 8px;cursor:pointer;color:var(--ink);font:inherit;font-size:13px;text-align:left}
.deck-card-row:hover{background:rgba(122,95,16,.12)}
.friend-deck-line{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-bottom:10px;font-size:14.5px}
/* Selected state must read EVERYWHERE, not only inside filter bars —
   the optimizer's commands, its synergy chips and the Collection view
   toggle all use .btn.sel (Jace, Nov 4: the optimizer button did not
   light up). */
.btn.sel{background:var(--gold2);border-color:#7a5f10;font-weight:bold}

@media (prefers-reduced-motion: reduce){
  .stars,.stars::before,.stars::after,.meteor,.screen.active{animation:none!important}
}

/* ===== THE TABLE & THE MAT (Nov 4, 2026) =====
   Layering, as Jace ruled it: the TABLE (theme image) is the desktop base;
   the PLAYMAT is a baked transparent PNG layered over it — no border, no
   plate, its printed fields float on the art; the boards sit IN the frame so
   cards land on the printed fields. The frame is locked to the mat's own 8:5
   aspect, so the image can never stretch or distort. */
/* The playmat is the play surface: always the same 8:5 image, as large as
   the screen allows, on every device. The table is simply the space
   around it — top and bottom on tall tablets, slim side edges on wide
   phones. Jace's model, Nov 4, 2026. */
.mat-frame{position:relative;flex:1 1 auto;min-height:0;width:100%;display:flex;align-items:center;justify-content:center;container-type:size}
.mat-stage{position:relative;aspect-ratio:8/5;width:min(1180px,97vw,calc((100dvh - 118px)*1.6));width:min(1180px,100cqw,160cqh)}
.mat-img{position:absolute;inset:0;width:100%;height:100%;filter:drop-shadow(0 12px 26px rgba(0,0,0,.5));pointer-events:none}
.mat-ui{position:absolute;inset:0;display:flex;flex-direction:column;gap:2px;padding:5px 8px}
.mat-ui .board{background:transparent;border:none;backdrop-filter:none;box-shadow:none;margin:0;width:100%;padding:2px 4px;display:flex;flex-direction:column;min-height:0}
.mat-ui #board-banner{margin:0;width:100%}
#table .mat-ui .opp-board{flex:0 0 auto}
.mat-ui .midline{margin:0;width:100%}
#table .mat-ui .my-board{flex:1 1 auto}
#table.view-opp .mat-ui .opp-board{flex:1 1 auto}
.mat-ui .field-row{align-items:center}
.mat-ui .my-board .field-row,.mat-ui .opp-board .field-row{flex:1 1 auto}
#table.view-mine .mat-ui .opp-board .player-strip{padding:2px 2px}
/* shop + cosmetics thumbnails and the preview stage */
.shop-item .thumb,.cosmetic-item img.mat-thumb{background:repeating-conic-gradient(rgba(255,255,255,.06) 0 25%, transparent 0 50%) 0 0/18px 18px, rgba(10,14,20,.65)}
.shop-item .thumb{width:100%;height:110px;object-fit:cover;border-radius:8px;display:block}
.shop-item .thumb.mat{object-fit:cover}
.cosmetic-item img.mat-thumb{object-fit:cover}
.preview-stage{position:relative;width:100%;aspect-ratio:8/5;border-radius:10px;overflow:hidden;background-size:cover;background-position:center}
.preview-stage img{position:absolute;inset:6.5% 5%;width:90%;height:87%;border-radius:6px;box-shadow:0 10px 24px rgba(0,0,0,.55)}
.preview-caption{margin-top:6px;text-align:center;font-size:12.5px;opacity:.85}
.modal-card:has(.preview-stage){max-width:640px;width:94vw}
.melt-filters{margin:8px 0;padding:8px 10px;border:1px solid rgba(232,200,119,.25);border-radius:10px}
.mf-row{display:flex;gap:6px;align-items:center;flex-wrap:wrap;margin:4px 0}
.mf-label{font-size:12.5px;opacity:.85;min-width:52px}
.melt-filters select{background:#10161d;color:var(--parch);border:1px solid rgba(232,200,119,.4);border-radius:6px;padding:3px 6px}
/* Long captain/deck names ride in ONE line on the strip — no more
   three-line wrap spilling over the mat (Jace's phone, Nov 4, 2026). */
.player-strip{overflow:hidden}
.player-strip .pinfo{min-width:0;flex:1 1 auto}
.player-strip .pname{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* Markers rail (Jace, Nov 4, 2026): board state notes — Captain in the Berth,
   the field is empty, no Energy set — live OFF the mat, on the table to its
   left, as dark pills with a gold edge so they read against any table or mat
   artwork. The mat's rows belong to the cards alone. */
.mat-frame{gap:10px}
#mat-markers{position:relative;width:126px;flex:0 0 auto;align-self:stretch}
.mat-stage{width:min(1180px,calc(100cqw - 136px),160cqh)}
.marker-pill{position:absolute;right:0;transform:translateY(-50%);max-width:126px;background:rgba(10,13,19,.86);border:1px solid rgba(232,201,132,.6);color:#f3e6c8;border-radius:999px;padding:5px 9px;font-size:11.5px;line-height:1.3;text-align:center;box-shadow:0 2px 10px rgba(0,0,0,.5);white-space:normal}
#mat-markers .pill-berth{top:29%}
#mat-markers .pill-field{top:61%}
#mat-markers .pill-energy{top:88%}
#table.view-opp #mat-markers .pill-energy{top:20%}
#table.view-opp #mat-markers .pill-field{top:55%}
#table.view-opp #mat-markers .pill-berth{top:88%}

/* Enemy-board view lines up with the mat (Jace, Nov 4, 2026): the enemy board
   takes the same row order as your own — berth, field, energy — so every row
   sits inside the panel baked for it, and the marker pills keep one set of
   positions for both views. The board banner gets a solid backing so it
   reads over bright mat art. */
#table.view-opp .opp-board .berth-row{order:1}
#table.view-opp .opp-board .field-row{order:2}
#table.view-opp .opp-board .energy-row{order:3}
#table.view-opp #mat-markers .pill-energy{top:88%}
#table.view-opp #mat-markers .pill-field{top:61%}
#table.view-opp #mat-markers .pill-berth{top:29%}
#board-banner.mine{background:rgba(13,38,24,.88)}
#board-banner.opp{background:rgba(44,15,11,.88)}
.flip-payoff{margin:8px auto 0;font-size:19px;color:#ffe9b0;text-align:center;max-width:560px;min-height:26px;text-shadow:0 2px 8px #000;line-height:1.4}

/* Flip result hint (cmh-v31): quiet line under the payoff while the result
   hold waits for a tap (auto-continues after 10s). */
.flip-hint{margin-top:10px;font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:rgba(240,230,210,.55)}

/* Deck guide (cmh-v32): quick overview always shown; full guide folded
   until the reader opens it. */
.deck-guide .guide-quick{line-height:1.5}
.deck-guide .guide-full{margin-top:6px}
.deck-guide .guide-full h5{margin:12px 0 3px;font-size:13px;letter-spacing:.06em;text-transform:uppercase;color:#e8c96a}
.deck-guide .guide-full p{margin:0 0 6px;line-height:1.5}
.deck-guide button{margin-top:8px}

/* ============ RESPONSIVE STAGE LAW (cmh-v33, Jace, Nov 4, 2026) ============
   One sizing authority: the mat stage itself. Every band inside the mat
   sits at the exact fraction of the stage height where the artwork's
   panels are baked (strip 5.8% · berth 17% · field 41.8% · energy 82.4%
   · home strip 92.2%), and every card, portrait, pile and font inside
   the stage is sized from --sh (the stage height in px, set by
   fitStage()). No viewport units, no fixed pixels inside the mat — so
   the board lays out the same on a phone, a tablet, or anything else. */
.mat-stage{--sh:62vh}
.mat-ui{padding:0;gap:0}
.mat-ui .board{position:absolute;inset:0;display:block;padding:0;pointer-events:none;background:transparent}
.mat-ui .board>*{pointer-events:auto}
.mat-ui #board-banner{position:absolute;top:.5%;left:.8%;right:.8%;z-index:6;width:auto;font-size:calc(var(--sh)*.027);padding:calc(var(--sh)*.009) 10px;text-align:center}
.mat-ui .player-strip{position:absolute;left:1.2%;right:1.2%;display:flex;align-items:center;gap:calc(var(--sh)*.016);padding:0 calc(var(--sh)*.008);overflow:hidden}
.mat-ui .opp-board .player-strip{top:5.6%;height:9.2%}
.mat-ui .my-board .player-strip{top:92%;height:7.8%}
.mat-ui .portrait{width:calc(var(--sh)*.064);height:calc(var(--sh)*.064);font-size:calc(var(--sh)*.03);flex:0 0 auto}
.mat-ui .pname{font-size:calc(var(--sh)*.027);line-height:1.15}
.mat-ui .hearts{font-size:calc(var(--sh)*.025);line-height:1.15}
.mat-ui .pile-info{gap:calc(var(--sh)*.01)}
.mat-ui .pile{font-size:calc(var(--sh)*.019);padding:calc(var(--sh)*.007) calc(var(--sh)*.013);line-height:1.25}
.mat-ui .pile b{font-size:calc(var(--sh)*.026)}
.mat-ui .berth-row,.mat-ui .field-row,.mat-ui .energy-row{position:absolute;left:1.2%;right:1.2%;display:flex;align-items:flex-start;gap:calc(var(--sh)*.012);padding:calc(var(--sh)*.011) calc(var(--sh)*.006) 0;overflow-x:auto;overflow-y:hidden;min-height:0}
.mat-ui .berth-row{top:16.8%;height:24.8%;--cardh:calc(var(--sh)*.212);--cardw:calc(var(--sh)*.152)}
.mat-ui .field-row{top:41.6%;height:40.4%;--cardh:calc(var(--sh)*.30);--cardw:calc(var(--sh)*.214)}
.mat-ui .energy-row{top:82.2%;height:9.8%;--cardh:calc(var(--sh)*.08);--cardw:calc(var(--sh)*.057)}
.mat-ui .mini-card{width:var(--cardw);height:var(--cardh);min-height:0;font-size:calc(var(--sh)*.019)}
.mat-ui .mini-card.face-card{height:var(--cardh)}
.mat-ui .midline{position:absolute;top:38.2%;right:1%;width:44%;max-height:3.4%;overflow:hidden;z-index:5;margin:0;pointer-events:auto;cursor:pointer}
.mat-ui .resolution-rail{font-size:calc(var(--sh)*.02);text-align:left;color:#e9dfc8;width:100%;max-width:none;max-height:none;overflow:hidden}
#mat-markers{align-self:center}
#mat-markers .pill-berth{top:29%}
#mat-markers .pill-field{top:62%}
#mat-markers .pill-energy{top:87%}
.marker-pill{font-size:clamp(10px,1.55vh,13px)}
/* The match top bar never wraps: the ladder stays on one line and the
   turn text gives way first, then hides on narrow screens. */
.match-top{flex-wrap:nowrap;min-width:0;width:100%}
.phase-ladder{flex-wrap:nowrap;overflow:hidden;flex:0 1 auto}
.phase-ladder .ph{flex:0 0 auto}
.turn-banner{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#btn-view-toggle,#btn-gear{flex:0 0 auto}
@media (max-width:840px){
  .turn-banner{display:none}
  .phase-ladder .ph{padding:2px 7px;font-size:11px}
  .match-top{gap:6px}
}
@media (max-height:540px){
  :root{--cardw:clamp(38px,13.5dvh,92px);--cardh:calc(var(--cardw)*1.4)}
  .hand{padding-top:3px}
}

/* Stage law, round two (cmh-v33): the banner rides as a centred pill so
   it never reaches the strips' names at small sizes; strip text keeps
   legible floors; the resolution rail shows only when it has something
   to say. */
.mat-ui #board-banner{left:17%;right:17%;font-size:calc(var(--sh)*.024)}
.mat-ui .midline:has(#rail:empty){display:none}
.mat-ui .resolution-rail{background:rgba(8,11,17,.72);border:1px solid rgba(232,200,119,.25);border-radius:999px;box-shadow:0 2px 8px rgba(0,0,0,.35);padding:2px 9px}
/* RAIL FIX (Jace, Nov 4, 2026): on stage only the LATEST log line
   shows, on its plate in the berth/field seam; the full log opens in
   a modal on tap (see #rail click in app.js). Earlier lines stay in
   the DOM (renderRail keeps the last 9) but are not displayed. */
.mat-ui .resolution-rail div{display:none;padding:0;border-bottom:none}
.mat-ui .resolution-rail div:last-child{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mat-ui .pname{font-size:max(9px,calc(var(--sh)*.027))}
.mat-ui .hearts{font-size:max(9px,calc(var(--sh)*.025))}
.mat-ui .pile{font-size:max(8px,calc(var(--sh)*.019))}
.mat-ui .portrait{width:max(16px,calc(var(--sh)*.064));height:max(16px,calc(var(--sh)*.064))}

/* ============ STRIP PLATES + PHONE ROOM (cmh-v34, Jace, Nov 4, 2026) ============
   Both player strips ride on a soft dark plate so names, Hearts and
   piles read against every playmat, bright or dark. The Hearts numeral
   scales with the stage like everything else (its fixed 19px was
   cropping the tops of names on small stages). On landscape phones the
   furniture around the mat slims down — narrower notes rail, smaller
   hand, tighter dock — so the board itself gets bigger; tablets and
   taller screens are untouched. */
.mat-ui .player-strip{background:rgba(8,11,17,.55);border:1px solid rgba(232,200,119,.20);border-radius:calc(var(--sh)*.014);box-shadow:0 2px 10px rgba(0,0,0,.35)}
.mat-ui .pname{font-size:max(9px,calc(var(--sh)*.025));line-height:1.05}
.mat-ui .hearts{font-size:max(9px,calc(var(--sh)*.023));line-height:1.05}
.mat-ui .hearts .hnum{font-size:max(11px,calc(var(--sh)*.034))}
.mat-ui .portrait{width:calc(var(--sh)*.059);height:calc(var(--sh)*.059)}
.mat-ui .pile{background:rgba(13,20,32,.85)}
@media (max-height:560px) and (orientation:landscape){
  #mat-markers{width:96px;flex:0 0 96px}
  .marker-pill{max-width:96px;font-size:10.5px;padding:4px 6px}
  .mat-stage{width:min(1180px,calc(100cqw - 106px),160cqh)}
  :root{--cardw:clamp(36px,11.5dvh,84px);--cardh:calc(var(--cardw)*1.4)}
  .hand{padding-top:2px}
  .action-dock .hint{font-size:11.5px;line-height:1.3}
  #btn-primary{padding:8px 14px}
  .match-top{gap:6px}
  #btn-raise-hand{padding:4px 8px;font-size:12px}
}

/* ============ TRAVEL GHOSTS (cmh-v38, Jace, Nov 4, 2026) ============
   Draw/destruction ghosts: fixed, transform/opacity only, ~520ms,
   pointer-events none; JS removes them when the flight ends. */
.anim-ghost{position:fixed;z-index:70;pointer-events:none;margin:0;box-shadow:0 10px 28px rgba(0,0,0,.5);border-radius:8px;transition:transform .52s cubic-bezier(.22,.8,.3,1),opacity .52s ease}
.anim-ghost.ghost-back{padding:0;border:none;background:none;overflow:hidden}

/* ---------- online play (cmh-v39) ---------- */
.tag-chip{font-family:ui-monospace,Menlo,Consolas,monospace;background:#efe7d2;color:var(--ink);border:1px solid #cbbf9f;border-radius:6px;padding:1px 7px;font-weight:bold;letter-spacing:.02em}
#online-wait{z-index:75}
body.online-match #opp-name{cursor:pointer;text-decoration:underline dotted rgba(246,241,231,.7) 1.5px;text-underline-offset:3px}
body.online-match #opp-name:hover{color:var(--gold2)}
.silence-banner{position:fixed;top:52px;left:50%;transform:translateX(-50%);z-index:58;background:rgba(13,20,32,.94);color:var(--parch);border:1.5px solid var(--gold);border-radius:10px;padding:8px 14px;display:flex;gap:12px;align-items:center;font-size:14px;box-shadow:0 10px 26px rgba(0,0,0,.5);max-width:92vw;text-align:center}
.silence-banner.hidden{display:none}
#online-play-sec .friend-add{flex-wrap:wrap}

/* ============ PACK OPENING + BRAND (cmh-v41, Jace, Nov 4, 2026) ====
   The pack is the canonical card back under a foil seal bearing the
   logo. It swells, splits, and the ten cards fly to their places in
   the results grid (JS/WAAPI, transform/opacity only). With animations
   off there is no stage at all — results render directly. */
#pack-results{position:relative}
.pack-stage{position:fixed;inset:0;z-index:58;background:rgba(8,10,18,.74);display:flex;flex-direction:column;align-items:center;justify-content:center;cursor:pointer}
.pack-visual{position:relative;width:min(150px,34vh);aspect-ratio:5/7;filter:drop-shadow(0 18px 34px rgba(0,0,0,.6))}
.pack-piece{position:absolute;left:0;width:100%;overflow:hidden}
.pack-piece img{width:100%;display:block}
.pack-piece-top{top:0;height:27%;border-radius:10px 10px 0 0}
.pack-piece-bot{top:27%;height:73%;border-radius:0 0 10px 10px}
.pack-piece-bot img{transform:translateY(-27%)}
.pack-seal{position:absolute;left:0;right:0;top:21.5%;height:11%;background:linear-gradient(180deg,#e8c877,#b98a2e 55%,#8a5f10);display:flex;align-items:center;justify-content:center;box-shadow:0 2px 8px rgba(0,0,0,.5);z-index:2}
.pack-seal img{height:170%;width:auto;filter:drop-shadow(0 1px 2px rgba(0,0,0,.6))}
.pack-burst{position:absolute;left:50%;top:50%;width:270%;aspect-ratio:1;transform:translate(-50%,-50%);background:radial-gradient(circle,rgba(255,236,180,.95) 0%,rgba(232,200,119,.45) 38%,rgba(232,200,119,0) 68%);opacity:0;pointer-events:none}
.pack-hint{margin-top:22px;color:var(--parch);font-size:13.5px;letter-spacing:.4px;text-shadow:0 2px 6px #000}
.shop-item .thumb.pack{object-fit:contain;background:#0b101f;padding:6px 0}

/* Deck Captain portraits (Jace, Nov 4, 2026): each built deck carries its
   Captain's art alongside its name in the selector and the editor. */
.deck-cap-art{width:76px;height:50px;object-fit:cover;border-radius:6px;border:1px solid rgba(58,44,20,.35);flex:none;background:#20180c}
.pick-row.has-art{flex-direction:row;align-items:center;gap:10px}
.pick-text{display:flex;flex-direction:column;gap:2px;align-items:flex-start;text-align:left}
#deck-stats{display:flex;gap:10px;align-items:center}
.deck-stats-text{flex:1}

/* Pack reveal presentation (Jace, Nov 4, 2026): a pull reads at a glance —
   Mythic burns orange, Rare shines gold, Uncommon glints silver, Common
   stays plain; a first-ever pull carries the NEW banner. */
.pack-results .mini-card{position:relative}
/* Pack rarity glows (revised scheme, Jace Nov 4, 2026 18:53): red Mythic,
   blue Rare, green Uncommon, Common none — deliberately strong: a solid
   ring plus a wide halo, readable at a glance on a phone. */
.glow-mythic{box-shadow:0 0 0 3px rgba(255,40,40,.95),0 0 22px 8px rgba(255,40,40,.85),0 0 48px 18px rgba(255,40,40,.4)!important}
.glow-rare{box-shadow:0 0 0 3px rgba(40,110,255,.95),0 0 22px 8px rgba(40,110,255,.85),0 0 48px 18px rgba(40,110,255,.4)!important}
.glow-uncommon{box-shadow:0 0 0 3px rgba(30,205,100,.95),0 0 22px 8px rgba(30,205,100,.85),0 0 48px 18px rgba(30,205,100,.4)!important}
/* The modest glow key at the top of the pack-opening view. */
.pack-key{display:flex;gap:14px;flex-wrap:wrap;align-items:center;font-size:.8rem;opacity:.92;margin:2px 0 10px}
.pack-key .pk{display:inline-flex;align-items:center;gap:5px}
.pk-dot{width:10px;height:10px;border-radius:50%;display:inline-block}
.pk-mythic{background:#ff2828;box-shadow:0 0 8px 2px rgba(255,40,40,.8)}
.pk-rare{background:#286eff;box-shadow:0 0 8px 2px rgba(40,110,255,.8)}
.pk-uncommon{background:#1ecd64;box-shadow:0 0 8px 2px rgba(30,205,100,.8)}
.new-banner{position:absolute;top:6px;left:6px;z-index:3;background:#b3271e;color:#fff;font-size:10.5px;font-weight:bold;letter-spacing:.08em;padding:2.5px 7px;border-radius:4px;box-shadow:0 1px 4px rgba(0,0,0,.45);pointer-events:none}

/* Collection completion counter (Jace, Nov 4, 2026): sits with the view
   toggles, right-aligned, in the panel's stat voice. */
.coll-views{align-items:center}
.coll-counter{margin-left:auto;font-size:13.5px;font-weight:bold;color:var(--ink2);letter-spacing:.02em}

/* Settings menu (Nov 4, 2026): music toggle + volume live here, never as
   an on-screen mute button. */
.set-row{display:flex;flex-direction:column;gap:8px;margin:14px 0 4px;font-weight:600}
.set-row input[type="range"]{width:100%;accent-color:var(--gold);height:28px;cursor:pointer}

/* ---------- profile identity + editor (Nov 4, 2026) ----------
   The home identity header (avatar + name + tag + title, tap to edit),
   friend-row faces, and the profile editor's avatar picket. Identity
   lives on the account; these are only its clothes. */
.home-top-row{display:flex;align-items:center;gap:12px;width:100%;max-width:1060px;margin:0 auto 14px}
.home-identity{display:flex;align-items:center;gap:12px;flex:1 1 auto;min-width:0;background:rgba(13,20,32,.82);color:var(--parch);border:1.5px solid rgba(232,200,119,.45);border-radius:10px;padding:8px 14px;cursor:pointer;text-align:left;font:inherit}
.home-identity:hover{border-color:var(--gold)}
/* The equipped companion keeps the player company beside the identity
   chip on Home (cmh-v75): same pet art, a quiet harbour-side perch. */
.home-companion{flex:0 0 auto;width:128px;height:104px;display:flex;align-items:center;justify-content:center;background:rgba(13,20,32,.82);border:1.5px solid rgba(232,200,119,.45);border-radius:10px;padding:4px;cursor:pointer}
.home-companion:hover{border-color:var(--gold)}
.home-companion .pet-art{width:120px;height:96px}
/* cmh-v80: the perch grew a step (96x78 -> 128x104, Jace's order);
   on narrow phones it steps back a touch so the identity row keeps
   its balance. */
@media (max-width:560px){.home-companion{width:112px;height:92px}.home-companion .pet-art{width:104px;height:84px}}
.hi-avatar{width:44px;height:44px;flex:0 0 auto;display:flex;align-items:center;justify-content:center}
.hi-avatar .avatar-circle{width:44px;height:44px;border:1.5px solid var(--gold)}
.medallion{width:44px;height:44px;border-radius:50%;background:radial-gradient(circle at 35% 30%,#5a4632,#241a0c);border:2px solid var(--gold);color:var(--gold2);display:inline-flex;align-items:center;justify-content:center;font-size:19px;font-weight:bold;flex:0 0 auto}
.hi-avatar .medallion{width:40px;height:40px;font-size:17px}
.hi-text{display:flex;flex-direction:column;gap:3px;min-width:0}
.hi-name{font-variant:small-caps;letter-spacing:1px;font-size:17px;font-weight:bold}
.hi-sub{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.hi-title{font-style:italic;color:var(--gold2);font-size:13.5px}
.hi-edit{margin-left:auto;color:var(--gold2);font-size:13.5px;white-space:nowrap}
.friend-avatar{flex:0 0 auto}
.avatar-circle.friend-avatar{width:36px;height:36px;border:1px solid rgba(58,44,20,.4)}
.friend-avatar.medallion{width:36px;height:36px;font-size:16px}
.friend-who{display:flex;flex-direction:column;gap:1px;min-width:0}
.friend-title{font-style:italic;color:var(--ink2);font-size:12.5px}
.pe-card{max-width:560px}
.pe-user-row{display:flex;gap:8px;align-items:center}
.pe-user-row input{flex:1}
.pe-user-row .tag-chip{flex:0 0 auto;font-size:14px;padding:5px 9px}
.pe-label{display:block;margin-bottom:6px}
.avatar-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(74px,1fr));gap:8px;max-height:300px;overflow-y:auto;padding:6px;border:1px solid #cbbf9f;border-radius:8px;background:#fff}
.avatar-pick{display:flex;flex-direction:column;align-items:center;gap:3px;background:transparent;border:2px solid transparent;border-radius:8px;padding:5px 3px;cursor:pointer;font:inherit}
.avatar-pick .avatar-circle{width:56px;height:56px;border:1px solid rgba(58,44,20,.4)}
.avatar-pick .avatar-none{width:56px;height:56px;display:flex;align-items:center;justify-content:center;border-radius:50%;border:1.5px dashed var(--ink2);color:var(--ink2);font-size:13px}
.avatar-cap-name{font-size:10px;line-height:1.15;color:var(--ink2);text-align:center;max-width:70px}
.avatar-pick.sel{border-color:var(--gold);background:#fdf6dd;box-shadow:0 0 0 1px var(--gold),0 0 12px rgba(232,200,119,.7)}
.pe-error{background:#f8e3e0;border:1.5px solid var(--red);color:var(--red);border-radius:8px;padding:9px 12px;font-size:14px}
.pe-actions{display:flex;gap:10px;margin-top:14px}

/* ============ cmh-v64: gilding · companions · shop · gifts ============
   Contrast law for everything added here: panels are parchment, so
   text is var(--ink)/var(--ink2); anything that ever sits on the dark
   harbour background (companion slots live in the match player strips)
   uses light-on-dark treatment only. Shop section headers sit INSIDE
   the parchment wide-panel, so they take ink text. */

/* --- gilded cards: gold frame, drifting sheen, living twinkle --- */
.mini-card.gilded{border-color:#a07d1c;outline:2px solid rgba(201,162,39,.9);outline-offset:-4px;box-shadow:inset 0 0 0 2px rgba(232,200,119,.85),inset 0 0 18px rgba(201,162,39,.45),0 2px 10px rgba(122,95,16,.35)}
.mini-card.face-card.gilded{box-shadow:inset 0 0 0 3px rgba(232,200,119,.95),inset 0 0 22px rgba(201,162,39,.5),0 2px 10px rgba(0,0,0,.4)}
.gild-sheen{position:absolute;inset:0;border-radius:inherit;pointer-events:none;z-index:2;background:linear-gradient(115deg,transparent 30%,rgba(255,215,130,.35) 48%,rgba(255,240,190,.5) 52%,transparent 70%);background-size:250% 250%;background-position:85% 85%}
.gilded-anim .gild-sheen{animation:gildSweep 5.5s ease-in-out infinite alternate}
/* cmh-v78: field-weight gilding for board minis — a stronger gold
   frame with an outer halo (so the card reads gold against the mat
   at play size) and a slow sheen sweep; applyGild gives minis 3
   twinkle dots instead of 7. Pure CSS on the same .gilded data. */
.mini-card.gilded-mini{box-shadow:inset 0 0 0 2px rgba(232,200,119,.9),inset 0 0 18px rgba(201,162,39,.5),0 0 0 2px rgba(201,162,39,.6),0 0 14px 2px rgba(201,162,39,.5)}
.mini-card.face-card.gilded-mini{box-shadow:inset 0 0 0 3px rgba(232,200,119,.95),inset 0 0 22px rgba(201,162,39,.55),0 0 0 2px rgba(201,162,39,.6),0 0 14px 2px rgba(201,162,39,.5)}
/* cmh-v89: a gilded card that can be played keeps its gold inset frame
   and takes the green play halo OUTSIDE it — gilded reads gold, playable
   reads green, the two never share a halo again. (While the glowpulse
   animation runs it overrides box-shadow with the same green halo; the
   gold outline/sheen still mark the gild.) */
.mini-card.gilded-mini.legal{box-shadow:inset 0 0 0 2px rgba(232,200,119,.9),inset 0 0 18px rgba(201,162,39,.5),0 0 0 2px var(--play),0 0 16px 4px rgba(47,230,115,.75)}
.mini-card.face-card.gilded-mini.legal{box-shadow:inset 0 0 0 3px rgba(232,200,119,.95),inset 0 0 22px rgba(201,162,39,.55),0 0 0 2px var(--play),0 0 16px 4px rgba(47,230,115,.75)}
.mini-card.gilded-mini .gild-sheen{animation:gildSweep 7s ease-in-out infinite alternate}
body.anim-off .mini-card.gilded-mini .gild-sheen{animation:none}
@keyframes gildSweep{from{background-position:88% 88%}to{background-position:12% 12%}}
.gild-twinkle{position:absolute;inset:0;pointer-events:none;z-index:3}
.gild-twinkle i{position:absolute;width:5px;height:5px;border-radius:50%;background:radial-gradient(circle,#fff6d8 0%,rgba(255,220,130,.85) 45%,rgba(255,220,130,0) 72%);opacity:0;animation:gildTwinkle 3.4s ease-in-out infinite}
@keyframes gildTwinkle{0%,100%{opacity:0;transform:scale(.4)}50%{opacity:1;transform:scale(1.25)}}
body.anim-off .gild-sheen,body.anim-off .gild-twinkle i{animation:none}
.mini-card.gilded-static .gild-sheen,.mini-card.gilded-static .gild-twinkle i{animation:none}
@media (prefers-reduced-motion: reduce){
  .gild-sheen,.gild-twinkle i{animation:none!important}
}
/* cmh-v107 (e): the chip hangs on the right frame rail BELOW the cost
   circle — measured on the printed faces, the cost circle spans
   x 82–93.6%, y 4.4–11.0% (Champions/Tactics/Gear/Domains alike), and
   the old top:4px;right:4px seat put the chip's centre at ~(94%, 4%),
   squarely on it (Jace's Collection screenshot, Nov 6, 2026: Sojobo's
   Heir, Tengu Fan-Bearer, Tengu of the Turning Tide and Tengu
   Stormcaller all showed the badge instead of their cost). The new
   seat is percentage-based so the clearance tracks the face at every
   tile size: below the cost (top 12.5%), clear of the mark gem
   (top-left), the title band (y < 11%), the typeline, the count chip
   (bottom-left) and Power (bottom-right). */
.gild-chip{position:absolute;top:12.5%;right:5.2%;z-index:4;background:linear-gradient(180deg,var(--gold2),var(--gold));color:var(--ink);border:1px solid #7a5f10;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:bold;box-shadow:0 1px 4px rgba(0,0,0,.4);pointer-events:none}
.gild-head{font-weight:bold}
.gild-cell{display:flex;flex-direction:column;gap:6px;align-items:stretch}
.gild-foot{display:flex;justify-content:center}
.gilded-label{color:#7a5f10;font-weight:bold;font-size:14px}

/* --- companions: HYBRID pets (cmh-v73) --------------------------
   The companions (Pocket Puss, Star Sprite, Tide Turtle, Little
   Lighthouse, Moon Moth, Ship's Cat) are keyed AI-generated films: an animated WebP loop
   with a stillness hold at the seam, or its poster PNG when
   Animations are off (app.js swaps the img src). since cmh-v77 ALL SIX are films
   (the Ship's Cat was the last SVG holdout). The .pet-svg rig
   rules and .pet-* keyframes further down are the retired
   cmh-v66-v70 SVG rig, kept inert for the record. The container
   boxes below are shared by both kinds, so tile/hub/slot sizing
   is identical; a WebP pet's img fills its .pet-art box with
   object-fit:contain. */
.companion-slot{flex:0 0 auto;display:flex;align-items:center;min-width:0}
.pet-art{display:inline-flex;line-height:0;width:100%;height:100%}
.pet-art svg{width:100%;height:100%;display:block}
.pet-art img.pet-img{width:100%;height:100%;object-fit:contain;display:block}
.pet-wrap{display:inline-flex;width:54px;height:54px;filter:drop-shadow(0 2px 5px rgba(0,0,0,.4))}
.mat-ui .companion-slot .pet-wrap{width:calc(var(--sh)*.075);height:calc(var(--sh)*.075)}
/* cmh-v79: the player's companion leaves the player strip and keeps
   the player company at the LEFT of the battle table, large — a real
   presence, not a thumbnail. Its size is computed from the actual
   free space beside the mat (the calc mirrors .mat-stage's own width
   formula: the side margin plus a graceful step onto the mat's edge),
   height-capped so it never swamps a short frame. pointer-events are
   off — company only, never a target, never covering a control — and
   when the margins vanish on tall wide frames it also fades a step.
   The opponent's slot keeps the strip sizing above. */
.battle-pet{position:absolute;left:10px;bottom:10px;z-index:6;pointer-events:none}
.battle-pet .pet-wrap{width:min(220px,38cqh,calc((100cqw - min(1180px,100cqw,160cqh))/2 + 70px));height:min(220px,38cqh,calc((100cqw - min(1180px,100cqw,160cqh))/2 + 70px));filter:drop-shadow(0 4px 14px rgba(0,0,0,.5))}
@container (min-width:1180px) and (min-height:738px){.battle-pet{opacity:.85}}
/* cmh-v85: the wrap formula above is only the first-paint fallback —
   fitBattlePet() (app.js) measures the TRUE free strip (frame edge to
   the markers rail, whose pills are text and occupied at all times)
   and sizes the pet inline to fit it; when the natural strip is too
   narrow on a desktop-width frame, this dock padding reserves the
   room instead, shifting the rail + stage right by --pet-dock. */
.mat-frame.pet-dock{padding-left:var(--pet-dock,0px)}
.shop-item .pet-thumb{height:110px;display:flex;align-items:center;justify-content:center}
.shop-item .pet-thumb .pet-art{width:104px;height:104px}
.cosmetic-item .pet-hub{height:96px;display:flex;align-items:center;justify-content:center}
.cosmetic-item .pet-hub .pet-art{width:92px;height:92px}
.companion-item .companion-none-art{height:96px;display:flex;align-items:center;justify-content:center;font-size:40px;color:var(--ink2);background:var(--parch2)}
/* --- avatars: circles of pure art (cmh-v68) -----------------------
   An avatar is NEVER a card face: it is the card's raw art inside a
   round mask, cropped on the subject via AVATAR_FOCAL (app.js) — the
   img is absolutely positioned by % (width/left/top from the table),
   the circle clips it. Same table on every surface, so the subject
   sits identically in the shop, the editor, friends lists and the
   in-match plates. */
.avatar-circle{position:relative;display:inline-block;border-radius:50%;overflow:hidden;background:#20180c;flex:0 0 auto;vertical-align:middle}
.avatar-circle img{position:absolute;max-width:none;height:auto;display:block}
.shop-item .avatar-thumb{height:110px;width:100%;display:flex;align-items:center;justify-content:center}
.shop-item .avatar-thumb .avatar-circle{width:100px;height:100px;border:2px solid var(--gold)}
.portrait .avatar-circle{width:100%;height:100%}
/* --- SVG pet animation (cmh-v66-v70, restored verbatim for the
   Ship's Cat + Moon Moth in the cmh-v73 hybrid) --- */
.pet-svg g{transform-box:fill-box}
.pet-svg .rig{transform-box:view-box}
.pet-eyes{transform-origin:center;animation:petBlink 4.8s ease-in-out infinite}
@keyframes petBlink{0%,90%,100%{transform:scaleY(1)}94%{transform:scaleY(.06)}97.5%{transform:scaleY(1)}}
.pet-breathe{transform-origin:50% 92%;animation:petBreathe 3.6s ease-in-out infinite}
@keyframes petBreathe{0%,100%{transform:translateY(0) scale(1)}50%{transform:translateY(-1.6px) scale(1.015)}}
.pet-tail{animation:petTail 3.6s ease-in-out infinite}
@keyframes petTail{0%,100%{transform:rotate(0)}30%{transform:rotate(-6deg)}62%{transform:rotate(3deg)}}
.pet-bobsm{animation:petBobSm 4.2s ease-in-out infinite}
@keyframes petBobSm{0%,100%{transform:translateY(0)}50%{transform:translateY(-2.4px)}}
.pet-tent{animation:petTent 2.2s ease-in-out infinite alternate}
@keyframes petTent{from{transform:rotate(-4deg)}to{transform:rotate(4deg)}}
.pet-bub{animation:petRise 3.6s linear infinite}
@keyframes petRise{0%{transform:translateY(5px);opacity:0}18%{opacity:.95}82%{opacity:.95}100%{transform:translateY(-30px);opacity:0}}
.pet-beamg{animation:petBeamSweep 4.8s ease-in-out infinite alternate}
@keyframes petBeamSweep{from{transform:rotate(-17deg)}to{transform:rotate(17deg)}}
.pet-sway{transform-origin:50% 100%;animation:petSway 4.6s ease-in-out infinite}
@keyframes petSway{0%,100%{transform:rotate(-1.5deg)}50%{transform:rotate(1.5deg)}}
.pet-lamp{animation:petLamp 2.6s ease-in-out infinite}
@keyframes petLamp{0%,100%{opacity:1}50%{opacity:.55}}
.pet-drift{animation:petDrift 3.8s ease-in-out infinite}
@keyframes petDrift{0%,100%{transform:translateY(1.5px)}50%{transform:translateY(-2.5px)}}
.pet-glow{transform-origin:center;animation:petGlowPulse 2.8s ease-in-out infinite}
@keyframes petGlowPulse{0%,100%{transform:scale(.93)}50%{transform:scale(1.07)}}
.pet-twinkle{transform-origin:center;animation:petTwinkle 2.4s ease-in-out infinite}
@keyframes petTwinkle{0%,100%{transform:scale(.65) rotate(0deg);opacity:.45}50%{transform:scale(1.1) rotate(12deg);opacity:1}}
.pet-wingl{animation:petFlutterL .8s ease-in-out infinite alternate}
@keyframes petFlutterL{from{transform:rotate(4deg)}to{transform:rotate(-7deg)}}
.pet-wingr{animation:petFlutterR .8s ease-in-out infinite alternate}
@keyframes petFlutterR{from{transform:rotate(-4deg)}to{transform:rotate(7deg)}}
.pet-antl{animation:petAntL 2.8s ease-in-out infinite}
@keyframes petAntL{0%,100%{transform:rotate(0)}50%{transform:rotate(-5deg)}}
.pet-antr{animation:petAntR 2.8s ease-in-out infinite}
@keyframes petAntR{0%,100%{transform:rotate(0)}50%{transform:rotate(5deg)}}
.pet-flipl{animation:petFlipL 1.9s ease-in-out infinite}
@keyframes petFlipL{0%,100%{transform:rotate(0)}50%{transform:rotate(-10deg)}}
.pet-flipr{animation:petFlipR 1.9s ease-in-out infinite}
@keyframes petFlipR{0%,100%{transform:rotate(0)}50%{transform:rotate(10deg)}}
.pet-arml{animation:petArmL 2.6s ease-in-out infinite alternate}
@keyframes petArmL{from{transform:rotate(-3deg)}to{transform:rotate(6deg)}}
.pet-armr{animation:petArmR 2.6s ease-in-out infinite alternate}
@keyframes petArmR{from{transform:rotate(3deg)}to{transform:rotate(-6deg)}}
.pet-headbob{animation:petHeadBob 2.9s ease-in-out infinite}
@keyframes petHeadBob{0%,100%{transform:translateY(0)}50%{transform:translateY(2.6px)}}
body.anim-off .pet-svg *{animation:none!important}
@media (prefers-reduced-motion: reduce){
  .pet-svg *{animation:none!important}
}

/* --- profile editor: the keep-wearing ring --- */
.avatar-pick.keep{border-color:var(--gold);border-style:dashed;background:#fdf6dd}

/* --- shop sections & tiles (on the parchment wide-panel: ink text) --- */
.shop-section{margin-top:22px}
.shop-section-head h4{margin:0 0 2px;font-size:18px;color:var(--ink)}
.shop-section-head .fine{margin:0 0 4px}
.shop-item{position:relative;display:flex;flex-direction:column;align-items:center;gap:5px}
.shop-item h4{margin:2px 0 0}
.shop-item-wide{grid-column:1/-1}
.shop-item-wide .mini-card{margin:0 auto}
.shop-ribbon{position:absolute;top:8px;left:8px;z-index:2;background:linear-gradient(180deg,var(--gold2),var(--gold));color:var(--ink);border:1px solid #7a5f10;border-radius:10px;font-size:11px;font-weight:bold;padding:2px 8px;box-shadow:0 1px 4px rgba(0,0,0,.3)}
.rar-band{display:inline-block;font-size:11px;font-weight:bold;letter-spacing:.05em;text-transform:uppercase;border-radius:9px;padding:1px 8px;border:1.5px solid}
.rar-band-Mythic{color:#d81f1f;border-color:#ff2828;background:rgba(255,40,40,.08)}
.rar-band-Rare{color:#1f4fd8;border-color:#286eff;background:rgba(40,110,255,.08)}
.rar-band-Uncommon{color:#128a44;border-color:#1ecd64;background:rgba(30,205,100,.10)}
.rar-band-Common{color:var(--ink2);border-color:#cbbf9f;background:rgba(203,191,159,.15)}
.shop-btns{display:flex;gap:7px;flex-wrap:wrap;justify-content:center;margin-top:auto}
.forge-input{width:100%;max-width:420px;padding:9px;border:1px solid var(--ink2);border-radius:6px;background:#fff;font-size:15px;text-align:center}
.forge-count{margin:0}

/* --- gifts (friends panel + modal are parchment: ink text) --- */
.gift-row{display:flex;align-items:center;gap:10px;background:#fff;border:1px solid #cbbf9f;border-radius:8px;padding:8px 11px;margin:6px 0;font-size:14.5px;color:var(--ink)}
.gift-when{margin-left:auto;font-size:12.5px;color:var(--ink2);white-space:nowrap}
.gift-friend-head{display:flex;align-items:center;gap:10px;width:100%}
.gift-tabs{display:flex;gap:7px;flex-wrap:wrap;margin:12px 0 8px}
.gift-chips{display:flex;gap:7px;flex-wrap:wrap;margin:8px 0}
.gift-custom{width:180px;padding:8px;border:1px solid var(--ink2);border-radius:6px;font-size:15px;margin:4px 0}
.gift-amt-line{font-size:14.5px;color:var(--ink)}
.gift-pane .btn.primary{margin-top:8px}
.gift-group-head{margin:14px 0 6px;color:var(--ink)}
.gift-item-row{display:flex;align-items:center;gap:10px;background:#fff;border:1px solid #cbbf9f;border-radius:8px;padding:7px 11px;margin:5px 0;font-size:14.5px;color:var(--ink)}
.gift-item-row b{margin-left:auto}
.gift-item-row.preselected{border-color:var(--gold);box-shadow:0 0 0 2px var(--gold),0 0 12px rgba(232,200,119,.7)}
.gift-card-grid{width:100%}

/* ==== cmh-v87 — PHONE-ONLY home fit (Jace, Nov 5): the home screen was
   stacking into a long scroll of tall, near-empty panels on his phone.
   Every rule below lives behind a phone-only query — landscape phones
   (the S26 Ultra tier: short screens, max-height 560px, the same tier
   the match table already uses) or portrait phones (max-width 560px).
   Tablet (1024×768) and desktop (1280×800+) can match neither query and
   render exactly as before — proven by home-v87-proof layout boxes.
   Layout only: no element, text or behaviour changes. ==== */
@media (orientation:landscape) and (max-height:560px){
  #screen-home{padding:8px}
  #screen-home .topbar{gap:6px 8px;padding:6px 10px;margin:0 auto 6px}
  #screen-home .brand{font-size:14px;white-space:nowrap;flex:0 0 auto}
  #screen-home .brand .mark{width:24px;height:24px}
  #screen-home #wallet{order:3;flex:1 1 100%;flex-wrap:nowrap;gap:10px;font-size:11.5px;min-width:0}
  #screen-home #wallet .wchip{white-space:nowrap}
  #screen-home .topbar>.btn{order:2;flex:0 0 auto;padding:4px 8px;font-size:12.5px}
  #screen-home .home-top-row{margin:0 auto 6px;gap:8px}
  #screen-home .home-identity{padding:5px 10px;gap:9px}
  #screen-home .hi-avatar{width:32px;height:32px}
  #screen-home .hi-main{flex:1 1 auto;min-width:0}
  #screen-home .hi-name{font-size:14.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  #screen-home .hi-sub{font-size:11px}
  #screen-home #hi-tag{display:inline-block;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom}
  #screen-home .home-companion{width:68px;height:52px}
  #screen-home .home-hero{padding:8px 12px}
  #screen-home #home-greeting{font-size:16px;margin:0}
  #screen-home #home-stats{font-size:12px;margin:1px 0 0}
  #screen-home .home-actions{gap:8px;margin:5px 0 4px}
  #screen-home .home-actions .btn.big{padding:6px 12px;font-size:13.5px}
  #screen-home .bot-setup{flex-direction:row;flex-wrap:nowrap;gap:10px;margin:0 0 6px}
  #screen-home .bot-setup label{flex-direction:row;align-items:center;gap:6px;flex:1 1 0;min-width:0;font-size:12px}
  #screen-home .bot-setup select{flex:1 1 0;min-width:0;padding:2px 4px;font-size:12.5px}
  #screen-home .bot-setup select{padding-right:24px;background-position:right 7px center}
  #screen-home .home-actions .art-btn{min-height:40px;padding:6px 12px;max-width:none}
  #screen-home .home-grid{grid-template-columns:repeat(6,minmax(0,1fr));gap:6px}
  #screen-home .tile{padding:6px 4px;font-size:18px;gap:2px}
  #screen-home .tile-icon{width:30px;height:30px}
  #screen-home .tile span{font-size:12px}
  #screen-home .tile small{font-size:10px}
}
/* Wide landscape phones (the S26 Ultra tier) have room for the whole
   topbar on one line — brand, wallet and buttons side by side. */
@media (orientation:landscape) and (max-height:560px) and (min-width:840px){
  #screen-home .topbar{flex-wrap:nowrap}
  #screen-home #wallet{order:0;flex:0 1 auto}
}
@media (orientation:portrait) and (max-width:560px){
  #screen-home{padding:10px}
  #screen-home .topbar{gap:6px 8px;padding:7px 10px;margin:0 auto 8px}
  #screen-home .brand{font-size:15px;flex:0 0 auto}
  #screen-home .brand .mark{width:24px;height:24px}
  #screen-home #wallet{order:3;flex:1 1 100%;gap:3px 9px;font-size:12px}
  #screen-home .topbar>.btn{order:2;flex:0 0 auto;padding:5px 9px;font-size:12.5px}
  #screen-home .home-top-row{margin:0 auto 8px;gap:8px}
  #screen-home .home-identity{padding:7px 10px;gap:9px}
  #screen-home .hi-avatar{width:38px;height:38px}
  #screen-home .hi-main{flex:1 1 auto;min-width:0}
  #screen-home .hi-name{font-size:15.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  #screen-home #hi-tag{display:inline-block;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom}
  #screen-home .hi-edit{flex:0 0 auto;font-size:12px}
  #screen-home .home-companion{width:96px;height:76px}
  #screen-home .home-hero{padding:12px 14px}
  #screen-home #home-greeting{font-size:19px;margin:0 0 2px}
  #screen-home #home-stats{margin:0}
  #screen-home .home-actions{gap:8px;margin:8px 0 6px}
  #screen-home .home-actions .btn.big{padding:9px 14px;font-size:15px}
  #screen-home .bot-setup{gap:6px;margin:4px 0 8px}
  #screen-home .bot-setup label{gap:2px;font-size:12px}
  #screen-home .bot-setup select{padding:4px 6px;font-size:13px}
  #screen-home .bot-setup select{padding-right:26px}
  #screen-home .home-actions .art-btn{flex:1 1 100%;max-width:none;min-height:54px}
  #screen-home .home-grid{grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}
  #screen-home .tile{padding:10px 4px 9px;font-size:21px;gap:3px}
  #screen-home .tile-icon{width:38px;height:38px}
  #screen-home .tile span{font-size:12.5px}
  #screen-home .tile small{font-size:10.5px}
}

/* --- Crafting Bench overhaul (cmh-v97): hero, furnace, stat melt --- */
.bench-hero{display:flex;gap:16px;align-items:center;background:linear-gradient(135deg,rgba(232,200,119,.20),rgba(255,255,255,.35));border:1.5px solid rgba(146,118,54,.45);border-radius:14px;padding:14px 16px;margin-bottom:14px}
.bh-icon{width:76px;height:76px;border-radius:50%;box-shadow:0 3px 10px rgba(31,24,8,.30);flex:0 0 auto}
.bh-title{margin:0 0 3px;font-size:22px}
.bh-sub{margin:0 0 8px;font-size:14px;max-width:640px}
.bh-chips{display:flex;gap:8px;flex-wrap:wrap}
.res-chip{background:#fff;border:1.5px solid #cbbf9f;border-radius:999px;padding:4px 12px;font-size:14px;box-shadow:0 1px 3px rgba(31,24,8,.10)}
.furnace{background:linear-gradient(180deg,#fff8ea,#f7ecd4);border:1.5px solid rgba(146,118,54,.5);border-radius:14px;padding:12px 14px;margin-bottom:14px;box-shadow:inset 0 1px 0 #fff}
.furnace-head{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;margin-bottom:6px}
.furnace-title{font-weight:800;font-size:17px}
.bench-panel .melt-filters{border:none;margin:4px 0;padding:0}
.bench-panel .mf-label{font-weight:700;min-width:74px}
.bench-panel .melt-filters select{appearance:none;-webkit-appearance:none;background-color:rgba(255,253,247,.94);background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%23926f22' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 10px center;border:1.5px solid rgba(146,118,54,.55);border-radius:9px;padding:7px 30px 7px 11px;font:inherit;font-size:13.5px;color:var(--ink);cursor:pointer}
.melt-stats{display:flex;align-items:center;gap:14px;margin:10px 0 4px;min-height:44px}
.ms-stat{display:flex;flex-direction:column;align-items:center;background:#fff;border:1.5px solid #cbbf9f;border-radius:10px;padding:5px 18px;box-shadow:0 1px 3px rgba(31,24,8,.10)}
.ms-stat b{font-size:19px;line-height:1.1}
.ms-stat i{font-style:normal;font-size:11px;color:#6b6353;font-weight:600;text-transform:uppercase;letter-spacing:.05em}
.ms-arrow{font-size:19px;color:#926f22}
.ms-none{font-size:14px;color:#6b6353}
.melt-btn{width:100%;padding:11px;font-size:15.5px;margin-top:6px}
.bench-sec-head{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;margin:18px 0 4px}
.bench-sec-head h4{margin:0;font-size:17px}
.bench-cell{display:flex;flex-direction:column;gap:6px}
.bench-craft-btn{width:100%}
.bench-empty{grid-column:1/-1;display:flex;gap:14px;align-items:center;background:rgba(255,255,255,.55);border:1.5px dashed #cbbf9f;border-radius:12px;padding:16px 18px}
.bench-empty .be-icon{font-size:30px}
.bench-empty p{margin:0;font-size:15px}

/* --- Friends overhaul (cmh-v97): hero, sail tiles, captain cards --- */
.friends-hero{display:flex;gap:16px;align-items:center;background:linear-gradient(135deg,rgba(232,200,119,.20),rgba(255,255,255,.35));border:1.5px solid rgba(146,118,54,.45);border-radius:14px;padding:14px 16px;margin-bottom:12px}
.fh-icon{width:76px;height:76px;border-radius:50%;box-shadow:0 3px 10px rgba(31,24,8,.30);flex:0 0 auto}
.fh-title{margin:0 0 3px;font-size:22px}
.fh-tag{margin:0;font-size:14px}
.friend-deck-line{display:flex;align-items:center;gap:12px;background:#fff;border:1.5px solid #cbbf9f;border-radius:12px;padding:8px 12px;margin:0 0 14px;box-shadow:0 1px 4px rgba(31,24,8,.08)}
.friend-deck-line .fdl-art{width:88px;height:60px;object-fit:cover;border-radius:8px;border:1px solid rgba(146,118,54,.5);flex:0 0 auto}
.friend-deck-line .fdl-text{display:flex;flex-direction:column;flex:1;font-size:15px}
.friend-deck-line .fdl-text .fine{font-size:12.5px}
.sail-tiles{display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px;margin:6px 0 4px}
@media (max-width:760px){.sail-tiles{grid-template-columns:1fr}}
.sail-tile{display:flex;flex-direction:column;align-items:stretch;text-align:left;background:#fff;border:1.5px solid #cbbf9f;border-radius:14px;overflow:hidden;padding:0;cursor:pointer;box-shadow:0 2px 6px rgba(31,24,8,.10);transition:transform .12s,box-shadow .12s}
button.sail-tile:hover{transform:translateY(-2px);box-shadow:0 6px 14px rgba(31,24,8,.18)}
.sail-tile .st-art{height:74px;background-size:cover;background-position:center 30%}
.sail-tile .st-body{padding:10px 12px 12px;display:flex;flex-direction:column;gap:2px}
.sail-tile .st-name{font-weight:800;font-size:16px}
.sail-tile .st-sub{font-size:12.5px;color:#6b6353}
.sail-tile.primary{border-color:var(--gold);background:linear-gradient(180deg,#fffdf4,#fdf3d0)}
.join-tile{cursor:default}
.join-tile .friend-add{flex-direction:column;margin:6px 0 0}
.join-tile .friend-add input{width:100%;box-sizing:border-box}
.join-tile .friend-add button{width:100%}
.friends-sec-head{font-size:17px;margin:16px 0 4px}
.friend-card{border-radius:12px;padding:10px 13px;box-shadow:0 1px 4px rgba(31,24,8,.07)}
.friend-card .friend-face,.invite-row .friend-face{border-radius:50%}
.add-friend-block{background:rgba(255,255,255,.5);border:1.5px solid rgba(203,191,159,.8);border-radius:12px;padding:10px 13px;margin:12px 0}
.add-friend-block h4{margin:0 0 2px;font-size:16px}
.add-friend-block .friend-add{margin:8px 0 2px}

/* ---------- desktop scrolling for the collapsed hand strip ----------
   (Jace, Nov 5, 2026) The strip already swipe-scrolls on touch. These
   rules only add mouse affordances: a wrap that anchors ◀ ▶ nudge
   buttons to the strip's own edges, a grab cursor on the strip's empty
   ground, and the buttons themselves — which render ONLY on
   hover-capable fine-pointer devices and only while the strip
   actually overflows (.hand-overflows is toggled from app.js). Touch
   devices never see any of this. */
.hand-strip-wrap{position:relative;flex:1;min-width:0;display:flex}
#my-hand.strip-dragging{cursor:grabbing}
.hand-nudge{display:none;position:absolute;top:50%;transform:translateY(-50%);z-index:6;width:30px;height:46px;padding:0;border-radius:9px;border:1.5px solid var(--gold);background:rgba(13,20,32,.85);color:var(--gold2);font-size:13px;cursor:pointer;align-items:center;justify-content:center}
.hand-nudge:hover{background:rgba(13,20,32,.97)}
.hand-nudge-left{left:2px}
.hand-nudge-right{right:2px}
@media (hover:hover) and (pointer:fine){
  #my-hand{cursor:grab}
  #my-hand .mini-card{cursor:pointer}
  .hand-zone.hand-overflows .hand-nudge{display:flex}
}

/* ============================================================
   IMG-BTN — graphical primary buttons (button overhaul, Nov 5, 2026)
   One family with the home art banners (.art-btn): painterly navy /
   antique-gold art as the face, a left-weighted shade, and the label
   as live HTML text over the art (never baked in). The component is
   safe with a bare text node OR a span.art-label child: isolation +
   ::before at z-index:-1 parks the shade above the art but below
   the text either way, so dynamically-labelled buttons (#btn-primary)
   and textContent-written buttons keep working untouched.
   Per-art rules are compound (.img-btn.art-x) so they outrank the
   .btn.primary gradient shorthand on equal footing by file order.
   ============================================================ */
.img-btn{position:relative;isolation:isolate;overflow:hidden;border:1.5px solid rgba(232,200,119,.75);border-radius:12px;color:#fdf6e0;font-weight:700;letter-spacing:.02em;text-shadow:0 1px 3px rgba(0,0,0,.9),0 0 14px rgba(0,0,0,.55);background-color:#0d1420;background-size:cover;background-position:center right;min-height:56px;display:inline-flex;align-items:center;justify-content:flex-start;padding:10px 16px;text-align:left;transition:filter .15s ease,border-color .15s ease}
.img-btn::before{content:"";position:absolute;inset:0;z-index:-1;background:linear-gradient(90deg,rgba(6,10,18,.78) 0%,rgba(6,10,18,.5) 46%,rgba(6,10,18,.05) 80%);pointer-events:none}
.img-btn:hover{border-color:var(--gold);filter:brightness(1.08);box-shadow:0 3px 12px rgba(0,0,0,.35)}
.img-btn:active{transform:translateY(1px)}
.img-btn:disabled{filter:grayscale(.45) brightness(.68);cursor:default;transform:none}
.img-btn:disabled:hover{border-color:rgba(232,200,119,.75);box-shadow:none}
.img-btn.art-play{background-image:url("assets/banners/btn-play.webp");background-size:cover;background-position:center right}
.img-btn.art-packs{background-image:url("assets/banners/btn-packs.webp");background-size:cover;background-position:center right}
.img-btn.art-phase{background-image:url("assets/buttons/btn-phase.webp");background-size:cover;background-position:center right}
.img-btn.art-allattack{background-image:url("assets/buttons/btn-allattack.webp");background-size:cover;background-position:center right}
.img-btn.art-newdeck{background-image:url("assets/buttons/btn-newdeck.webp");background-size:cover;background-position:center right}
.img-btn.art-editdeck{background-image:url("assets/buttons/btn-editdeck.webp");background-size:cover;background-position:center right}
.img-btn.art-buildforme{background-image:url("assets/buttons/btn-buildforme.webp");background-size:cover;background-position:center right}
.img-btn.art-savedeck{background-image:url("assets/buttons/btn-savedeck.webp");background-size:cover;background-position:center right}
/* slots */
.builder-choice .img-btn{flex:1 1 190px;min-height:66px}
#screen-packs .img-btn{min-width:min(340px,100%);min-height:60px}
.action-dock .img-btn{min-height:46px;padding:8px 14px;font-size:14.5px;width:100%}
/* Play-menu choices (modalChoice actions carrying art spans): the two
   mode buttons become wide mini-banners; Cancel stays a plain ghost. */
#modal-actions .btn:has(.mb-art){position:relative;isolation:isolate;overflow:hidden;flex:1 1 215px;min-height:64px;display:inline-flex;align-items:center;justify-content:flex-start;padding:10px 16px;border:1.5px solid rgba(232,200,119,.75);border-radius:12px;background:#0d1420;color:#fdf6e0;font-weight:700;letter-spacing:.02em;text-align:left;transition:filter .15s ease,border-color .15s ease}
#modal-actions .btn:has(.mb-art):hover{border-color:var(--gold);filter:brightness(1.08);box-shadow:0 3px 12px rgba(0,0,0,.35)}
#modal-actions .mb-art{position:absolute;inset:0;background-size:cover;background-position:center right;pointer-events:none}
#modal-actions .mb-art::after{content:"";position:absolute;inset:0;background:linear-gradient(90deg,rgba(6,10,18,.78) 0%,rgba(6,10,18,.48) 48%,rgba(6,10,18,.04) 82%)}
#modal-actions .mb-label{position:relative;z-index:1;text-shadow:0 1px 3px rgba(0,0,0,.9),0 0 14px rgba(0,0,0,.55)}
/* IMG-BTN addendum: the phase button's target-bar mirror rides at
   compact size on its surface. (The tray mirror died with the tray,
   cmh-v120.) */
#tb-actions .img-btn{min-height:40px;padding:6px 12px;font-size:14px}

/* ============ PACK OPENING — REAL ART THEATRE (pk2, Nov 5, 2026) ====
   The painted-art pack opening (app.js playPackOpening). The stage
   reuses .pack-stage's fixed frame but paints its own backdrop layer
   (.pk2-bg) so the dark can lift in stages while the real results-grid
   cards — raised above the stage — fan, flip and settle by transform
   alone. The old cmh-v41 shape-art rules above (.pack-piece/.pack-seal/
   the gradient .pack-burst) are retired with the old theatre and no
   longer referenced. */
.pack-stage.pk2-stage{background:transparent}
.pk2-bg{position:absolute;inset:0;background:radial-gradient(120% 90% at 50% 42%,rgba(10,14,26,.66),rgba(5,7,13,.88));z-index:0}
.pk2-rays{position:absolute;left:50%;top:46%;width:min(92vmin,660px);aspect-ratio:1;background:url("assets/pack-burst.webp") center/contain no-repeat;opacity:0;pointer-events:none;z-index:1}
.pk2-rays.pk2-cardrays{z-index:1}
.pack-visual.pk2-packwrap{width:min(216px,52vw,44vh);aspect-ratio:700/1174;filter:none;z-index:2}
.pk2-pack{width:100%;display:block;filter:drop-shadow(0 22px 38px rgba(0,0,0,.65))}
.pk2-half{position:absolute;left:0;width:100%;overflow:hidden;pointer-events:none}
.pk2-half img{width:100%;display:block}
.pk2-half-top{top:0;height:33%;clip-path:polygon(0 0,100% 0,100% calc(100% - 7px),93% 100%,86% calc(100% - 7px),78% 100%,70% calc(100% - 7px),62% 100%,54% calc(100% - 7px),46% 100%,38% calc(100% - 7px),30% 100%,22% calc(100% - 7px),14% 100%,7% calc(100% - 7px),0 100%)}
.pk2-half-bot{top:33%;height:67%;clip-path:polygon(0 7px,7% 0,14% 7px,22% 0,30% 7px,38% 0,46% 7px,54% 0,62% 7px,70% 0,78% 7px,86% 0,93% 7px,100% 0,100% 100%,0 100%)}
.pk2-half-bot img{transform:translateY(-33%)}
.pk2-packclip{position:absolute;inset:0;overflow:hidden;border-radius:10px;pointer-events:none}
.pk2-gleam{position:absolute;top:-12%;bottom:-12%;left:0;width:46%;background:linear-gradient(100deg,transparent,rgba(255,244,200,.5) 42%,rgba(255,255,255,.8) 50%,rgba(255,244,200,.5) 58%,transparent);transform:translateX(-140%) skewX(-18deg);opacity:0}
.pk2-sparks{position:absolute;inset:0;pointer-events:none;z-index:3}
.pk2-spark{position:absolute;transform:translate(-50%,-50%);pointer-events:none}
.pk2-hint{position:relative;z-index:2}
.pk2-back{position:absolute;inset:0;border-radius:9px;overflow:hidden;z-index:2}
.pk2-back img{width:100%;height:100%;object-fit:cover;display:block}
.pk2-flip{will-change:transform}
.pack-results.pk2-revealing .mini-card{pointer-events:none}
.pk2-footbar{margin-top:16px;text-align:center}
.pk2-footbar.hidden{display:none}
.pk2-actions{display:flex;gap:10px;justify-content:center;margin-top:8px;flex-wrap:wrap}
@media (prefers-reduced-motion: reduce){
  .pk2-stage{display:none}
}

/* ---- Builder Brain strategy picker + brain blocks (v102) ---- */
.strat-picker{width:100%}
.strat-cap{font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--gold);margin:2px 0 6px;font-weight:bold}
.strat-sugg{display:flex;flex-direction:column;gap:6px}
.strat-row{display:flex;align-items:center;gap:9px;width:100%;text-align:left;cursor:pointer;
  background:linear-gradient(180deg,#fffdf7,#f3ead6);border:1.5px solid #b08d3e;border-radius:10px;
  padding:7px 10px;min-height:46px;font-family:inherit;color:var(--ink);
  transition:transform .12s ease,border-color .12s ease,background .12s ease}
.strat-row:active{transform:translateY(1px)}
.strat-row.sel{border:2px solid var(--gold);background:#fff8e6;transform:translateY(-1px)}
.strat-row.slim{min-height:32px;padding:4px 10px;border-radius:8px}
.strat-bar{flex:0 0 3px;align-self:stretch;border-radius:2px}
.strat-dot{flex:0 0 12px;width:12px;height:12px;border-radius:50%;border:2px solid var(--gold);background:transparent}
.strat-row.sel .strat-dot{background:var(--gold)}
.strat-main{flex:1 1 auto;min-width:0;display:flex;flex-direction:column}
.strat-name{font-size:13.5px;font-weight:bold;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.strat-row.slim .strat-name{font-size:12.5px}
.strat-star{font-style:normal;color:#a07d1c;font-size:10px;letter-spacing:.04em}
.strat-desc{font-size:11px;color:var(--ink2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.strat-pips{flex:0 0 auto;text-align:right;color:var(--gold);font-size:9px;letter-spacing:2px;line-height:1.1}
.strat-pips small{display:block;color:var(--ink2);font-size:9.5px;letter-spacing:.08em;text-transform:uppercase}
.strat-allbar{display:flex;justify-content:space-between;align-items:center;width:100%;margin-top:10px;cursor:pointer;
  background:linear-gradient(180deg,#16233a,#0d1420);color:var(--gold2);border:1.5px solid var(--gold);border-radius:9px;
  padding:8px 12px;font-family:inherit;font-size:13px;font-weight:bold;min-height:34px}
.strat-more{margin-top:8px;background:rgba(13,20,32,.08);border:1px solid #cbb27a;border-radius:9px;padding:8px}
.strat-filter{width:100%;box-sizing:border-box;height:28px;border-radius:7px;border:1px solid #b08d3e;
  background:#fffdf7;padding:4px 9px;font-family:inherit;font-size:12.5px;color:var(--ink);margin-bottom:6px}
.strat-list{max-height:34vh;overflow-y:auto;scrollbar-width:thin;display:flex;flex-direction:column;gap:4px}
.strat-fam{position:sticky;top:0;background:#16233a;color:var(--gold2);font-size:9.5px;letter-spacing:.14em;
  padding:4px 9px;border-radius:5px;font-weight:bold;z-index:1}
.strat-strip{margin-top:10px;background:rgba(13,20,32,.88);border:1.5px solid var(--gold);border-radius:9px;
  color:var(--parch);padding:8px 12px;display:flex;flex-direction:column;gap:2px;min-height:52px;box-sizing:border-box}
.strat-strip b{color:var(--gold2);font-size:13px}
.strat-strip span{font-size:11px;line-height:1.35}
.brain-block{margin-top:10px;border-top:1px dashed #b08d3e;padding-top:8px}
.brain-head{margin-bottom:8px}
/* Optimizer "Tune toward" target row (v103): one slim navy bar in the
   picker's own treatment — the overarching strategy target lives here. */
.tune-row{display:flex;justify-content:space-between;align-items:center;width:100%;cursor:pointer;
  background:linear-gradient(180deg,#16233a,#0d1420);color:var(--parch);border:1.5px solid var(--gold);border-radius:9px;
  padding:7px 12px;font-family:inherit;font-size:12.5px;min-height:34px;margin-bottom:8px;text-align:left}
.tune-row b{color:var(--gold2)}
.tune-row:active{transform:translateY(1px)}
.tune-chev{color:var(--gold2);flex:0 0 auto}

/* ---------- The Annals — lore encyclopedia (cmh-v111) ---------- */
.ann-panel{overflow-y:auto}
.ann-intro{font-size:15.5px;line-height:1.55;color:var(--ink);margin:2px 0 12px}
.ann-search{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:12px}
.ann-search input{flex:1 1 260px;padding:10px 12px;border:1.5px solid var(--ink2);border-radius:8px;background:#fff;font-size:15.5px;font-family:inherit;color:var(--ink)}
.ann-count{font-size:13px;color:var(--ink2);font-style:italic}
.ann-chips{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:12px}
.ann-chips .btn.sel{background:var(--gold2);border-color:#7a5f10;font-weight:bold}
.ann-h{margin:4px 0 6px;font-size:21px}
.ann-group-h{font-size:17px;margin:18px 0 8px;padding-bottom:3px;border-bottom:1.5px solid var(--gold)}
.ann-catblurb{margin:0 0 10px}
.ann-catgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:12px}
.ann-catcard{display:flex;gap:12px;align-items:stretch;text-align:left;background:#fffdf6;border:1.5px solid var(--ink2);border-radius:10px;padding:10px;cursor:pointer;font-family:inherit;color:var(--ink);transition:transform .08s, box-shadow .15s;overflow:hidden}
.ann-catcard:hover{box-shadow:0 3px 12px rgba(0,0,0,.22)}
.ann-catcard:active{transform:scale(.98)}
.ann-catcard-art{width:92px;height:92px;object-fit:cover;border-radius:8px;flex:0 0 auto;border:1px solid var(--gold)}
.ann-catcard-body{display:flex;flex-direction:column;gap:3px;min-width:0;flex:1 1 auto;overflow:hidden}
.ann-catcard-name{font-size:17px;font-weight:bold;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ann-catcard-blurb{font-size:13.5px;line-height:1.4;color:var(--ink2);display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.ann-catcard-count{margin-top:auto;font-size:12.5px;font-weight:bold;color:var(--red);letter-spacing:.03em}
.ann-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:10px}
.ann-tile{display:flex;gap:10px;align-items:center;text-align:left;background:#fffdf6;border:1.5px solid var(--ink2);border-radius:10px;padding:8px;cursor:pointer;font-family:inherit;color:var(--ink);transition:transform .08s, box-shadow .15s;overflow:hidden;min-height:82px}
.ann-tile:hover{box-shadow:0 3px 12px rgba(0,0,0,.22)}
.ann-tile:active{transform:scale(.98)}
.ann-tile-art{width:64px;height:64px;object-fit:cover;border-radius:7px;flex:0 0 auto;border:1px solid var(--gold)}
.ann-tile-body{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1 1 auto;overflow:hidden}
.ann-tile-name{font-size:15.5px;font-weight:bold;line-height:1.25;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.ann-tile-epi{font-size:12.5px;font-style:italic;color:var(--ink2);line-height:1.3;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.ann-tile-cat{font-size:11px;font-weight:bold;letter-spacing:.06em;text-transform:uppercase;color:var(--red);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ann-tile .ann-marks,.ann-catcard .ann-marks{width:64px;height:64px;flex:0 0 auto}
.ann-back{margin-bottom:10px}
.ann-entry{max-width:680px;margin:0 auto}
.ann-hero{width:100%;max-height:320px;object-fit:cover;border-radius:10px;border:2px solid var(--gold);display:block}
.ann-noart{width:100%;height:180px;display:flex;align-items:center;justify-content:center;font-size:44px;background:var(--parch2);border:2px solid var(--gold);border-radius:10px;color:var(--ink2)}
/* cmh-v118 layout fix: in LIST contexts the no-art fallback takes the SAME
   box as real art. The full-panel size on .ann-noart above is the detail
   view's hero treatment only — left unscoped it also matched the tile and
   shelf-card fallbacks (equal specificity, later in the sheet), blowing
   them up to 100%x180px inside the flex row and crushing the text body
   beside them to 0px wide. Scoped rules below win on specificity. */
.ann-tile .ann-noart{width:64px;height:64px;flex:0 0 auto;font-size:22px;border-width:1px;border-radius:7px}
.ann-catcard .ann-noart{width:92px;height:92px;flex:0 0 auto;font-size:30px;border-width:1px;border-radius:8px}
.ann-marks{display:flex;gap:10px;justify-content:center;align-items:center;background:var(--parch2);border:2px solid var(--gold);border-radius:10px;padding:14px 10px;flex-wrap:wrap}
.ann-hero.ann-marks{min-height:150px}
.ann-mark{display:flex;flex-direction:column;align-items:center;gap:4px;font-size:14px;font-weight:bold;color:var(--ink)}
.ann-mark img{width:52px;height:52px;object-fit:contain}
.ann-tile .ann-mark img{width:22px;height:22px}
.ann-tile .ann-mark{font-size:10px;gap:2px}
.ann-tile .ann-marks{padding:6px 4px;gap:5px;border-width:1px}
.ann-name{font-size:30px;margin:14px 0 2px;line-height:1.15}
.ann-epithet{font-style:italic;font-size:16.5px;color:var(--ink2);margin:0 0 4px}
.ann-catline{font-size:12.5px;letter-spacing:.04em;color:var(--ink2);margin:0 0 12px}
.ann-text p{font-size:16.5px;line-height:1.62;color:var(--ink);margin:0 0 12px}
.ann-see{display:flex;gap:8px;flex-wrap:wrap;align-items:center;border-top:1px solid var(--gold);padding-top:12px;margin-top:4px}
.ann-see-label{font-variant:small-caps;letter-spacing:1.5px;font-weight:bold;color:var(--red);font-size:13px}

/* ---------- cmh-v120: reduced motion + Animations-off dampening ----------
   Flights, lunges and shakes are gated in JS (fxLive); what remains
   here is CSS-owned motion: under reduced motion the deal and the
   inspect entry become plain fades, damage numbers fade in place,
   and the fan's spring flattens. */
@keyframes cmhFadeIn{from{opacity:0}to{opacity:1}}
@media (prefers-reduced-motion: reduce){
  .hand .mini-card.deal-in{animation:cmhFadeIn .3s ease backwards}
  #inspect:not(.hidden) .inspect-card,
  #inspect:not(.hidden) .inspect-actions,
  #inspect:not(.hidden) .inspect-extra:not(.hidden),
  #inspect:not(.hidden) #inspect-close{animation:cmhFadeIn .22s ease backwards}
  .float-dmg{animation:cmhFadeIn .3s ease backwards}
  .hand .mini-card{transition-duration:.01s}
  .pile.deep-tick{animation:none}
}
body.anim-off .hand .mini-card.deal-in{animation:none}
body.anim-off .pile.deep-tick{animation:none}
