/* Montserrat, self-hosted (fonts/montserrat, SIL OFL 1.1; the variable 100-900 faces of the SB Lucky 6 / SB Lucky Greek TVs,
   sga/slot-engine six-for-win-tv/fonts): the guide reads as our TVs do (Founder 2026-10-25). Arabic keeps Rubik's Arabic
   face below (Montserrat has none); Greek, Devanagari, Gujarati and Han fall to the TV's own system face. */
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('fonts/montserrat/montserrat-0.woff2?v=e7893a06eb38') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('fonts/montserrat/montserrat-1.woff2?v=e7893a06eb38') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('fonts/montserrat/montserrat-2.woff2?v=e7893a06eb38') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('fonts/montserrat/montserrat-3.woff2?v=e7893a06eb38') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('fonts/montserrat/montserrat-4.woff2?v=e7893a06eb38') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* The scripts Montserrat lacks, in the family Montserrat (one family and weight for every menu language; no box ever, Founder
   2026-10-25): Noto Sans (OFL, fonts/scripts, scripts/script-fonts.py), variable 400-900, declared 100-900 like the Montserrat faces (Chrome draws a family from the faces of ONE weight
   descriptor: a 400-900 face next to 100-900 ones was never used); a face loads only when its script is drawn. */
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('fonts/scripts/script-greek.woff2?v=e7893a06eb38') format('woff2');
  unicode-range: U+0370-03FF, U+1F00-1FFF;
}
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('fonts/scripts/script-devanagari.woff2?v=e7893a06eb38') format('woff2');
  unicode-range: U+0900-097F, U+A8E0-A8FF, U+200C-200D;
}
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('fonts/scripts/script-gujarati.woff2?v=e7893a06eb38') format('woff2');
  unicode-range: U+0A80-0AFF, U+200C-200D;
}
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('fonts/scripts/script-han.woff2?v=e7893a06eb38') format('woff2');
  unicode-range: U+3000-303F, U+4E00-9FFF, U+FF00-FFEF;
}
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('fonts/scripts/script-symbols.woff2?v=e7893a06eb38') format('woff2');
  unicode-range: U+25A0-25FF;
}
/* Rubik, self-hosted (fonts/rubik, SIL OFL 1.1, Google Fonts v31 variable 300-900): the guide named it with no
   @font-face, so every TV drew the system font (Founder 2026-10-08, lux-1000). */
