/* ==========================================================================
   CHUTOGEL RTP — stylesheet
   Palette: kuning (#ffd919) + jingga (#ff7a00) on a warm dark base.
   Zero external assets: system fonts, no network requests, no frameworks.
   ========================================================================== */

:root {
    --y-500: #ffd919;
    --y-400: #ffe45c;
    --y-600: #f2b705;
    --o-500: #ff7a00;
    --o-600: #e85d04;
    --o-700: #b34700;
    --ink: #100a02;
    --ink-2: #1a1206;
    --ink-3: #241a09;
    --line: rgba(255, 217, 25, .16);
    --line-2: rgba(255, 122, 0, .26);
    --text: #fbf3df;
    --muted: #b9a584;
    --hot: #ff4d2e;
    --warm: #ffb020;
    --cool: #8fd3ff;
    --radius: 16px;
    --radius-sm: 10px;
    --shadow: 0 18px 46px -22px rgba(255, 122, 0, .55);
    --font: "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
    --mono: ui-monospace, "Cascadia Mono", "Consolas", "SF Mono", Menlo, monospace;
}

*,
*::before,
*::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

/* Sticky topbar would otherwise cover the heading of whatever section an
   anchor jumps to. JS scrolling uses its own offset; this covers the native
   jump the browser does when a hash arrives with the page. */
:target { scroll-margin-top: 84px; }

body {
    margin: 0;
    min-height: 100vh;
    font-family: var(--font);
    color: var(--text);
    background:
        radial-gradient(1200px 620px at 12% -12%, rgba(255, 122, 0, .22), transparent 62%),
        radial-gradient(900px 520px at 92% 4%, rgba(255, 217, 25, .16), transparent 58%),
        linear-gradient(184deg, #150d03 0%, #0d0801 46%, #120a02 100%);
    background-attachment: fixed;
    letter-spacing: .01em;
    overflow-x: hidden;
}

img { max-width: 100%; height: auto; display: block; }

a { color: inherit; text-decoration: none; }

code {
    font-family: var(--mono);
    font-size: .88em;
    background: rgba(255, 217, 25, .1);
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: .1em .45em;
}

/* ---------- ambient glows ---------- */

.glow {
    position: fixed;
    z-index: 0;
    pointer-events: none;
    border-radius: 50%;
    filter: blur(90px);
    opacity: .5;
}

.glow-a {
    width: 42vw;
    height: 42vw;
    min-width: 320px;
    min-height: 320px;
    top: -14vw;
    left: -10vw;
    background: radial-gradient(circle, rgba(255, 122, 0, .55), transparent 70%);
}

.glow-b {
    width: 36vw;
    height: 36vw;
    min-width: 280px;
    min-height: 280px;
    bottom: -16vw;
    right: -8vw;
    background: radial-gradient(circle, rgba(255, 217, 25, .38), transparent 70%);
}

/* ---------- top bar ---------- */

.topbar {
    position: sticky;
    top: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    gap: 18px;
    padding: 12px clamp(14px, 3vw, 34px);
    background: linear-gradient(180deg, rgba(16, 10, 2, .96), rgba(16, 10, 2, .74));
    backdrop-filter: blur(14px) saturate(140%);
    border-bottom: 1px solid var(--line);
}

.brand {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
}

/* picture is a flex child too, so it needs the layout rules the img used to
   carry directly. */
.brand picture {
    display: flex;
    align-items: center;
}

.brand-logo {
    height: clamp(42px, 6.4vw, 64px);
    width: auto;
    /* The source logo is gold-on-black; screen blending drops the black plate
       so it sits on the warm header instead of inside a dark rectangle.
       Applies to the animated webp exactly as it did to the static one. */
    mix-blend-mode: screen;
    filter: drop-shadow(0 4px 16px rgba(255, 122, 0, .5)) saturate(1.12);
}

.marquee {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}

.marquee-track {
    display: inline-flex;
    align-items: center;
    gap: 14px;
    white-space: nowrap;
    font-size: 11px;
    font-weight: 800;
    letter-spacing: .22em;
    color: var(--y-500);
    animation: slide 26s linear infinite;
}

.marquee-track .dot { color: var(--o-500); }

@keyframes slide {
    from { transform: translateX(0); }
    to   { transform: translateX(-50%); }
}

.cta {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 9px 20px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 900;
    letter-spacing: .14em;
    color: #2a1500;
    background: linear-gradient(135deg, var(--y-400), var(--o-500));
    box-shadow: 0 10px 26px -12px rgba(255, 122, 0, .9), inset 0 1px 0 rgba(255, 255, 255, .5);
    transition: transform .16s ease, box-shadow .16s ease;
}

.cta:hover {
    transform: translateY(-1px);
    box-shadow: 0 14px 32px -12px rgba(255, 178, 32, .95), inset 0 1px 0 rgba(255, 255, 255, .6);
}

/* ---------- shell ---------- */

.shell {
    position: relative;
    z-index: 1;
    width: min(1180px, 100%);
    margin: 0 auto;
    padding: clamp(20px, 4vw, 44px) clamp(14px, 3vw, 28px) 60px;
}

/* ---------- hero ---------- */

/* Cinema-mode banner: rendered outside <main class="shell">, so it spans the
   full viewport width and sits flush under the sticky topbar — no side gutters,
   no gap above, no rounded corners (the edges ARE the viewport edges).
   aspect-ratio holds the exact 2.35:1 frame at every width. */
.banner {
    position: relative;
    width: 100%;
    margin: 0;
    overflow: hidden;
    background: var(--ink);
    aspect-ratio: 235 / 100;
    isolation: isolate;
}

.banner picture { display: block; height: 100%; }

.banner-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    display: block;
}

/* Bottom-only scrim: melts the artwork into the page underneath. No side
   vignette — cinema mode should run clean to the edges. */
.banner::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;                 /* above slides, below the paging dots */
    pointer-events: none;
    background: linear-gradient(180deg, transparent 74%, rgba(13, 8, 1, .55) 100%);
}

/* ---------- banner slider ---------- */

/* Slides share ONE grid cell so they overlap exactly and the frame height is
   owned by .banner's aspect-ratio — never by whichever image happens to be
   showing. That is what keeps the page from jumping as slides change. */
.banner-track {
    display: grid;
    width: 100%;
    height: 100%;
}

.banner-slide {
    grid-area: 1 / 1;
    display: block;
    position: relative;
    width: 100%;
    height: 100%;
    color: inherit;
    text-decoration: none;
}

.banner-slide picture { display: block; height: 100%; }

/* Cross-fade. Only armed once JS confirms it is alive (.is-live on the
   figure), so a no-JS page shows a plain stack of images with the first one
   on top rather than an invisible hero. */
.banner-slider.is-live .banner-slide {
    opacity: 0;
    transition: opacity .7s ease;
    will-change: opacity;
}

.banner-slider.is-live .banner-slide.is-active { opacity: 1; }

.banner-slider.is-live .banner-slide:not(.is-active) {
    pointer-events: none;
}

/* Without JS both slides occupy the same grid cell, and the later one would
   paint over the first. Park every slide after the first until the slider
   takes over, so a no-JS page shows slide one rather than the last one. */
.banner-slider:not(.is-live) .banner-slide + .banner-slide { visibility: hidden; }

/* Paging dots: small, centred, and clear of the bottom scrim. Gold when
   active, hollow otherwise. Enlarged to a 24px hit area while the visible
   pip stays 7px, so they are tappable without looking heavy. */
