﻿/* ==========================================================================
   1. VARIABLES & GLOBAL STYLES
   ========================================================================== */
:root {
    --sgt-cyan: #00d2ff;
    --sgt-cyan-hover: #00a8cc;
    --sgt-dark-bg: #0f1115;
}

html {
    /* Reserves space on BOTH sides so the content NEVER jumps or offsets */
    scrollbar-gutter: stable both-edges;
    background-color: var(--sgt-dark-bg);
    /* Baseline. Bootstrap + most app CSS is rem-based, so shrinking the root font cascades
       to padding/margin/gaps/heights/widths/icon sizes across the entire site. Desktop
       breakpoints below adjust this; mobile keeps the default for readability + parity with
       Bootstrap's expected sizing. */
    font-size: 16px;
}

/* Responsive root-font scaling. Targets common desktop/laptop/ultra-wide/4K resolutions so
   the site doesn't feel oversized on smaller-than-FHD displays and stays readable on 4K.
   Mobile/tablet (<1024px) intentionally NOT included — those rely on Bootstrap's mobile
   breakpoints and the viewport meta tag, and shrinking the root font there would make
   touch targets too small. Cascading min-width queries: only the largest matching rule wins. */
@media (min-width: 1024px) { html { font-size: 13px; } }      /* 1024x768, 1280x720/800/960/1024, 1366x768 */
@media (min-width: 1400px) { html { font-size: 13.5px; } }    /* 1400x900 */
@media (min-width: 1600px) { html { font-size: 14.5px; } }    /* 1600x900, 1680x1050, 1600x1200 */
@media (min-width: 1920px) { html { font-size: 16px; } }      /* 1920x1080 baseline */
@media (min-width: 2560px) { html { font-size: 17px; } }      /* 2560x1080, 2560x1440 */
@media (min-width: 3440px) { html { font-size: 18px; } }      /* 3440x1440, 3840x2160 */

html, body {
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
    background-color: var(--sgt-dark-bg);
    color: #fff;
}

a, .btn-link {
    color: var(--sgt-cyan);
}

/* ==========================================================================
   2. GLOBAL SCROLLBARS
   ========================================================================== */
/* Webkit (Chrome/Edge/Safari) */
body::-webkit-scrollbar {
    width: 12px;
}

body::-webkit-scrollbar-track {
    background: transparent;
}

body::-webkit-scrollbar-thumb {
    background-color: transparent;
    border-radius: 20px;
    border: 3px solid transparent;
    background-clip: content-box;
    transition: background-color 0.5s ease;
}

/* High-Visibility "Scrolled" State */
body.is-scrolling::-webkit-scrollbar-thumb {
    background-color: rgba(0, 210, 255, 0.5);
    border: 3px solid var(--sgt-dark-bg);
}

body::-webkit-scrollbar-thumb:hover {
    background-color: var(--sgt-cyan) !important;
}

/* Firefox Support */
html {
    scrollbar-color: transparent transparent;
    scrollbar-width: thin;
}

    html.is-scrolling {
        scrollbar-color: rgba(0, 210, 255, 0.5) transparent;
    }

/* ==========================================================================
   3. BLAZOR DEFAULTS & FORMS
   ========================================================================== */

/* --- Stop Mobile Double-Tap Zoom --- */
/* This tells mobile browsers not to wait for a double-tap to zoom, 
   which also magically removes the infamous 300ms mobile click delay! */
button,
.btn,
.dropdown-menu,
.dropdown-item {
    touch-action: manipulation !important;
}

.content {
    padding-top: 1.1rem;
}

h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid #e50000;
}

.validation-message {
    color: #e50000;
}

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred.";
    }

/* ==========================================================================
   4. NAVBAR & BUTTONS
   ========================================================================== */
.custom-glass-nav {
    background: rgba(15, 17, 21, 0.4);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border-bottom: 1px solid rgba(0, 210, 255, 0.1);
    transition: all 0.3s ease;
}

.custom-nav-dropdown {
    background-color: rgba(15, 17, 21, 0.95);
    backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.05) !important;
    border-radius: 12px;
    min-width: 220px;
}

    .custom-nav-dropdown .dropdown-item {
        color: rgba(255, 255, 255, 0.8);
        transition: all 0.2s ease;
        font-weight: 500;
        font-size: 0.9rem;
    }

        .custom-nav-dropdown .dropdown-item:hover,
        .custom-nav-dropdown .dropdown-item:focus {
            background-color: rgba(0, 210, 255, 0.1);
            color: #fff;
            padding-left: 1.5rem;
        }

        .custom-nav-dropdown .dropdown-item.active {
            background-color: transparent;
            color: var(--sgt-cyan);
        }

.text-primary {
    color: var(--sgt-cyan) !important;
}

.btn-primary {
    color: #000 !important;
    background-color: var(--sgt-cyan);
    border-color: var(--sgt-cyan);
    font-weight: 600;
}

    .btn-primary:hover, .btn-primary:focus, .btn-primary:active {
        color: #000 !important;
        background-color: var(--sgt-cyan-hover);
        border-color: var(--sgt-cyan-hover);
    }

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
    box-shadow: 0 0 0 0.25rem rgba(0, 210, 255, 0.25);
}

.btn-shimmer {
    position: relative;
    overflow: hidden;
}

    .btn-shimmer::after {
        content: '';
        position: absolute;
        top: 0;
        left: -150%;
        width: 50%;
        height: 100%;
        background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.5), transparent);
        transform: skewX(-25deg);
        transition: 0s;
    }

    .btn-shimmer:hover::after {
        left: 150%;
        transition: 0.7s ease-in-out;
    }

/* ==========================================================================
   5. HOME PAGE SECTIONS
   ========================================================================== */
.hero-section {
    min-height: 100vh;
    margin-top: -80px;
    padding-top: 80px;
    /*background: radial-gradient(circle at center, rgba(0, 0, 0, 0.2) 0%, var(--sgt-dark-bg) 85%), url('/images/hero-bg.jpg') no-repeat center center;*/
    background-size: cover;
}

/* Feature Cards */
.feature-wrapper {
    position: relative;
    z-index: 1;
}

.feature-card {
    background-color: rgba(15, 17, 21, 0.8);
    border: 1px solid rgba(255, 255, 255, 0.05);
    border-radius: 12px;
    transition: all 0.3s ease;
    position: relative;
    z-index: 2;
}

    .feature-card:hover {
        transform: translateY(-5px);
        border-color: rgba(0, 210, 255, 0.3);
        background-color: rgba(15, 17, 21, 1);
        box-shadow: 0 10px 30px rgba(0, 210, 255, 0.05);
    }

.feature-aura {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 100%;
    height: 100%;
    transform: translate(-50%, -50%) scale(0.9);
    border-radius: 12px;
    opacity: 0;
    z-index: -1;
    filter: blur(25px);
    transition: opacity 0.4s cubic-bezier(0.25, 0.8, 0.25, 1), transform 0.4s cubic-bezier(0.25, 0.8, 0.25, 1);
}

.feature-wrapper:hover .feature-aura {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1.05);
}

.feature-icon-wrapper {
    width: 60px;
    height: 60px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 12px;
    background: rgba(0, 210, 255, 0.1);
    color: var(--sgt-cyan);
    margin-bottom: 1.5rem;
}

