/* ==========================================================================
   gz.css — Gamezfan design system (v1)

   This file is the SINGLE SOURCE OF TRUTH for the new look. Pages that use it
   load ONLY this stylesheet — not style.css / portal.css / arcade.css. That is
   deliberate: the old three files partly override each other, which is why the
   site felt inconsistent. Nothing here depends on them.

   Performance rules carried over from arcade.css (still apply):
     - no backdrop-filter / blur on repeated elements (cards, thumbs)
     - no blurred box-shadow on repeated elements
     - transitions on colour/opacity/transform only, never on layout properties
   ========================================================================== */

/* ---------- 1. Tokens ---------------------------------------------------- */
:root {
    /* Surfaces: three steps, darkest to lightest. Solid, not translucent. */
    --gz-bg:          #080d18;
    --gz-surface:     #101728;
    --gz-surface-2:   #16203a;
    --gz-line:        #22304f;
    --gz-line-soft:   #1a2337;

    /* Text */
    --gz-text:        #eef3ff;
    --gz-text-dim:    #9dadcc;
    --gz-text-faint:  #6c7c9c;

    /* One accent family only. */
    --gz-accent:      #3b82f6;
    --gz-accent-hi:   #60a5fa;
    --gz-accent-deep: #1d4ed8;
    --gz-on-accent:   #ffffff;

    /* Shape + rhythm */
    --gz-r-sm: 8px;
    --gz-r:    12px;
    --gz-r-lg: 18px;
    --gz-r-pill: 999px;

    --gz-pad: 16px;
    --gz-gap: 12px;

    /* Page width steps. Mobile-first; opens up on tablet/desktop. */
    --gz-max: 1180px;

    --gz-font: "Montserrat", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* ---------- 2. Reset ----------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

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

body {
    margin: 0;
    background: var(--gz-bg);
    color: var(--gz-text);
    font-family: var(--gz-font);
    font-size: 15px;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; }

:focus-visible {
    outline: 2px solid var(--gz-accent-hi);
    outline-offset: 2px;
    border-radius: var(--gz-r-sm);
}

/* Screen-reader-only text. */
.gz-sr {
    position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------- 3. Layout shell --------------------------------------------- */
.gz-wrap {
    width: 100%;
    max-width: var(--gz-max);
    margin: 0 auto;
    padding: 0 var(--gz-pad);
}

/* Plain breathing room under the content. There is no bottom dock any more,
   so nothing needs reserving here. */
.gz-page { padding-bottom: 24px; }
@media (min-width: 768px) { .gz-page { padding-bottom: 32px; } }

/* ---------- 4. Header ---------------------------------------------------- */
.gz-top {
    position: sticky;
    top: 0;
    z-index: 40;
    background: var(--gz-bg);
    border-bottom: 1px solid var(--gz-line-soft);
}

/* One row at every screen size.
     phone   : brand | search | menu button
     desktop : brand | Home All Games Categories | search
   nowrap because this row must never become two rows - a phone header that
   spilled onto a second line was the original complaint. */
.gz-top-row {
    display: flex;
    align-items: center;
    flex-wrap: nowrap;
    gap: 8px;
    min-height: 56px;
}

.gz-brand {
    font-size: 18px;
    font-weight: 800;
    letter-spacing: -0.02em;
    white-space: nowrap;
    flex: 0 0 auto;
}
.gz-brand span { color: var(--gz-accent-hi); }

@media (min-width: 768px) {
    .gz-top-row { gap: var(--gz-gap); }
    .gz-brand { font-size: 20px; }
}

/* In the header the logo is a primary tap target, so give it a full-height
   hit area rather than just the height of the text (was 30px). */
.gz-top .gz-brand {
    display: flex;
    align-items: center;
    min-height: 44px;
}

/* Search field ---------------------------------------------------------- */
/* Always visible, at every screen size. On a games site "find me a specific
   game" is the single most common task, so hiding search behind an icon (as
   this header did) buried the most important control on the page. It takes
   the space left over after the brand and the menu button. */
.gz-search {
    position: relative;
    flex: 1 1 auto;
    min-width: 0;
}
.gz-search-icon {
    position: absolute;
    left: 11px; top: 50%;
    width: 17px; height: 17px;
    transform: translateY(-50%);
    color: var(--gz-text-faint);
    pointer-events: none;
}
.gz-search-input {
    width: 100%;
    height: 40px;
    padding: 0 12px 0 36px;
    border: 1px solid var(--gz-line);
    border-radius: var(--gz-r-pill);
    background: var(--gz-surface);
    color: var(--gz-text);
    font: inherit;
    /* 16px so iOS Safari does not zoom the page in when it gains focus. */
    font-size: 16px;
    transition: border-color .15s ease, background-color .15s ease;
}
.gz-search-input::placeholder { color: var(--gz-text-faint); }
.gz-search-input:focus {
    outline: none;
    border-color: var(--gz-accent);
    background: var(--gz-surface-2);
}
@media (min-width: 768px) {
    /* Desktop has room for the nav links, so search stops being greedy and
       sits at the right at a comfortable reading width. */
    .gz-search { flex: 0 1 340px; margin-left: auto; }
    .gz-search-input { height: 42px; font-size: 14px; }
}

/* Menu button ----------------------------------------------------------- */
.gz-menu-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    flex: 0 0 auto;
    border: 1px solid var(--gz-line);
    border-radius: 50%;
    background: var(--gz-surface);
    color: var(--gz-text-dim);
    cursor: pointer;
    transition: color .15s ease, background-color .15s ease, border-color .15s ease;
}
.gz-menu-btn:hover {
    color: var(--gz-text);
    background: var(--gz-surface-2);
    border-color: var(--gz-accent);
}
.gz-menu-btn svg { width: 20px; height: 20px; }

/* Nav ------------------------------------------------------------------- */
/* Desktop-only. See the note above the 768px block below. */
.gz-nav {
    display: none;
    align-items: center;
    flex-wrap: nowrap;
    gap: 2px;
}
.gz-navlink {
    padding: 6px 10px;
    border-radius: var(--gz-r-pill);
    font-size: 13px;
    font-weight: 600;
    white-space: nowrap;
    color: var(--gz-text-dim);
    transition: color .15s ease, background-color .15s ease;
}
.gz-navlink:hover { color: var(--gz-text); background: var(--gz-surface); }
.gz-navlink[aria-current="page"] {
    color: var(--gz-on-accent);
    background: var(--gz-accent-deep);
}
/* The logo is the Home link, so it gets the current-page colour on the home
   page - but not the filled pill, which would look wrong on a wordmark. */
.gz-brand[aria-current="page"] { color: var(--gz-text); }

/* The three text links are a DESKTOP-only affordance. On a phone the same
   destinations - plus every category, which these links cannot show - live in
   the menu panel, so showing both would be the duplicate-navigation problem
   all over again. */
@media (min-width: 768px) {
    .gz-top-row { min-height: 68px; }
    .gz-nav { display: flex; gap: 6px; }
    .gz-navlink { padding: 7px 13px; font-size: 13.5px; }
    /* Desktop shows the links instead, so the panel trigger goes away. */
    .gz-menu-btn { display: none; }
}

/* Very narrow phones (320px - iPhone SE and older Androids).
   Measured: brand 94 + nav 160 + icon 40 + gaps needs 310px, but a 320px
   screen minus the 16px side padding only offers 288px, so the row spilled
   over and the whole page scrolled sideways. Everything tightens a little
   here rather than the row being allowed to wrap or overflow.
   --gz-pad is reduced on :root so .gz-wrap AND the chip rail's negative
   margins stay in agreement - that is why they both reference the variable. */
@media (max-width: 360px) {
    :root { --gz-pad: 12px; }
    .gz-top-row { gap: 6px; }
    .gz-brand { font-size: 17px; }
    .gz-navlink { padding: 6px 8px; font-size: 12.5px; }
    /* The menu button stays 40px - it is a primary control and the row has
       room for it once the padding tightens. */
}

/* ---------- 5. Browse panel (behind the header's menu button) ------------ */
/* A modal drawer, phone only. It exists because reaching a category used to
   take two taps from most pages, and play.html / contact / privacy had no
   category navigation at all. Every category is now one tap from every page.

   Closed state is visibility:hidden rather than display:none on purpose:
   display:none cannot be transitioned, and visibility:hidden still removes
   the links from the tab order, so no `inert` polyfill is needed. */
.gz-panel-backdrop {
    position: fixed;
    inset: 0;
    z-index: 60;
    background: rgba(3, 6, 14, .66);
    opacity: 0;
    visibility: hidden;
    transition: opacity .2s ease, visibility .2s ease;
}
.gz-panel {
    position: fixed;
    top: 0; right: 0; bottom: 0;
    z-index: 61;
    width: min(340px, 86vw);
    display: flex;
    flex-direction: column;
    background: var(--gz-surface);
    border-left: 1px solid var(--gz-line);
    transform: translateX(100%);
    visibility: hidden;
    transition: transform .22s ease, visibility .22s ease;
    overscroll-behavior: contain;
}

body.gz-panel-open .gz-panel-backdrop { opacity: 1; visibility: visible; }
body.gz-panel-open .gz-panel { transform: none; visibility: visible; }
/* Stop the page behind the drawer scrolling under the finger. */
body.gz-panel-open { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
    .gz-panel, .gz-panel-backdrop { transition: none; }
}

.gz-panel-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 12px 14px 18px;
    border-bottom: 1px solid var(--gz-line-soft);
    flex: 0 0 auto;
}
.gz-panel-title {
    margin: 0;
    font-size: 15px;
    font-weight: 800;
    letter-spacing: -0.01em;
}
.gz-panel-close {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    flex: 0 0 auto;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--gz-text-dim);
    cursor: pointer;
    transition: color .15s ease, background-color .15s ease;
}
.gz-panel-close:hover { color: var(--gz-text); background: var(--gz-surface-2); }
.gz-panel-close svg { width: 20px; height: 20px; }

