/* ==================================================================
   THEME.CSS - mejson / Tebex Custom Theme
   GTA V colourway: near-black steel surfaces, the same dark ground
   the game's own menus use, with two accents - GTA Online's neon
   "money" green for every primary action, and the pink/orange/purple
   Los Santos sunset gradient reserved for the hero wordmark, badges
   and glow - never flooded everywhere, the way the cover art uses it
   as one gradient beam, not a wash. Upright display type throughout
   for legibility across a full shop grid. Mobile-first. No
   framework. Dark only, by design - no light mode.

   Contents:
   1. Design tokens        6. Hero
   2. Reset                 7. Features
   3. Layout / type         8. Shop / product cards
   4. Navbar                9. Quick-view modal
   5. Buttons               10. Cart drawer
                             11. Footer
                             12. Responsive
   ================================================================== */

/* ---------------------------------------------------------------
   1. DESIGN TOKENS
   --------------------------------------------------------------- */
:root {
    /* Surfaces - Dark mode default: steel / concrete / gunmetal
       grays, cool and neutral. A fuller step scale than strictly
       necessary on purpose - more distinct grays to build depth/
       hierarchy with, since colour isn't doing that job here. */
    --gray-100: #f1f1ef;
    --gray-200: #d6d6d3;
    --gray-300: #b4b4b1;
    --gray-400: #9a9a97;
    --gray-500: #7a7a77;
    --gray-600: #585856;
    --gray-700: #38383a;
    --gray-800: #262627;
    --gray-850: #1e1e1f;
    --gray-900: #1b1b1c;
    --gray-925: #131314;
    --gray-950: #0b0b0c;

    --color-bg: var(--gray-950);
    --color-bg-alt: var(--gray-925);
    --color-surface: var(--gray-900);
    --color-surface-2: var(--gray-800);
    --color-border: rgba(255, 255, 255, 0.09);
    --color-border-metal: rgba(255, 255, 255, 0.3);

    /* Text */
    --color-text: var(--gray-100);
    --color-text-dim: var(--gray-400);
    /* Was gray-600 (~1.8:1 against these dark surfaces) - legal fine
       print (footer disclaimer, Tebex merchant-of-record line, cart/
       login notes) actually conveys real information, not just
       decoration, so it needs to clear WCAG AA's 4.5:1 for text this
       small (11-13px, well under the "large text" 18px threshold).
       gray-400 is the next step up that actually gets there (~4.6:1);
       everything between 500 and 600 still falls short on this near-
       black background. */
    --color-text-faint: var(--gray-400);

    /* Accents. --color-accent is GTA Online's neon green - every
       primary action, focus ring and selection uses it, so it's
       recognisable at a glance as "the thing you can do." The sunset
       trio only shows up in the gradient token below, kept out of
       the accent role on purpose: one bright hue for interaction,
       the gradient reserved for a handful of decorative moments. */
    --color-accent: #b6ff2e;
    --color-accent-strong: #97e600;      /* darker green, hover/press */
    --color-on-accent: #17140d;          /* text/icons on top of --color-accent fills */
    --scrim-rgb: 10, 9, 8;              /* RGB triplet, no alpha - used as rgba(var(--scrim-rgb), x) so the hero's darkening gradient fades into the same colour as the section below it, dark or light */
    --backdrop-filter: blur(9px) brightness(0.32) saturate(1.25); /* the fixed ambient photo behind the whole page - see .site-backdrop img */
    --color-pink: #ff3d7e;
    --color-orange: #ff8a3d;
    --color-purple: #9b5cff;
    --gradient-sunset: linear-gradient(100deg, var(--color-pink) 0%, var(--color-orange) 52%, var(--color-purple) 100%);
    --color-tag-fill: var(--color-pink);     /* subscription tag fill */
    --color-tag-outline: var(--color-orange); /* pay-what-you-want tag outline */
    --color-discount: #ef4444;               /* struck-through old price + %-off chip - a real red, kept apart from --color-pink so a discounted subscription's card doesn't show two chips that look like the same colour meaning two different things */

    /* Type */
    --font-display: 'Anton', 'Arial Narrow', sans-serif; /* Pricedown substitute, see note in layout.html head */
    --font-body: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, sans-serif;

    /* Shape / motion */
    --radius-sm: 4px;
    --radius-md: 10px;
    --radius-lg: 20px;
    --ease-out: cubic-bezier(0.19, 1, 0.22, 1);

    /* Layout */
    --container-width: 1280px;
    --container-pad: 20px;
    --nav-height: 72px;
}

/* ---------------------------------------------------------------
   2. RESET
   --------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: auto; } /* Lenis owns scroll, not native CSS */

/* Any element given its own `display` (basically every .btn, every
   flex/grid container) otherwise wins over the browser's built-in
   `[hidden] { display: none }` rule - author styles beat UA styles at
   equal specificity, so a `hidden`/`.hidden = true` toggle on, say, a
   quick-view action button or a gallery arrow silently stopped doing
   anything visible the moment that element also got a display rule.
   One `!important` here is the standard fix (this is exactly the kind
   of low-level override it's for) rather than chasing down every
   individual selector - confirmed missing on more than one element
   when checked directly (a hidden .btn still computed to
   display:inline-flex). */
[hidden] { display: none !important; }

/* Themed scrollbar - the page itself and any internally-scrolling
   panel (quick-view description, cart drawer list). Transparent until
   the container is hovered, so it stays out of the way rather than
   sitting there as a constant colour bar. Firefox via the scrollbar-*
   properties, everything Chromium/WebKit via ::-webkit-scrollbar. */
html, .quick-view__description, .cart-drawer__list {
    scrollbar-width: thin;
    scrollbar-color: transparent transparent;
}
html:hover, .quick-view__description:hover, .cart-drawer__list:hover {
    scrollbar-color: var(--color-accent) var(--color-surface-2);
}
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: transparent; background-clip: padding-box; border-radius: 999px; border: 2px solid transparent; }
html:hover::-webkit-scrollbar-track,
.quick-view__description:hover::-webkit-scrollbar-track,
.cart-drawer__list:hover::-webkit-scrollbar-track { background: var(--color-surface-2); }
html:hover::-webkit-scrollbar-thumb,
.quick-view__description:hover::-webkit-scrollbar-thumb,
.cart-drawer__list:hover::-webkit-scrollbar-thumb { background: var(--color-accent); background-clip: padding-box; border: 2px solid var(--color-surface-2); }
::-webkit-scrollbar-thumb:hover { background: var(--color-accent-strong); }

body {
    background: var(--color-bg);
    color: var(--color-text);
    font-family: var(--font-body);
    font-size: 16px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
    /* Sticky footer: on a short page (package.html with a brief
       description is the common case) the footer used to end right
       after the content instead of at the bottom of the viewport -
       "floating" partway down a mostly-empty page. Every overlay
       (navbar, backdrop, modals, cart drawer) is position:fixed, so
       <main> and <footer> are the only two normal-flow children this
       actually affects. */
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}
body.no-scroll { overflow: hidden; }
body > main { flex: 1 0 auto; }

/* Ambient page backdrop - the same render uploaded for the hero,
   reused here fixed, blurred and heavily darkened behind the whole
   page instead of a flat colour. Shows through the open gaps
   between sections; opaque panels (cards, footer, the solid navbar)
   still read as solid on top of it. See .site-backdrop in
   layout.html for the <img> this styles. */
.site-backdrop {
    position: fixed;
    inset: -30px;
    z-index: -1;
    overflow: hidden;
    pointer-events: none;
}
.site-backdrop__img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    filter: var(--backdrop-filter);
    transform: scale(1.05);
}
/* Landing shows --1; --2 crossfades in on scroll (see
   initBackdropCrossfade() in index.html) and simply never becomes
   visible on pages that don't run that script. */
