/* ============================================================
   GAME READABILITY BASELINE (Oct 8, 2026; floor raised Oct 9, 2026)
   Brody: game UI chrome text still hard to read, phones + desktops —
   the 0.8rem floor shipped Oct 8 and he STILL flags text as too small.
   Hard floor: every real text element >= 0.9rem; nav/buttons a
   touch higher. Loaded by every games/*.html page AFTER its
   inline <style> block; the `body` prefix outranks the original
   selectors so these overrides always win. Styles only — no
   game logic touched (kg-3d.js / kg-anim.js untouched).
   The Oct 9 additions below cover page-inline selectors that sat
   between 0.8 and 0.9rem and were never in this sheet.
   ============================================================ */

/* ---------- shared game chrome (multiple pages) ---------- */
body .oc-eyebrow{font-size:.9rem}
body .back-link{font-size:.9rem}
body .footer-copy{font-size:.9rem}
body .nav-item.dropdown .dropdown-toggle::after{font-size:.9rem}
body .nav-item.dropdown .dropdown-menu a{font-size:.9rem}
body .hud-box .lbl{font-size:.9rem;line-height:1.45}
body .btn{font-size:.9rem}
body .btn.small{font-size:.9rem}
body .btn.danger{font-size:.9rem}
body .gbtn{font-size:.9rem}
body .gbtn.small{font-size:.9rem}
body .kbd{font-size:.9rem}

/* ---------- games/cards.html ---------- */
body .pmap-depth{font-size:.9rem}
body .attacker-badge,body .blocker-badge{font-size:.9rem}
body .practice-diff small,body .practice-decksrc small{font-size:.9rem}
body .lane-label{font-size:.9rem}
body .bcreature .debt-tag{font-size:.9rem}
body .pw-indicator{font-size:.9rem}
body .scale-ends{font-size:.9rem}
body .trap-row .tlabel{font-size:.9rem}
body .reward-card .rw-cost{font-size:.9rem}
body .reward-card .rw-text{font-size:.9rem;line-height:1.5}

/* ---------- games/armies.html ---------- */
body #blog:before{font-size:.9rem}
body #legend b{font-size:.9rem}
body #legend{font-size:.9rem}
body .banner small{font-size:.9rem}
body #ucard .uf,body #ucard .usp{font-size:.9rem}
body .mana-line{font-size:.9rem}
body #midbar .omen{font-size:.9rem}
body #ucard .ustats{font-size:.9rem}
body #midbar .turn{font-size:.9rem}
body #blog{font-size:.9rem}
body #midbar .vp{font-size:.9rem}
body #sumList .btn small{font-size:.9rem}
body .fcard small{font-size:.9rem}
body .sect{font-size:.9rem}

/* ---------- games/backs-review.html ---------- */
body .tag{font-size:.9rem}

/* ---------- games/crawler.html ---------- */
body #btn-abl .lbl{font-size:.9rem;letter-spacing:.08em}
body .tbtn .sub{font-size:.9rem;letter-spacing:.1em}
body .navlink{font-size:.9rem}
body .run-stats .stat .k{font-size:.9rem}
body .class-card .role{font-size:.9rem}
body .ledger-table th{font-size:.9rem}
body .hint kbd{font-size:.9rem}
body #keybind-panel kbd{font-size:.9rem}
body #toast .small{font-size:.9rem}
body #hud{font-size:.9rem}
body #topbar .brand{font-size:.9rem}
body .class-card .stats{font-size:.9rem;line-height:1.7}
body #objective{font-size:.9rem}
body .hint{font-size:.9rem;line-height:1.8}
body #keybind-panel{font-size:.9rem}
body .boon p{font-size:.9rem;line-height:1.7}
body #keybind-panel h2.sub{font-size:.9rem}
body #bossbar-wrap .bname{font-size:.9rem}
body .class-card p{font-size:.9rem}
body .boon .cost,body .boon .flavor{font-size:.9rem}

/* ---------- games/crossword.html ---------- */
body .xw-eyebrow{font-size:.9rem}
body .clue-box h3{font-size:.9rem}