@font-face {
  font-family: 'Rubik';
  font-style: normal;
  font-weight: 300 900;
  font-display: swap;
  src: url('fonts/rubik/rubik-arabic.woff2?v=e7893a06eb38') format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC;
}
@font-face {
  font-family: 'Rubik';
  font-style: normal;
  font-weight: 300 900;
  font-display: swap;
  src: url('fonts/rubik/rubik-cyrillic-ext.woff2?v=e7893a06eb38') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-family: 'Rubik';
  font-style: normal;
  font-weight: 300 900;
  font-display: swap;
  src: url('fonts/rubik/rubik-cyrillic.woff2?v=e7893a06eb38') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Rubik';
  font-style: normal;
  font-weight: 300 900;
  font-display: swap;
  src: url('fonts/rubik/rubik-latin-ext.woff2?v=e7893a06eb38') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Rubik';
  font-style: normal;
  font-weight: 300 900;
  font-display: swap;
  src: url('fonts/rubik/rubik-latin.woff2?v=e7893a06eb38') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* The venue TV: one channel frame plus a Smart-TV style guide around it.
   Deliberately not tied to any tenant theme: colourful tiles per channel, glass panels.
   Every value of the guide comes from guide-layout.json (the one source shared with the native TV shell): guide.js sets
   it on <html> as --<its path in kebab-case> (colors.* as --<name>) before anything is drawn; this file only uses them. */
:root {
  --gz: 1;            /* guide scale: the layout is drawn for 1920x1080; guide.js sets this on smaller screens (Fold, tablets) */
}
* { box-sizing: border-box; }
[hidden] { display: none !important; }
html, body { margin: 0; width: 100%; height: 100%; overflow: hidden; background: var(--black); color: var(--txt);
  font-family: 'Montserrat', 'Rubik', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  -webkit-user-select: none; user-select: none; -webkit-tap-highlight-color: transparent; }
button { font: inherit; color: inherit; }

/* ---------- the channel frame ---------- */
.stage { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; transform-origin: top right;
  transition: transform var(--frame-transition-ms) var(--frame-ease), border-radius var(--frame-transition-ms), box-shadow var(--frame-transition-ms); z-index: 1; overflow: hidden; background: var(--black); }
.stage iframe.top-fixed { position: absolute; left: 0; top: 0; width: var(--stage-w); height: var(--stage-h); transform-origin: 0 0; }
body.top-screen { background: var(--black); }
.stage iframe { width: 100%; height: 100%; border: 0; display: block; pointer-events: none; background: var(--black); transition: opacity var(--frame-switch-fade-ms) ease; }
.stage.switching iframe { opacity: 0; }
/* the channel's tile while its frame loads (guide.js tileWhileLoading) */
body .stage.loading { background-size: contain; background-position: center; background-repeat: no-repeat; }
body .stage.loading iframe { background: transparent; }
body.guide-open .stage { cursor: pointer; }
body.guide-open .stage { transform: translate(calc(var(--frame-guide-offset-0) * var(--gz)), calc(var(--frame-guide-offset-1) * var(--gz))) scale(var(--frame-guide-zoom)); border-radius: var(--frame-radius);
  box-shadow: 0 0 0 var(--frame-ring-w) var(--frame-ring), var(--frame-shadow); z-index: 3; }

.banner, .digits { zoom: var(--gz); } /* the corner hotspot keeps its full size: it is a finger's target */
.hotspot { position: fixed; top: 0; left: 0; width: var(--hotspot-w); height: var(--hotspot-h); border: 0; background: transparent; z-index: 5; cursor: pointer; }
/* The corner stays while the guide is open: a pointer remote (Hisense/VIDAA) has no Back key the page sees,
   so OK on the corner is its way out (cancel). */
.keys { position: fixed; left: var(--keys-left); bottom: var(--keys-bottom); z-index: 9; font: var(--keys-weight) var(--keys-size)/var(--keys-line-height) system-ui, sans-serif; color: var(--keys-color);
        background: var(--keys-bg); padding: var(--keys-pad); border-radius: var(--keys-radius); pointer-events: none; }

/* ---------- colourful tiles (shared by rail, banner, info) ---------- */
.tile { background: var(--grad); }
[data-tone="green"]   { --grad: var(--tones-green-grad); --glow: var(--tones-green-glow); }
[data-tone="orange"]  { --grad: var(--tones-orange-grad); --glow: var(--tones-orange-glow); }
[data-tone="lime"]    { --grad: var(--tones-lime-grad); --glow: var(--tones-lime-glow); }
[data-tone="ice"]     { --grad: var(--tones-ice-grad); --glow: var(--tones-ice-glow); }
[data-tone="gold"]    { --grad: var(--tones-gold-grad); --glow: var(--tones-gold-glow); }
[data-tone="violet"]  { --grad: var(--tones-violet-grad); --glow: var(--tones-violet-glow); }
[data-tone="pink"]    { --grad: var(--tones-pink-grad); --glow: var(--tones-pink-glow); }
[data-tone="cyan"]    { --grad: var(--tones-cyan-grad); --glow: var(--tones-cyan-glow); }
[data-tone="red"]     { --grad: var(--tones-red-grad); --glow: var(--tones-red-glow); }
[data-tone="brown"]   { --grad: var(--tones-brown-grad); --glow: var(--tones-brown-glow); }
[data-tone="indigo"]  { --grad: var(--tones-indigo-grad); --glow: var(--tones-indigo-glow); }
[data-tone="rainbow"] { --grad: var(--tones-rainbow-grad); --glow: var(--tones-rainbow-glow); }
.glyph { display: grid; place-items: center; }
.glyph img { width: var(--glyph-size); height: var(--glyph-size); object-fit: contain; filter: brightness(0) invert(1) drop-shadow(var(--glyph-shadow)); }
.glyph svg { width: var(--glyph-size); height: var(--glyph-size); fill: var(--glyph-color); filter: drop-shadow(var(--glyph-shadow)); }

/* ---------- channel banner (watching) ---------- */
.banner { position: fixed; left: var(--banner-left); bottom: var(--banner-bottom); z-index: 6; display: flex; align-items: center; gap: var(--banner-gap);
  max-width: calc(100vw / var(--gz) - 2 * var(--banner-left));
  min-width: var(--banner-min-w); padding: var(--banner-pad); border-radius: var(--banner-radius); background: var(--banner-bg); border: var(--hairline) solid var(--line);
  box-shadow: var(--banner-shadow); overflow: hidden; animation: rise var(--banner-rise-ms) var(--frame-ease); }
.banner-tile { width: var(--banner-tile); height: var(--banner-tile); border-radius: var(--banner-tile-radius); flex: 0 0 auto; background: var(--grad); display: grid; place-items: center; box-shadow: var(--banner-tile-shadow); }
.banner-tile .banner-glyph { width: 100%; height: 100%; }
.banner-top { display: flex; align-items: center; gap: var(--banner-top-gap); }
.banner-num { font-weight: var(--banner-num-weight); font-size: var(--banner-num-size); color: var(--banner-num-color); background: var(--banner-num-bg); border-radius: var(--banner-num-radius); padding: var(--banner-num-pad); }
.banner-kind { font-size: var(--banner-kind-size); font-weight: var(--banner-kind-weight); color: var(--dim); text-transform: uppercase; letter-spacing: var(--banner-kind-spacing); }
.banner-name { font-size: var(--banner-name-size); font-weight: var(--banner-name-weight); line-height: var(--banner-name-line-height); margin-top: var(--banner-name-top); overflow-wrap: break-word; }
.banner-meta { margin-top: var(--banner-meta-top); font-size: var(--banner-meta-size); color: var(--dim); display: flex; gap: var(--banner-meta-gap); align-items: center; }
.banner-bar { position: absolute; left: 0; right: 0; bottom: 0; height: var(--banner-bar-h); background: var(--banner-bar-bg); }
.banner-bar span { display: block; height: 100%; background: var(--grad); animation: drain var(--timing-banner-ms) linear forwards; }
@keyframes drain { from { width: 100%; } to { width: 0; } }
@keyframes rise { from { transform: translateY(var(--banner-rise-px)); opacity: 0; } to { transform: none; opacity: 1; } }

.digits { position: fixed; top: var(--digits-top); right: var(--digits-right); z-index: 7; font-size: var(--digits-size); font-weight: var(--digits-weight); letter-spacing: var(--digits-spacing);
  padding: var(--digits-pad); border-radius: var(--digits-radius); background: var(--digits-bg); border: var(--hairline) solid var(--line); }

.live-pill { display: inline-flex; align-items: center; gap: var(--live-pill-gap); font-size: var(--live-pill-size); font-weight: var(--live-pill-weight); letter-spacing: var(--live-pill-spacing); color: var(--live-pill-color); background: var(--live); border-radius: var(--live-pill-radius); padding: var(--live-pill-pad); }
.live-dot { width: var(--live-pill-dot); height: var(--live-pill-dot); border-radius: 50%; background: currentColor; animation: pulse var(--live-pill-pulse-ms) ease-in-out infinite; }
@keyframes pulse { 50% { opacity: var(--live-pill-pulse-opacity); } }

/* ---------- guide ---------- */
.guide { position: fixed; inset: 0; z-index: 2; zoom: var(--gz); opacity: 0; transition: opacity var(--guide-fade-ms) ease; pointer-events: none; }
body.guide-open .guide { opacity: 1; pointer-events: auto; }
.guide .rail, .guide .info, .guide .guide-top { transition: transform var(--guide-slide-ms) var(--frame-ease); }
body:not(.guide-open) .guide .rail { transform: translateX(var(--guide-enter-rail-x)); }
body:not(.guide-open) .guide .info { transform: translateY(var(--guide-enter-info-y)); }
body:not(.guide-open) .guide .guide-top { transform: translateY(var(--guide-enter-top-y)); }
/* The background stands still (Founder 2026-10-25: the preview stuttered): the colour drift animated a full-screen layer
   under the playing preview on every frame. Nothing over the playing picture blurs it (banner, digits: a solid glass) and no
   blurred glow is re-rasterised around the preview, the focused row or the info panel. */
.guide-bg { position: absolute; inset: 0; background: var(--guide-bg), var(--bg); }
.guide-top { position: absolute; top: var(--guide-top-top); left: var(--guide-top-left); right: var(--guide-top-right); height: var(--guide-top-h); display: flex; align-items: center; gap: var(--guide-top-gap); z-index: 4; }
.guide-title { display: flex; align-items: center; gap: var(--guide-top-title-gap); font-size: var(--guide-top-title-size); font-weight: var(--guide-top-title-weight); letter-spacing: var(--guide-top-title-spacing); }
.tv-chip { font-size: var(--guide-top-chip-size); padding: var(--guide-top-chip-pad); border-radius: var(--guide-top-chip-radius); color: var(--guide-top-chip-color); background: var(--guide-top-chip-grad); }
.guide-clock { margin-left: auto; font-size: var(--guide-top-clock-size); font-weight: var(--guide-top-clock-weight); color: var(--dim); font-variant-numeric: tabular-nums; }

.rail { position: absolute; top: var(--guide-rail-top); bottom: var(--guide-rail-bottom); left: var(--guide-rail-left); width: var(--guide-rail-w); overflow-y: auto; overflow-x: hidden;
  padding: var(--guide-rail-pad); scroll-behavior: smooth; z-index: 4; scrollbar-width: none; }
.rail::-webkit-scrollbar { display: none; }
.rail-group { margin: var(--guide-rail-group-margin); font-size: var(--guide-rail-group-size); font-weight: var(--guide-rail-group-weight); letter-spacing: var(--guide-rail-group-spacing); text-transform: uppercase; color: var(--dim); }
.ch { display: flex; align-items: center; gap: var(--guide-rail-row-gap); width: 100%; padding: var(--guide-rail-row-pad); margin: 0 0 var(--guide-rail-row-bottom); border: 0; border-radius: var(--guide-rail-row-radius);
  background: var(--guide-rail-row-bg); cursor: pointer; text-align: left; transition: transform var(--guide-rail-row-transition-ms), background var(--guide-rail-row-transition-ms), box-shadow var(--guide-rail-row-transition-ms); }
.ch:active { transform: scale(var(--guide-rail-row-press-scale)); }
.ch-tile { width: var(--guide-rail-tile-w); height: var(--guide-rail-tile-h); border-radius: var(--guide-rail-tile-radius); background: var(--grad); flex: 0 0 auto; box-shadow: var(--guide-rail-tile-shadow); }
.ch-num { width: var(--guide-rail-num-w); font-size: var(--guide-rail-num-size); font-weight: var(--guide-rail-num-weight); color: var(--dim); text-align: right; flex: 0 0 auto; }
.ch-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: var(--guide-rail-text-gap); }
/* a name is never cut (no ellipsis): a long one takes a second line */
.ch-name { font-size: var(--guide-rail-name-size); font-weight: var(--guide-rail-name-weight); line-height: var(--guide-rail-name-line-height); overflow-wrap: break-word; }
.ch-meta { font-size: var(--guide-rail-meta-size); color: var(--dim); display: flex; flex-wrap: wrap; align-items: center; gap: var(--guide-rail-meta-gap); }
.ch.focus { background: var(--guide-rail-row-focus-bg); transform: scale(var(--guide-rail-row-focus-scale)); box-shadow: 0 0 0 var(--guide-rail-row-focus-ring) var(--focus), var(--guide-rail-row-focus-shadow); }
.ch.current .ch-num { color: var(--guide-rail-num-current-color); }
.ch.current::after { content: ''; width: var(--guide-rail-row-dot-size); height: var(--guide-rail-row-dot-size); border-radius: 50%; background: var(--live); margin-left: auto; box-shadow: 0 0 var(--guide-rail-row-dot-glow) var(--live); }
.ch.empty { opacity: var(--guide-rail-row-empty-opacity); }
/* a row or heading the rail's edge would cut is not shown while it is not wholly in view (guide.js markCut) */
.rail > .cut { opacity: 0 !important; transition: none !important; }