.site-backdrop__img--2 { opacity: 0; }
.site-backdrop::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(var(--scrim-rgb),0.55) 0%, rgba(var(--scrim-rgb),0.8) 100%);
}

img, video { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
svg { display: block; width: 1em; height: 1em; } /* the global [hidden] rule up top (see RESET) covers this now */
::selection { background: var(--color-accent); color: var(--color-on-accent); }

/* Consistent, on-brand visible focus indicator for every interactive
   element. A couple of components individually suppress the default
   outline for their own hover/focus color swap (.input,
   .navbar__currency-select) without offering a real replacement -
   this site-wide rule is what keyboard users actually see landing on
   any control, everywhere on the site. */
:is(a, button, input, select, textarea, [tabindex]):focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}

/* Off-screen until focused - lets keyboard/screen-reader users jump
   straight past the navbar to <main> instead of tabbing through the
   currency picker, login and cart controls on every single page. */
.skip-link {
    position: absolute;
    top: -100px;
    left: 16px;
    z-index: 200;
    padding: 12px 20px;
    background: var(--color-accent);
    color: var(--color-on-accent);
    font-family: var(--font-display);
    font-style: normal;
    font-size: 14px;
    letter-spacing: 0.04em;
    border-radius: var(--radius-sm);
    transition: top 0.2s var(--ease-out);
}
.skip-link:focus-visible {
    top: 16px;
    outline-offset: 4px;
}

/* ---------------------------------------------------------------
   3. LAYOUT / TYPOGRAPHY
   Display type (headings, eyebrows, buttons, tags, prices) is set
   in Anton - the closest legitimately licensed stand-in for
   Pricedown - upright throughout, same as body copy, so a full shop
   grid stays easy to scan at a glance.
   --------------------------------------------------------------- */
.container {
    width: 100%;
    max-width: var(--container-width);
    margin-inline: auto;
    padding-inline: var(--container-pad);
}

h1, h2, h3, h4 {
    font-family: var(--font-display);
    font-style: normal;
    font-weight: 400;
    letter-spacing: 0.005em;
    line-height: 1.05;
    text-transform: uppercase;
}

/* One solid colour, not the gradient - a whole word in a
   pink-orange-purple blend read as noisy against the surrounding
   type. The gradient stays reserved for the hero glow and badges. */
.text-accent {
    color: var(--color-accent);
}

.section-eyebrow, .hero__eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-family: var(--font-display);
    font-style: normal;
    font-size: 13px;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--color-accent);
    margin-bottom: 14px;
}
.section-eyebrow::before, .hero__eyebrow::before {
    content: '';
    width: 18px;
    height: 1px;
    background: var(--color-accent);
}

.section-title { font-size: clamp(28px, 4.2vw, 42px); margin-bottom: 40px; }

/* ---------------------------------------------------------------
   4. NAVBAR
   --------------------------------------------------------------- */
.navbar {
    position: fixed;
    top: 0; right: 0; left: 0;
    height: var(--nav-height);
    z-index: 200;
    background: transparent;
    border-bottom: 1px solid transparent;
    transition: background-color 0.4s var(--ease-out), border-color 0.4s var(--ease-out);
}
.navbar--solid {
    background: rgba(var(--scrim-rgb), 0.88);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    border-bottom-color: var(--color-border);
}

.navbar__inner {
    position: relative;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
}

.navbar__brand { display: flex; align-items: center; height: 30px; }
.navbar__logo { height: 100%; width: auto; max-width: 100%; object-fit: contain; }
.navbar__logo-text {
    font-family: var(--font-display);
    font-style: normal;
    font-size: 22px;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

/* Desktop only - see the comment on this element in layout.html for
   why (mobile carries the same links in the footer instead).
   Absolutely centred on .navbar__inner (position:relative, see above)
   instead of just sitting wherever flex leaves it between brand and
   actions - those two are rarely the same width as each other, so
   space-between alone left the links looking off-centre rather than
   centred on the bar as a whole. */
.navbar__nav { display: none; }
@media (min-width: 768px) {
    .navbar__nav {
        display: flex;
        align-items: center;
        gap: 22px;
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        pointer-events: auto;
    }
    .navbar__nav-link {
        font-family: var(--font-display);
        font-style: normal;
        font-size: 13px;
        letter-spacing: 0.03em;
        text-transform: uppercase;
        color: var(--color-text-dim);
        white-space: nowrap;
        transition: color 0.25s var(--ease-out);
    }
    .navbar__nav-link:hover { color: var(--color-text); }
}

.navbar__actions { display: flex; align-items: center; gap: 12px; }

/* FiveM/cfx.re login - links to /login, which Tebex renders as
   username.html any time (not just mid-checkout). Small outlined
   pill so it doesn't compete with the cart icon next to it. */
.navbar__login {
    padding: 8px 16px;
    font-family: var(--font-display);
    font-style: normal;
    font-size: 12px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--color-text);
    border: 1px solid var(--color-border-metal);
    border-radius: var(--radius-sm);
    transition: border-color 0.25s var(--ease-out), color 0.25s var(--ease-out);
}
.navbar__login:hover { border-color: var(--color-accent); color: var(--color-accent); }

.navbar__currency { position: relative; }
.navbar__currency-select {
    -webkit-appearance: none;
    appearance: none;
    padding: 8px 28px 8px 14px;
    font-family: var(--font-display);
    font-style: normal;
    font-size: 12px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--color-text);
    background-color: transparent;
    border: 1px solid var(--color-border-metal);
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: border-color 0.25s var(--ease-out), color 0.25s var(--ease-out);
    /* Plain CSS chevron - no icon font/asset needed for one glyph. */
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239a9a97' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 8px center;
    background-size: 14px;
}
.navbar__currency-select:hover, .navbar__currency-select:focus-visible { border-color: var(--color-accent); color: var(--color-text); }
.navbar__currency-select option { background: var(--color-surface); color: var(--color-text); }
.navbar__currency-note {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    z-index: 60;
    width: 200px;
    padding: 10px 12px;
    background: var(--color-surface);
    border: 1px solid var(--color-border-metal);
    border-radius: var(--radius-sm);
    box-shadow: 0 12px 28px -12px rgba(0, 0, 0, 0.6);
    font-size: 11px;
    line-height: 1.5;
    color: var(--color-text-dim);
    text-transform: none;
    letter-spacing: normal;
    /* Only ever in the DOM (not [hidden]) once a non-store currency is
       actually selected - see applyCurrency() - and even then only
       revealed on hover/focus, so there's nothing to disclose (and
       nothing sitting there permanently) while showing store prices. */
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 0.2s var(--ease-out), visibility 0.2s;
}
.navbar__currency:hover .navbar__currency-note:not([hidden]),
.navbar__currency:focus-within .navbar__currency-note:not([hidden]) {
    opacity: 1;
    visibility: visible;
}
.navbar__login--active {
    border-color: var(--color-accent);
    color: var(--color-accent);
    max-width: 160px;
}
/* Both spans share the same grid cell (grid-area: 1/1) so the pill
   sizes to whichever is wider without a resize jump on hover, and
   crossfade/slide between them instead of one replacing the other
   outright - same idea as Tebex's own default header.twig
   (.user-name > .text-inner > .text/.text-hover), restyled for this
   theme instead of the click-to-open dropdown this used to be. */
.navbar__login-inner {
    display: inline-grid;
    overflow: hidden;
}
.navbar__login-text,
.navbar__login-text-hover {
    grid-area: 1 / 1;
    max-width: 160px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    text-align: center;
    transition: opacity 0.25s var(--ease-out), transform 0.25s var(--ease-out);
}
.navbar__login-text-hover {
    color: var(--color-pink);
    opacity: 0;
    transform: translateY(6px);
}
.navbar__login--active:hover { border-color: var(--color-pink); }
.navbar__login--active:hover .navbar__login-text { opacity: 0; transform: translateY(-6px); }
.navbar__login--active:hover .navbar__login-text-hover { opacity: 1; transform: translateY(0); }