/* ---------- games/dice.html ---------- */
body .exact-num small{font-size:.9rem}
body .end-stats span{font-size:.9rem}
body .tell-hint{font-size:.9rem}
body .coach-tip .ct-step{font-size:.9rem}
body .tray-label{font-size:.9rem}
body .chip .cd{font-size:.9rem}
body .stake-note{font-size:.9rem}
body .stats-strip{font-size:.9rem;line-height:1.7}
body .carry-banner{font-size:.9rem}
body .new-best{font-size:.9rem}
body .stranger-name{font-size:.9rem}
body .coach-tip button{font-size:.9rem}
body .help-toggle-btn,body .sound-btn{font-size:.9rem}
body .chip .cp{font-size:.9rem}

/* ---------- games/hall.html ---------- */
body .abtn .key{font-size:.9rem}
body .door .dtag{font-size:.9rem}
body .hbar>span{font-size:.9rem}
body .logcard h4{font-size:.9rem}
body .logcard .petbadge{font-size:.9rem}
body .tbtn{font-size:.9rem}
body #hudrow{font-size:.9rem}
body .door .dname{font-size:.9rem}
body .logtab{font-size:.9rem}
body .logcard{font-size:.9rem;line-height:1.6}
body #toast{font-size:.9rem}

/* ---------- games/index.html ---------- */
body .badge{font-size:.9rem}
body .footer-links a{font-size:.9rem}
body .games-hero .eyebrow{font-size:.9rem}
body .board li.you em{font-size:.9rem}

/* ---------- games/ledger.html ---------- */
body .ing-btn .nm{font-size:.9rem;overflow-wrap:anywhere;line-height:1.35}
body .ing-btn .st{font-size:.9rem}
body .hud-card .lbl{font-size:.9rem}
body .best-card .lbl{font-size:.9rem}
body .modal-card .m-eyebrow{font-size:.9rem}
body .game-title .eyebrow{font-size:.9rem}
body .day-banner .phase{font-size:.9rem}
body .seat .ptype{font-size:.9rem}
body .mode-btn small{font-size:.9rem}
body .seat .order .dname{font-size:.9rem}
body .stock-row .nm small{font-size:.9rem}
body .modal-choices .choice-sub{font-size:.9rem}
body .seat .pname{font-size:.9rem}
body .ledger-log h3{font-size:.9rem}
body .ledger-log li .d{font-size:.9rem}
body .recipe-row .rc{font-size:.9rem}
body .upg-card .pips{font-size:.9rem}
body .upg-card .un{font-size:.9rem}
body .fest-banner{font-size:.9rem}

/* ---------- games/ravens.html ---------- */
body .scry .scry-label{font-size:.9rem}
body .wotr-eyebrow{font-size:.9rem}
body .wotr-hud .stat .lbl{font-size:.9rem}
body .ct-label{font-size:.9rem}
body .answer-zone .az-label{font-size:.9rem}
body .wb-toolhead{font-size:.9rem}
body .hint-btn{font-size:.9rem}
body .astro-note{font-size:.9rem}
body .workbench h3{font-size:.9rem}
body .workbench h4{font-size:.9rem}
body .colhead{font-size:.9rem}
body .wb-row label{font-size:.9rem}
body .wotr-hud{font-size:.9rem}
body .wb-apply{font-size:.9rem}
body .best-badge{font-size:.9rem}
body .freq .fc{font-size:.9rem}
body .stat-line{font-size:.9rem}
body .meta-list .rn{font-size:.9rem}
body details.howto summary{font-size:.9rem}

/* ---------- games/shop.html ---------- */
body .rcard .r-rar,body .rcard .r-new{font-size:.9rem}
body .shop-eyebrow{font-size:.9rem}
body .steps li{font-size:.9rem;line-height:1.7}
body .featured-chip{font-size:.9rem}
body .status{font-size:.9rem}
body .rcard .r-name{font-size:.9rem}

/* ---------- games/siege.html ---------- */
body .ammo small{font-size:.9rem}
body #odbtn{font-size:.9rem}
body .ammo{font-size:.9rem}
body #dlgHint{font-size:.9rem}
body .hud-box{font-size:.9rem}
body .questitem small{font-size:.9rem}
body .shopitem small{font-size:.9rem}