/* Showcase Section */
.showcase-container {
    overflow: hidden;
    min-height: 60vh;
    display: flex;
    align-items: center;
}

.tech-grid-bg {
    background-image: linear-gradient(rgba(0, 210, 255, 0.04) 1px, transparent 1px), linear-gradient(90deg, rgba(0, 210, 255, 0.04) 1px, transparent 1px);
    background-size: 40px 40px;
    background-position: center center;
}

.glowing-borders {
    box-shadow: inset 0 20px 20px -20px rgba(0, 210, 255, 0.15), inset 0 -20px 20px -20px rgba(0, 210, 255, 0.15);
}

.showcase-underlay {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 120%;
    height: 150%;
    background: radial-gradient(ellipse at center, rgba(0, 210, 255, 0.1) 0%, rgba(15, 17, 21, 0) 65%);
    z-index: 1;
    pointer-events: none;
    animation: sequenceUnderlay 12s infinite ease-in-out;
}

/* Footer */
.footer-link {
    transition: all 0.2s ease;
    display: inline-block;
}

    .footer-link:hover {
        color: var(--sgt-cyan) !important;
        opacity: 1 !important;
        transform: translateX(5px);
    }

/* ==========================================================================
   6. GAMES SECTION & CAROUSEL
   ========================================================================== */

/* The outer wrapper sets the stage height and protects arrow placement */
.scroll-wrapper {
    position: relative;
    padding: 0 5px; /* Mobile only: reducded from 40px to reclaim mobile space without arrows... */
}

#games-container {
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: nowrap !important;
    overflow-x: auto !important;
    gap: 1.5rem;
    -ms-overflow-style: none;
    scrollbar-width: none;
    /*15px top/bottom, 15px left/right for mobile edge-to-edge feel */
    padding: 15px 15px !important;
    width: 100%;
}

    #games-container::-webkit-scrollbar {
        display: none !important;
    }

/* The cards inside the track */
.game-track-card {
    width: 220px;
    flex-shrink: 0;
    position: relative;
}

    /* This centers the group of cards if they don't fill the screen,
    but reverts to standard left-aligned scrolling if there are many */
    .game-track-card:first-child {
        margin-left: auto !important;
    }

    .game-track-card:last-child {
        margin-right: auto !important;
    }
/* --------------------------- */

.game-card {
    transition: transform 0.3s cubic-bezier(0.25, 0.8, 0.25, 1), box-shadow 0.3s ease;
    box-shadow: 0 0 15px rgba(0,0,0,0.5);
    cursor: pointer;
    z-index: 1;
}

    .game-card:hover {
        transform: scale(1.05);
        box-shadow: 0 0 25px rgba(0, 210, 255, 0.4) !important;
        z-index: 10;
    }

    /* Active Modal Fullscreen State */
    .game-card.fullscreen-active {
        box-shadow: 0 0 80px rgba(0, 210, 255, 0.4) !important;
        border: 2px solid var(--sgt-cyan) !important;
        cursor: zoom-out !important;
    }

#games-container.sgt-modal-active .game-card-wrapper:not(.has-fullscreen) {
    filter: blur(8px) brightness(0.5);
    opacity: 0.7;
    pointer-events: none;
    transition: all 0.4s ease;
}

.sgt-glass-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    background: rgba(15, 17, 21, 0.5);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    z-index: 1040;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.4s ease;
}

    .sgt-glass-overlay.active {
        opacity: 1;
        pointer-events: auto;
    }

/* Image Previews */
.preview-container {
    position: relative;
    width: 100%;
    aspect-ratio: 9 / 16;
    overflow: hidden;
    background-color: #000;
}

.preview-frame {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
    opacity: 0;
    /* Kept comfortably under the rotation cadence in App.js so each crossfade completes
       before the next frame begins. */
    transition: opacity 0.8s ease-in-out;
}

    .preview-frame.active-frame {
        opacity: 1;
    }

/* Arrows & Hints */
.scroll-arrow {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 60px;
    color: var(--sgt-cyan);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 2.5rem;
    cursor: pointer;
    z-index: 10;
    opacity: 0;
    transition: opacity 0.3s ease, color 0.2s ease;
}

    .scroll-arrow.left {
        left: 0;
        background: linear-gradient(to right, rgba(15, 17, 21, 1) 0%, rgba(15, 17, 21, 0) 100%);
    }

    .scroll-arrow.right {
        right: 0;
        background: linear-gradient(to left, rgba(15, 17, 21, 1) 0%, rgba(15, 17, 21, 0) 100%);
    }

.scroll-wrapper:hover .scroll-arrow {
    opacity: 0.7;
}

.scroll-arrow:hover {
    opacity: 1 !important;
    color: #fff;
}

.swipe-helper {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 50px;
    height: 50px;
    background: rgba(0, 210, 255, 0.4);
    border: 2px solid var(--sgt-cyan);
    border-radius: 50%;
    z-index: 100;
    pointer-events: none;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    animation: ghostSwipe 2.5s ease-out forwards;
}

    .swipe-helper i {
        color: white;
        font-size: 1.5rem;
    }

/* Hide scroll arrows on mobile/tablet devices (users will just swipe) */
@media (max-width: 991px) {
    .scroll-arrow {
        display: none !important;
    }
}

/* Responsive Game Carousel Adjustments */
@media (min-width: 992px) {
    .game-track-card {
        width: 220px;
    }

    .scroll-wrapper {
        min-height: 420px;
        display: flex;
        align-items: center;
        padding: 0 40px; /* Restores the 40px space for the desktop click-arrows! */
    }

    #games-container {
        padding: 45px !important;
    }
}

@media (min-width: 1400px) {
    .game-track-card {
        /* Reduced from 280px to 240px to save about ~70px of vertical height */
        width: 240px;
    }

    .scroll-wrapper {
        /* Shrunk the minimum stage height to match the new card size */
        min-height: 460px;
    }

    #games-container {
        /* Kept padding at 45px (same as standard desktop) to ensure glow safety without wasting space */
        padding: 45px !important;
    }
}

/* ==========================================================================
   7. ANIMATIONS & KEYFRAMES
   ========================================================================== */
.reveal-up {
    opacity: 0;
    transform: translateY(40px);
    transition: all 0.7s cubic-bezier(0.25, 0.8, 0.25, 1);
}

    .reveal-up.active {
        opacity: 1 !important;
        transform: translateY(0);
    }

.kiosk-anim {
    animation: sequenceKiosk 12s infinite ease-in-out;
    max-height: 600px;
    z-index: 2;
}

.text-anim-1 {
    animation: sequenceText1 12s infinite ease-in-out;
    opacity: 0;
}

.text-anim-2 {
    animation: sequenceText2 12s infinite ease-in-out;
    opacity: 0;
}

.text-anim-3 {
    animation: sequenceText3 12s infinite ease-in-out;
    opacity: 0;
}

.pulse-text {
    display: inline-block;
    animation: sequencePulse 12s infinite ease-in-out;
}

@keyframes sequenceKiosk {
    0%, 5% {
        opacity: 0;
        transform: translateX(-30px);
    }

    15%, 85% {
        opacity: 1;
        transform: translateX(0);
    }

    90%, 100% {
        opacity: 0;
        transform: translateX(0);
    }
}