.info { position: absolute; right: var(--guide-info-right); bottom: var(--guide-info-bottom); left: calc(var(--guide-rail-w) + var(--guide-info-left-from-rail)); height: var(--guide-info-h); z-index: 4; display: flex; gap: var(--guide-info-gap); align-items: center;
  padding: var(--guide-info-pad); border-radius: var(--guide-info-radius); background: var(--glass); border: var(--hairline) solid var(--line); }
/* No backdrop-filter on the info panel: it sits on the guide's smooth gradient, never on the picture, so a blur
   changed nothing visible while re-blurring 1100x262 px on every scroll frame of the channel list. */
.info-tile { width: var(--guide-info-tile-w); height: var(--guide-info-tile-h); border-radius: var(--guide-info-tile-radius); background: var(--grad); flex: 0 0 auto; box-shadow: var(--guide-info-tile-shadow); }
.info-tile .info-glyph { width: 100%; height: 100%; }
.info-top { display: flex; align-items: center; gap: var(--guide-info-top-gap); }
.info-num { font-size: var(--guide-info-num-size); font-weight: var(--guide-info-num-weight); color: var(--guide-info-num-color); background: var(--guide-info-num-bg); border-radius: var(--guide-info-num-radius); padding: var(--guide-info-num-pad); }
.info-kind { font-size: var(--guide-info-kind-size); font-weight: var(--guide-info-kind-weight); letter-spacing: var(--guide-info-kind-spacing); text-transform: uppercase; color: var(--dim); }
.info-body { flex: 1 1 auto; min-width: 0; }
.info-name { font-size: var(--guide-info-name-size); font-weight: var(--guide-info-name-weight); line-height: var(--guide-info-name-line-height); margin-top: var(--guide-info-name-top); overflow-wrap: break-word; }
.info-desc { font-size: var(--guide-info-desc-size); color: var(--dim); margin-top: var(--guide-info-desc-top); display: flex; flex-wrap: wrap; align-items: center; gap: var(--guide-info-desc-gap); }
.info-hint { font-size: var(--guide-info-hint-size); margin-top: var(--guide-info-hint-top); color: var(--guide-info-hint-color); display: flex; gap: var(--guide-info-hint-gap); align-items: center; }
.key { font-size: var(--guide-key-size); font-weight: var(--guide-key-weight); padding: var(--guide-key-pad); border-radius: var(--guide-key-radius); border: var(--hairline) solid var(--line); background: var(--guide-key-bg); }

