/* Base: reset, screens, text, buttons, panels. Spacing uses the 4pt tokens, corners use the three radii. */
*{box-sizing:border-box}
html,body{height:100%;margin:0}
body{font-family:var(--font-ui);font-weight:500;color:var(--ink);background:var(--app-bg);overflow:hidden;touch-action:manipulation;user-select:none;-webkit-user-select:none;-webkit-tap-highlight-color:transparent;-webkit-text-size-adjust:100%;line-height:1.35}
button{font-family:inherit;color:inherit;cursor:pointer}
button:focus-visible,input:focus-visible,.trace-cv:focus-visible{outline:4px solid var(--focus);outline-offset:3px;box-shadow:0 0 0 8px var(--focus-halo)}
[tabindex="-1"]:focus{outline:none} /* headings show() focuses for screen readers; not a tap target */
[hidden]{display:none !important}
input{user-select:text;-webkit-user-select:text}
img{-webkit-touch-callout:none} /* a long press on a picture must not open the save-image sheet */
::selection{background:rgba(255,143,179,.4)}
#app{position:relative;height:100%;width:100%;overflow:hidden;background:var(--app-bg)}
#app::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:1;background:radial-gradient(120% 90% at 50% 40%,transparent 60%,rgb(var(--shade)/.16))}
/* paper grain over the painted scene, under the screens. The noise is baked dark (black, alpha = (1 - red) / 2) so it needs no
   mix-blend-mode, which forced a full-screen blend group; at .05 it measures as the old multiply grain did (mean and spread within 0.1 of a level) */
#app::before{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;opacity:.05;background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -.5 0 0 0 .5'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")}
.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .stitched::before{border-color:rgba(255,255,255,.18)}}
#confetti{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:15;visibility:hidden}
#confetti.on{visibility:visible} /* fx.js sets .on only while particles fly, so an idle screen keeps no full-screen canvas layer */
body[data-screen="s-result"] #confetti{z-index:1} /* on the result the confetti falls behind the card, so it never covers the explorer */

/* ===== screens ===== */
.screen{position:absolute;inset:0;z-index:2;display:none;flex-direction:column;overflow-y:auto;overflow-x:hidden;padding-block:max(var(--s4),env(safe-area-inset-top)) max(var(--s4),env(safe-area-inset-bottom));padding-inline:var(--gutter);-webkit-overflow-scrolling:touch}
.screen.active{display:flex;animation:pageIn var(--t-ui) var(--ease-out)}
@keyframes pageIn{from{opacity:0;transform:translateY(10px)}}
.center{margin:auto;width:100%;max-width:980px;display:flex;flex-direction:column;align-items:center;gap:var(--s4)}

/* ===== text ===== */
.bi{display:inline-flex;flex-direction:column;align-items:center;line-height:1.15;text-align:center}
.bi .ar{font-size:1.1em;font-weight:700}
.bi .en{font-size:max(.8em,.875rem);font-weight:600;color:var(--ink-2)}
.bi.start{align-items:flex-start;text-align:start}
/* one language at a time (applyLang in data.js): the other half is not shown or read, and the English half takes the main size and ink */
:root[data-lang="ar"] .bi>.en,:root[data-lang="en"] .bi>.ar{display:none}
:root[data-lang="en"] .bi>.en{font-size:1em;font-weight:700;color:inherit;opacity:1}
/* mirrored for Arabic: arrows that mean "back" point the reading way; LTR islands (boards, equations, the duel) keep theirs */
img[src$="/back.webp"]:dir(rtl){scale:-1 1}
h1,h2,h3{font-family:var(--font-display);font-weight:400;margin:0}

/* ===== buttons ===== */
.btn{--c:var(--sun);--cd:var(--sun-d);display:inline-flex;align-items:center;justify-content:center;gap:var(--s3);min-height:64px;padding:var(--s3) var(--s6);border:0;border-radius:var(--r-pill);font-family:var(--font-display);font-size:var(--fs-lg);color:var(--on-c);background:linear-gradient(180deg,var(--sheen,rgba(255,255,255,.42)),rgba(255,255,255,0) 54%),var(--c);box-shadow:var(--bevel),0 12px 18px -10px var(--cd),0 2px 4px rgb(var(--shade)/.16);transition:transform var(--t-fast) var(--ease-out),box-shadow var(--t-fast) var(--ease-out)}
.btn .bi .en{color:inherit;opacity:.8}
.btn:active{transform:translateY(2px) scale(.98);box-shadow:inset 0 -2px 0 rgb(var(--shade)/.16),inset 0 2px 0 rgba(255,255,255,var(--hi)),var(--sh-press)}
.btn.blue{--c:var(--sky);--cd:var(--sky-d)}
.btn.blue .bi .en{opacity:1}
.btn.ghost{--c:var(--paper);--cd:rgb(var(--shade)/.5);--sheen:rgba(255,255,255,0);color:var(--ink)}
.btn.big{min-height:84px;padding-inline:var(--s7);font-size:var(--fs-xl)}
.btn.small{min-height:56px;padding:var(--s2) var(--s5);font-size:var(--fs-md)}
.btn .ic{width:1.3em;height:1.3em}
.btn.pulse{animation:pulse var(--t-loop) ease-in-out 4} /* an oscillation breathes on both halves */
@keyframes pulse{50%{scale:1.05}}
.icon-btn{border:0;width:var(--tap);height:var(--tap);border-radius:50%;display:inline-flex;align-items:center;justify-content:center;flex:none;background:var(--paper);color:var(--ink);box-shadow:var(--sh-1);transition:transform var(--t-fast) var(--ease-out)}
.icon-btn:active{transform:scale(.94)}
.icon-btn .ic{width:28px;height:28px}
.icon-btn.small .ic{width:26px;height:26px}
.pill{display:inline-flex;align-items:center;gap:var(--s2);min-height:48px;padding:var(--s2) var(--s4);border:0;border-radius:var(--r-pill);background:var(--paper);color:var(--ink);font-weight:700;box-shadow:var(--sh-1);font-variant-numeric:tabular-nums}
.pill.as-btn{cursor:pointer;min-height:var(--tap);min-width:var(--tap);justify-content:center}
.chip{display:inline-flex;align-items:center;gap:var(--s1);font-weight:700;font-variant-numeric:tabular-nums;background:var(--paper-2);border-radius:var(--r-pill);padding:2px var(--s3)}
:is(.btn,.icon-btn,.pill.as-btn,.chip-btn,.mode-card,.who,.prof,.badge-btn,.land,.gcard,.level,.item,.chr-pick):active{transition-duration:var(--t-fast)}