/* ---------------------------------------------------------------
   5. BUTTONS
   --------------------------------------------------------------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 13px 28px;
    border-radius: var(--radius-sm);
    font-family: var(--font-display);
    font-style: normal;
    font-size: 14px;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    white-space: nowrap;
    border: 1px solid transparent;
    transition: transform 0.3s var(--ease-out), border-color 0.3s var(--ease-out), background-color 0.3s var(--ease-out), color 0.3s var(--ease-out);
}
/* Baseline tactile press feedback for every button - variants with
   their own :active override it. */
.btn:active { transform: scale(0.96); }
/* A genuinely disabled button (checkoutBtn with an empty basket, say) -
   distinct from .btn--disabled above, which is a plain <span> standing
   in for a button that was never interactive to begin with. */
.btn:disabled { opacity: 0.4; cursor: not-allowed; pointer-events: none; }
.btn:disabled:active { transform: none; }

.btn--primary {
    background: var(--color-accent);
    color: var(--color-on-accent);
}
.btn--primary:active { transform: scale(0.96) translateY(0); }
.btn--primary:hover { background: var(--color-accent-strong); transform: translateY(-1px); }

.btn--ghost {
    background: transparent;
    color: var(--color-text);
    border-color: var(--color-border-metal);
}
.btn--ghost:hover { border-color: var(--color-accent); color: var(--color-accent); }

.btn--icon {
    padding: 9px;
    border: 1px solid var(--color-border-metal);
    border-radius: var(--radius-sm);
    background: rgba(255, 255, 255, 0.02);
    position: relative;
}
.btn--icon:hover { border-color: var(--color-accent); }
.btn--icon svg { width: 18px; height: 18px; min-width: 18px; flex-shrink: 0; }
.btn--icon__badge {
    position: absolute;
    top: -6px; right: -6px;
    min-width: 17px;
    height: 17px;
    padding: 0 4px;
    border-radius: 999px;
    background: var(--color-accent);
    color: var(--color-on-accent);
    font-family: var(--font-display);
    font-style: normal;
    font-size: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.btn--buy {
    padding: 10px 18px;
    font-size: 12px;
    background: var(--color-surface-2);
    border: 1px solid var(--color-border-metal);
    color: var(--color-text);
}
.btn--buy:hover { background: var(--color-accent); color: var(--color-on-accent); border-color: var(--color-accent); }
.btn--buy.is-added { background: var(--color-tag-outline); color: #131314; border-color: var(--color-tag-outline); }

.btn--subscribe { border-color: var(--color-border-metal); }
/* --color-tag-fill is the sunset pink - dark text keeps it readable. */
.btn--subscribe:hover { background: var(--color-tag-fill); color: #131314; border-color: var(--color-tag-fill); }
.btn--subscribe.is-added { background: var(--color-tag-outline); color: #131314; border-color: var(--color-tag-outline); }

/* "Remove from Basket" - replaces Add to Basket/Subscribe once a
   package is already in the basket. Muted/outline rather than a solid
   fill, so it doesn't read as a second "buy" action. */
.btn--remove {
    flex: 1;
    padding: 10px 18px;
    font-size: 12px;
    background: transparent;
    color: var(--color-text-dim);
    border: 1px solid var(--color-border-metal);
    cursor: pointer;
}
.btn--remove:hover { color: var(--color-pink); border-color: var(--color-pink); }

.btn--disabled {
    padding: 10px 18px;
    font-size: 12px;
    color: var(--color-text-faint);
    border: 1px solid var(--color-border);
    cursor: not-allowed;
}

.btn--quickview {
    padding: 9px 16px;
    font-size: 12px;
    background: rgba(var(--scrim-rgb), 0.6);
    border: 1px solid rgba(255, 255, 255, 0.14);
    color: var(--color-text);
    backdrop-filter: blur(6px);
}
.btn--quickview:hover { border-color: var(--color-accent); color: var(--color-accent); }

.btn--close {
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--color-border-metal);
    border-radius: var(--radius-sm);
}
.btn--close:hover { border-color: var(--color-accent); }
.btn--close svg { width: 16px; height: 16px; min-width: 16px; flex-shrink: 0; }

/* ---------------------------------------------------------------
   6. HERO
   --------------------------------------------------------------- */
.hero {
    position: relative;
    min-height: 100svh;
    display: flex;
    align-items: center;
    overflow: hidden;
    padding-top: var(--nav-height);
}

/* Sunset glow behind the headline - the key-art gradient at low
   opacity, the one place it washes a large area rather than tracing
   a line or a badge. */
.hero::before {
    content: '';
    position: absolute;
    z-index: 0;
    top: -20%;
    left: 50%;
    transform: translateX(-50%);
    width: min(1100px, 140vw);
    aspect-ratio: 1;
    background: radial-gradient(circle, rgba(255, 61, 126, 0.22) 0%, rgba(255, 138, 61, 0.14) 38%, transparent 70%);
    pointer-events: none;
}

.hero__backdrop {
    position: absolute;
    inset: -8% 0;
    z-index: 0;
}
.hero__backdrop img, .hero__backdrop video {
    width: 100%; height: 100%; object-fit: cover;
    filter: grayscale(0.15) contrast(1.12) saturate(1.3) brightness(0.94);
}
.hero__backdrop::after {
    content: '';
    position: absolute;
    inset: 0;
    background:
        linear-gradient(180deg, rgba(var(--scrim-rgb),0.35) 0%, rgba(var(--scrim-rgb),0.6) 55%, rgba(var(--scrim-rgb),0.97) 100%),
        linear-gradient(90deg, rgba(var(--scrim-rgb),0.92) 0%, rgba(var(--scrim-rgb),0.2) 45%);
}

.hero__grid {
    position: relative;
    z-index: 1;
    display: grid;
    grid-template-columns: 1fr;
    gap: 40px;
    align-items: center;
}

.hero__copy { max-width: 560px; }
.hero__title { font-size: clamp(38px, 7.5vw, 72px); margin-bottom: 18px; }
.hero__subtitle {
    color: var(--color-text-dim);
    font-size: clamp(15px, 1.6vw, 17px);
    max-width: 460px;
    margin-bottom: 32px;
}
.hero__actions { display: flex; flex-wrap: wrap; gap: 14px; }

/* Floating preview card layered above the backdrop */
.hero__preview {
    display: block;
    width: 100%;
    text-align: left;
    position: relative;
    border-radius: var(--radius-lg);
    overflow: hidden;
    border: 1px solid var(--color-border-metal);
    box-shadow: 0 40px 80px -30px rgba(0, 0, 0, 0.75);
    min-height: 220px; /* floor only, so the card isn't a 0-height sliver before the image src is set - the image's own ratio decides the real height once it loads */
    background: var(--color-surface);
    transition: transform 0.3s var(--ease-out);
}
.hero__preview:hover { transform: translateY(-3px); }
.hero__preview img { display: block; width: 100%; height: auto; } /* the tile's shape now follows the image, not the other way round - no object-fit needed since nothing is being forced into a fixed box */
.hero__preview::before {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, transparent 60%, rgba(var(--scrim-rgb),0.88));
    pointer-events: none;
}
.hero__preview-tag {
    position: absolute;
    left: 18px; bottom: 18px;
    z-index: 1;
    font-family: var(--font-display);
    font-style: normal;
    font-size: 13px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--color-text);
}

.hero__scroll-cue {
    position: absolute;
    left: 50%;
    bottom: 28px;
    transform: translateX(-50%);
    width: 1px;
    height: 40px;
    background: var(--color-border-metal);
    z-index: 1;
}
.hero__scroll-cue::after {
    content: '';
    position: absolute;
    top: 0; left: -1.5px;
    width: 4px; height: 4px;
    border-radius: 50%;
    background: var(--color-accent);
    animation: scrollCue 2s ease-in-out infinite;
}
@keyframes scrollCue {
    0% { top: 0; opacity: 1; }
    85% { opacity: 0; }
    100% { top: 100%; opacity: 0; }
}

/* ---------------------------------------------------------------
   7. FEATURES
   --------------------------------------------------------------- */
.features { padding: 90px 0; }

.support-tile {
    display: flex;
    /* Mobile-first: stacked. The icon + "Join Discord →" cta are both
       fixed-width and don't shrink - in a single row on a narrow
       viewport that squeezed the title/text column down to ~50px,
       wrapping every word onto its own line and reading as broken/
       overlapping. Row layout (icon | text | cta) only turns back on
       at 768px, once there's actually room for all three. */
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
    padding: 32px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-top: 3px solid var(--color-accent);
    border-radius: var(--radius-md);
    transition: background-color 0.3s var(--ease-out), transform 0.3s var(--ease-out);
}
.support-tile:hover { background: var(--color-surface-2); transform: translateY(-4px); }
.support-tile__icon {
    display: flex; align-items: center; justify-content: center;
    width: 56px; height: 56px; flex-shrink: 0;
    border-radius: var(--radius-md);
    background: rgba(var(--scrim-rgb), 0.4);
    color: var(--color-accent);
}
.support-tile__copy { flex: 1; min-width: 0; }
.support-tile__title { font-size: 19px; margin-bottom: 6px; }
.support-tile__text { color: var(--color-text-dim); font-size: 14px; }
.support-tile__cta {
    font-family: var(--font-display);
    font-style: normal;
    font-size: 13px;
    letter-spacing: 0.04em;
    color: var(--color-accent);
    white-space: nowrap;
    flex-shrink: 0;
}
@media (min-width: 768px) {
    .support-tile { flex-direction: row; align-items: center; gap: 24px; }
}

/* ---------------------------------------------------------------
   8. SHOP / PRODUCT CARDS
   --------------------------------------------------------------- */
.shop { padding: 90px 0 120px; }
.shop__header { margin-bottom: 40px; }

/* Purchase-type filter - Buy Once / Subscription - segmented control
   above the shop grid on index.html, driven client-side (see
   loadShop()/renderShopGrid() in that file's script block). */
.type-toggle {
    display: inline-flex;
    margin-bottom: 32px;
    border: 1px solid var(--color-border-metal);
    border-radius: var(--radius-sm);
    overflow: hidden;
}
.type-toggle__btn {
    padding: 10px 20px;
    font-family: var(--font-display);
    font-style: normal;
    font-size: 13px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--color-text-dim);
    transition: background-color 0.25s var(--ease-out), color 0.25s var(--ease-out);
}
.type-toggle__btn + .type-toggle__btn { border-left: 1px solid var(--color-border-metal); }
.type-toggle__btn:hover { color: var(--color-text); }
.type-toggle__btn.is-active { background: var(--color-accent); color: var(--color-on-accent); }