.gz-panel-body {
    flex: 1 1 auto;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: 10px 10px calc(18px + env(safe-area-inset-bottom));
}

.gz-panel-label {
    margin: 16px 0 4px;
    padding: 0 8px;
    font-size: 11px;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--gz-text-faint);
}

.gz-panel-link {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    /* 46px tall: comfortably above the 44px minimum tap target, and the list
       is scrollable so there is no reason to squeeze. */
    min-height: 46px;
    padding: 0 10px;
    border: 0;
    border-radius: var(--gz-r);
    background: transparent;
    font-size: 14.5px;
    font-weight: 600;
    text-align: left;
    color: var(--gz-text-dim);
    cursor: pointer;
    transition: color .15s ease, background-color .15s ease;
}
.gz-panel-link:hover { color: var(--gz-text); background: var(--gz-surface-2); }
.gz-panel-link[aria-current="page"] {
    color: var(--gz-text);
    background: var(--gz-surface-2);
}
.gz-panel-link span:not(.gz-panel-count):not(.gz-sr) { flex: 1 1 auto; }
.gz-panel-icon { width: 19px; height: 19px; flex: 0 0 auto; color: var(--gz-accent-hi); }
.gz-panel-count {
    flex: 0 0 auto;
    min-width: 22px;
    padding: 2px 7px;
    border-radius: var(--gz-r-pill);
    background: var(--gz-bg);
    color: var(--gz-text-faint);
    font-size: 12px;
    font-weight: 700;
    text-align: center;
}
/* Desktop uses the header's own links, so the drawer is never reachable and
   is removed from the accessibility tree entirely. */