@keyframes sequenceText1 {
    0%, 5% {
        opacity: 0;
        transform: translateX(30px);
    }

    15%, 85% {
        opacity: 1;
        transform: translateX(0);
    }

    90%, 100% {
        opacity: 0;
        transform: translateX(0);
    }
}

@keyframes sequenceText2 {
    0%, 15% {
        opacity: 0;
        transform: translateX(30px);
    }

    25%, 85% {
        opacity: 1;
        transform: translateX(0);
    }

    90%, 100% {
        opacity: 0;
        transform: translateX(0);
    }
}

@keyframes sequenceText3 {
    0%, 25% {
        opacity: 0;
        transform: translateX(30px);
    }

    35%, 85% {
        opacity: 1;
        transform: translateX(0);
    }

    90%, 100% {
        opacity: 0;
        transform: translateX(0);
    }
}

@keyframes sequenceUnderlay {
    0%, 5% {
        opacity: 0;
    }

    15%, 85% {
        opacity: 1;
    }

    90%, 100% {
        opacity: 0;
    }
}

@keyframes ghostSwipe {
    0% {
        opacity: 0;
        transform: translate(50px, -50%);
    }

    20% {
        opacity: 1;
        transform: translate(50px, -50%);
    }

    80% {
        opacity: 1;
        transform: translate(-150px, -50%);
    }

    100% {
        opacity: 0;
        transform: translate(-150px, -50%);
    }
}

@keyframes sequencePulse {
    0%, 45% {
        transform: scale(1);
        color: var(--sgt-cyan);
    }

    50% {
        transform: scale(1.1);
        color: #fff;
        text-shadow: 0 0 20px rgba(0,210,255,0.8);
    }

    55% {
        transform: scale(1);
        color: var(--sgt-cyan);
    }

    60% {
        transform: scale(1.1);
        color: #fff;
        text-shadow: 0 0 20px rgba(0,210,255,0.8);
    }

    65% {
        transform: scale(1);
        color: var(--sgt-cyan);
    }

    70% {
        transform: scale(1.1);
        color: #fff;
        text-shadow: 0 0 20px rgba(0,210,255,0.8);
    }

    75%, 100% {
        transform: scale(1);
        color: var(--sgt-cyan);
    }
}

/* ==========================================================================
   8. LOGO SLOT MACHINE EFFECTS
   ========================================================================== */
.sgt-logo-container {
    position: relative;
    width: 100%;
    max-width: 650px;
    margin: 0 auto;
    aspect-ratio: 1567 / 510;
    filter: drop-shadow(0px 10px 20px rgba(0, 210, 255, 0.15));
    transition: transform 0.1s ease;
}

/* Padding-bottom aspect-ratio fallback for browsers without CSS aspect-ratio support
   (older Chromium/Edge/Firefox/Safari, some embedded webviews). 32.547% = 510/1567 — gives
   the container a proportional height when aspect-ratio is ignored. All the logo art is
   position:absolute inside; without explicit container height the container collapses to
   zero and the absolutely-positioned images render outside the visible area. */
@supports not (aspect-ratio: 1 / 1) {
    .sgt-logo-container::before {
        content: "";
        display: block;
        padding-bottom: 32.547%;
    }
}

    .sgt-logo-container:active {
        transform: scale(0.98);
    }

.logo-base {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    z-index: 10;
}

.slot-window {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    overflow: hidden;
    z-index: 5;
    -webkit-mask-image: linear-gradient(to bottom, transparent 0%, black 15%, black 75%, transparent 100%);
    mask-image: linear-gradient(to bottom, transparent 0%, black 15%, black 75%, transparent 100%);
}

.logo-letter {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    opacity: 1;
    transform: translateY(0) scale(1, 1);
}

.letter-s {
    animation: slotSpinInit 0.8s ease-out forwards;
}

.letter-g {
    animation: slotSpinInit 1.2s ease-out forwards;
}

.letter-t {
    animation: slotSpinInit 1.6s ease-out forwards;
}

.spinning {
    animation: slotSpinInfinite 0.55s linear infinite;
    opacity: 0.7 !important;
}

.stopping {
    animation: slotSpinStop 0.6s ease-out forwards;
    opacity: 1 !important;
}

@keyframes slotSpinInit {
    0% {
        transform: translateY(-250%) scale(1, 0.3);
        opacity: 0;
        filter: blur(5px);
    }

    30% {
        transform: translateY(250%) scale(1, 0.3);
        opacity: 0.8;
        filter: blur(5px);
    }

    30.1% {
        transform: translateY(-250%) scale(1, 0.3);
        opacity: 0;
    }

    60% {
        transform: translateY(20px) scale(1, 1.15);
        opacity: 1;
        filter: blur(0);
    }

    80% {
        transform: translateY(-8px) scale(1, 0.9);
        opacity: 1;
    }

    100% {
        transform: translateY(0) scale(1, 1);
        opacity: 1;
        filter: brightness(1);
    }
}

@keyframes slotSpinInfinite {
    0% {
        transform: translateY(-250%) scale(1, 0.3);
        filter: blur(6px);
    }

    50% {
        transform: translateY(250%) scale(1, 0.3);
        filter: blur(6px);
    }

    50.1% {
        transform: translateY(-250%) scale(1, 0.3);
    }

    100% {
        transform: translateY(250%) scale(1, 0.3);
        filter: blur(6px);
    }
}

@keyframes slotSpinStop {
    0% {
        transform: translateY(-150%) scale(1, 0.3);
        filter: blur(4px);
    }

    30% {
        transform: translateY(20px) scale(1, 1.15);
        filter: blur(0);
    }

    50% {
        transform: translateY(-8px) scale(1, 0.9);
    }

    70% {
        transform: translateY(0) scale(1, 1);
        filter: brightness(1) drop-shadow(0 0 0 rgba(0,210,255,0));
    }

    85% {
        transform: translateY(0) scale(1.03, 1.03);
        filter: brightness(1.3) drop-shadow(0 0 15px rgba(0,210,255,0.9));
    }

    100% {
        transform: translateY(0) scale(1, 1);
        filter: brightness(1);
    }
}

.initial-pulse {
    animation: logoPulseAnim 0.6s ease-out 2.11s forwards;
}

.interactive-pulse {
    animation: logoPulseAnim 0.6s ease-out forwards;
}

@keyframes logoPulseAnim {
    0% {
        transform: scale(1);
    }

    40% {
        transform: scale(1.05);
        filter: drop-shadow(0px 15px 40px rgba(0, 210, 255, 0.5));
    }

    100% {
        transform: scale(1);
        filter: drop-shadow(0px 10px 20px rgba(0, 210, 255, 0.15));
    }
}

.logo-sweep, .logo-star {
    position: absolute;
    top: 63.9%;
    left: 22.3%;
    width: 56.8%;
    height: 2%;
    pointer-events: none;
}

.logo-sweep {
    z-index: 20;
    overflow: hidden;
    border-radius: 5px;
}

.logo-star {
    z-index: 25;
}

.logo-sweep::before {
    content: '';
    position: absolute;
    top: 0;
    left: -10%;
    width: 3%;
    height: 100%;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 1), transparent);
    mix-blend-mode: color-dodge;
    transform: skewX(-45deg);
    opacity: 0;
}