/* ---------- pictures: always WHOLE (Founder 2026-10-25: "Svaka ikonica svugde mora cela da se vidi, ne može da odseče na
   pola brojeva") ----------
   A game's artwork and a race's frame keep their own aspect (our tiles 1280x861, a studio's 510x340, 800x600, 1200x630, a
   race frame 16:9): the tile is a box of the guide's standard picture shape (guide-layout.json tile w x h = 1.486:1, our
   tiles) and the picture is drawn as large as fits in it, centred, at its own aspect: never cropped to the box (no
   object-fit / background-size cover), never stretched, nothing over it (no badge, no shade). Its corners are rounded by
   at most 5 % of its height (artRadius). test/gate/whole.mjs fails on any crop, at every breakpoint and in every language. */
.ch-tile.art, .info-tile.art { background: none; box-shadow: none; display: flex; align-items: center; justify-content: center; }
.art-img, .glyph img.art-img { display: block; width: auto; height: auto; max-width: 100%; max-height: 100%; object-fit: contain; filter: none; }
.ch-tile .art-img { border-radius: var(--guide-rail-tile-art-radius); box-shadow: var(--guide-rail-tile-art-shadow); }
.info-tile .art-img { border-radius: var(--guide-info-tile-art-radius); box-shadow: var(--guide-info-tile-art-shadow); }
/* Happy Hour's gold tile (guide.js hhTwin): the same picture recoloured, right over it at the same place and size, crossfaded in
   while the game's Happy Hour runs; it is the picture itself, never something over it */