@media (min-width: 768px) {
    .gz-panel, .gz-panel-backdrop { display: none; }
}

/* ---------- 5b. Home intro --------------------------------------------- */
/* Replaced a full hero block. The old one read "Free games. Just press play."
   above a "Browse all 20 games" button - an instruction with no button to
   press, and a link to a page showing the same games already underneath it,
   while pushing those games most of a screen down. This says what the site is
   in one line and gets out of the way. */
.gz-intro {
    padding: 14px 0 14px;
    border-bottom: 1px solid var(--gz-line-soft);
}
.gz-intro-row {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
}
.gz-intro-text { flex: 1 1 260px; min-width: 0; }
.gz-intro-title {
    margin: 0;
    font-size: 23px;
    line-height: 1.15;
    font-weight: 800;
    letter-spacing: -0.02em;
}
.gz-intro-sub {
    margin: 6px 0 0;
    max-width: 48ch;
    color: var(--gz-text-dim);
    font-size: 14px;
}
/* Hidden on phones. Measured: with the button in the row the intro was 171px
   tall and the first game card sat 316px down the page - on a normal handset
   that is half a screen of chrome before a single game appears, which is the
   exact problem the old hero had. Surprise me is still one tap away on a
   phone, in the header menu and in the footer. From 520px up there is room
   beside the text, so it comes back.
   Deliberately a modest pill, never a full-width call to action: the games
   are the call to action on this page. */
/* Scoped as .gz-intro .gz-intro-cta, not .gz-intro-cta: this block sits
   ABOVE section 6, so a bare single-class selector loses to
   `.gz-btn { display: inline-flex }` further down the file and the button
   stayed visible on phones. */
