/* UI 0.8.7. A continuous crown and a full-width, independent touch console.
   Tile faces retain 2:3; controls have real visible and interactive geometry. */
html,body{width:100%;height:100%;height:100dvh;min-height:0;margin:0;padding:0;overflow:hidden;overscroll-behavior:none}
html:root{background:#650816 url('/assets/approved-v082/backdrop.webp') center/cover no-repeat}
body{display:flex;align-items:flex-start;justify-content:center;background:transparent}
/* The installed app paints behind native status/home indicators. Insets only
   move live content; they never add padding or an empty border to the canvas. */
html.standalone,html.standalone body{height:100vh;height:100lvh}
.game-stage{
  --ff-safe-top:env(safe-area-inset-top,0px);--ff-safe-bottom:env(safe-area-inset-bottom,0px);
  --ff-safe-left:env(safe-area-inset-left,0px);--ff-safe-right:env(safe-area-inset-right,0px);
  width:var(--ff-width,100vw);height:var(--ff-height,100dvh);min-width:0;max-width:none;
  min-height:0;max-height:none;aspect-ratio:auto;flex:none;margin:0;overflow:hidden;
  background:#650816 url('/assets/approved-v082/backdrop.webp') center/cover no-repeat;
}
.fullframe-art{position:absolute;inset:0;pointer-events:none;z-index:0}
.fullframe-art i{display:block;position:absolute;left:0;width:100%;background-repeat:no-repeat;background-size:100% 100%}
.fullframe-art b{display:block;background-repeat:no-repeat;background-size:100% 100%;min-width:0}
.fullframe-art .art-crown{top:var(--ff-crown-top);width:var(--ff-scene-width);height:var(--ff-crown-height);background-image:url('/assets/portrait-v085/frame.webp');background-size:var(--ff-crown-width) calc(var(--ff-crown-unit)*1859);background-position:0 0}
/* One continuous source image spans the crown. The old three-piece container
   remains in the generated shell for compatibility, but paints no side strips. */
.fullframe-art .art-crown b{display:none}
.fullframe-art .art-rail{top:var(--ff-rail-top);width:var(--ff-scene-width);height:var(--ff-rail-height);background-image:url('/assets/fullframe-v086/rail.webp')}
.fullframe-art .art-board{top:var(--ff-board-top);width:var(--ff-scene-width);height:var(--ff-board-height);display:grid;grid-template-columns:var(--ff-board-left) var(--ff-board-width) 1fr}
.art-board b:first-child{background-image:url('/assets/fullframe-v086/board-left.webp')}.art-board b:nth-child(2){background-image:url('/assets/fullframe-v086/board-center.webp')}.art-board b:last-of-type{background-image:url('/assets/fullframe-v086/board-right.webp')}
.art-board b:first-child,.art-board b:last-of-type{position:relative;overflow:hidden;background-size:100% var(--ornament-middle-image);background-position:0 var(--ornament-middle-offset)}
.art-board b:first-child{--ornament-top:var(--ff-left-top-height);--ornament-bottom:var(--ff-left-bottom-height);--ornament-top-image:var(--ff-left-top-image-height);--ornament-bottom-image:var(--ff-left-bottom-image-height);--ornament-middle-image:var(--ff-left-middle-image-height);--ornament-middle-offset:var(--ff-left-middle-offset);--ornament-image:url('/assets/fullframe-v086/board-left.webp')}
.art-board b:last-of-type{--ornament-top:var(--ff-right-top-height);--ornament-bottom:var(--ff-right-bottom-height);--ornament-top-image:var(--ff-right-top-image-height);--ornament-bottom-image:var(--ff-right-bottom-image-height);--ornament-middle-image:var(--ff-right-middle-image-height);--ornament-middle-offset:var(--ff-right-middle-offset);--ornament-image:url('/assets/fullframe-v086/board-right.webp')}
.art-board b:first-child::before,.art-board b:last-of-type::before,.art-board b:first-child::after,.art-board b:last-of-type::after{content:'';position:absolute;left:0;right:0;background-image:var(--ornament-image);background-repeat:no-repeat;pointer-events:none}
.art-board b:first-child::before,.art-board b:last-of-type::before{top:0;height:var(--ornament-top);background-size:100% var(--ornament-top-image);background-position:0 0}
.art-board b:first-child::after,.art-board b:last-of-type::after{bottom:0;height:var(--ornament-bottom);background-size:100% var(--ornament-bottom-image);background-position:0 100%}
.fullframe-art .art-hud{top:var(--ff-footer-top);height:var(--ff-hud-height)}
.fullframe-art .art-controls{top:var(--ff-controls-top);height:var(--ff-controls-height)}
.fullframe-art .art-controls b{display:none}
.game-stage::before{display:none!important}.pwa-footer-extension{display:none}
.game-header{left:var(--ff-crown-left);right:auto;width:var(--ff-crown-width);top:var(--ff-crown-top);height:calc(var(--ff-crown-unit)*307.2)}
.game-header #menu-btn,.game-header #sound-btn{pointer-events:auto;min-width:32px;min-height:32px}
.game-header #menu-btn{left:max(2.5%,var(--ff-header-inset-left))}.game-header #sound-btn{right:max(2.5%,var(--ff-header-inset-right))}
.logo-fx{left:calc(var(--ff-crown-left) + var(--ff-crown-width)*.292824);width:calc(var(--ff-crown-width)*.414352);top:calc(var(--ff-crown-top) + var(--ff-crown-unit)*123);height:calc(var(--ff-crown-unit)*135)}
.multiplier-frame{left:calc(var(--ff-scene-width)*.126);width:calc(var(--ff-scene-width)*.748);top:calc(var(--ff-rail-top) + var(--ff-rail-height)*7.576/89);height:calc(var(--ff-rail-height)*62.976/89)}
.multiplier-rail{min-height:0;height:100%;grid-template-rows:minmax(0,1fr)}
.multiplier-rail .mult{min-height:0;height:100%;font-size:min(8.15cqw,calc(var(--ff-rail-height)*.9));line-height:.95}
.reel-theatre{left:var(--ff-board-left);width:var(--ff-board-width);top:var(--ff-board-top);height:var(--ff-board-height)}
.announcement{left:var(--ff-panel-left);width:var(--ff-panel-width);top:var(--ff-footer-top);height:var(--ff-notice-height,38px)}
.credits-strip{left:calc(var(--ff-controls-left) + 12px);width:calc(var(--ff-controls-width) - 24px);top:calc(var(--ff-footer-top) + var(--ff-meter-offset,40px));height:var(--ff-meter-height,34px)}
.play-controls{left:var(--ff-controls-left);right:auto;width:var(--ff-controls-width);top:var(--ff-controls-top);height:var(--ff-controls-height)}
#spin-btn .spin-disk{height:auto;aspect-ratio:1;object-fit:fill}
#stage-notice{max-width:64%;font:italic 800 clamp(16px,4.9vw,22px)/1.05 Georgia,serif;color:#fff1ad;text-shadow:0 2px 1px #5a0800,0 0 5px #f7a70080}
.announcement.winning #stage-notice{font-size:clamp(18px,5.5vw,24px)}
.credits-strip .meter-value{font-size:16px;line-height:1.05}
@media(min-aspect-ratio:1/1){.game-stage{width:var(--ff-width);max-width:none}}

/* The existing rays above the crest gain a slow warm pulse and a small sweep.
   These layers never cover controls or issue animation-frame JavaScript. */
.fullframe-art .art-crown{overflow:hidden;isolation:isolate}
.art-crown::before,.art-crown::after{content:'';position:absolute;z-index:1;pointer-events:none;mix-blend-mode:screen}
.art-crown::before{inset:0;background:radial-gradient(ellipse at 50% 23%,#fff8d5bb 0%,#ffd76a80 6%,#ffb72f30 22%,transparent 54%);-webkit-mask-image:linear-gradient(to bottom,transparent,#000 14%,#000 70%,transparent);mask-image:linear-gradient(to bottom,transparent,#000 14%,#000 70%,transparent);opacity:.20;animation:crown-glow 4.8s ease-in-out infinite}
.art-crown::after{left:8%;right:8%;top:0;height:52%;background:repeating-conic-gradient(from 176deg at 50% 45%,transparent 0deg 8deg,#ffe6a780 9deg 10deg,#ffc3452b 11deg,transparent 13deg 20deg);-webkit-mask-image:radial-gradient(ellipse at 50% 50%,#000 0%,#000b 22%,transparent 68%);mask-image:radial-gradient(ellipse at 50% 50%,#000 0%,#000b 22%,transparent 68%);transform-origin:50% 45%;opacity:.28;animation:crown-rays 6.4s ease-in-out infinite}
@keyframes crown-glow{0%,100%{opacity:.16;transform:scale(1)}50%{opacity:.55;transform:scale(1.06)}}
@keyframes crown-rays{0%,100%{opacity:.20;transform:rotate(-3deg) scale(1)}50%{opacity:.58;transform:rotate(3deg) scale(1.06)}}
html.reels-running .art-crown::before,html.reels-running .art-crown::after,body.reels-active .art-crown::before,body.reels-active .art-crown::after{animation-play-state:paused;opacity:.12}
@media(prefers-reduced-motion:reduce){.art-crown::before{animation:none;opacity:.18;transform:none}.art-crown::after{animation:none;opacity:.14;transform:none}}
/* Native status/home areas use decorative extensions, never baked-in OS text. */
.fullframe-art::before,.fullframe-art::after{content:'';position:absolute;left:0;right:0;pointer-events:none;background-repeat:no-repeat;background-size:100% 100%}
.fullframe-art::before{top:0;height:var(--ff-crown-top);background-image:url('/assets/approved-v082/extension-top.webp')}
.fullframe-art::after{top:calc(var(--ff-controls-top) + var(--ff-controls-height));bottom:0}

/* The approved ruby/gold stage is one continuous backing. Original banner,
   counters and control artwork are independent CSS sprite windows from the
   approved master derivative; no fixed values or duplicate controls are drawn.
   Studio may still override --ff-console-art with a published footer image. */
.game-stage{--ff-console-art:url('/assets/control-panel-v091/stage-clean.webp')}
.fullframe-art .art-hud,.fullframe-art .art-controls,.fullframe-art::after{left:var(--ff-panel-left);right:auto;width:var(--ff-panel-width);background-color:#66070d;background-image:var(--ff-console-art);background-size:100% var(--ff-footer-art-height)}
.fullframe-art .art-hud{background-position:0 calc(var(--ff-footer-art-top) - var(--ff-footer-top))}
.fullframe-art .art-controls{background-position:0 calc(var(--ff-footer-art-top) - var(--ff-controls-top))}
.fullframe-art::after{background-position:0 calc(var(--ff-footer-art-top) - var(--ff-controls-top) - var(--ff-controls-height))}
/* Source-preserving 3-slice notice. Only the undecorated center tiles
   horizontally; neither cloud cap, gold sculpture nor lettering is stretched. */
.announcement{
  display:flex;align-items:center;justify-content:center;isolation:isolate;
  padding:0;border:0;border-radius:0;box-shadow:none;overflow:visible;
  background:url('/assets/fullframe-v086/notice-center.webp') center center / auto 100% repeat-x;
}
.announcement::before,.announcement::after{
  content:'';position:absolute;top:0;bottom:0;pointer-events:none;z-index:1;
  width:calc(var(--ff-notice-height,30px) * 2.0733944954);
  background-repeat:no-repeat;background-position:center;
  background-size:100% 100%;
}
.announcement::before{left:0;background-image:url('/assets/fullframe-v086/notice-left.webp')}
.announcement::after{right:0;background-image:url('/assets/fullframe-v086/notice-right.webp')}
.announcement #stage-notice{position:relative;z-index:2;white-space:nowrap}
.credits-strip{gap:6px}
.credits-strip .meter{position:relative;padding:var(--ff-meter-padding,4px) 6px var(--ff-meter-padding,4px) clamp(24px,calc(var(--ff-controls-width)*.095),44px);gap:1px;border:0;border-radius:0;background-image:url('/assets/approved-v082/frame.webp');background-repeat:no-repeat;box-shadow:none;overflow:hidden}
.credits-strip .meter:first-child{background-size:318.819188% 2363.076923%;background-position:4.721754% 77.294358%}
.credits-strip .meter-bet{background-size:340.157480% 2363.076923%;background-position:50.163934% 77.294358%;cursor:pointer}
.credits-strip .meter:last-child{background-size:320% 2363.076923%;background-position:95.286195% 77.294358%}
.credits-strip .meter small{position:static;width:auto;height:auto;margin:0;clip:auto;overflow:visible;letter-spacing:.1em;font:600 8px/1 Arial,sans-serif;color:#f7dfa0}
.credits-strip .meter-value{font-weight:600;color:#fff5d9;text-shadow:0 1px 2px #001b17}
.credits-strip .meter-bet:focus-visible{outline:2px solid #fff0ad;outline-offset:2px}
.play-controls{display:grid;grid-template-columns:var(--ff-secondary-size) 44px var(--ff-spin-size) 44px var(--ff-secondary-size);justify-content:space-between;align-items:center;box-sizing:border-box;padding:8px 12px 12px;gap:6px}
.play-controls button{position:relative;inset:auto!important;width:44px;height:44px;min-width:44px;min-height:44px;display:block;margin:0;border:0;border-radius:50%;background-color:transparent;background-image:url('/assets/approved-v082/frame.webp');background-repeat:no-repeat;box-shadow:none;color:#fff0aa;cursor:pointer;transition:transform .12s,filter .12s}
.play-controls button:focus-visible{outline:3px solid #fff0b5;outline-offset:3px}
.play-controls button:disabled{opacity:.45;cursor:default;filter:saturate(.5)}
.play-controls button:not(:disabled):active{transform:scale(.95)}
/* Keep the approved circular faces and their original caption pixels, while
   masking the opaque rectangular red surround from the source sprite sheet. */
#turbo-btn,#auto-btn{width:var(--ff-secondary-size);height:var(--ff-secondary-size);border-radius:50%;background:none}
#turbo-btn::after,#auto-btn::after{content:'';position:absolute;inset:0;z-index:0;pointer-events:none;background-image:url('/assets/approved-v082/frame.webp');background-repeat:no-repeat;--control-alpha:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 102 102'%3E%3Cg fill='white'%3E%3Ccircle cx='51' cy='49' r='47'/%3E%3Crect x='7' y='75' width='88' height='25' rx='5'/%3E%3C/g%3E%3C/svg%3E");-webkit-mask-image:var(--control-alpha);mask-image:var(--control-alpha);-webkit-mask-size:100% 100%;mask-size:100% 100%;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}
#turbo-btn::after{background-size:847.058824% 1505.882353%;background-position:6.692913% 86.192469%}
#auto-btn::after{background-size:830.769231% 1476.923077%;background-position:93.421053% 86.312849%}
#turbo-btn::before,#auto-btn::before,#minus-btn::before,#plus-btn::before{content:none}
.play-controls .secondary-control>span{position:absolute;z-index:2;top:auto;bottom:0;left:0;width:100%;padding:2px 0;border:0;border-radius:4px;background:#651007;opacity:0;font:700 9px/1 Arial,sans-serif;letter-spacing:.025em;text-align:center;white-space:nowrap;color:#fff0ad;text-shadow:0 1px 2px #260100}
.play-controls .secondary-control.active>span,.play-controls .secondary-control[aria-pressed=true]>span{opacity:1}
.play-controls .secondary-control.active,#turbo-btn[aria-pressed=true]{filter:brightness(1.3);box-shadow:none}
#auto-btn.active::before{content:'';position:absolute;z-index:1;left:50%;top:47%;width:16px;height:16px;transform:translate(-50%,-50%);border:1px solid #fff1aa;background:linear-gradient(#fff0a4,#e9ac22);box-shadow:0 0 0 6px #5d1809}
#minus-btn{background-size:881.632653% 1567.346939%;background-position:25.848564% 86.300417%}
#plus-btn{background-size:881.632653% 1567.346939%;background-position:73.890339% 86.300417%}
#spin-btn{width:var(--ff-spin-size);height:var(--ff-spin-size);border:0;background:radial-gradient(circle,#087b66 42%,#012f27 59%,#f5ba34 61%,#fff5b6 65%,#a34b08 70%,#f6c452 74%);box-shadow:0 0 0 2px #ffe89f,0 0 0 4px #ba670e,0 0 0 5px #fff1b3,0 0 17px #ffbd43b3,0 4px 7px #500700}
#spin-btn .spin-disk{inset:0;width:100%;height:100%;object-fit:fill;filter:none}
#spin-btn .spin-label,#spin-btn.busy .spin-label{position:absolute;left:0;bottom:7px;width:100%;font:700 9px/1 Arial,sans-serif;letter-spacing:.12em;opacity:1;background:none;color:#fff7c4;text-shadow:0 1px 2px #00382b,0 0 3px #00382b}
@media(hover:hover){.play-controls button:not(:disabled):hover{filter:brightness(1.15)}}
#turbo-btn:focus-visible,#auto-btn:focus-visible{outline-offset:-4px;filter:brightness(1.12) drop-shadow(0 0 3px #fff0b5)}
.game-stage[data-fullframe=landscape] .fullframe-art::before{width:var(--ff-scene-width)}
.game-stage[data-fullframe=landscape] .fullframe-art::after{top:0;bottom:0;background-position:0 0;border-left:1px solid #ecc96d66;box-sizing:border-box}
.game-stage[data-fullframe=landscape] .multiplier-rail .mult{font-size:calc(var(--ff-scene-width)*.0815)}
/* Short landscape rows use intact, uniformly scaled ornament columns. Their
   lanterns must not flatten into wide discs just to fill a side gutter. */
.game-stage[data-fullframe=landscape] .art-board b:first-child{width:calc(var(--ff-board-height)*118/938);justify-self:end;background-size:100% 100%;background-position:0 0}
.game-stage[data-fullframe=landscape] .art-board b:last-of-type{width:calc(var(--ff-board-height)*117/938);justify-self:start;background-size:100% 100%;background-position:0 0}
.game-stage[data-fullframe=landscape] .art-board b:first-child::before,.game-stage[data-fullframe=landscape] .art-board b:first-child::after,.game-stage[data-fullframe=landscape] .art-board b:last-of-type::before,.game-stage[data-fullframe=landscape] .art-board b:last-of-type::after{display:none}

/* v0.9.2. Ornamental half-tile caps do not participate in the 4/5/5/5/4 game grid. */
.fullframe-art .art-board b:first-child,.fullframe-art .art-board b:last-of-type{background-color:#650b0b;background-repeat:no-repeat}
.reel-theatre .board-frame{position:relative;isolation:isolate}
.board .reel.short{position:relative;overflow:visible}
.board .reel.short::before{content:'';position:absolute;left:0;right:0;bottom:calc(100% + .14cqw);height:25%;z-index:0;border-radius:11%;pointer-events:none;background:var(--corner-cap-image) center/100% 100% no-repeat;box-shadow:inset 0 0 0 1px #ffe7a68c,0 3px 7px #230800af,0 0 7px #ffbf5973}
.reel-theatre .board-frame::before,.reel-theatre .board-frame::after{content:'';position:absolute;z-index:5;top:0;width:11%;height:11%;pointer-events:none;opacity:.65;background:radial-gradient(ellipse at top left,#ffe095c2 0%,#b86f157c 17%,transparent 65%)}
.reel-theatre .board-frame::before{left:0}.reel-theatre .board-frame::after{right:0;transform:scaleX(-1)}
.multiplier-rail .mult:not(.active) .mult-glyph{filter:saturate(.53) brightness(.75) drop-shadow(0 1px 1px #062823)!important}
.multiplier-rail .mult.active .mult-glyph{filter:grayscale(1) sepia(1) saturate(7) hue-rotate(-12deg) brightness(1.2) drop-shadow(0 0 4px #fff2aa) drop-shadow(0 0 8px #ffc43e)!important}
.multiplier-rail .mult.active:not(.art-mult){color:#ffe46b!important;text-shadow:0 0 5px #ffc040,0 2px 2px #693012!important}


/* v0.9.3: desktop is a single height-fitted cabinet, not a detached side console.
   Keep the source artwork proportional and fill unused monitor width with atmosphere.
   Mobile portrait and short mobile landscape still use their existing layouts. */
html.desktop-layout body{
  background:
    radial-gradient(ellipse at 50% 36%,rgba(186,43,40,.28) 0%,rgba(79,7,16,.24) 36%,rgba(23,1,8,.72) 100%),
    linear-gradient(90deg,rgba(32,3,11,.46),transparent 30%,transparent 70%,rgba(32,3,11,.46)),
    url('/assets/approved-v082/backdrop.webp') center center / cover no-repeat;
}
.game-stage[data-fullframe="desktop"]{
  border:0;
  box-shadow:inset 1px 0 rgba(255,197,87,.42),inset -1px 0 rgba(255,197,87,.42),
             0 0 0 1px rgba(90,15,12,.52),0 0 42px rgba(9,1,5,.72),0 0 110px rgba(181,39,20,.2);
}
.game-stage[data-fullframe="desktop"] .multiplier-rail .mult{
  font-size:min(calc(var(--ff-scene-width)*.0815),calc(var(--ff-rail-height)*.9));
}


/* Ornament v0.9.4: one unbroken image for each dragon body.
   No separately rescaled upper, middle, or lower ornament. The original
   approved portrait raster owns the lantern-to-tail and lower corner joins. */
.fullframe-art .art-board b:first-child,
.fullframe-art .art-board b:last-of-type{
  position:relative;
  overflow:hidden!important;
  background-repeat:no-repeat!important;
  background-color:#650b0b;
}
.fullframe-art .art-board b:first-child{
  background-size:var(--ff-left-base-width) var(--ff-board-height)!important;
  background-position:left top!important;
  box-shadow:inset -3px 0 10px rgba(249,175,63,.16);
}
.fullframe-art .art-board b:last-of-type{
  background-size:var(--ff-right-base-width) var(--ff-board-height)!important;
  background-position:right top!important;
  box-shadow:inset 3px 0 10px rgba(249,175,63,.16);
}
.fullframe-art .art-board b:first-child::before,
.fullframe-art .art-board b:last-of-type::before,
.fullframe-art .art-board b:first-child::after,
.fullframe-art .art-board b:last-of-type::after{
  display:none!important;
  content:none!important;
  background-image:none!important;
}

/* Ornament revision: remove all patterned side panels and use only
   a thin gold rule at the scoring-reel edge. No columns, dots, tiles or beams. */
.fullframe-art .art-board{
  background:linear-gradient(90deg,#610b13 0%,#680b12 12%,#680b12 88%,#610b13 100%);
}
/* Keep the source lantern and upper dragon unwarped; crossfade the lower body
   into a *separate*, uniformly enlarged tail/cloud derivative. This also avoids
   duplicating the source's old straight interior framing stripe. */
.fullframe-art .art-board b:first-child,
.fullframe-art .art-board b:last-of-type{
  -webkit-mask-image:linear-gradient(to bottom,#000 0%,#000 40%,#000b 46%,transparent 60%);
  mask-image:linear-gradient(to bottom,#000 0%,#000 40%,#000b 46%,transparent 60%);
}
/* The actual 5-reel board retains its 2:3 symbol pixels and interaction.
   The decorative gold line is a 1px outline, not an extra layout column. */
.game-stage .reel-theatre{isolation:isolate;overflow:visible}
.game-stage .reel-theatre .board-frame{
  position:relative;z-index:1;outline:1px solid rgba(255,209,114,.86);
  outline-offset:0;box-shadow:0 0 5px rgba(255,180,67,.38);
}
/* Every tail/cloud foreground sprite is resized by one common scale computed
   from boardHeight/938. The opacity is in the *generated* source cutout, never
   a crop of a stretched raster. Each reaches at most 8% of a tile into reels. */
.game-stage .reel-theatre::before,.game-stage .reel-theatre::after{
  content:'';display:block!important;position:absolute;top:auto;bottom:0;
  min-width:0;height:var(--ff-tail-height,0px);z-index:5;
  border:0;box-shadow:none;pointer-events:none;opacity:1;
  background-color:transparent;background-repeat:no-repeat;
  background-size:100% 100%;background-position:center;
  -webkit-mask-image:none;mask-image:none;
}
.game-stage .reel-theatre::before{
  right:auto;
  left:calc(var(--ff-tail-overlap,0px) - var(--ff-tail-left-width,0px));
  width:var(--ff-tail-left-width,0px);
  background-image:url('/assets/fullframe-v086/tail-left.webp');
}
.game-stage .reel-theatre::after{
  left:auto;
  right:calc(var(--ff-tail-overlap,0px) - var(--ff-tail-right-width,0px));
  width:var(--ff-tail-right-width,0px);
  background-image:url('/assets/fullframe-v086/tail-right.webp');
}

/* Mobile-first portrait composition: six image-backed layers from the exact
   approved dragon/lantern/cloud source. NEVER stretch the 938px master into
   the full column height. Layout.js calculates both dimensions from ONE
   uniform per-kind scale, while background-size:contain preserves aspect. */
.fullframe-art .art-board > .mobile-ornament{
  display:none;position:absolute;pointer-events:none;
  background-color:transparent;background-repeat:no-repeat;
  background-position:center center;background-size:contain;
  box-shadow:none;transform:none;
}
.game-stage[data-fullframe="portrait"] .fullframe-art .art-board > .mobile-ornament{
  display:block;
}
.game-stage[data-fullframe="portrait"] .fullframe-art .art-board > b:first-child,
.game-stage[data-fullframe="portrait"] .fullframe-art .art-board > b:last-of-type{
  opacity:0!important;
}
/* Retire the older combined tail pseudo-elements only in mobile portrait.
   Desktop/landscape retain the previous verified continuous art. */
.game-stage[data-fullframe="portrait"] .reel-theatre::before,
.game-stage[data-fullframe="portrait"] .reel-theatre::after{
  display:none!important;content:none!important;
}
.fullframe-art .art-board > .mobile-ornament--dragon{z-index:1}
.fullframe-art .art-board > .mobile-ornament--lantern{z-index:2}
.fullframe-art .art-board > .mobile-ornament--cloud{z-index:3}
.fullframe-art .art-board > .mobile-ornament--lantern-left{
  left:calc(var(--ff-board-left) - var(--ff-mobile-lantern-left-width));
  top:calc(0px - var(--ff-mobile-lantern-top-offset));
  width:var(--ff-mobile-lantern-left-width);
  height:var(--ff-mobile-lantern-height);
  background-image:url('/assets/fullframe-v086/mobile-lantern-left.webp');
}
.fullframe-art .art-board > .mobile-ornament--lantern-right{
  right:calc(var(--ff-board-right-gutter) - var(--ff-mobile-lantern-right-width));
  top:calc(0px - var(--ff-mobile-lantern-top-offset));
  width:var(--ff-mobile-lantern-right-width);
  height:var(--ff-mobile-lantern-height);
  background-image:url('/assets/fullframe-v086/mobile-lantern-right.webp');
}
.fullframe-art .art-board > .mobile-ornament--dragon-left{
  left:calc(var(--ff-board-left) - var(--ff-mobile-dragon-left-width) + var(--ff-mobile-ornament-overlap));
  top:var(--ff-mobile-dragon-top-offset);
  width:var(--ff-mobile-dragon-left-width);
  height:var(--ff-mobile-dragon-height);
  background-image:url('/assets/fullframe-v086/mobile-dragon-left.webp');
}
.fullframe-art .art-board > .mobile-ornament--dragon-right{
  right:calc(var(--ff-board-right-gutter) - var(--ff-mobile-dragon-right-width) + var(--ff-mobile-ornament-overlap));
  top:var(--ff-mobile-dragon-top-offset);
  width:var(--ff-mobile-dragon-right-width);
  height:var(--ff-mobile-dragon-height);
  background-image:url('/assets/fullframe-v086/mobile-dragon-right.webp');
}
.fullframe-art .art-board > .mobile-ornament--cloud-left{
  left:calc(var(--ff-board-left) - var(--ff-mobile-cloud-left-width) + var(--ff-mobile-ornament-overlap));
  bottom:0;
  width:var(--ff-mobile-cloud-left-width);
  height:var(--ff-mobile-cloud-height);
  background-image:url('/assets/fullframe-v086/mobile-cloud-left.webp');
}
.fullframe-art .art-board > .mobile-ornament--cloud-right{
  right:calc(var(--ff-board-right-gutter) - var(--ff-mobile-cloud-right-width) + var(--ff-mobile-ornament-overlap));
  bottom:0;
  width:var(--ff-mobile-cloud-right-width);
  height:var(--ff-mobile-cloud-height);
  background-image:url('/assets/fullframe-v086/mobile-cloud-right.webp');
}

/* A desktop monitor hosts a PORTRAIT cabinet but sets fullframe=desktop.
   Activate the same foreground layering instead of showing dark corner caps. */
.game-stage[data-corner-reels="masked-v103"][data-fullframe="desktop"] .fullframe-art .art-board > .mobile-ornament{display:block}
.game-stage[data-corner-reels="masked-v103"][data-fullframe="desktop"] .fullframe-art .art-board > b:first-child,
.game-stage[data-corner-reels="masked-v103"][data-fullframe="desktop"] .fullframe-art .art-board > b:last-of-type{opacity:0!important}
.game-stage[data-corner-reels="masked-v103"][data-fullframe="desktop"] .reel-theatre::before,
.game-stage[data-corner-reels="masked-v103"][data-fullframe="desktop"] .reel-theatre::after{display:none!important;content:none!important}

/* APPROVED v103. All six VISUAL positions on the two outer reels are the
   exact same 2:3 tile assets as the five-row central reels. Four of each six
   are the true scoring cells. The first and last full-size sprites are
   generated by CSS pseudo-elements, never by changing settlement DOM order.
   The board itself alone masks their invisible outer halves. */
.game-stage[data-corner-reels="masked-v103"]:is([data-fullframe="portrait"],[data-fullframe="desktop"]) .board .reel.short{
  position:relative!important;
  top:-10%!important;
  height:120%!important;
  margin:0!important;
  align-self:start!important;
  grid-template-rows:repeat(6,minmax(0,1fr))!important;
  overflow:visible!important;
}
.game-stage[data-corner-reels="masked-v103"]:is([data-fullframe="portrait"],[data-fullframe="desktop"]) .board .reel.short::before,
.game-stage[data-corner-reels="masked-v103"]:is([data-fullframe="portrait"],[data-fullframe="desktop"]) .board .reel.short::after{
  content:''!important;
  display:block!important;
  position:relative!important;
  inset:auto!important;
  min-width:0;min-height:0;width:100%;height:100%;
  border:0;border-radius:10%;
  pointer-events:none;user-select:none;
  opacity:1!important;
  background-color:transparent!important;
  background-image:var(--corner-top-image)!important;
  background-position:center!important;
  background-size:100% 100%!important;
  background-repeat:no-repeat!important;
  box-shadow:none!important;
  filter:drop-shadow(0 2px 3px #46020ec9) drop-shadow(0 0 3px #7612258c);
}
.game-stage[data-corner-reels="masked-v103"]:is([data-fullframe="portrait"],[data-fullframe="desktop"]) .board .reel.short::after{
  background-image:var(--corner-bottom-image)!important;
}
/* The GPU canvas covers the ENTIRE six-row visual, including masked corners,
   while the unchanged 4/5/5/5/4 gameplay DOM stays below it. */
.game-stage[data-corner-reels="masked-v103"]:is([data-fullframe="portrait"],[data-fullframe="desktop"]) .board .reel.short .reel-surface{
  inset:0!important;
  height:100%!important;width:100%!important;
  overflow:hidden!important;
}
/* Only the TILE FIELD receives the corner mask. Not the gold frame,
   not the dragon, and never the jade artwork. No solid green triangles. */
.game-stage[data-corner-reels="masked-v103"]:is([data-fullframe="portrait"],[data-fullframe="desktop"]) .reel-theatre .board{
  overflow:hidden!important;
  clip-path:polygon(0 4%, 5.5% 0, 94.5% 0, 100% 4%,
    100% 96%, 94.5% 100%, 5.5% 100%, 0 96%);
}
.game-stage[data-corner-reels="masked-v103"]:is([data-fullframe="portrait"],[data-fullframe="desktop"]) .reel-theatre .board-frame{
  overflow:hidden!important;
}
.game-stage[data-corner-reels="masked-v103"]:is([data-fullframe="portrait"],[data-fullframe="desktop"]) .reel-theatre .board-frame::before,
.game-stage[data-corner-reels="masked-v103"]:is([data-fullframe="portrait"],[data-fullframe="desktop"]) .reel-theatre .board-frame::after{
  display:none!important;content:none!important;
}
/* Original mobile jade is moved into the theatre's FOREGROUND paint layer.
   It remains unwarped (native 118x338 / 117x338), fully visible and over
   EVERY tile, clipped corner, and gold board outline. */
.game-stage[data-corner-reels="masked-v103"]:is([data-fullframe="portrait"],[data-fullframe="desktop"]) .fullframe-art .art-board > .mobile-ornament--cloud{
  visibility:hidden!important;
}
.game-stage .reel-theatre > .jade-cloud-foreground{
  display:none;position:absolute;bottom:0;z-index:15;
  pointer-events:none;user-select:none;
  background-color:transparent;background-position:center bottom;
  background-repeat:no-repeat;background-size:contain;
  filter:drop-shadow(0 4px 5px #4b0618bf) drop-shadow(0 1px 3px #290209c9);
}
.game-stage[data-corner-reels="masked-v103"]:is([data-fullframe="portrait"],[data-fullframe="desktop"]) .reel-theatre > .jade-cloud-foreground{
  display:block;
}
.game-stage[data-corner-reels="masked-v103"]:is([data-fullframe="portrait"],[data-fullframe="desktop"]) .reel-theatre > .jade-cloud-foreground--left{
  left:calc(var(--ff-mobile-ornament-overlap) - var(--ff-mobile-cloud-left-width));
  width:var(--ff-mobile-cloud-left-width);
  height:var(--ff-mobile-cloud-height);
  background-image:url('/assets/fullframe-v086/mobile-cloud-left.webp');
}
.game-stage[data-corner-reels="masked-v103"]:is([data-fullframe="portrait"],[data-fullframe="desktop"]) .reel-theatre > .jade-cloud-foreground--right{
  right:calc(var(--ff-mobile-ornament-overlap) - var(--ff-mobile-cloud-right-width));
  width:var(--ff-mobile-cloud-right-width);
  height:var(--ff-mobile-cloud-height);
  background-image:url('/assets/fullframe-v086/mobile-cloud-right.webp');
}


/* Mahjong Wild MASTER V105: source-faithful responsive composition.
   Original logo/dragons/controls remain in the existing approved source.
   Do not bake scored symbols, wallet values, buttons or page chrome in raster. */
.game-stage[data-master-art^="v105"] .fullframe-art .art-crown{
  background-position:center top!important;
  background-repeat:no-repeat;
  background-size:var(--ff-crown-width) calc(var(--ff-crown-unit)*1859)!important;
}
.game-stage[data-master-art^="v105"] .reel-theatre > .jade-cloud-foreground{
  z-index:19;
  filter:drop-shadow(0 5px 7px #4a0318d9)
         drop-shadow(0 1px 4px #200006bb)!important;
}
.game-stage[data-master-art^="v105"] .reel-theatre > .jade-top-corner{
  display:none;position:absolute;top:-1.5%;
  z-index:20;pointer-events:none;user-select:none;
  width:calc(var(--ff-tile-width)*1.25);
  height:calc(var(--ff-tile-width)*.88);
  background-repeat:no-repeat;background-position:top center;
  background-size:contain;
  filter:drop-shadow(0 2px 4px #460714c9);
}
.game-stage[data-master-art^="v105"]:is([data-fullframe="portrait"],[data-fullframe="desktop"]) .reel-theatre > .jade-top-corner{display:block}
.game-stage[data-master-art^="v105"] .reel-theatre > .jade-top-corner--left{
  left:calc(var(--ff-tile-width)*-.28);
  background-image:var(--mw-master-top-left,url('/assets/ornaments/jade-corner-v105.svg'));
}
.game-stage[data-master-art^="v105"] .reel-theatre > .jade-top-corner--right{
  right:calc(var(--ff-tile-width)*-.28);
  background-image:var(--mw-master-top-right,url('/assets/ornaments/jade-corner-v105.svg'));
  transform:scaleX(-1);
}
/* User-supplied approved raster derivatives are the highest-fidelity layer
   whenever the locked master asset pack is installed. In fallback mode the
   existing verified source artwork remains visible with new v105 geometry. */
.game-stage .reel-theatre > .approved-master-side{
  display:none;position:absolute;top:0;height:100%;z-index:21;
  pointer-events:none;user-select:none;
  background-repeat:no-repeat;background-size:100% 100%;
  filter:drop-shadow(0 2px 3px #4f0712af);
  width:44.5969125%;
}
.game-stage[data-master-art="v105-locked"] .reel-theatre > .approved-master-side{display:block}
.game-stage[data-master-art="v105-locked"] .reel-theatre > .approved-master-side--left{
  left:-30.703259%;
  background-image:var(--mw-master-left,none);
}
.game-stage[data-master-art="v105-locked"] .reel-theatre > .approved-master-side--right{
  right:-30.703259%;
  background-image:var(--mw-master-right,none);
}
.game-stage[data-master-art="v105-locked"] .fullframe-art .art-crown{
  background-image:var(--mw-master-crown,none)!important;
  background-size:100% auto!important;
  background-position:center top!important;
}
.game-stage[data-master-art="v105-locked"] .logo-fx{
  opacity:0!important; /* Title already exists inside the locked raster */
}
.game-stage[data-master-art="v105-locked"] .game-header #menu-btn,
.game-stage[data-master-art="v105-locked"] .game-header #sound-btn{
  opacity:.01!important; /* Retain hit areas / events without duplicate icons */
}
.game-stage[data-master-art="v105-locked"] .fullframe-art .art-board > .mobile-ornament,
.game-stage[data-master-art="v105-locked"] .reel-theatre > .jade-cloud-foreground{
  visibility:hidden!important; /* Layered source art replaces older sprites */
}

/* The v105 jade clouds cover 26% of each outside bottom tile as approved,
   rather than the retired 8% decorative side-gutter overlap. They paint above
   the scrolling GPU atlas and must never become scoring tiles. */
.game-stage[data-master-art^="v105"] .reel-theatre > .jade-cloud-foreground--left{
  left:calc(var(--ff-tile-width)*.26 - var(--ff-mobile-cloud-left-width));
}
.game-stage[data-master-art^="v105"] .reel-theatre > .jade-cloud-foreground--right{
  right:calc(var(--ff-tile-width)*.26 - var(--ff-mobile-cloud-right-width));
}

/* MASTER V105 LOCKED. Source geometry (x179..762, y373..1240)
   is measured from the approved screenshot after removing browser chrome.
   Side dragons and jade float over only the outside corners. */
.game-stage[data-master-art="v105-locked"]:is([data-fullframe="portrait"],[data-fullframe="desktop"])
 .reel-theatre > .jade-top-corner {
  top:-9.227221%; width:38.765009%;height:18.454441%;
  background-size:100% 100%;filter:drop-shadow(0 3px 5px #460714c9);
}
.game-stage[data-master-art="v105-locked"]:is([data-fullframe="portrait"],[data-fullframe="desktop"])
 .reel-theatre > .jade-top-corner--left{left:-30.703259%}
.game-stage[data-master-art="v105-locked"]:is([data-fullframe="portrait"],[data-fullframe="desktop"])
 .reel-theatre > .jade-top-corner--right{right:-30.703259%;transform:none}
.game-stage[data-master-art="v105-locked"] .reel-theatre > .approved-master-side{display:none}
.game-stage[data-master-art="v105-locked"]:is([data-fullframe="portrait"],[data-fullframe="desktop"])
 .reel-theatre > .approved-master-side{display:block}
.game-stage[data-master-art="v105-locked"] .game-header{
 left:0!important;width:var(--ff-scene-width)!important;
}
.game-stage[data-master-art="v105-locked"] .game-header #menu-btn{
 left:3.7%!important;min-width:44px;min-height:44px;opacity:.01!important;
}
.game-stage[data-master-art="v105-locked"] .game-header #sound-btn{
 right:3.7%!important;min-width:44px;min-height:44px;opacity:.01!important;
}
/* A genuinely overlapping jade foreground: 26% of a standard tile width
   on fallback. The original higher-specificity 8% rule must not win. */
.game-stage[data-corner-reels="masked-v103"][data-master-art="v105-fallback"]:is([data-fullframe="portrait"],[data-fullframe="desktop"])
 .reel-theatre > .jade-cloud-foreground--left{
 left:calc(var(--ff-tile-width)*.26 - var(--ff-mobile-cloud-left-width));
}
.game-stage[data-corner-reels="masked-v103"][data-master-art="v105-fallback"]:is([data-fullframe="portrait"],[data-fullframe="desktop"])
 .reel-theatre > .jade-cloud-foreground--right{
 right:calc(var(--ff-tile-width)*.26 - var(--ff-mobile-cloud-right-width));
}
/* Keep compact landscape controls; no portrait source crop in side-panel UI. */
.game-stage[data-master-art="v105-locked"][data-fullframe="landscape"]
 .fullframe-art .art-crown{
 background-image:url('/assets/portrait-v085/frame.webp')!important;
 background-size:var(--ff-crown-width) calc(var(--ff-crown-unit)*1859)!important;
}
.game-stage[data-master-art="v105-locked"][data-fullframe="landscape"] .logo-fx{
 opacity:1!important;
}
.game-stage[data-master-art="v105-locked"][data-fullframe="landscape"] .game-header #menu-btn,
.game-stage[data-master-art="v105-locked"][data-fullframe="landscape"] .game-header #sound-btn{
 opacity:1!important;
}

/* In locked artwork mode the logo is painted inside the crown image, but the
   hidden legacy logo still needs a correctly proportioned (358:135) layout box
   for source-compatible accessible geometry and downstream layout checks. */
.game-stage[data-master-art="v105-locked"] .logo-fx{
 width:calc(var(--ff-crown-unit) * 358)!important;
 height:calc(var(--ff-crown-unit) * 135)!important;
 left:calc(var(--ff-crown-left) + var(--ff-crown-width)*.5 - var(--ff-crown-unit)*179)!important;
 opacity:0!important;
}
