/* The Capsule opening (src/ui/capsule.js, its 3D src/graphics/capsule.js): a full-window dialog over everything, its
   own canvas under crisp HTML (the title, the throw button, the reward card, the buttons). The tier's colours are
   --capC (the shell), --capG (its glow) and --capD (deep) by [data-tier]; before the server answers it is neutral.
   States by [data-state] (loading, ready, toss, land, break, reveal, settled, error), the timeline's beats by
   [data-phase] (appear, throw, land, break, burst, beat, card, settle, fade, done). Flashes are single, small and capped
   (no rapid full-screen flashing); .reduced and prefers-reduced-motion drop the beats and keep the cross-fade. */
.capOv{--capC:#9aa6c8;--capG:#c8d2f0;--capD:#1b2347;position:fixed;inset:0;z-index:90;overflow:hidden;display:block;color:var(--fg,#e8ecff);font-family:var(--body,'Barlow',system-ui,sans-serif);
  background:radial-gradient(ellipse 70% 55% at 50% 64%,color-mix(in srgb,var(--capD) 70%,transparent),transparent 70%),radial-gradient(ellipse at 50% 120%,#0d1330,#03050c 70%);
  touch-action:manipulation;-webkit-tap-highlight-color:transparent;user-select:none;-webkit-user-select:none;outline:none;animation:capOvIn .25s ease-out both}
.capOv[data-tier=standard]{--capC:#e6ecf6;--capG:#d8e6ff;--capD:#2a3552}
.capOv[data-tier=rare]{--capC:#38e4ff;--capG:#8cf5ff;--capD:#073a66}
.capOv[data-tier=epic]{--capC:#b47aff;--capG:#dcb8ff;--capD:#2f1366}
.capOv[data-tier=legendary]{--capC:#ffb43a;--capG:#ffe07a;--capD:#5a2604}
.capOv[hidden]{display:none}
@keyframes capOvIn{from{opacity:0}to{opacity:1}}
/* the 3D, under everything */
.capOv .capStage{position:absolute;inset:0;transition:opacity .45s ease,filter .45s ease}
.capOv .capStage canvas{position:absolute;inset:0;display:block;width:100%;height:100%}
.capOv[data-state=settled] .capStage{opacity:.55;filter:saturate(.9)}
.capOv[data-phase=fade] .capStage,.capOv[data-phase=fade] .capCss{opacity:0}
/* the title row: Back at the top left (hub.css .hubBack), the tier in the middle, Skip at the right */
.capOv .capHead{position:absolute;top:calc(1rem + env(safe-area-inset-top,0px));left:50%;transform:translateX(-50%);z-index:3;display:flex;flex-direction:column;align-items:center;gap:.15rem;max-width:calc(100% - 15rem);text-align:center;pointer-events:none}
.capOv .capTitle{margin:0;font:400 1.6rem/1 'Bangers',var(--disp);letter-spacing:.06em;text-transform:uppercase;color:#fff;transform:skewX(-6deg);
  text-shadow:0 .12rem 0 #000,0 0 .9rem color-mix(in srgb,var(--capG) 70%,transparent);-webkit-text-stroke:.03em #000;paint-order:stroke;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
.capOv[data-tier] .capTitle{color:var(--capG)}
.capOv .capSub{font-family:var(--disp);font-style:italic;font-size:.75rem;letter-spacing:.12em;text-transform:uppercase;color:var(--dim,#a7b0d8)}
.capOv .capBack{top:calc(1rem + env(safe-area-inset-top,0px));z-index:4}
.capOv .capSkip{position:absolute;top:calc(1rem + env(safe-area-inset-top,0px));right:calc(1rem + env(safe-area-inset-right,0px));z-index:4}   /* its look is the game's one Skip (style.css .skipBtn, 2026-10-28); its own slanted italic one before */
.capOv button:focus-visible{outline:.125rem solid var(--capG);outline-offset:.15rem}
/* loading and the error */
.capOv .capLoad{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:3;display:flex;flex-direction:column;align-items:center;gap:.9rem;font-family:var(--disp);font-style:italic;text-transform:uppercase;letter-spacing:.08em;color:#dfe4ff}
.capOv .capSpin{width:3.25rem;height:3.25rem;border-radius:50%;background:conic-gradient(from 0deg,transparent 0 55%,var(--capG) 100%);-webkit-mask:radial-gradient(circle,transparent 52%,#000 54%);mask:radial-gradient(circle,transparent 52%,#000 54%);animation:capSpin .9s linear infinite}
@keyframes capSpin{to{transform:rotate(1turn)}}
.capOv .capErr{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:3;width:min(26rem,calc(100% - 2rem));padding:1.25rem 1.25rem 1rem;display:flex;flex-direction:column;gap:.6rem;text-align:center;
  background:linear-gradient(180deg,#0e1533,#090e22);border:1px solid #2a3766;border-top:.1875rem solid var(--foe,#ff6a5a)}
.capOv .capErr b{font-family:var(--disp);font-style:italic;font-size:1.1rem;text-transform:uppercase;color:#fff}
.capOv .capErrMsg{margin:0;color:#ffd0c8}
.capOv .capErr small{color:var(--dim,#a7b0d8);line-height:1.35}
.capOv .capErrBtns{display:flex;gap:.6rem;justify-content:center;flex-wrap:wrap;margin-top:.3rem}
/* the throw: one big button low in the middle, breathing */
.capOv .capCta{position:absolute;left:50%;bottom:calc(9% + env(safe-area-inset-bottom,0px));transform:translateX(-50%);z-index:3;display:flex;flex-direction:column;align-items:center;gap:.2rem;max-width:calc(100% - 2rem);
  padding:.85rem 1.75rem;border:0;border-radius:0;background:linear-gradient(180deg,color-mix(in srgb,var(--capC) 92%,#fff),var(--capC));color:#0b0f1f;cursor:pointer;
  clip-path:polygon(.875rem 0,100% 0,calc(100% - .875rem) 100%,0 100%);box-shadow:0 0 1.5rem color-mix(in srgb,var(--capG) 60%,transparent);animation:capCta 1.6s ease-in-out infinite}
.capOv .capCta b{font:400 1.45rem/1 'Bangers',var(--disp);letter-spacing:.07em;white-space:nowrap}
.capOv .capCta small{font-family:var(--disp);font-style:italic;font-size:.6875rem;letter-spacing:.1em;text-transform:uppercase;opacity:.75}
@keyframes capCta{0%,100%{filter:brightness(1)}50%{filter:brightness(1.12)}}
/* the Capsule in CSS, when WebGL can't start: a pill in the tier's colours, hovering */
.capOv .capCss{position:absolute;left:50%;top:44%;z-index:1;width:6.5rem;height:9.5rem;transform:translate(-50%,-50%);transition:opacity .45s ease;animation:capHover 2.4s ease-in-out infinite}
.capOv .capCss i{position:absolute;left:0;right:0;display:block}
.capOv .capCssTop{top:0;height:50%;border-radius:3.25rem 3.25rem 0 0;background:radial-gradient(circle at 35% 30%,#fff 0,var(--capC) 35%,color-mix(in srgb,var(--capC) 55%,#000) 100%);border:.2rem solid #04050b;border-bottom:0}
.capOv .capCssBot{bottom:0;height:50%;border-radius:0 0 3.25rem 3.25rem;background:radial-gradient(circle at 35% 20%,#5a6788 0,#29314a 45%,#0e1220 100%);border:.2rem solid #04050b;border-top:0}
.capOv .capCssSeam{top:calc(50% - .3rem);height:.6rem;z-index:1;background:var(--capG);box-shadow:0 0 1rem var(--capG),0 0 2.2rem color-mix(in srgb,var(--capG) 55%,transparent);border-radius:.3rem}
@keyframes capHover{0%,100%{transform:translate(-50%,-50%)}50%{transform:translate(-50%,-54%) rotate(3deg)}}
.capOv[data-phase=fade] .capCss{animation:capPop .45s ease-out both}
@keyframes capPop{0%{transform:translate(-50%,-50%) scale(1)}40%{transform:translate(-50%,-50%) scale(1.12)}100%{transform:translate(-50%,-50%) scale(1.3);opacity:0}}
/* the beats over the 3D: speed lines through the throw, an impact frame at the landing, one capped flash at the burst */
.capOv .capFx{position:absolute;inset:0;z-index:2;pointer-events:none;overflow:hidden}
.capOv .capFx i{position:absolute;display:block;opacity:0}
.capOv .capLines{inset:-25%;background:repeating-conic-gradient(from 0deg at 50% 50%,rgba(255,255,255,0) 0 3.2deg,rgba(255,255,255,.55) 3.4deg 3.9deg,rgba(255,255,255,0) 4.1deg 7.5deg);
  -webkit-mask:radial-gradient(circle at 50% 50%,transparent 28%,#000 62%);mask:radial-gradient(circle at 50% 50%,transparent 28%,#000 62%)}
.capOv[data-phase=throw] .capLines{animation:capLines .55s linear both}
@keyframes capLines{0%{opacity:0;transform:rotate(0)}20%{opacity:.5}75%{opacity:.4}100%{opacity:0;transform:rotate(4deg)}}
.capOv .capImpact{inset:0;background:radial-gradient(circle at 50% 62%,transparent 0 18%,rgba(0,0,0,.55) 60%),repeating-conic-gradient(from 0deg at 50% 62%,rgba(255,255,255,0) 0 6deg,rgba(255,255,255,.35) 6.3deg 6.8deg,rgba(255,255,255,0) 7deg 13deg)}
.capOv[data-phase=land] .capImpact{animation:capImpact .2s ease-out both}
.capOv[data-phase=burst] .capImpact{animation:capImpact .26s ease-out both}
@keyframes capImpact{0%{opacity:.5}100%{opacity:0}}
.capOv .capFlash{left:50%;top:60%;width:70vmin;height:70vmin;transform:translate(-50%,-50%);border-radius:50%;background:radial-gradient(circle,#fff 0,var(--capG) 25%,transparent 70%)}
.capOv[data-phase=burst] .capFlash{animation:capFlash .42s ease-out both}
@keyframes capFlash{0%{opacity:0}18%{opacity:.5}100%{opacity:0}}
.capOv .capStar{left:50%;top:52%;width:58vmin;height:58vmin;transform:translate(-50%,-50%);background:var(--capG);
  clip-path:polygon(50% 0,58% 32%,85% 12%,68% 40%,100% 45%,70% 58%,92% 86%,60% 68%,50% 100%,40% 68%,8% 86%,30% 58%,0 45%,32% 40%,15% 12%,42% 32%)}
.capOv[data-state=settled] .capStar{animation:capStar .6s ease-out both}
.capOv:not(.nogl)[data-state=settled] .capStar{animation:none}
@keyframes capStar{0%{opacity:.6;transform:translate(-50%,-50%) scale(.3) rotate(0)}100%{opacity:0;transform:translate(-50%,-50%) scale(1.25) rotate(12deg)}}
.capOv[data-tier=legendary][data-phase=beat] .capFx::after{content:"";position:absolute;inset:0;background:radial-gradient(ellipse at 50% 55%,transparent 35%,rgba(255,170,40,.18) 75%);animation:capBeat .4s ease-in-out both}
@keyframes capBeat{0%,100%{opacity:0}50%{opacity:1}}
/* the item's name, flashed as the card turns face-up */
.capOv .capNameFlash{position:absolute;left:50%;top:74%;z-index:2;transform:translate(-50%,-50%) skewX(-8deg);max-width:calc(100% - 2rem);font:400 clamp(1.8rem,7vmin,3.6rem)/1 'Bangers',var(--disp);letter-spacing:.04em;text-align:center;color:#fff;
  -webkit-text-stroke:.05em #000;paint-order:stroke;text-shadow:0 .08em 0 #000,0 0 .5em var(--capG);opacity:0;pointer-events:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.capOv .capNameFlash.on{animation:capName .5s cubic-bezier(.2,1.4,.4,1) both}
@keyframes capName{0%{opacity:0;transform:translate(-50%,-50%) skewX(-8deg) scale(1.6)}100%{opacity:1;transform:translate(-50%,-50%) skewX(-8deg) scale(1)}}
/* SETTLED: the reward card and its buttons, crisp HTML, scrolling on a short window */
.capOv .capSettle{position:absolute;inset:0;z-index:3;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1rem;padding:4.5rem 1rem calc(1.25rem + env(safe-area-inset-bottom,0px));overflow-y:auto;overflow-x:hidden}
.capOv .capCard{position:relative;width:min(36rem,100%);display:flex;flex-direction:column;align-items:stretch;gap:.55rem;padding:.75rem .75rem .9rem;
  background:linear-gradient(180deg,#121a3a,#0a0f24);border:1px solid color-mix(in srgb,var(--capG) 55%,#2a3766);border-top:.1875rem solid var(--capC);
  clip-path:polygon(.9rem 0,100% 0,100% calc(100% - .9rem),calc(100% - .9rem) 100%,0 100%,0 .9rem);animation:capCardIn .5s cubic-bezier(.2,1.25,.3,1) both}
.capOv .capCard[data-kind=banner]{width:min(64rem,96vw)}
.capOv .capCardGlow{position:absolute;inset:-40% -20% auto;height:80%;background:radial-gradient(ellipse at 50% 100%,color-mix(in srgb,var(--capG) 35%,transparent),transparent 70%);pointer-events:none}
@keyframes capCardIn{0%{opacity:0;transform:scale(.86) translateY(.6rem);filter:blur(4px)}100%{opacity:1;transform:none;filter:none}}
.capOv .capTag{position:relative;align-self:flex-start;padding:.2rem .7rem;font-family:var(--disp);font-style:italic;font-size:.7rem;letter-spacing:.14em;text-transform:uppercase;color:#0b0f1f;background:var(--capC);clip-path:polygon(.35rem 0,100% 0,calc(100% - .35rem) 100%,0 100%)}
.capOv .capArt{position:relative;aspect-ratio:1/1;max-height:min(28rem,52vh);margin:0 auto;width:100%;overflow:hidden;background:radial-gradient(circle at 50% 40%,color-mix(in srgb,var(--capD) 80%,#000),#05070f);border:1px solid #2a3766}
.capOv .capCard[data-kind=banner] .capArt{aspect-ratio:3/1;max-height:none}
.capOv .capCard[data-kind=platform] .capArt{aspect-ratio:5/4}
.capOv .capArt img{display:block;width:100%;height:100%;object-fit:cover}
.capOv .capCard[data-kind=icon] .capArt{width:min(24rem,100%);border-radius:.9rem}   /* an icon shown square (the owner, 2026-10-22: the Tactician's Crest is a square picture), never cropped round here */
.capOv .capArt.noArt img{display:none}
.capOv .capArt.noArt::after{content:"";position:absolute;left:50%;top:50%;width:38%;aspect-ratio:1;transform:translate(-50%,-50%);background:var(--capG);opacity:.7;
  clip-path:polygon(50% 0,61% 35%,98% 35%,68% 57%,79% 91%,50% 70%,21% 91%,32% 57%,2% 35%,39% 35%)}
.capOv .capInfo{position:relative;display:flex;flex-direction:column;align-items:center;gap:.2rem;text-align:center}
.capOv .capRar{font-family:var(--disp);font-style:italic;font-size:.75rem;letter-spacing:.18em;color:var(--capG)}
.capOv .capRar[data-r=standard]{color:#d8e6ff}.capOv .capRar[data-r=rare]{color:#8cf5ff}.capOv .capRar[data-r=epic]{color:#dcb8ff}.capOv .capRar[data-r=legendary]{color:#ffe07a}
.capOv .capName{font:400 clamp(1.5rem,5vmin,2.1rem)/1.05 'Bangers',var(--disp);letter-spacing:.04em;color:#fff;text-shadow:0 .08em 0 #000,0 0 .6em color-mix(in srgb,var(--capG) 60%,transparent);overflow-wrap:anywhere}
.capOv .capKind{font-family:var(--disp);font-size:.75rem;letter-spacing:.12em;text-transform:uppercase;color:var(--dim,#a7b0d8)}
.capOv .capRefund{position:relative;display:flex;flex-wrap:wrap;justify-content:center;align-items:baseline;gap:.15rem .35rem;padding:1rem .5rem;text-align:center}
.capOv .capRefund b{font-family:var(--disp);font-style:italic;font-size:1rem;letter-spacing:.12em;color:#fff}
.capOv .capRefund i{font-style:normal;color:var(--capG)}
.capOv .capRefund strong{font:400 clamp(1.9rem,7vmin,2.6rem)/1 'Bangers',var(--disp);letter-spacing:.04em;color:var(--capG);text-shadow:0 .08em 0 #000}
.capOv .capRefund small{flex-basis:100%;margin-top:.4rem;color:var(--dim,#a7b0d8);line-height:1.35}
.capOv .capMeta{position:relative;text-align:center;font-size:.75rem;color:var(--dim,#a7b0d8)}
.capOv .capMeta:empty,.capOv .capStatus:empty{display:none}
.capOv .capStatus{position:relative;text-align:center;font-size:.8125rem;color:#dfe4ff}
.capOv .capBtns{display:flex;flex-wrap:wrap;justify-content:center;gap:.6rem;width:min(36rem,100%)}
.capOv .capBtns button{flex:1 1 11rem;min-height:3rem;border:0;border-radius:0;background:#141d3d;color:#dfe4ff;font-family:var(--disp);font-style:italic;font-size:.9375rem;letter-spacing:.03em;text-transform:uppercase;
  clip-path:polygon(.5rem 0,100% 0,calc(100% - .5rem) 100%,0 100%);cursor:pointer;animation:capBtnIn .3s ease-out both}
.capOv .capBtns button:hover{background:#243063;color:#fff}
.capOv .capBtns .capEquip{background:var(--hubAcc,#ff9f1c);color:var(--hubInk,#160c00);box-shadow:0 .375rem 1.5rem rgba(255,159,28,.3)}
.capOv .capBtns .capEquip:hover{background:var(--hubAcc2,#ffb547);color:var(--hubInk,#160c00)}
.capOv .capBtns .capEquip:disabled{opacity:1;background:#1d4f3a;color:#bff5d4;box-shadow:none}
.capOv .capBtns .capNext{background:color-mix(in srgb,var(--capD) 70%,#141d3d);color:#fff;outline:1px solid color-mix(in srgb,var(--capG) 60%,transparent);outline-offset:-1px}
.capOv .capBtns button{animation-delay:.25s}
.capOv .capBtns button:nth-child(2){animation-delay:.31s}.capOv .capBtns button:nth-child(3){animation-delay:.37s}.capOv .capBtns button:nth-child(4){animation-delay:.43s}
@keyframes capBtnIn{from{opacity:0;transform:translateY(.5rem)}to{opacity:1;transform:none}}
/* the screen reader's line, out of sight */
.capOv .capSay{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}
/* phones: the title under Back and Skip, the buttons two to a row */
@media (max-width:560px){
  .capOv .capHead{top:calc(3.9rem + env(safe-area-inset-top,0px));max-width:calc(100% - 2rem)}
  .capOv .capTitle{font-size:1.35rem}
  .capOv .capBack{height:2.25rem;font-size:.75rem}
  .capOv .capSkip{right:.75rem}
  .capOv .capBack{left:.75rem}
  .capOv .capSettle{padding-top:6.25rem;justify-content:flex-start}
  .capOv .capBtns button{flex:1 1 calc(50% - .6rem);min-height:2.85rem;font-size:.8125rem}
  .capOv .capCta{padding:.75rem 1.2rem}
  .capOv .capCta b{font-size:1.2rem}
}
@media (max-height:520px){.capSettle{justify-content:flex-start;padding-top:3.75rem}.capArt{max-height:30vh}}
/* reduced motion: the game's setting (.reduced) or the system's; the throw is a cross-fade and nothing flashes */
  .capOv.reduced .capFx,.capOv.reduced .capNameFlash{display:none}
  .capOv.reduced .capCta,.capOv.reduced .capCss,.capOv.reduced .capSpin{animation:none}
  .capOv.reduced .capCard,.capOv.reduced .capBtns button{animation:capFade .35s ease-out both}
@keyframes capFade{from{opacity:0}to{opacity:1}}
@media (prefers-reduced-motion:reduce){
  .capOv .capFx,.capOv .capNameFlash{display:none}
  .capOv .capCta,.capOv .capCss,.capOv .capSpin{animation:none}
  .capOv .capCard,.capOv .capBtns button{animation:capFade .35s ease-out both}
}