.banner-dots {
    position: absolute;
    left: 0;
    right: 0;
    bottom: clamp(8px, 1.6vw, 15px);
    z-index: 3;
    display: flex;
    justify-content: center;
    gap: 4px;
}

.banner-dot {
    width: 24px;
    height: 24px;
    padding: 0;
    display: grid;
    place-items: center;
    background: none;
    border: 0;
    cursor: pointer;
}

.banner-dot::before {
    content: "";
    width: 8px;
    height: 8px;
    border-radius: 999px;
    background: rgba(255, 240, 205, .55);
    border: 1px solid rgba(0, 0, 0, .55);
    box-shadow: 0 1px 3px rgba(0, 0, 0, .6);
    transition: width .22s ease, background .22s ease, box-shadow .22s ease;
}

.banner-dot:hover::before { background: rgba(255, 240, 205, .85); }

.banner-dot.is-active::before {
    width: 22px;
    background: linear-gradient(90deg, var(--y-400), var(--o-500));
    border-color: rgba(0, 0, 0, .5);
    box-shadow: 0 0 10px rgba(255, 122, 0, .75), 0 1px 3px rgba(0, 0, 0, .6);
}

.banner-dot:focus-visible { outline: 2px solid var(--y-500); outline-offset: 2px; border-radius: 50%; }

/* Wide animated GIF strip under the hero banner (source 840x112 = 7.5:1).
   aspect-ratio reserves the exact height before the GIF decodes, so nothing
   below it jumps once the animation loads in. */
.feedstrip {
    position: relative;
    margin: 0 0 clamp(16px, 2.4vw, 24px);
    border-radius: var(--radius-sm);
    overflow: hidden;
    background: rgba(16, 10, 2, .6);
    box-shadow: inset 0 0 0 1px var(--line-2), 0 14px 34px -26px rgba(255, 122, 0, .8);
    aspect-ratio: 840 / 112;
}

.feedstrip-img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
}

.hero { text-align: center; padding: clamp(8px, 2vw, 22px) 0 clamp(20px, 3vw, 30px); }

.eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    margin: 0 0 16px;
    padding: 7px 16px;
    border: 1px solid var(--line-2);
    border-radius: 999px;
    background: rgba(255, 122, 0, .08);
    font-size: 10.5px;
    font-weight: 800;
    letter-spacing: .2em;
    color: var(--y-400);
}

.pulse {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--hot);
    box-shadow: 0 0 0 0 rgba(255, 77, 46, .7);
    animation: pulse 1.8s ease-out infinite;
}

@keyframes pulse {
    0%   { box-shadow: 0 0 0 0 rgba(255, 77, 46, .65); }
    70%  { box-shadow: 0 0 0 11px rgba(255, 77, 46, 0); }
    100% { box-shadow: 0 0 0 0 rgba(255, 77, 46, 0); }
}

.hero-title {
    margin: 0 0 12px;
    font-size: clamp(29px, 6.2vw, 56px);
    line-height: 1.02;
    font-weight: 900;
    letter-spacing: -.02em;
    text-transform: uppercase;
    text-shadow: 0 12px 40px rgba(255, 122, 0, .35);
}

.hl {
    background: linear-gradient(135deg, var(--y-400) 8%, var(--o-500) 92%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

.hero-sub {
    max-width: 620px;
    margin: 0 auto;
    font-size: clamp(13px, 1.6vw, 15px);
    line-height: 1.65;
    color: var(--muted);
}

/* ---------- provider hero banner ---------- */

/* Same cinema frame as the home slider (full bleed, 2.35:1, flush under the
   sticky topbar) but with the provider name burned in over the art. The scrim
   runs from the bottom edge only, so the left of the artwork stays readable. */
.pbanner {
    position: relative;
    width: 100%;
    margin: 0;
    overflow: hidden;
    background: var(--ink);
    aspect-ratio: 235 / 100;
    isolation: isolate;
}

.pbanner-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    display: block;
}

.pbanner::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background:
        linear-gradient(180deg, transparent 40%, rgba(13, 8, 1, .82) 100%),
        linear-gradient(90deg, rgba(13, 8, 1, .72) 0%, transparent 58%);
}

.pbanner-copy {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 2;
    padding: clamp(14px, 3vw, 34px) clamp(16px, 4vw, 40px);
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.pbanner-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    align-self: flex-start;
    margin: 0;
    padding: 5px 12px;
    border: 1px solid rgba(255, 122, 0, .5);
    border-radius: 999px;
    background: rgba(16, 10, 2, .62);
    font-size: 9.5px;
    font-weight: 800;
    letter-spacing: .18em;
    color: var(--y-400);
}

.pbanner-title {
    margin: 0;
    font-size: clamp(22px, 5.6vw, 46px);
    font-weight: 900;
    letter-spacing: -.01em;
    line-height: 1;
    text-transform: uppercase;
    background: linear-gradient(135deg, #fff3c4, var(--y-500) 45%, var(--o-500));
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    text-shadow: 0 10px 30px rgba(0, 0, 0, .5);
}

.pbanner-sub {
    margin: 0;
    font-size: clamp(11px, 2.2vw, 13px);
    color: #e7d9bb;
    letter-spacing: .02em;
}

@media (max-width: 560px) {
    .pbanner { border-radius: 0; }
    .pbanner-sub { display: none; }
}

/* ---------- provider picker ---------- */

.picker { margin-top: clamp(24px, 4vw, 40px); }

.picker-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 14px;
    margin-bottom: 14px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--line);
}

.picker-head h2 {
    margin: 0;
    font-size: clamp(14px, 2.2vw, 18px);
    font-weight: 900;
    letter-spacing: .13em;
    color: var(--y-500);
    text-transform: uppercase;
}

.picker-hint { font-size: 11px; color: var(--muted); letter-spacing: .06em; }

.grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(232px, 1fr));
    gap: 14px;
}

/* Banner-only tile: 546x267 art, no text, whole card is the link. */
.card {
    position: relative;
    display: block;
    aspect-ratio: 546 / 267;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: rgba(26, 18, 6, .72);
    overflow: hidden;
    transition: transform .16s ease, border-color .16s ease, box-shadow .16s ease;
}

.card::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: linear-gradient(135deg, rgba(255, 217, 25, .2), transparent 52%);
    opacity: 0;
    transition: opacity .18s ease;
    pointer-events: none;
}

.card:hover,
.card:focus-visible {
    transform: translateY(-3px);
    border-color: var(--line-2);
    box-shadow: var(--shadow);
    outline: none;
}

.card:hover::after,
.card:focus-visible::after { opacity: 1; }