.gz-intro .gz-intro-cta { display: none; }

@media (min-width: 520px) {
    .gz-intro .gz-intro-cta {
        display: inline-flex;
        flex: 0 0 auto;
        height: 40px;
        font-size: 14px;
    }
}

@media (min-width: 768px) {
    .gz-intro { padding: 30px 0 26px; }
    .gz-intro-title { font-size: 32px; }
    .gz-intro-sub { font-size: 15.5px; margin-top: 8px; }
    .gz-intro .gz-intro-cta { height: 44px; font-size: 14.5px; }
}

/* ---------- 6. Buttons -------------------------------------------------- */
.gz-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    height: 44px;
    padding: 0 20px;
    border: 1px solid transparent;
    border-radius: var(--gz-r-pill);
    background: var(--gz-surface-2);
    color: var(--gz-text);
    font-size: 14.5px;
    font-weight: 700;
    cursor: pointer;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
.gz-btn:hover { background: var(--gz-line); }

.gz-btn-primary {
    background: var(--gz-accent);
    color: var(--gz-on-accent);
}
.gz-btn-primary:hover { background: var(--gz-accent-hi); }

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

.gz-btn-icon { width: 18px; height: 18px; flex: 0 0 auto; }

/* ---------- 7. Section headers ------------------------------------------ */
/* 18px on phones rather than 26px: every section pays this cost, and it was
   part of what pushed the first game card off the first screen. */
.gz-section { padding: 18px 0 4px; }

.gz-section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 14px;
}
.gz-section-title {
    margin: 0;
    font-size: 17px;
    font-weight: 800;
    letter-spacing: -0.01em;
}
.gz-section-sub {
    display: block;
    margin-top: 3px;
    font-size: 13px;
    font-weight: 500;
    color: var(--gz-text-faint);
    letter-spacing: 0;
}
.gz-section-link {
    flex: 0 0 auto;
    font-size: 13.5px;
    font-weight: 700;
    color: var(--gz-accent-hi);
    transition: color .15s ease;
}
.gz-section-link:hover { color: var(--gz-text); }

@media (min-width: 768px) {
    .gz-section { padding: 40px 0 4px; }
    .gz-section-title { font-size: 22px; }
}

/* ---------- 8. Category chips ------------------------------------------- */
/* Wraps freely on tablet and desktop. On a phone the nine chips wrapped onto
   THREE rows, pushing the games most of a screen down, so there they become
   one sideways-swipe row instead. See .gz-chiprail below for the fade that
   makes the scrolling visible. */
.gz-chiprail { position: relative; }

.gz-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

@media (max-width: 767px) {
    /* Break out to both screen edges so a partly-cut chip is visible at the
       right - the clearest possible hint that the row scrolls. */
    .gz-chiprail {
        margin-left: calc(-1 * var(--gz-pad));
        margin-right: calc(-1 * var(--gz-pad));
    }

    /* The fade sits on the rail, NOT on the scroller: a gradient inside a
       scrolling box scrolls away with the content and stops meaning anything.
       Transparent is written as rgba(...,0) rather than the keyword because
       `transparent` interpolates through transparent BLACK in a gradient,
       which shows as a dirty smudge over the navy. */
    .gz-chiprail::after {
        content: "";
        position: absolute;
        top: 0; right: 0; bottom: 0;
        width: 40px;
        background: linear-gradient(to right, rgba(8, 13, 24, 0), var(--gz-bg));
        pointer-events: none;
    }

    .gz-chiprail .gz-chips {
        flex-wrap: nowrap;
        overflow-x: auto;
        /* Vertical padding leaves room for the focus ring, which would
           otherwise be clipped by overflow. */
        padding: 3px var(--gz-pad);
        scroll-padding-left: var(--gz-pad);
        scrollbar-width: none;
        -ms-overflow-style: none;
    }
    .gz-chiprail .gz-chips::-webkit-scrollbar { display: none; }
    .gz-chiprail .gz-chip { flex: 0 0 auto; }
}
.gz-chip {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 8px 14px 8px 11px;
    border: 1px solid var(--gz-line);
    border-radius: var(--gz-r-pill);
    background: var(--gz-surface);
    font-size: 13.5px;
    font-weight: 600;
    color: var(--gz-text-dim);
    transition: color .15s ease, border-color .15s ease, background-color .15s ease;
}
.gz-chip:hover {
    color: var(--gz-text);
    border-color: var(--gz-accent);
    background: var(--gz-surface-2);
}
.gz-chip-icon { width: 17px; height: 17px; flex: 0 0 auto; color: var(--gz-accent-hi); }
.gz-chip-count { color: var(--gz-text-faint); font-weight: 600; font-size: 12.5px; }