/* ---------- games/tavern.html ---------- */
body .tile .lvl{font-size:.9rem}
body .tile .dmg{font-size:.9rem}
body .chip small{font-size:.9rem}
body .modal .stat .k{font-size:.9rem}
body .panel-h .sub{font-size:.9rem}
body .btn .cost{font-size:.9rem}
body .bc-cost{font-size:.9rem}
body .bc-lock{font-size:.9rem}
body .save-flash{font-size:.9rem}
body .game-back{font-size:.9rem}
body .seg button{font-size:.9rem}
body .panel-h{font-size:.9rem}
body #log-list li .lt{font-size:.9rem}
body .bc-out{font-size:.9rem}
body .ins-sub{font-size:.9rem}
body .q-progress,body .q-reward{font-size:.9rem}
body .syn-note{font-size:.9rem}
body .bc-name{font-size:.9rem}
body .toast{font-size:.9rem}
body .ec-desc,body .ec-bonus,body .ec-penalty{font-size:.9rem}

/* ---------- games/wordsearch.html ---------- */
body .whead .eyebrow{font-size:.9rem}
body .footnote{font-size:.9rem}
body .packbtn{font-size:.9rem}
body #wlist h2{font-size:.9rem}

/* ---------- admin/backs.html ---------- */
body th{font-size:.9rem}
body label{font-size:.9rem}

/* ---------- clamp() minimums that sat below the floor ---------- */
body .screen h2.sub{font-size:clamp(.9rem,2.4vw,1.05rem)}
body #grid .cell{font-size:clamp(.9rem,2.6vw,1.1rem)}
/* crossword clue numerals: superscript-style markers inside 26px cells;
   floor-exempt by design (test allowlist), max raised for legibility */
body .cell .num{font-size:clamp(.55rem,1.6vw,.8rem)}

/* ---------- clipping guards after the size bump ---------- */
/* crawler topbar: brand + 2 navlinks exceed 390px at the new sizes — allow wrap */
body #topbar{flex-wrap:wrap;justify-content:center;row-gap:8px}
/* ledger ingredient names: 5-up grid on phones, let long names wrap */
body .ing-grid{gap:.5rem}