.card-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.card-fallback {
    display: grid;
    place-items: center;
    width: 100%;
    height: 100%;
    padding: 12px;
    background: linear-gradient(150deg, #fff8dc, #ffe9a8);
}

.card-fallback img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

/* Logo fallback: a provider with no banner tile still gets a card that reads
   as a card — the mark centred on the house plate, never a stretched logo. */
.card-img.is-logo {
    object-fit: contain;
    padding: 22px 30px;
    background:
        radial-gradient(ellipse at 50% 45%, rgba(255, 150, 0, .18), transparent 62%),
        linear-gradient(170deg, #1e1204, #120b02);
}

/* Last resort: no banner and no logo — a monogram plate, never an empty box. */
.card-mono {
    display: grid;
    place-items: center;
    width: 100%;
    height: 100%;
    font-family: var(--font);
    font-size: clamp(28px, 5vw, 44px);
    letter-spacing: .08em;
    color: rgba(255, 217, 25, .82);
    background:
        radial-gradient(ellipse at 50% 45%, rgba(255, 150, 0, .16), transparent 62%),
        linear-gradient(170deg, #1e1204, #120b02);
}

/* ---------- strip ---------- */

.strip {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 1px;
    margin-top: clamp(26px, 4vw, 40px);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--line);
    overflow: hidden;
}

.strip-in {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 13px 16px;
    background: rgba(16, 10, 2, .88);
}

.strip-label {
    font-size: 9px;
    font-weight: 800;
    letter-spacing: .18em;
    color: var(--muted);
}

.strip-value {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .04em;
    color: var(--text);
    font-family: var(--mono);
}

.strip-value.ok { color: #4ade80; }
.strip-link { font-size: 12px; font-weight: 800; color: var(--y-500); letter-spacing: .06em; }
.strip-link:hover { color: var(--o-500); }

/* ---------- provider page ---------- */

.crumbs {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 10.5px;
    font-weight: 800;
    letter-spacing: .16em;
    color: var(--muted);
    margin-bottom: 18px;
}

.crumbs a { color: var(--y-500); }
.crumbs a:hover { color: var(--o-500); }
.crumbs .now { color: var(--text); }

/* Stats ribbon under the crumbs: totals, average, hottest game, last tick. */
.pmeta { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 clamp(14px, 2.4vw, 20px); }

.pmeta-stats span {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 13px;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: rgba(255, 217, 25, .05);
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--muted);
}

.pmeta-stats b { color: var(--y-500); font-weight: 900; font-variant-numeric: tabular-nums; }
.pmeta-stats .hot { border-color: rgba(255, 77, 46, .4); background: rgba(255, 77, 46, .09); }
.pmeta-stats .hot b { color: var(--hot); }
.pmeta-stats .cold { border-color: rgba(143, 211, 255, .35); background: rgba(143, 211, 255, .08); }
.pmeta-stats .cold b { color: var(--cool); }
.pmeta-stats .pmeta-upd { border-style: dashed; }

/* Search row under the RTP PER GAME heading: field on the left, live hit
   counter on the right. Kept on one line down to ~420px, then the counter drops
   under the field rather than squeezing the input. */
.gtools {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin: 0 0 14px;
}

.gsearch {
    position: relative;
    flex: 1 1 260px;
    display: flex;
    align-items: center;
    min-width: 0;
}

.gsearch-icon {
    position: absolute;
    left: 13px;
    color: var(--muted);
    pointer-events: none;
    transition: color .16s ease;
}

.gsearch-input {
    width: 100%;
    padding: 11px 38px 11px 37px;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: rgba(16, 10, 2, .82);
    color: var(--text);
    font: inherit;
    font-size: 12.5px;
    letter-spacing: .01em;
    transition: border-color .16s ease, background .16s ease, box-shadow .16s ease;
    -webkit-appearance: none;
    appearance: none;
}

.gsearch-input::placeholder { color: rgba(185, 165, 132, .72); }

.gsearch-input:hover { border-color: var(--line-2); }

.gsearch-input:focus {
    outline: none;
    border-color: rgba(255, 217, 25, .55);
    background: rgba(26, 18, 6, .92);
    box-shadow: 0 0 0 3px rgba(255, 217, 25, .12);
}

.gsearch-input:focus + .gsearch-clear,
.gsearch:focus-within .gsearch-icon { color: var(--y-500); }

/* Safari draws its own cancel glyph; the visible button below replaces it. */
.gsearch-input::-webkit-search-decoration,
.gsearch-input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }

.gsearch-clear {
    position: absolute;
    right: 7px;
    display: grid;
    place-items: center;
    width: 24px;
    height: 24px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: rgba(255, 217, 25, .12);
    color: var(--y-400);
    font-size: 15px;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
}

.gsearch-clear:hover,
.gsearch-clear:focus-visible {
    background: rgba(255, 122, 0, .3);
    color: #fff6dd;
    outline: none;
}

.gsearch-count {
    flex: 0 0 auto;
    margin: 0;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--muted);
    white-space: nowrap;
}

.gsearch-count b { color: var(--y-500); font-variant-numeric: tabular-nums; }

.gsearch-count.is-empty b { color: var(--hot); }

/* A card filtered out by the search: collapsed, not just invisible, so the
   grid closes the gap instead of leaving holes. */
.gcard.is-hidden { display: none; }

.gsearch-none {
    margin: 18px 0 0;
    padding: 22px;
    border: 1px dashed var(--line);
    border-radius: var(--radius-sm);
    text-align: center;
    font-size: 12.5px;
    color: var(--muted);
}

/* Narrow screens: the field takes the full row and the counter sits under it,
   right-aligned. An inline counter here would wrap arbitrarily depending on
   the exact phone width, which reads as a bug. */
@media (max-width: 520px) {
    .gsearch { flex: 1 1 100%; }
    .gsearch-count { width: 100%; margin: -2px 0 0; text-align: right; font-size: 9.5px; }
}

/* ---------- game card grid ---------- */

.games { margin-top: clamp(6px, 1.4vw, 12px); }

.games-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 14px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--line);
}

.games-head h2 {
    margin: 0;
    font-size: clamp(14px, 2.2vw, 18px);
    font-weight: 900;
    letter-spacing: .13em;
    color: var(--y-500);
    text-transform: uppercase;
}

.games-hint { font-size: 11px; color: var(--muted); letter-spacing: .05em; }

.ggrid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(146px, 1fr));
    gap: clamp(9px, 1.4vw, 14px);
    margin: 0;
    padding: 0;
    list-style: none;
}

/* One tile per game: square art on top, name, RTP bar, then the three pattern
   slots. The whole card is a surface — no link, because there is nowhere to
   go; the numbers are the content. */
.gcard {
    display: flex;
    flex-direction: column;
    gap: 7px;
    padding: 8px 8px 10px;
    border: 1px solid var(--line);
    border-radius: 14px;
    background: linear-gradient(168deg, rgba(36, 26, 9, .92), rgba(18, 11, 2, .95));
    box-shadow: 0 12px 28px -22px rgba(0, 0, 0, .95);
    transition: transform .16s ease, border-color .16s ease, box-shadow .16s ease;
}

.gcard:hover {
    transform: translateY(-2px);
    border-color: var(--line-2);
    box-shadow: var(--shadow);
}