/* ---------- 9. Game grid ------------------------------------------------ */
.gz-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--gz-gap);
}
@media (min-width: 520px) { .gz-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 768px) { .gz-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; } }
@media (min-width: 1024px) { .gz-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); } }

/* Game card ------------------------------------------------------------- */
/* The WHOLE card is one link. The old design had a thumbnail and a separate
   "Play Game" button, which meant two tap targets for one action. */
.gz-card {
    display: block;
    position: relative;
    border: 1px solid var(--gz-line-soft);
    border-radius: var(--gz-r);
    background: var(--gz-surface);
    overflow: hidden;
    transition: border-color .15s ease, background-color .15s ease, transform .15s ease;
}
.gz-card:hover {
    border-color: var(--gz-accent);
    background: var(--gz-surface-2);
    transform: translateY(-2px);
}
@media (prefers-reduced-motion: reduce) {
    .gz-card, .gz-card:hover { transform: none; transition: border-color .15s ease; }
}

/* Square thumbnail. object-fit: cover crops to fill, so we no longer need
   the blurred duplicate image the old design used to hide letterboxing. */
.gz-card-thumb {
    position: relative;
    aspect-ratio: 1 / 1;
    background: var(--gz-surface-2);
    overflow: hidden;
}
.gz-card-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.gz-card-body { padding: 9px 10px 11px; }
.gz-card-title {
    margin: 0;
    font-size: 13.5px;
    font-weight: 700;
    line-height: 1.3;
    /* Two lines maximum, then ellipsis, so cards stay the same height. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.gz-card-cat {
    margin: 4px 0 0;
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--gz-text-faint);
}

/* Badge. Only shown where the data actually supports it (featured games) —
   no invented "hot"/"new" labels. */
.gz-badge {
    position: absolute;
    top: 8px; left: 8px;
    padding: 3px 8px;
    border-radius: var(--gz-r-pill);
    background: var(--gz-accent-deep);
    color: var(--gz-on-accent);
    font-size: 10.5px;
    font-weight: 800;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

@media (min-width: 768px) {
    .gz-card-body { padding: 11px 12px 13px; }
    .gz-card-title { font-size: 14.5px; }
}

/* ---------- 10. Ad slot ------------------------------------------------- */
/* Same ad markup as before — only the container styling is new. */
.gz-ad {
    margin: 28px 0 4px;
    text-align: center;
}
.gz-ad-label {
    margin: 0 0 8px;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--gz-text-faint);
}
.gz-ad-note {
    margin: 0;
    padding: 18px 10px;
    color: var(--gz-text-faint);
    font-size: 12.5px;
}

/* ---------- 11. Empty state -------------------------------------------- */
.gz-empty {
    padding: 40px 20px;
    border: 1px dashed var(--gz-line);
    border-radius: var(--gz-r);
    text-align: center;
    color: var(--gz-text-dim);
}

/* ---------- 12. Footer -------------------------------------------------- */
.gz-foot {
    margin-top: 44px;
    padding: 28px 0 24px;
    border-top: 1px solid var(--gz-line-soft);
    background: var(--gz-surface);
}
.gz-foot-grid {
    display: grid;
    gap: 24px;
    grid-template-columns: 1fr;
}
@media (min-width: 640px) {
    .gz-foot-grid { grid-template-columns: 1.4fr 1fr 1fr; gap: 32px; }
}
.gz-foot-about p {
    margin: 8px 0 0;
    max-width: 40ch;
    color: var(--gz-text-dim);
    font-size: 13.5px;
}
.gz-foot-col h3 {
    margin: 0 0 10px;
    font-size: 12px;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--gz-text-faint);
}
.gz-foot-col ul { margin: 0; padding: 0; list-style: none; }
.gz-foot-col li { margin-bottom: 7px; }
.gz-foot-col a {
    font-size: 13.5px;
    color: var(--gz-text-dim);
    transition: color .15s ease;
}
.gz-foot-col a:hover { color: var(--gz-text); }

/* "Surprise me" is a button, not a link, but it belongs in the footer link
   list, so it is reset to match its neighbours exactly. */