.ch-tile.art.has-hh, .info-tile.art.has-hh { position: relative; }
.art-img.art-hh { position: absolute; left: 0; top: 0; width: 100%; height: 100%; max-width: none; max-height: none; object-fit: contain; opacity: 0;
  transition: opacity var(--tiles-hh-fade-ms, 800ms) ease; box-shadow: none; }
.hh-on > .art-img.art-hh { opacity: 1; }

/* ---------- crash channels: the real client cropped to its flight and live bets ---------- */
.stage.cropped { background: var(--crash-bg); }
.stage iframe.cropped { position: absolute; left: 0; top: 0; width: var(--stage-w); height: var(--stage-h); transform-origin: 0 0; }
/* The kiosk's top screen (guide.js TOP): a channel with no page (the Arcade, the advertising skeleton) is black. */
.stage iframe[src="about:blank"] { visibility: hidden; }

/* ---------- attract mode (Founder 2026-10-20, v3): the tenant's ads on a free terminal's top screen ----------
   The terminal below shows itself (its tour); up here only ads, drawn on one 1920x1080 canvas (guide.js attractFit
   scales it onto the 16:9 box); only transform and opacity animate. Looks: b = Studio (crossfade, the Founder's pick),
   a = the logo's slanted bands wipe across, c = neon. */