.shop__empty { color: var(--color-text-dim); text-align: center; padding: 40px 0; }

.product-grid { display: grid; grid-template-columns: 1fr; gap: 22px; }

.product-card {
    position: relative;
    display: flex;
    flex-direction: column;
    height: 100%; /* grid rows already stretch it this tall; this + the flex body below is what actually keeps the footer pinned to the bottom regardless of title length */
    cursor: pointer;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    overflow: hidden;
    transition: border-color 0.35s var(--ease-out), transform 0.35s var(--ease-out);
}
.product-card:hover { border-color: var(--color-border-metal); transform: translateY(-3px); }

/* 16/9, not the old 16/10 - every real product photo in the catalogue
   (checked directly: all 18 are 570x321, exactly 16:9) was getting its
   left and right edges cropped off by object-fit: cover fighting a
   container ratio that didn't match, cutting into the baked-in title/
   watermark text near those edges on literally every card. */
.product-card__media { position: relative; display: block; aspect-ratio: 16 / 9; overflow: hidden; background: var(--color-surface-2); }
.product-card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.7s var(--ease-out); }
.product-card:hover .product-card__media img { transform: scale(1.06); }

.product-card__media-placeholder {
    width: 100%; height: 100%;
    display: flex; align-items: center; justify-content: center;
    color: var(--color-text-faint);
    font-family: var(--font-display);
    font-style: normal;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-size: 14px;
}

.product-card__tag {
    padding: 4px 10px;
    border-radius: 999px;
    font-family: var(--font-display);
    font-style: normal;
    font-size: 11px;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    white-space: nowrap;
}
/* The chip(s) themselves used to carry this positioning directly, back
   when there was only ever one - now .product-card__tags (the shared
   wrapper, see QUICK-VIEW MODAL) carries it instead, stacked in a
   column here since a product card has no horizontal room to spare
   for two chips side by side the way Quick View does. */
.product-card__media > .product-card__tags {
    position: absolute;
    top: 12px; left: 12px;
    z-index: 2;
    flex-direction: column;
    align-items: flex-start;
}
/* Fill-vs-outline carries the distinction: subscription reads as a
   filled pink "active" chip, pay-what-you-want as an outlined
   orange "info" chip. */