/* ---------- Oct 9, 2026: page-inline selectors below the 0.9rem floor ---------- */
/* cards.html (lobby / bout / map / campaign / practice) */
body #fieldAnnex .annex-sub{font-size:.9rem}
body .hand-card .cost-tag{font-size:.9rem}
body .fixture-mini{font-size:.9rem}
body .shop-buy .btn{font-size:.9rem}
body .shop-info .skind{font-size:.9rem}
body .shop-info span.sdesc{font-size:.9rem}
body .campaign-level .cl-blurb{font-size:.9rem}
body .campaign-level .cl-final-tag{font-size:.9rem}
body .campaign-level .cl-foe{font-size:.9rem}
body .campaign-level .cl-status{font-size:.9rem}
body .rank-badge{font-size:.9rem}
body .rw-sec{font-size:.9rem}
body .rw-tier .rw-quality{font-size:.9rem}
body .practice-note{font-size:.9rem}
/* armies.html */
body #topbar{font-size:.9rem}
body #midbar{font-size:.9rem}
body #cmdbar .btn{font-size:.9rem}
body #dlgName{font-size:.9rem}
body .banner .fn{font-size:.9rem}
body #ucard .un{font-size:.9rem}
body #banner .sub{font-size:.9rem}
body .toastmsg{font-size:.9rem}
/* crawler.html / hall.html / tavern.html / ledger.html / dice.html / ravens.html / siege.html */
body #log-list{font-size:.9rem}
body #tutOverlay .tut-steps{font-size:.9rem}
body .back-card p.desc{font-size:.9rem}
body .chip .cn{font-size:.9rem}
body .cs-beat{font-size:.9rem}
body .cs-hint{font-size:.9rem}
body .door .dthreat{font-size:.9rem}
body .end-stats div{font-size:.9rem}
body .explainer li::before{font-size:.9rem}
body .freq{font-size:.9rem}
body .ibtn{font-size:.9rem}
body .icon-btn{font-size:.9rem}
body .ins-desc{font-size:.9rem}
body .ins-hint{font-size:.9rem}
body .ins-stat{font-size:.9rem}
body .kb-key.wide{font-size:.9rem}
body .ledger-log ol{font-size:.9rem}
body .ledger-table td{font-size:.9rem}
body .meta{font-size:.9rem}
body .mix-hint{font-size:.9rem}
body .note{font-size:.9rem}
body .odds-label{font-size:.9rem}
body .odds-note{font-size:.9rem}
body .panel .dim{font-size:.9rem}
body .q-box{font-size:.9rem}
body .quest{font-size:.9rem}
body .recipe-row .rp{font-size:.9rem}
body .score-line{font-size:.9rem}
body .screen p.lore{font-size:.9rem}
body .shaker .ph{font-size:.9rem}
body .tab{font-size:.9rem}
body .tally{font-size:.9rem}
body .tile{font-size:.9rem}
body .tray-label .sum-badge{font-size:.9rem}
body .upg-card .ud{font-size:.9rem}
body .wager-hint{font-size:.9rem}
body .wb-grid{font-size:.9rem}
body .wstats{font-size:.9rem}
body .xw-meta{font-size:.9rem}
/* shop.html / crossword.html / wordsearch.html / index.html / backs-review.html */
body #priorityLog{font-size:.9rem}
body .boards-cta{font-size:.9rem}
body .city-sub{font-size:.9rem}
body .cu-cap{font-size:.9rem}
body .custom-opt{font-size:.9rem}
body .ec-name{font-size:.9rem}
body .foot-note{font-size:.9rem}
body .internal{font-size:.9rem}
body .mock-box{font-size:.9rem}
body .mock-btn{font-size:.9rem}
body .mock-check{font-size:.9rem}
body .modal-content .payout-table{font-size:.9rem}
body .offline-gains .chip{font-size:.9rem}
body .shop-stats{font-size:.9rem}

/* ---------- clipping guards after the 0.9rem bump (Oct 9, 2026) ---------- */
/* cards.html back-shelf shop: buy buttons grew; let the info side shrink/wrap */
body .shop-row{flex-wrap:wrap}
body .shop-info{min-width:0;flex:1 1 200px}
body .shop-info b{overflow-wrap:anywhere}
body .shop-buy .btn{white-space:nowrap}
/* armies.html command bar: absolutely centered; never wider than the viewport */
body #cmdbar{flex-wrap:wrap;justify-content:center;max-width:96vw}
/* crawler/hall/tavern shared footer link rows already wrap; keep the 390px
   ledger seat rows from clipping long names */
body .seat .pname{overflow-wrap:anywhere}

/* ============================================================
   Oct 9, 2026 — SHARED INTERACTIVE-STATE BASELINE (Crew D:
   clickable-UI polish pass). Loaded AFTER every page's inline
   <style>; the `body` prefix outranks the original selectors so
   these affordance rules always win. Styles only — no game logic.
   Every games page (except bts.html, which carries the same block
   in bts.css) inherits:
     1. clear hover states on clickables (glow/lift/color shift)
     2. visible :active press feedback
     3. cursor:pointer + touch-action:manipulation (no 300ms tap delay)
     4. a visible :focus-visible ring for keyboard navigation.
        Existing outline:none REPLACEMENTS are higher-specificity
        and keep winning — the ring only covers what has none.
     5. disabled controls that look disabled
     6. canonical .btn-primary / .btn-secondary / .btn-danger
        hierarchy in the dark-tavern aesthetic (compose with the
        page's .btn base; colors only, geometry stays page-local)
     7. >=44px touch targets on the shared nav chrome
   ============================================================ */

/* ---------- clickables: pointer cursor + instant tap ---------- */
body button, body input[type="button"], body input[type="submit"],
body [role="button"], body summary { cursor: pointer; touch-action: manipulation; }
body a { touch-action: manipulation; }

