/* Video feed, tap to play (reels/video-feed.js; Sai 2026-11-02). Only used when HOBBI_FEED_MODE is 'video'.
   Layers in #feed: the game track (0), the clip pager (2), caption (3), rail (4), top bar (5), intro (6), Back (7), the full-screen X (8).
   Fonts: the app's own (--hb-font-display Baloo, --hb-font-ui), never a serif fallback. */
/* The tabs: three feeds in a row (.vf-tabs) moved by a transform (video-feed.js setTabX), like each feed's track. The
   page owns every pan (touch-action none): video-feed.js decides one axis per gesture (round 8 axis lock). */
.vf-pager{position:absolute;inset:0;z-index:2;overflow:hidden;touch-action:none;background:var(--hb-night,#0a0c12)}
.vf-tabs{display:flex;width:100%;height:100%;will-change:transform;transform:translate3d(0,0,0)}
.vfeed{position:relative;flex:0 0 100%;height:100%;overflow:hidden;touch-action:none;background:var(--hb-night,#0a0c12)}
/* Each slide is its own compositing island: nothing inside it lays out or repaints while the pager moves. */
.vf-slide{position:relative;height:100%;width:100%;overflow:hidden;touch-action:none;cursor:pointer;-webkit-tap-highlight-color:transparent;contain:strict;background:var(--hb-night,#0a0c12)}
/* The clip's box: the whole screen, the clip edge to edge across and centred both ways, uncropped (contain). Its poster is the
   box's background, painted from the first frame; the <video> fades in over it once a real frame is shown. */
.vf-stage{position:absolute;inset:0;overflow:hidden;pointer-events:none}
/* The content window: exactly the clip's content box at scale k, centred and device-pixel snapped (video-fit.js). */
.vf-win{position:absolute;left:0;top:0;overflow:hidden;transform-origin:0 0;visibility:hidden}
.vf-win.fit{visibility:visible}
/* The clip's whole frame, sized and placed (video-feed.js fitClip) so its real content fits the screen whole, centred,
   the baked-in empty bands outside the window. The poster is its background from the first frame; the video fills it exactly. */
.vf-clip{position:absolute;left:0;top:0;background:center/100% 100% no-repeat;transform-origin:0 0}
.vf-video{position:absolute;inset:0;width:100%;height:100%;object-fit:fill;opacity:0;transition:opacity .12s linear;pointer-events:none;background:transparent}
.vf-video.on{opacity:1}
.vf-slide:not(.vf-end)::after{content:"";position:absolute;left:0;right:0;bottom:0;height:28%;background:linear-gradient(to top,rgba(10,12,18,.55),rgba(10,12,18,0));pointer-events:none}

/* Browse: the game stage stays hidden under the pager; the caption name sits on the clip, the long caption is off. */
html[data-feed-mode="video"] #feed:not(.vf-game-on) .feed-track{visibility:hidden}
html[data-feed-mode="video"] #feed.vf-opening .feed-track{visibility:visible}
html[data-feed-mode="video"] #feed:not(.vf-game) .feed-name{bottom:calc(var(--sa-safe-bottom,0px) + 28px);transition:none}
html[data-feed-mode="video"] #feed:not(.vf-game) .tt-caption{opacity:0;pointer-events:none}
html[data-feed-mode="video"] #feed:not(.vf-game) .social-rail{transition:none}

/* In a game: the clips are gone, the top bar gives way to Back (Sai, round 2), the game's own bet panel shows. */
#feed.vf-game #gamesButton,#feed.vf-game #sections,#feed.vf-game #railClips{visibility:hidden;pointer-events:none}
.vf-back{position:absolute;z-index:7;top:calc(var(--sa-safe-top,0px) + 6px);left:calc(var(--sa-safe-left,0px) + 10px);width:44px;height:44px;border:0;border-radius:999px;display:none;align-items:center;justify-content:center;padding:0;color:#fff;background:rgba(10,12,18,.38);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);-webkit-tap-highlight-color:transparent;transition:opacity .2s ease}
.vf-back svg{width:24px;height:24px;fill:none;stroke:#fff;stroke-width:2.6;stroke-linecap:round;stroke-linejoin:round}
.vf-back:active{transform:scale(.92)}
#feed.vf-game .vf-back{display:flex}
#feed.vf-game.playing .vf-back{opacity:0;pointer-events:none}
/* The state (video-feed.js apply: #feed[data-vf]): in the intro and in a game the pagers are not in the document at all;
   the rail is hidden there and in full screen, and shown and live while browsing. */
#feed[data-vf=intro] .social-rail,#feed[data-vf=game] .social-rail{visibility:hidden;pointer-events:none}
#feed[data-vf=browse]:not(.vf-full):not(.vf-end-on) .social-rail{visibility:visible;pointer-events:auto}
#feed.vf-game.vf-game-on .feed-name{opacity:0}
/* Full screen (Sai round 2): the rail and the side text go; the X under the top bar's right end brings them back. */
.vf-full-key .rail-icon svg{fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
#feed.vf-full .social-rail,#feed.vf-full .feed-name{opacity:0!important;visibility:hidden;pointer-events:none}
/* Round 8 (Sai: the X was too big): a 28 px glass key in the top bar's own style (--sa-glass, its line, rim and shadow)
   with a thin glyph, in a 44 px hit area. The top bar stays in full screen and the wallet holds its right end, so the X
   sits 10 px under the bar's keys with its edge on the bar's right margin (--sa-safe-right). Resting at 55 %; a touch
   anywhere brings it to full for 2.5 s (vf-x-awake). */
.vf-full-x{position:absolute;z-index:8;top:calc(var(--sa-safe-top,14px) + var(--sa-control,44px) + 2px);right:calc(var(--sa-safe-right,16px) - 8px);width:44px;height:44px;touch-action:manipulation;border:0;border-radius:999px;display:none;align-items:center;justify-content:center;padding:0;background:none;opacity:.55;transition:opacity .2s var(--sa-ease,ease-out);-webkit-tap-highlight-color:transparent}
.vf-full-x::before{content:"";position:absolute;left:8px;top:8px;width:28px;height:28px;box-sizing:border-box;border-radius:50%;background:var(--sa-glass,rgba(12,20,32,.34));border:1px solid var(--sa-glass-line,rgba(255,255,255,.2));-webkit-backdrop-filter:var(--sa-glass-blur,blur(18px));backdrop-filter:var(--sa-glass-blur,blur(18px));box-shadow:var(--sa-glass-rim,none),var(--sa-glass-shadow,none);transition:transform var(--sa-fast,.15s) var(--sa-spring,ease-out)}
.vf-full-x svg{position:relative;width:16px;height:16px;fill:none;stroke:var(--sa-text,#fff);stroke-width:2.2;stroke-linecap:round}
#feed.vf-x-awake .vf-full-x,.vf-full-x:focus-visible{opacity:1}
.vf-full-x:active::before{transform:scale(.9);background:var(--sa-glass-press,rgba(12,20,32,.3))}
#feed.vf-full .vf-full-x{display:flex}
#feed.vf-full.playing .vf-full-x{opacity:0;pointer-events:none}
.vf-buzz{position:absolute;width:1px;height:1px;overflow:hidden;opacity:0;pointer-events:none;left:-10px;top:-10px}

/* The intro: opaque, over everything from the tap until the game has drawn. It takes every touch. */
.vf-intro{--vf-font:var(--hb-font-ui,var(--sa-font,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif));--vf-display:var(--hb-font-display,var(--vf-font));position:absolute;inset:0;z-index:6;display:flex;align-items:center;justify-content:center;overflow:hidden;touch-action:none;pointer-events:auto;color:#fff;text-align:center;font-family:var(--vf-font);background:var(--hb-night,#0a0c12)}
.vf-intro[hidden]{display:none}
.vf-intro-poster{position:absolute;left:-60px;top:-60px;width:calc(100% + 120px);height:calc(100% + 120px);transform:scale(1.08);opacity:0;transition:opacity .16s linear,transform .9s cubic-bezier(.2,.8,.2,1)}
.vf-intro-shade{position:absolute;inset:0;background:radial-gradient(90% 55% at 50% 44%,rgba(10,12,18,.12),rgba(10,12,18,.78) 72%),linear-gradient(to bottom,rgba(10,12,18,.35),rgba(10,12,18,.2) 40%,rgba(10,12,18,.85));opacity:0;transition:opacity .16s linear}
.vf-intro.in .vf-intro-poster{opacity:.7;transform:scale(1)}
.vf-intro.in .vf-intro-shade{opacity:1}
.vf-intro-core{position:relative;display:flex;flex-direction:column;align-items:center;padding:0 24px;margin-top:-6vh}
.vf-star{width:184px;height:184px;opacity:0;transform:translateY(46vh) scale(.5);position:relative}
.vf-glow{position:absolute;left:50%;top:92px;width:320px;height:320px;margin:-160px 0 0 -160px;border-radius:50%;background:radial-gradient(closest-side,rgba(63,175,243,.42),rgba(63,175,243,0));opacity:0;pointer-events:none}
.vf-intro.in .vf-glow{animation:vf-rise .4s ease-out .1s forwards}
.vf-star canvas{display:block;width:184px!important;height:184px!important;image-rendering:pixelated}
.vf-intro.in .vf-star{animation:vf-spring .5s cubic-bezier(.2,1.45,.4,1) forwards,vf-bob 1.2s ease-in-out .55s infinite}
.vf-kicker{margin:18px 0 0;font:700 12px/1 var(--vf-font);letter-spacing:.16em;text-transform:uppercase;color:rgba(255,255,255,.7);opacity:0;transform:translateY(10px)}
.vf-name{margin:6px 0 0;font-family:var(--vf-display);font-weight:800;font-size:clamp(38px,12vw,52px);line-height:1;letter-spacing:-.01em;max-width:340px;text-shadow:0 4px 24px rgba(0,0,0,.45);opacity:0;transform:translateY(22px) scale(.96)}
.vf-cue{margin:16px 0 0;font-family:var(--vf-display);font-weight:800;font-size:26px;line-height:1;color:var(--hb-gold,#f2c14e);opacity:0;transform:translateY(10px)}
.vf-intro.in .vf-kicker{animation:vf-rise .28s ease-out .1s forwards}
.vf-intro.in .vf-name{animation:vf-rise .36s cubic-bezier(.2,1.3,.4,1) .12s forwards}
.vf-intro.in .vf-cue{animation:vf-rise .26s ease-out .3s forwards,vf-breathe .9s ease-in-out .6s infinite}
.vf-bar{width:132px;height:3px;margin-top:20px;border-radius:2px;background:rgba(255,255,255,.14);overflow:hidden;opacity:0;transition:opacity .3s}
.vf-bar i{display:block;width:40%;height:100%;background:rgba(255,255,255,.85);border-radius:2px;animation:vf-indet 1.1s ease-in-out infinite}
.vf-intro.slow .vf-bar{opacity:1}
.vf-intro.play .vf-cue{animation:vf-pop .3s cubic-bezier(.2,1.6,.4,1) forwards;color:#fff;text-shadow:0 0 22px rgba(242,193,78,.95)}
.vf-intro.play .vf-star{animation:vf-jump .3s cubic-bezier(.3,1.4,.5,1) forwards}
.vf-flash{position:absolute;inset:0;background:radial-gradient(60% 45% at 50% 46%,rgba(255,255,255,.95),rgba(255,255,255,0) 70%);opacity:0;pointer-events:none}
.vf-sweep{position:absolute;inset:-25%;background:conic-gradient(from 0deg at 50% 50%,rgba(63,175,243,0),rgba(63,175,243,.55),rgba(242,193,78,.5),rgba(63,175,243,0) 40%);opacity:0;pointer-events:none}
/* The snap (0.45 s): a flash and a sweep, the intro scales up and clears off the game already drawn under it. */
.vf-intro.snap{pointer-events:none;animation:vf-out .45s cubic-bezier(.5,0,.75,0) forwards}
.vf-intro.snap .vf-flash{animation:vf-flash .45s ease-out forwards}
.vf-intro.snap .vf-sweep{animation:vf-sweep .45s ease-out forwards}
.vf-fail{position:relative;display:flex;flex-direction:column;align-items:center;gap:16px;padding:22px 20px;border-radius:22px;background:rgba(20,24,34,.94);width:min(320px,calc(100% - 48px))}
.vf-fail[hidden]{display:none}
.vf-fail-title{margin:0;font:700 18px/1.25 var(--vf-font)}
.vf-fail-actions{display:flex;gap:10px;width:100%}
.vf-fail-actions button{flex:1;min-height:48px;border-radius:14px;border:0;font:700 16px/1 var(--vf-font);color:#fff;background:rgba(255,255,255,.12)}
.vf-fail-actions .vf-retry{background:var(--hb-blue,#3faff3);color:#0a0c12}
@keyframes vf-spring{to{transform:translateY(0) scale(1);opacity:1}}
@keyframes vf-bob{0%,100%{transform:translateY(0) scale(1)}50%{transform:translateY(-7px) scale(1.02,.98)}}
@keyframes vf-rise{to{opacity:1;transform:translateY(0) scale(1)}}
@keyframes vf-breathe{0%,100%{opacity:1}50%{opacity:.6}}
@keyframes vf-pop{0%{transform:scale(.7);opacity:.6}60%{transform:scale(1.28);opacity:1}100%{transform:scale(1);opacity:1}}
@keyframes vf-jump{0%{transform:translateY(0) scale(1)}40%{transform:translateY(-30px) scale(.94,1.08)}100%{transform:translateY(-10px) scale(1.08)}}
@keyframes vf-indet{0%{transform:translateX(-110%)}100%{transform:translateX(260%)}}
@keyframes vf-flash{0%{opacity:0}25%{opacity:.85}100%{opacity:0}}
@keyframes vf-sweep{0%{opacity:0;transform:rotate(0) scale(.8)}30%{opacity:1}100%{opacity:0;transform:rotate(200deg) scale(1.4)}}
@keyframes vf-out{0%{opacity:1;transform:scale(1)}35%{opacity:1;transform:scale(1.04)}100%{opacity:0;transform:scale(1.18)}}
@media (prefers-reduced-motion:reduce){.vf-intro *,.vf-intro{animation-duration:.01s!important;animation-delay:0s!important;animation-iteration-count:1!important}.vf-intro.in .vf-star,.vf-intro.in .vf-kicker,.vf-intro.in .vf-name,.vf-intro.in .vf-cue{opacity:1;transform:none}}
/* The document never scrolls in the video feed (iOS: no page bounce behind the pagers or a game). */
html[data-feed-mode=video],html[data-feed-mode=video] body{overflow:hidden;overscroll-behavior:none}
/* The Hobbi blue brand backdrop behind a clip that doesn't fill the screen (Sai round 3): the feed's dither field with the
   mark pattern (--pv-edges, drawn once by social-feed.js paintBrandFields) over the night colour; the rise field until
   it is painted. Static, centred, no blur, no repeated frame. */
.vf-stage.vf-banded{background:var(--pv-edges,var(--pv-rise,none)) center/100% 100% no-repeat,var(--hb-accent-shade,#296b95);image-rendering:pixelated}
/* The vertical pager's track (video-feed.js place): moved by translate3d, snapped on the compositor. */
.vf-track{position:relative;height:100%;will-change:transform;transform:translate3d(0,0,0)}
/* Round 8: "More games coming", the last page of every tab. The blue Hobbi field (the clip stages' backdrop), the
   mascot (a whole number of device pixels per cell: crisp) and the app's display font. Not a game: no pointer, no tap. */
.vf-end{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;cursor:default;background:var(--pv-edges,var(--pv-rise,none)) center/100% 100% no-repeat,var(--hb-accent-shade,#296b95);image-rendering:pixelated}
.vf-end-star{display:grid;place-items:center;min-height:150px;filter:drop-shadow(0 10px 28px rgba(0,0,0,.35))}
.vf-end-title{margin:0;font-family:var(--hb-font-display,var(--hb-font-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif));font-weight:800;font-size:clamp(26px,8vw,32px);line-height:1.1;color:var(--sa-text,#fff);text-align:center;text-shadow:0 3px 18px rgba(0,0,0,.4);image-rendering:auto}
#feed.vf-end-on .social-rail,#feed.vf-end-on .feed-name{opacity:0!important;visibility:hidden;pointer-events:none}
/* Back: the clips fade in over the game's last frame (video-feed.js dissolveFrom), so the change of framing is a dissolve. */
.vf-pager.vf-in{animation:vf-fade-in .2s ease-out both}
@keyframes vf-fade-in{from{opacity:0}to{opacity:1}}