.product-card__tag--subscription { background: var(--color-tag-fill); color: #131314; border: 1px solid #000; }
.product-card__tag--pwyw { background: transparent; color: var(--color-text); border: 1px solid var(--color-tag-outline); }
/* Discount %-off chip - its own filled-red look, kept separate from
   the subscription chip above (same shape, but that one uses the
   site's pink brand accent for an unrelated meaning - "this renews
   monthly" - reusing it here as well would make a discounted
   subscription's card show two chips that read as the same thing). */
.product-card__tag--discount { background: var(--color-discount); color: #fff; border: 1px solid rgba(0, 0, 0, 0.25); }

.product-card__quickview {
    position: absolute;
    right: 12px; bottom: 12px;
    z-index: 2;
    opacity: 0;
    transform: translateY(6px);
    transition: opacity 0.3s var(--ease-out), transform 0.3s var(--ease-out);
}
.product-card:hover .product-card__quickview,
.product-card:focus-within .product-card__quickview { opacity: 1; transform: translateY(0); }

.product-card__body { padding: 18px; display: flex; flex-direction: column; flex: 1; }
.product-card__title {
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 15px;
    margin-bottom: 14px;
}
.product-card__title button { text-align: left; }
.product-card__title button:hover { color: var(--color-accent); }

.product-card__footer { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: auto; }
.product-card__actions { display: flex; align-items: stretch; gap: 8px; } /* stretch, not center - .btn--icon and .btn--buy/.btn--subscribe have different padding, so centering left them visibly mismatched in height */
.product-card__gift svg { width: 18px; height: 18px; min-width: 18px; flex-shrink: 0; }

.product-card__price-group { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.product-card__price { font-family: var(--font-display); font-style: normal; font-size: 17px; }
.product-card__price--muted { font-family: var(--font-body); font-style: normal; font-size: 12px; font-weight: 500; color: var(--color-text-dim); }
.product-card__price-old { font-family: var(--font-body); font-style: normal; font-size: 12px; color: var(--color-discount); text-decoration: line-through; }

/* ---------------------------------------------------------------
   9. QUICK-VIEW MODAL
   --------------------------------------------------------------- */
.modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 900;
    background: rgba(var(--scrim-rgb), 0.74);
    backdrop-filter: blur(4px);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.35s var(--ease-out), visibility 0.35s;
}
.modal-backdrop.is-open { opacity: 1; visibility: visible; }

.quick-view {
    position: fixed;
    top: 50%; left: 50%;
    transform: translate(-50%, -48%) scale(0.96);
    width: min(640px, 92vw);
    max-height: 88vh;
    z-index: 901;
    background: var(--color-bg-alt);
    border: 1px solid var(--color-border-metal);
    border-radius: var(--radius-lg);
    box-shadow: 0 60px 120px -40px rgba(0, 0, 0, 0.88);
    overflow: hidden;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.4s var(--ease-out), transform 0.4s var(--ease-out), visibility 0.4s;
    display: flex;
    flex-direction: column;
}
.quick-view.is-open { opacity: 1; visibility: visible; transform: translate(-50%, -50%) scale(1); }

.quick-view__close {
    position: absolute;
    top: 14px; right: 14px;
    z-index: 3;
    background: rgba(var(--scrim-rgb), 0.6);
    backdrop-filter: blur(6px);
}

/* Images on top, details below - every breakpoint. */
.quick-view__body { display: flex; flex-direction: column; overflow-y: auto; }

.quick-view__gallery { position: relative; background: var(--color-surface-2); flex: none; }
.quick-view__gallery-main { width: 100%; max-height: 52vh; object-fit: contain; background: var(--color-bg); margin: 0 auto; display: block; cursor: zoom-in; transition: opacity 0.15s var(--ease-out); }
.quick-view__gallery-main.is-loading { opacity: 0; }

.quick-view__gallery-loading {
    position: absolute; inset: 0; display: none; align-items: center; justify-content: center; gap: 8px; pointer-events: none;
}
.quick-view__gallery-loading.is-visible { display: flex; }
.quick-view__gallery-loading span {
    width: 9px; height: 9px; border-radius: 50%; background: var(--color-accent);
    animation: quick-view-dot 1s ease-in-out infinite both;
}
.quick-view__gallery-loading span:nth-child(2) { animation-delay: 0.15s; }
.quick-view__gallery-loading span:nth-child(3) { animation-delay: 0.3s; }
@keyframes quick-view-dot {
    0%, 80%, 100% { opacity: 0.25; transform: scale(0.75); }
    40% { opacity: 1; transform: scale(1); }
}

/* Arrows + counter - see the comment on the markup in layout.html for
   why this replaced a row of dots. */
.quick-view__gallery-arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 40px; height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: rgba(var(--scrim-rgb), 0.6);
    border: 1px solid var(--color-border-metal);
    color: var(--color-text);
    backdrop-filter: blur(6px);
    transition: border-color 0.25s var(--ease-out), color 0.25s var(--ease-out), background-color 0.25s var(--ease-out);
}
.quick-view__gallery-arrow svg { width: 20px; height: 20px; min-width: 20px; flex-shrink: 0; }
.quick-view__gallery-arrow:hover { border-color: var(--color-accent); color: var(--color-accent); background: rgba(var(--scrim-rgb), 0.85); }
.quick-view__gallery-arrow--prev { left: 14px; }
.quick-view__gallery-arrow--next { right: 14px; }

.quick-view__gallery-counter {
    position: absolute;
    right: 14px; bottom: 14px;
    padding: 5px 12px;
    border-radius: 999px;
    background: rgba(var(--scrim-rgb), 0.6);
    border: 1px solid var(--color-border-metal);
    backdrop-filter: blur(6px);
    font-family: var(--font-display);
    font-style: normal;
    font-size: 13px;
    color: var(--color-text);
}

/* Sits at bottom-left, clear of both the prev arrow above it and the
   modal's own close button (top-right). */
.quick-view__gallery-fullscreen { position: absolute; top: auto; left: 14px; bottom: 14px; transform: none; }

/* Fullscreen mode - same modal element, just resized to ~90% of the
   viewport with the info panel hidden so the image gets the space;
   arrows/keyboard nav keep working unchanged. Toggled by JS adding
   .is-fullscreen to #quickView (see initGalleryFullscreen()). */
.quick-view.is-fullscreen {
    width: 90vw;
    max-height: 90vh;
}
.quick-view.is-fullscreen .quick-view__gallery-main { max-height: 90vh; }
.quick-view.is-fullscreen .quick-view__info { display: none; }
.quick-view.is-fullscreen .quick-view__body { overflow: hidden; } /* .quick-view__body's overflow-y:auto is there for the normal info+gallery layout on short screens - with .quick-view__info hidden here, there's nothing left that needs scrolling, and without this override a few stray pixels of overflow show a pointless scrollbar */

.quick-view__info { padding: 28px; }
.quick-view__category { font-family: var(--font-display); font-style: normal; font-size: 12px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--color-accent); margin-bottom: 10px; }
.quick-view__title { font-size: clamp(23px, 3vw, 30px); margin-bottom: 14px; }
.quick-view__description { color: var(--color-text-dim); font-size: 14px; line-height: 1.7; margin-bottom: 24px; max-height: 220px; overflow-y: auto; overscroll-behavior: contain; }
.quick-view__description img { display: none; } /* images already surfaced in the gallery above */
/* Descriptions are freeform WYSIWYG HTML pasted in by the store owner, so
   left unstyled these leak the browser's default look: a beveled grey <hr>
   line that reads as a random stripe on a dark theme, oversized black
   headings, default-blue links. Everything below just re-themes those raw
   tags to match the rest of the page instead of touching the HTML itself. */
.quick-view__description h1,
.quick-view__description h2,
.quick-view__description h3,
.quick-view__description h4 {
    color: var(--color-text); font-family: var(--font-display); font-weight: 400;
    font-size: 13px; letter-spacing: 0.04em; text-transform: uppercase;
    margin: 18px 0 8px;
}
.quick-view__description h1:first-child,
.quick-view__description h2:first-child,
.quick-view__description h3:first-child,
.quick-view__description h4:first-child { margin-top: 0; }
.quick-view__description p { margin: 0 0 10px; }
.quick-view__description ul,
.quick-view__description ol { margin: 0 0 10px; padding-left: 20px; }
.quick-view__description li { margin-bottom: 4px; }
.quick-view__description a { color: var(--color-accent); text-decoration: underline; text-underline-offset: 2px; }
.quick-view__description strong { color: var(--color-text); }
.quick-view__description hr { border: none; height: 1px; background: var(--color-border); margin: 16px 0; }

.quick-view__footer { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; padding-top: 18px; border-top: 1px solid var(--color-border); }
.quick-view__actions { display: flex; align-items: stretch; gap: 10px; }
.quick-view__price-group { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.quick-view__price { font-family: var(--font-display); font-style: normal; font-size: 24px; }
.quick-view__price-old { font-size: 15px; color: var(--color-discount); text-decoration: line-through; }
/* Shared badge-row wrapper - product cards, package detail and Quick
   View all stack a discount chip above/alongside a subscription/PWYW
   one here instead of just one replacing the other. */
.product-card__tags { display: flex; align-items: flex-start; gap: 6px; flex-wrap: wrap; }
.quick-view__info .product-card__tags { position: static; margin-bottom: 12px; }

/* ---------------------------------------------------------------
   10. CART DRAWER
   --------------------------------------------------------------- */
.cart-drawer {
    position: fixed;
    top: 0; right: 0;
    bottom: 0;
    width: min(420px, 100vw);
    z-index: 901;
    background: var(--color-bg-alt);
    border-left: 1px solid var(--color-border-metal);
    display: flex;
    flex-direction: column;
    transform: translateX(100%);
    transition: transform 0.4s var(--ease-out);
}
.cart-drawer.is-open { transform: translateX(0); }

.cart-drawer__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 22px;
    border-bottom: 1px solid var(--color-border);
}
.cart-drawer__title { font-size: 18px; }

.cart-drawer__list { flex: 1; overflow-y: auto; overscroll-behavior: contain; padding: 8px 22px; }
.cart-drawer__empty { color: var(--color-text-dim); font-size: 14px; padding: 40px 0; text-align: center; }