/* ---------- press feedback (transient; pages' own :active rules keep priority where stronger) ---------- */
body button:not(:disabled):active,
body input[type="button"]:not(:disabled):active,
body input[type="submit"]:not(:disabled):active,
body [role="button"]:not([aria-disabled="true"]):active { transform: scale(0.97); }

/* ---------- keyboard focus: always a visible ring ---------- */
body :focus-visible { outline: 2px solid var(--gold-lt, #e8b34b); outline-offset: 2px; }

/* ---------- disabled reads as disabled ---------- */
body button:disabled, body input:disabled,
body [aria-disabled="true"] { cursor: not-allowed; }

/* ---------- button hierarchy: primary / secondary / danger ---------- */
body .btn-primary { background: linear-gradient(180deg, var(--gold-lt, #e8b34b), var(--gold, #c4902a));
  border: 1px solid rgba(230,176,64,0.6); color: #140e02;
  min-height: 44px; cursor: pointer; touch-action: manipulation; text-decoration: none;
  transition: filter 0.15s ease, box-shadow 0.15s ease, transform 0.1s ease; }
body .btn-primary:hover:not(:disabled):not([aria-disabled="true"]) {
  filter: brightness(1.12); box-shadow: 0 4px 26px rgba(255,191,0,0.5); transform: translateY(-1px); }
body .btn-primary:active:not(:disabled):not([aria-disabled="true"]) { transform: scale(0.97); }
body .btn-primary:disabled, body .btn-primary[aria-disabled="true"] { opacity: 0.4; cursor: not-allowed; }

body .btn-secondary { background: rgba(196,144,42,0.08);
  border: 1px solid rgba(196,144,42,0.35); color: var(--gold-lt, #e8b34b);
  min-height: 44px; cursor: pointer; touch-action: manipulation; text-decoration: none;
  transition: filter 0.15s ease, box-shadow 0.15s ease, transform 0.1s ease, background 0.15s ease; }
body .btn-secondary:hover:not(:disabled):not([aria-disabled="true"]) {
  background: rgba(196,144,42,0.18); border-color: var(--gold-lt, #e8b34b);
  box-shadow: 0 0 16px rgba(196,144,42,0.3); transform: translateY(-1px); }
body .btn-secondary:active:not(:disabled):not([aria-disabled="true"]) { transform: scale(0.97); }
body .btn-secondary:disabled, body .btn-secondary[aria-disabled="true"] { opacity: 0.4; cursor: not-allowed; }

body .btn-danger { background: linear-gradient(180deg, #a02323, #5f1010);
  border: 1px solid rgba(255,120,90,0.45); color: #ffe9e9;
  min-height: 44px; cursor: pointer; touch-action: manipulation; text-decoration: none;
  transition: filter 0.15s ease, box-shadow 0.15s ease, transform 0.1s ease; }
body .btn-danger:hover:not(:disabled):not([aria-disabled="true"]) {
  filter: brightness(1.2); box-shadow: 0 4px 22px rgba(200,40,30,0.5); transform: translateY(-1px); }
body .btn-danger:active:not(:disabled):not([aria-disabled="true"]) { transform: scale(0.97); }
body .btn-danger:disabled, body .btn-danger[aria-disabled="true"] { opacity: 0.4; cursor: not-allowed; }

/* ---------- shared nav chrome: >=44px touch targets (cards.html pattern) ---------- */
body .nav-toggle { min-width: 44px; min-height: 44px; align-items: center; justify-content: center; }
body .nav-toggle:hover span { background: var(--amber-lt, #ffd97a); }
body .oc-close { width: 44px; height: 44px; }

/* ============================================================
   Oct 9, 2026 — CREW 2: GAME-FEEL / FUN FACTOR
   Hit feedback, turn beats, "what just happened" feed strip,
   win/lose drama, SFX volume slider. Styles only — the wiring
   lives in games/kg-anim.js (already loaded by cards.html).
   The `body` prefix keeps these winning over page-inline rules.
   ============================================================ */

/* ---------- turn banner sweep (KGAnim.turnBanner) ---------- */
body #kgTurnBanner{position:fixed;top:16%;left:0;right:0;z-index:3950;pointer-events:none;
  text-align:center;opacity:0;transform:translateY(-18px) scale(.96);
  transition:opacity .28s ease,transform .34s cubic-bezier(.2,1.4,.4,1);}
body #kgTurnBanner.show{opacity:1;transform:none;}
body #kgTurnBanner .kg-tb-eyebrow{display:block;font:600 .9rem Georgia,serif;letter-spacing:.34em;
  text-transform:uppercase;color:#c9a86a;margin-bottom:6px;text-shadow:0 2px 8px #000;}
body #kgTurnBanner .kg-tb-title{display:block;font:800 2rem Georgia,serif;letter-spacing:.18em;
  text-shadow:0 3px 18px #000,0 0 34px rgba(0,0,0,.7);}
body #kgTurnBanner.kg-tb-you .kg-tb-title{color:#ffd97a;text-shadow:0 3px 18px #000,0 0 44px rgba(255,200,90,.55);}
body #kgTurnBanner.kg-tb-foe .kg-tb-title{color:#9adfff;text-shadow:0 3px 18px #000,0 0 44px rgba(120,200,255,.5);}
body #kgTurnBanner.kg-tb-combat .kg-tb-title{color:#ff9d6a;text-shadow:0 3px 18px #000,0 0 44px rgba(255,120,60,.55);}

/* ---------- "what just happened" strip (mirrors newest log row) ---------- */
body #kgLastBeat{max-height:0;overflow:hidden;opacity:0;
  transition:max-height .3s ease,opacity .3s ease,margin .3s ease,border-color .3s ease;
  margin:0;border-left:3px solid transparent;padding:0 10px;}
body #kgLastBeat.show{max-height:4.5em;opacity:1;margin:6px 0;
  border-left-color:rgba(255,210,110,.85);background:rgba(20,12,6,.72);border-radius:0 8px 8px 0;}
body #kgLastBeat > div{font-size:.95rem;line-height:1.5;color:#f0e2c4;padding:6px 0;}

/* ---------- new log-row spotlight ---------- */
body #battleLog > div.kg-new{animation:kgNewRow 2.6s ease both;}
@keyframes kgNewRow{0%{background:rgba(255,210,110,.22);box-shadow:inset 0 0 0 1px rgba(255,210,110,.5);}
  70%{background:rgba(255,210,110,.06);}100%{background:transparent;box-shadow:none;}}

/* ---------- hit feedback ---------- */
body .kg-hitflash{position:absolute;inset:0;pointer-events:none;border-radius:6px;
  background:radial-gradient(ellipse at center,rgba(255,246,220,.75),rgba(255,240,210,.15) 65%,transparent 80%);
  animation:kgFlash .24s ease-out both;}
@keyframes kgFlash{0%{opacity:1;}100%{opacity:0;}}
body .dmg-num.kg-big{font-size:2.1rem;font-weight:800;color:#ff5a4a;
  text-shadow:0 2px 10px #000,0 0 22px rgba(255,60,40,.8);}
body .dmg-num.kg-tabnum{font-size:1.5rem;font-weight:800;}
body .dmg-num.kg-tab-bad{color:#ff6a5a;text-shadow:0 2px 8px #000,0 0 18px rgba(255,60,40,.7);}
body .dmg-num.kg-tab-good{color:#ffd97a;text-shadow:0 2px 8px #000,0 0 18px rgba(255,200,90,.7);}

/* board-wide shake (JS toggles .kg-shake / .kg-shake-hard, then removes) */
body .kg-shake{animation:kgShake .38s linear;}
body .kg-shake-hard{animation:kgShakeHard .45s linear;}
@keyframes kgShake{0%,100%{transform:translate(0,0);}20%{transform:translate(-5px,2px);}
  40%{transform:translate(4px,-3px);}60%{transform:translate(-3px,-2px);}80%{transform:translate(3px,2px);}}
@keyframes kgShakeHard{0%,100%{transform:translate(0,0);}15%{transform:translate(-9px,4px);}
  30%{transform:translate(8px,-5px);}45%{transform:translate(-6px,-4px);}60%{transform:translate(6px,4px);}
  75%{transform:translate(-4px,2px);}90%{transform:translate(3px,-2px);}}

/* ---------- win / lose title drama (dressed onto #resultTitle) ---------- */
body #resultTitle.kg-win{animation:kgWinPulse 1.6s ease-in-out 3;color:#ffd97a !important;
  text-shadow:0 0 34px rgba(255,200,90,.8),0 3px 12px #000 !important;}
body #resultTitle.kg-lose{animation:kgLosePulse 2s ease-in-out 2;color:#ff6a5a !important;
  text-shadow:0 0 30px rgba(180,30,20,.85),0 3px 12px #000 !important;}
@keyframes kgWinPulse{0%,100%{transform:scale(1);}50%{transform:scale(1.06);}}
@keyframes kgLosePulse{0%,100%{transform:scale(1);opacity:1;}50%{transform:scale(.985);opacity:.82;}}

/* ---------- SFX volume slider (injected next to #soundBtn) ---------- */
body .kg-sfxvol-wrap{display:inline-flex;align-items:center;gap:6px;margin-left:8px;vertical-align:middle;}
body .kg-sfxvol-lab{font-size:.9rem;opacity:.85;}
body #kgSfxVol{width:84px;accent-color:#c4902a;cursor:pointer;}

/* ---------- UX sweep (Oct 11 2026): six selectors that sat below the floor ---------- */
body .play-card .pc-sub{font-size:.9rem}
body .rw-cur{font-size:.9rem}
body .xcp-roadmap-label{font-size:.9rem}
body .xcp-roadmap-hint{font-size:.9rem}
body .reward-card.picked::after{font-size:.9rem}
body .card-tile.just-claimed .new-god-badge{font-size:.9rem}

/* ---------- TRACK 4 FEEL (Oct 11 2026): impact pop, screen blinks, result rise, ash wisps ---------- */
/* impact pop: the struck target thumps (scale 1 → 1.06 → 1, 160ms).
   Class-based so it never fights the tween engine's inline transforms. */
body .kg-impact-pop{animation:kgImpactPop .16s ease-out;}
@keyframes kgImpactPop{0%{transform:scale(1);}35%{transform:scale(1.06);}100%{transform:scale(1);}}
/* screen transitions (showOnly): outgoing screen fades out 180ms, the
   incoming one breathes in 240ms — a soft blink between tavern rooms. */
body .kg-screen-out{transition:opacity .18s ease;opacity:0;}
body .kg-screen-in{animation:kgScreenIn .24s ease-out;}
@keyframes kgScreenIn{0%{opacity:0;}100%{opacity:1;}}
/* result card entrance: rises into view instead of popping (260ms). */
body .end-card.kg-result-in{animation:kgResultIn .26s cubic-bezier(.2,.9,.3,1.15);}
@keyframes kgResultIn{0%{opacity:0;transform:translateY(14px) scale(.98);}
  100%{opacity:1;transform:translateY(0) scale(1);}}
/* ash wisp: a spent card drifting to the ash pile (motion driven by kg-anim.js) */
body .kg-ashwisp{position:absolute;transform:translate(-50%,-50%);z-index:3950;pointer-events:none;
  color:#cfc4b4;font:600 12px Georgia,serif;text-shadow:0 1px 6px #000;white-space:nowrap;
  background:rgba(20,14,8,.85);border:1px solid rgba(196,144,42,.4);border-radius:6px;padding:3px 8px;}

/* ---------- reduced motion: feel collapses to instant cuts ---------- */
@media (prefers-reduced-motion: reduce){
  body #kgTurnBanner{display:none;}
  body #battleLog > div.kg-new{animation:none;}
  body .kg-hitflash{animation:none;opacity:0;}
  body .kg-shake,body .kg-shake-hard{animation:none;}
  body #resultTitle.kg-win,body #resultTitle.kg-lose{animation:none;}
  body .kg-impact-pop{animation:none;}
  body .kg-screen-out{transition:none;opacity:1;}
  body .kg-screen-in{animation:none;}
  body .end-card.kg-result-in{animation:none;}
  body .kg-ashwisp{display:none;}
}

/* ============================================================
   Oct 12, 2026 — LIVE-BUG READABILITY (Brody, deck-builder screenshot):
   "everything is hard to read" — grid card rules text ~11-12px
   effective, unowned collection cards dimmed to near-illegible.
   Card faces are canvas-drawn in a 300x420 design space, so the
   effective text size scales with TILE width: at the old 170px
   tiles the 19px rules font rendered at ~10.8px. These fixes are
   layout + contrast only — the canvas text floors (pinned in
   tests/test-readability.mjs) and inspect/zoom are untouched.
   ============================================================ */
/* Wider tiles on desktop-class viewports: the whole face scales up.
   (Oct 13 2026: floor raised 208→240px — see the correction block
   below; at 900–1199px viewports tiles land ~273–311px, rules text
   ~17–20px effective.) Phones keep the two-column 170px grid (a 240px
   minimum would collapse them to one giant column). */
@media (min-width: 900px){
  body .card-grid{grid-template-columns:repeat(auto-fill,minmax(240px,1fr))}
}
/* Unowned dimming floor raised: still unmistakably not-yours (dimmed,
   slightly desaturated, "not owned" badge), but the face — name and
   rules text included — stays legible instead of sinking into the
   page background at the old 0.55 opacity. */
body .card-tile.unowned{opacity:.8;filter:saturate(.85)}
body .card-tile .own-count.not-owned{color:#d8cdea;border-color:rgba(196,144,42,.65)}

/* ============================================================
   Oct 13, 2026 — COLLECTION READABILITY, CORRECTED DIRECTION
   (Brody, live): "the default view text needs improved — it's
   blurry pixelated and needs clarity" + "no we already have the
   magnifier." So: NO new detail view (an inspect-extension draft
   was built and fully reverted the same day — the existing 🔍
   inspect is untouched), and size alone was not the defect. The
   grid itself had to become readable at a glance AND sharp:
   (1) DEFAULT tiles step up hard (below) — the default Brody
       lands on is the reading size; S density is the opt-in for
       people who want browsing density, never the default.
   (2) CLARITY: tiles are canvas renders. Measured by executing
       the renderer: first paint backs at 600×840, portrait repaint
       at 1200×1680, displayed at ~213 CSS px — never undersized,
       but the browser resamples that backing by a fractional
       factor, smearing the thin serif strokes (the crisp DOM
       badges beside them made it obvious). cards.html now re-draws
       each tile once at EXACTLY cssWidth × devicePixelRatio
       (kgSharpenGridCanvases) so tiles present 1:1, resample-free.
   Effective rules size = 19px design × tile/300, at the DEFAULT:
     ≥900px  → 240px min (tiles ~273–311px → rules ~17.3–19.7px)
     ≥1200px → 264px min (1200: 4 cols ≈276px → ~17.5px;
               1440: 5 cols ≈266px → ~16.9px)
     ≥1600px → 288px min (1600/1920: 5 cols ≈298px → ~18.9px,
               flavor ~16.9px)
   Phones (<900px) unchanged: 2 cols × ~172px — the widest tiles
   the screen allows at 2 columns; density L gives one full-width
   ~358px column (~22.7px rules) on demand.
   ============================================================ */
@media (min-width: 1200px){
  body .card-grid{grid-template-columns:repeat(auto-fill,minmax(264px,1fr))}
}
@media (min-width: 1600px){
  body .card-grid{grid-template-columns:repeat(auto-fill,minmax(288px,1fr))}
}
/* density preference: ID-scoped so it outranks every default above */
body #kg-lobby[data-density="S"] .card-grid{grid-template-columns:repeat(auto-fill,minmax(150px,1fr))}
body #kg-lobby[data-density="L"] .card-grid{grid-template-columns:repeat(auto-fill,minmax(250px,1fr))}
@media (min-width: 900px){
  body #kg-lobby[data-density="L"] .card-grid{grid-template-columns:repeat(auto-fill,minmax(320px,1fr))}
}