.logo-star::after {
    content: '';
    position: absolute;
    top: 50%;
    width: 80px;
    height: 80px;
    margin-top: -40px;
    margin-left: -40px;
    background: radial-gradient(ellipse 40px 2px at center, rgba(255,255,255,1) 0%, transparent 100%), radial-gradient(ellipse 2px 40px at center, rgba(255,255,255,1) 0%, transparent 100%);
    mix-blend-mode: color-dodge;
    opacity: 0;
}

.sweep-initial::before {
    animation: sweepLight 0.9s ease-in 2.3s forwards;
}

.interactive-sweep::before {
    animation: sweepLight 0.9s ease-in forwards;
}

.star-initial::after {
    animation: sweepStar 0.9s ease-in 2.3s forwards;
}

.interactive-star::after {
    animation: sweepStar 0.9s ease-in forwards;
}

@keyframes sweepLight {
    0% {
        left: -10%;
        width: 2%;
        opacity: 0;
        filter: brightness(1);
    }

    15% {
        opacity: 0.6;
    }

    70% {
        left: 70%;
        width: 6%;
        opacity: 0.9;
        filter: brightness(1.5);
    }

    85% {
        left: 88%;
        width: 14%;
        opacity: 1;
        filter: brightness(3) drop-shadow(0 0 10px rgba(255,255,255,1));
    }

    100% {
        left: 110%;
        width: 2%;
        opacity: 0;
        filter: brightness(1);
    }
}

@keyframes sweepStar {
    0% {
        left: -10%;
        transform: rotate(0deg) scale(0);
        opacity: 0;
    }

    15% {
        opacity: 0;
    }

    70% {
        left: 70%;
        transform: rotate(-45deg) scale(0.6);
        opacity: 0.8;
    }

    85% {
        left: 88%;
        transform: rotate(-100deg) scale(1.6);
        opacity: 1;
        filter: brightness(2.5);
    }

    100% {
        left: 110%;
        transform: rotate(-180deg) scale(0);
        opacity: 0;
    }
}

/* ==========================================================================
   9. LIGHT MODE OVERRIDES
   ========================================================================== */
[data-bs-theme="light"] body {
    --sgt-dark-bg: #f0f2f5;
    color: #2c3e50;
}

[data-bs-theme="light"] .text-white, [data-bs-theme="light"] .text-light, [data-bs-theme="light"] .feature-card h4, [data-bs-theme="light"] .feature-card p {
    color: #2c3e50 !important;
}

[data-bs-theme="light"] .bg-dark, [data-bs-theme="light"] .feature-card {
    background-color: #ffffff !important;
    border-color: #dee2e6 !important;
    box-shadow: 0 8px 20px rgba(0,0,0,0.05) !important;
}

[data-bs-theme="light"] .custom-glass-nav {
    background: rgba(240, 242, 245, 0.85);
    border-bottom: 1px solid rgba(0, 0, 0, 0.05);
}

[data-bs-theme="light"] .hero-section {
    background: radial-gradient(circle at center, rgba(255, 255, 255, 0.9) 0%, rgba(240, 242, 245, 0.95) 100%), url('/images/hero-bg.jpg') no-repeat center center;
    background-blend-mode: overlay;
}

[data-bs-theme="light"] .dropdown-menu-dark {
    background-color: #ffffff;
    border: 1px solid #dee2e6 !important;
}

    [data-bs-theme="light"] .dropdown-menu-dark .dropdown-item {
        color: #2c3e50;
    }

        [data-bs-theme="light"] .dropdown-menu-dark .dropdown-item:hover {
            background-color: #f8f9fa;
        }

[data-bs-theme="light"] .form-control.bg-dark, [data-bs-theme="light"] .form-select.bg-dark {
    background-color: #ffffff !important;
    color: #2c3e50 !important;
    border-color: #ced4da !important;
}

[data-bs-theme="light"] .showcase-container {
    background-color: #e9ecef !important;
    border-top: 2px solid rgba(0, 210, 255, 0.5) !important;
    border-bottom: 2px solid rgba(0, 210, 255, 0.5) !important;
    box-shadow: 0 0 30px rgba(0,0,0,0.05) !important;
}

[data-bs-theme="light"] .showcase-underlay {
    background: radial-gradient(ellipse at center, rgba(0, 210, 255, 0.2) 0%, rgba(255, 255, 255, 0) 65%);
}

/* ==========================================================================
   6b. MEDIA PREVIEW LIGHTBOX (Games - new page)
   Namespaced sgt-mp-* so nothing here can reach the original Games carousel.
   ========================================================================== */

/* A: always-visible affordance that the card opens a gallery. Mirrors the media badge in the
   opposite corner so the two read as a pair rather than competing. pointer-events stay off so
   neither can swallow the click or confuse the carousel drag guard. */
/* Info panel below the artwork: centred title on the first line, affordance and media counts
   on the second. Sits outside the image so nothing covers the screenshot. */
.sgt-card-info {
    display: flex;
    flex-direction: column;
    gap: 5px;
    padding: 7px 9px 8px;
    background: #000;
    border-top: 1px solid rgba(255, 255, 255, 0.12);
    pointer-events: none;
}

.sgt-card-title {
    margin: 0;
    font-size: 0.85rem;
    line-height: 1.25;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    color: #fff;
    text-align: center;
    /* One line for every card. Reserving a second line meant one long name left every other
       card with an empty gap, so the size is set to fit the longest title instead. Ellipsis is
       kept purely as a safety net if a longer name is added later. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.sgt-card-meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
}

.sgt-card-view-hint {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 9px;
    border-radius: 999px;
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: #fff;
    background: rgba(0, 210, 255, 0.14);
    border: 1px solid rgba(0, 210, 255, 0.6);
    white-space: nowrap;
    transition: background 0.25s ease, border-color 0.25s ease, color 0.25s ease;
}

/* The longer label and the scrim are hover-only: on touch the short pill is the whole story. */
.sgt-card-view-more {
    display: none;
}

@media (hover: hover) {
    .game-card .preview-container::after {
        content: "";
        position: absolute;
        inset: 0;
        z-index: 2;
        /* The glass bar already handles legibility at the top, so hover just deepens the whole
           face to signal interactivity rather than shading one edge. */
        background: rgba(0, 0, 0, 0.28);
        opacity: 0;
        transition: opacity 0.25s ease;
        pointer-events: none;
    }

    .game-card:hover .preview-container::after {
        opacity: 1;
    }

    .game-card:hover .sgt-card-view-hint {
        background: rgba(0, 210, 255, 0.9);
        border-color: rgba(0, 210, 255, 0.9);
        color: #000;
    }

        .game-card:hover .sgt-card-view-more {
            display: inline;
        }
}

/* Permanent: it was dismissed on first interaction, but losing its height snapped the
   carousel upward, which looked like a rendering fault. */
/* No capsule: the padding and border cost a row of vertical space on a phone for decoration
   the text can carry itself. */
.games-open-hint-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 1.05rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    color: var(--sgt-cyan);
    text-shadow: 0 0 12px rgba(0, 210, 255, 0.35);
}