.cart-drawer__item {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 16px 0;
    border-bottom: 1px solid var(--color-border);
}
.cart-drawer__item-media { width: 64px; height: 48px; border-radius: var(--radius-sm); overflow: hidden; flex-shrink: 0; background: var(--color-surface-2); }
.cart-drawer__item-media.is-broken img { display: none; } /* a dead/wrong image URL falls back to a plain surface tile instead of the browser's broken-image icon */
.cart-drawer__item-media img { width: 100%; height: 100%; object-fit: cover; }
.cart-drawer__item-info { flex: 1; min-width: 0; }
.cart-drawer__item-name { font-size: 13px; font-weight: 600; margin-bottom: 4px; }
.cart-drawer__item-meta { font-family: var(--font-display); font-style: normal; font-size: 13px; color: var(--color-text-dim); display: inline-block; }
.cart-drawer__item-gift { margin-top: 4px; font-size: 12px; color: var(--color-accent); }
.cart-drawer__item-remove {
    display: flex; align-items: center; justify-content: center;
    width: 32px; height: 32px; flex-shrink: 0;
    border-radius: var(--radius-sm); color: var(--color-text-dim);
    transition: color 0.2s var(--ease-out), background 0.2s var(--ease-out);
}
.cart-drawer__item-remove svg { width: 18px; height: 18px; min-width: 18px; flex-shrink: 0; }

.cart-drawer__item-controls { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; flex-shrink: 0; }
.cart-drawer__item-remove:hover { color: var(--color-accent); background: var(--color-surface-2); }

.cart-drawer__footer { padding: 22px; border-top: 1px solid var(--color-border); }
.cart-drawer__note { font-size: 12px; color: var(--color-text-faint); margin-bottom: 16px; line-height: 1.6; }
.cart-drawer__note--gift { display: flex; align-items: flex-start; gap: 8px; color: var(--color-text-dim); }
.cart-drawer__note--gift svg { flex-shrink: 0; min-width: 14px; margin-top: 2px; color: var(--color-accent); }
.cart-drawer__footer .btn { width: 100%; }