.gz-footbtn {
    padding: 0;
    border: 0;
    background: none;
    font-size: 13.5px;
    font-weight: 500;
    text-align: left;
    color: var(--gz-text-dim);
    cursor: pointer;
    transition: color .15s ease;
}
.gz-footbtn:hover { color: var(--gz-text); }

.gz-foot-legal {
    margin: 26px 0 0;
    padding-top: 18px;
    border-top: 1px solid var(--gz-line-soft);
    color: var(--gz-text-faint);
    font-size: 12.5px;
}

/* ---------- 13. (was the mobile bottom dock) ----------------------------
   Removed 2026-08-26. A permanently docked bottom bar cost ~56px plus the
   phone's home-bar inset on every screen, duplicated the header nav, and sits
   exactly where Google's anchor ad unit docks itself. Navigation is now the
   sticky one-row header only; "Surprise me" moved to the home hero and the
   footer. See topbar() in tools/gzui.py.
   ------------------------------------------------------------------------ */

/* ==========================================================================
   PART 2 — page-level components
   Added when the design was rolled out to every page (play, search, category,
   contact, legal). Same rules as Part 1: mobile-first, no blur on repeated
   elements, colour/opacity/transform transitions only.
   ========================================================================== */

/* ---------- 14. Skip link ----------------------------------------------- */
/* Keyboard users land on this first and can jump past the header. */
.gz-skip {
    position: absolute;
    left: 12px;
    top: -60px;
    z-index: 60;
    padding: 10px 16px;
    border-radius: var(--gz-r-sm);
    background: var(--gz-accent);
    color: var(--gz-on-accent);
    font-size: 14px;
    font-weight: 700;
    transition: top .15s ease;
}
.gz-skip:focus { top: 12px; }

/* ---------- 15. Breadcrumbs --------------------------------------------- */
/* Small but important on mobile: it says where you are and gives a one-tap
   way back up without relying on the browser's back button. */
.gz-crumbs {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    /* padding-top ONLY. This element carries BOTH .gz-wrap and .gz-crumbs, and
       the `padding` shorthand here wiped out .gz-wrap's `padding: 0 16px` -
       so the trail sat hard against the left screen edge while the logo and
       the card below it were indented 16px. */
    padding-top: 14px;
    font-size: 12.5px;
    color: var(--gz-text-faint);
}
.gz-crumbs a {
    color: var(--gz-text-dim);
    font-weight: 600;
    transition: color .15s ease;
}
.gz-crumbs a:hover { color: var(--gz-accent-hi); }
.gz-crumbs-sep { opacity: .5; }
.gz-crumbs [aria-current] { color: var(--gz-text); font-weight: 600; }

/* ---------- 16. Page head (non-home pages) ------------------------------ */
.gz-pagehead { padding: 18px 0 6px; }
.gz-pagehead-title {
    margin: 0;
    font-size: 24px;
    font-weight: 800;
    letter-spacing: -0.02em;
    line-height: 1.15;
}
.gz-pagehead-sub {
    margin: 7px 0 0;
    max-width: 56ch;
    color: var(--gz-text-dim);
    font-size: 14px;
}
@media (min-width: 768px) {
    .gz-pagehead { padding: 30px 0 8px; }
    .gz-pagehead-title { font-size: 34px; }
    .gz-pagehead-sub { font-size: 15px; }
}

/* ---------- 17. Play page ----------------------------------------------- */
.gz-play {
    display: grid;
    gap: 18px;
    margin-top: 16px;
    padding: 16px;
    border: 1px solid var(--gz-line-soft);
    border-radius: var(--gz-r-lg);
    background: var(--gz-surface);
}
.gz-play-thumb-wrap {
    width: 140px;
    aspect-ratio: 1 / 1;
    border-radius: var(--gz-r);
    overflow: hidden;
    background: var(--gz-surface-2);
    flex: 0 0 auto;
}
.gz-play-thumb-wrap img { width: 100%; height: 100%; object-fit: cover; }