/* The hand carries the affordance, so it gets the motion; the pill only breathes. Separating
   them keeps the label readable instead of pulsing under the eye while being read. */
.games-open-hint-icon {
    font-size: 1.3rem;
    color: var(--sgt-cyan);
    animation: sgt-hint-tap 2.8s ease-in-out infinite;
}

/* Mostly glow, barely any growth: scale moved the text toward the icon and toward a wrap on a
   phone, where text-shadow costs no layout at all. */
@keyframes sgt-hint-breathe {
    0%, 100% {
        transform: scale(1);
        opacity: 0.85;
        text-shadow: 0 0 6px rgba(0, 210, 255, 0.22);
    }

    50% {
        transform: scale(1.015);
        opacity: 1;
        text-shadow: 0 0 10px rgba(0, 210, 255, 0.75), 0 0 24px rgba(0, 210, 255, 0.45);
    }
}

@keyframes sgt-hint-tap {
    0%, 70%, 100% { transform: translateY(0) scale(1); }
    80%           { transform: translateY(3px) scale(0.92); }
    90%           { transform: translateY(0) scale(1.06); }
}

@media (max-width: 575.98px) {
    .games-open-hint-pill {
        font-size: 0.95rem;
        gap: 0.4rem;
    }

    .games-open-hint-icon {
        font-size: 1.1rem;
    }

    /* Two labelled controls on one line at 390px: trim the label rather than wrap the row. */
    .games-controls-mobile .small {
        font-size: 0.7rem;
    }

}

/* The two messages share one grid cell so the line keeps the width of the longer of them and
   nothing shifts as they cross-fade. The breathing lives here rather than on the pill: with it
   on the parent the icon inherited the scale, and its own tap and swipe gestures were damped
   by whatever the text was doing at that moment. Transforms do not affect layout, so the icon
   stays put while the text grows around its own centre. */
.games-hint-msgs {
    display: inline-grid;
    transform-origin: center;
    animation: sgt-hint-breathe 2.8s ease-in-out infinite;
}

.games-hint-msg {
    grid-area: 1 / 1;
}

.games-hint-swipe {
    opacity: 0;
}

/* Only the Showcase has anything to swipe, so only it cycles. Dropping the class when the
   layout changes restores the default message and restarts the animation. */
.games-hint-cycle .games-hint-select {
    animation: sgt-hint-msg-out 7s ease-in-out infinite;
}

.games-hint-cycle .games-hint-swipe {
    animation: sgt-hint-msg-in 7s ease-in-out infinite;
}

/* One timeline shared with the messages above, so the gesture matches the phrase on screen:
   a tap while the first is up, a swipe while the second is. Every stop writes the whole
   transform — a keyframe that names only rotate would drop the translate set before it. */
.games-hint-cycle .games-open-hint-icon {
    animation: sgt-hint-gesture 7s ease-in-out infinite;
}

@keyframes sgt-hint-gesture {
    0%, 12% { transform: translate(0, 0) rotate(0deg) scale(1); }
    16% { transform: translate(0, 3px) rotate(0deg) scale(0.92); }
    20% { transform: translate(0, 0) rotate(0deg) scale(1.06); }
    24%, 48% { transform: translate(0, 0) rotate(0deg) scale(1); }
    56% { transform: translate(4px, 0) rotate(-4deg) scale(1); }
    68% { transform: translate(-5px, 0) rotate(-16deg) scale(1); }
    80% { transform: translate(4px, 0) rotate(-4deg) scale(1); }
    88%, 100% { transform: translate(0, 0) rotate(0deg) scale(1); }
}

@keyframes sgt-hint-msg-out {
    0%, 40% { opacity: 1; }
    46%, 90% { opacity: 0; }
    96%, 100% { opacity: 1; }
}

@keyframes sgt-hint-msg-in {
    0%, 40% { opacity: 0; }
    46%, 90% { opacity: 1; }
    96%, 100% { opacity: 0; }
}

/* Touch is the accurate verb on a phone; select is the accurate one with a pointer. */
.games-open-hint-short { display: none; }

@media (max-width: 767.98px) {
    .games-open-hint-long { display: none; }
    .games-open-hint-short { display: inline; }
}

@media (prefers-reduced-motion: reduce) {
    .games-hint-msgs,
    .games-open-hint-icon,
    .games-hint-cycle .games-open-hint-icon,
    .games-hint-cycle .games-hint-select,
    .games-hint-cycle .games-hint-swipe {
        animation: none;
    }

    /* With no cross-fade the second message would sit invisible forever, so keep the first. */
    .games-hint-cycle .games-hint-select {
        opacity: 1;
    }
}

.sgt-mp-card-badge {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 2px 8px 2px 4px;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 700;
    color: #fff;
    background: rgba(255, 255, 255, 0.10);
    border: 1px solid rgba(255, 255, 255, 0.22);
    white-space: nowrap;
}

.sgt-mp-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1060;
    background: rgba(10, 11, 14, 0.72);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
}

.sgt-mp-shell {
    position: fixed;
    inset: 0;
    z-index: 1061;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2vh 2vw;
    pointer-events: none;
}

.sgt-mp-panel {
    pointer-events: auto;
    display: flex;
    flex-direction: column;
    width: min(1180px, 96vw);
    /* vh on mobile measures the viewport with browser chrome hidden, so a vh-sized panel
       overflows the visible area and the filmstrip drops off the bottom. dvh tracks the
       chrome; the vh line stays first as a fallback for older engines. */
    max-height: 96vh;
    height: 96vh;
    max-height: 96dvh;
    height: 96dvh;
    background: #1c1c1e;
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 16px;
    box-shadow: 0 24px 70px rgba(0, 0, 0, 0.65);
    overflow: hidden;
}

.sgt-mp-shell.fullscreen {
    padding: 0;
}

    .sgt-mp-shell.fullscreen .sgt-mp-panel {
        width: 100vw;
        max-height: 100vh;
        height: 100vh;
        border-radius: 0;
        border: none;
    }

.sgt-mp-header {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.65rem 0.85rem;
}

.sgt-mp-title {
    margin: 0;
    color: #fff;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-size: 0.9rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sgt-mp-header-actions {
    display: flex;
    gap: 0.5rem;
    flex-shrink: 0;
}

.sgt-mp-iconbtn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 8px;
    border: none;
    color: #fff;
    background: rgba(255, 255, 255, 0.08);
    transition: background 0.15s ease;
}

    .sgt-mp-iconbtn:hover {
        background: rgba(255, 255, 255, 0.2);
    }

.sgt-mp-stage {
    position: relative;
    flex: 1 1 auto;
    min-height: 0;
    margin: 0 0.85rem;
    background: #000;
    border-radius: 6px;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
}

.sgt-mp-video-wrap {
    position: relative;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}

.sgt-mp-play {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 82px;
    height: 82px;
    border-radius: 50%;
    border: none;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    font-size: 2.6rem;
    line-height: 1;
    background: rgba(0, 0, 0, 0.55);
    box-shadow: 0 6px 26px rgba(0, 0, 0, 0.55);
    transition: background 0.15s ease, transform 0.15s ease;
    cursor: pointer;
}

    .sgt-mp-video-wrap.playing .sgt-mp-play {
        display: none;
    }

    .sgt-mp-play:hover {
        background: rgba(0, 0, 0, 0.75);
        transform: translate(-50%, -50%) scale(1.06);
    }