:root { --atr-accent: #8bd508; --atr-ease: cubic-bezier(.22,.8,.22,1); }
#attract { position: fixed; inset: 0; overflow: hidden; pointer-events: none; z-index: 2; background: #000; }
body.attract { background: #000; }
.atr-canvas { position: absolute; left: 0; top: 0; width: 1920px; height: 1080px; transform-origin: 0 0; overflow: hidden; contain: layout paint;
  font-family: 'Rubik', system-ui, sans-serif; color: #fff; background: #040604; }
.atr-layer { position: absolute; inset: 0; }
.atr-logo { position: absolute; left: 56px; top: 40px; height: 64px; width: auto; z-index: 6; filter: drop-shadow(0 6px 18px rgba(0,0,0,.6)); }
body.attract .atr-canvas:has(.atr-current.atr-ad-intro) .atr-logo { opacity: 0; }
/* SB Jackpots: the engine's scene fills the canvas; it carries its own wordmark, so the tenant's logo steps aside */
.atr-ad-jackpots be-jackpots { position: absolute; inset: 0; display: block; width: 100%; height: 100%; }
body.attract .atr-canvas:has(.atr-current.atr-ad-jackpots) .atr-logo { opacity: 0; }
.atr-ad { position: absolute; inset: 0; overflow: hidden; background: #040604; will-change: opacity, transform;
  transition: opacity .8s var(--atr-ease), transform .8s var(--atr-ease); }
.atr-ad.atr-in { opacity: 0; transform: scale(1.05); }
.atr-ad.atr-out { opacity: 0; transition-duration: .5s; }
/* the ad on screen over the one going, the next ad built ahead (prepareAd) under both: covered, drawn, ready at its slot */
.atr-ad.atr-current { z-index: 2; }
.atr-ad.atr-out { z-index: 1; }
.atr-ad.atr-prep { z-index: 0; transition: none; pointer-events: none; }
.atr-ad.atr-cut, .atr-ad.atr-cut.atr-out { transition: none; }
.atr-ad.atr-cut.atr-in { opacity: 1; transform: none; }
.attract-a .atr-ad.atr-in, .attract-c .atr-ad.atr-in { transform: none; }
/* a cms banner as designed: its motif right, the dark left for the words; the same picture blurred around it */
.atr-blur { position: absolute; inset: -6%; width: 112%; height: 112%; object-fit: cover; filter: blur(36px) saturate(1.3) brightness(.45); }
/* The banner stands still (Founder's performance gate 2026-10-20: a 14 s zoom of the whole banner kept the top screen's
   Chromium at 14 % of a core on spb-1000; still, the screen costs nothing between two ads). The motion is the change of
   ad and the entrance of its words; between two ads only the plate's arrow moves (a small layer). */
/* Founder 2026-10-20: the banner as big as the 16:9 screen allows (the whole canvas, no bands); the cms banners put their
   motif on the right and leave the left for the words, so the picture keeps its right edge and gives up its empty left. */
.atr-art { position: absolute; left: 0; top: 0; width: 1920px; height: 1080px; object-fit: cover; object-position: 100% 50%; }
.atr-shade { position: absolute; inset: 0; background: linear-gradient(90deg, rgba(0,0,0,.88) 0, rgba(0,0,0,.62) 30%, rgba(0,0,0,0) 50%),
  linear-gradient(0deg, rgba(4,6,4,.75) 0, rgba(4,6,4,0) 28%); }
.atr-card { position: absolute; right: 110px; top: 150px; width: 900px; height: 600px; object-fit: cover; border-radius: 40px;
  box-shadow: 0 40px 90px rgba(0,0,0,.65); border: 3px solid rgba(255,255,255,.12); animation: atr-rise .7s var(--atr-ease) .1s both; }
.atr-words { position: absolute; left: 96px; top: 160px; width: 1000px; }
/* over a cms banner the words keep to its empty left (the motif is on the right): never more than ~42 % of its width */
.atr-ad:has(.atr-art) .atr-words { width: 720px; }
.atr-ad-game .atr-words { width: 780px; }
.atr-ad-game:has(.atr-art) .atr-words { width: 720px; }
/* a promotion with a QR: the banner smaller, top left, its whole motif in view; the QR in a panel beside it; the small
   print under the banner. Nothing over the motif. */
/* a promotion with a QR (Founder 2026-10-20): the banner over the whole screen as every ad; the QR inside the banner's
   empty left, under the headline, never over the motif on the right. The small print above the QR. */
.atr-ad.atr-ad-qr:has(.atr-art) .atr-words { top: 120px; width: 640px; }
.atr-ad-qr .atr-title { font-size: 128px; }
.atr-band { position: absolute; left: 96px; top: 470px; width: 640px; font-size: 34px; line-height: 1.25; font-weight: 600; color: rgba(255,255,255,.85);
  animation: atr-rise .6s var(--atr-ease) .45s both; }
.atr-qrpanel { position: absolute; left: 96px; bottom: 96px; display: flex; flex-direction: row; align-items: center; gap: 34px;
  animation: atr-rise .6s var(--atr-ease) .3s both; text-align: left; }
.atr-qrpanel .atr-qr { position: static; animation: none; padding: 16px; border-radius: 22px; }
.atr-qrpanel .atr-qr svg { width: 260px; height: 260px; }
.atr-qrpanel .atr-qr-cap { font-size: 22px; max-width: 260px; }
.atr-qrpanel .atr-onsite { position: static; animation: none; font-size: 34px; font-weight: 700; color: rgba(255,255,255,.8); }
.atr-host { font-size: 46px; font-weight: 900; color: var(--atr-accent); overflow-wrap: anywhere; max-width: 330px; }
.atr-qrtext { display: flex; flex-direction: column; gap: 10px; }
.atr-kicker { line-height: 1.2; font-size: 34px; font-weight: 800; letter-spacing: .2em; text-transform: uppercase; color: var(--atr-accent); animation: atr-slide .6s var(--atr-ease) both; }
.atr-title { margin-top: 14px; font-size: 150px; font-weight: 900; line-height: 1; letter-spacing: -.02em; text-transform: uppercase; white-space: nowrap; overflow: hidden;
  animation: atr-slam .65s cubic-bezier(.2,1.4,.3,1) .12s both; }
.atr-sub { margin-top: 24px; font-size: 38px; font-weight: 500; line-height: 1.25; color: rgba(255,255,255,.78); animation: atr-rise .6s var(--atr-ease) .45s both; }
.atr-site .atr-title { font-size: 190px; text-transform: none; }
.atr-ad-site .atr-words { top: 230px; width: 1150px; }
.atr-count { position: absolute; left: 96px; bottom: 210px; animation: atr-rise .6s var(--atr-ease) .6s both; }
.atr-count-label { font-size: 34px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: rgba(255,255,255,.75); }
.atr-count-num { font-size: 150px; font-weight: 900; line-height: .95; color: var(--atr-accent); font-variant-numeric: tabular-nums; }
.atr-below { position: absolute; left: 96px; bottom: 96px; padding: 12px 36px; transform: skewX(-14deg); border-radius: 6px; background: var(--atr-accent); color: #0b1400;
  animation: atr-rise .6s var(--atr-ease) .75s both; }
.atr-below span { display: inline-block; transform: skewX(14deg); font-size: 42px; font-weight: 800; white-space: nowrap; }
/* Pocket Play (the approved poster): its art fills the canvas as drawn; the words on its dark left, the call above the phone */
.atr-ad-pp .atr-pp-art { object-position: 50% 50%; }
.atr-pp-shade { position: absolute; left: 0; top: 0; width: 1100px; height: 800px; background: radial-gradient(ellipse at 20% 30%, rgba(0,0,0,.55) 0, rgba(0,0,0,0) 70%); }
.atr-ad.atr-ad-pp:has(.atr-art) .atr-words { top: 160px; width: 450px; }
.atr-ad-pp .atr-title { font-size: 60px; line-height: 1.04; white-space: normal; text-transform: none; }
.atr-ad-pp .atr-sub { margin-top: 18px; font-size: 27px; }
/* the call is as wide as the poster's phone and on its edges (phone x 24..581, top y 805), just above it */
.atr-ad-pp .atr-below { left: 24px; width: 557px; bottom: 289px; box-sizing: border-box; padding: 12px 20px; text-align: center; }
.atr-ad-pp .atr-below span { font-size: 34px; }
.atr-arrow { display: inline-block; font-style: normal; animation: atr-bob 1.4s ease-in-out infinite; will-change: transform; }
@keyframes atr-bob { 0%, 100% { transform: translate3d(0, -4px, 0); } 50% { transform: translate3d(0, 6px, 0); } }
.atr-facts { position: absolute; left: 96px; top: 660px; display: flex; gap: 16px; animation: atr-rise .6s var(--atr-ease) .6s both; }
.atr-fact { padding: 14px 24px; border-radius: 16px; background: rgba(255,255,255,.08); border: 2px solid rgba(255,255,255,.12); font-size: 32px; font-weight: 700; }
/* a game's name enters from the left, never scaled up over the picture card beside it (Founder 2026-10-21) */
.atr-ad-game .atr-title { animation-name: atr-slide; white-space: normal; overflow-wrap: normal; }
/* a game's facts keep to the words' column (the picture card is on the right): a second line rather than over it */
.atr-ad-game .atr-facts { max-width: 780px; flex-wrap: wrap; }
.atr-qr { position: absolute; right: 110px; top: 120px; padding: 20px; border-radius: 26px; background: #fff; text-align: center; box-shadow: 0 20px 60px rgba(0,0,0,.55);
  animation: atr-rise .6s var(--atr-ease) .3s both; }
.atr-qr svg { display: block; }
.atr-qr-cap { margin: 14px auto 0; max-width: 330px; font-size: 28px; line-height: 1.15; font-weight: 800; color: #0b1400; }
.atr-qr-site .atr-qr-cap { max-width: 420px; }
.atr-qr-site { top: 190px; right: 140px; }
.atr-onsite { position: absolute; left: 96px; bottom: 110px; font-size: 48px; font-weight: 800; animation: atr-rise .6s var(--atr-ease) .6s both; }
.atr-glow { position: absolute; inset: 0; background: radial-gradient(ellipse at 50% 55%, color-mix(in srgb, var(--atr-accent) 28%, transparent), transparent 60%), #040604; }
/* the tenant's own loader (attract/intro-<name>.html, the kiosk boot loader's page): the whole canvas, black */
.atr-intro-loader { position: absolute; left: 0; top: 0; width: 1920px; height: 1080px; border: 0; background: #000; pointer-events: none; }
.atr-intro-logo { position: absolute; left: 410px; top: 400px; width: 1100px; height: auto; animation: atr-slam .7s cubic-bezier(.2,1.4,.3,1) both; }
@keyframes atr-slam { from { opacity: 0; transform: scale(1.5); } to { opacity: 1; transform: none; } }
@keyframes atr-rise { from { opacity: 0; transform: translate3d(0, 46px, 0); } to { opacity: 1; transform: none; } }
@keyframes atr-slide { from { opacity: 0; transform: translate3d(-70px, 0, 0); } to { opacity: 1; transform: none; } }
/* a: the logo's slanted bands wipe across at every change, drifting bands behind */
.atr-wipe { position: absolute; inset: -10% -40%; z-index: 8; display: flex; animation: atr-wipe 1s cubic-bezier(.7,0,.3,1) both; }
.atr-wipe i { flex: 0 0 auto; width: 34%; height: 100%; transform: skewX(-18deg); background: var(--atr-accent); }
.atr-wipe i:nth-child(2) { background: #0d1608; }
.atr-wipe i:nth-child(3) { width: 12%; background: color-mix(in srgb, var(--atr-accent) 70%, #000); }
@keyframes atr-wipe { from { transform: translate3d(-120%, 0, 0); } to { transform: translate3d(120%, 0, 0); } }
.atr-ambient { position: absolute; inset: 0; overflow: hidden; z-index: 4; pointer-events: none; }
.atr-ambient i { position: absolute; top: -20%; left: -30%; height: 140%; width: 22%; transform: skewX(-18deg);
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--atr-accent) 12%, transparent), transparent); animation: atr-drift 16s linear infinite; }
.atr-ambient i:nth-child(2) { width: 9%; animation-duration: 11s; animation-delay: -4s; }
.atr-ambient i:nth-child(3) { width: 34%; animation-duration: 23s; animation-delay: -9s; }
@keyframes atr-drift { from { transform: translate3d(0, 0, 0) skewX(-18deg); } to { transform: translate3d(2600px, 0, 0) skewX(-18deg); } }
/* c: neon edge and a pulse from the terminal's side */
.attract-c .atr-ambient i { width: 4px; background: var(--atr-accent); box-shadow: 0 0 24px var(--atr-accent); opacity: .6; }
.atr-neon { position: absolute; inset: 18px; z-index: 7; border-radius: 24px; border: 3px solid color-mix(in srgb, var(--atr-accent) 55%, transparent);
  box-shadow: 0 0 40px color-mix(in srgb, var(--atr-accent) 35%, transparent), inset 0 0 40px color-mix(in srgb, var(--atr-accent) 20%, transparent); animation: atr-neon 3s ease-in-out infinite; }
@keyframes atr-neon { 50% { opacity: .45; } }
.atr-pulse { position: absolute; left: 860px; top: 980px; z-index: 8; width: 200px; height: 200px; border-radius: 50%;
  background: radial-gradient(circle, var(--atr-accent) 0%, color-mix(in srgb, var(--atr-accent) 60%, transparent) 45%, transparent 70%); animation: atr-pulse 1.1s cubic-bezier(.3,0,.2,1) both; }
@keyframes atr-pulse { 0% { opacity: .95; transform: scale(.1); } 60% { opacity: .9; } 100% { opacity: 0; transform: scale(22); } }
@media (prefers-reduced-motion: reduce) { .atr-arrow, .atr-ambient i, .atr-neon { animation: none; } }

/* ---------- channel 99: the language menu (guide.js "the language menu") ----------
   Full screen over the channel, drawn for 1920x1080 and scaled like the guide (--gz): four columns of eight, each row the
   language's number, its flag and its name in its own language, big enough to read from a sofa. The TV's language has a
   gold frame; the focus is the guide's white ring; the chosen row blinks in its frame before the menu goes. */
.langmenu { position: fixed; inset: 0; z-index: 4; zoom: var(--gz); animation: lang-in var(--lang-menu-in-ms) ease both; }
.langmenu.closing { animation: lang-out var(--lang-menu-out-ms) ease both; }
@keyframes lang-in { from { opacity: 0; transform: scale(var(--lang-menu-in-scale)); } to { opacity: 1; transform: none; } }
@keyframes lang-out { to { opacity: 0; transform: scale(var(--lang-menu-out-scale)); } }
.lang-top { position: absolute; top: var(--lang-menu-top-top); left: var(--lang-menu-top-left); right: var(--lang-menu-top-right); height: var(--lang-menu-top-h); display: flex; align-items: center; gap: var(--lang-menu-top-gap); z-index: 1; }
.lang-top .tv-chip { font-size: var(--lang-menu-top-chip-size); font-weight: var(--lang-menu-top-chip-weight); }
.lang-chan { font-size: var(--lang-menu-top-chan-size); font-weight: var(--lang-menu-top-chan-weight); color: var(--dim); font-variant-numeric: tabular-nums; }
.lang-title-word { font-size: var(--lang-menu-top-title-size); font-weight: var(--lang-menu-top-title-weight); letter-spacing: var(--lang-menu-top-title-spacing); }
.lang-hint { margin-left: auto; display: flex; gap: var(--lang-menu-top-hint-gap); }
.lang-hint .key { font-size: var(--lang-menu-top-key-size); padding: var(--lang-menu-top-key-pad); border-radius: var(--lang-menu-top-key-radius); }
.lang-grid { position: absolute; top: var(--lang-menu-grid-top); left: var(--lang-menu-grid-left); right: var(--lang-menu-grid-right); bottom: var(--lang-menu-grid-bottom); z-index: 1;
  display: grid; grid-auto-flow: column; grid-template-columns: repeat(var(--lang-menu-grid-cols), 1fr); grid-template-rows: repeat(var(--lang-menu-grid-rows), 1fr); gap: var(--lang-menu-grid-gap); }
.lang-row { display: flex; align-items: center; gap: var(--lang-menu-row-gap); min-width: 0; padding: var(--lang-menu-row-pad); border: 0; border-radius: var(--lang-menu-row-radius); text-align: left;
  background: var(--lang-menu-row-bg); box-shadow: inset 0 0 0 2px transparent; cursor: pointer;
  transition: transform var(--lang-menu-row-transition-ms) ease, background var(--lang-menu-row-transition-ms) ease, box-shadow var(--lang-menu-row-transition-ms) ease; }
.lang-num { flex: 0 0 var(--lang-menu-row-num-w); font-size: var(--lang-menu-row-num-size); font-weight: var(--lang-menu-row-num-weight); color: var(--dim); text-align: right; font-variant-numeric: tabular-nums; }
.lang-flag { flex: 0 0 auto; width: var(--lang-menu-row-flag-w); height: var(--lang-menu-row-flag-h); border-radius: var(--lang-menu-row-flag-radius); object-fit: contain; box-shadow: var(--lang-menu-row-flag-shadow); }
/* a language's name is never cut (no line clamp): the longest ("Português (Brasil)") takes two lines inside its row */
.lang-name { min-width: 0; font-size: var(--lang-menu-row-name-size); font-weight: var(--lang-menu-row-name-weight); line-height: var(--lang-menu-row-name-line-height); overflow-wrap: break-word; }
.lang-row.current { background: var(--lang-menu-row-current-bg); box-shadow: inset 0 0 0 var(--lang-menu-row-current-ring) var(--current); }
.lang-row.current .lang-num { color: var(--current); }
.lang-row.focus { background: var(--lang-menu-row-focus-bg); transform: scale(var(--lang-menu-row-focus-scale)); box-shadow: 0 0 0 var(--lang-menu-row-focus-ring) var(--focus), var(--lang-menu-row-focus-shadow); }
.lang-row.current.focus { box-shadow: inset 0 0 0 var(--lang-menu-row-current-ring) var(--current), 0 0 0 var(--lang-menu-row-focus-ring) var(--focus), var(--lang-menu-row-focus-shadow); }
.lang-row.chosen { animation: lang-blink var(--lang-menu-row-chosen-blink-ms) steps(1, end) var(--lang-menu-row-chosen-blinks); }
@keyframes lang-blink { 50% { background: var(--lang-menu-row-chosen-bg); box-shadow: 0 0 0 var(--lang-menu-row-focus-ring) transparent; } }