.gz-play-top { display: flex; gap: 16px; align-items: flex-start; }
.gz-play-title {
    margin: 0;
    font-size: 21px;
    font-weight: 800;
    line-height: 1.2;
    letter-spacing: -0.02em;
}
.gz-play-cat {
    display: inline-block;
    margin: 8px 0 0;
    padding: 3px 10px;
    border-radius: var(--gz-r-pill);
    background: var(--gz-surface-2);
    color: var(--gz-text-dim);
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}
.gz-play-desc {
    margin: 12px 0 0;
    color: var(--gz-text-dim);
    font-size: 14.5px;
}
.gz-play-cta {
    /* Full width on mobile so it is impossible to miss and easy to thumb. */
    width: 100%;
    height: 52px;
    font-size: 16px;
}
.gz-play-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 16px;
    margin: 14px 0 0;
    color: var(--gz-text-faint);
    font-size: 12.5px;
}
.gz-play-meta span { display: inline-flex; align-items: center; gap: 6px; }
.gz-play-meta svg { width: 14px; height: 14px; }

@media (min-width: 640px) {
    .gz-play { padding: 22px; gap: 20px; }
    .gz-play-thumb-wrap { width: 180px; }
    .gz-play-title { font-size: 27px; }
    .gz-play-cta { width: auto; min-width: 220px; }
}

/* Related games: styled to match .gz-card exactly. Markup for these comes
   from js/gz-play-details.js, which is shared with the old design, so the
   class names here are its names rather than the .gz-card ones. */
.gz-related-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--gz-gap);
}
@media (min-width: 520px) { .gz-related-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 768px) { .gz-related-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; } }
.gz-related-card {
    display: block;
    border: 1px solid var(--gz-line-soft);
    border-radius: var(--gz-r);
    background: var(--gz-surface);
    overflow: hidden;
    transition: border-color .15s ease, background-color .15s ease, transform .15s ease;
}
.gz-related-card:hover {
    border-color: var(--gz-accent);
    background: var(--gz-surface-2);
    transform: translateY(-2px);
}
.gz-related-thumb {
    width: 100%;
    aspect-ratio: 1 / 1;
    height: auto;
    object-fit: cover;
    background: var(--gz-surface-2);
}
.gz-related-title {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    padding: 9px 10px 11px;
    font-size: 13.5px;
    font-weight: 700;
    line-height: 1.3;
}
@media (prefers-reduced-motion: reduce) {
    .gz-related-card, .gz-related-card:hover { transform: none; }
}

/* ---------- 18. Search page -------------------------------------------- */
.gz-searchbig { position: relative; margin: 14px 0 0; }
.gz-searchbig-icon {
    position: absolute;
    left: 16px; top: 50%;
    width: 20px; height: 20px;
    transform: translateY(-50%);
    color: var(--gz-text-faint);
    pointer-events: none;
}
.gz-searchbig-input {
    width: 100%;
    height: 52px;
    padding: 0 46px;
    border: 1px solid var(--gz-line);
    border-radius: var(--gz-r-pill);
    background: var(--gz-surface);
    color: var(--gz-text);
    font: inherit;
    font-size: 16px; /* 16px minimum, or iOS Safari zooms in on focus */
    transition: border-color .15s ease, background-color .15s ease;
}
.gz-searchbig-input:focus {
    outline: none;
    border-color: var(--gz-accent);
    background: var(--gz-surface-2);
}
.gz-searchbig-clear {
    position: absolute;
    right: 6px; top: 50%;
    transform: translateY(-50%);
    /* 40px box keeps this a comfortable thumb target on a phone. */
    width: 40px; height: 40px;
    display: none;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--gz-text-faint);
    cursor: pointer;
    transition: color .15s ease, background-color .15s ease;
}
.gz-searchbig-clear:hover { color: var(--gz-text); background: var(--gz-line); }
.gz-searchbig-clear svg { width: 17px; height: 17px; }
.gz-searchbig-clear[data-show="1"] { display: flex; }

.gz-status {
    margin: 14px 0 0;
    color: var(--gz-text-faint);
    font-size: 13px;
    font-weight: 600;
}

/* Suggested searches, shown when the box is empty or nothing matched. */
.gz-suggest { margin: 14px 0 0; }
.gz-suggest-label {
    margin: 0 0 8px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--gz-text-faint);
}