.sgt-mp-stage-media {
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    object-fit: contain;
    display: block;
}

/* Chrome draws its own buffering spinner between pressing play and the first frame. The poster
   is already on screen and our play button covers the affordance, so the spinner adds nothing
   but a flash of chrome. Webkit-only selector; Firefox does not draw one here. */
.sgt-mp-video-wrap video::-webkit-media-controls-loading-panel {
    display: none !important;
}

/* A video sizes itself from the poster until metadata loads, and the poster is smaller than the
   source, so an intrinsically-sized element would visibly grow the moment playback starts. Give
   the video the whole stage instead and let object-fit letterbox both the poster and the frames
   into the same box, so nothing moves. Stills keep the rule above and are never scaled up. */
.sgt-mp-video-wrap .sgt-mp-stage-media {
    width: 100%;
    height: 100%;
    max-width: none;
    max-height: none;
}

/* An iframe cannot size to its content the way an img or video can, so the YouTube player takes
   the stage and holds 16:9 inside it. */
.sgt-mp-stage-frame {
    width: 100%;
    height: 100%;
    aspect-ratio: 16 / 9;
    border: 0;
    display: block;
}

.sgt-mp-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 50%;
    font-size: 1.5rem;
    color: #fff;
    background: rgba(0, 0, 0, 0.35);
    opacity: 0.65;
    transition: opacity 0.2s ease, background 0.2s ease;
    z-index: 2;
}

    .sgt-mp-nav:hover {
        opacity: 1;
        background: rgba(0, 0, 0, 0.6);
    }

    .sgt-mp-nav.left {
        left: 10px;
    }

    .sgt-mp-nav.right {
        right: 10px;
    }

.sgt-mp-counter-row {
    flex: 0 0 auto;
    display: flex;
    justify-content: center;
    padding: 0.6rem 0 0.5rem;
}

.sgt-mp-counter {
    padding: 3px 14px;
    border-radius: 999px;
    font-size: 0.8rem;
    font-weight: 600;
    color: #fff;
    background: rgba(255, 255, 255, 0.12);
}

.sgt-mp-strip-wrapper {
    position: relative;
    flex: 0 0 auto;
    padding: 0 0.85rem 0.9rem;
}

.sgt-mp-strip {
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    gap: 0.6rem;
    overflow-x: auto;
    scroll-behavior: smooth;
    cursor: grab;
    -ms-overflow-style: none;
    scrollbar-width: none;
}

    .sgt-mp-strip::-webkit-scrollbar {
        display: none;
    }

/* Boxes take their shape from what is in them: screenshots are portrait, clips are 16:9.
   A shared height keeps the row even while each box matches its own content. */
.sgt-mp-thumb {
    position: relative;
    flex: 0 0 auto;
    height: 112px;
    width: auto;
    aspect-ratio: 9 / 16;
    padding: 0;
    border-radius: 8px;
    overflow: hidden;
    background: #000;
    border: 2px solid transparent;
    transition: border-color 0.15s ease, opacity 0.15s ease;
    opacity: 0.75;
}

    .sgt-mp-thumb.is-video {
        aspect-ratio: 16 / 9;
    }

    .sgt-mp-thumb:hover {
        opacity: 1;
        border-color: rgba(255, 255, 255, 0.45);
    }

    .sgt-mp-thumb.active {
        opacity: 1;
        border-color: #fff;
    }

    /* contain, not cover: the strip mixes 16:9 posters with 9:16 screenshots, and cropping to
       fill left the portrait ones showing only a middle band, so they all looked alike. */
    .sgt-mp-thumb img,
    .sgt-mp-thumb video {
        width: 100%;
        height: 100%;
        object-fit: contain;
        display: block;
        pointer-events: none;
    }

.sgt-mp-thumb-play {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.6rem;
    color: #fff;
    text-shadow: 0 2px 8px rgba(0, 0, 0, 0.8);
    background: rgba(0, 0, 0, 0.25);
    pointer-events: none;
}

.sgt-mp-strip-arrow {
    position: absolute;
    top: 0;
    bottom: 0.9rem;
    width: 46px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.6rem;
    color: #fff;
    cursor: pointer;
    z-index: 3;
    opacity: 0;
    transition: opacity 0.25s ease;
}

    .sgt-mp-strip-arrow.left {
        left: 0.85rem;
        background: linear-gradient(to right, rgba(28, 28, 30, 0.98) 0%, rgba(28, 28, 30, 0) 100%);
    }

    .sgt-mp-strip-arrow.right {
        right: 0.85rem;
        background: linear-gradient(to left, rgba(28, 28, 30, 0.98) 0%, rgba(28, 28, 30, 0) 100%);
    }

.sgt-mp-strip-wrapper:hover .sgt-mp-strip-arrow {
    opacity: 0.85;
}

.sgt-mp-strip-arrow:hover {
    opacity: 1;
}