.gcard-art {
    position: relative;
    aspect-ratio: 1 / 1;
    border-radius: 10px;
    overflow: hidden;
    background:
        radial-gradient(ellipse at 50% 40%, rgba(255, 150, 0, .18), transparent 62%),
        linear-gradient(170deg, #1e1204, #120b02);
}

.gcard-art img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ---------- tap-to-reveal MAINKAN ---------- */

/* The transparent sheet over the art is the tap target. It only ever listens
   for the first tap; once .is-open lands on the card it stops taking pointer
   events so the button underneath is clickable on the *same* open state. */
.gcard-tap {
    position: absolute;
    inset: 0;
    z-index: 3;
    display: block;
    width: 100%;
    padding: 0;
    border: 0;
    border-radius: inherit;
    background: transparent;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

.gcard-tap:focus-visible {
    outline: 2px solid var(--y-500);
    outline-offset: -3px;
}

/* The scrim. Painted by the art box (which already clips), so it can never
   spill past the rounded tile. Sits above the image and below the warning
   label, the tap sheet and the button. pointer-events is always none — it is
   decoration, the tap sheet owns the input. */
.gcard-art::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 1;
    border-radius: inherit;
    /* Centre-weighted dim: the middle goes properly dark so the button reads,
       the edges keep enough art visible to still recognise the game. */
    background:
        radial-gradient(ellipse at 50% 50%, rgba(0, 0, 0, .78) 0%, rgba(0, 0, 0, .64) 55%, rgba(0, 0, 0, .42) 100%);
    opacity: 0;
    transition: opacity .22s ease;
    pointer-events: none;
}

.gcard.is-open .gcard-art::after { opacity: 1; }

/* The play button. Hidden by default so the grid stays a grid of art; a tap
   on the card brings it up in the middle of the art. It is a real <a> because
   the whole point is a navigation to AUTH_URL, and hiding it with visibility
   keeps it out of the tab order until the card is open. */
.gcard-play {
    position: absolute;
    top: 50%;
    left: 50%;
    z-index: 4;
    display: block;
    width: max-content;
    max-width: calc(100% - 16px);
    padding: 9px 18px;
    border-radius: 999px;
    background: linear-gradient(135deg, var(--o-500), var(--y-500));
    color: #1a1200;
    font-size: 11px;
    font-weight: 900;
    letter-spacing: .1em;
    text-align: center;
    text-decoration: none;
    text-transform: uppercase;
    white-space: nowrap;
    box-shadow:
        0 10px 26px -12px rgba(255, 140, 0, .95),
        0 0 0 1px rgba(255, 246, 221, .35) inset;
    opacity: 0;
    visibility: hidden;
    transform: translate(-50%, -50%) scale(.82);
    /* Two animations on open: the pop-in (once) then the breathing glow
       (forever). Both carry the centring translate, because an animated
       transform replaces the declared one outright. */
    animation: none;
}

.gcard.is-open .gcard-play {
    opacity: 1;
    visibility: visible;
    animation:
        mainkan-pop .26s cubic-bezier(.34, 1.56, .64, 1) both,
        mainkan-glow 1.9s ease-in-out .26s infinite;
}

/* A light sweeps across the pill, so the button reads as live rather than as
   a static label that happened to appear. */
.gcard-play::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: linear-gradient(100deg, transparent 30%, rgba(255, 255, 255, .65) 50%, transparent 70%);
    transform: translateX(-120%);
    pointer-events: none;
}

.gcard.is-open .gcard-play::before {
    animation: mainkan-sheen 2.6s ease-in-out .5s infinite;
}

.gcard-play:hover,
.gcard-play:focus-visible {
    background: linear-gradient(135deg, var(--y-500), var(--o-400));
    outline: none;
}

.gcard-play:active { filter: brightness(.94); }

@keyframes mainkan-pop {
    0%   { opacity: 0; transform: translate(-50%, -50%) scale(.8); }
    60%  { opacity: 1; transform: translate(-50%, -50%) scale(1.06); }
    100% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}

@keyframes mainkan-glow {
    0%, 100% {
        box-shadow:
            0 10px 26px -12px rgba(255, 140, 0, .9),
            0 0 0 1px rgba(255, 246, 221, .35) inset,
            0 0 0 0 rgba(255, 217, 25, .55);
        transform: translate(-50%, -50%) scale(1);
    }
    50% {
        box-shadow:
            0 12px 30px -10px rgba(255, 170, 0, 1),
            0 0 0 1px rgba(255, 246, 221, .5) inset,
            0 0 0 7px rgba(255, 217, 25, 0);
        transform: translate(-50%, -50%) scale(1.045);
    }
}

@keyframes mainkan-sheen {
    0%, 55%  { transform: translateX(-120%); }
    85%, 100% { transform: translateX(120%); }
}

/* Motion-sensitivity: keep the reveal, drop the loop. */
@media (prefers-reduced-motion: reduce) {
    .gcard.is-open .gcard-play { animation: mainkan-pop .18s ease both; }
    .gcard.is-open .gcard-play::before { animation: none; }
    .gcard-art::after { transition: none; }
}

.gcard.is-open .gcard-tap { pointer-events: none; }

.gcard.is-open .gcard-tap:focus-visible {
    pointer-events: auto; /* keyboard users still need the toggle */
}

/* A dead game keeps the button — the visitor decides — but the art is dimmed
   and the label says plainly what the number means. */
.gcard.is-dead { border-color: rgba(255, 77, 46, .28); }

.gcard.is-dead .gcard-art img,
.gcard.is-dead .gcard-mono { filter: grayscale(.55) brightness(.72); }

.gcard-warn {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    /* 2 = above the open-card scrim, below the tap sheet (3) and button (4). */
    z-index: 2;
    display: block;
    padding: 5px 6px 6px;
    /* Solid, not a gradient: over busy game art a fading backdrop left the
       label unreadable at 390px wide. */
    background: rgba(58, 6, 0, .93);
    border-bottom: 1px solid rgba(255, 77, 46, .55);
    color: #ffc9c9;
    font-size: 8.5px;
    font-weight: 900;
    line-height: 1.25;
    letter-spacing: .04em;
    text-align: center;
    text-transform: uppercase;
    text-shadow: 0 1px 1px rgba(0, 0, 0, .9);
}

.gcard-mono {
    display: grid;
    place-items: center;
    width: 100%;
    height: 100%;
    font-size: clamp(22px, 4vw, 32px);
    font-weight: 900;
    letter-spacing: .06em;
    color: rgba(255, 217, 25, .8);
}