/* ---------- 19. Forms --------------------------------------------------- */
.gz-form {
    display: grid;
    gap: 14px;
    margin-top: 18px;
    padding: 18px;
    border: 1px solid var(--gz-line-soft);
    border-radius: var(--gz-r-lg);
    background: var(--gz-surface);
}
.gz-field { display: grid; gap: 6px; }
.gz-label { font-size: 13px; font-weight: 700; color: var(--gz-text-dim); }
.gz-label span { color: var(--gz-text-faint); font-weight: 600; }
.gz-input, .gz-textarea {
    width: 100%;
    padding: 12px 14px;
    border: 1px solid var(--gz-line);
    border-radius: var(--gz-r);
    background: var(--gz-bg);
    color: var(--gz-text);
    font: inherit;
    font-size: 16px; /* prevents the iOS zoom-on-focus jump */
    transition: border-color .15s ease;
}
.gz-input { height: 48px; }
.gz-textarea { min-height: 130px; resize: vertical; }
.gz-input:focus, .gz-textarea:focus { outline: none; border-color: var(--gz-accent); }
.gz-input:user-invalid, .gz-textarea:user-invalid { border-color: #e05252; }

.gz-form-note {
    margin: 0;
    color: var(--gz-text-faint);
    font-size: 12.5px;
    line-height: 1.55;
}
.gz-form-note a { color: var(--gz-accent-hi); }

/* Inline confirmation / error message under a form. */
.gz-note {
    margin: 14px 0 0;
    padding: 12px 14px;
    border: 1px solid var(--gz-line);
    border-radius: var(--gz-r);
    background: var(--gz-surface-2);
    font-size: 13.5px;
    color: var(--gz-text-dim);
}
.gz-note strong { color: var(--gz-text); }

/* ---------- 20. Long-form text (legal pages) ---------------------------- */
.gz-prose {
    max-width: 68ch;
    margin-top: 18px;
    color: var(--gz-text-dim);
    font-size: 15px;
    line-height: 1.7;
    /* The policy text quotes full URLs (e.g. the Google partner-sites page).
       An unbroken 45-character link cannot wrap, and it pushed a 320px screen
       13px wide - the whole page scrolled sideways. */
    overflow-wrap: break-word;
}
/* Links get the more aggressive value: a URL has no spaces to break at, so
   break-word alone still leaves it as one long unbreakable run. */
.gz-prose a { overflow-wrap: anywhere; }
.gz-prose h2 {
    margin: 30px 0 8px;
    color: var(--gz-text);
    font-size: 17px;
    font-weight: 800;
    letter-spacing: -0.01em;
}
.gz-prose h2:first-child { margin-top: 0; }
.gz-prose p { margin: 0 0 12px; }
.gz-prose ul { margin: 0 0 14px; padding-left: 20px; }
.gz-prose li { margin-bottom: 7px; }
.gz-prose a { color: var(--gz-accent-hi); text-decoration: underline; }
.gz-prose strong { color: var(--gz-text); }
.gz-prose-meta {
    margin: 0 0 22px;
    padding: 10px 14px;
    border-left: 3px solid var(--gz-accent);
    background: var(--gz-surface);
    border-radius: 0 var(--gz-r-sm) var(--gz-r-sm) 0;
    font-size: 13px;
    color: var(--gz-text-faint);
}

/* ---------- 21. Category tiles (categories.html) ------------------------ */
.gz-tiles {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--gz-gap);
    margin-top: 16px;
}
@media (min-width: 560px) { .gz-tiles { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 860px) { .gz-tiles { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; } }

.gz-tile {
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-height: 108px;
    padding: 16px;
    border: 1px solid var(--gz-line-soft);
    border-radius: var(--gz-r);
    background: var(--gz-surface);
    transition: border-color .15s ease, background-color .15s ease, transform .15s ease;
}
.gz-tile:hover {
    border-color: var(--gz-accent);
    background: var(--gz-surface-2);
    transform: translateY(-2px);
}
.gz-tile-icon { width: 26px; height: 26px; color: var(--gz-accent-hi); }
.gz-tile-name { font-size: 15px; font-weight: 700; }
.gz-tile-count {
    margin-top: auto;
    color: var(--gz-text-faint);
    font-size: 12.5px;
    font-weight: 600;
}
.gz-tile-empty { opacity: .55; }
@media (prefers-reduced-motion: reduce) {
    .gz-tile, .gz-tile:hover, .gz-card:hover { transform: none; }
}

/* ---------- 22. Empty state (refined) ---------------------------------- */
.gz-empty {
    margin-top: 18px;
    padding: 34px 20px;
}
.gz-empty-icon { width: 34px; height: 34px; margin: 0 auto 12px; color: var(--gz-text-faint); }
.gz-empty h2 { margin: 0 0 6px; color: var(--gz-text); font-size: 16px; font-weight: 700; }
.gz-empty p { margin: 0 0 16px; font-size: 14px; }
.gz-empty-actions { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; }