@media (max-width: 768px) {
    .sgt-mp-panel {
        width: 100vw;
        max-height: 100vh;
        height: 100vh;
        max-height: 100dvh;
        height: 100dvh;
        border-radius: 0;
    }

    .sgt-mp-shell {
        padding: 0;
    }

    .sgt-mp-thumb {
        width: 104px;
        height: 66px;
    }

    /* The card face is 9:16, so width drives height: a 220px card is ~390px tall before any
       chrome, which swallows a phone screen. Bounding by dvh keeps the whole card visible
       and still shows the edge of the next one, so the row reads as swipeable. */
    .game-track-card {
        /* Fallback repeated: the variable lives on the track, and the Row grid's cards are not
           inside it. */
        width: var(--sgt-card-w, min(250px, 68vw, 30dvh));
    }

    /* The auto margins below centre the group only while it fits; once the track overflows they
       resolve to zero, so the first and last cards stop at the track's own padding and can never
       reach the middle. Padding the track by half its leftover width lets every card, including
       those two, scroll to true centre — which is also what the centred-card auto-rotate keys on. */
    #games-container {
        --sgt-card-w: min(250px, 68vw, 30dvh);
        padding-left: calc(50% - (var(--sgt-card-w) / 2)) !important;
        padding-right: calc(50% - (var(--sgt-card-w) / 2)) !important;
        padding-top: 15px !important;
        padding-bottom: 15px !important;
        scroll-padding-inline: calc(50% - (var(--sgt-card-w) / 2));
    }

    .game-track-card:first-child {
        margin-left: 0 !important;
    }

    .game-track-card:last-child {
        margin-right: 0 !important;
    }

    /* Cards can be as narrow as ~200px here, so the title steps down to keep the longest
       name on one line. */
    .sgt-card-title {
        font-size: 0.75rem;
    }

    /* Public pages sit inside main.pt-5.mt-5 — 6rem above the content, on top of the space
       already reserved for the fixed navbar. That reads as a large empty band on a phone, so
       the games page pulls itself back up. Scoped here, so Home and Contact keep their spacing. */
    .games-page,
    .contact-page {
        /* !important is required: these elements also carry Bootstrap's mt-1 utility, and every
           Bootstrap spacing utility is itself !important, so a plain rule here never applied. */
        margin-top: -2.5rem !important;
    }

    /* Contact adds py-3 where Games uses py-1, so trim the extra inch for parity. */
    .contact-page {
        padding-top: 0.25rem !important;
    }

    /* ---- Home hero: fit logo through the badges on one screen ----------------
       100vh measures the viewport with browser chrome hidden, so the hero ran taller than the
       visible area and pushed the next section's cyan border up against the badges. dvh tracks
       the chrome. The Bootstrap margins below stack to roughly 11rem, which is generous on a
       phone; each override needs !important because the utilities themselves are !important. */
    .hero-section {
        min-height: 100dvh;
        padding-bottom: 1.5rem;
    }

    .sgt-logo-container {
        margin-bottom: 0.75rem !important;
    }

    .hero-copy {
        margin-top: 0.5rem !important;
    }

        .hero-copy .lead {
            font-size: 1.05rem !important;
            margin-bottom: 1.25rem !important;
        }

    .hero-cta {
        margin-top: 1.25rem !important;
        gap: 0.75rem !important;
    }

        .hero-cta .btn {
            padding-top: 0.7rem !important;
            padding-bottom: 0.7rem !important;
            font-size: 1rem !important;
        }

    .hero-badges {
        margin-top: 1.5rem !important;
        padding-top: 0 !important;
    }

    /* With that space reclaimed the title can be read at a sensible size and keep its
       strapline, rather than being shrunk to buy room for the cards. */
    .games-heading {
        font-size: 1.9rem;
    }

    .games-subheading {
        font-size: 0.95rem;
        margin-bottom: 0.5rem !important;
    }

    /* Touch has no hover, so the strip arrows would never appear; swipe drives it instead. */
    .sgt-mp-strip-arrow {
        display: none;
    }

    /* 34px is below the ~44px touch target guidance, and Close is the only way out of a
       full-screen preview on a phone, so it gets thumb-sized along with the header. */
    .sgt-mp-iconbtn {
        width: 44px;
        height: 44px;
        font-size: 1.15rem;
    }

    .sgt-mp-header {
        padding: 0.75rem 0.85rem;
        gap: 0.5rem;
    }

    /* Keep the stage from eating the strip when the viewport is short and wide. */
    .sgt-mp-stage {
        margin: 0 0.5rem;
    }

    .sgt-mp-strip-wrapper {
        padding: 0 0.5rem 0.6rem;
    }
}

/* ==========================================================================
   HERO REEL BAND  (landing page, replaces the kiosk showcase)
   Appended last on purpose: it shares the .showcase-container element with the older rules
   above, including a light-theme background, and equal specificity means source order decides.
   ========================================================================== */

/* Band height is set by the reel's width, because the reel is aspect-locked rather than
   cropped: the painted EXPLORE GAMES button sits at y 657-743 of 800, so any vertical crop
   past ~7% removes it and the click target below it lands on empty floor. Capping the WIDTH
   shortens the band without touching the frame. One knob: 12/5 means height = width * 0.4167. */
:root {
    --hero-reel-max: 1440px;

    /* The portrait cut's own ratio. The stage must switch to it, or the 4:5 file gets
       cover-cropped inside a 12:5 box and the separate composition buys nothing. */
    --hero-reel-portrait: 4 / 5;
}

.hero-reel-section {
    position: relative;
    display: block;
    padding: 0;
    background-color: #050608;
    border-top: 2px solid var(--sgt-cyan);
    border-bottom: 2px solid var(--sgt-cyan);
    box-shadow: 0 0 40px rgba(0, 210, 255, 0.15);
    transition: box-shadow 0.3s ease;
}

    /* No cursor change here: only the painted button is clickable, so the band must not
       advertise itself as one big target. */
    .hero-reel-section:hover {
        box-shadow: 0 0 60px rgba(0, 210, 255, 0.30);
    }

    /* The link itself is a zero-size labelled anchor, so the ring goes on the band. */
    .hero-reel-section:focus-within {
        outline: 2px solid var(--sgt-cyan);
        outline-offset: -2px;
    }