.gcard-name {
    margin: 0;
    font-size: 11.5px;
    font-weight: 700;
    line-height: 1.3;
    letter-spacing: .01em;
    color: var(--text);
    /* Two lines max, so a long name cannot stagger the grid rows. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    min-height: 2.6em;
}

/* RTP bar: track + fill + the number riding the end of the track. The tier
   colour on the wrapper drives both the fill and the label. */
.gcard-bar {
    position: relative;
    display: block;
    height: 15px;
    border-radius: 999px;
    background: rgba(255, 217, 25, .09);
    box-shadow: inset 0 0 0 1px rgba(255, 217, 25, .08);
    overflow: hidden;
}

.gcard-bar i {
    position: absolute;
    inset: 0 auto 0 0;
    display: block;
    border-radius: inherit;
    transition: width .5s cubic-bezier(.22, .8, .3, 1);
}

.gcard-bar.t-hot i { background: linear-gradient(90deg, var(--o-600), var(--hot)); box-shadow: 0 0 10px rgba(255, 77, 46, .75); }
.gcard-bar.t-warm i { background: linear-gradient(90deg, var(--o-500), var(--y-500)); box-shadow: 0 0 10px rgba(255, 178, 32, .6); }
.gcard-bar.t-cool i { background: linear-gradient(90deg, #2f6f96, var(--cool)); }
/* Cold games are the point of the page: slate-grey fill, no glow, so a 78%
   tile is visibly dead next to a 98% one at a glance. */
.gcard-bar.t-cold i { background: linear-gradient(90deg, #3a3550, #6f6a8a); }
/* Under ADVISED_MIN: red, so a card the visitor should skip cannot be mistaken
   for merely "cool". */
.gcard-bar.t-dead i { background: linear-gradient(90deg, #7a1f14, var(--hot)); }

.gcard-trend {
    margin-left: 5px;
    font-size: 8px;
    font-style: normal;
    font-weight: 800;
    letter-spacing: .02em;
    opacity: .9;
}

.gcard-trend.up { color: #7ee0b8; }
.gcard-trend.down { color: #ff8f8f; }
.gcard-trend.flat { color: rgba(255, 246, 221, .55); }

.gcard-pct {
    position: relative;
    display: block;
    padding-right: 7px;
    font-size: 10px;
    font-weight: 900;
    line-height: 15px;
    text-align: right;
    font-variant-numeric: tabular-nums;
    letter-spacing: .02em;
    color: #fff6dd;
    /* The fill can end under the label; the shadow keeps the number legible
       over both the lit track and the dark remainder. */
    text-shadow: 0 1px 2px rgba(0, 0, 0, .85), 0 0 6px rgba(0, 0, 0, .6);
}

/* The three pattern slots, stacked — the reference layout reads them as a
   short list, not as chips. */
.gcard-pola { display: flex; flex-direction: column; gap: 3px; }

/* Lead-in label: the numbers under it are spin counts, so the card has to say
   what they count. Same colours as the slots, deliberately quieter. */
.gcard-pola-lead {
    font-family: var(--mono);
    font-size: 8.5px;
    font-weight: 700;
    letter-spacing: .08em;
    color: var(--muted);
    text-transform: uppercase;
}

.gcard-pola span {
    display: block;
    padding: 3px 7px;
    border-radius: 6px;
    border: 1px solid rgba(255, 217, 25, .12);
    background: rgba(255, 217, 25, .05);
    font-family: var(--mono);
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: .02em;
    color: var(--y-400);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ---------- empty / error ---------- */

.empty { padding: 22px; text-align: center; color: var(--muted); font-size: 12.5px; }

.errbox {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
    padding: clamp(30px, 7vw, 70px) 20px;
    text-align: center;
}

.errbox h1 {
    margin: 0;
    font-size: clamp(52px, 13vw, 110px);
    font-weight: 900;
    line-height: 1;
    letter-spacing: -.03em;
    background: linear-gradient(135deg, var(--y-400), var(--o-500));
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

.errbox p { margin: 0; color: var(--muted); font-size: 13px; }

.errdetail {
    max-width: 100%;
    overflow-x: auto;
    padding: 12px 16px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: rgba(0, 0, 0, .45);
    color: #ffb4a2;
    font-family: var(--mono);
    font-size: 11.5px;
    text-align: left;
}

/* ---------- footer ---------- */

.foot {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    /* Mirrors .shell exactly — same max width, same horizontal padding — so
       the footer article's edges line up with the provider grid and the APK
       band above it instead of sitting in a narrower column. */
    width: min(1180px, 100%);
    margin: 0 auto;
    padding: 26px clamp(14px, 3vw, 28px) 34px;
    border-top: 1px solid var(--line);
    text-align: center;
}

.foot p { margin: 0; font-size: 11px; color: var(--muted); letter-spacing: .04em; }
.foot .small { font-size: 10px; opacity: .66; }

/* ---------- footer article ---------- */

/* Long-form copy in the footer. The block fills the same column as the grid
   and the APK band so all three share one left and right edge; the measure is
   kept sane by the paragraph size, not by a narrower container. */
.foot-article {
    width: 100%;
    max-width: none;
    margin: 0 auto 26px;
    text-align: left;
}

.foot-article-title {
    margin: 0 0 12px;
    font-size: clamp(17px, 2.4vw, 22px);
    line-height: 1.35;
    font-weight: 900;
    letter-spacing: -.005em;
    background: linear-gradient(96deg, var(--y-400), var(--o-500));
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

.foot-article-lead {
    margin: 0 0 18px;
    padding-left: 12px;
    border-left: 2px solid var(--line-2);
    font-size: 13px;
    line-height: 1.7;
    color: var(--text);
    opacity: .92;
}

.foot-article-block { margin-bottom: 16px; }

.foot-article-block h3 {
    margin: 0 0 6px;
    font-size: 12.5px;
    font-weight: 800;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--y-400);
}

.foot-article-block p {
    margin: 0 0 10px;
    font-size: 12.5px;
    line-height: 1.75;
    color: var(--muted);
    letter-spacing: .005em;
}

.foot-article-block p:last-child { margin-bottom: 0; }

/* Byline: who wrote it, their role, and both dates. E-E-A-T signal that has
   to be visible, not just machine-readable. */
.foot-article-byline {
    margin: 0 0 14px;
    font-size: 11.5px;
    line-height: 1.6;
    color: var(--muted);
    letter-spacing: .01em;
}

.foot-article-byline time { color: var(--y-400); font-weight: 600; }

/* Methodology list — numbered by marker so the steps read as a procedure. */
.foot-article-list {
    margin: 8px 0 10px;
    padding-left: 20px;
    font-size: 12.5px;
    line-height: 1.75;
    color: var(--muted);
}

.foot-article-list li { margin-bottom: 5px; }
.foot-article-list li::marker { color: var(--o-500); }

/* FAQ — collapsed-by-default is wrong for SEO, so every answer is rendered.
   Cards instead of a plain stack: numbered gold badge, hairline card, hover
   lift. Numbering comes from a CSS counter so the markup stays a plain list
   and the visible order can never drift from the JSON-LD order. */
.foot-article-faq,
.foot-article-author,
.foot-article-sources {
    margin-top: 22px;
    padding-top: 16px;
    border-top: 1px solid var(--line);
}

.foot-article-faq > h3,
.foot-article-author > h3,
.foot-article-sources > h3 {
    margin: 0 0 10px;
    font-size: 12.5px;
    font-weight: 800;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--y-400);
}

.foot-article-faq {
    counter-reset: faq;
}

.foot-article-faq > h3 { margin-bottom: 14px; }

.faq-item {
    counter-increment: faq;
    position: relative;
    margin-bottom: 10px;
    padding: 13px 16px 13px 46px;
    border: 1px solid var(--line);
    border-left: 2px solid var(--line-2);
    border-radius: 12px;
    background:
        linear-gradient(135deg, rgba(255, 217, 25, .045), rgba(255, 122, 0, .03));
    transition: border-color .18s ease, background .18s ease, transform .18s ease;
}

/* Accent seam that warms up on hover — the same gold-to-amber gradient the
   provider cards and the APK band use, so the footer reads as the same site. */
.faq-item::after {
    content: "";
    position: absolute;
    left: 0;
    top: 8px;
    bottom: 8px;
    width: 2px;
    border-radius: 2px;
    background: linear-gradient(180deg, var(--y-500), var(--o-500));
    opacity: .5;
    transition: opacity .18s ease;
}

/* Numbered badge, drawn from the counter above. */
.faq-item::before {
    content: counter(faq);
    position: absolute;
    left: 14px;
    top: 12px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    font-family: var(--mono);
    font-size: 10px;
    font-weight: 700;
    line-height: 1;
    color: var(--o-500);
    background: rgba(255, 122, 0, .12);
    border: 1px solid var(--line-2);
    border-radius: 7px;
}

.faq-item:hover,
.faq-item:focus-within {
    border-color: rgba(255, 217, 25, .3);
    border-left-color: var(--y-500);
    background:
        linear-gradient(135deg, rgba(255, 217, 25, .08), rgba(255, 122, 0, .05));
}

.faq-item:hover::after,
.faq-item:focus-within::after { opacity: 1; }

.faq-item h4 {
    position: relative;
    margin: 0 0 6px;
    padding-right: 18px;
    font-size: 12.5px;
    font-weight: 800;
    line-height: 1.5;
    color: var(--text);
}

/* Small gold cue that this block is a question, not a paragraph. */
.faq-item h4::after {
    content: "?";
    position: absolute;
    right: 0;
    top: 0;
    font-family: var(--mono);
    font-size: 11px;
    font-weight: 700;
    color: var(--y-500);
    opacity: .55;
}

.faq-item p {
    margin: 0;
    font-size: 12.5px;
    line-height: 1.75;
    color: var(--muted);
}

@media (max-width: 560px) {
    .faq-item {
        padding: 12px 13px 12px 41px;
        border-radius: 10px;
    }

    .faq-item::before { left: 12px; top: 11px; width: 18px; height: 18px; }
    .faq-item h4 { padding-right: 0; }
    .faq-item h4::after { display: none; }
}

.foot-article-author p {
    margin: 0;
    font-size: 12.5px;
    line-height: 1.75;
    color: var(--muted);
}

.foot-article-author strong { color: var(--text); }

.foot-article-sources ul {
    margin: 0;
    padding-left: 20px;
    font-size: 12px;
    line-height: 1.7;
    color: var(--muted);
}

.foot-article-sources li { margin-bottom: 4px; }
.foot-article-sources li::marker { color: var(--o-500); }

.foot-article-note {
    margin: 18px 0 0;
    padding: 11px 13px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: rgba(255, 217, 25, .045);
    font-size: 11.5px;
    line-height: 1.6;
    color: var(--muted);
}

.foot-base {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding-top: 18px;
    border-top: 1px solid var(--line);
    width: 100%;
}

/* The footer line mirrors the page <title> verbatim, so it can run long: cap
   the measure and centre it instead of letting one sentence stretch the shell. */
.foot-title {
    margin: 0;
    max-width: 74ch;
    text-align: center;
    font-size: 11px;
    line-height: 1.55;
    color: var(--muted);
}

/* ---------- responsive ---------- */

@media (max-width: 860px) {
    .ggrid { grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); }
}

@media (max-width: 560px) {
    .topbar { gap: 10px; padding: 10px 14px; }
    .marquee { display: none; }
    /* Logo takes the room the missing marquee/MASUK leave free. */
    .brand-logo { height: 40px; }
    .cta { padding: 8px 15px; font-size: 11px; }

    /* Cinema mode holds on phones too: full bleed, square edges, exact 2.35. */
    .banner { border-radius: 0; }

    .grid { grid-template-columns: repeat(auto-fill, minmax(148px, 1fr)); gap: 9px; }
    .card { border-radius: 12px; }

    /* Phones: two tiles per row. Three fits mathematically but the pattern
       rows shrink past reading size, so the grid trades density for legibility. */
    .ggrid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 9px; }

    .gcard { padding: 7px 7px 9px; border-radius: 12px; gap: 6px; }
    .gcard-name { font-size: 11px; }
    .gcard-pola span { font-size: 9px; padding: 3px 6px; }
    .gcard-pct { font-size: 9.5px; }
    /* Art is ~130-176px wide here, so the warning has to hold three lines
       without covering the whole tile, and the pill shrinks to fit the centre. */
    .gcard-warn { font-size: 7.5px; padding: 4px 4px 5px; letter-spacing: .02em; }
    .gcard-play { padding: 7px 14px; font-size: 10px; letter-spacing: .08em; }
}

/* Narrow phones keep the name on one line so the tile rows stay even. */
@media (max-width: 380px) {
    .gcard-name { -webkit-line-clamp: 2; font-size: 10.5px; }
}

/* ---------- APK download band ---------- */

/* Sits directly under the provider grid: copy on the left, phone art on the
   right, and on narrow screens the art tucks in behind the copy so the band
   never grows taller than one screen. */
.apk {
    position: relative;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: clamp(14px, 3vw, 34px);
    margin-top: clamp(18px, 2.6vw, 28px);
    padding: clamp(24px, 3.2vw, 40px) clamp(18px, 3.2vw, 36px);
    min-height: clamp(210px, 20vw, 300px);
    border: 1px solid var(--line-2);
    border-radius: var(--radius);
    overflow: hidden;
    background:
        radial-gradient(680px 300px at 88% 18%, rgba(255, 217, 25, .2), transparent 66%),
        radial-gradient(520px 280px at 8% 96%, rgba(255, 122, 0, .2), transparent 62%),
        linear-gradient(168deg, #241704 0%, #170e03 58%, #1d1204 100%);
    box-shadow: var(--shadow);
    isolation: isolate;
}

/* Thin gold seam along the top edge, echoing the provider cards. */
.apk::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 2px;
    background: linear-gradient(90deg, transparent, var(--y-500), var(--o-500), transparent);
    opacity: .75;
}

/* Two halves that slide in from opposite edges when the band scrolls into
   view — the left copy from the left, the phone art from the right. The JS
   adds .is-animated (proving it is alive) and then .is-revealed once the band
   is 40% up the viewport. Without JS the band simply sits visible. */
.apk.is-animated .apk-half {
    opacity: 0;
    transition: opacity .9s ease, transform .9s cubic-bezier(.22, .61, .36, 1);
    will-change: opacity, transform;
}

.apk.is-animated .apk-copy { transform: translateX(-60px); }
.apk.is-animated .apk-art  { transform: translateX(60px); }

.apk.is-animated.is-revealed .apk-half {
    opacity: 1;
    transform: translateX(0);
}

/* Stagger the art slightly so the two halves don't land on the same frame. */
.apk.is-animated.is-revealed .apk-art { transition-delay: .1s; }

.apk-copy { position: relative; z-index: 2; min-width: 0; }

.apk-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 10px;
    font-size: 9px;
    font-weight: 800;
    letter-spacing: .2em;
    color: var(--y-400);
}

.apk-title {
    margin: 0;
    font-size: clamp(21px, 3.4vw, 32px);
    line-height: 1.12;
    font-weight: 900;
    letter-spacing: -.01em;
    color: var(--text);
}

.apk-title span {
    background: linear-gradient(96deg, var(--y-500), var(--o-500) 72%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    -webkit-text-fill-color: transparent;
}

.apk-sub {
    margin: 8px 0 0;
    font-size: 13px;
    font-weight: 600;
    color: var(--muted);
}

.apk-actions {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px 16px;
    margin-top: clamp(16px, 2.4vw, 22px);
}

/* Download button: solid gold face, dark text — the loudest thing in the band. */
.apk-btn {
    display: inline-flex;
    align-items: center;
    gap: 11px;
    padding: 11px 20px 11px 16px;
    border-radius: 999px;
    background: linear-gradient(168deg, var(--y-400), var(--y-600) 62%, var(--o-500));
    color: #23160a;
    border: 1px solid rgba(255, 255, 255, .32);
    box-shadow: 0 12px 26px -12px rgba(255, 122, 0, .8), inset 0 1px 0 rgba(255, 255, 255, .5);
    transition: transform .16s ease, box-shadow .16s ease, filter .16s ease;
}

.apk-btn:hover,
.apk-btn:focus-visible {
    transform: translateY(-2px);
    filter: brightness(1.05);
    box-shadow: 0 18px 34px -14px rgba(255, 122, 0, .9), inset 0 1px 0 rgba(255, 255, 255, .6);
    outline: none;
}

.apk-btn[aria-disabled="true"] { cursor: not-allowed; filter: saturate(.72); }
.apk-btn[aria-disabled="true"]:hover { transform: none; }

.apk-btn-icon { width: 22px; height: 22px; flex: 0 0 auto; }

.apk-btn-text { display: flex; flex-direction: column; line-height: 1.15; text-align: left; }
.apk-btn-text b { font-size: 14px; font-weight: 900; letter-spacing: .01em; }
.apk-btn-text small { font-size: 10px; font-weight: 700; opacity: .72; letter-spacing: .04em; }

.apk-guide {
    padding: 9px 14px;
    font: inherit;
    font-size: 12px;
    font-weight: 700;
    color: var(--y-400);
    background: transparent;
    border: 1px solid var(--line-2);
    border-radius: 999px;
    cursor: pointer;
    transition: border-color .16s ease, color .16s ease, background .16s ease;
}

.apk-guide:hover,
.apk-guide:focus-visible {
    color: var(--y-500);
    border-color: rgba(255, 217, 25, .5);
    background: rgba(255, 217, 25, .08);
    outline: none;
}

/* Phone art: transparent PNG, drop-shadowed to sit on the plate. Sized large
   enough to give the band real height; the copy column stays minmax(0,1fr)
   so the grid never lets the art squeeze the text. */
.apk-art {
    position: relative;
    z-index: 1;
    justify-self: end;
    align-self: center;
    width: clamp(230px, 33vw, 400px);
    /* Hold the art off the right border — the tassel on the PNG runs to the
       very edge of its bounding box and otherwise touches the frame. */
    margin: -10px clamp(0px, 1.2vw, 16px) 0 0;
    pointer-events: none;
}

.apk-phone {
    display: block; /* kills the inline-image baseline gap under the phone */
    width: 100%;
    height: auto;
    filter: drop-shadow(0 22px 30px rgba(0, 0, 0, .55)) saturate(1.03);
}

/* ---------- APK install guide modal ---------- */

.apk-modal {
    position: fixed;
    inset: 0;
    z-index: 90;
    display: grid;
    place-items: center;
    padding: 18px;
}

.apk-modal[hidden] { display: none; }

.apk-modal-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(6, 3, 0, .78);
    backdrop-filter: blur(3px);
}

.apk-modal-card {
    position: relative;
    width: min(460px, 100%);
    max-height: 86vh;
    overflow: auto;
    padding: clamp(20px, 3vw, 28px);
    border: 1px solid var(--line-2);
    border-radius: var(--radius);
    background: linear-gradient(170deg, #241704, #150d03);
    box-shadow: 0 40px 80px -30px rgba(0, 0, 0, .9);
}

.apk-modal-card h3 {
    margin: 0 0 14px;
    font-size: 17px;
    font-weight: 900;
    letter-spacing: -.01em;
}

.apk-modal-x {
    position: absolute;
    top: 10px;
    right: 12px;
    width: 30px;
    height: 30px;
    font-size: 20px;
    line-height: 1;
    color: var(--muted);
    background: transparent;
    border: 0;
    border-radius: 50%;
    cursor: pointer;
}

.apk-modal-x:hover,
.apk-modal-x:focus-visible { color: var(--y-500); background: rgba(255, 217, 25, .1); outline: none; }

.apk-steps {
    margin: 0;
    padding-left: 20px;
    font-size: 13px;
    line-height: 1.62;
    color: var(--text);
}

.apk-steps li { margin-bottom: 9px; }
.apk-steps li::marker { color: var(--y-600); font-weight: 800; }

.apk-note {
    margin: 14px 0 0;
    padding-top: 12px;
    border-top: 1px solid var(--line);
    font-size: 11px;
    line-height: 1.5;
    color: var(--muted);
}

@media (max-width: 560px) {
    .apk {
        grid-template-columns: 1fr;
        justify-items: center;
        text-align: center;
        gap: 4px;
        padding: clamp(18px, 5vw, 24px) 18px clamp(20px, 5.4vw, 26px);
        min-height: 0;
    }

    /* Stacked, not tucked: the art takes its own row above the copy, centered
       and full-opacity. Positioning it in a corner clipped the tassels and let
       it collide with the buttons, so it gets real space instead. */
    .apk-art,
    .apk.is-animated .apk-art,
    .apk.is-animated.is-revealed .apk-art {
        position: static;
        order: -1;
        justify-self: center;
        width: min(250px, 70%);
        max-width: none;
        opacity: 1;
        transform: none;
        transition: none;
    }

    .apk-phone { filter: drop-shadow(0 14px 20px rgba(0, 0, 0, .5)) saturate(1.03); }

    .apk-copy { padding-right: 0; width: 100%; }

    .apk-eyebrow { justify-content: center; }
    .apk-title { margin-top: 6px; }

    .apk-actions {
        position: relative;
        z-index: 3;
        justify-content: center;
        flex-wrap: wrap;
        gap: 10px;
        padding-right: 0;
        margin-top: 14px;
    }

    .apk-btn { padding: 10px 18px 10px 14px; }
    .apk-btn-text b { font-size: 13px; }
}

/* ---------- bottom navigation (mobile) ---------- */

/* Sticky tab bar for phones. Hidden from 861px up, where the topbar already
   carries navigation and a second bar would just eat the viewport. */
.bnav {
    display: none;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 80;
    padding-bottom: env(safe-area-inset-bottom, 0px);
    background: linear-gradient(180deg, rgba(18, 10, 2, .92), rgba(10, 6, 1, .98));
    border-top: 1px solid var(--line-2);
    box-shadow: 0 -14px 34px -18px rgba(0, 0, 0, .9);
    backdrop-filter: blur(10px);
}

.bnav-in {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    max-width: 620px;
    margin: 0 auto;
}

.bnav-tab {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    padding: 9px 4px 8px;
    font: inherit;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .02em;
    color: var(--muted);
    background: transparent;
    border: 0;
    cursor: pointer;
    transition: color .16s ease;
    -webkit-tap-highlight-color: transparent;
}

.bnav-tab:hover,
.bnav-tab:focus-visible { color: var(--y-400); outline: none; }

.bnav-icon {
    width: 21px;
    height: 21px;
    flex: 0 0 auto;
    transition: transform .16s ease;
}

.bnav-label { line-height: 1; }

/* Active tab: gold, with a short amber bar on the top edge. */
.bnav-tab.is-active { color: var(--y-500); }

.bnav-tab.is-active::before {
    content: "";
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 26px;
    height: 2px;
    border-radius: 0 0 2px 2px;
    background: linear-gradient(90deg, var(--y-500), var(--o-500));
    box-shadow: 0 0 12px rgba(255, 217, 25, .6);
}

.bnav-tab.is-active .bnav-icon { transform: translateY(-1px); }

/* ---------- account drawer (right-edge slide) ---------- */

/* The hamburger only exists on phones — from 861px up the topbar's MASUK pill
   already does the job and a second control would be noise. */
.navtoggle {
    display: none;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    /* The marquee is hidden on phones, so nothing else pushes this to the
       right edge — the auto margin is what keeps it in the corner. */
    margin-left: auto;
    width: 40px;
    height: 36px;
    padding: 0 9px;
    font: inherit;
    background: linear-gradient(135deg, rgba(255, 217, 25, .16), rgba(255, 122, 0, .16));
    border: 1px solid var(--line-2);
    border-radius: 11px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: background .18s ease, border-color .18s ease, transform .18s ease;
    /* Belt and braces: the auto margin above pins it right even if the
       sibling order or the marquee's flex growth changes later. */
    order: 99;
    justify-self: flex-end;
    flex: 0 0 auto;
}

.navtoggle > span {
    display: block;
    height: 2px;
    border-radius: 2px;
    background: var(--y-400);
    box-shadow: 0 0 8px rgba(255, 217, 25, .45);
    transition: transform .26s cubic-bezier(.22, .61, .36, 1), opacity .18s ease, width .26s ease;
}

.navtoggle > span:nth-child(1) { width: 100%; }
.navtoggle > span:nth-child(2) { width: 74%; }
.navtoggle > span:nth-child(3) { width: 88%; }

.navtoggle:hover,
.navtoggle:focus-visible {
    background: linear-gradient(135deg, rgba(255, 217, 25, .28), rgba(255, 122, 0, .28));
    border-color: rgba(255, 217, 25, .5);
    outline: none;
}

.navtoggle:active { transform: scale(.95); }

/* X-shape while the drawer is open, so the same control closes it. */
.navtoggle[aria-expanded="true"] > span { width: 100%; }
.navtoggle[aria-expanded="true"] > span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.navtoggle[aria-expanded="true"] > span:nth-child(2) { opacity: 0; }
.navtoggle[aria-expanded="true"] > span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* Fixed overlay, full viewport, above the bottom bar and the guide modal.
   The panel itself starts translated fully off the right edge and slides in
   on .is-open — transform only, so it composites on the GPU and the scroll
   beneath never repaints. */
.acct {
    position: fixed;
    inset: 0;
    z-index: 120;
    display: flex;
    justify-content: flex-end;
}

.acct[hidden] { display: none; }

.acct-scrim {
    position: absolute;
    inset: 0;
    background: rgba(8, 4, 0, .72);
    backdrop-filter: blur(3px);
    opacity: 0;
    transition: opacity .34s ease;
}

.acct.is-open .acct-scrim { opacity: 1; }

.acct-panel {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    width: min(340px, 86vw);
    height: 100%;
    padding: 16px 18px calc(20px + env(safe-area-inset-bottom, 0px));
    background:
        radial-gradient(420px 220px at 100% 0%, rgba(255, 217, 25, .16), transparent 62%),
        radial-gradient(360px 220px at 0% 100%, rgba(255, 122, 0, .16), transparent 60%),
        linear-gradient(196deg, #1c1204 0%, #120b02 62%, #170e03 100%);
    border-left: 1px solid var(--line-2);
    box-shadow: -24px 0 60px -22px rgba(0, 0, 0, .92);
    overflow-y: auto;
    overscroll-behavior: contain;
    transform: translateX(100%);
    transition: transform .38s cubic-bezier(.22, .61, .36, 1);
    will-change: transform;
}

.acct.is-open .acct-panel { transform: translateX(0); }

/* Contents ride in a beat behind the panel so the slide reads as one motion
   rather than a flat sheet of paper arriving. */
.acct-body {
    opacity: 0;
    transform: translateX(18px);
    transition: opacity .3s ease .06s, transform .36s cubic-bezier(.22, .61, .36, 1) .06s;
}

.acct.is-open .acct-body { opacity: 1; transform: translateX(0); }

.acct-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding-bottom: 14px;
    border-bottom: 1px solid var(--line);
}

.acct-logo {
    height: 30px;
    width: auto;
    mix-blend-mode: screen;
    filter: drop-shadow(0 4px 14px rgba(255, 122, 0, .45)) saturate(1.1);
}

.acct-close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    flex: 0 0 auto;
    color: var(--muted);
    background: rgba(255, 217, 25, .07);
    border: 1px solid var(--line);
    border-radius: 10px;
    cursor: pointer;
    transition: color .18s ease, background .18s ease;
}

.acct-close svg { width: 17px; height: 17px; }
.acct-close:hover,
.acct-close:focus-visible { color: var(--y-500); background: rgba(255, 217, 25, .14); outline: none; }

.acct-guest {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 20px 0 14px;
}

.acct-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 52px;
    height: 52px;
    flex: 0 0 auto;
    color: #2a1500;
    background: linear-gradient(135deg, var(--y-400), var(--o-500));
    border-radius: 50%;
    box-shadow: 0 10px 24px -12px rgba(255, 122, 0, .9), inset 0 1px 0 rgba(255, 255, 255, .5);
}

.acct-avatar svg { width: 28px; height: 28px; }

.acct-title {
    margin: 0;
    font-size: 19px;
    font-weight: 900;
    letter-spacing: .01em;
    color: var(--text);
}

.acct-state {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 3px 0 0;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--muted);
}

.acct-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--o-500);
    box-shadow: 0 0 10px rgba(255, 122, 0, .8);
}

.acct-note {
    margin: 0 0 18px;
    font-size: 12.5px;
    line-height: 1.62;
    color: var(--muted);
}

.acct-actions {
    display: grid;
    gap: 9px;
    margin-bottom: 20px;
}

.acct-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 12px 16px;
    font-size: 13px;
    font-weight: 900;
    letter-spacing: .08em;
    text-transform: uppercase;
    border-radius: 12px;
    transition: transform .16s ease, box-shadow .16s ease, background .16s ease, border-color .16s ease;
}

.acct-btn svg { width: 15px; height: 15px; }

.acct-btn-primary {
    color: #2a1500;
    background: linear-gradient(135deg, var(--y-400), var(--o-500));
    box-shadow: 0 12px 28px -14px rgba(255, 122, 0, .95), inset 0 1px 0 rgba(255, 255, 255, .5);
}

.acct-btn-primary:hover,
.acct-btn-primary:focus-visible { transform: translateY(-1px); outline: none; }

.acct-btn-ghost {
    color: var(--y-400);
    background: rgba(255, 217, 25, .07);
    border: 1px solid var(--line-2);
}

.acct-btn-ghost:hover,
.acct-btn-ghost:focus-visible { background: rgba(255, 217, 25, .14); border-color: rgba(255, 217, 25, .5); outline: none; }

.acct-links {
    display: grid;
    gap: 2px;
    padding-top: 16px;
    border-top: 1px solid var(--line);
}

.acct-links a {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 11px 10px;
    font-size: 13px;
    font-weight: 700;
    color: var(--text);
    border-radius: 10px;
    transition: background .16s ease, color .16s ease, transform .16s ease;
}

.acct-links a svg { width: 18px; height: 18px; color: var(--y-500); flex: 0 0 auto; }

.acct-links a:hover,
.acct-links a:focus-visible {
    color: var(--y-400);
    background: rgba(255, 217, 25, .08);
    transform: translateX(3px);
    outline: none;
}

body.acct-locked { overflow: hidden; }

@media (max-width: 860px) {
    .bnav { display: block; }

    /* Keep the last content clear of the fixed bar. */
    body { padding-bottom: calc(62px + env(safe-area-inset-bottom, 0px)); }

    /* The guide modal must sit above the bar, not behind it. */
    .apk-modal { z-index: 95; }

    /* Phones: the MASUK pill gives way to the hamburger. */
    .navtoggle { display: flex; }
    .topbar > .cta { display: none; }
}

@media (prefers-reduced-motion: reduce) {
    .marquee-track, .pulse { animation: none; }
    * { transition: none !important; }

    /* Nothing animates here, so nothing may stay hidden waiting to. Scoped to
       the animation's own state so it cannot clobber the absolute positioning
       the mobile block gives .apk-art. */
    .apk.is-animated .apk-half { opacity: 1 !important; transform: none !important; }
    .apk.is-animated .apk-art { transform: none !important; }
}