.cart-drawer__total {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 14px;
    padding-bottom: 14px;
    border-bottom: 1px solid var(--color-border);
    font-family: var(--font-display);
    font-style: normal;
    font-size: 13px;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--color-text-dim);
} /* the global [hidden] rule up top (see RESET) covers this now */
.cart-drawer__total-prices { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
#cartDrawerTotalValue { font-size: 22px; color: var(--color-text); }
.cart-drawer__total-old { font-size: 15px; color: var(--color-discount); text-decoration: line-through; }
.cart-drawer__total-savings {
    font-family: var(--font-display);
    font-style: normal;
    font-size: 12px;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    padding: 4px 9px;
    border-radius: 999px;
    background: var(--color-discount);
    color: #fff;
}

.cart-drawer__coupon { margin-bottom: 16px; }
.cart-drawer__active-coupons { display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; }
.cart-drawer__active-coupon {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 10px 10px 12px;
    background: linear-gradient(135deg, rgba(182, 255, 46, 0.12), rgba(182, 255, 46, 0.04));
    border: 1px solid rgba(182, 255, 46, 0.35);
    border-radius: var(--radius-md, 10px);
    box-shadow: 0 1px 0 rgba(0, 0, 0, 0.15) inset;
}
.cart-drawer__active-coupon-icon {
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0;
    width: 26px; height: 26px;
    border-radius: 50%;
    background: rgba(182, 255, 46, 0.15);
    color: var(--color-accent);
}
.cart-drawer__active-coupon-body {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.cart-drawer__active-coupon-code {
    font-family: var(--font-display);
    font-style: normal;
    font-size: 13px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--color-accent);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.cart-drawer__active-coupon-label {
    font-size: 11px;
    color: var(--color-text-dim);
}
.cart-drawer__active-coupon-remove {
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0;
    width: 24px; height: 24px;
    border-radius: 50%;
    color: var(--color-text-dim);
    background: transparent;
    border: 1px solid transparent;
    transition: background 0.2s var(--ease-out), color 0.2s var(--ease-out), border-color 0.2s var(--ease-out);
}
.cart-drawer__active-coupon-remove:hover { background: rgba(239, 68, 68, 0.12); border-color: rgba(239, 68, 68, 0.3); color: var(--color-discount); }
.cart-drawer__active-coupon-remove:disabled { opacity: 0.5; pointer-events: none; }
.cart-drawer__coupon-toggle {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: var(--color-text-dim);
    transition: color 0.2s var(--ease-out);
}
.cart-drawer__coupon-toggle:hover { color: var(--color-accent); }
.cart-drawer__coupon-toggle svg { flex-shrink: 0; }
.cart-drawer__coupon-form { margin-top: 10px; overflow: hidden; }
.cart-drawer__coupon-row { display: flex; gap: 8px; }
.cart-drawer__coupon-row .input { width: auto; flex: 1; min-width: 0; padding: 10px 12px; font-size: 13px; }
.cart-drawer__coupon-row .btn { width: auto; flex-shrink: 0; padding: 10px 18px; font-size: 11px; }
.cart-drawer__coupon-message { margin: 8px 0 0; font-size: 12px; color: var(--color-accent); }
.cart-drawer__coupon-message--error { color: var(--color-pink); }

/* ---------------------------------------------------------------
   11. FOOTER
   --------------------------------------------------------------- */
.footer { border-top: 1px solid var(--color-border); background: var(--color-bg-alt); padding: 60px 0 0; }
.footer__inner { display: grid; grid-template-columns: 1fr; gap: 30px; margin-bottom: 36px; }
/* align-items defaults to stretch on a column flex container, which
   forces a child <img> with only height set to fill the container's
   full width instead of keeping its own aspect ratio - the "flat,
   100x1" logo. flex-start opts every child back out of that. */
.footer__brand { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
.footer__logo { height: 26px; width: auto; max-width: 100%; object-fit: contain; }
.footer__logo-text { font-family: var(--font-display); font-style: normal; font-size: 20px; text-transform: uppercase; }
.footer__tagline { color: var(--color-text-dim); font-size: 13px; max-width: 300px; }
.footer__legal { font-size: 11px; color: var(--color-text-faint); display: flex; flex-direction: column; gap: 6px; }
.footer__legal a { color: var(--color-text-dim); text-decoration: underline; }
.footer__payments { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 4px; }
.footer__payments img { height: 22px; width: auto; border-radius: 4px; }
.footer__links { display: flex; flex-direction: column; gap: 10px; }
.footer__links-title {
    font-family: var(--font-display);
    font-style: normal;
    font-size: 12px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--color-text-dim);
}
.footer__links a { font-size: 13px; color: var(--color-text-dim); }
.footer__links a:hover { color: var(--color-accent); }
.footer__disclaimer-bar { border-top: 1px solid var(--color-border); padding: 18px var(--container-pad) 22px; }
.footer__disclaimer { max-width: var(--container-width); margin-inline: auto; text-align: center; line-height: 1.6; font-size: 11px; color: var(--color-text-faint); }

/* ---------------------------------------------------------------
   12. LOGIN (username.html - cfx.re / FiveM / Steam / Discord)
   --------------------------------------------------------------- */
.login {
    position: relative;
    min-height: calc(100svh - var(--nav-height));
    display: flex;
    align-items: center;
    padding: 60px 0;
}
.login__grid { display: flex; justify-content: center; }
.login__card {
    width: min(480px, 100%);
    padding: 40px clamp(24px, 5vw, 44px);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: 0 40px 80px -40px rgba(0, 0, 0, 0.6);
    text-align: center;
}
.login__title { font-size: clamp(26px, 4vw, 34px); margin: 4px 0 16px; }
.login__subtitle { color: var(--color-text-dim); font-size: 14.5px; line-height: 1.65; margin-bottom: 28px; }
.login__cta { width: 100%; }
.login__form { display: flex; flex-direction: column; gap: 18px; text-align: left; margin-bottom: 4px; }
.login__note { margin-top: 24px; font-size: 12px; line-height: 1.6; color: var(--color-text-faint); }

.checkout-summary { text-align: left; border: 1px solid var(--color-border); border-radius: var(--radius-sm); margin: 24px 0; overflow: hidden; }
.checkout-summary__item { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 12px 16px; border-bottom: 1px solid var(--color-border); font-size: 14px; }
.checkout-summary__item:last-child { border-bottom: none; }
.checkout-summary__name { display: flex; flex-direction: column; gap: 2px; }
.checkout-summary__gift { font-size: 12px; color: var(--color-accent); }
.checkout-summary__price { font-family: var(--font-display); font-style: normal; font-size: 13px; color: var(--color-text-dim); white-space: nowrap; }
.gift-form__error { margin: -8px 0 0; font-size: 13px; color: var(--color-tag-fill); }

/* Text input - used only by the non-external ("enter your username")
   fallback form; external providers (FiveM/cfx.re included) never
   render this. */
.field { display: flex; flex-direction: column; gap: 6px; }
.field label { font-size: 12px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--color-text-dim); }
.field__note { font-size: 12px; line-height: 1.5; color: var(--color-text-faint); }
.input {
    width: 100%;
    padding: 13px 16px;
    font: inherit;
    font-size: 15px;
    color: var(--color-text);
    background: var(--color-surface-2);
    border: 1px solid var(--color-border-metal);
    border-radius: var(--radius-sm);
    transition: border-color 0.25s var(--ease-out);
}
.input:focus-visible { border-color: var(--color-accent); }

/* Login modal - same look as the .login__card on /login itself (that
   page's markup is reused verbatim inside .login-modal__body, see
   layout.html), just repositioned as a centred overlay instead of a
   full page, sharing .modal-backdrop with the quick-view modal and
   cart drawer. */
.login-modal {
    position: fixed;
    top: 50%; left: 50%;
    transform: translate(-50%, -48%) scale(0.96);
    width: min(480px, 92vw);
    max-height: 88vh;
    overflow-y: auto;
    z-index: 901;
    padding: 40px clamp(24px, 5vw, 44px);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: 0 60px 120px -40px rgba(0, 0, 0, 0.88);
    text-align: center;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.4s var(--ease-out), transform 0.4s var(--ease-out), visibility 0.4s;
}
.login-modal.is-open { opacity: 1; visibility: visible; transform: translate(-50%, -50%) scale(1); }
.login-modal__close {
    position: absolute;
    top: 14px; right: 14px;
    z-index: 1;
}
.login-modal__body .section-eyebrow { justify-content: center; }

/* ---------------------------------------------------------------
   13. PACKAGE DETAIL, OPTIONS, CMS, CATEGORY
   --------------------------------------------------------------- */
.shop__category-description { color: var(--color-text-dim); font-size: 15px; max-width: 60ch; margin-top: 4px; }

/* Package detail (package.html) - a bit wider than the site's usual
   1280px container: a real image carousel benefits from the extra
   room, and this page only ever holds the one two-column layout, so
   widening it here doesn't ripple into anything else.
   Top padding: the navbar is position:fixed and transparent until
   scrolled (see .navbar/.navbar--solid), so every section is on its
   own to clear it - .hero and .shop both do; this one didn't (48px
   against a 72px --nav-height), so the top of the gallery - and the
   navbar's own logo, sitting over it while still transparent -
   visibly overlapped. */
.package-detail { padding: calc(var(--nav-height) + 24px) 0 110px; }
.package-detail .container { max-width: 1440px; }
.package-detail__grid { display: flex; flex-direction: column; gap: 36px; }
.package-detail__media {
    background: var(--color-surface-2);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    overflow: hidden;
}
.package-detail__image { width: 100%; height: auto; display: block; }
.package-detail__media-placeholder {
    aspect-ratio: 16 / 10;
    display: flex; align-items: center; justify-content: center;
    color: var(--color-text-faint);
    font-family: var(--font-display); text-transform: uppercase; letter-spacing: 0.06em;
}
/* Was a bare 13px text link (a ~16px-tall click target, under even
   WCAG's 24px minimum) - a real bordered pill now, matching the
   navbar login/currency buttons' look, with an actual comfortable
   touch target. position:relative + z-index defends against ever
   again ending up under something else's stacking context, the same
   symptom as "the button doesn't respond to clicks" would look like. */
.package-detail__back {
    position: relative;
    z-index: 2;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 11px 20px;
    font-family: var(--font-display);
    font-style: normal;
    font-size: 13px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--color-text);
    border: 1px solid var(--color-border-metal);
    border-radius: var(--radius-sm);
    margin-bottom: 24px;
    transition: border-color 0.25s var(--ease-out), color 0.25s var(--ease-out);
}
.package-detail__back:hover { border-color: var(--color-accent); color: var(--color-accent); }
.package-detail__badge { position: static; display: inline-flex; margin-bottom: 14px; }
.package-detail__title { font-size: clamp(28px, 4.5vw, 42px); margin-bottom: 16px; }
.package-detail__price { display: flex; align-items: baseline; gap: 12px; margin-bottom: 24px; }
.package-detail__price-old { font-size: 15px; color: var(--color-discount); text-decoration: line-through; }
.package-detail__price-current { font-family: var(--font-display); font-size: 28px; color: var(--color-accent); }
.package-detail__price-current--muted { font-family: var(--font-body); color: var(--color-text); font-size: 18px; }
.package-detail__description { color: var(--color-text-dim); font-size: 15px; line-height: 1.75; margin-bottom: 32px; }
.package-detail__description img { border-radius: var(--radius-sm); margin: 16px 0; }
.package-detail__actions { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
.package-detail__cta { min-width: 220px; }
.package-detail__cta-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.package-detail__cta-row .package-detail__cta { min-width: 0; }
/* .btn--remove's own padding/font-size (10px/18px, 12px) are sized for
   the compact contexts it's normally paired with - a product card, the
   cart drawer. Next to this page's full-size Add to Basket/Buy as a
   Gift buttons (the base .btn's own 13px/28px, 14px) it read visibly
   shorter. Restoring the base .btn sizing here only, so all three CTAs
   on this page match. */
.package-detail__cta-row .btn--remove { padding: 13px 28px; font-size: 14px; }
.package-detail__owned { font-size: 13px; color: var(--color-text-faint); }

/* Options (options.html) */
.options-page__card { width: min(560px, 100%); text-align: left; }
.options-page__form { display: flex; flex-direction: column; gap: 18px; margin-bottom: 4px; }
.options-page__discord-connected { font-size: 14px; color: var(--color-text); margin-bottom: 6px; }
.options-page__discord-connected--pending { color: var(--color-text-dim); }
.options-page__discord-change { align-self: center; font-size: 13px; color: var(--color-text-dim); text-decoration: underline; text-underline-offset: 2px; }
.options-page__discord-change:hover { color: var(--color-accent); }
select.input { appearance: none; -webkit-appearance: none; background-image: none; }

/* CMS pages (cms/page.html) */
.cms-page { padding: 70px 0 110px; }
.cms-page__inner { max-width: 76ch; margin: 0 auto; }
.cms-page__title { font-size: clamp(30px, 5vw, 46px); margin: 6px 0 32px; }
.cms-content { color: var(--color-text-dim); font-size: 15.5px; line-height: 1.8; }
.cms-content h1, .cms-content h2, .cms-content h3 { color: var(--color-text); margin: 32px 0 14px; }
.cms-content h1 { font-size: 26px; } .cms-content h2 { font-size: 22px; } .cms-content h3 { font-size: 18px; }
.cms-content p { margin-bottom: 16px; }
.cms-content a { color: var(--color-accent); text-decoration: underline; }
.cms-content ul, .cms-content ol { margin: 0 0 16px 22px; }
.cms-content img { max-width: 100%; border-radius: var(--radius-sm); margin: 16px 0; }

/* ---------------------------------------------------------------
   14. STORE WIDGETS
   Tebex's own Creator Panel lets a store owner drop pre-built
   widgets onto the site (funding goal, community goal, featured
   package, recent payments, top donator, server status, gift card
   balance checker, plain text block) without touching any code -
   the same  block the stock theme renders via its
   own sidebar.twig. This theme had never wired that variable in at
   all, so anything added there was configured successfully in the
   dashboard but simply never appeared anywhere on the live site.
   Tebex renders the widgets itself as plain HTML (confirmed from
   its own default template's module.*.html source - every one
   wraps in .widget.widget-<type>, with .widget-title/.widget-content
   inside), so this styles that fixed, external markup to match the
   theme rather than building the widgets ourselves.
   --------------------------------------------------------------- */
.store-widgets { padding: 0 0 70px; }
.store-widgets__grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 20px;
}
.widget {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: 24px;
}
.widget-title {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    font-family: var(--font-display);
    font-style: normal;
    font-size: 15px;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--color-text);
    margin-bottom: 16px;
}
/* Collapsed-by-default accordion - see the JS that adds this class
   and the chevron itself (Tebex's own fixed widget markup has no hook
   to add either from Twig). */