.hero-reel-stage {
    position: relative;
    width: 100%;
    max-width: var(--hero-reel-max);
    margin-inline: auto;
    aspect-ratio: 12 / 5;
    overflow: hidden;
}

    /* The reel is capped in width, so its edges meet bare band either side. These soften the
       seam only. Kept to 4% and ramped down fast because the wide cut has no horizontal safe
       inset — its beats rotate through the corners, so ink runs close to the frame edge and a
       wider or flatter fade veils the copy. */
    .hero-reel-stage::before,
    .hero-reel-stage::after {
        content: "";
        position: absolute;
        top: 0;
        bottom: 0;
        width: 4%;
        z-index: 1;
        pointer-events: none;
    }

    .hero-reel-stage::before {
        left: 0;
        background: linear-gradient(90deg, #050608 0%, rgba(5, 6, 8, 0.45) 22%, rgba(5, 6, 8, 0) 100%);
    }

    .hero-reel-stage::after {
        right: 0;
        background: linear-gradient(270deg, #050608 0%, rgba(5, 6, 8, 0.45) 22%, rgba(5, 6, 8, 0) 100%);
    }

/* Absolute rather than in flow, so the stage's aspect-ratio alone decides the band height and
   the video fills whatever that comes to. */
.hero-reel-video {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;   /* a no-op while the stage ratio matches the source */
    pointer-events: none;
}

/* No controls attribute is set, but a stray UA/extension default must not surface chrome on a
   decorative background video. */
.hero-reel-video::-webkit-media-controls,
.hero-reel-video::-webkit-media-controls-enclosure {
    display: none !important;
}

/* Covers only the rectangle the video paints, in video coordinates. Valid because the stage is
   aspect-locked to the source; if that ever changes this anchor lands on empty floor. */
.hero-reel-button {
    position: absolute;
    left: 37.79%;
    top: 82.15%;
    width: 24.41%;
    height: 10.70%;
    z-index: 3;
    border-radius: 999px;
}

/* Full-bleed on small screens either way up, so there is no band beside the frame to blend into. */
@media (max-width: 767.98px) {
    .hero-reel-stage::before,
    .hero-reel-stage::after {
        display: none;
    }
}

/* Portrait phones take a separate 4:5 composition, not a crop of the wide cut. The orientation
   clause matters: a small phone held sideways stays on the 12:5 file, which is why the ratio,
   the poster and the button rectangle are all gated here rather than on width alone. */
@media (max-width: 767.98px) and (orientation: portrait) {
    .hero-reel-stage {
        aspect-ratio: var(--hero-reel-portrait);
        background: #050608 url('/media/hero/sgt_hero_reel_p_poster_1080.jpg') center / cover no-repeat;
    }

    /* The portrait cut paints a deliberately wider button (53% of frame against the wide cut's
       24%) for a bigger tap target, so this is not the wide rectangle rescaled. */
    .hero-reel-button {
        left: 23.30%;
        top: 83.87%;
        width: 53.40%;
        height: 7.81%;
    }
}

@media (prefers-reduced-motion: reduce) {
    .hero-reel-video {
        display: none;
    }

    .hero-reel-section {
        transition: none;
    }

    .hero-reel-stage {
        background: #050608 url('/media/hero/sgt_hero_reel_d_poster_1600.jpg') center / cover no-repeat;
    }

    @media (max-width: 767.98px) and (orientation: portrait) {
        .hero-reel-stage {
            background-image: url('/media/hero/sgt_hero_reel_p_poster_1080.jpg');
        }
    }
}

/* The reel is dark by design, so this band stays dark in light mode while the rest of the page
   flips. Overrides the [data-bs-theme="light"] .showcase-container rule earlier in this file. */
[data-bs-theme="light"] .hero-reel-section {
    background-color: #050608 !important;
    border-top: 2px solid rgba(0, 210, 255, 0.5) !important;
    border-bottom: 2px solid rgba(0, 210, 255, 0.5) !important;
    box-shadow: 0 0 30px rgba(0, 0, 0, 0.12) !important;
}

/* ==========================================================================
   GAMES PAGE - GRID AND ROW LAYOUTS
   Both identify a game by its branded title card ("<stem>_title.jpg", lifted from the animated
   title render) rather than by gameplay stills, which is what the showcase uses.
   ========================================================================== */
.games-layout-toggle {
    line-height: 1;
}

    .games-layout-toggle i {
        font-size: 1.05rem;
        vertical-align: -1px;
    }

.games-grid {
    display: grid;
    gap: 0.75rem;
    /* Three across on a phone. At 390px that is ~118px per tile, which is the floor at which
       these logos stay identifiable. */
    grid-template-columns: repeat(3, minmax(0, 1fr));
    max-width: 1320px;
    margin-inline: auto;
    padding-inline: 0.25rem;
}

@media (min-width: 576px) {
    .games-grid { gap: 1.25rem; grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* Four is the ceiling. A fifth column inside the same container width took the tiles back down
   to ~245px, which is what read as cramped. */
@media (min-width: 992px) {
    .games-grid { gap: 1.75rem; max-width: 1400px; }
}

@media (min-width: 1400px) {
    .games-grid { gap: 2rem; }
}

.games-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    background: none;
    border: 0;
    padding: 0;
    color: inherit;
    cursor: pointer;
    min-width: 0;
}

.games-tile-art {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    aspect-ratio: 1 / 1;
    overflow: hidden;
    border-radius: 14px;
    background: #0d1016;
    border: 1px solid rgba(0, 210, 255, 0.22);
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);
    transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}

    /* The cards are 1.91:1, so a square tile crops about 48% of the width. The logos are
       centred, which is what makes that survivable. */
    .games-tile-art img {
        display: block;
        width: 100%;
        height: 100%;
        object-fit: cover;
    }

    .games-tile-art > i {
        font-size: 1.8rem;
        color: rgba(255, 255, 255, 0.25);
    }

.games-tile:hover .games-tile-art,
.games-tile:focus-visible .games-tile-art {
    border-color: rgba(0, 210, 255, 0.85);
    box-shadow: 0 6px 22px rgba(0, 0, 0, 0.5), 0 0 18px rgba(0, 210, 255, 0.25);
    transform: translateY(-3px);
}

.games-tile:focus {
    outline: none;
}

.games-tile-name {
    margin-top: 0.45rem;
    font-size: 0.72rem;
    font-weight: 600;
    color: #dfe6ee;
    /* One line: Gold Mine 3x3 and 5x3 differ only by the suffix, so the tail must not wrap away. */
    width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    text-align: center;
}

/* Inside the artwork rather than under it: the name below is the only thing costing vertical
   space, which is what lets the tiles grow. Sized up from the Showcase badge because at a
   glance across a grid it is doing more work here than it does on a single focused card. */
.games-tile-badge {
    position: absolute;
    right: 6px;
    bottom: 6px;
    z-index: 2;
    gap: 4px;
    font-size: 0.8rem;
    padding: 3px 10px 3px 7px;
    background: rgba(0, 0, 0, 0.6);
    border-color: rgba(255, 255, 255, 0.3);
    backdrop-filter: blur(4px);
}

/* Row cards carry theirs under the title, so it grows there instead. */
.game-card-compact .sgt-mp-card-badge {
    gap: 4px;
    font-size: 0.8rem;
    padding: 3px 10px 3px 7px;
}

@media (min-width: 768px) {
    .games-tile-name { font-size: 0.85rem; }

    .games-tile-badge,
    .game-card-compact .sgt-mp-card-badge {
        font-size: 0.95rem;
        padding: 4px 12px 4px 8px;
    }
}

/* Tiles are ~118px on a phone, so the badge sat far enough up to crowd the logo. Placed after
   the base rule rather than with the other mobile overrides: a media query adds no specificity,
   so whichever comes last in the file wins. */
@media (max-width: 575.98px) {
    .games-tile-badge {
        right: 4px;
        bottom: 2px;
    }
}

/* Row layout: the Showcase card, wrapped. The horizontal track's auto-margins would centre
   the first and last cells inside their grid columns, so they are cancelled here. */
.games-cards-grid {
    display: grid;
    gap: 1rem;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    max-width: 1400px;
    margin-inline: auto;
    padding-inline: 0.25rem;
}

    .games-cards-grid .game-track-card {
        width: 100%;
    }

        .games-cards-grid .game-track-card:first-child {
            margin-left: 0 !important;
        }

        .games-cards-grid .game-track-card:last-child {
            margin-right: 0 !important;
        }

@media (min-width: 576px) {
    .games-cards-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (min-width: 768px) {
    .games-cards-grid { gap: 1.25rem; grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

@media (min-width: 1200px) {
    .games-cards-grid { gap: 1.5rem; grid-template-columns: repeat(5, minmax(0, 1fr)); }
}

@media (min-width: 1500px) {
    .games-cards-grid { grid-template-columns: repeat(6, minmax(0, 1fr)); }
}

/* Touch has no hover, so the card the auto-rotate picked is marked instead. The mark is a ring
   on the wrapper rather than a border on the card: it can then cross-fade on its own opacity
   without fighting Bootstrap's !important border-secondary and shadow-lg, and it sits outside
   the card's overflow:hidden, which would otherwise clip the glow. No transform — shifting the
   card is what made a mid-scroll change read as a shake. */
.games-cards-grid .game-track-card::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 3;
    border-radius: 12px;
    pointer-events: none;
    box-shadow: 0 0 0 2px rgba(0, 210, 255, 0.85), 0 0 22px rgba(0, 210, 255, 0.30);
    opacity: 0;
    transition: opacity 0.25s ease;
}

.games-cards-grid .game-track-card.sgt-card-centered::after {
    opacity: 1;
}

/* Muted for the length of the scroll, so a fast flick does not strobe the ring across cards. */
.games-cards-grid.sgt-scrolling .game-track-card.sgt-card-centered::after {
    opacity: 0;
}

/* Compact cards drop the View Gallery pill, so the info strip is title plus counts. */
.game-card-compact .sgt-card-info {
    padding: 6px 8px 7px;
}

.game-card-compact .sgt-card-title {
    font-size: 0.78rem;
}

.sgt-card-meta-center {
    justify-content: center;
}

/* The public layout gives <main> pt-5 mt-5, six rems above the fold. Home and Contact open on
   full-bleed art that wants the room; this page opens on a heading that does not. */
@media (min-width: 768px) {
    .games-page {
        margin-top: -2.25rem !important;
    }
}