/* ===== icons ===== */
.ic{width:1.15em;height:1.15em;flex:none;vertical-align:-.2em} /* the icon box; the picture inside is a 3D .ui3d image */
/* ===== 3D art (art.js): emoji items, game glyphs, UI icons ===== */
/* an emoji's item takes the box the emoji had: its height follows the font-size, its width the image's own ratio */
.it{display:inline-block;height:1.15em;width:auto;vertical-align:-.2em;object-fit:contain;pointer-events:none}
:is(.it,.gi,.ui3d){object-fit:contain;pointer-events:none}
.gi{width:72%;height:72%} /* a glyph fills most of whatever round holder it sits in */
/* a UI icon keeps the .ic box it replaced; the drop keeps a pale icon readable on paper */
.ui3d{filter:var(--art-drop)}
.btn .ui3d{width:1.6em;height:1.6em;margin-block:-.2em}
.icon-btn .ui3d{width:38px;height:38px}
.icon-btn.small .ui3d{width:34px;height:34px}
.pill .ui3d,.chip .ui3d{width:1.5em;height:1.5em}
/* earned and unearned stars differ in size and colour, not colour alone */
.ui3d.off,.bigstars .ui3d:not(.on){filter:grayscale(1) opacity(.45);scale:.8}
.badge{--bc:var(--sky);flex:none;display:inline-flex;align-items:center;justify-content:center;width:64px;height:64px;border-radius:50%;background:var(--enamel),var(--bc);box-shadow:var(--bevel),var(--ring-in),0 8px 12px -6px rgb(var(--shade)/.5)}
.badge.sm{width:40px;height:40px;box-shadow:var(--bevel-sm),inset 0 0 0 2px rgba(255,255,255,.7),0 4px 8px -4px rgb(var(--shade)/.5)}
[aria-disabled="true"] .badge{background:var(--enamel),#7d79a6} /* background, not --bc: gameBadge sets --bc inline */
.badge.lg{width:84px;height:84px}
/* the 3D icon stands on the enamel disc and rises past its top edge, so the disc reads as a plinth */
.badge .gi{width:92%;height:92%;translate:0 -14%;filter:var(--art-drop)}
[aria-disabled="true"] .badge .gi{filter:grayscale(1) opacity(.55)}

/* ===== modals, toast ===== */
.modal{position:absolute;inset:0;z-index:20;display:none;align-items:center;justify-content:center;padding:var(--s4);background:rgba(30,28,60,.55)}
.modal.open{display:flex;animation:fade var(--t-ui) var(--ease-out)}
@keyframes fade{from{opacity:0}}
.panel{width:100%;max-width:560px;max-height:92%;overflow:auto;display:flex;flex-direction:column;align-items:center;gap:var(--s4);padding:var(--s5);background:var(--paper);border-radius:var(--r-lg);box-shadow:var(--sh-2);animation:pageIn var(--t-ui) var(--ease-out)}
.panel h3{font-size:var(--fs-lg);text-align:center}
#lv-title{display:flex;align-items:center;justify-content:center;gap:var(--s3)}
#m-gate{z-index:30}#m-break{z-index:25}#m-leave{z-index:22}
/* centred with translate so transform stays free for the entrance; modal.js toggles .show and plays the exit */
.toast{position:absolute;left:50%;translate:-50% 0;bottom:max(var(--s5),env(safe-area-inset-bottom));z-index:40;max-width:min(92vw,520px);padding:var(--s3) var(--s5);border-radius:var(--r-pill);background:var(--ink);color:var(--paper);box-shadow:var(--sh-2);text-align:center;opacity:0;visibility:hidden;pointer-events:none}
.toast.show{opacity:1;visibility:visible;animation:toastIn var(--t-ui) var(--ease-out)}
@keyframes toastIn{from{opacity:0;transform:translateY(12px) scale(.97)}}
.toast .bi .en{color:inherit;opacity:.8}

/* ===== reduced motion: fewer and gentler, not none ===== */
@media (prefers-reduced-motion:reduce){
  *,::before,::after{animation-duration:.001s !important;animation-delay:0s !important;animation-iteration-count:1 !important;transition-duration:.001s !important}
  .screen.active,.panel,.modal.open{animation:fade var(--t-fast) linear !important}
}