.widget-title--toggle { cursor: pointer; user-select: none; }
.widget-title--toggle:hover { color: var(--color-accent); }
.widget-title__chevron { margin-left: auto; flex-shrink: 0; transition: transform 0.3s var(--ease-out); }
.widget.is-open .widget-title__chevron { transform: rotate(180deg); }
.widget-content { color: var(--color-text-dim); font-size: 14.5px; line-height: 1.7; }
.widget-content p { margin-bottom: 10px; }
.widget-content p:last-child { margin-bottom: 0; }
.widget-content a { color: var(--color-accent); text-decoration: underline; text-underline-offset: 2px; }
.widget-content img.goal-image { width: 100%; border-radius: var(--radius-sm); margin-bottom: 14px; }

/* Funding goal / community goal progress bar */
.widget .progress {
    height: 10px;
    border-radius: 999px;
    background: var(--color-surface-2);
    overflow: hidden;
    margin-bottom: 12px;
}
.widget .progress-bar { height: 100%; background: var(--color-accent); border-radius: inherit; }
.widget .progress-bar.striped {
    background-image: linear-gradient(45deg, rgba(0,0,0,0.15) 25%, transparent 25%, transparent 50%, rgba(0,0,0,0.15) 50%, rgba(0,0,0,0.15) 75%, transparent 75%, transparent);
    background-size: 24px 24px;
}
.widget .progress-bar.animated { animation: widget-stripes 1.1s linear infinite; }
@keyframes widget-stripes { from { background-position: 0 0; } to { background-position: 24px 0; } }

/* Recent payments / top donator */
.widget .purchases { display: flex; flex-direction: column; gap: 14px; }
.widget .purchase { display: flex; align-items: center; gap: 12px; }
.widget .avatar { width: 36px; height: 36px; border-radius: 50%; flex-shrink: 0; background: var(--color-surface-2); }
.widget .username { font-size: 14px; color: var(--color-text); margin-bottom: 2px; }
.widget .info p { margin: 0; font-size: 13px; }
.widget .sep { margin: 0 4px; opacity: 0.5; }
.widget time { display: block; font-size: 12px; color: var(--color-text-faint); margin-top: 2px; }
.widget p.empty { color: var(--color-text-faint); font-style: italic; }

/* Server status */
.widget .badge {
    font-family: var(--font-display);
    font-style: normal;
    font-size: 11px;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    padding: 3px 9px;
    border-radius: 999px;
}
.widget .badge-success { background: rgba(182, 255, 46, 0.15); color: var(--color-accent); }
.widget .badge-danger { background: rgba(255, 61, 126, 0.15); color: var(--color-pink); }
.widget-content h6 { font-family: var(--font-body); font-size: 15px; color: var(--color-text); margin-bottom: 6px; cursor: pointer; }

/* Gift card balance form */
.widget-content input.gift-card-input {
    width: 100%;
    padding: 12px 16px;
    margin-bottom: 12px;
    background: var(--color-surface-2);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    color: var(--color-text);
    font-family: var(--font-body);
    font-size: 14px;
}
.widget-content button.check,
.widget-content button.btn-secondary {
    font-family: var(--font-display);
    font-style: normal;
    font-size: 13px;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    padding: 11px 20px;
    background: var(--color-surface-2);
    border: 1px solid var(--color-border-metal);
    border-radius: var(--radius-sm);
    color: var(--color-text);
    cursor: pointer;
    transition: border-color 0.3s var(--ease-out), color 0.3s var(--ease-out);
}
.widget-content button.check:hover,
.widget-content button.btn-secondary:hover { border-color: var(--color-accent); color: var(--color-accent); }
.widget-content .alert { padding: 10px 14px; border-radius: var(--radius-sm); font-size: 13px; margin-top: 8px; }
.widget-content .alert-danger { background: rgba(255, 61, 126, 0.12); color: var(--color-pink); }
.widget-content .alert-warning { background: rgba(255, 138, 61, 0.12); color: var(--color-orange); }

/* Featured package - reuses this theme's own product-card markup
   (package-entry.twig include on Tebex's side has no visibility
   into our classes), so give its bare elements inside .widget-content
   sane defaults instead of leaving them unstyled. */
.widget-content .product { display: flex; flex-direction: column; gap: 10px; }
.widget-content .product img { width: 100%; border-radius: var(--radius-sm); }

@media (min-width: 768px) {
    .store-widgets__grid { grid-template-columns: repeat(2, 1fr); align-items: start; }
}
@media (min-width: 1100px) {
    .store-widgets__grid { grid-template-columns: repeat(3, 1fr); }
}

/* ---------------------------------------------------------------
   15. FAQ
   --------------------------------------------------------------- */
.faq { padding: 90px 0 100px; border-top: 1px solid var(--color-border); }
.faq__inner { max-width: 820px; margin: 0 auto; }
.faq__inner .section-title { text-align: center; margin-bottom: 40px; }
.faq__inner .section-eyebrow { display: flex; justify-content: center; }
.faq__list { display: flex; flex-direction: column; gap: 12px; }
.faq__item {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    overflow: hidden;
}
.faq__question {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 20px 22px;
    text-align: left;
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 15.5px;
    color: var(--color-text);
    cursor: pointer;
}
.faq__chevron { flex-shrink: 0; color: var(--color-text-dim); transition: transform 0.3s var(--ease-out); }
.faq__item.is-open .faq__chevron { transform: rotate(180deg); color: var(--color-accent); }
.faq__answer { padding: 0 22px; }
.faq__answer p { padding-bottom: 20px; color: var(--color-text-dim); font-size: 14.5px; line-height: 1.7; }
.faq__answer a { color: var(--color-accent); text-decoration: underline; text-underline-offset: 2px; }

/* ---------------------------------------------------------------
   16. RESPONSIVE
   --------------------------------------------------------------- */
@media (min-width: 768px) {
    .hero__grid { grid-template-columns: 1.1fr 0.9fr; }
    .product-grid { grid-template-columns: repeat(2, 1fr); }
    .footer__inner { grid-template-columns: 1.3fr 0.9fr 1fr; align-items: end; }
    /* Quick-view stays image-on-top / details-below at every width. */
    .quick-view__gallery { aspect-ratio: auto; }

    .package-detail__grid { flex-direction: row; align-items: flex-start; gap: 48px; }
    .package-detail__media { flex: 1.1; }
    .package-detail__info { flex: 0.9; position: sticky; top: calc(var(--nav-height) + 24px); }
}

@media (min-width: 1024px) {
    /* Caps at 3 - cards stay large rather than shrinking to fit a 4th
       column as the viewport grows past this point. */
    .product-grid { grid-template-columns: repeat(3, 1fr); }
}

@media (prefers-reduced-motion: reduce) {
    .hero__scroll-cue::after { animation: none; }
    * { scroll-behavior: auto !important; }
}
