/* ============================================================================
   Barlin Games — public Game Directory UI system
   ----------------------------------------------------------------------------
   Loaded only by the public game pages, via @push('styles').

   WHY THIS FILE EXISTS
   The game pages previously borrowed class names from article.css. Two of them
   collided badly — `.ba-body` is that sheet's <body> rule and `.ba-main` is its
   page-main rule — so the game page's layout containers were being handed
   document-level styling and the two-column grid never applied. Another seven
   (.ba-sec, .ba-side, .ba-sidecard, .ba-chip, .ba-chips, .ba-cards, .ba-prose)
   were never defined anywhere, so those elements had no styling at all.

   Everything here is namespaced `gd-` (game directory) and every token is
   redeclared on `.gd`. Nothing in this file can reach an article page, and
   nothing article.css does can reach a game page's layout.

   Articles are untouched: article.css is not edited, imported or overridden.
   ========================================================================== */

/* ── Tokens ─────────────────────────────────────────────────────────────── */

.gd {
    --gd-red:        #E51B23;
    --gd-red-dark:   #C2151C;
    --gd-red-soft:   rgba(229, 27, 35, .08);
    --gd-red-ring:   rgba(229, 27, 35, .18);

    --gd-ink:        #0F1115;
    --gd-body:       #33383F;
    --gd-muted:      #6B7280;
    --gd-faint:      #9CA3AF;

    --gd-canvas:     #F6F7F9;
    --gd-surface:    #FFFFFF;
    --gd-raise:      #FFFFFF;
    --gd-line:       #E7EAF0;
    --gd-line-soft:  #F0F2F6;

    --gd-r-sm:  10px;
    --gd-r:     14px;
    --gd-r-lg:  20px;

    --gd-shadow:    0 1px 2px rgba(16, 18, 24, .04), 0 8px 24px rgba(16, 18, 24, .05);
    --gd-shadow-lg: 0 2px 6px rgba(16, 18, 24, .06), 0 18px 48px rgba(16, 18, 24, .10);

    --gd-ease: cubic-bezier(.22, .61, .36, 1);

    color: var(--gd-body);
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
}

/*
 * Dark mode follows both signals the site already uses: the OS preference and
 * the explicit html.theme-dark toggle. The toggle is listed second so a reader
 * who has chosen light on a dark OS still gets light.
 */
@media (prefers-color-scheme: dark) {
    .gd {
        --gd-ink: #F3F5F8; --gd-body: #C3C8D2; --gd-muted: #8B93A2; --gd-faint: #6B7280;
        --gd-canvas: #0D0F13; --gd-surface: #14171E; --gd-raise: #191D26;
        --gd-line: #242936; --gd-line-soft: #1C212B;
        --gd-red-soft: rgba(229, 27, 35, .14);
        --gd-shadow: 0 1px 2px rgba(0,0,0,.4), 0 8px 24px rgba(0,0,0,.32);
        --gd-shadow-lg: 0 2px 6px rgba(0,0,0,.45), 0 18px 48px rgba(0,0,0,.45);
    }
}
/* The explicit choice, and it must win.
   Matched on an ANCESTOR or on the `.gd` element itself, because the class
   lands in different places depending on the layout: the public layout marks
   <body>, while `layouts.article` deliberately does not — so on those pages the
   `.gd` wrapper carries it (App\Support\ThemeMode). Keyed on `html` as it was
   before, this selector matched neither, and the whole namespace silently fell
   through to the OS preference above: a visitor on a dark OS who had chosen
   light got a light header on a dark page. */
.theme-light .gd, .gd.theme-light {
    --gd-ink: #0F1115; --gd-body: #33383F; --gd-muted: #6B7280; --gd-faint: #9CA3AF;
    --gd-canvas: #F6F7F9; --gd-surface: #FFFFFF; --gd-raise: #FFFFFF;
    --gd-line: #E7EAF0; --gd-line-soft: #F0F2F6;
    --gd-red-soft: rgba(229, 27, 35, .06);
    --gd-shadow: 0 1px 2px rgba(15,17,21,.05), 0 8px 24px rgba(15,17,21,.06);
    --gd-shadow-lg: 0 2px 6px rgba(15,17,21,.06), 0 18px 48px rgba(15,17,21,.10);
}
.theme-dark .gd, .gd.theme-dark {
    --gd-ink: #F3F5F8; --gd-body: #C3C8D2; --gd-muted: #8B93A2; --gd-faint: #6B7280;
    --gd-canvas: #0D0F13; --gd-surface: #14171E; --gd-raise: #191D26;
    --gd-line: #242936; --gd-line-soft: #1C212B;
    --gd-red-soft: rgba(229, 27, 35, .14);
    --gd-shadow: 0 1px 2px rgba(0,0,0,.4), 0 8px 24px rgba(0,0,0,.32);
    --gd-shadow-lg: 0 2px 6px rgba(0,0,0,.45), 0 18px 48px rgba(0,0,0,.45);
}

/* ── Base ───────────────────────────────────────────────────────────────── */

.gd, .gd *, .gd *::before, .gd *::after { box-sizing: border-box; }
/*
 * Zeroed deliberately. layouts/article.blade.php puts `ba-body` on <body>, and
 * article.css declares `.ba-body img { margin: 26px 0 }` for editorial prose.
 * Every image on a game page inherited it — measured live, that put 26px above
 * and 26px below the hero cover inside its own frame, which is the empty band
 * that looked like a broken layout.
 *
 * article.css is owned by Articles and is not edited; this only resets the
 * inherited margin inside `.gd`, and .gd-prose restores it for real prose
 * further down.
 */
.gd img, .gd svg { max-width: 100%; margin: 0; }
.gd a { color: inherit; text-decoration: none; }
.gd h1, .gd h2, .gd h3, .gd h4 { color: var(--gd-ink); margin: 0; letter-spacing: -.017em; }
.gd p { margin: 0; }
.gd .gd-i { flex: 0 0 auto; }

/* Focus is never removed — only restyled, so keyboard users keep a target. */
.gd a:focus-visible,
.gd button:focus-visible,
.gd input:focus-visible,
.gd select:focus-visible,
.gd [tabindex]:focus-visible {
    outline: 2px solid var(--gd-red);
    outline-offset: 2px;
    border-radius: 6px;
}

.gd-page { background: var(--gd-canvas); min-height: 100vh; }
/* Card grids are the content type that benefits most from a large display:
   the wide token lets a directory add COLUMNS rather than widen its cards.
   1280px at 1920 and below, so Full HD is unchanged. */
.gd-wrap { width: 100%; max-width: var(--bg-wrap-wide, 1280px); margin: 0 auto; padding: 0 20px; }
.gd-muted { color: var(--gd-muted); }
.gd-sr {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

@media (prefers-reduced-motion: reduce) {
    .gd *, .gd *::before, .gd *::after {
        animation-duration: .001ms !important;
        transition-duration: .001ms !important;
    }
}

/* ── Header ─────────────────────────────────────────────────────────────── */

.gd-head {
    position: sticky; top: 0; z-index: 60;
    background: color-mix(in srgb, var(--gd-surface) 88%, transparent);
    backdrop-filter: saturate(160%) blur(12px);
    -webkit-backdrop-filter: saturate(160%) blur(12px);
    border-bottom: 1px solid var(--gd-line);
}
.gd-head-in { display: flex; align-items: center; gap: 20px; height: 66px; }

.gd-brand { display: inline-flex; align-items: center; gap: 10px; flex: 0 0 auto; }
.gd-brand img { width: 36px; height: 36px; display: block; }
.gd-brand-tx { display: flex; flex-direction: column; line-height: 1.02; }
.gd-brand-tx b { font-size: 15px; font-weight: 900; letter-spacing: .01em; color: var(--gd-ink); }
.gd-brand-tx i { font-size: 15px; font-weight: 900; font-style: normal; color: var(--gd-red); }

.gd-nav { display: flex; align-items: center; gap: 4px; flex: 1 1 auto; }
.gd-nav a {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 9px 13px; border-radius: 10px;
    font-size: 14px; font-weight: 600; color: var(--gd-muted);
    transition: background .18s var(--gd-ease), color .18s var(--gd-ease);
}
.gd-nav a:hover { background: var(--gd-line-soft); color: var(--gd-ink); }
.gd-nav a.is-on { color: var(--gd-red); background: var(--gd-red-soft); }

.gd-search { position: relative; flex: 0 1 300px; display: flex; align-items: center; }
.gd-search .gd-i { position: absolute; left: 12px; color: var(--gd-faint); pointer-events: none; }
.gd-search input {
    width: 100%; height: 40px; padding: 0 14px 0 36px;
    border: 1px solid var(--gd-line); border-radius: 999px;
    background: var(--gd-canvas); color: var(--gd-ink);
    font-family: inherit; font-size: 14px;
    transition: border-color .18s var(--gd-ease), box-shadow .18s var(--gd-ease);
}
.gd-search input::placeholder { color: var(--gd-faint); }
.gd-search input:focus {
    outline: none; border-color: var(--gd-red);
    box-shadow: 0 0 0 4px var(--gd-red-ring);
}

.gd-burger {
    display: none; width: 40px; height: 40px; align-items: center; justify-content: center;
    border: 1px solid var(--gd-line); border-radius: 10px;
    background: var(--gd-surface); color: var(--gd-ink); cursor: pointer;
}

/* ── Buttons ────────────────────────────────────────────────────────────── */

.gd-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    padding: 11px 18px; border-radius: 12px; border: 1px solid var(--gd-line);
    background: var(--gd-surface); color: var(--gd-ink);
    font-family: inherit; font-size: 14px; font-weight: 700; line-height: 1;
    cursor: pointer; white-space: nowrap;
    transition: transform .16s var(--gd-ease), border-color .16s var(--gd-ease),
                background .16s var(--gd-ease), box-shadow .16s var(--gd-ease);
}
.gd-btn:hover { border-color: var(--gd-red); color: var(--gd-red); transform: translateY(-1px); }
.gd-btn:active { transform: translateY(0); }

.gd-btn-primary {
    background: var(--gd-red); border-color: var(--gd-red); color: #fff;
    box-shadow: 0 6px 18px rgba(229, 27, 35, .28);
}
.gd-btn-primary:hover {
    background: var(--gd-red-dark); border-color: var(--gd-red-dark); color: #fff;
    box-shadow: 0 10px 26px rgba(229, 27, 35, .34);
}
.gd-btn-ghost { background: transparent; }
.gd-btn-sm { padding: 8px 13px; font-size: 13px; border-radius: 10px; }
.gd-btn-lg { padding: 14px 24px; font-size: 15px; border-radius: 14px; }
.gd-btn-block { width: 100%; }

/* ── Layout ─────────────────────────────────────────────────────────────── */

.gd-layout {
    display: grid; grid-template-columns: minmax(0, 1fr) 348px;
    gap: 26px; align-items: start; padding: 28px 0 72px;
}
.gd-col { display: flex; flex-direction: column; gap: 22px; min-width: 0; }
.gd-rail { position: sticky; top: 86px; }

/* ── Section card ───────────────────────────────────────────────────────── */

.gd-sec {
    position: relative;
    background: var(--gd-surface); border: 1px solid var(--gd-line);
    border-radius: var(--gd-r-lg); box-shadow: var(--gd-shadow);
    overflow: hidden;
    scroll-margin-top: 132px;
}

/*
 * A one-pixel highlight along the top edge. It is what stops a stack of these
 * from reading as a spreadsheet: the card catches light at its top like a
 * physical surface would, which is most of the difference between "card" and
 * "bordered box".
 */
.gd-sec::before {
    content: ''; position: absolute; inset: 0 0 auto; height: 1px;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .7) 22%, rgba(255, 255, 255, .7) 78%, transparent);
    opacity: .8; pointer-events: none; z-index: 1;
}
@media (prefers-color-scheme: dark) {
    .gd-sec::before { background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .09) 30%, rgba(255, 255, 255, .09) 70%, transparent); }
}
html.theme-dark .gd-sec::before { background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .09) 30%, rgba(255, 255, 255, .09) 70%, transparent); }
html.theme-light .gd-sec::before { background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .7) 22%, rgba(255, 255, 255, .7) 78%, transparent); }

.gd-sec-h {
    display: flex; align-items: center; gap: 11px;
    padding: 18px 22px; border-bottom: 1px solid var(--gd-line-soft);
    background: linear-gradient(180deg, var(--gd-line-soft) 0%, transparent 100%);
}
.gd-sec-h h2 { font-size: 16px; font-weight: 800; }
.gd-sec-h .gd-sec-ic {
    display: grid; place-items: center; width: 32px; height: 32px; flex: 0 0 32px;
    border-radius: 9px; background: var(--gd-red-soft); color: var(--gd-red);
}
.gd-sec-h .gd-sec-n {
    margin-left: auto; font-size: 12px; font-weight: 800; color: var(--gd-muted);
    background: var(--gd-line-soft); padding: 4px 10px; border-radius: 999px;
}
.gd-sec-b { padding: 22px; }
.gd-sec-b.is-flush { padding: 0; }

/*
 * Plain variant: a section that carries its own <h2> instead of a header bar.
 * Used where the heading is the only chrome the section needs, so the markup
 * stays a <section> with a heading and content rather than three nested divs.
 */
.gd-sec--plain { padding: 22px; }
.gd-sec--plain > h2 {
    display: flex; align-items: center; gap: 10px;
    font-size: 17px; font-weight: 800; margin-bottom: 16px;
}
.gd-sec--plain > h2::before {
    content: ''; width: 3px; height: 18px; border-radius: 2px;
    background: var(--gd-red); flex: 0 0 3px;
}
.gd-sec--plain > h3 { font-size: 14px; font-weight: 800; margin: 20px 0 10px; color: var(--gd-muted); }

/* ── Card grid (games, related, franchise entries) ──────────────────────── */

.gd-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); gap: 16px; }
.gd-tile { display: flex; flex-direction: column; gap: 9px; min-width: 0; }
.gd-tile .gd-cover { box-shadow: var(--gd-shadow); transition: transform .28s var(--gd-ease), box-shadow .28s var(--gd-ease); }
.gd-tile:hover .gd-cover { transform: translateY(-4px); box-shadow: var(--gd-shadow-lg); }
.gd-tile .gd-cover img { transition: transform .5s var(--gd-ease); }
.gd-tile:hover .gd-cover img { transform: scale(1.05); }
.gd-tile-t { font-size: 14.5px; font-weight: 750; color: var(--gd-ink); line-height: 1.35; }
.gd-tile:hover .gd-tile-t { color: var(--gd-red); }
.gd-tile-m { display: block; font-size: 12px; color: var(--gd-muted); font-weight: 600; }

/*
 * Tiles that carry a plain <img> rather than the <x-cover> component. Same
 * frame and the same hover, so the two forms are indistinguishable on screen
 * while the markup is migrated section by section.
 */
.gd-tile-img {
    width: 100%; aspect-ratio: 3 / 4; object-fit: cover; display: block;
    border-radius: var(--gd-r); border: 1px solid var(--gd-line);
    background: var(--gd-line-soft); box-shadow: var(--gd-shadow);
    transition: transform .5s var(--gd-ease), box-shadow .28s var(--gd-ease);
}
.gd-tile:hover .gd-tile-img { box-shadow: var(--gd-shadow-lg); transform: scale(1.03); }
.gd-tile-b { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.gd-tile-b b { font-size: 14.5px; font-weight: 750; color: var(--gd-ink); line-height: 1.35; }
.gd-tile:hover .gd-tile-b b { color: var(--gd-red); }

.gd-pager { margin-top: 26px; display: flex; justify-content: center; }

/*
 * Cover component used inside frames the older sheets own — the directory
 * card's .bg-card-media and the detail hero's .ba-game-cover. It fills its
 * parent rather than imposing its own box, so those frames keep deciding the
 * size and this only decides what is drawn inside.
 */
.gd-card-cover { position: absolute; inset: 0; aspect-ratio: auto !important; border-radius: inherit; }
.gd-card-cover img, .gd-card-cover .gd-cover-fb { border-radius: inherit; }

.gd-hero-cover {
    width: 220px; aspect-ratio: 3 / 4; border-radius: var(--gd-r);
    box-shadow: 0 14px 38px rgba(0, 0, 0, .22);
}
.gd-tile-cover {
    border-radius: var(--gd-r); border: 1px solid var(--gd-line);
    box-shadow: var(--gd-shadow); transition: transform .28s var(--gd-ease), box-shadow .28s var(--gd-ease);
}
.gd-tile:hover .gd-tile-cover { transform: translateY(-3px); box-shadow: var(--gd-shadow-lg); }
.gd-tile-cover img { transition: transform .5s var(--gd-ease); }
.gd-tile:hover .gd-tile-cover img { transform: scale(1.05); }

@media (max-width: 900px) { .gd-hero-cover { width: 168px; } }
.gd-tile-badge {
    position: absolute; top: 9px; left: 9px; z-index: 2;
    padding: 4px 9px; border-radius: 999px;
    background: rgba(15, 17, 21, .72); backdrop-filter: blur(6px);
    color: #fff; font-size: 11px; font-weight: 800; letter-spacing: .02em;
}
.gd-tile-score {
    position: absolute; top: 9px; right: 9px; z-index: 2;
    display: inline-flex; align-items: center; gap: 4px;
    padding: 4px 9px; border-radius: 999px;
    background: var(--gd-red); color: #fff; font-size: 12px; font-weight: 800;
}

@media (max-width: 560px) {
    .gd-grid { grid-template-columns: repeat(auto-fill, minmax(136px, 1fr)); gap: 12px; }
    .gd-sec--plain { padding: 16px; }
}

/* A compact rail card — same family, lighter weight. */
.gd-rcard {
    background: var(--gd-surface); border: 1px solid var(--gd-line);
    border-radius: var(--gd-r); box-shadow: var(--gd-shadow); overflow: hidden;
}
.gd-rcard-h {
    display: flex; align-items: center; gap: 9px; padding: 14px 16px;
    border-bottom: 1px solid var(--gd-line-soft);
    background: linear-gradient(180deg, var(--gd-line-soft) 0%, transparent 100%);
}
.gd-rcard-h > .gd-i { color: var(--gd-red); }
.gd-rcard-h h2, .gd-rcard-h h3 {
    font-size: 12px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em;
    color: var(--gd-muted);
}
.gd-rcard-b { padding: 16px; }

/* ── Chips ──────────────────────────────────────────────────────────────── */

.gd-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.gd-chip {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 7px 13px; border-radius: 999px;
    border: 1px solid var(--gd-line); background: var(--gd-surface);
    font-size: 13px; font-weight: 650; color: var(--gd-body);
    transition: border-color .16s var(--gd-ease), color .16s var(--gd-ease),
                background .16s var(--gd-ease), transform .16s var(--gd-ease);
}
a.gd-chip:hover {
    border-color: var(--gd-red); color: var(--gd-red);
    background: var(--gd-red-soft); transform: translateY(-1px);
}
.gd-chip-solid { background: var(--gd-red); border-color: var(--gd-red); color: #fff; }
.gd-chip-quiet { background: var(--gd-line-soft); border-color: transparent; color: var(--gd-muted); }

/* ── Stat tiles ─────────────────────────────────────────────────────────── */

.gd-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 14px; }
.gd-stat {
    display: flex; align-items: center; gap: 13px; padding: 16px 18px;
    background: var(--gd-surface); border: 1px solid var(--gd-line);
    border-radius: var(--gd-r); box-shadow: var(--gd-shadow);
    transition: transform .18s var(--gd-ease), box-shadow .18s var(--gd-ease);
}
.gd-stat:hover { transform: translateY(-2px); box-shadow: var(--gd-shadow-lg); }
.gd-stat-ic {
    display: grid; place-items: center; width: 42px; height: 42px; flex: 0 0 42px;
    border-radius: 12px; background: var(--gd-red-soft); color: var(--gd-red);
}
.gd-stat b { display: block; font-size: 20px; font-weight: 900; color: var(--gd-ink); line-height: 1.1; }
.gd-stat span { display: block; margin-top: 2px; font-size: 12px; font-weight: 600; color: var(--gd-muted); }

/* ── Spec list (label / value rows) ─────────────────────────────────────── */

.gd-specs { display: flex; flex-direction: column; }
.gd-spec {
    display: flex; align-items: flex-start; gap: 12px;
    padding: 11px 0; border-top: 1px solid var(--gd-line-soft);
}
.gd-spec:first-child { border-top: 0; padding-top: 0; }
.gd-spec:last-child { padding-bottom: 0; }
.gd-spec-k {
    display: inline-flex; align-items: center; gap: 8px; flex: 0 0 auto; min-width: 132px;
    font-size: 13px; font-weight: 600; color: var(--gd-muted);
}
.gd-spec-k .gd-i { color: var(--gd-faint); }
.gd-spec-v {
    flex: 1 1 auto; min-width: 0; text-align: right;
    font-size: 13.5px; font-weight: 700; color: var(--gd-ink);
}
.gd-spec-v a:hover { color: var(--gd-red); }

/* ── Cover art + branded fallback ───────────────────────────────────────── */

.gd-cover { position: relative; display: block; overflow: hidden; border-radius: var(--gd-r); background: var(--gd-line-soft); }
.gd-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }

/*
 * The fallback when a game has no cover. A branded gradient tile with the
 * title's initial — deliberately not the site-wide no-thumb.svg, which is a
 * grey camera glyph and reads as a broken image on a game card.
 */
.gd-cover-fb {
    position: relative; display: grid; place-items: center;
    width: 100%; height: 100%;
    background:
        radial-gradient(120% 100% at 18% 0%, rgba(229, 27, 35, .30) 0%, transparent 58%),
        linear-gradient(150deg, #1B1F2A 0%, #0E1116 100%);
    color: #fff; overflow: hidden;
}
.gd-cover-fb::after {
    content: ''; position: absolute; inset: 0;
    background-image:
        linear-gradient(rgba(255,255,255,.045) 1px, transparent 1px),
        linear-gradient(90deg, rgba(255,255,255,.045) 1px, transparent 1px);
    background-size: 22px 22px;
    mask-image: radial-gradient(80% 70% at 50% 40%, #000 25%, transparent 100%);
    -webkit-mask-image: radial-gradient(80% 70% at 50% 40%, #000 25%, transparent 100%);
}
.gd-cover-fb-in { position: relative; z-index: 1; display: grid; place-items: center; gap: 8px; text-align: center; padding: 12px; }
.gd-cover-fb-mono {
    font-size: clamp(28px, 22cqw, 64px); font-weight: 900; letter-spacing: -.04em;
    line-height: 1; color: #fff;
}
.gd-cover-fb-lb {
    font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .14em;
    color: rgba(255, 255, 255, .55);
}
.gd-cover-fb .gd-i { color: rgba(255, 255, 255, .5); }

/* ── Prose ──────────────────────────────────────────────────────────────── */

.gd-prose { color: var(--gd-body); font-size: 15.5px; line-height: 1.75; max-width: 72ch; }
.gd-prose > * + * { margin-top: 1.05em; }
.gd-prose h2 { font-size: 20px; font-weight: 800; margin-top: 1.6em; }
.gd-prose h3 { font-size: 17px; font-weight: 800; margin-top: 1.4em; }
.gd-prose a { color: var(--gd-red); font-weight: 600; text-decoration: underline; text-underline-offset: 2px; }
.gd-prose ul, .gd-prose ol { padding-left: 1.35em; }
.gd-prose li + li { margin-top: .4em; }
.gd-prose img { border-radius: var(--gd-r); margin: 1.25em 0; }

/* ── Empty state ────────────────────────────────────────────────────────── */

.gd-empty {
    display: grid; place-items: center; gap: 10px; text-align: center;
    padding: 46px 24px; border: 1px dashed var(--gd-line); border-radius: var(--gd-r);
    color: var(--gd-muted);
}
.gd-empty-ic { display: grid; place-items: center; width: 46px; height: 46px; border-radius: 14px; background: var(--gd-line-soft); color: var(--gd-faint); }
.gd-empty h3 { font-size: 16px; font-weight: 800; }
.gd-empty p { font-size: 14px; max-width: 46ch; }

/* ── Breadcrumbs ────────────────────────────────────────────────────────── */

.gd-crumbs { display: flex; align-items: center; flex-wrap: wrap; gap: 7px; font-size: 13px; color: var(--gd-muted); }
/* Padded to a usable tap size on touch. The trail sits inline in text, so the
   padding is negated horizontally — the words stay where they read, only the
   hit area grows. */
.gd-crumbs a {
    font-weight: 600;
    display: inline-block;
    padding: 6px 4px; margin: -6px -4px;
}
.gd-crumbs a:hover { color: var(--gd-red); }
.gd-crumbs .gd-i { color: var(--gd-faint); }
.gd-crumbs [aria-current] { color: var(--gd-ink); font-weight: 700; }

/* ── Preview bar (admin previewing a draft) ─────────────────────────────── */

.gd-preview {
    display: flex; align-items: center; justify-content: center; gap: 9px;
    padding: 11px 18px; background: #FFF4E5; border-bottom: 1px solid #F3CD93;
    color: #8A5300; font-size: 13px; font-weight: 700;
}
html.theme-dark .gd-preview { background: #2A1F0C; border-bottom-color: #4A3712; color: #F0C070; }

/* ── Footer ─────────────────────────────────────────────────────────────── */

.gd-foot { border-top: 1px solid var(--gd-line); background: var(--gd-surface); margin-top: 40px; }
.gd-foot-in {
    display: grid; grid-template-columns: minmax(240px, 1.4fr) repeat(auto-fit, minmax(150px, 1fr));
    gap: 34px; padding: 42px 0 30px;
}
.gd-foot-brand p { margin-top: 12px; font-size: 14px; color: var(--gd-muted); max-width: 40ch; line-height: 1.6; }
.gd-foot-col h2 { font-size: 12px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; color: var(--gd-muted); margin-bottom: 12px; }
.gd-foot-col a { display: block; padding: 5px 0; font-size: 14px; color: var(--gd-body); font-weight: 550; }
.gd-foot-col a:hover { color: var(--gd-red); }
.gd-foot-social { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.gd-foot-social a {
    display: inline-flex; align-items: center; justify-content: center;
    width: 38px; height: 38px; border-radius: 11px;
    border: 1px solid var(--gd-line); color: var(--gd-muted);
    transition: .16s var(--gd-ease);
}
.gd-foot-social a:hover { border-color: var(--gd-red); color: var(--gd-red); transform: translateY(-2px); }
.gd-foot-base {
    display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap;
    padding: 18px 0 30px; border-top: 1px solid var(--gd-line-soft);
    font-size: 13px; color: var(--gd-muted);
}

/* ── Responsive ─────────────────────────────────────────────────────────── */

@media (max-width: 1080px) {
    .gd-layout { grid-template-columns: minmax(0, 1fr); }
    .gd-rail { position: static; }
}

@media (max-width: 860px) {
    .gd-head-in { height: 60px; gap: 12px; }
    .gd-burger { display: inline-flex; }
    .gd-search { display: none; }

    /* The nav becomes a horizontal scroller rather than a hamburger drawer:
       four links do not justify a JS menu, and a scroller keeps them reachable
       in one tap. */
    .gd-nav {
        order: 3; width: 100%; overflow-x: auto; padding: 0 0 10px;
        scrollbar-width: none; -webkit-overflow-scrolling: touch;
    }
    .gd-nav::-webkit-scrollbar { display: none; }
    .gd-head-in { flex-wrap: wrap; height: auto; padding-top: 12px; }
    .gd-burger { display: none; }
}

@media (max-width: 560px) {
    .gd-wrap { padding: 0 14px; }
    .gd-sec-h { padding: 15px 16px; }
    .gd-sec-b { padding: 16px; }
    .gd-layout { padding: 18px 0 52px; gap: 18px; }
    .gd-col { gap: 16px; }
    .gd-spec { flex-direction: column; gap: 3px; }
    .gd-spec-v { text-align: left; }
    .gd-foot-in { grid-template-columns: 1fr; gap: 26px; padding: 32px 0 22px; }
}

/* ============================================================================
   GAME DETAIL PAGE
   ----------------------------------------------------------------------------
   Everything below is specific to /games/{slug}. Kept in the same sheet because
   the detail page is where most of the system's components are actually used,
   and a second request would cost more than the bytes save.

   THE STAGE
   The hero is a dark cinematic stage in both of its states. With artwork it is
   the art, scaled and scrimmed. Without artwork it is a designed brand surface
   — gradient, glow and a faint grid — never a stand-in screenshot and never a
   flat white band. Both states share one layout, so uploading art changes what
   the hero looks like and nothing about how it is built.

   Children inside the stage read the --gd-onstage-* tokens declared on it,
   rather than each needing a `.gd-stage .thing` colour override. That is what
   keeps this section short despite the stage carrying a full second palette.
   ========================================================================== */

/* ── Cinematic stage ────────────────────────────────────────────────────── */

.gd-stage {
    position: relative; isolation: isolate; overflow: hidden;
    background: #0A0C11;
    border-bottom: 1px solid rgba(255, 255, 255, .07);

    /* The on-dark palette. Everything inside the stage uses these. */
    --gd-onstage:      #FFFFFF;
    --gd-onstage-soft: rgba(255, 255, 255, .76);
    --gd-onstage-dim:  rgba(255, 255, 255, .56);
    --gd-onstage-line: rgba(255, 255, 255, .14);
    --gd-onstage-fill: rgba(255, 255, 255, .07);
    --gd-red-lit:      #FF5157;

    color: var(--gd-onstage-soft);
}

/*
 * The artwork itself. Decorative — every fact it carries also appears as text
 * below it — so it is rendered with an empty alt behind two scrim layers that
 * hold the foreground readable no matter how bright the art is.
 */
.gd-stage-art { position: absolute; inset: 0; z-index: -3; }
.gd-stage-art img {
    width: 100%; height: 100%; object-fit: cover; display: block;
    transform: scale(1.06); filter: saturate(1.12) contrast(1.02);
}

/* Readability scrim: heavy at the left where the copy sits, light at the
   right so the art still reads as art. */
.gd-stage::before {
    content: ''; position: absolute; inset: 0; z-index: -2; pointer-events: none;
    background:
        linear-gradient(102deg, rgba(8, 10, 14, .95) 0%, rgba(8, 10, 14, .84) 34%, rgba(8, 10, 14, .44) 66%, rgba(8, 10, 14, .70) 100%),
        linear-gradient(180deg, rgba(8, 10, 14, .74) 0%, rgba(8, 10, 14, .12) 30%, rgba(8, 10, 14, .90) 100%);
}

/* Brand glow and vignette, over the scrim. */
.gd-stage::after {
    content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
    background:
        radial-gradient(68% 88% at 6% -4%, rgba(229, 27, 35, .32) 0%, transparent 58%),
        radial-gradient(46% 66% at 102% 104%, rgba(229, 27, 35, .18) 0%, transparent 60%);
}

/*
 * No artwork. A composed brand surface rather than an empty one: two red
 * washes over a cool gradient, with a faint grid that fades out before it
 * reaches the copy. This is design, not a placeholder image.
 */
.gd-stage.no-art {
    background:
        radial-gradient(88% 118% at 10% -18%, rgba(229, 27, 35, .40) 0%, transparent 56%),
        radial-gradient(66% 88% at 94% 6%, rgba(229, 27, 35, .17) 0%, transparent 58%),
        linear-gradient(158deg, #191E2A 0%, #0E1116 46%, #090B10 100%);
}
.gd-stage.no-art::before {
    background-image:
        linear-gradient(rgba(255, 255, 255, .04) 1px, transparent 1px),
        linear-gradient(90deg, rgba(255, 255, 255, .04) 1px, transparent 1px);
    background-size: 58px 58px, 58px 58px;
    -webkit-mask-image: radial-gradient(126% 104% at 34% 0%, #000 0%, transparent 74%);
            mask-image: radial-gradient(126% 104% at 34% 0%, #000 0%, transparent 74%);
}
.gd-stage.no-art::after { background: radial-gradient(46% 66% at 100% 100%, rgba(229, 27, 35, .16) 0%, transparent 62%); }

.gd-stage-in { position: relative; padding-top: 20px; }

/* Copy on the left, score panel on the right — the reference composition. */
.gd-stage-grid {
    display: grid; grid-template-columns: minmax(0, 1fr) 340px;
    gap: 40px; align-items: start; padding: 20px 0 28px;
}
.gd-stage-main { display: flex; flex-direction: column; gap: 15px; min-width: 0; }

/* Breadcrumbs sit on the dark, so they take the stage palette. */
.gd-stage .gd-crumbs, .gd-stage .gd-crumbs a { color: var(--gd-onstage-dim); }
.gd-stage .gd-crumbs a:hover { color: var(--gd-onstage); }
.gd-stage .gd-crumbs [aria-current] { color: var(--gd-onstage); font-weight: 700; }
.gd-stage .gd-crumbs .gd-i { color: rgba(255, 255, 255, .32); }

/* ── Stage flags ────────────────────────────────────────────────────────── */

/*
 * Every flag on this row is a fact the database holds — a release status, a
 * franchise, an age rating. There is no trending position, no award count and
 * no "featured" ribbon, because nothing in the schema records one.
 */
.gd-flags { display: flex; flex-wrap: wrap; gap: 8px; }
.gd-flag {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 6px 12px; border-radius: 999px;
    font-size: 11.5px; font-weight: 800; letter-spacing: .045em; text-transform: uppercase;
    background: var(--gd-onstage-fill); border: 1px solid var(--gd-onstage-line);
    color: var(--gd-onstage);
    -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
    transition: background .18s var(--gd-ease), border-color .18s var(--gd-ease), transform .18s var(--gd-ease);
}
a.gd-flag:hover { background: rgba(255, 255, 255, .17); border-color: rgba(255, 255, 255, .4); transform: translateY(-1px); }
.gd-flag--red {
    background: linear-gradient(135deg, #FF2A32, var(--gd-red-dark));
    border-color: transparent; box-shadow: 0 6px 20px rgba(229, 27, 35, .38);
}
a.gd-flag--red:hover { background: linear-gradient(135deg, #FF3B43, var(--gd-red)); border-color: transparent; }
.gd-flag .gd-i { opacity: .9; }

/* ── Title block ────────────────────────────────────────────────────────── */

.gd-stage-id { display: grid; grid-template-columns: 170px minmax(0, 1fr); gap: 26px; align-items: end; }

/*
 * The poster floats over the stage rather than sitting in a column of its own,
 * so an artless game does not leave a tall empty gutter beside the copy.
 *
 * The frame takes the ARTWORK's own aspect ratio, not a fixed 3:4.
 *
 * Game covers are not one shape — the one on file here is 941x1672, a tall
 * poster, and forcing it into a 3:4 box gives a choice between cropping the art
 * or letterboxing it. Letterboxing is what produced the empty bands above and
 * below the cover. Overriding the component's inline aspect-ratio and letting
 * the image set its own height removes both problems: nothing is cropped,
 * nothing is padded, and the art meets the frame on every edge.
 *
 * `aspect-ratio: auto` needs !important because the cover component writes its
 * ratio as an inline style, which no class selector can outrank. The same
 * technique is already used by .gd-card-cover below.
 */
.gd-stage-poster {
    width: 170px; aspect-ratio: auto !important;
    border-radius: 16px; background: transparent;
    box-shadow: 0 22px 52px rgba(0, 0, 0, .55);

    /*
     * line-height:0 is load-bearing. The frame is a <span> holding whitespace
     * text nodes around the <img>, so it forms a line box and inherits the
     * page's line-height — measured live, that left the frame 320px tall
     * around a 302px image and produced an 18px band under the cover. Zeroing
     * the line box makes the frame shrink-wrap the artwork exactly.
     */
    line-height: 0; font-size: 0;
}
.gd-stage-poster.gd-cover { background: transparent; }
.gd-stage-poster img {
    width: 100%; height: auto;
    object-fit: contain;
    border-radius: 16px;
    box-shadow: 0 0 0 1px rgba(255, 255, 255, .10);
}
/* The branded monogram fallback has nothing to show through to, so it keeps a
   surface and a poster shape of its own. */
.gd-stage-poster .gd-cover-fb { border-radius: 16px; aspect-ratio: 3 / 4; }

.gd-stage-name { min-width: 0; }
.gd-stage-name h1 {
    font-size: clamp(32px, 5vw, 60px); font-weight: 900;
    letter-spacing: -.034em; line-height: 1.02; color: var(--gd-onstage);
    text-shadow: 0 2px 26px rgba(0, 0, 0, .55);
}
/* The tagline: one editorial line, set directly under the title and above the
   summary. Sized between the two so the three read as a hierarchy rather than
   as three paragraphs. */
/* ── Game Details: structured attribute rows ────────────────────────────────
   A definition list rather than a table: the values are chips of varying width
   and a table would force every row to the widest one. Collapses to stacked
   label-over-values on narrow screens.
   ------------------------------------------------------------------------- */
.gd-attrs { margin: 0; display: flex; flex-direction: column; gap: 2px; }
.gd-attrs-row {
    display: grid; grid-template-columns: 150px minmax(0, 1fr);
    gap: 10px 18px; align-items: baseline;
    padding: 9px 0; border-bottom: 1px solid var(--gd-line, rgba(128,128,128,.16));
}
.gd-attrs-row:last-child { border-bottom: 0; }
.gd-attrs-row dt {
    font-size: 11px; font-weight: 800; text-transform: uppercase;
    letter-spacing: .07em; color: var(--gd-dim, #7b8494);
}
.gd-attrs-row dd { margin: 0; display: flex; flex-wrap: wrap; gap: 6px; }

.gd-attrs-block { margin-top: 22px; }
.gd-attrs-block h3 {
    margin: 0 0 9px; font-size: 12px; font-weight: 800;
    text-transform: uppercase; letter-spacing: .07em; color: var(--gd-dim, #7b8494);
}
.gd-chiprow { display: flex; flex-wrap: wrap; gap: 6px; }
.gd-chip--quiet { opacity: .72; font-weight: 500; }

@media (max-width: 640px) {
    .gd-attrs-row { grid-template-columns: minmax(0, 1fr); gap: 6px; }
}

.gd-stage-tagline {
    margin-top: 12px; font-size: clamp(16px, 1.9vw, 20px); line-height: 1.4;
    max-width: 46ch; font-weight: 600; letter-spacing: -.012em;
    color: var(--gd-onstage-soft);
}

/* "Also known as" / "Formerly". Deliberately quiet — it is reference
   information, not part of the pitch. */
.gd-stage-aka {
    margin-top: 8px; font-size: 13.5px; line-height: 1.55; max-width: 58ch;
    color: var(--gd-onstage-dim);
}
.gd-stage-aka span {
    font-size: 10.5px; font-weight: 800; text-transform: uppercase;
    letter-spacing: .08em; margin-right: 7px;
}

.gd-stage-lede {
    margin-top: 14px; font-size: 16.5px; line-height: 1.65; max-width: 58ch;
    color: var(--gd-onstage-soft);
}

.gd-stage-meta { display: flex; flex-wrap: wrap; gap: 10px 28px; margin: 2px 0; }
.gd-stage-meta > div { display: flex; flex-direction: column; gap: 3px; }
.gd-stage-meta dt {
    font-size: 10.5px; font-weight: 800; text-transform: uppercase;
    letter-spacing: .08em; color: var(--gd-onstage-dim);
}
.gd-stage-meta dd { margin: 0; font-size: 14.5px; font-weight: 750; color: var(--gd-onstage); }
.gd-stage-meta a:hover { color: var(--gd-red-lit); }
.gd-stage-meta .gd-muted { color: var(--gd-onstage-dim); font-weight: 600; }

/* Chips and buttons inherit the stage palette rather than the page one. */
.gd-stage .gd-chip {
    background: var(--gd-onstage-fill); border-color: var(--gd-onstage-line); color: var(--gd-onstage);
    -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}
.gd-stage a.gd-chip:hover {
    background: rgba(255, 255, 255, .18); border-color: rgba(255, 255, 255, .5);
    color: var(--gd-onstage); transform: translateY(-1px);
}

/* ── Platform badges ────────────────────────────────────────────────────── */

.gd-plats-l {
    font-size: 10.5px; font-weight: 800; text-transform: uppercase;
    letter-spacing: .08em; color: var(--gd-onstage-dim); margin-bottom: 8px;
}
.gd-plats { display: flex; flex-wrap: wrap; gap: 8px; }

/*
 * Icon plus the platform's own short label — "PC", "PS5", "Switch". The glyph
 * comes from the family column, so a platform with an unmapped family still
 * gets a badge that names itself.
 */
.gd-plat {
    display: inline-flex; align-items: center; gap: 7px;
    height: 40px; padding: 0 13px; border-radius: 12px;
    background: var(--gd-onstage-fill); border: 1px solid var(--gd-onstage-line);
    color: var(--gd-onstage); font-size: 12.5px; font-weight: 750;
    -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
    transition: background .18s var(--gd-ease), border-color .18s var(--gd-ease), transform .18s var(--gd-ease);
}
.gd-plat:hover { background: rgba(255, 255, 255, .18); border-color: rgba(255, 255, 255, .48); transform: translateY(-2px); }
.gd-plat .gd-i { opacity: .92; }

.gd-stage-cta { display: flex; flex-wrap: wrap; gap: 11px; margin-top: 6px; }
.gd-stage .gd-btn {
    background: var(--gd-onstage-fill); border-color: var(--gd-onstage-line); color: var(--gd-onstage);
    -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}
.gd-stage .gd-btn:hover { background: rgba(255, 255, 255, .18); border-color: rgba(255, 255, 255, .5); color: var(--gd-onstage); }
.gd-stage .gd-btn-primary {
    background: linear-gradient(135deg, #FF2A32, var(--gd-red-dark));
    border-color: transparent; color: #fff;
    box-shadow: 0 12px 32px rgba(229, 27, 35, .44);
}
.gd-stage .gd-btn-primary:hover {
    background: linear-gradient(135deg, #FF3B43, var(--gd-red));
    border-color: transparent; box-shadow: 0 16px 40px rgba(229, 27, 35, .56); transform: translateY(-2px);
}

/* ── Score panel ────────────────────────────────────────────────────────── */

.gd-scorecard {
    position: relative; border-radius: 22px; overflow: hidden;
    background: rgba(255, 255, 255, .065);
    border: 1px solid var(--gd-onstage-line);
    -webkit-backdrop-filter: blur(24px) saturate(1.25); backdrop-filter: blur(24px) saturate(1.25);
    box-shadow: 0 26px 64px rgba(0, 0, 0, .46);
}
.gd-scorecard-h {
    display: flex; align-items: center; gap: 9px; padding: 14px 18px;
    border-bottom: 1px solid var(--gd-onstage-line);
    font-size: 11.5px; font-weight: 800; text-transform: uppercase;
    letter-spacing: .07em; color: var(--gd-onstage-soft);
}
.gd-scorecard-h .gd-i { color: var(--gd-red-lit); }

.gd-bigscore { display: flex; align-items: center; gap: 18px; padding: 20px 18px 16px; }
.gd-bigscore-b { min-width: 0; }
.gd-bigscore-n {
    display: flex; align-items: baseline; gap: 4px;
    font-size: 50px; font-weight: 900; line-height: .92;
    letter-spacing: -.042em; color: var(--gd-onstage);
}
.gd-bigscore-n i { font-size: 17px; font-weight: 800; font-style: normal; color: var(--gd-onstage-dim); }
.gd-bigscore-l { margin-top: 8px; font-size: 12.5px; font-weight: 600; color: var(--gd-onstage-soft); }

.gd-stars { display: flex; gap: 3px; margin-top: 9px; color: var(--gd-red-lit); }
.gd-stars .is-off { color: rgba(255, 255, 255, .2); }

/*
 * A ring drawn straight from the editorial rating — the same number the panel
 * prints beside it, shown a second way. It is not a separate metric and is
 * never rendered without one.
 */
.gd-ring {
    position: relative; flex: 0 0 84px; width: 84px; height: 84px; border-radius: 50%;
    display: grid; place-items: center;
    background: conic-gradient(var(--gd-red-lit) calc(var(--gd-pct) * 1%), rgba(255, 255, 255, .13) 0);
}
.gd-ring::after { content: ''; position: absolute; inset: 7px; border-radius: 50%; background: rgba(11, 14, 19, .88); }
.gd-ring b { position: relative; z-index: 1; font-size: 18px; font-weight: 900; color: var(--gd-onstage); }

/* Critic scores, coloured by the convention those boards themselves use. */
.gd-critics { display: flex; gap: 9px; padding: 0 18px 16px; }
.gd-critic {
    flex: 1 1 0; display: flex; flex-direction: column; gap: 3px;
    padding: 11px 13px; border-radius: 14px;
    background: var(--gd-onstage-fill); border: 1px solid var(--gd-onstage-line);
    transition: background .18s var(--gd-ease), border-color .18s var(--gd-ease);
}
a.gd-critic:hover { background: rgba(255, 255, 255, .16); border-color: rgba(255, 255, 255, .38); }
.gd-critic b { font-size: 19px; font-weight: 900; line-height: 1; color: var(--gd-onstage); }
.gd-critic span {
    font-size: 10px; font-weight: 800; text-transform: uppercase;
    letter-spacing: .07em; color: var(--gd-onstage-dim);
}
.gd-critic.is-high b { color: #4ADE80; }
.gd-critic.is-mid  b { color: #FACC15; }
.gd-critic.is-low  b { color: #F87171; }

.gd-scorestats {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
    gap: 1px; background: var(--gd-onstage-line); border-top: 1px solid var(--gd-onstage-line);
}
.gd-scorestat { display: flex; flex-direction: column; gap: 5px; padding: 14px 16px; background: rgba(10, 12, 17, .42); }
.gd-scorestat .gd-i { color: var(--gd-red-lit); }
.gd-scorestat b { font-size: 19px; font-weight: 900; line-height: 1.05; color: var(--gd-onstage); }
.gd-scorestat span { font-size: 11.5px; font-weight: 650; color: var(--gd-onstage-dim); }

/* ── Media strip, docked to the stage ───────────────────────────────────── */

.gd-strip { position: relative; padding-bottom: 24px; }
.gd-strip-in { display: flex; align-items: center; gap: 11px; }
.gd-strip-rail {
    display: flex; gap: 10px; overflow-x: auto; scroll-behavior: smooth;
    padding: 4px 2px; scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.gd-strip-rail::-webkit-scrollbar { display: none; }

.gd-thumb {
    position: relative; flex: 0 0 162px; aspect-ratio: 16 / 9; height: auto; padding: 0;
    border-radius: 12px; overflow: hidden; cursor: pointer;
    background: #0E1116; border: 1px solid var(--gd-onstage-line);
    transition: transform .22s var(--gd-ease), border-color .22s var(--gd-ease), box-shadow .22s var(--gd-ease);
}
/* Every tile crops the same way, so a 16:9 video poster and a screenshot sit
   at identical proportions instead of one letterboxing beside the other. */
.gd-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.gd-thumb:hover { transform: translateY(-3px); border-color: rgba(255, 255, 255, .55); box-shadow: 0 14px 30px rgba(0, 0, 0, .45); }

/* Videos carry a play badge so the two media kinds are told apart before the
   reader clicks one. */
.gd-thumb-play {
    position: absolute; inset: 0; display: grid; place-items: center;
    background: linear-gradient(180deg, rgba(8, 10, 14, .04), rgba(8, 10, 14, .42));
    color: #fff;
}
.gd-thumb-play span {
    display: grid; place-items: center; width: 38px; height: 38px; border-radius: 50%;
    background: rgba(229, 27, 35, .92); box-shadow: 0 6px 18px rgba(0, 0, 0, .45);
}
.gd-thumb-l {
    position: absolute; left: 8px; bottom: 7px; padding: 3px 8px; border-radius: 7px;
    background: rgba(8, 10, 14, .72); color: #fff;
    font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em;
}

.gd-strip-nav {
    flex: 0 0 auto; display: grid; place-items: center; width: 38px; height: 38px;
    border-radius: 50%; background: var(--gd-onstage-fill);
    border: 1px solid var(--gd-onstage-line); color: var(--gd-onstage);
    -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
    transition: background .18s var(--gd-ease), border-color .18s var(--gd-ease);
}
.gd-strip-nav:hover { background: rgba(255, 255, 255, .2); border-color: rgba(255, 255, 255, .5); }

/*
 * No media. A stated absence, styled — never a row of grey rectangles
 * pretending to be screenshots that have not loaded.
 */
.gd-strip-empty {
    display: flex; align-items: center; gap: 13px;
    padding: 15px 18px; border-radius: 16px;
    border: 1px dashed var(--gd-onstage-line); background: rgba(255, 255, 255, .04);
    color: var(--gd-onstage-soft); font-size: 13.5px; line-height: 1.5;
}
.gd-strip-empty .gd-i { color: var(--gd-onstage-dim); }
.gd-strip-empty b { display: block; color: var(--gd-onstage); font-size: 14px; font-weight: 750; margin-bottom: 2px; }

/* ── Section tab bar ────────────────────────────────────────────────────── */

/*
 * Anchors, not a JS tab widget: every section is on the page and reachable
 * without script, and the bar only marks where you are. It is rendered at all
 * only when there are at least two sections to move between.
 */
.gd-tabs {
    position: sticky; top: 65px; z-index: 20;
    background: color-mix(in srgb, var(--gd-surface) 92%, transparent);
    -webkit-backdrop-filter: saturate(160%) blur(12px); backdrop-filter: saturate(160%) blur(12px);
    border-bottom: 1px solid var(--gd-line);
}
.gd-tabs-in { display: flex; gap: 2px; overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
.gd-tabs-in::-webkit-scrollbar { display: none; }
.gd-tab {
    display: inline-flex; align-items: center; gap: 8px; white-space: nowrap;
    padding: 15px 15px 13px; border-bottom: 2px solid transparent;
    font-size: 14px; font-weight: 700; color: var(--gd-muted);
    transition: color .18s var(--gd-ease), border-color .18s var(--gd-ease);
}
.gd-tab:hover { color: var(--gd-ink); }
.gd-tab.is-on { color: var(--gd-red); border-bottom-color: var(--gd-red); }
.gd-tab-n {
    font-size: 11px; font-weight: 800; padding: 2px 7px; border-radius: 999px;
    background: var(--gd-line-soft); color: var(--gd-muted);
}
.gd-tab.is-on .gd-tab-n { background: var(--gd-red-soft); color: var(--gd-red); }

/* ── Feature cards ──────────────────────────────────────────────────────── */

.gd-feats { display: grid; grid-template-columns: repeat(auto-fit, minmax(214px, 1fr)); gap: 13px; }
.gd-feat {
    position: relative; overflow: hidden;
    display: flex; flex-direction: column; gap: 9px; padding: 18px;
    border-radius: 16px; border: 1px solid var(--gd-line);
    background: linear-gradient(158deg, var(--gd-line-soft) 0%, var(--gd-surface) 62%);
    transition: transform .24s var(--gd-ease), box-shadow .24s var(--gd-ease), border-color .24s var(--gd-ease);
}
.gd-feat::after {
    content: ''; position: absolute; right: -36px; bottom: -46px;
    width: 128px; height: 128px; border-radius: 50%;
    background: var(--gd-red-soft); opacity: 0;
    transition: opacity .3s var(--gd-ease); pointer-events: none;
}
.gd-feat:hover { transform: translateY(-3px); box-shadow: var(--gd-shadow-lg); border-color: var(--gd-red-ring); }
.gd-feat:hover::after { opacity: 1; }
.gd-feat > * { position: relative; z-index: 1; }
.gd-feat-ic {
    display: grid; place-items: center; width: 38px; height: 38px; border-radius: 12px;
    background: linear-gradient(140deg, var(--gd-red), var(--gd-red-dark)); color: #fff;
    box-shadow: 0 6px 16px rgba(229, 27, 35, .3);
}
.gd-feat b { font-size: 14.5px; font-weight: 750; color: var(--gd-ink); }
.gd-feat p { font-size: 13px; line-height: 1.55; color: var(--gd-muted); }

/* ── Screenshots ────────────────────────────────────────────────────────── */

.gd-shots { display: grid; gap: 12px; }
.gd-shots-lead {
    position: relative; padding: 0; border-radius: var(--gd-r); overflow: hidden;
    border: 1px solid var(--gd-line); cursor: pointer;
}
.gd-shots-lead img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; display: block; transition: transform .6s var(--gd-ease); }
.gd-shots-lead:hover img { transform: scale(1.03); }
.gd-shots-rest { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }
.gd-shot {
    position: relative; padding: 0; border-radius: var(--gd-r-sm); overflow: hidden;
    border: 1px solid var(--gd-line); cursor: pointer; background: var(--gd-line-soft);
}
.gd-shot img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; display: block; transition: transform .5s var(--gd-ease); }
.gd-shot:hover img { transform: scale(1.06); }
.gd-shot::after {
    content: ''; position: absolute; inset: 0; background: transparent;
    transition: background .22s var(--gd-ease);
}
.gd-shot:hover::after { background: rgba(9, 11, 15, .16); }

/* ── Lightbox ───────────────────────────────────────────────────────────── */

.gd-lb[hidden] { display: none; }
.gd-lb {
    position: fixed; inset: 0; z-index: 200;
    display: grid; place-items: center; padding: 40px;
    background: rgba(6, 8, 12, .93);
    -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}
.gd-lb-fig { margin: 0; max-width: min(1200px, 94vw); display: flex; flex-direction: column; gap: 12px; }
.gd-lb-fig img { max-width: 100%; max-height: 78vh; object-fit: contain; border-radius: var(--gd-r); display: block; margin: 0 auto; }
/* `display: block` above outranks the [hidden] attribute's UA rule, so without
   this the still frame stays on screen behind a video — with an empty src, which
   the browser renders as a broken-image icon. */
.gd-lb-fig img[hidden], .gd-lb-video[hidden] { display: none; }
.gd-lb-cap { color: rgba(255, 255, 255, .78); font-size: 13.5px; text-align: center; }
.gd-lb-count { color: rgba(255, 255, 255, .5); font-size: 12px; font-weight: 700; }
.gd-lb-btn {
    position: absolute; top: 50%; transform: translateY(-50%);
    display: grid; place-items: center; width: 46px; height: 46px; border-radius: 50%;
    background: rgba(255, 255, 255, .12); border: 1px solid rgba(255, 255, 255, .2); color: #fff;
    transition: background .18s var(--gd-ease);
}
.gd-lb-btn:hover { background: rgba(255, 255, 255, .24); }
.gd-lb-prev { left: 18px; }
.gd-lb-next { right: 18px; }
.gd-lb-close { position: absolute; top: 18px; right: 18px; transform: none; }

/* Video player frame, used when a trailer URL resolves to an embeddable host. */
.gd-lb-video { width: min(1100px, 92vw); aspect-ratio: 16 / 9; border-radius: var(--gd-r); overflow: hidden; background: #000; }
.gd-lb-video iframe { width: 100%; height: 100%; border: 0; display: block; }

/* ── Where to buy ───────────────────────────────────────────────────────── */

.gd-buys { display: grid; gap: 11px; }
.gd-buy {
    display: flex; align-items: center; gap: 14px; padding: 15px 17px;
    border-radius: 16px; border: 1px solid var(--gd-line);
    background: linear-gradient(150deg, var(--gd-line-soft) 0%, var(--gd-surface) 58%);
    transition: transform .2s var(--gd-ease), border-color .2s var(--gd-ease), box-shadow .2s var(--gd-ease);
}
.gd-buy:hover { transform: translateY(-2px); border-color: var(--gd-red-ring); box-shadow: var(--gd-shadow-lg); }
.gd-buy.is-gone { opacity: .58; }
.gd-buy.is-gone:hover { transform: none; border-color: var(--gd-line); box-shadow: none; }
.gd-buy-ic {
    display: grid; place-items: center; width: 44px; height: 44px; flex: 0 0 44px;
    border-radius: 13px; background: var(--gd-surface); border: 1px solid var(--gd-line);
    color: var(--gd-muted); overflow: hidden;
}
.gd-buy-ic img { width: 100%; height: 100%; object-fit: contain; }
.gd-buy-b { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.gd-buy-b b { font-size: 15px; font-weight: 750; color: var(--gd-ink); }
.gd-buy-m { display: flex; flex-wrap: wrap; gap: 6px; font-size: 12px; color: var(--gd-muted); }
.gd-buy-m span { display: inline-flex; align-items: center; gap: 4px; }
.gd-buy-m span + span::before { content: '·'; margin-right: 5px; color: var(--gd-faint); }
.gd-buy-p { flex: 0 0 auto; text-align: right; display: flex; flex-direction: column; align-items: flex-end; gap: 2px; }
.gd-buy-p b { font-size: 18px; font-weight: 850; color: var(--gd-ink); white-space: nowrap; }
.gd-buy-was { font-size: 12.5px; color: var(--gd-faint); text-decoration: line-through; }
.gd-buy-off { display: inline-block; padding: 2px 7px; border-radius: 6px; background: #16A34A; color: #fff; font-size: 11px; font-weight: 800; }
.gd-buy-tag { font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .05em; color: var(--gd-muted); }

/* ── Credits, companies and people ──────────────────────────────────────── */

.gd-credits { display: grid; grid-template-columns: repeat(auto-fill, minmax(238px, 1fr)); gap: 12px; }
.gd-credit {
    display: flex; align-items: center; gap: 13px; padding: 13px 15px;
    border-radius: 15px; border: 1px solid var(--gd-line);
    background: linear-gradient(150deg, var(--gd-line-soft) 0%, var(--gd-surface) 58%);
    transition: transform .2s var(--gd-ease), border-color .2s var(--gd-ease), box-shadow .2s var(--gd-ease);
}
a.gd-credit:hover { transform: translateY(-2px); border-color: var(--gd-red-ring); box-shadow: var(--gd-shadow-lg); }
.gd-credit-av {
    display: grid; place-items: center; width: 44px; height: 44px; flex: 0 0 44px;
    border-radius: 13px; overflow: hidden;
    background: var(--gd-surface); border: 1px solid var(--gd-line);
    font-size: 16px; font-weight: 850; color: var(--gd-muted);
}
.gd-credit-av.is-round { border-radius: 50%; }
.gd-credit-av img { width: 100%; height: 100%; object-fit: cover; }
.gd-credit-b { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.gd-credit-b b { font-size: 14.5px; font-weight: 750; color: var(--gd-ink); }
a.gd-credit:hover .gd-credit-b b { color: var(--gd-red); }
.gd-credit-b span { font-size: 12.5px; color: var(--gd-muted); }

.gd-rolegrp + .gd-rolegrp { margin-top: 22px; }
.gd-rolegrp > h3 {
    display: flex; align-items: center; gap: 9px; margin-bottom: 11px;
    font-size: 12px; font-weight: 800; text-transform: uppercase;
    letter-spacing: .07em; color: var(--gd-muted);
}
.gd-rolegrp > h3::before { content: ''; width: 3px; height: 13px; border-radius: 2px; background: var(--gd-red); flex: 0 0 3px; }

/* ── Rating boards ──────────────────────────────────────────────────────── */

.gd-boards { display: flex; flex-wrap: wrap; gap: 9px; }
.gd-board {
    display: flex; flex-direction: column; gap: 3px; padding: 10px 13px;
    border-radius: 12px; border: 1px solid var(--gd-line); background: var(--gd-line-soft);
}
a.gd-board:hover { border-color: var(--gd-red-ring); background: var(--gd-red-soft); }
.gd-board b { font-size: 16px; font-weight: 850; color: var(--gd-ink); line-height: 1.15; }
.gd-board span { font-size: 10.5px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; color: var(--gd-muted); }

.gd-verdict {
    display: flex; align-items: center; gap: 15px; margin-bottom: 14px; padding: 15px;
    border-radius: 15px; background: var(--gd-red-soft); border: 1px solid var(--gd-red-ring);
}
.gd-verdict-n { font-size: 32px; font-weight: 900; color: var(--gd-red); line-height: 1; }
.gd-verdict-b b { display: block; font-size: 14px; font-weight: 800; color: var(--gd-ink); }
.gd-verdict-b span { font-size: 12.5px; color: var(--gd-muted); }

/* ── Language matrix ────────────────────────────────────────────────────── */

.gd-langs { width: 100%; border-collapse: collapse; font-size: 14px; }
.gd-langs th, .gd-langs td { padding: 10px 12px; text-align: left; border-bottom: 1px solid var(--gd-line-soft); }
.gd-langs thead th {
    font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em;
    color: var(--gd-muted); background: var(--gd-line-soft);
}
.gd-langs th:not(:first-child), .gd-langs td:not(:first-child) { text-align: center; width: 108px; }
.gd-langs tbody tr:last-child td, .gd-langs tbody tr:last-child th { border-bottom: 0; }
.gd-langs tbody tr:hover { background: var(--gd-line-soft); }
.gd-langs td:first-child { font-weight: 650; color: var(--gd-ink); }
.gd-yes { color: #16A34A; }
.gd-no { color: var(--gd-faint); }

/* ── System requirements ────────────────────────────────────────────────── */

.gd-reqs { display: grid; grid-template-columns: repeat(auto-fit, minmax(258px, 1fr)); gap: 14px; }
.gd-req { border: 1px solid var(--gd-line); border-radius: var(--gd-r); overflow: hidden; }
.gd-req > h3 {
    padding: 12px 16px; font-size: 12px; font-weight: 800; text-transform: uppercase;
    letter-spacing: .06em; color: var(--gd-muted); background: var(--gd-line-soft);
    border-bottom: 1px solid var(--gd-line);
}
.gd-req.is-rec > h3 { color: var(--gd-red); background: var(--gd-red-soft); }
.gd-req .gd-specs { padding: 14px 16px; }

/* ── Video cards ────────────────────────────────────────────────────────── */

.gd-videos { display: grid; grid-template-columns: repeat(auto-fit, minmax(262px, 1fr)); gap: 14px; }
.gd-video {
    position: relative; display: block; padding: 0; overflow: hidden;
    border-radius: 16px; border: 1px solid var(--gd-line); background: var(--gd-line-soft);
    cursor: pointer; text-align: left;
    transition: transform .22s var(--gd-ease), border-color .22s var(--gd-ease), box-shadow .22s var(--gd-ease);
}
.gd-video:hover { transform: translateY(-3px); border-color: var(--gd-red-ring); box-shadow: var(--gd-shadow-lg); }
.gd-video-poster { position: relative; display: block; aspect-ratio: 16 / 9; background: #0E1116; }
.gd-video-poster img { width: 100%; height: 100%; object-fit: cover; display: block; }
.gd-video-play {
    position: absolute; inset: 0; display: grid; place-items: center;
    background: linear-gradient(180deg, rgba(8, 10, 14, .1), rgba(8, 10, 14, .5));
}
.gd-video-play span {
    display: grid; place-items: center; width: 52px; height: 52px; border-radius: 50%;
    background: rgba(229, 27, 35, .94); color: #fff; box-shadow: 0 10px 26px rgba(0, 0, 0, .45);
    transition: transform .22s var(--gd-ease);
}
.gd-video:hover .gd-video-play span { transform: scale(1.08); }
.gd-video-b { display: flex; flex-direction: column; gap: 3px; padding: 13px 15px; background: var(--gd-surface); }
.gd-video-b b { font-size: 14.5px; font-weight: 750; color: var(--gd-ink); }
.gd-video-b span { font-size: 12.5px; color: var(--gd-muted); }

/* ── Franchise / engine feature card ────────────────────────────────────── */

/*
 * Used for the series and engine blocks: a wide card with its own art where
 * the record carries a logo, and typography alone where it does not.
 */
.gd-bill {
    display: flex; align-items: center; gap: 16px; padding: 16px 18px;
    border-radius: 16px; border: 1px solid var(--gd-line);
    background: linear-gradient(150deg, var(--gd-red-soft) 0%, var(--gd-surface) 62%);
    transition: transform .2s var(--gd-ease), border-color .2s var(--gd-ease), box-shadow .2s var(--gd-ease);
}
a.gd-bill:hover { transform: translateY(-2px); border-color: var(--gd-red-ring); box-shadow: var(--gd-shadow-lg); }
.gd-bill-ic {
    display: grid; place-items: center; width: 52px; height: 52px; flex: 0 0 52px;
    border-radius: 15px; overflow: hidden;
    background: linear-gradient(140deg, var(--gd-red), var(--gd-red-dark)); color: #fff;
    box-shadow: 0 8px 20px rgba(229, 27, 35, .28);
}
.gd-bill-ic img { width: 100%; height: 100%; object-fit: cover; }
/* Two or more bills stack with a gap; a lone one needs no wrapper rule. */
.gd-bills { display: grid; gap: 10px; }

.gd-bill-b { min-width: 0; display: flex; flex-direction: column; gap: 3px; }

/* The role a company is credited in — "Developer", "Publisher" — sitting above
   its name rather than beside it, so the name stays the thing you scan for. */
.gd-bill-r {
    font-size: 10.5px; font-weight: 800; text-transform: uppercase;
    letter-spacing: .07em; color: var(--gd-red);
}
.gd-bill-b b { font-size: 16px; font-weight: 800; color: var(--gd-ink); }
.gd-bill-b span { font-size: 13px; color: var(--gd-muted); line-height: 1.5; }
.gd-bill-go { margin-left: auto; flex: 0 0 auto; color: var(--gd-faint); }
a.gd-bill:hover .gd-bill-go { color: var(--gd-red); }

/* ── Read more ──────────────────────────────────────────────────────────── */

.gd-more { position: relative; }
.gd-more[data-collapsed="true"] .gd-more-body {
    max-height: 232px; overflow: hidden;
    -webkit-mask-image: linear-gradient(180deg, #000 62%, transparent 100%);
            mask-image: linear-gradient(180deg, #000 62%, transparent 100%);
}
.gd-more-btn { margin-top: 14px; }

/* ── Responsive ─────────────────────────────────────────────────────────── */

@media (max-width: 1180px) {
    /* The score panel stops being a column and becomes a band under the copy,
       with its stats spread across the full width. */
    .gd-stage-grid { grid-template-columns: minmax(0, 1fr); gap: 26px; }
    .gd-scorecard { max-width: 640px; }
}

@media (max-width: 900px) {
    .gd-stage-id { grid-template-columns: 130px minmax(0, 1fr); gap: 20px; }
    .gd-stage-poster { width: 130px; }
    .gd-stage-lede { font-size: 15.5px; }
    .gd-tabs { position: static; }
}

@media (max-width: 620px) {
    .gd-stage-in { padding-top: 14px; }
    .gd-stage-grid { padding: 16px 0 22px; gap: 20px; }

    /* Poster above the title rather than beside it — at this width a side-by
       -side pair leaves the title two words wide. */
    .gd-stage-id { grid-template-columns: minmax(0, 1fr); gap: 16px; align-items: start; }
    .gd-stage-poster { width: 112px; }
    .gd-stage-name h1 { font-size: clamp(27px, 8vw, 36px); }
    .gd-stage-meta { gap: 10px 20px; }
    .gd-stage-cta .gd-btn { flex: 1 1 100%; justify-content: center; }

    .gd-bigscore { gap: 14px; padding: 16px 15px 12px; }
    .gd-bigscore-n { font-size: 40px; }
    .gd-ring { flex-basis: 70px; width: 70px; height: 70px; }
    .gd-critics { padding: 0 15px 14px; }

    .gd-thumb { flex-basis: 138px; height: 78px; }
    .gd-strip-nav { display: none; }

    .gd-buy { flex-wrap: wrap; }
    .gd-buy-p { width: 100%; align-items: flex-start; text-align: left; }

    .gd-langs th:not(:first-child), .gd-langs td:not(:first-child) { width: auto; }
    .gd-langs th, .gd-langs td { padding: 8px 6px; font-size: 13px; }

    .gd-lb { padding: 12px; }
    .gd-lb-btn { width: 40px; height: 40px; }
    .gd-lb-prev { left: 6px; }
    .gd-lb-next { right: 6px; }
}

/* Motion is an enhancement; readers who ask for less get none of it. */
@media (prefers-reduced-motion: reduce) {
    .gd-stage-art img { transform: none; }
    .gd *, .gd *::before, .gd *::after {
        transition-duration: .01ms !important; animation-duration: .01ms !important;
    }
    .gd-strip-rail { scroll-behavior: auto; }
}

/* ============================================================================
   GAME DIRECTORY
   ----------------------------------------------------------------------------
   Everything below is specific to the listing pages — /games and its genre,
   platform, feature, collection and developer slices.

   The detail page's hero is a dark cinematic stage; this one is deliberately
   the opposite. A directory is a bright, scannable surface a reader sweeps
   across, so the brand shows up here as red light over white rather than as
   red light in the dark. The two pages then read as two rooms in one building
   instead of two attempts at the same room.

   All `gd-` namespaced, so nothing here can reach an article page and the older
   games.css the profile pages still load cannot reach any of this.
   ========================================================================== */

/* ── Directory hero ─────────────────────────────────────────────────────── */

.gd-dir-hero {
    position: relative; isolation: isolate; overflow: hidden;
    border-bottom: 1px solid var(--gd-line);
    background:
        radial-gradient(72% 130% at 88% -30%, rgba(229, 27, 35, .16) 0%, transparent 62%),
        radial-gradient(52% 96% at 4% 0%, rgba(229, 27, 35, .10) 0%, transparent 58%),
        linear-gradient(180deg, var(--gd-surface) 0%, var(--gd-canvas) 100%);
}

/* A faint grid, masked away before it reaches the copy — texture at the edges,
   clean where the words are. */
.gd-dir-hero::before {
    content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
    background-image:
        linear-gradient(var(--gd-line) 1px, transparent 1px),
        linear-gradient(90deg, var(--gd-line) 1px, transparent 1px);
    background-size: 62px 62px, 62px 62px;
    opacity: .5;
    -webkit-mask-image: radial-gradient(118% 96% at 78% 6%, #000 0%, transparent 72%);
            mask-image: radial-gradient(118% 96% at 78% 6%, #000 0%, transparent 72%);
}

.gd-dir-hero-in { position: relative; padding: 22px 0 30px; }

.gd-dir-head {
    display: grid; grid-template-columns: minmax(0, 1fr) auto;
    gap: 34px; align-items: end; margin-top: 18px;
}
.gd-dir-copy { min-width: 0; }

.gd-dir-t {
    font-size: clamp(34px, 5vw, 58px); font-weight: 900;
    letter-spacing: -.036em; line-height: 1.02; color: var(--gd-ink);
}
/* The brand half of the wordmark. */
.gd-dir-t em {
    font-style: normal;
    background: linear-gradient(120deg, #FF2A32 0%, var(--gd-red) 46%, var(--gd-red-dark) 100%);
    -webkit-background-clip: text; background-clip: text; color: transparent;
}
.gd-dir-x {
    margin-top: 13px; font-size: 16.5px; line-height: 1.62;
    max-width: 54ch; color: var(--gd-muted);
}

/* Stat tiles. Rendered only for counts the database actually returns, so this
   row is three tiles wide as readily as four and never shows a zero. */
.gd-dir-stats {
    display: grid; grid-auto-flow: column; grid-auto-columns: minmax(138px, 1fr);
    gap: 12px; flex: 0 0 auto;
}
.gd-dir-stat {
    display: flex; align-items: center; gap: 12px;
    padding: 14px 17px; border-radius: 17px;
    background: color-mix(in srgb, var(--gd-surface) 76%, transparent);
    border: 1px solid var(--gd-line);
    -webkit-backdrop-filter: blur(16px) saturate(1.3); backdrop-filter: blur(16px) saturate(1.3);
    box-shadow: var(--gd-shadow);
    transition: transform .2s var(--gd-ease), box-shadow .2s var(--gd-ease), border-color .2s var(--gd-ease);
}
.gd-dir-stat:hover { transform: translateY(-2px); box-shadow: var(--gd-shadow-lg); border-color: var(--gd-red-ring); }
.gd-dir-stat-i {
    display: grid; place-items: center; width: 40px; height: 40px; flex: 0 0 40px;
    border-radius: 13px; color: #fff;
    background: linear-gradient(140deg, #FF2A32, var(--gd-red-dark));
    box-shadow: 0 8px 20px rgba(229, 27, 35, .3);
}
.gd-dir-stat-b { min-width: 0; display: flex; flex-direction: column; }
.gd-dir-stat-b b { font-size: 22px; font-weight: 900; line-height: 1.08; color: var(--gd-ink); letter-spacing: -.02em; }
.gd-dir-stat-b span { font-size: 12px; font-weight: 650; color: var(--gd-muted); }

/* Collection shortcuts. */
.gd-dir-colls { display: flex; flex-wrap: wrap; gap: 9px; margin-top: 24px; }
.gd-dir-coll {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 9px 15px; border-radius: 999px;
    background: var(--gd-surface); border: 1px solid var(--gd-line);
    font-size: 13.5px; font-weight: 700; color: var(--gd-body);
    box-shadow: var(--gd-shadow);
    transition: transform .18s var(--gd-ease), border-color .18s var(--gd-ease), color .18s var(--gd-ease);
}
.gd-dir-coll .gd-i { color: var(--gd-faint); transition: transform .18s var(--gd-ease); }
.gd-dir-coll:hover { color: var(--gd-red); border-color: var(--gd-red-ring); transform: translateY(-2px); }
.gd-dir-coll:hover .gd-i { color: var(--gd-red); transform: translateX(2px); }

/* ── Directory layout ───────────────────────────────────────────────────── */

.gd-dir-layout {
    display: grid; grid-template-columns: 274px minmax(0, 1fr);
    gap: 26px; padding: 26px 0 60px; align-items: start;
}

/* ── Filter rail ────────────────────────────────────────────────────────── */

.gd-filters { position: sticky; top: 84px; min-width: 0; }
.gd-filters-box {
    border-radius: var(--gd-r-lg); overflow: hidden;
    background: var(--gd-surface); border: 1px solid var(--gd-line);
    box-shadow: var(--gd-shadow);
}
.gd-filters-h {
    display: flex; align-items: center; gap: 10px; padding: 15px 18px;
    font-size: 12px; font-weight: 800; text-transform: uppercase; letter-spacing: .07em;
    color: var(--gd-ink); cursor: pointer; list-style: none;
    background: linear-gradient(150deg, var(--gd-red-soft) 0%, transparent 70%);
    border-bottom: 1px solid var(--gd-line);
}
.gd-filters-h::-webkit-details-marker { display: none; }
.gd-filters-h > span:first-child { display: inline-flex; align-items: center; gap: 9px; }
.gd-filters-h .gd-i { color: var(--gd-red); }
.gd-filters-n {
    display: grid; place-items: center; min-width: 21px; height: 21px; padding: 0 6px;
    border-radius: 999px; background: var(--gd-red); color: #fff;
    font-size: 11px; font-weight: 800; letter-spacing: 0;
}
/* The caret is the only part that moves, and only where the disclosure is
   actually interactive. */
.gd-filters-caret { margin-left: auto; color: var(--gd-faint); transition: transform .2s var(--gd-ease); }
.gd-filters-box[open] .gd-filters-caret { transform: rotate(90deg); }

.gd-filters-b { padding: 17px 18px 19px; display: flex; flex-direction: column; gap: 15px; }
.gd-filters-clear { margin-top: 3px; }
.gd-filters-clear:hover { border-color: var(--gd-red); color: var(--gd-red); }

/* ── Form controls ──────────────────────────────────────────────────────── */

.gd-field { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.gd-field-l {
    font-size: 11px; font-weight: 800; text-transform: uppercase;
    letter-spacing: .06em; color: var(--gd-muted);
}
.gd-input {
    width: 100%; height: 42px; padding: 0 13px;
    border-radius: 12px; border: 1px solid var(--gd-line);
    background: var(--gd-canvas); color: var(--gd-ink);
    font-size: 14px; font-weight: 600; font-family: inherit;
    transition: border-color .18s var(--gd-ease), box-shadow .18s var(--gd-ease), background .18s var(--gd-ease);
}
.gd-input:hover { border-color: var(--gd-faint); }
.gd-input:focus {
    outline: none; background: var(--gd-surface);
    border-color: var(--gd-red); box-shadow: 0 0 0 3px var(--gd-red-ring);
}
.gd-input::placeholder { color: var(--gd-faint); font-weight: 500; }

/* Search keeps its glyph inside the field. */
.gd-field-search { position: relative; display: flex; align-items: center; }
.gd-field-search .gd-i { position: absolute; left: 12px; color: var(--gd-faint); pointer-events: none; }
.gd-field-search .gd-input { padding-left: 35px; }

/*
 * Native <select> with the platform arrow replaced. Kept native rather than
 * rebuilt as a JS listbox: the browser's own control is keyboard-accessible,
 * screen-reader correct and works on touch without any of it being reimplemented.
 */
.gd-select {
    -webkit-appearance: none; appearance: none; cursor: pointer;
    padding-right: 34px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236B7280' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: right 11px center; background-size: 15px;
}

/* ── Toolbar ────────────────────────────────────────────────────────────── */

.gd-results { min-width: 0; display: flex; flex-direction: column; gap: 16px; }

.gd-toolbar {
    display: flex; align-items: center; justify-content: space-between;
    flex-wrap: wrap; gap: 14px;
    padding: 13px 17px; border-radius: 16px;
    background: var(--gd-surface); border: 1px solid var(--gd-line);
    box-shadow: var(--gd-shadow);
}
.gd-toolbar-c { font-size: 14px; color: var(--gd-muted); }
.gd-toolbar-c b { color: var(--gd-ink); font-weight: 800; }
.gd-toolbar-r { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

.gd-sort { position: relative; display: flex; align-items: center; }
.gd-sort .gd-i { position: absolute; left: 12px; color: var(--gd-faint); pointer-events: none; }
.gd-sort .gd-select { height: 40px; padding-left: 34px; min-width: 178px; background-color: var(--gd-canvas); }

.gd-viewsw {
    display: flex; gap: 3px; padding: 3px; border-radius: 12px;
    background: var(--gd-line-soft); border: 1px solid var(--gd-line);
}
.gd-viewsw-b {
    display: inline-flex; align-items: center; gap: 7px;
    height: 32px; padding: 0 13px; border-radius: 9px;
    font-size: 13px; font-weight: 700; color: var(--gd-muted);
    transition: background .18s var(--gd-ease), color .18s var(--gd-ease), box-shadow .18s var(--gd-ease);
}
.gd-viewsw-b:hover { color: var(--gd-ink); }
.gd-viewsw-b.is-on { background: var(--gd-surface); color: var(--gd-red); box-shadow: var(--gd-shadow); }

/* ── Active filter chips ────────────────────────────────────────────────── */

.gd-chiprow { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.gd-chipx {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 7px 11px 7px 12px; border-radius: 999px;
    background: var(--gd-surface); border: 1px solid var(--gd-line);
    font-size: 13px; font-weight: 700; color: var(--gd-ink);
    box-shadow: var(--gd-shadow);
    transition: border-color .18s var(--gd-ease), color .18s var(--gd-ease), transform .18s var(--gd-ease);
}
.gd-chipx-k { font-size: 10.5px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; color: var(--gd-muted); }
.gd-chipx .gd-i { color: var(--gd-faint); }
.gd-chipx:hover { border-color: var(--gd-red); color: var(--gd-red); transform: translateY(-1px); }
.gd-chipx:hover .gd-i, .gd-chipx:hover .gd-chipx-k { color: var(--gd-red); }
.gd-chipclear { font-size: 13px; font-weight: 750; color: var(--gd-red); padding: 7px 4px; }
.gd-chipclear:hover { text-decoration: underline; text-underline-offset: 3px; }

/* ── Result containers ──────────────────────────────────────────────────── */

.gd-cards {
    display: grid; gap: 18px;
    grid-template-columns: repeat(auto-fill, minmax(212px, 1fr));
}
.gd-rows { display: flex; flex-direction: column; gap: 13px; }

/* ── Game card ──────────────────────────────────────────────────────────── */

.gd-gc {
    position: relative; min-width: 0;
    background: var(--gd-surface); border: 1px solid var(--gd-line);
    border-radius: var(--gd-r-lg); overflow: hidden;
    box-shadow: var(--gd-shadow);
    transition: transform .24s var(--gd-ease), box-shadow .24s var(--gd-ease), border-color .24s var(--gd-ease);
}
.gd-gc:hover { transform: translateY(-4px); box-shadow: var(--gd-shadow-lg); border-color: var(--gd-red-ring); }

/*
 * The art must meet the card edge on all four sides. The placeholder fill is
 * dark rather than near-white so that a sub-pixel rounding gap, or a cover
 * still decoding, never flashes a white band inside the frame.
 */
.gd-gc-art {
    position: relative; display: block; overflow: hidden;
    background: #10131A; line-height: 0; font-size: 0;
}
.gd-gc-cover { display: block; width: 100%; border-radius: 0; }
.gd-gc-art .gd-cover { border-radius: 0; background: #10131A; }
.gd-gc-art .gd-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.gd-gc-art .gd-cover img { transition: transform .5s var(--gd-ease); }
.gd-gc:hover .gd-gc-art .gd-cover img { transform: scale(1.055); }

/* A wash at the foot of the art so a bright cover never fights the badges. */
.gd-gc-art::after {
    content: ''; position: absolute; inset: auto 0 0; height: 42%;
    background: linear-gradient(180deg, transparent, rgba(9, 11, 15, .34));
    pointer-events: none;
}

.gd-gc-badge {
    position: absolute; top: 10px; left: 10px; z-index: 2;
    padding: 5px 10px; border-radius: 999px;
    font-size: 10.5px; font-weight: 800; text-transform: uppercase; letter-spacing: .05em;
    color: #fff; box-shadow: 0 6px 16px rgba(0, 0, 0, .28);
    -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}
.gd-gc-badge.is-soon { background: linear-gradient(135deg, #FF2A32, var(--gd-red-dark)); }
.gd-gc-badge.is-ea   { background: linear-gradient(135deg, #F59E0B, #D97706); }
.gd-gc-badge.is-free { background: linear-gradient(135deg, #22C55E, #15803D); }

.gd-gc-score {
    position: absolute; top: 10px; right: 10px; z-index: 2;
    display: inline-flex; align-items: center; gap: 4px;
    padding: 5px 9px; border-radius: 999px;
    background: rgba(9, 11, 15, .72); color: #fff;
    font-size: 12px; font-weight: 850;
    -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}
.gd-gc-score .gd-i { color: #FFC53D; }

.gd-gc-b { padding: 14px 15px 15px; display: flex; flex-direction: column; gap: 9px; min-width: 0; }

.gd-gc-t { font-size: 15.5px; font-weight: 800; line-height: 1.32; letter-spacing: -.012em; }
.gd-gc-t a { color: var(--gd-ink); }
/* The title link covers the card, so the whole thing is one target and there is
   still only one link in the accessibility tree. */
.gd-gc-t a::after { content: ''; position: absolute; inset: 0; z-index: 1; }
.gd-gc:hover .gd-gc-t a { color: var(--gd-red); }

.gd-gc-x { font-size: 13.5px; line-height: 1.6; color: var(--gd-muted); }

.gd-gc-m { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.gd-gc-genre {
    position: relative; z-index: 2;
    padding: 3px 9px; border-radius: 7px;
    background: var(--gd-red-soft); color: var(--gd-red);
    font-size: 11.5px; font-weight: 750;
    transition: background .16s var(--gd-ease);
}
.gd-gc-genre:hover { background: var(--gd-red); color: #fff; }
.gd-gc-year { font-size: 12px; font-weight: 700; color: var(--gd-faint); margin-left: auto; }

.gd-gc-dev { display: flex; align-items: center; gap: 7px; font-size: 13px; color: var(--gd-muted); }
.gd-gc-dev .gd-i { color: var(--gd-faint); }
.gd-gc-dev a { position: relative; z-index: 2; font-weight: 650; color: var(--gd-body); }
.gd-gc-dev a:hover { color: var(--gd-red); }

.gd-gc-p { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: auto; padding-top: 2px; }
.gd-gc-plat {
    display: grid; place-items: center; width: 27px; height: 27px;
    border-radius: 8px; background: var(--gd-line-soft); color: var(--gd-muted);
    transition: background .16s var(--gd-ease), color .16s var(--gd-ease);
}
.gd-gc:hover .gd-gc-plat { background: var(--gd-red-soft); color: var(--gd-red); }
.gd-gc-more { font-size: 11.5px; font-weight: 750; color: var(--gd-faint); }

/* List variant: the same card turned on its side, carrying the excerpt and the
   developer that the grid card has no room for. */
.gd-gc--list { display: grid; grid-template-columns: 218px minmax(0, 1fr); align-items: stretch; }
.gd-gc--list:hover { transform: translateY(-2px); }
.gd-gc--list .gd-gc-art { height: 100%; }
.gd-gc--list .gd-gc-cover { height: 100%; }
.gd-gc--list .gd-gc-cover .gd-cover-fb, .gd-gc--list .gd-gc-cover img { height: 100%; }
.gd-gc--list .gd-gc-b { padding: 17px 19px; gap: 10px; }
.gd-gc--list .gd-gc-t { font-size: 18px; }
.gd-gc--list .gd-gc-year { margin-left: 0; }

/* ── Empty state ────────────────────────────────────────────────────────── */

.gd-noresults {
    display: flex; flex-direction: column; align-items: center; text-align: center;
    gap: 13px; padding: 62px 28px;
    border-radius: var(--gd-r-lg); border: 1px dashed var(--gd-line);
    background:
        radial-gradient(64% 88% at 50% 0%, var(--gd-red-soft) 0%, transparent 62%),
        var(--gd-surface);
}
.gd-noresults-i {
    display: grid; place-items: center; width: 66px; height: 66px;
    border-radius: 21px; color: var(--gd-red);
    background: var(--gd-red-soft); border: 1px solid var(--gd-red-ring);
}
.gd-noresults h2 { font-size: 20px; font-weight: 850; }
.gd-noresults p { font-size: 14.5px; line-height: 1.6; color: var(--gd-muted); max-width: 46ch; }
.gd-noresults-a { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; margin-top: 6px; }

/* ── Pagination ─────────────────────────────────────────────────────────── */

.gd-pg { display: flex; align-items: center; justify-content: center; gap: 8px; margin-top: 10px; }
.gd-pg-n { display: flex; align-items: center; gap: 5px; }
.gd-pg-b, .gd-pg-i {
    display: grid; place-items: center; min-width: 40px; height: 40px; padding: 0 12px;
    border-radius: 12px; border: 1px solid var(--gd-line); background: var(--gd-surface);
    font-size: 14px; font-weight: 750; color: var(--gd-body);
    transition: border-color .18s var(--gd-ease), color .18s var(--gd-ease), transform .18s var(--gd-ease), box-shadow .18s var(--gd-ease);
}
.gd-pg-b:hover, .gd-pg-i:hover { border-color: var(--gd-red); color: var(--gd-red); transform: translateY(-2px); box-shadow: var(--gd-shadow); }
.gd-pg-i.is-on {
    background: linear-gradient(135deg, #FF2A32, var(--gd-red-dark));
    border-color: transparent; color: #fff;
    box-shadow: 0 8px 22px rgba(229, 27, 35, .34);
}
.gd-pg-i.is-on:hover { transform: none; color: #fff; }
.gd-pg-b.is-off { opacity: .42; pointer-events: none; }
.gd-pg-gap { padding: 0 4px; color: var(--gd-faint); font-weight: 800; }

/* ── Responsive ─────────────────────────────────────────────────────────── */

@media (max-width: 1180px) {
    .gd-dir-layout { grid-template-columns: 244px minmax(0, 1fr); gap: 20px; }
    .gd-dir-head { grid-template-columns: minmax(0, 1fr); gap: 24px; align-items: start; }
    .gd-dir-stats { grid-auto-flow: row; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
}

@media (max-width: 900px) {
    /*
     * The rail stops being a column and becomes a disclosure above the results.
     * Reflowed rather than shrunk: a 240px column of selects at this width is
     * unusable, and collapsing it puts the games first, which is what the page
     * is for.
     */
    .gd-dir-layout { grid-template-columns: minmax(0, 1fr); padding-top: 20px; }
    .gd-filters { position: static; }
    .gd-filters-b { display: grid; grid-template-columns: repeat(auto-fit, minmax(196px, 1fr)); gap: 14px; }
    .gd-filters-clear { grid-column: 1 / -1; }

    .gd-cards { grid-template-columns: repeat(auto-fill, minmax(178px, 1fr)); gap: 14px; }
    .gd-gc--list { grid-template-columns: 168px minmax(0, 1fr); }
}

@media (max-width: 620px) {
    .gd-dir-hero-in { padding: 16px 0 22px; }
    .gd-dir-head { margin-top: 14px; }
    .gd-dir-x { font-size: 15px; }
    .gd-dir-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
    .gd-dir-stat { padding: 12px 13px; gap: 10px; }
    .gd-dir-stat-i { width: 34px; height: 34px; flex-basis: 34px; border-radius: 11px; }
    .gd-dir-stat-b b { font-size: 19px; }

    .gd-toolbar { padding: 12px 13px; }
    .gd-toolbar-r { width: 100%; justify-content: space-between; }
    .gd-sort { flex: 1 1 auto; }
    .gd-sort .gd-select { width: 100%; min-width: 0; }
    /* Labels off, glyphs on — the pair still reads as a switch at this width. */
    .gd-viewsw-b span { display: none; }
    .gd-viewsw-b { padding: 0 12px; }

    .gd-cards { grid-template-columns: repeat(auto-fill, minmax(148px, 1fr)); gap: 12px; }
    .gd-gc-b { padding: 12px 12px 13px; gap: 8px; }
    .gd-gc-t { font-size: 14.5px; }

    /* The list row stacks: a 168px thumbnail beside text leaves neither usable. */
    .gd-gc--list { grid-template-columns: minmax(0, 1fr); }
    .gd-gc--list .gd-gc-t { font-size: 16.5px; }
    .gd-gc--list .gd-gc-x { display: none; }

    .gd-noresults { padding: 44px 20px; }
    .gd-pg-b, .gd-pg-i { min-width: 36px; height: 36px; padding: 0 9px; font-size: 13.5px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   GAME GALLERY
   ---------------------------------------------------------------------------
   The kind=gallery half of game_screenshots, rendered as its own section
   between Features and Screenshots. Deliberately a different shape from
   .gd-shots (which leads with one wide screenshot): gallery art is a set of
   equals, so it tiles evenly.

   Tokens, radius, border and easing all come from the existing game UI scale
   so this reads as part of the page rather than a bolted-on block.
   ═══════════════════════════════════════════════════════════════════════════ */

.gd-sec-lead {
    margin: 0 0 16px;
    font-size: 14px;
    line-height: 1.6;
    color: var(--gd-muted);
}

.gd-gal {
    display: grid;
    gap: 12px;
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

.gd-gal-item {
    position: relative;
    padding: 0;
    margin: 0;
    border-radius: var(--gd-r-sm);
    overflow: hidden;
    border: 1px solid var(--gd-line);
    background: var(--gd-line-soft);
    cursor: pointer;
    display: block;
    width: 100%;
    transition: border-color .2s var(--gd-ease), box-shadow .2s var(--gd-ease), transform .2s var(--gd-ease);
}

.gd-gal-item img {
    width: 100%;
    aspect-ratio: 16 / 10;
    object-fit: cover;
    display: block;
    transition: transform .5s var(--gd-ease);
}

.gd-gal-item:hover {
    border-color: var(--gd-red);
    box-shadow: var(--gd-shadow);
    transform: translateY(-2px);
}
.gd-gal-item:hover img { transform: scale(1.06); }

/* Keyboard users get the same affordance as the mouse hover. */
.gd-gal-item:focus-visible {
    outline: 2px solid var(--gd-red);
    outline-offset: 2px;
}

@media (max-width: 900px) {
    .gd-gal { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 520px) {
    /* One column reads better than two thumbnails too small to make out. */
    .gd-gal { grid-template-columns: 1fr; gap: 10px; }
}

@media (prefers-reduced-motion: reduce) {
    .gd-gal-item,
    .gd-gal-item img { transition: none; }
    .gd-gal-item:hover { transform: none; }
    .gd-gal-item:hover img { transform: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   PROSE — elements the rich-text editor can now emit
   ---------------------------------------------------------------------------
   .gd-prose already styled headings, links, lists and images. The Description
   field is a full TinyMCE editor, so it can also produce quotes, emphasis,
   tables, rules and aligned text. Without rules for those, a blockquote read
   as an ordinary paragraph and a table lost its grid.
   ═══════════════════════════════════════════════════════════════════════════ */

.gd-prose strong, .gd-prose b { font-weight: 700; color: var(--gd-ink); }
.gd-prose em, .gd-prose i     { font-style: italic; }
.gd-prose u                   { text-underline-offset: 2px; }
.gd-prose s, .gd-prose del    { opacity: .7; }

.gd-prose blockquote {
    margin: 20px 0;
    padding: 12px 18px;
    border-left: 3px solid var(--gd-red);
    background: var(--gd-line-soft);
    border-radius: 0 var(--gd-r-sm) var(--gd-r-sm) 0;
    color: var(--gd-ink);
    font-style: italic;
}
.gd-prose blockquote > :last-child { margin-bottom: 0; }

.gd-prose hr {
    margin: 26px 0;
    border: 0;
    border-top: 1px solid var(--gd-line);
}

/* Editor-emitted alignment classes. */
.gd-prose [style*="text-align: center"],
.gd-prose [style*="text-align:center"] { text-align: center; }
.gd-prose [style*="text-align: right"],
.gd-prose [style*="text-align:right"]  { text-align: right; }

/* A wide table must scroll inside the column, never widen the page. */
.gd-prose table {
    width: 100%;
    border-collapse: collapse;
    margin: 20px 0;
    font-size: 14.5px;
    display: block;
    overflow-x: auto;
}
.gd-prose th,
.gd-prose td {
    border: 1px solid var(--gd-line);
    padding: 8px 12px;
    text-align: left;
    vertical-align: top;
}
.gd-prose th {
    background: var(--gd-line-soft);
    font-weight: 700;
    color: var(--gd-ink);
}

/* Follower count beside a social link label — a quiet secondary note, not a
   competing value. Matches the muted treatment company/creator pages use. */
.gd-spec-sub {
    margin-left: 6px;
    font-style: normal;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--gd-muted);
    background: var(--gd-line-soft);
    padding: 1px 6px;
    border-radius: 999px;
}

/* =============================================================================
   COMPANIES DIRECTORY — /companies
   -----------------------------------------------------------------------------
   The Games directory's sibling section. It reuses this sheet's tokens, filter
   panel, toolbar, chip row, empty state and pagination wholesale; what follows
   is only what a company listing needs that a game listing does not:

     • a centred hero, because a directory of makers opens on a search rather
       than on a heading and a stat rail
     • a search field big enough to be the hero's main object
     • a logo tile that CONTAINS rather than covers — a wordmark cropped to fill
       a square is a broken logo
     • a card built from facts (location, founded, game count) instead of art

   Everything is `co-` namespaced and sits inside `.gd`, so it inherits the same
   palette in both themes without redeclaring a single colour.
   ============================================================================= */

/* ── Hero ───────────────────────────────────────────────────────────────── */

.gd .co-hero-in {
    position: relative;
    display: flex; flex-direction: column; align-items: center;
    text-align: center;
    padding: 30px 0 34px;
}

.gd .co-badge {
    display: inline-flex; align-items: center; gap: 9px;
    padding: 8px 16px 8px 13px;
    border: 1px solid var(--gd-line);
    border-radius: 999px;
    background: var(--gd-surface);
    box-shadow: var(--gd-shadow);
    font-size: 12px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase;
    color: var(--gd-ink);
}
.gd .co-badge svg { color: var(--gd-red); }

/* The one heading on the page, sized to lead. Weight and tracking come from
   the same Inter scale the Games hero uses — no display face, no effects. */
.gd .co-hero-t {
    margin: 20px 0 0;
    font-size: clamp(44px, 8.5vw, 96px);
    font-weight: 900;
    line-height: .96;
    letter-spacing: -.045em;
    color: var(--gd-ink);
}

.gd .co-hero-x {
    max-width: 620px;
    margin: 16px 0 0;
    font-size: clamp(15px, 1.5vw, 17px);
    line-height: 1.6;
    color: var(--gd-muted);
}

/* ── Hero search ────────────────────────────────────────────────────────── */

.gd .co-search {
    position: relative;
    display: flex; align-items: center;
    width: min(760px, 100%);
    margin: 28px 0 0;
    padding: 7px 7px 7px 18px;
    background: var(--gd-surface);
    border: 1px solid var(--gd-line);
    border-radius: 999px;
    /* The red glow the brief asks for: a ring, not a shadow, so it reads as
       focus affordance rather than elevation. */
    box-shadow: var(--gd-shadow-lg), 0 0 0 6px rgba(229, 27, 35, .05);
    transition: box-shadow .2s var(--gd-ease), border-color .2s var(--gd-ease);
}
.gd .co-search:focus-within {
    border-color: var(--gd-red-ring);
    box-shadow: var(--gd-shadow-lg), 0 0 0 6px rgba(229, 27, 35, .12);
}
.gd .co-search-ic { display: grid; place-items: center; flex: none; color: var(--gd-faint); }
.gd .co-search-i {
    flex: 1; min-width: 0;
    height: 50px; padding: 0 14px;
    border: 0; background: none; outline: none;
    font: inherit; font-size: 16px; color: var(--gd-ink);
}
.gd .co-search-i::placeholder { color: var(--gd-faint); }
.gd .co-search-i::-webkit-search-cancel-button { -webkit-appearance: none; }
.gd .co-search-b {
    flex: none;
    display: grid; place-items: center;
    width: 50px; height: 50px;
    border: 0; border-radius: 999px;
    background: var(--gd-red); color: #fff;
    cursor: pointer;
    transition: background .18s var(--gd-ease), transform .18s var(--gd-ease);
}
.gd .co-search-b:hover { background: var(--gd-red-dark); transform: scale(1.04); }
.gd .co-search-b svg { transform: rotate(0deg); }

/* ── Popular searches ───────────────────────────────────────────────────── */

.gd .co-pop {
    display: flex; align-items: center; justify-content: center;
    flex-wrap: wrap; gap: 8px;
    margin: 18px 0 0;
}
.gd .co-pop-l { font-size: 13px; font-weight: 600; color: var(--gd-muted); }
.gd .co-pop-c {
    padding: 7px 14px;
    border: 1px solid var(--gd-line); border-radius: 999px;
    background: var(--gd-surface);
    font: inherit; font-size: 13px; font-weight: 600; color: var(--gd-body);
    cursor: pointer;
    transition: border-color .16s var(--gd-ease), color .16s var(--gd-ease), background .16s var(--gd-ease);
}
.gd .co-pop-c:hover { border-color: var(--gd-red-ring); background: var(--gd-red-soft); color: var(--gd-red); }

/* The statistics used to render as six boxed cards with icon tiles. That read
   as a SaaS dashboard rather than a games directory, and it is gone — see
   `.co-glance` below for the editorial band that replaced it. */

/* ── Founded range ──────────────────────────────────────────────────────── */

.gd .co-range { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 8px; }
/* Tighter than a full-width select: two of them plus a dash have to fit the
   274px filter rail without clipping "Any year". */
.gd .co-range .gd-select { min-width: 0; padding-left: 11px; padding-right: 26px; font-size: 13px; background-position: right 8px center; }
.gd .co-range-d { color: var(--gd-faint); font-size: 13px; }

/* ── Company card ───────────────────────────────────────────────────────────
   The directory's unit. Art, mark, facts, figures, action — the approved
   design's card, built once and used in both the grid and the list.

   THE ACCENT IS A PROPERTY, NOT A RULE. Every tinted thing below reads --a,
   an "R, G, B" triple the template sets from the company record. Nothing in
   this stylesheet names a company, and adding the six-hundredth needs no line
   here. */

.gd .co-card {
    position: relative;
    isolation: isolate;
    display: flex;
    flex-direction: column;
    border-radius: 18px;

    /*
     * TINTED AT REST, not only on hover.
     *
     * A whisper of the company's own colour bleeding down from under the art
     * and dissolving into white by the time it reaches the facts — so a card
     * belongs to its company before you touch it, and a grid of them reads as
     * six companies rather than six white boxes.
     *
     * The alphas are deliberately tiny (.085 → .028 → nothing). Any heavier and
     * the body stops being white, the ink loses contrast, and six tinted panels
     * start competing with the Barlin red rather than sitting under it. The
     * inset highlight along the top edge is what keeps it reading as a lit
     * surface instead of a flat fill.
     */
    background:
        linear-gradient(180deg,
            rgba(var(--a), .13) 0%,
            rgba(var(--a), .05) 26%,
            rgba(255, 255, 255, 0) 62%),
        var(--gd-surface);

    border: 1px solid rgba(var(--a), .17);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, .75),
        0 1px 2px rgba(16, 24, 40, .04),
        0 14px 30px -22px rgba(var(--a), .42);
    overflow: hidden;
    transition: transform .3s var(--gd-ease), box-shadow .3s var(--gd-ease), border-color .3s var(--gd-ease);
}

/*
 * THE GLOW. A soft disc in the company's own colour that drifts behind the
 * card on hover.
 *
 * One element, no image, and it moves — a static halo reads as a highlight,
 * a drifting one reads as alive. Kept well under the content and at low
 * opacity: this is a suggestion of light, not a neon rim, and the card has to
 * stay as readable hovered as it is at rest.
 *
 * translate/scale rather than top/left/width so the whole thing runs on the
 * compositor and never triggers layout.
 */
.gd .co-card-glow {
    position: absolute;
    top: -30%; left: 50%;
    width: 78%; aspect-ratio: 1;
    z-index: -1;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(var(--a), .62) 0%, rgba(var(--a), 0) 68%);
    opacity: 0;
    filter: blur(26px);
    translate: -50% 0;
    transition: opacity .45s var(--gd-ease);
    pointer-events: none;
}
.gd .co-card:hover { transform: translateY(-5px); }
.gd .co-card:hover,
.gd .co-card:focus-within {
    border-color: rgba(var(--a), .42);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, .75),
        0 2px 6px rgba(16, 24, 40, .05),
        0 30px 56px -24px rgba(var(--a), .58);
}

/*
 * THE TRAVELLING EDGE LIGHT.
 *
 * A conic gradient in the company's own colour, drawn as a RING by masking out
 * everything except a 2px band at the edge (content-box XOR border-box), and
 * turned by animating --co-ang. The light runs around the card rather than
 * sitting on it — a static glow reads as a highlight, a moving one reads as
 * alive, which is the whole difference.
 *
 * --co-ang is a registered @property (declared with the hero, above). That
 * registration is what makes this work at all: to an unregistered custom
 * property an angle is just a string, and the animation would jump 0deg → 360deg
 * in a single frame and look like nothing is happening.
 *
 * Idle cost is zero — opacity 0, no animation — and the keyframes only run while
 * the card is hovered or holds focus.
 */
.gd .co-card::before {
    content: '';
    position: absolute; inset: 0; z-index: 5;
    border-radius: inherit;
    padding: 2px;
    background: conic-gradient(from var(--co-ang),
        transparent 0deg 40deg,
        rgba(var(--a), .95) 78deg,
        #FFFFFF 92deg,
        rgba(var(--a), .95) 106deg,
        transparent 150deg 360deg);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
            mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
            mask-composite: exclude;
    opacity: 0;
    pointer-events: none;
    transition: opacity .3s var(--gd-ease);
}
.gd .co-card:hover::before,
.gd .co-card:focus-within::before {
    opacity: 1;
    animation: co-orbit 2.6s linear infinite;
}

/*
 * THE SWEEP. A band of light crossing the face once on hover — the way light
 * moves over a card you have just picked up. ONE pass, not a loop: a sheen that
 * never stops is a distraction rather than a response.
 *
 * Clipped by the card's own overflow, so no extra wrapper is needed.
 */
.gd .co-card::after {
    content: '';
    position: absolute; z-index: 6;
    top: -60%; left: -150%;
    width: 45%; height: 220%;
    transform: rotate(16deg);
    pointer-events: none;
    background: linear-gradient(100deg,
        rgba(255, 255, 255, 0) 0%,
        rgba(255, 255, 255, .30) 42%,
        rgba(255, 255, 255, .68) 50%,
        rgba(255, 255, 255, .30) 58%,
        rgba(255, 255, 255, 0) 100%);
}
.gd .co-card:hover::after,
.gd .co-card:focus-within::after {
    animation: co-sweep 1.05s cubic-bezier(.22, .61, .36, 1);
}
.gd .co-card:hover .co-card-glow,
.gd .co-card:focus-within .co-card-glow {
    opacity: 1;
    animation: co-drift 6s ease-in-out infinite;
}
@keyframes co-drift {
    0%, 100% { translate: -50% 0;    scale: 1; }
    33%      { translate: -34% 6%;   scale: 1.08; }
    66%      { translate: -66% -4%;  scale: .96; }
}

/* ── Art ────────────────────────────────────────────────────────────────── */

.gd .co-card-art {
    position: relative;
    aspect-ratio: 16 / 8.4;
    background: linear-gradient(150deg, rgba(var(--a), .22), rgba(var(--a), .06));
    overflow: hidden;
}
.gd .co-card-art img {
    width: 100%; height: 100%;
    display: block;
    object-fit: cover;
    transition: transform .6s var(--gd-ease);
}
/* The parallax: the picture moves further than the card does, which is what
   makes the frame read as a window rather than a border. */
.gd .co-card:hover .co-card-art img { transform: scale(1.07); }

.gd .co-card-art.is-blank { display: grid; place-items: center; }
.gd .co-card-art.is-blank img { width: 38%; height: auto; object-fit: contain; opacity: .45; transform: none; }
.gd .co-card:hover .co-card-art.is-blank img { transform: none; }

.gd .co-card-wash {
    position: absolute; inset: 0;
    background:
        linear-gradient(180deg, rgba(10, 12, 16, .34) 0%, rgba(10, 12, 16, 0) 46%),
        linear-gradient(150deg, rgba(var(--a), .34) 0%, rgba(var(--a), .06) 100%);
    mix-blend-mode: multiply;
    transition: opacity .3s var(--gd-ease);
}
.gd .co-card:hover .co-card-wash { opacity: .82; }

.gd .co-card-vf {
    position: absolute; top: 10px; left: 10px; z-index: 3;
    display: inline-flex; align-items: center; gap: 5px;
    padding: 4px 9px 4px 5px;
    border-radius: 999px;
    background: rgba(12, 14, 18, .62);
    -webkit-backdrop-filter: blur(6px);
            backdrop-filter: blur(6px);
    color: #FFF;
    font-size: 9.5px; font-weight: 800; letter-spacing: .07em; text-transform: uppercase;
}
.gd .co-card-vf i {
    display: grid; place-items: center;
    width: 13px; height: 13px; border-radius: 50%;
    background: rgb(var(--a)); color: #FFF;
}
.gd .co-card-vf svg { width: 8px; height: 8px; }

/* A real control, so a real button — above the card's stretched link, with a
   focus ring of its own. */
.gd .co-card-fav {
    position: absolute; top: 9px; right: 9px; z-index: 4;
    display: grid; place-items: center;
    width: 30px; height: 30px;
    border: 0; border-radius: 50%; cursor: pointer;
    background: rgba(255, 255, 255, .24);
    -webkit-backdrop-filter: blur(6px);
            backdrop-filter: blur(6px);
    color: #FFF;
    transition: background .18s var(--gd-ease), transform .18s var(--gd-ease), color .18s var(--gd-ease);
}
.gd .co-card-fav:hover { background: rgba(255, 255, 255, .42); transform: scale(1.1); }
.gd .co-card-fav:focus-visible { outline: 3px solid #FFF; outline-offset: 2px; }
.gd .co-card-fav.is-on { background: #FFF; color: var(--gd-red); }
.gd .co-card-fav.is-on svg { fill: currentColor; }
.gd .co-card-fav svg { width: 15px; height: 15px; }

/* ── Body ───────────────────────────────────────────────────────────────── */

.gd .co-card-b {
    /*
     * POSITIONED, and above the art.
     *
     * .co-card-art is position:relative, which puts it in the positioned paint
     * layer — above any in-flow sibling. Without a position of its own the body
     * paints underneath it, and the logo tile's negative margin pulls its top
     * half straight behind the picture.
     *
     * z-index 1 sits under the badge (3) and the heart (4), which are children
     * of an art block with z-index:auto and so share the card's stacking
     * context rather than the art's.
     */
    position: relative;
    z-index: 1;
    flex: 1 1 auto;
    display: flex; flex-direction: column;
    gap: 7px;
    padding: 12px 15px 15px;
}

/*
 * The mark, straddling the seam. A flow child with a negative margin rather
 * than an absolute offset: it lands on the boundary whatever the art ratio is,
 * and changing that ratio needs no new number here.
 */
.gd .co-card-mark {
    align-self: flex-start;
    margin-top: calc(-1 * (var(--tile, 52px) / 2 + 12px));
    margin-bottom: 1px;
    display: grid; place-items: center;
    width: var(--tile, 52px); height: var(--tile, 52px);
    border-radius: 14px;
    background: var(--gd-surface);
    border: 1px solid var(--gd-line);
    box-shadow: 0 8px 20px -8px rgba(16, 24, 40, .35);
    overflow: hidden;
    transition: transform .3s var(--gd-ease);
}
.gd .co-card:hover .co-card-mark { transform: translateY(-2px); }
/* CONTAIN, never cover: a wordmark cropped to fill a square is a broken logo. */
.gd .co-card-mark img { width: 76%; height: 76%; object-fit: contain; display: block; }

.gd .co-card-n {
    display: flex; align-items: center; gap: 6px;
    margin: 0;
    font-size: 15.5px; font-weight: 800; letter-spacing: -.015em;
    color: var(--gd-ink); line-height: 1.25;
}
/* The stretched link. The whole card is the target while the heart above keeps
   its own — an <a> wrapping the card would make that <button> invalid markup
   and swallow its click. */
.gd .co-card-n a { color: inherit; text-decoration: none; min-width: 0; }
.gd .co-card-n a::after { content: ''; position: absolute; inset: 0; z-index: 2; border-radius: inherit; }
.gd .co-card-n a:focus-visible { outline: none; }
.gd .co-card:focus-within { outline: 3px solid var(--gd-red-ring); outline-offset: 2px; }

.gd .co-card-tick {
    flex: none;
    display: grid; place-items: center;
    width: 15px; height: 15px; border-radius: 50%;
    background: rgb(var(--a)); color: #FFF;
}
.gd .co-card-tick svg { width: 9px; height: 9px; }

.gd .co-card-role {
    margin: -2px 0 0;
    font-size: 12px; font-weight: 750;
    color: rgb(var(--a));
    line-height: 1.3;
}

.gd .co-card-facts { display: flex; flex-direction: column; gap: 4px; }
.gd .co-card-fact {
    display: flex; align-items: center; gap: 6px;
    font-size: 11.5px; color: var(--gd-muted); line-height: 1.35;
    min-width: 0;
}
.gd .co-card-fact svg { flex: none; width: 12px; height: 12px; color: var(--gd-faint); }
/* One line each. A three-line address turns a grid of cards into a ragged
   wall; the full string stays reachable as the title. */
.gd .co-card-fact > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.gd .co-card-parent b { color: var(--gd-ink); font-weight: 700; }

/* ── The three figures ──────────────────────────────────────────────────── */

.gd .co-card-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
    gap: 7px;
    margin-top: 3px;
}
.gd .co-card-stat {
    display: flex; flex-direction: column; align-items: center; gap: 1px;
    padding: 8px 4px;
    border: 1px solid rgba(var(--a), .14);
    border-radius: 11px;
    background: linear-gradient(180deg, rgba(var(--a), .06), rgba(var(--a), .02));
    min-width: 0;
    transition: border-color .25s var(--gd-ease), background .25s var(--gd-ease);
}
.gd .co-card:hover .co-card-stat { border-color: rgba(var(--a), .28); background: rgba(var(--a), .05); }
.gd .co-card-stat b {
    font-size: 15px; font-weight: 850; letter-spacing: -.02em;
    color: var(--gd-ink); line-height: 1.1;
    max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gd .co-card-stat span {
    font-size: 9.5px; font-weight: 700; letter-spacing: .045em; text-transform: uppercase;
    color: var(--gd-faint); line-height: 1.2;
}

/* ── Tags ───────────────────────────────────────────────────────────────── */

.gd .co-card-tags { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 1px; }
.gd .co-card-tag {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 3px 8px; border-radius: 999px;
    font-size: 10.5px; font-weight: 700;
    background: var(--gd-line-soft); color: var(--gd-muted);
}
.gd .co-card-tag svg { width: 11px; height: 11px; }
.gd .co-card-tag.is-featured { background: var(--gd-red-soft); color: var(--gd-red); }
.gd .co-card-tag.is-acquired { background: rgba(var(--a), .12); color: rgb(var(--a)); }
.gd .co-card-tag.is-closed   { background: var(--gd-line-soft); color: var(--gd-faint); }

/* ── The action ─────────────────────────────────────────────────────────── */

/*
 * A FILLED action, not a text link.
 *
 * This is the single thing that makes a card of facts read as a card you can
 * act on: a solid bar of the company's own colour at the foot, the same width
 * as the card. A tinted underline asks to be noticed; a filled button is the
 * thing you were looking for.
 *
 * The gradient is built from --a at two lightnesses via colour-mix, so one
 * custom property still drives it and no company is named here. colour-mix is
 * in every current browser; the flat rgb() declared first is what a browser
 * without it falls back to, and that is a perfectly good button.
 */
.gd .co-card-go {
    display: flex; align-items: center; justify-content: center; gap: 8px;
    margin-top: auto;
    margin-inline: -2px;
    padding: 11px 14px;
    border-radius: 12px;
    background: rgb(var(--a));
    background: linear-gradient(140deg,
        color-mix(in srgb, rgb(var(--a)) 82%, #FFFFFF),
        rgb(var(--a)));
    color: #FFFFFF;
    font-size: 12.5px; font-weight: 800; letter-spacing: -.005em;
    text-decoration: none;
    box-shadow: 0 8px 18px -10px rgba(var(--a), .95);
    transition: box-shadow .25s var(--gd-ease), transform .2s var(--gd-ease), filter .25s var(--gd-ease);
}
.gd .co-card:hover .co-card-go {
    box-shadow: 0 13px 24px -10px rgba(var(--a), 1);
    filter: saturate(1.08);
}
.gd .co-card-go svg { transition: transform .25s var(--gd-ease); }
.gd .co-card:hover .co-card-go svg { transform: translateX(4px); }
/* It is aria-hidden and tabindex -1 — the card's stretched link is the real
   target — so it must never look like a second, separate focus stop. */
.gd .co-card-go:focus { outline: none; }

@media (prefers-reduced-motion: reduce) {
    .gd .co-card,
    .gd .co-card-art img,
    .gd .co-card-mark,
    .gd .co-card-go svg { transition: none; }
    .gd .co-card:hover { transform: none; }
    .gd .co-card:hover .co-card-art img { transform: none; }
    .gd .co-card-glow { animation: none !important; }
    .gd .co-card::before { animation: none !important; }
    .gd .co-card::after  { display: none; }
}

/* ── List variant ───────────────────────────────────────────────────────────
   The same card, laid on its side. Art becomes a fixed-width panel, the facts
   and figures run in a row rather than a column, and the action moves to the
   end — one component, two shapes, no second template to keep in step. */

.gd .co-card-row { flex-direction: row; align-items: stretch; border-radius: 16px; }
.gd .co-card-row .co-card-art { flex: 0 0 clamp(150px, 20%, 230px); aspect-ratio: auto; }
.gd .co-card-row .co-card-b {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
        'mark  stats'
        'name  stats'
        'role  stats'
        'facts action'
        'tags  action';
    align-items: center;
    gap: 3px 16px;
    padding: 13px 16px;
}
.gd .co-card-row .co-card-mark { grid-area: mark; margin-top: 0; width: 40px; height: 40px; border-radius: 11px; }
.gd .co-card-row .co-card-n     { grid-area: name; }
.gd .co-card-row .co-card-role  { grid-area: role; }
.gd .co-card-row .co-card-facts { grid-area: facts; flex-direction: row; flex-wrap: wrap; gap: 4px 14px; margin-top: 4px; }
.gd .co-card-row .co-card-tags  { grid-area: tags; }
.gd .co-card-row .co-card-stats { grid-area: stats; grid-auto-flow: column; grid-template-columns: none; align-self: center; }
.gd .co-card-row .co-card-stat  { min-width: 62px; }
.gd .co-card-row .co-card-go {
    grid-area: action;
    margin-top: 0; margin-inline: 0;
    justify-content: center; white-space: nowrap;
    padding: 9px 18px;
}

/* ── Filter rail: ownership switches and the rail foot ──────────────────── */

.gd .co-switches { display: flex; flex-direction: column; gap: 6px; }
.gd .co-switch {
    display: flex; align-items: center; gap: 9px;
    padding: 8px 10px;
    border: 1px solid var(--gd-line); border-radius: 10px;
    cursor: pointer;
    transition: border-color .18s var(--gd-ease), background .18s var(--gd-ease);
}
.gd .co-switch:hover { border-color: var(--gd-red-ring); }
/* The input stays in the DOM and stays focusable — it is the control. It is
   moved off-screen rather than display:none, which would take it out of the
   tab order and off a screen reader entirely. */
.gd .co-switch input {
    position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.gd .co-switch-b {
    flex: none; position: relative;
    width: 32px; height: 18px; border-radius: 999px;
    background: var(--gd-line);
    transition: background .2s var(--gd-ease);
}
.gd .co-switch-b::after {
    content: ''; position: absolute; top: 2px; left: 2px;
    width: 14px; height: 14px; border-radius: 50%;
    background: var(--gd-surface);
    box-shadow: 0 1px 3px rgba(16, 24, 40, .3);
    transition: translate .2s var(--gd-ease);
}
.gd .co-switch input:checked + .co-switch-b { background: var(--gd-red); }
.gd .co-switch input:checked + .co-switch-b::after { translate: 14px 0; }
.gd .co-switch input:focus-visible + .co-switch-b { outline: 3px solid var(--gd-red-ring); outline-offset: 2px; }
.gd .co-switch-t {
    display: flex; align-items: center; gap: 6px;
    font-size: 13px; font-weight: 650; color: var(--gd-body);
}
.gd .co-switch-t svg { width: 12px; height: 12px; color: var(--gd-faint); }
.gd .co-switch input:checked ~ .co-switch-t { color: var(--gd-ink); }
.gd .co-switch input:checked ~ .co-switch-t svg { color: var(--gd-red); }

.gd .co-apply {
    display: flex; align-items: center; justify-content: center; gap: 8px;
    width: 100%; margin-top: 4px;
    padding: 11px 14px;
    border: 0; border-radius: 11px; cursor: pointer;
    background: linear-gradient(140deg, #FF5E58, var(--gd-red));
    color: #FFF; font: inherit; font-weight: 750; font-size: 13.5px;
    box-shadow: 0 10px 22px -12px rgba(229, 27, 35, .9);
    transition: transform .16s var(--gd-ease), box-shadow .16s var(--gd-ease);
}
.gd .co-apply:hover { transform: translateY(-1px); box-shadow: 0 14px 26px -12px rgba(229, 27, 35, 1); }
.gd .co-apply:focus-visible { outline: 3px solid var(--gd-red-ring); outline-offset: 3px; }

.gd .co-suggest {
    margin-top: 14px;
    padding: 16px;
    border: 1px solid var(--gd-line); border-radius: 16px;
    background: var(--gd-surface);
    box-shadow: 0 1px 2px rgba(16, 24, 40, .04);
    text-align: center;
}
.gd .co-suggest-i {
    display: inline-grid; place-items: center;
    width: 40px; height: 40px; margin-bottom: 8px;
    border-radius: 12px;
    background: var(--gd-red-soft); color: var(--gd-red);
}
.gd .co-suggest b { display: block; font-size: 13.5px; font-weight: 800; color: var(--gd-ink); }
.gd .co-suggest p { margin: 4px 0 11px; font-size: 12px; color: var(--gd-muted); line-height: 1.5; }

/* ── The quick-filter bar ───────────────────────────────────────────────────
   The horizontal row above the results: the facets a reader reaches for most,
   beside the sort and the view switch.

   It binds the SAME Livewire properties the rail binds. Two surfaces, one
   state — change a facet in either and both update, because neither of them
   holds the value. */

.gd .co-quick {
    display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
    margin-bottom: 12px;
    padding: 10px;
    border: 1px solid var(--gd-line); border-radius: 15px;
    background: var(--gd-surface);
    box-shadow: 0 1px 2px rgba(16, 24, 40, .04);
}
.gd .co-quick-s {
    display: flex; align-items: center; gap: 8px;
    flex: 1 1 210px; min-width: 0;
    padding: 0 12px;
    border: 1px solid var(--gd-line); border-radius: 10px;
    background: var(--gd-canvas);
}
.gd .co-quick-s:focus-within { border-color: var(--gd-red-ring); background: var(--gd-surface); }
.gd .co-quick-s > svg { flex: none; color: var(--gd-faint); }
.gd .co-quick-s input {
    flex: 1 1 auto; min-width: 0;
    border: 0; background: none; outline: none; box-shadow: none;
    font: inherit; font-size: 13.5px; color: var(--gd-ink);
    padding: 10px 0;
}
.gd .co-quick-s input::placeholder { color: var(--gd-faint); }
.gd .co-quick-s input::-webkit-search-cancel-button { display: none; }

.gd .co-quick .gd-select {
    flex: 0 1 auto; width: auto; min-width: 0;
    padding: 10px 30px 10px 12px;
    font-size: 13px;
    border-radius: 10px;
    background-color: var(--gd-canvas);
}
.gd .co-quick .gd-select:focus { background-color: var(--gd-surface); }
/* A facet holding a value says so without being opened. */
.gd .co-quick .gd-select.is-on {
    border-color: var(--gd-red-ring);
    background-color: var(--gd-red-soft);
    color: var(--gd-red);
    font-weight: 700;
}

.gd .co-quick-sp { flex: 1 1 auto; }
.gd .co-quick-sort { display: flex; align-items: center; gap: 7px; flex: 0 0 auto; }
.gd .co-quick-sort > span { font-size: 12.5px; color: var(--gd-muted); white-space: nowrap; }

/* ══ RESPONSIVE ═════════════════════════════════════════════════════════════
   The grid is intrinsic — `auto-fill` with a floor, so the column count is
   whatever the available width supports rather than a number this file has to
   guess per breakpoint. That is what makes it correct on an ultra-wide as well
   as on a laptop, and it needs no rule at all in between. */

@media (max-width: 1080px) {
    .gd .co-card-row .co-card-b {
        grid-template-columns: minmax(0, 1fr);
        grid-template-areas: 'mark' 'name' 'role' 'facts' 'stats' 'tags' 'action';
        gap: 5px;
    }
    .gd .co-card-row .co-card-stats { grid-auto-flow: column; justify-content: start; margin-top: 6px; }
    .gd .co-card-row .co-card-go { justify-content: flex-start; padding-top: 10px; border-top: 1px solid var(--gd-line-soft); }
}

@media (max-width: 720px) {
    .gd .co-card-row { flex-direction: column; }
    .gd .co-card-row .co-card-art { flex: none; aspect-ratio: 16 / 8.4; }
    .gd .co-card-row .co-card-mark { margin-top: calc(-1 * (var(--tile, 52px) / 2 + 12px)); }

    .gd .co-quick { gap: 7px; padding: 9px; border-radius: 13px; }
    .gd .co-quick-s { flex: 1 1 100%; }
    .gd .co-quick .gd-select { flex: 1 1 calc(50% - 4px); }
    .gd .co-quick-sp { display: none; }
    .gd .co-quick-sort { flex: 1 1 100%; }
    .gd .co-quick-sort .gd-select { flex: 1 1 auto; }
}

@media (max-width: 420px) {
    .gd .co-card-stat b { font-size: 13.5px; }
    .gd .co-card-b { padding: 11px 13px 13px; }
}

/* ── Loading skeletons ──────────────────────────────────────────────────── */

/* Hidden in the stylesheet so they never flash before Livewire boots; the
   wire:loading directive sets an inline display while a request is in flight,
   which is what reveals them. */
.gd .co-skeletons { display: none; margin-bottom: 18px; }
.gd .is-dimmed { opacity: .45; pointer-events: none; transition: opacity .15s var(--gd-ease); }

.gd .co-skeleton { pointer-events: none; }
.gd .co-skeleton:hover { transform: none; box-shadow: none; border-color: var(--gd-line); }
.gd .co-sk-line,
.gd .co-skeleton .co-card-logo {
    display: block;
    background: linear-gradient(90deg, var(--gd-line-soft) 25%, var(--gd-line) 37%, var(--gd-line-soft) 63%);
    background-size: 400% 100%;
    animation: co-sk 1.4s ease infinite;
    border-radius: 8px;
}
.gd .co-sk-line { height: 12px; margin-bottom: 9px; }
.gd .co-sk-line.is-w80 { width: 80%; }
.gd .co-sk-line.is-w60 { width: 60%; }
.gd .co-sk-line.is-w50 { width: 50%; height: 42px; border-radius: var(--gd-r-sm); }
.gd .co-sk-line.is-w40 { width: 40%; }

@keyframes co-sk {
    0%   { background-position: 100% 50%; }
    100% { background-position: 0 50%; }
}
@media (prefers-reduced-motion: reduce) {
    .gd .co-sk-line, .gd .co-skeleton .co-card-logo { animation: none; }
    .gd .co-card, .gd .co-search, .gd .co-pop-c, .gd .co-search-b { transition: none; }
    .gd .co-card:hover { transform: none; }
}

/* ── Responsive ─────────────────────────────────────────────────────────── */

/* ── Grid density ───────────────────────────────────────────────────────
   Company cards carry text, not cover art, so they do not inherit the game
   grid's tile widths: four across a desktop, two or three on a tablet, one on
   a phone. A 148px company card — which is what .gd-cards drops to — would put
   a name, a type, three facts and a button in a column too narrow to read. */
.gd .co-results { grid-template-columns: repeat(auto-fill, minmax(238px, 1fr)); }

@media (max-width: 900px) {
    .gd .co-results { grid-template-columns: repeat(auto-fill, minmax(216px, 1fr)); gap: 14px; }
    .gd .co-hero-t { letter-spacing: -.035em; }
    .gd .co-hero-in { padding: 22px 0 26px; }
    /* The glance band reflows to fewer columns rather than scrolling: it is a
       short list of figures, not a rail. */
    .gd .co-glance-row { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
}

@media (max-width: 620px) {
    /* One column. Not a shrunken desktop grid — a full-width card is the only
       shape these facts fit on a phone. */
    .gd .co-results { grid-template-columns: minmax(0, 1fr); gap: 12px; }
    .gd .co-card { padding: 16px; }
    .gd .co-card-logo { height: 84px; }

    .gd .co-search { padding: 6px 6px 6px 14px; }
    .gd .co-search-i { height: 46px; font-size: 15px; padding: 0 10px; }
    .gd .co-search-b { width: 46px; height: 46px; }
    .gd .co-pop { gap: 7px; }
    .gd .co-pop-l { width: 100%; }

    /* One column, and the row variant folds into the card shape rather than
       squeezing four columns of facts into a phone. */
    .gd .co-card-row { flex-direction: column; align-items: stretch; }
    .gd .co-card-row .co-card-logo { width: 100%; height: 84px; margin-bottom: 14px; }
    .gd .co-card-row .co-card-facts { grid-auto-flow: row; grid-auto-columns: auto; gap: 7px; }
    .gd .co-card-row .co-card-f { margin-top: 14px; }
}

/* =============================================================================
   COMPANIES HERO — the approved design
   -----------------------------------------------------------------------------
   Built to the reference in assets/img/company/herosection.png. Four rules
   carry the composition:

     • It is a SHOWCASE, not a carousel. All five featured companies are on
       screen together — no arrows, no dots, no scroll container, no sliding,
       at any width.
     • The deck is five cards SIDE BY SIDE with a small gap, each given the same
       lean and each stepping up as the row runs right. The lean is a rotate
       plus a skew, which is what tilts the vertical edges as well as the
       horizontal ones; a rotation alone reads as five crooked tiles.
     • Everything INSIDE a card is counter-transformed back to upright, so the
       frame leans and the artwork, the logo and the type do not.
     • The cards are sized against their COLUMN, so the group holds its
       proportions from a laptop to a 4K display without a media query per
       width, and the whole set never overflows the page.

   Each card carries --i (its index) from the template. Feature four companies
   instead of five and nothing here needs changing.
   ============================================================================= */

/* The hero runs wider than the article measure below it, as the approved
   design does — a five-card deck inside a 1280px column has no room to be a
   deck.

   Built from the site's own wide-container token rather than a number of its
   own, so the hero can never end up NARROWER than the results grid beneath it
   on a large display, which is what a fixed cap here would cause at 2560px and
   above. `max()` with 93vw closes the side margins on a laptop; the token's own
   ceiling stops a 4K display from stretching the measure past reading width. */
.gd .co-hero > .gd-wrap {
    /* `max()` against the site's own token so the hero can never end up
       NARROWER than the results grid beneath it on a large display; the inner
       `min()` closes the side margins on a laptop without letting a 2560px
       screen stretch the search field to a metre wide. */
    max-width: max(var(--bg-wrap-wide, 1280px), min(1700px, 93vw));
}

.gd .co-hero-grid {
    display: grid;
    grid-template-columns: minmax(0, .88fr) minmax(0, 1.12fr);
    align-items: center;
    gap: clamp(18px, 2vw, 44px);
    padding: clamp(16px, 2vw, 34px) 0 clamp(12px, 1.4vw, 22px);
}
/* The column can be wider than the copy should ever be. A search field that
   grows to fill 1000px stops reading as a field and starts reading as a bar. */
.gd .co-hero-copy { min-width: 0; max-width: 680px; position: relative; z-index: 2; }

/* ── The hero stage ─────────────────────────────────────────────────────────
   A CENTRED composition, not a two-column one. The directory opens on a title
   and a search box the reader aims at, with the featured companies fanned
   underneath as a single object. Everything sits on one axis so the eye travels
   title → search → cards without moving sideways.

   The stage stays light: white through very pale red, with the brand marks
   drawn behind it rather than over it. Nothing in this hero is dark. */

.gd .co-hero {
    position: relative;
    isolation: isolate;
    overflow: clip;
    padding: 26px 0 40px;
    background:
        radial-gradient(120% 90% at 50% -20%, rgba(229, 27, 35, .10) 0%, rgba(229, 27, 35, 0) 62%),
        linear-gradient(180deg, var(--gd-surface) 0%, var(--gd-canvas) 100%);
    border-bottom: 1px solid var(--gd-line);
}

/* ── Background furniture ───────────────────────────────────────────────────
   The streaks, dot field, sparkles and floating tiles from the approved
   design. Drawn with gradients and clip-paths rather than shipped as images:
   four more requests for shapes a browser can paint is four requests spent on
   nothing, and a gradient stays crisp at 4K.

   The whole layer is aria-hidden and pointer-events:none. None of it may ever
   sit between a reader and the search box. */

.gd .co-fx { position: absolute; inset: 0; z-index: -1; pointer-events: none; }

.gd .co-fx-dots {
    position: absolute; inset: 0;
    background-image: radial-gradient(currentColor 1px, transparent 1px);
    background-size: 22px 22px;
    color: rgba(229, 27, 35, .16);
    -webkit-mask-image: radial-gradient(90% 60% at 50% 12%, #000 0%, transparent 70%);
            mask-image: radial-gradient(90% 60% at 50% 12%, #000 0%, transparent 70%);
}

.gd .co-fx-streak {
    position: absolute; top: 12%;
    width: 46vw; height: 190px;
    background: linear-gradient(96deg,
        rgba(229, 27, 35, 0) 0%,
        rgba(229, 27, 35, .16) 45%,
        rgba(255, 106, 100, .30) 70%,
        rgba(229, 27, 35, 0) 100%);
    filter: blur(2px);
    border-radius: 999px;
}
.gd .co-fx-streak.is-l { left: -18vw; transform: rotate(-14deg); }
.gd .co-fx-streak.is-r { right: -18vw; transform: rotate(166deg); }

/* Four-pointed stars — the design's accent mark. */
.gd .co-fx-star {
    position: absolute;
    width: var(--s, 14px); height: var(--s, 14px);
    background: var(--gd-red);
    opacity: var(--o, .5);
    clip-path: polygon(50% 0%, 60% 40%, 100% 50%, 60% 60%, 50% 100%, 40% 60%, 0% 50%, 40% 40%);
}

.gd .co-fx-tile {
    position: absolute;
    display: grid; place-items: center;
    width: 76px; height: 76px;
    border-radius: 22px;
    background: var(--gd-surface);
    color: var(--gd-red);
    box-shadow: 0 18px 40px -18px rgba(229, 27, 35, .45), 0 2px 8px rgba(16, 24, 40, .06);
    animation: co-float 7s ease-in-out infinite;
}
.gd .co-fx-tile svg { width: 34px; height: 34px; }
.gd .co-fx-tile.is-l { left: 6%;  top: 78px;  transform: rotate(-8deg); }
.gd .co-fx-tile.is-r { right: 6%; top: 100px; transform: rotate(9deg); animation-delay: -3.5s; }

@keyframes co-float {
    0%, 100% { translate: 0 0; }
    50%      { translate: 0 -14px; }
}

/* ── The masthead ───────────────────────────────────────────────────────────
   Three stacked lines, heavy and tight, with the middle line — the word that
   names the section — largest and in the brand red.

   The lean is a skew, not `font-style: italic`. A face with no true italic gets
   a synthesised slant that differs by platform; a skew is the same angle in
   every browser and survives a font swap.

   Sized in clamp() rather than at breakpoints: the title is the one element
   here that has to stay proportional to the viewport at every width, and four
   breakpoints would still leave gaps between them. */

.gd .co-tt {
    margin: 0 auto;
    display: flex; flex-direction: column; align-items: center;
    gap: clamp(0px, .2vw, 4px);
    text-transform: uppercase;
    /*
     * A DISPLAY FACE, and only here.
     *
     * Saira 900 italic: heavy, geometric, flat-apexed, with a true italic
     * rather than a synthesised slant — the masthead treatment the approved
     * design uses. It is loaded on the same Google Fonts request as Inter, so
     * it costs no extra round trip, and it is scoped to this one element: the
     * rest of the page, and the rest of the site, stay on Inter.
     *
     * The fallback chain ends at Inter, so a blocked font request degrades to
     * a heavy sans rather than to a serif.
     */
    font-family: 'Saira', 'Inter', system-ui, sans-serif;
    font-weight: 900;
    font-style: italic;
    letter-spacing: -.022em;
    line-height: .9;
}
.gd .co-tt > span { display: block; }

.gd .co-tt-1,
.gd .co-tt-3 {
    color: var(--gd-ink);
    text-shadow: 0 2px 0 rgba(255, 255, 255, .85), 0 10px 26px rgba(16, 24, 40, .12);
}
.gd .co-tt-1 { font-size: clamp(30px, 4.4vw, 62px); }
.gd .co-tt-3 { font-size: clamp(26px, 3.7vw, 52px); }

/*
 * The accent line: a red that lightens across the word, as the design reads.
 * background-clip: text carries no colour of its own, so the ::before paints
 * the same word flat underneath — a browser that cannot composite the gradient
 * shows a solid red word rather than an invisible one.
 */
.gd .co-tt-2 {
    position: relative;
    font-size: clamp(40px, 6.6vw, 94px);
    background: linear-gradient(96deg, #B3121A 0%, var(--gd-red) 38%, #FF5E58 100%);
    -webkit-background-clip: text;
            background-clip: text;
    color: transparent;
    -webkit-text-fill-color: transparent;
    filter: drop-shadow(0 8px 20px rgba(229, 27, 35, .30));
}
.gd .co-tt-2::before {
    content: attr(data-t);
    position: absolute; inset: 0; z-index: -1;
    color: var(--gd-red);
    -webkit-text-fill-color: var(--gd-red);
}

/* A dark theme still needs the ink lines readable.

   Keyed like every other dark rule in this file — the OS preference, then the
   explicit class on an ancestor or on `.gd` itself. This was written as
   `:root[data-theme="dark"]`, which matches nothing here: the site marks the
   theme with a CLASS, on <body> or on the `.gd` wrapper depending on the
   layout, so the rule never applied and the masthead stayed dark-on-dark. */
@media (prefers-color-scheme: dark) {
    .gd .co-tt-1,
    .gd .co-tt-3 {
        color: #FFF;
        text-shadow: 0 2px 0 rgba(0, 0, 0, .4), 0 10px 26px rgba(0, 0, 0, .5);
    }
}
.theme-light .gd .co-tt-1, .gd.theme-light .co-tt-1,
.theme-light .gd .co-tt-3, .gd.theme-light .co-tt-3 {
    color: var(--gd-ink);
    text-shadow: none;
}
.theme-dark .gd .co-tt-1, .gd.theme-dark .co-tt-1,
.theme-dark .gd .co-tt-3, .gd.theme-dark .co-tt-3 {
    color: #FFF;
    text-shadow: 0 2px 0 rgba(0, 0, 0, .4), 0 10px 26px rgba(0, 0, 0, .5);
}

.gd .co-hero-x {
    max-width: 34em;
    margin: 18px auto 0;
    text-align: center;
    font-size: clamp(14px, 1.05vw, 16.5px);
    line-height: 1.6;
    color: var(--gd-muted);
}

/* ── The search ─────────────────────────────────────────────────────────────
   The hero's main object: the widest thing on the line and the only control.
   A red tile left, the field, a red action right.

   The outer ring is a shadow rather than a second border, so focus can thicken
   it without the box changing size and shifting the row below. */

.gd .co-search {
    display: flex; align-items: center; gap: 10px;
    width: min(820px, 100%);
    margin: 26px auto 0;
    padding: 9px 9px 9px 10px;
    border-radius: 999px;
    background: var(--gd-surface);
    border: 1px solid var(--gd-line);
    /* No tinted ring at rest — the field is white on white with one hairline.
       Red is reserved for focus, where it means something. */
    box-shadow: 0 18px 44px -24px rgba(16, 24, 40, .28);
    transition: box-shadow .2s ease, border-color .2s ease;
}
.gd .co-search:focus-within {
    border-color: var(--gd-red-ring);
    box-shadow: 0 0 0 4px rgba(229, 27, 35, .12), 0 18px 44px -20px rgba(229, 27, 35, .34);
}

.gd .co-search-ic {
    flex: none;
    display: grid; place-items: center;
    width: 46px; height: 46px;
    border-radius: 14px;
    background: linear-gradient(140deg, #FF5E58, var(--gd-red));
    color: #FFF;
    box-shadow: 0 8px 18px -8px rgba(229, 27, 35, .7);
}

.gd .co-search-i {
    flex: 1 1 0; min-width: 0;
    /* The sheet frames inputs; inside the pill that frame is a second box
       around a box. All three of border, shadow and ring are cleared. */
    border: 0; box-shadow: none; background: none; outline: none;
    font: inherit;
    font-size: clamp(14px, 1.05vw, 16px);
    color: var(--gd-ink);
    padding: 0 2px;
}
.gd .co-search-i::placeholder { color: var(--gd-faint); }
.gd .co-search-i::-webkit-search-cancel-button { display: none; }

.gd .co-search-b {
    /* 0 0 auto AND a min-width: the field is the elastic element here, never
       the action. Without the floor, a long placeholder pushes the row over
       its width and the browser takes the difference out of the button — which
       is how "Search" ends up rendering as 50px of clipped text. */
    flex: 0 0 auto;
    min-width: max-content;
    white-space: nowrap;
    display: inline-flex; align-items: center; gap: 8px;
    height: 46px; padding: 0 22px;
    border: 0; border-radius: 999px; cursor: pointer;
    background: linear-gradient(140deg, #FF5E58, var(--gd-red));
    color: #FFF; font: inherit; font-weight: 700; font-size: 14.5px;
    box-shadow: 0 10px 22px -10px rgba(229, 27, 35, .8);
    transition: transform .16s ease, box-shadow .16s ease;
}
.gd .co-search-b:hover { transform: translateY(-1px); box-shadow: 0 14px 26px -10px rgba(229, 27, 35, .9); }
.gd .co-search-b:active { transform: translateY(0); }
.gd .co-search-b:focus-visible { outline: 3px solid var(--gd-red-ring); outline-offset: 3px; }

/* ── The showcase arc ───────────────────────────────────────────────────────
   Five cards fanned on a shallow curve: the middle card upright and highest,
   each step outward rotated further and dropped lower.

   THE ARC IS ARITHMETIC, NOT PLACEMENT. Every card carries its signed distance
   from the centre of the set (--o, for the direction of the lean) and its
   unsigned distance (--ao, for how far it drops), both written by the template
   from the set's own length. Three companies fan as correctly as five, and
   neither needs a rule naming a position.

   No carousel, no arrows, no desktop scrolling: all five are on screen at once,
   which is what makes it a showcase rather than a slider. */

.gd .co-arc-wrap {
    width: min(1320px, 100%);
    margin: clamp(30px, 4vw, 54px) auto 0;
    padding: 0 clamp(12px, 2vw, 24px);
}

.gd .co-arc {
    list-style: none; margin: 0; padding: 0;
    display: grid;
    grid-template-columns: repeat(var(--n, 5), minmax(0, 1fr));
    gap: clamp(10px, 1.1vw, 18px);
    align-items: start;
    /* Room for the lean and the lift, so neither is clipped by the hero's
       own `overflow: clip`. */
    padding-block: 10px 26px;

    /*
     * The set is capped at a card width per company and centred, so a short
     * arc stays an arc of cards instead of being stretched into a billboard.
     *
     * `1fr` tracks divide whatever they are given, which is correct at five and
     * wrong at one: with a single featured company the lone track took the full
     * 1272px column and the card's 16/12 art rendered 1270x952 — one photograph
     * taller than the viewport standing where a row of cards belongs.
     *
     * At five this cap is 1340px, wider than the 1272px the wrapper actually
     * offers, so it never binds and the intended layout is untouched. It only
     * engages at the small counts that had no case before — which is also why
     * it is a cap rather than a fixed track size.
     */
    max-width: calc(var(--n, 5) * 268px);
    margin-inline: auto;
}

.gd .co-arc-i {
    --lean: calc(var(--o) * 2.6deg);
    --drop: calc(var(--ao) * 8px);

    min-width: 0;
    transform: rotate(var(--lean)) translateY(var(--drop));
    transform-origin: 50% 120%;
    z-index: var(--z, 1);
    transition: transform .34s ease;
}

/* Hover lifts one card out of the fan and levels it: the set stays a set, and
   the card being read is straight. */
.gd .co-arc-i:hover,
.gd .co-arc-i:focus-within {
    transform: rotate(0deg) translateY(calc(var(--drop) - 10px)) scale(1.03);
    z-index: 20;
}

@media (prefers-reduced-motion: reduce) {
    .gd .co-arc-i { transition: none; }
    .gd .co-fx-tile { animation: none; }
    .gd .co-cc::before { animation: none; }
    .gd .co-cc-shine { display: none; }
}

/* ── The showcase card ──────────────────────────────────────────────────────
   Art on top, the company's own mark straddling the seam, facts below, a tinted
   strip at the foot.

   All four tints are ONE custom property, --a, holding this company's accent as
   an "R, G, B" triple, set on the element by the template from the company
   record. There is no company named anywhere in this stylesheet. */

/*
 * An animatable angle. Registering it is what lets the conic gradient below
 * actually TURN: a plain custom property is a string to the animation engine
 * and jumps from 0deg to 360deg in one frame, which is why an unregistered
 * conic "rotation" looks like nothing is happening.
 */
@property --co-ang {
    syntax: '<angle>';
    initial-value: 0deg;
    inherits: false;
}

.gd .co-cc {
    position: relative;
    display: flex; flex-direction: column;
    /* Taller than wide, as the design draws it. A minimum rather than a fixed
       height: a long company name may take a second line and must not be
       clipped, and the games strip is pushed to the foot so five cards of
       different content still end level. */
    min-height: clamp(330px, 25vw, 396px);
    border-radius: 22px;
    background: var(--gd-surface);
    border: 1px solid var(--gd-line);
    box-shadow: 0 22px 44px -26px rgba(16, 24, 40, .40), 0 2px 6px rgba(16, 24, 40, .05);
    overflow: hidden;
    transition: box-shadow .3s ease, border-color .3s ease;
}

/*
 * THE TRAVELLING EDGE LIGHT.
 *
 * A conic gradient in the company's own colour, drawn as a ring by masking out
 * everything except a 2px band at the edge (content-box XOR border-box), and
 * turned by animating --co-ang. The light runs around the card rather than
 * sitting on it — a static glow reads as a highlight, a moving one reads as
 * alive, which is the difference being asked for.
 *
 * Idle cost is nothing: opacity 0, no animation, and the keyframes only run
 * while the card is hovered or holds focus.
 */
.gd .co-cc::before {
    content: '';
    position: absolute; inset: 0; z-index: 4;
    border-radius: inherit;
    padding: 2px;
    background: conic-gradient(from var(--co-ang),
        transparent 0deg 40deg,
        rgba(var(--a), .95) 78deg,
        #FFFFFF 92deg,
        rgba(var(--a), .95) 106deg,
        transparent 150deg 360deg);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
            mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
            mask-composite: exclude;
    opacity: 0;
    pointer-events: none;
    transition: opacity .28s ease;
}
.gd .co-arc-i:hover .co-cc::before,
.gd .co-arc-i:focus-within .co-cc::before {
    opacity: 1;
    animation: co-orbit 2.4s linear infinite;
}
@keyframes co-orbit { to { --co-ang: 360deg; } }

/*
 * THE SWEEP. A band of light that crosses the face of the card once on hover,
 * the way light moves over a card you have just picked up. One pass, not a
 * loop: a sheen that never stops is a distraction rather than a response.
 */
.gd .co-cc-shine {
    position: absolute; inset: 0; z-index: 5;
    border-radius: inherit;
    overflow: hidden;
    pointer-events: none;
}
.gd .co-cc-shine::before {
    content: '';
    position: absolute; top: -60%; left: -150%;
    width: 55%; height: 220%;
    transform: rotate(16deg);
    background: linear-gradient(100deg,
        rgba(255, 255, 255, 0) 0%,
        rgba(255, 255, 255, .35) 42%,
        rgba(255, 255, 255, .75) 50%,
        rgba(255, 255, 255, .35) 58%,
        rgba(255, 255, 255, 0) 100%);
}
.gd .co-arc-i:hover .co-cc-shine::before,
.gd .co-arc-i:focus-within .co-cc-shine::before {
    animation: co-sweep 1s cubic-bezier(.22, .61, .36, 1);
}
@keyframes co-sweep { to { left: 190%; } }

.gd .co-arc-i:hover .co-cc,
.gd .co-arc-i:focus-within .co-cc {
    border-color: rgba(var(--a), .45);
    box-shadow: 0 34px 62px -22px rgba(var(--a), .50), 0 4px 12px rgba(16, 24, 40, .08);
}

/* The card's own content sits above the ring but below the sweep. */
.gd .co-cc-art,
.gd .co-cc-b { position: relative; z-index: 1; }

.gd .co-cc-art {
    position: relative;
    display: block;
    aspect-ratio: 16 / 12;
    background: linear-gradient(150deg, rgba(var(--a), .22), rgba(var(--a), .06));
    overflow: hidden;
}
.gd .co-cc-art img {
    width: 100%; height: 100%;
    object-fit: cover;
    display: block;
    transition: transform .5s ease;
}
.gd .co-arc-i:hover .co-cc-art img { transform: scale(1.06); }

/* The accent wash that ties the picture to the company's colour, over a floor
   of shade that keeps the white pills legible on a bright photograph. */
.gd .co-cc-tint {
    position: absolute; inset: 0;
    /* Light enough to tie the picture to the company's colour, not so heavy
       that it becomes the picture. The shade at the top is only what the white
       pills need to stay legible over a bright photograph. */
    background:
        linear-gradient(180deg, rgba(10, 12, 16, .30) 0%, rgba(10, 12, 16, 0) 40%),
        linear-gradient(150deg, rgba(var(--a), .30) 0%, rgba(var(--a), .05) 100%);
    mix-blend-mode: multiply;
}

/* No artwork: the company's colour carries the panel rather than a grey box. */
.gd .co-cc-art.is-blank { display: grid; place-items: center;
    background: linear-gradient(150deg, rgba(var(--a), .30), rgba(var(--a), .10)); }
.gd .co-cc-art.is-blank img { width: 44%; height: auto; object-fit: contain; opacity: .5; }

.gd .co-cc-verified {
    position: absolute; top: 10px; left: 10px; z-index: 3;
    display: inline-flex; align-items: center; gap: 5px;
    padding: 4px 9px 4px 5px;
    border-radius: 999px;
    background: rgba(12, 14, 18, .62);
    -webkit-backdrop-filter: blur(6px);
            backdrop-filter: blur(6px);
    color: #FFF;
    font-size: 9.5px; font-weight: 800; letter-spacing: .07em; text-transform: uppercase;
}
.gd .co-cc-verified i {
    display: grid; place-items: center;
    width: 13px; height: 13px; border-radius: 50%;
    background: rgb(var(--a)); color: #FFF;
}
.gd .co-cc-verified svg { width: 8px; height: 8px; }

/* The heart. A real control, so a real button — above the card's stretched
   link, with a focus ring of its own. */
.gd .co-cc-fav {
    position: absolute; top: 9px; right: 9px; z-index: 4;
    display: grid; place-items: center;
    width: 30px; height: 30px;
    border: 0; border-radius: 50%; cursor: pointer;
    background: rgba(255, 255, 255, .22);
    -webkit-backdrop-filter: blur(6px);
            backdrop-filter: blur(6px);
    color: #FFF;
    transition: background .18s ease, transform .18s ease, color .18s ease;
}
.gd .co-cc-fav:hover { background: rgba(255, 255, 255, .4); transform: scale(1.1); }
.gd .co-cc-fav:focus-visible { outline: 3px solid #FFF; outline-offset: 2px; }
.gd .co-cc-fav.is-on { background: #FFF; color: var(--gd-red); }
.gd .co-cc-fav.is-on svg { fill: currentColor; }
.gd .co-cc-fav svg { width: 15px; height: 15px; }

/*
 * The logo tile, straddling art and body.
 *
 * A FLOW child of the body with a negative margin, not an absolutely positioned
 * child of the card. Absolute positioning would have to measure from one edge
 * or the other: `bottom` puts it below the card's foot, and `top` would need
 * the art's rendered height — a number that changes the moment the art ratio
 * does. Pulling it up out of the body's own top padding lands it on the seam
 * whatever that ratio is, and it costs one margin.
 */
.gd .co-cc-logo {
    position: relative; z-index: 3;
    align-self: flex-start;
    margin-top: calc(-1 * (var(--tile, 52px) + 12px));
    margin-bottom: 2px;
    display: grid; place-items: center;
    width: var(--tile, 52px); height: var(--tile, 52px);
    border-radius: 15px;
    background: var(--gd-surface);
    border: 1px solid var(--gd-line);
    box-shadow: 0 8px 20px -8px rgba(16, 24, 40, .35);
    overflow: hidden;
}
/* CONTAIN, never cover: a wordmark cropped to fill a square is a broken logo. */
.gd .co-cc-logo img { width: 78%; height: 78%; object-fit: contain; display: block; }

.gd .co-cc-b {
    /* flex: 1 so the body takes the slack under a short art block, and the
       games strip below it can be pushed to the foot — five cards holding
       different amounts of text then still end on the same line. */
    flex: 1 1 auto;
    display: flex; flex-direction: column;
    gap: 6px;
    padding: 12px 15px 15px;
}

.gd .co-cc-n {
    display: flex; align-items: center; gap: 6px;
    margin: 0;
    font-size: clamp(14px, 1.05vw, 16.5px);
    font-weight: 800;
    letter-spacing: -.015em;
    color: var(--gd-ink);
    line-height: 1.25;
}
/*
 * The stretched link. The whole card is the target while the heart above keeps
 * its own: an <a> wrapping a <button> would be invalid markup AND would swallow
 * the heart's click.
 */
.gd .co-cc-n a { color: inherit; text-decoration: none; min-width: 0; }
.gd .co-cc-n a::after { content: ''; position: absolute; inset: 0; z-index: 2; border-radius: inherit; }
.gd .co-cc-n a:focus-visible { outline: none; }
.gd .co-arc-i:focus-within .co-cc { outline: 3px solid var(--gd-red-ring); outline-offset: 2px; }

.gd .co-cc-n i {
    flex: none;
    display: grid; place-items: center;
    width: 15px; height: 15px; border-radius: 50%;
    background: rgb(var(--a)); color: #FFF;
}
.gd .co-cc-n i svg { width: 9px; height: 9px; }

.gd .co-cc-role { font-size: 12px; font-weight: 700; color: rgb(var(--a)); line-height: 1.3; }

.gd .co-cc-meta {
    display: flex; align-items: flex-start; gap: 6px;
    font-size: 11.5px; color: var(--gd-muted); line-height: 1.35;
}
.gd .co-cc-meta svg { flex: none; width: 12px; height: 12px; margin-top: 1px; color: var(--gd-faint); }

.gd .co-cc-games {
    display: flex; align-items: center; gap: 7px;
    margin-top: auto;
    padding: 9px 11px;
    border-radius: 12px;
    background: rgba(var(--a), .10);
    color: rgb(var(--a));
    font-size: 12.5px; font-weight: 800;
    transition: background .2s ease;
}
.gd .co-arc-i:hover .co-cc-games { background: rgba(var(--a), .18); }
.gd .co-cc-games svg { flex: none; width: 15px; height: 15px; }
.gd .co-cc-games .co-cc-go { margin-left: auto; transition: transform .22s ease; }
.gd .co-arc-i:hover .co-cc-games .co-cc-go { transform: translateX(3px); }

/* ── Popular searches ───────────────────────────────────────────────────── */

.gd .co-pop {
    display: flex; align-items: center; justify-content: center;
    flex-wrap: wrap; gap: 8px;
    margin: clamp(18px, 2.4vw, 30px) auto 0;
}
.gd .co-pop-l { font-size: 13px; font-weight: 700; color: var(--gd-muted); margin-right: 2px; }
.gd .co-pop-more { position: relative; }
.gd .co-pop-more > summary { list-style: none; cursor: pointer; }
.gd .co-pop-more > summary::-webkit-details-marker { display: none; }
.gd .co-pop-caret { transition: transform .2s ease; }
.gd .co-pop-more[open] .co-pop-caret { transform: rotate(180deg); }
.gd .co-pop-rest {
    position: absolute; top: calc(100% + 8px); left: 50%; translate: -50% 0; z-index: 30;
    display: flex; flex-direction: column; gap: 6px;
    padding: 10px; min-width: 190px;
    border-radius: 14px;
    background: var(--gd-surface);
    border: 1px solid var(--gd-line);
    box-shadow: var(--gd-shadow-lg);
}

/* ── Companies at a glance ──────────────────────────────────────────────────
   ONE band divided by hairlines, as the design draws it — not six floating
   boxes, which is what turns a directory into a dashboard.

   Every figure is a live COUNT. The label and the note under it are the
   editor's words; there is deliberately nowhere in the admin to type a number.
   The tile count is whatever the data supports, so the row is auto-fit rather
   than a fixed five: a site with no publishers yet gets four tiles that still
   fill the band. */

/*
 * One compact strip, sitting inside the hero directly under the cards — the
 * band in the approved design, not a titled panel. No heading, no standfirst:
 * six figures explain themselves, and the vertical space a title would take is
 * space the hero needs for the cards above it.
 */
.gd .co-glance {
    width: min(1320px, 100%);
    margin: clamp(14px, 1.8vw, 24px) auto 0;
    padding: clamp(8px, .9vw, 13px) clamp(8px, 1vw, 14px);
    border-radius: 20px;
    background: var(--gd-surface);
    border: 1px solid var(--gd-line);
    box-shadow: 0 20px 46px -30px rgba(16, 24, 40, .40), 0 2px 6px rgba(16, 24, 40, .04);
}

.gd .co-glance-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    gap: 0;
    margin: 0;
}

.gd .co-glance-i {
    display: flex; align-items: center; gap: 11px;
    padding: 6px clamp(9px, 1.1vw, 16px);
    border-left: 1px solid var(--gd-line-soft);
    min-width: 0;
}
.gd .co-glance-i:first-child { border-left: 0; }

/* The hexagon mark, tinted per statistic. */
.gd .co-glance-ic {
    flex: none;
    display: grid; place-items: center;
    width: 42px; height: 42px;
    background: rgba(var(--tone), .12);
    color: rgb(var(--tone));
    clip-path: polygon(25% 3%, 75% 3%, 100% 50%, 75% 97%, 25% 97%, 0% 50%);
    transition: background .22s ease;
}
.gd .co-glance-i:hover .co-glance-ic { background: rgba(var(--tone), .2); }
.gd .co-glance-ic svg { width: 21px; height: 21px; }

.gd .co-glance-tx { display: flex; flex-direction: column; min-width: 0; }
.gd .co-glance-n {
    margin: 0;
    font-size: clamp(19px, 1.55vw, 25px); font-weight: 900; letter-spacing: -.025em;
    color: var(--gd-red); line-height: 1.08;
}
.gd .co-glance-l { font-size: 12.5px; font-weight: 750; color: var(--gd-ink); line-height: 1.2; }
/*
 * ONE LINE. The editor's note is a caption, not a paragraph: left to wrap it
 * takes three lines, trebles the height of every tile and turns a strip into a
 * block. It ellipsises instead and keeps the full text in the title attribute.
 */
.gd .co-glance-note {
    display: flex; align-items: center; gap: 4px;
    margin-top: 1px;
    font-size: 10.5px; color: var(--gd-faint); line-height: 1.3;
    white-space: nowrap; overflow: hidden;
}
.gd .co-glance-note > span {
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
.gd .co-glance-note svg { flex: none; width: 11px; height: 11px; color: rgb(var(--tone)); }

/* ══ RESPONSIVE ═════════════════════════════════════════════════════════════
   The five companies never change. Only their arrangement does.

   1180  the fan flattens — a 170px card cannot carry an 8° rotation without the
         type inside it reading as crooked rather than arranged.
    900  three across, upright, then wrapping — the set reflows rather than
         shrinking further.
    620  ONE ROW THAT SCROLLS, with snap points. Five cards stacked vertically
         is five screens of hero before the directory starts; a swipeable row
         keeps the showcase to one screen and keeps it a showcase. */

@media (max-width: 1180px) {
    .gd .co-arc-i { --lean: calc(var(--o) * 1.6deg); --drop: calc(var(--ao) * 5px); }
    .gd .co-cc-logo { --tile: 46px; }
    .gd .co-fx-tile { width: 60px; height: 60px; border-radius: 18px; }
    .gd .co-fx-tile svg { width: 27px; height: 27px; }
}

@media (max-width: 900px) {
    .gd .co-arc { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .gd .co-arc-i { --lean: 0deg; --drop: 0px; }
    .gd .co-fx-tile { display: none; }
    .gd .co-glance-i { border-left: 0; border-top: 1px solid var(--gd-line-soft); }
    .gd .co-glance-row > .co-glance-i:first-child { border-top: 0; }
}

@media (max-width: 620px) {
    .gd .co-hero { padding: 18px 0 28px; }

    .gd .co-arc-wrap { padding: 0; }
    .gd .co-arc {
        display: flex;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        gap: 12px;
        padding: 10px clamp(14px, 5vw, 22px) 22px;
    }
    .gd .co-arc::-webkit-scrollbar { display: none; }
    .gd .co-arc-i { flex: 0 0 min(74vw, 268px); scroll-snap-align: center; }

    /* The search stacks: a 46px action beside a field on a 320px screen leaves
       the field too narrow to read what you typed. */
    .gd .co-search { flex-wrap: wrap; border-radius: 24px; padding: 10px; }
    .gd .co-search-i { order: 1; flex: 1 1 auto; width: 100%; padding: 4px 2px; }
    .gd .co-search-b { order: 2; width: 100%; justify-content: center; }
    .gd .co-search-ic { order: 0; }

    .gd .co-glance { border-radius: 18px; }
    .gd .co-glance-i { padding: 11px 8px; }
}

@media (max-width: 380px) {
    .gd .co-tt { letter-spacing: -.045em; }
    .gd .co-hero-x { font-size: 13.5px; }
    .gd .co-glance-note { display: none; }
}
/* =============================================================================
   COMPANY PROFILE — /companies/{slug}
   -----------------------------------------------------------------------------
   The directory's sibling, one level down. It inherits every token, the wrap and
   the game card from the sheet above; what is here is only the profile's own
   furniture.

   THE ACCENT IS A PROPERTY. `--a` is set once on the page root from the company
   record, and every tinted thing below reads it — the hero wash, the chips, the
   chain, the links, the CTA. Nothing in this file names a company, and the six
   hundredth needs no line here.

   THREE CARDS SCROLL INSIDE THEMSELVES. The timeline, the people list and the
   links list are `cp-scroller`: a company with forty events does not get a page
   three screens taller, and nobody is sent to a sub-page to read the rest of a
   list that belongs on this one.
   ============================================================================= */

.gd .cp-crumbs { margin: 14px 0 12px; }

/* ── Hero ───────────────────────────────────────────────────────────────────
   The banner IS the card. A veil over it does two jobs at once: it holds the
   white type at a readable contrast over any photograph, and it tints the whole
   panel toward the company's own colour. */

.gd .cp-hero {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    border-radius: 22px;
    min-height: 268px;
    /* --co, not --a: the hero is the one place the COMPANY's own colour
       belongs, because it sits over that company's own artwork. Everything
       else on this page is Barlin red. */
    background: linear-gradient(135deg, rgb(var(--co)), color-mix(in srgb, rgb(var(--co)) 55%, #0B0E14));
    box-shadow: 0 26px 56px -30px rgba(16, 24, 40, .55), 0 2px 8px rgba(16, 24, 40, .08);
}
.gd .cp-hero-bg {
    position: absolute; inset: 0; z-index: -2;
    width: 100%; height: 100%;
    object-fit: cover;
}
.gd .cp-hero-veil {
    position: absolute; inset: 0; z-index: -1;
    background:
        linear-gradient(100deg, rgba(9, 12, 18, .90) 0%, rgba(9, 12, 18, .62) 42%, rgba(9, 12, 18, .18) 100%),
        linear-gradient(180deg, rgba(var(--co), .30), rgba(var(--co), .08));
}

.gd .cp-hero-in {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: start;
    gap: clamp(16px, 2vw, 28px);
    padding: clamp(18px, 2.2vw, 26px);
}

/* The mark, on white. CONTAIN, never cover — a wordmark cropped to fill a
   square is a broken logo. */
.gd .cp-hero-mark {
    flex: none;
    display: grid; place-items: center;
    width: clamp(96px, 11vw, 145px); aspect-ratio: 1;
    border-radius: 18px;
    background: #FFFFFF;
    box-shadow: 0 18px 40px -18px rgba(0, 0, 0, .55);
    overflow: hidden;
}
.gd .cp-hero-mark img { width: 78%; height: 78%; object-fit: contain; display: block; }
.gd .cp-hero-mark img.is-fallback { width: 54%; height: 54%; opacity: .5; }

.gd .cp-hero-body { min-width: 0; color: #FFFFFF; }

.gd .cp-hero-vf {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 5px 11px 5px 7px; margin-bottom: 10px;
    border-radius: 999px;
    background: rgba(16, 185, 129, .92);
    color: #FFFFFF;
    font-size: 10.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
}
.gd .cp-hero-vf svg { width: 12px; height: 12px; }

.gd .cp-hero-n {
    margin: 0;
    font-size: clamp(26px, 3.2vw, 42px); font-weight: 850; letter-spacing: -.028em;
    line-height: 1.1;
    color: #FFFFFF;
    text-shadow: 0 2px 14px rgba(0, 0, 0, .4);
}
.gd .cp-hero-x {
    margin: 8px 0 0;
    max-width: 54ch;
    font-size: clamp(13.5px, 1vw, 15.5px); line-height: 1.55;
    color: rgba(255, 255, 255, .84);
}

.gd .cp-hero-facts {
    display: flex; flex-wrap: wrap; gap: 8px 20px;
    margin-top: 14px;
    font-size: 13px; color: rgba(255, 255, 255, .9);
}
.gd .cp-hero-facts span { display: inline-flex; align-items: center; gap: 7px; }
.gd .cp-hero-facts svg { color: rgba(255, 255, 255, .62); }

.gd .cp-hero-social { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.gd .cp-hero-soc {
    display: grid; place-items: center;
    width: 38px; height: 38px;
    border-radius: 11px;
    background: rgba(255, 255, 255, .14);
    -webkit-backdrop-filter: blur(8px);
            backdrop-filter: blur(8px);
    color: #FFFFFF;
    transition: background .18s var(--gd-ease), transform .18s var(--gd-ease);
}
.gd .cp-hero-soc:hover { background: #FFFFFF; color: rgb(var(--a)); transform: translateY(-2px); }
.gd .cp-hero-soc:focus-visible { outline: 3px solid #FFFFFF; outline-offset: 2px; }

/* ── Owned by ───────────────────────────────────────────────────────────── */

.gd .cp-owner {
    flex: none;
    width: clamp(200px, 17vw, 232px);
    padding: 14px;
    border-radius: 16px;
    background: var(--gd-surface);
    box-shadow: 0 20px 44px -22px rgba(0, 0, 0, .6);
}
.gd .cp-owner-l {
    display: block; margin-bottom: 9px;
    font-size: 10.5px; font-weight: 800; letter-spacing: .07em; text-transform: uppercase;
    color: var(--gd-faint);
}
.gd .cp-owner-co {
    display: flex; align-items: center; gap: 9px;
    text-decoration: none; color: var(--gd-ink);
}
.gd .cp-owner-co img {
    width: 34px; height: 34px; flex: none;
    object-fit: contain; border-radius: 8px;
    background: var(--gd-canvas); border: 1px solid var(--gd-line);
}
.gd .cp-owner-co b { font-size: 15px; font-weight: 800; letter-spacing: -.015em; min-width: 0; }
.gd .cp-owner-co:hover b { color: var(--gd-red); }
.gd .cp-owner-since { display: block; margin-top: 8px; font-size: 12px; color: var(--gd-muted); }
.gd .cp-owner-b {
    display: flex; align-items: center; justify-content: center; gap: 7px;
    margin-top: 12px; padding: 9px 12px;
    border: 1px solid rgba(var(--a), .32); border-radius: 10px;
    color: rgb(var(--a)); font-size: 12.5px; font-weight: 750;
    text-decoration: none;
    transition: background .18s var(--gd-ease);
}
.gd .cp-owner-b:hover { background: rgba(var(--a), .08); }

/* ── Section nav ────────────────────────────────────────────────────────────
   Tabs, and the one piece of chrome the reader touches most, so it is the one
   piece that earns some weight: a raised glass bar, a marker that TRAVELS
   between tabs rather than blinking from one to the next, and a light that
   crosses a tab as the pointer does.

   The marker is one element for the whole strip. Two pills cross-fading reads
   as two things; one pill moving reads as a single object you are steering,
   which is the difference between "a state changed" and "I did that". */

.gd .cp-nav {
    position: sticky; top: 0; z-index: 30;
    display: flex; align-items: center; gap: 12px;
    margin: 18px 0 20px;
    padding: 8px;
    border: 1px solid var(--gd-line); border-radius: 16px;
    background:
        linear-gradient(180deg,
            color-mix(in srgb, var(--gd-surface) 96%, transparent),
            color-mix(in srgb, var(--gd-surface) 86%, transparent));
    -webkit-backdrop-filter: blur(14px) saturate(140%);
            backdrop-filter: blur(14px) saturate(140%);
    box-shadow:
        0 1px 0 rgba(255, 255, 255, .55) inset,
        0 2px 4px rgba(16, 24, 40, .05),
        0 18px 36px -28px rgba(16, 24, 40, .5);
}
/* The inset highlight is a light-mode trick; in the dark theme a white inner
   edge looks like a rendering fault rather than glass.

   Keyed the way the rest of this file keys dark: the OS preference, then the
   explicit `.theme-dark` on an ancestor OR on `.gd` itself, because the class
   lands in different places depending on the layout. A `[data-theme]` selector
   would match nothing here. */
@media (prefers-color-scheme: dark) {
    .gd .cp-nav {
        box-shadow: 0 1px 0 rgba(255, 255, 255, .06) inset,
                    0 18px 36px -28px rgba(0, 0, 0, .9);
    }
}
.theme-light .gd .cp-nav, .gd.theme-light .cp-nav {
    box-shadow:
        0 1px 0 rgba(255, 255, 255, .55) inset,
        0 2px 4px rgba(16, 24, 40, .05),
        0 18px 36px -28px rgba(16, 24, 40, .5);
}
.theme-dark .gd .cp-nav, .gd.theme-dark .cp-nav {
    box-shadow: 0 1px 0 rgba(255, 255, 255, .06) inset,
                0 18px 36px -28px rgba(0, 0, 0, .9);
}

.gd .cp-nav-l {
    position: relative;
    display: flex; align-items: center; gap: 2px;
    flex: 1 1 auto; min-width: 0;
    overflow-x: auto; scrollbar-width: none;
}
.gd .cp-nav-l::-webkit-scrollbar { display: none; }

/* The travelling marker. left is never touched — only width and translateX —
   so the browser can keep the whole movement on the compositor. */
.gd .cp-nav-ind {
    position: absolute; left: 0; top: 0; bottom: 0; z-index: 0;
    width: 0; opacity: 0;
    border-radius: 11px;
    background: linear-gradient(180deg, rgba(var(--a), .16), rgba(var(--a), .09));
    box-shadow:
        0 0 0 1px rgba(var(--a), .22) inset,
        0 6px 16px -10px rgba(var(--a), .9);
    pointer-events: none;
    transition:
        transform .42s cubic-bezier(.34, 1.4, .5, 1),
        width .42s cubic-bezier(.34, 1.4, .5, 1),
        opacity .2s var(--gd-ease);
}

.gd .cp-nav-i {
    position: relative; z-index: 1; overflow: hidden;
    display: inline-flex; align-items: center; gap: 7px;
    padding: 9px 14px;
    border-radius: 11px;
    white-space: nowrap;
    font-size: 13.5px; font-weight: 650;
    color: var(--gd-muted); text-decoration: none;
    transition: color .2s var(--gd-ease), transform .2s var(--gd-ease);
}
/* The sweep. One pass across the tab, triggered by the pointer arriving —
   a moving highlight rather than a background that switches on. */
.gd .cp-nav-i::after {
    content: ''; position: absolute; inset: 0;
    border-radius: inherit;
    background: linear-gradient(105deg,
        transparent 30%,
        color-mix(in srgb, rgb(var(--a)) 16%, transparent) 48%,
        transparent 66%);
    transform: translateX(-115%);
    opacity: 0;
    pointer-events: none;
}
.gd .cp-nav-i:hover::after { animation: cp-sweep .62s var(--gd-ease); }
@keyframes cp-sweep {
    0%   { transform: translateX(-115%); opacity: 0; }
    35%  { opacity: 1; }
    100% { transform: translateX(115%); opacity: 0; }
}

.gd .cp-nav-i svg { color: var(--gd-faint); transition: color .2s var(--gd-ease), transform .3s var(--gd-ease); }
.gd .cp-nav-i:hover { color: var(--gd-ink); }
.gd .cp-nav-i:hover svg { color: rgb(var(--a)); transform: translateY(-1px) scale(1.06); }
.gd .cp-nav-i:active { transform: scale(.97); }
.gd .cp-nav-i:focus-visible { outline: 3px solid rgba(var(--a), .35); outline-offset: 2px; }

/* Colour, not weight. A bolder active label would be a WIDER active label,
   which would move every tab after it and make the travelling pill impossible
   to measure until after the class landed. */
.gd .cp-nav-i.is-on { color: rgb(var(--a)); }
.gd .cp-nav-i.is-on svg { color: rgb(var(--a)); }

.gd .cp-nav-b {
    flex: none; position: relative; overflow: hidden;
    display: inline-flex; align-items: center; gap: 7px;
    padding: 9px 15px;
    border: 1px solid var(--gd-line); border-radius: 11px;
    background: var(--gd-surface);
    font-size: 13px; font-weight: 700; color: var(--gd-body); text-decoration: none;
    transition: border-color .2s var(--gd-ease), color .2s var(--gd-ease),
                box-shadow .2s var(--gd-ease), transform .2s var(--gd-ease);
}
.gd .cp-nav-b:hover {
    border-color: rgba(var(--a), .4); color: rgb(var(--a));
    transform: translateY(-1px);
    box-shadow: 0 10px 22px -16px rgba(var(--a), .9);
}

/* ── Rows and cards ─────────────────────────────────────────────────────────
   `auto-fit` with a floor rather than a column count per breakpoint: the row
   holds three cards where three fit, two where two do, and one on a phone,
   without a rule in between. `align-items: stretch` is what keeps the three
   cards in a row the same height — the fix for the short About card sitting
   beside a tall neighbour with a pool of empty space under it. */

.gd .cp-row {
    display: grid;
    gap: clamp(12px, 1.3vw, 18px);
    margin-bottom: clamp(12px, 1.3vw, 18px);
    align-items: stretch;
}
.gd .cp-row-3 { grid-template-columns: repeat(auto-fit, minmax(304px, 1fr)); }
.gd .cp-row-2 { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
/* Headquarters is the narrower of the pair; the gallery earns the space. */
.gd .cp-row-hq { grid-template-columns: minmax(280px, 1fr) minmax(340px, 1.72fr); }

/* A card, with somewhere to stand.
   A flat fill and a hairline read as a box drawn on the page; a shallow
   gradient, a lit top edge and a shadow that sits UNDER rather than around it
   read as a surface above the page. The difference is a few percent of
   luminance and it is most of why one looks finished and the other does not. */
.gd .cp-card {
    position: relative; isolation: isolate; overflow: hidden;
    display: flex; flex-direction: column;
    padding: clamp(16px, 1.6vw, 22px);
    border: 1px solid var(--gd-line); border-radius: 18px;
    background:
        linear-gradient(180deg,
            color-mix(in srgb, var(--gd-surface) 100%, #FFFFFF) 0%,
            var(--gd-surface) 42%,
            color-mix(in srgb, var(--gd-surface) 97%, var(--gd-canvas)) 100%);
    box-shadow:
        0 1px 0 rgba(255, 255, 255, .6) inset,
        0 1px 2px rgba(16, 24, 40, .05),
        0 18px 38px -30px rgba(16, 24, 40, .55);
    min-width: 0;
    transition: box-shadow .3s var(--gd-ease), border-color .3s var(--gd-ease),
                transform .3s var(--gd-ease);
}

/* The catch-light: a short bright rule along the top edge, brightest in the
   middle, so a wide card still looks lit from one place rather than uniformly
   outlined. */
.gd .cp-card::before {
    content: ''; position: absolute; top: 0; left: 12%; right: 12%; height: 1px;
    background: linear-gradient(90deg,
        transparent,
        color-mix(in srgb, rgb(var(--a)) 45%, transparent),
        transparent);
    opacity: .5;
    transition: opacity .3s var(--gd-ease), left .5s var(--gd-ease), right .5s var(--gd-ease);
    pointer-events: none; z-index: 2;
}
.gd .cp-card:hover {
    border-color: color-mix(in srgb, rgb(var(--a)) 26%, var(--gd-line));
    box-shadow:
        0 1px 0 rgba(255, 255, 255, .6) inset,
        0 2px 4px rgba(16, 24, 40, .05),
        0 26px 52px -34px color-mix(in srgb, rgb(var(--a)) 55%, rgba(16, 24, 40, .6));
}
.gd .cp-card:hover::before { opacity: 1; left: 4%; right: 4%; }

/* The sweep. Slow and faint — a card is something you read, so the light
   crosses it once and gets out of the way rather than pulsing under the text. */
.gd .cp-card::after {
    content: ''; position: absolute; inset: 0;
    background: linear-gradient(115deg,
        transparent 34%,
        color-mix(in srgb, rgb(var(--a)) 7%, transparent) 50%,
        transparent 64%);
    transform: translateX(-110%);
    opacity: 0;
    pointer-events: none; z-index: 1;
}
.gd .cp-card:hover::after { animation: cp-card-sweep 1.05s var(--gd-ease); }
@keyframes cp-card-sweep {
    0%   { transform: translateX(-110%); opacity: 0; }
    30%  { opacity: 1; }
    100% { transform: translateX(110%); opacity: 0; }
}

/* Everything the card holds sits above both effects. */
.gd .cp-card > * { position: relative; z-index: 3; }

/* The dark theme wants a gentler version of the same idea. Light still falls
   from above, so the top stays the lighter end — but a dark surface lifted
   toward white goes grey fast, so the lift is small and the inner edge is a
   whisper rather than the bright rule light mode can carry.

   Same keying as the tokens themselves: OS preference, then the explicit
   class on an ancestor or on `.gd`. */
@media (prefers-color-scheme: dark) {
    .gd .cp-card {
        background: linear-gradient(180deg,
            color-mix(in srgb, var(--gd-surface) 92%, #FFFFFF) 0%,
            var(--gd-surface) 55%,
            color-mix(in srgb, var(--gd-surface) 96%, #000000) 100%);
        box-shadow: 0 1px 0 rgba(255, 255, 255, .05) inset,
                    0 20px 40px -32px rgba(0, 0, 0, .95);
    }
    .gd .cp-card:hover {
        box-shadow: 0 1px 0 rgba(255, 255, 255, .07) inset,
                    0 26px 52px -34px color-mix(in srgb, rgb(var(--a)) 60%, #000000);
    }
}
.theme-light .gd .cp-card, .gd.theme-light .cp-card {
    background:
        linear-gradient(180deg,
            color-mix(in srgb, var(--gd-surface) 100%, #FFFFFF) 0%,
            var(--gd-surface) 42%,
            color-mix(in srgb, var(--gd-surface) 97%, var(--gd-canvas)) 100%);
    box-shadow:
        0 1px 0 rgba(255, 255, 255, .6) inset,
        0 1px 2px rgba(16, 24, 40, .05),
        0 18px 38px -30px rgba(16, 24, 40, .55);
}
.theme-dark .gd .cp-card, .gd.theme-dark .cp-card {
    background: linear-gradient(180deg,
        color-mix(in srgb, var(--gd-surface) 92%, #FFFFFF) 0%,
        var(--gd-surface) 55%,
        color-mix(in srgb, var(--gd-surface) 96%, #000000) 100%);
    box-shadow: 0 1px 0 rgba(255, 255, 255, .05) inset,
                0 20px 40px -32px rgba(0, 0, 0, .95);
}
.theme-dark .gd .cp-card:hover, .gd.theme-dark .cp-card:hover {
    box-shadow: 0 1px 0 rgba(255, 255, 255, .07) inset,
                0 26px 52px -34px color-mix(in srgb, rgb(var(--a)) 60%, #000000);
}
.gd .cp-card-t {
    margin: 0 0 14px;
    font-size: clamp(15px, 1.15vw, 17.5px); font-weight: 800; letter-spacing: -.018em;
    color: var(--gd-ink);
}

.gd .cp-prose { font-size: 13.5px; line-height: 1.65; color: var(--gd-body); }
.gd .cp-prose + .cp-mini { margin-top: auto; padding-top: 16px; }

/* ── About: the mini-fact grid ──────────────────────────────────────────── */

/*
 * TWO COLUMNS, and each cell carries its own border.
 *
 * The 1px-gap-over-a-tinted-background trick draws the grid's own colour
 * wherever a cell is missing — a company with three facts instead of four got a
 * grey phantom cell in the corner. Bordering the cells means an absent one
 * leaves clean white, which is what an optional field should do.
 */
.gd .cp-mini {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
}
.gd .cp-mini-i {
    display: flex; flex-direction: column; gap: 4px;
    padding: 11px 13px;
    border: 1px solid var(--gd-line); border-radius: 11px;
    background: var(--gd-surface);
    min-width: 0;
}
.gd .cp-mini-l {
    display: flex; align-items: center; gap: 6px;
    font-size: 10.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
    color: var(--gd-faint);
}
.gd .cp-mini-l svg { color: rgb(var(--a)); }
.gd .cp-mini-i b {
    display: flex; align-items: center; gap: 6px;
    font-size: 13px; font-weight: 750; color: var(--gd-ink); line-height: 1.3;
    min-width: 0; overflow-wrap: anywhere;
}
.gd .cp-dot { width: 7px; height: 7px; border-radius: 50%; background: #10B981; flex: none; }

/* ── Ownership chain ────────────────────────────────────────────────────────
   Read top-down: owner, the link, the company below it. Nobody types this —
   each company names its own immediate parent and the chain assembles itself.

   The connector used to be a chevron with the word "Owns" beside it. It is a
   drawn line with the word set on it now: the relationship between two cards
   is a thing you can see rather than a caption you have to read. */

.gd .cp-chain { display: flex; flex-direction: column; }
.gd .cp-chain-i {
    position: relative;
    display: flex; align-items: center; gap: 12px;
    padding: 13px 14px;
    border: 1px solid var(--gd-line); border-radius: 14px;
    background: var(--gd-surface);
    text-decoration: none; color: var(--gd-ink);
    box-shadow: 0 1px 2px rgba(16, 24, 40, .04);
    transition: border-color .18s var(--gd-ease), background .18s var(--gd-ease),
                box-shadow .18s var(--gd-ease), transform .18s var(--gd-ease);
}
.gd a.cp-chain-i:hover {
    border-color: rgba(var(--a), .45);
    box-shadow: 0 10px 24px -18px rgba(var(--a), .85);
    transform: translateY(-1px);
}
/* This company. It is the one the reader is on, so it is the one that is lit. */
.gd .cp-chain-i.is-self {
    border-color: rgba(var(--a), .5);
    background: linear-gradient(180deg, rgba(var(--a), .09), rgba(var(--a), .045));
    box-shadow: 0 1px 2px rgba(16, 24, 40, .04), inset 0 0 0 1px rgba(var(--a), .08);
}

/* A logo tile, not a bare image: a white ground keeps a transparent PNG legible
   in either theme, and every row lines up whatever shape the logo is. */
.gd .cp-chain-i img,
.gd .cp-chain-ph {
    width: 42px; height: 42px; flex: none;
    object-fit: contain; padding: 5px;
    border-radius: 11px;
    background: #FFFFFF;
    border: 1px solid var(--gd-line);
}
.gd .cp-chain-ph {
    display: grid; place-items: center; padding: 0;
    background: var(--gd-canvas); color: var(--gd-faint);
}

.gd .cp-chain-i > span { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.gd .cp-chain-i b {
    font-size: 14px; font-weight: 780; letter-spacing: -.01em;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gd .cp-chain-i small { font-size: 11.5px; color: var(--gd-muted); }
.gd .cp-chain-i.is-self small { color: rgb(var(--a)); font-weight: 650; }

/* The link. Two rules with a chip between them, inset so the line runs under
   the logo column rather than down the middle of the text. */
.gd .cp-chain-d {
    display: flex; flex-direction: column; align-items: center;
    gap: 4px; padding: 7px 0; margin-left: 35px;
    align-self: flex-start;
}
.gd .cp-chain-d i {
    display: block; width: 2px; height: 9px;
    border-radius: 1px;
    background: linear-gradient(180deg, transparent, rgba(var(--a), .45));
}
.gd .cp-chain-d i:last-child { background: linear-gradient(180deg, rgba(var(--a), .45), transparent); }
.gd .cp-chain-d em {
    font-style: normal;
    padding: 3px 9px; border-radius: 999px;
    background: rgba(var(--a), .1); color: rgb(var(--a));
    font-size: 9.5px; font-weight: 800; letter-spacing: .09em; text-transform: uppercase;
}

.gd .cp-indep { text-align: center; padding: 18px 12px; }
.gd .cp-indep-i {
    display: inline-grid; place-items: center;
    width: 46px; height: 46px; margin-bottom: 10px;
    border-radius: 14px;
    background: rgba(var(--a), .1); color: rgb(var(--a));
}
.gd .cp-indep b { display: block; font-size: 15px; font-weight: 800; color: var(--gd-ink); }
.gd .cp-indep p { margin: 5px 0 0; font-size: 12.5px; color: var(--gd-muted); line-height: 1.5; }

.gd .cp-subs { margin-top: auto; padding-top: 14px; border-top: 1px solid var(--gd-line-soft); }
.gd .cp-subs-l {
    display: block; margin-bottom: 7px;
    font-size: 10.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
    color: var(--gd-faint);
}
.gd .cp-subs-r { display: flex; flex-wrap: wrap; gap: 6px; }
.gd .cp-subs-r a {
    padding: 5px 10px; border-radius: 999px;
    background: rgba(var(--a), .09); color: rgb(var(--a));
    font-size: 12px; font-weight: 650; text-decoration: none;
}
.gd .cp-subs-r a:hover { background: rgba(var(--a), .18); }

/* ── Quick facts ────────────────────────────────────────────────────────── */

.gd .cp-facts { margin: 0; display: flex; flex-direction: column; }
.gd .cp-facts-i {
    display: flex; align-items: center; justify-content: space-between; gap: 14px;
    padding: 11px 0;
    border-top: 1px solid var(--gd-line-soft);
}
.gd .cp-facts-i:first-child { border-top: 0; padding-top: 0; }
.gd .cp-facts dt {
    display: flex; align-items: center; gap: 9px;
    font-size: 12.5px; color: var(--gd-muted); white-space: nowrap;
}
.gd .cp-facts dt svg { color: rgb(var(--a)); flex: none; }
.gd .cp-facts dd {
    margin: 0; min-width: 0;
    font-size: 13px; font-weight: 750; color: var(--gd-ink);
    text-align: right;
    overflow: hidden; text-overflow: ellipsis;
}
.gd .cp-facts dd a {
    display: inline-flex; align-items: center; gap: 5px;
    color: rgb(var(--a)); text-decoration: none;
}
.gd .cp-facts dd a:hover { text-decoration: underline; }

/* ── Headquarters ───────────────────────────────────────────────────────── */

.gd .cp-hq-pic {
    border-radius: 14px; overflow: hidden;
    aspect-ratio: 16 / 10;
    background: linear-gradient(150deg, rgba(var(--a), .22), rgba(var(--a), .06));
}
.gd .cp-hq-pic img { width: 100%; height: 100%; object-fit: cover; display: block; }
.gd .cp-hq-pic.is-blank { display: grid; place-items: center; color: rgba(var(--a), .5); }

.gd .cp-hq-b { display: flex; flex-direction: column; gap: 3px; margin-top: 13px; }
.gd .cp-hq-city {
    display: flex; align-items: center; gap: 8px;
    font-size: 14px; font-weight: 750; color: var(--gd-ink);
}
.gd .cp-hq-city svg { color: rgb(var(--a)); flex: none; }
.gd .cp-hq-b small { font-size: 12px; color: var(--gd-muted); padding-left: 23px; }

.gd .cp-hq-more {
    display: flex; flex-wrap: wrap; gap: 6px;
    margin-top: auto; padding-top: 13px;
}
.gd .cp-hq-more span {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 5px 9px; border-radius: 999px;
    background: var(--gd-canvas); border: 1px solid var(--gd-line);
    font-size: 11.5px; color: var(--gd-muted);
}
.gd .cp-hq-more svg { color: var(--gd-faint); }

/* ── Media gallery ──────────────────────────────────────────────────────────
   The whole gallery lives in the card. The first shot leads at double size and
   the rest tile beside it; past a certain count the grid scrolls inside itself
   rather than sending the reader to a media page. */

.gd .cp-gal-grid {
    flex: 1 1 auto;
    display: grid;
    /* auto-FIT, not auto-fill: with two images an auto-fill grid still lays out
       seven empty tracks and strands them at the left edge. auto-fit collapses
       the empty ones so the images expand to fill the card, which is what stops
       a company with a thin gallery looking broken. */
    grid-template-columns: repeat(auto-fit, minmax(126px, 1fr));
    grid-auto-rows: 108px;
    gap: 9px;
    max-height: 340px;
    overflow-y: auto;
    scrollbar-width: thin;
    padding-right: 3px;
}
.gd .cp-gal-i { position: relative; margin: 0; border-radius: 12px; overflow: hidden; background: var(--gd-canvas); }
.gd .cp-gal-i.is-lead { grid-column: span 2; grid-row: span 2; }
.gd .cp-gal-i img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .45s var(--gd-ease); }
.gd .cp-gal-i:hover img { transform: scale(1.06); }
.gd .cp-gal-i figcaption {
    position: absolute; inset: auto 0 0 0;
    padding: 16px 10px 8px;
    background: linear-gradient(180deg, transparent, rgba(9, 12, 18, .8));
    color: #FFFFFF; font-size: 11px; line-height: 1.35;
    opacity: 0; transition: opacity .25s var(--gd-ease);
}
.gd .cp-gal-i:hover figcaption { opacity: 1; }

/* ── Games ──────────────────────────────────────────────────────────────── */

.gd .cp-sec { margin-bottom: clamp(12px, 1.3vw, 18px); }
.gd .cp-sec-h {
    display: flex; align-items: flex-end; justify-content: space-between; gap: 16px;
    flex-wrap: wrap; margin-bottom: 14px;
}
.gd .cp-sec-h h2 { margin: 0; font-size: clamp(18px, 1.5vw, 23px); font-weight: 850; letter-spacing: -.022em; color: var(--gd-ink); }
.gd .cp-sec-h p { margin: 4px 0 0; font-size: 13px; color: var(--gd-muted); }
.gd .cp-sec-b {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 9px 16px; border-radius: 10px;
    border: 1px solid rgba(var(--a), .3);
    color: rgb(var(--a)); font-size: 13px; font-weight: 750; text-decoration: none;
    transition: background .18s var(--gd-ease);
}
.gd .cp-sec-b:hover { background: rgba(var(--a), .08); }

.gd .cp-tabs { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 14px; }
.gd .cp-tab {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 8px 14px;
    border: 1px solid var(--gd-line); border-radius: 999px;
    background: var(--gd-surface); cursor: pointer;
    font: inherit; font-size: 12.5px; font-weight: 700; color: var(--gd-muted);
    transition: border-color .18s var(--gd-ease), color .18s var(--gd-ease), background .18s var(--gd-ease);
}
.gd .cp-tab span {
    padding: 1px 7px; border-radius: 999px;
    background: var(--gd-canvas); font-size: 11px; color: var(--gd-faint);
}
.gd .cp-tab:hover { border-color: rgba(var(--a), .35); color: var(--gd-ink); }
.gd .cp-tab.is-on { background: rgb(var(--a)); border-color: rgb(var(--a)); color: #FFFFFF; }
.gd .cp-tab.is-on span { background: rgba(255, 255, 255, .22); color: #FFFFFF; }

/*
 * auto-FILL, never auto-fit.
 *
 * The two differ only when the row is not full, which is exactly the case
 * here: a studio credited on one game. auto-fit COLLAPSES the empty tracks and
 * lets the single card stretch across the whole container — one poster blown
 * up to eleven hundred pixels. auto-fill keeps the empty tracks at their
 * minimum, so one game renders one card the same size as it would be if there
 * were four beside it.
 */
.gd .cp-games {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(228px, 1fr));
    gap: clamp(12px, 1.2vw, 18px);
}

/* ── The scrolling cards ────────────────────────────────────────────────────
   A fixed body height with its own overflow. The card stays the same size
   whether the company has three timeline events or forty, which is what lets
   the pair sit level in a row — and what removes any reason to send a reader
   to a separate page for the rest of a list. */

.gd .cp-scroller > .cp-time,
.gd .cp-scroller > .cp-people,
.gd .cp-scroller > .cp-links {
    flex: 1 1 auto;
    max-height: 340px;
    overflow-y: auto;
    scrollbar-width: thin;
    padding-right: 4px;
}
.gd .cp-scroller > *:focus-visible { outline: 2px solid rgba(var(--a), .5); outline-offset: 3px; border-radius: 8px; }

/* ── Timeline. Vertical, one spine. ─────────────────────────────────────── */

.gd .cp-time { list-style: none; margin: 0; padding: 0 4px 0 0; }
.gd .cp-time-i {
    position: relative;
    padding: 0 0 18px 22px;
    border-left: 2px solid var(--gd-line);
    margin-left: 5px;
}
.gd .cp-time-i:last-child { padding-bottom: 2px; border-left-color: transparent; }
.gd .cp-time-dot {
    position: absolute; left: -6px; top: 3px;
    width: 10px; height: 10px; border-radius: 50%;
    background: rgb(var(--a));
    box-shadow: 0 0 0 3px color-mix(in srgb, rgb(var(--a)) 18%, var(--gd-surface));
}
.gd .cp-time-i time {
    display: block;
    font-size: 11px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase;
    color: rgb(var(--a));
}
.gd .cp-time-i b { display: block; margin-top: 3px; font-size: 13.5px; font-weight: 750; color: var(--gd-ink); line-height: 1.35; }
.gd .cp-time-i p { margin: 4px 0 0; font-size: 12.5px; line-height: 1.5; color: var(--gd-muted); }
.gd .cp-time-rel { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 7px; }
.gd .cp-time-rel a,
.gd .cp-time-rel span {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 3px 8px; border-radius: 999px;
    background: var(--gd-canvas); border: 1px solid var(--gd-line);
    font-size: 11px; color: var(--gd-muted); text-decoration: none;
}
.gd .cp-time-rel a:hover { border-color: rgba(var(--a), .4); color: rgb(var(--a)); }

/* ── History tab ────────────────────────────────────────────────────────────
   The timeline down the left, what the company wants said about itself down
   the right. When there is no rail the timeline takes the width rather than
   leaving a third of the panel empty. */

.gd .cp-hist {
    display: grid;
    grid-template-columns: minmax(0, 1.9fr) minmax(280px, 1fr);
    gap: clamp(12px, 1.3vw, 18px);
    align-items: start;
}
.gd .cp-hist.is-solo { grid-template-columns: minmax(0, 1fr); }
.gd .cp-hist-r { display: flex; flex-direction: column; gap: clamp(12px, 1.3vw, 18px); }

.gd .cp-journey-i { margin: -8px 0 20px; font-size: 13.5px; color: var(--gd-muted); }

/* The spine. A year, a dot on the line, and the event card — the line is a
   border on the list rather than a pseudo-element on every row, so it is one
   continuous rule instead of forty segments that can fall out of alignment. */
.gd .cp-jt { list-style: none; margin: 0; padding: 0; }
.gd .cp-jt-i {
    position: relative;
    display: grid;
    grid-template-columns: 58px 1fr;
    align-items: start;
    gap: 0 20px;
    padding-bottom: 14px;
}
.gd .cp-jt-i::before {
    content: ''; position: absolute;
    left: 63px; top: 12px; bottom: -2px;
    width: 2px; border-radius: 1px;
    background: rgba(var(--a), .3);
}
.gd .cp-jt-i:last-child { padding-bottom: 0; }
.gd .cp-jt-i:last-child::before { display: none; }

.gd .cp-jt-y {
    grid-column: 1;
    padding-top: 15px;
    font-size: 15px; font-weight: 800; letter-spacing: -.01em;
    color: rgb(var(--a)); text-align: right;
}
.gd .cp-jt-dot {
    position: absolute; left: 58px; top: 17px; z-index: 1;
    width: 12px; height: 12px; border-radius: 50%;
    background: rgb(var(--a));
    box-shadow: 0 0 0 3px var(--gd-surface), 0 0 0 5px rgba(var(--a), .18);
}

.gd .cp-jt-c {
    grid-column: 2;
    display: flex; align-items: flex-start; gap: 14px;
    padding: 13px 15px;
    border: 1px solid var(--gd-line); border-radius: 14px;
    background: var(--gd-surface);
    transition: border-color .18s var(--gd-ease), box-shadow .18s var(--gd-ease),
                transform .18s var(--gd-ease);
}
.gd .cp-jt-i:hover .cp-jt-c {
    border-color: rgba(var(--a), .4);
    box-shadow: 0 12px 26px -20px rgba(var(--a), .8);
    transform: translateX(2px);
}
.gd .cp-jt-ic {
    flex: none; display: grid; place-items: center;
    width: 42px; height: 42px; border-radius: 12px;
    background: rgba(var(--a), .1); color: rgb(var(--a));
}
.gd .cp-jt-b { min-width: 0; }
.gd .cp-jt-b b { display: block; font-size: 14.5px; font-weight: 780; color: var(--gd-ink); }
.gd .cp-jt-b p { margin: 4px 0 0; font-size: 13px; line-height: 1.55; color: var(--gd-muted); }

.gd .cp-jt-rel { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 9px; }
.gd .cp-jt-rel a,
.gd .cp-jt-rel span {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 3px 8px; border-radius: 999px;
    background: var(--gd-canvas); border: 1px solid var(--gd-line);
    font-size: 11px; color: var(--gd-muted); text-decoration: none;
}
.gd .cp-jt-rel a:hover { border-color: rgba(var(--a), .4); color: rgb(var(--a)); }

/* The rail. One heading treatment, three cards. */
.gd .cp-rail-t {
    margin: 0 0 14px; padding-bottom: 9px;
    font-size: 15.5px; font-weight: 800; letter-spacing: -.018em;
    color: var(--gd-ink);
    border-bottom: 2px solid var(--gd-line-soft);
    position: relative;
}
.gd .cp-rail-t::after {
    content: ''; position: absolute; left: 0; bottom: -2px;
    width: 42px; height: 2px; border-radius: 1px;
    background: rgb(var(--a));
}

.gd .cp-rail-st { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 9px; }
.gd .cp-rail-s {
    display: flex; align-items: center; gap: 10px;
    padding: 12px; border-radius: 13px;
    border: 1px solid var(--gd-line);
    background: var(--gd-canvas);
}
.gd .cp-rail-s > span {
    flex: none; display: grid; place-items: center;
    width: 38px; height: 38px; border-radius: 11px;
    background: rgba(var(--a), .12); color: rgb(var(--a));
}
.gd .cp-rail-s b {
    display: block; font-size: 17px; font-weight: 850;
    letter-spacing: -.02em; color: rgb(var(--a)); line-height: 1.1;
}
.gd .cp-rail-s small { display: block; margin-top: 2px; font-size: 11px; color: var(--gd-muted); line-height: 1.3; }

.gd .cp-hl { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.gd .cp-hl li {
    display: flex; align-items: flex-start; gap: 9px;
    font-size: 13px; line-height: 1.5; color: var(--gd-body);
}
.gd .cp-hl svg { flex: none; margin-top: 3px; color: rgb(var(--a)); }

/* The quote. The only card on the page that inverts, because it is the only
   one that is the company speaking rather than the site reporting. */
.gd .cp-quote {
    position: relative; overflow: hidden;
    margin: 0; padding: clamp(18px, 1.8vw, 24px);
    border-radius: 18px;
    background: linear-gradient(145deg, #FF5E58, var(--gd-red) 55%, #A5111A);
    color: #FFFFFF;
    box-shadow: 0 18px 40px -26px rgba(229, 27, 35, .95);
}
.gd .cp-quote-m {
    position: absolute; top: -14px; right: 14px;
    font-size: 110px; font-weight: 900; line-height: 1;
    color: rgba(255, 255, 255, .13); pointer-events: none;
}
.gd .cp-quote blockquote {
    margin: 0; position: relative;
    font-size: 14.5px; font-weight: 600; line-height: 1.6;
}
.gd .cp-quote figcaption {
    margin-top: 12px; position: relative;
    font-size: 12.5px; font-weight: 700; color: rgba(255, 255, 255, .82);
}

/* Empty states. Nothing invents data — a company with no timeline says so. */
.gd .cp-empty {
    display: flex; flex-direction: column; align-items: center;
    text-align: center; padding: 34px 20px;
}
.gd .cp-empty > span {
    display: grid; place-items: center;
    width: 54px; height: 54px; margin-bottom: 12px;
    border-radius: 16px;
    background: rgba(var(--a), .08); color: rgba(var(--a), .7);
}
.gd .cp-empty b { font-size: 14.5px; font-weight: 780; color: var(--gd-ink); }
.gd .cp-empty p { margin: 5px 0 0; font-size: 13px; color: var(--gd-muted); }

@media (max-width: 1080px) {
    .gd .cp-hist { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 620px) {
    .gd .cp-jt-i { grid-template-columns: 42px 1fr; gap: 0 16px; }
    .gd .cp-jt-i::before { left: 47px; }
    .gd .cp-jt-dot { left: 42px; }
    .gd .cp-jt-y { font-size: 13px; }
    .gd .cp-rail-st { grid-template-columns: minmax(0, 1fr); }
}
@media (prefers-reduced-motion: reduce) {
    .gd .cp-jt-c { transition: none; }
    .gd .cp-jt-i:hover .cp-jt-c { transform: none; }
}

/* ── Games tab ──────────────────────────────────────────────────────────────
   The catalogue with real controls over it, and a rail that counts rather
   than claims. Same two-column shape as History, so moving between tabs is
   not a change of scenery. */

.gd .cp-gtab {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(290px, 1fr);
    gap: clamp(12px, 1.3vw, 18px);
    align-items: start;
}
.gd .cp-gtab.is-solo { grid-template-columns: minmax(0, 1fr); }
.gd .cp-gtab-r { display: flex; flex-direction: column; gap: clamp(12px, 1.3vw, 18px); }

/* .cp-card-t is space-between so a card can put a "view all" link on its
   right. This heading has no link — it is an icon and a title that belong
   together — so it packs to the left instead. */
.gd .cp-glist .cp-gl-h .cp-card-t {
    display: flex; align-items: center; justify-content: flex-start;
    gap: 11px; margin-bottom: 0;
}
.gd .cp-gl-ic {
    flex: none; display: grid; place-items: center;
    width: 34px; height: 34px;
    border-radius: 10px;
    background: rgba(var(--a), .1); color: rgb(var(--a));
}

/* The control bar. Search takes the room left over; every select sizes to its
   own longest option so the row does not jump when a filter changes. */
.gd .cp-gl-bar {
    display: flex; flex-wrap: wrap; align-items: center; gap: 9px;
    margin: 16px 0 18px;
}
.gd .cp-gl-search {
    position: relative; display: flex; align-items: center;
    flex: 1 1 190px; min-width: 160px;
}
.gd .cp-gl-search > svg { position: absolute; left: 12px; color: var(--gd-faint); pointer-events: none; }
.gd .cp-gl-search input {
    width: 100%; padding: 10px 14px 10px 36px;
    border: 1px solid var(--gd-line); border-radius: 11px;
    background: var(--gd-surface); color: var(--gd-ink);
    font: inherit; font-size: 13px;
    transition: border-color .18s var(--gd-ease), box-shadow .18s var(--gd-ease);
}
.gd .cp-gl-search input::placeholder { color: var(--gd-faint); }
.gd .cp-gl-search input:focus {
    outline: 0; border-color: rgb(var(--a));
    box-shadow: 0 0 0 3px rgba(var(--a), .16);
}

.gd .cp-gl-sel { position: relative; display: inline-flex; align-items: center; flex: 0 0 auto; }
.gd .cp-gl-sel select {
    appearance: none; -webkit-appearance: none;
    padding: 10px 32px 10px 14px;
    border: 1px solid var(--gd-line); border-radius: 11px;
    background: var(--gd-surface); color: var(--gd-body);
    font: inherit; font-size: 13px; font-weight: 620;
    cursor: pointer;
}
.gd .cp-gl-sel select:focus-visible { outline: 3px solid rgba(var(--a), .3); outline-offset: 2px; }
.gd .cp-gl-sel > svg {
    position: absolute; right: 11px;
    transform: rotate(90deg); color: var(--gd-faint); pointer-events: none;
}

.gd .cp-gl-view {
    display: inline-flex; flex: 0 0 auto; gap: 3px; padding: 3px;
    border: 1px solid var(--gd-line); border-radius: 11px;
    background: var(--gd-canvas);
}
.gd .cp-gl-view button {
    display: grid; place-items: center;
    width: 34px; height: 32px;
    border: 0; border-radius: 8px;
    background: none; color: var(--gd-muted);
    cursor: pointer;
    transition: background .16s var(--gd-ease), color .16s var(--gd-ease);
}
.gd .cp-gl-view button.is-on { background: rgb(var(--a)); color: #FFFFFF; }
.gd .cp-gl-view button:focus-visible { outline: 3px solid rgba(var(--a), .35); outline-offset: 1px; }

.gd .cp-games-l { display: flex; flex-direction: column; gap: 10px; }

.gd .cp-gl-more {
    display: flex; flex-direction: column; align-items: center; gap: 7px;
    margin-top: 20px;
}
.gd .cp-more-b {
    display: inline-flex; align-items: center; gap: 8px;
    padding: 11px 22px;
    border: 1px solid rgba(var(--a), .35); border-radius: 12px;
    background: rgba(var(--a), .05); color: rgb(var(--a));
    font: inherit; font-size: 13px; font-weight: 720; cursor: pointer;
    transition: background .18s var(--gd-ease), gap .18s var(--gd-ease);
}
.gd .cp-more-b:hover { background: rgba(var(--a), .12); gap: 12px; }
.gd .cp-more-b svg { transform: rotate(90deg); }
.gd .cp-gl-more small { font-size: 11.5px; color: var(--gd-faint); }

/* ── The featured game ──────────────────────────────────────────────────── */

.gd .cp-fg { display: grid; grid-template-columns: 92px minmax(0, 1fr); gap: 14px; }
.gd .cp-fg-art {
    display: block; aspect-ratio: 3 / 4;
    border-radius: 12px; overflow: hidden;
    border: 1px solid var(--gd-line);
    background: var(--gd-canvas);
}
.gd .cp-fg-art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.gd .cp-fg-art > span { display: grid; place-items: center; height: 100%; color: var(--gd-faint); }

.gd .cp-fg-b { min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.gd .cp-fg-n {
    font-size: 15.5px; font-weight: 820; letter-spacing: -.018em;
    color: var(--gd-ink); text-decoration: none;
}
.gd .cp-fg-n:hover { color: rgb(var(--a)); }
.gd .cp-fg-tag {
    align-self: flex-start;
    padding: 3px 9px; border-radius: 999px;
    background: rgba(34, 160, 90, .12); color: #1B8B4C;
    font-size: 10.5px; font-weight: 750;
}
.gd .cp-fg-b p { margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--gd-muted); }

.gd .cp-fg-f { margin: 4px 0 0; display: flex; flex-direction: column; gap: 5px; }
.gd .cp-fg-f > div { display: flex; align-items: center; gap: 7px; }
.gd .cp-fg-f dt { margin: 0; display: flex; color: rgb(var(--a)); }
.gd .cp-fg-f dd { margin: 0; font-size: 12px; color: var(--gd-body); }

.gd .cp-fg-go {
    margin-top: 8px;
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    padding: 10px 16px; border-radius: 11px;
    background: linear-gradient(140deg, #FF5E58, var(--gd-red));
    color: #FFFFFF; font-size: 12.5px; font-weight: 730; text-decoration: none;
    box-shadow: 0 10px 22px -13px rgba(229, 27, 35, .9);
    transition: gap .18s var(--gd-ease), transform .18s var(--gd-ease);
}
.gd .cp-fg-go:hover { gap: 12px; transform: translateY(-1px); }

.gd .cp-gcta {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    padding: 15px 18px; border-radius: 16px;
    background: rgba(var(--a), .06);
    border: 1px solid rgba(var(--a), .16);
}
.gd .cp-gcta > span {
    flex: none; display: grid; place-items: center;
    width: 34px; height: 34px; border-radius: 10px;
    background: rgb(var(--a)); color: #FFFFFF;
}
.gd .cp-gcta p { margin: 0; flex: 1 1 140px; font-size: 13px; font-weight: 650; color: var(--gd-ink); }
.gd .cp-gcta a {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 9px 15px; border-radius: 10px;
    background: rgb(var(--a)); color: #FFFFFF;
    font-size: 12.5px; font-weight: 720; text-decoration: none;
    transition: gap .18s var(--gd-ease);
}
.gd .cp-gcta a:hover { gap: 11px; }

@media (max-width: 1080px) {
    .gd .cp-gtab { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 620px) {
    .gd .cp-gl-bar > * { flex: 1 1 100%; }
    .gd .cp-gl-view { flex: 0 0 auto; }
    .gd .cp-fg { grid-template-columns: minmax(0, 1fr); }
    .gd .cp-fg-art { max-width: 130px; }
}

/* ── Media tab ──────────────────────────────────────────────────────────────
   Wide thumbnails five across, each with what it is in the corner and its
   title beneath. The filter is a row of boxed tabs with the active one
   underlined — it reads as a place you are rather than a switch you flipped.

   Everything here is client-side: the gallery is a press kit, not a
   catalogue, so it is all in the DOM and filtering costs nothing. */

.gd .cp-md-bar {
    display: flex; flex-wrap: wrap; align-items: center; gap: 12px;
    justify-content: space-between;
    margin: 4px 0 20px;
}

.gd .cp-md-types { display: flex; flex-wrap: wrap; gap: 8px; }
.gd .cp-md-types button {
    position: relative;
    display: inline-flex; align-items: center; gap: 7px;
    padding: 10px 16px;
    border: 1px solid var(--gd-line); border-radius: 11px;
    background: var(--gd-surface); color: var(--gd-muted);
    font: inherit; font-size: 13px; font-weight: 680; cursor: pointer;
    transition: color .18s var(--gd-ease), border-color .18s var(--gd-ease),
                background .18s var(--gd-ease);
}
.gd .cp-md-types button:hover { color: var(--gd-ink); border-color: var(--gd-line); background: var(--gd-canvas); }
.gd .cp-md-types button.is-on {
    color: rgb(var(--a));
    border-color: rgba(var(--a), .3);
    background: rgba(var(--a), .05);
}
/* The underline sits on the box's own edge, so the active tab reads as the
   surface you are standing on rather than a highlighted button. */
.gd .cp-md-types button.is-on::after {
    content: ''; position: absolute; left: 16px; right: 16px; bottom: -1px;
    height: 2px; border-radius: 2px; background: rgb(var(--a));
}
.gd .cp-md-types button:focus-visible { outline: 3px solid rgba(var(--a), .3); outline-offset: 2px; }
/* An empty bucket. Visible, so the shape of the page does not depend on how
   far through filling it in an editor is; dimmed and inert, so it cannot be
   clicked into an empty grid. */
.gd .cp-md-types button[disabled] { opacity: .45; cursor: default; }
.gd .cp-md-types button[disabled]:hover { color: var(--gd-muted); background: var(--gd-surface); }
.gd .cp-md-types button > span {
    padding: 1px 6px; border-radius: 999px;
    background: var(--gd-canvas); color: var(--gd-muted);
    font-size: 10.5px; font-weight: 750;
}
.gd .cp-md-types button.is-on > span { background: rgba(var(--a), .14); color: rgb(var(--a)); }

.gd .cp-md-tools { display: flex; align-items: center; gap: 9px; }

/* Five across at full width, and never fewer than three until a phone. The
   tiles are 16:9 because that is the shape a screenshot and a film share. */
.gd .cp-md-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
    gap: clamp(12px, 1.2vw, 18px);
}
.gd .cp-md-grid.is-list { grid-template-columns: minmax(0, 1fr); }

.gd .cp-md-i { margin: 0; display: flex; flex-direction: column; gap: 9px; min-width: 0; }
.gd .cp-md-grid.is-list .cp-md-i {
    flex-direction: row; align-items: center; gap: 16px;
    padding: 10px; border: 1px solid var(--gd-line); border-radius: 14px;
    background: var(--gd-surface);
}
.gd .cp-md-grid.is-list .cp-md-h { flex: 0 0 clamp(160px, 22%, 240px); }

.gd .cp-md-h {
    position: relative; display: block; width: 100%;
    aspect-ratio: 16 / 9; overflow: hidden;
    padding: 0; border: 1px solid var(--gd-line); border-radius: 14px;
    background: var(--gd-canvas);
    cursor: pointer;
    transition: transform .22s var(--gd-ease), box-shadow .22s var(--gd-ease),
                border-color .22s var(--gd-ease);
}
.gd .cp-md-h img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .4s var(--gd-ease); }
.gd .cp-md-ph { display: grid; place-items: center; height: 100%; color: var(--gd-faint); }
.gd .cp-md-h:hover {
    border-color: rgba(var(--a), .45);
    transform: translateY(-3px);
    box-shadow: 0 18px 34px -22px rgba(var(--a), .85);
}
.gd .cp-md-h:hover img { transform: scale(1.05); }
.gd .cp-md-h:focus-visible { outline: 3px solid rgba(var(--a), .45); outline-offset: 3px; }

/* The corner badges. A translucent white ground rather than a solid one, so a
   badge over a light photograph is still legible without becoming a block. */
.gd .cp-md-tag,
.gd .cp-md-dur {
    position: absolute; bottom: 9px;
    padding: 4px 9px; border-radius: 8px;
    background: rgba(255, 255, 255, .92);
    color: #14171E;
    font-size: 10.5px; font-weight: 750; letter-spacing: .01em;
    backdrop-filter: blur(6px);
    box-shadow: 0 2px 8px rgba(16, 24, 40, .18);
}
.gd .cp-md-tag { left: 9px; }
.gd .cp-md-dur { right: 9px; background: rgba(15, 17, 21, .82); color: #FFFFFF; }

.gd .cp-md-play {
    position: absolute; inset: 0; margin: auto;
    display: grid; place-items: center;
    width: 52px; height: 52px; border-radius: 50%;
    background: rgba(255, 255, 255, .94); color: var(--gd-red);
    box-shadow: 0 8px 22px rgba(16, 24, 40, .35);
    transition: transform .22s var(--gd-ease), background .22s var(--gd-ease);
}
.gd .cp-md-h:hover .cp-md-play { transform: scale(1.1); background: #FFFFFF; }

.gd .cp-md-i figcaption { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.gd .cp-md-i figcaption b {
    font-size: 13px; font-weight: 700; color: var(--gd-ink);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gd .cp-md-i figcaption small { font-size: 11.5px; color: var(--gd-muted); line-height: 1.4; }
.gd .cp-md-i figcaption em { font-style: normal; font-size: 11px; color: var(--gd-faint); }
.gd .cp-md-grid.is-list figcaption b { white-space: normal; }

/* ── The viewer ─────────────────────────────────────────────────────────────
   Fixed to the viewport rather than the card, because a lightbox that scrolls
   with the page is a picture stuck to a wall in a moving room. */
.gd .cp-lb {
    position: fixed; inset: 0; z-index: 900;
    display: grid; place-items: center;
    padding: clamp(20px, 4vw, 56px);
    background: rgba(8, 10, 14, .88);
    backdrop-filter: blur(6px);
    animation: cp-lb-in .2s var(--gd-ease) both;
}
@keyframes cp-lb-in { from { opacity: 0; } to { opacity: 1; } }

.gd .cp-lb-f {
    margin: 0; display: flex; flex-direction: column; gap: 14px;
    max-width: min(1100px, 100%); max-height: 100%;
    animation: cp-lb-rise .28s var(--gd-ease) both;
}
@keyframes cp-lb-rise { from { opacity: 0; transform: scale(.96) translateY(10px); } to { opacity: 1; transform: none; } }

.gd .cp-lb-f img,
.gd .cp-lb-f video {
    max-width: 100%; max-height: min(74vh, 760px);
    width: auto; border-radius: 14px; display: block; margin: 0 auto;
    box-shadow: 0 30px 70px -30px rgba(0, 0, 0, .9);
}
.gd .cp-lb-f iframe {
    width: min(1000px, 88vw); aspect-ratio: 16 / 9; height: auto;
    border: 0; border-radius: 14px; display: block;
    box-shadow: 0 30px 70px -30px rgba(0, 0, 0, .9);
}

.gd .cp-lb-f figcaption {
    display: flex; flex-direction: column; gap: 3px;
    text-align: center; color: rgba(255, 255, 255, .9);
}
.gd .cp-lb-f figcaption b { font-size: 15px; font-weight: 750; }
.gd .cp-lb-f figcaption span { font-size: 13px; color: rgba(255, 255, 255, .72); }
.gd .cp-lb-f figcaption em { font-style: normal; font-size: 11.5px; color: rgba(255, 255, 255, .5); }
.gd .cp-lb-f figcaption a {
    align-self: center; margin-top: 5px;
    display: inline-flex; align-items: center; gap: 5px;
    font-size: 12px; font-weight: 650; color: #FF8A85; text-decoration: none;
}

.gd .cp-lb-x,
.gd .cp-lb-nav {
    position: absolute; z-index: 2;
    display: grid; place-items: center;
    border: 1px solid rgba(255, 255, 255, .18); border-radius: 50%;
    background: rgba(255, 255, 255, .1); color: #FFFFFF;
    cursor: pointer;
    transition: background .18s var(--gd-ease), transform .18s var(--gd-ease);
}
.gd .cp-lb-x { top: 20px; right: 20px; width: 42px; height: 42px; }
.gd .cp-lb-x:hover { background: var(--gd-red); border-color: var(--gd-red); transform: rotate(90deg); }
.gd .cp-lb-nav { top: 50%; margin-top: -24px; width: 48px; height: 48px; }
.gd .cp-lb-nav.is-prev { left: clamp(10px, 2vw, 28px); }
.gd .cp-lb-nav.is-next { right: clamp(10px, 2vw, 28px); }
.gd .cp-lb-nav.is-prev svg { transform: rotate(180deg); }
.gd .cp-lb-nav:hover { background: rgba(255, 255, 255, .22); }
.gd .cp-lb-x:focus-visible,
.gd .cp-lb-nav:focus-visible { outline: 3px solid rgba(255, 255, 255, .6); outline-offset: 2px; }

@media (max-width: 720px) {
    .gd .cp-md-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
    .gd .cp-md-bar { gap: 10px; }
    .gd .cp-md-tools { width: 100%; justify-content: space-between; }
    .gd .cp-md-grid.is-list .cp-md-i { flex-direction: column; align-items: stretch; }
    .gd .cp-md-grid.is-list .cp-md-h { flex: none; }
    .gd .cp-lb-nav { width: 40px; height: 40px; }
}

@media (prefers-reduced-motion: reduce) {
    .gd .cp-md-h,
    .gd .cp-md-h img,
    .gd .cp-md-play { transition: none; }
    .gd .cp-md-h:hover { transform: none; }
    .gd .cp-md-h:hover img { transform: none; }
    .gd .cp-lb,
    .gd .cp-lb-f { animation: none; }
}

/* ── Summary → detail ───────────────────────────────────────────────────────
   Overview is a summary of every subject with a way through to the tab that
   holds the rest. These are the ways through. */

.gd .cp-card-t {
    display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
    /* A heading and its "view all" link sit on one line while there is room
       for both, and stack when there is not — on a phone the pair is wider
       than the card and the title was being squeezed until it clipped. */
    flex-wrap: wrap;
}
.gd .cp-card-t > .cp-more { flex: none; }

.gd .cp-more {
    flex: none; display: inline-flex; align-items: center; gap: 5px;
    border: 0; background: none; padding: 0; cursor: pointer;
    font: inherit; font-size: 12.5px; font-weight: 700; color: rgb(var(--a));
    transition: gap .18s var(--gd-ease);
}
.gd .cp-more:hover { gap: 9px; }
.gd .cp-more:focus-visible { outline: 3px solid rgba(var(--a), .35); outline-offset: 3px; border-radius: 6px; }

.gd .cp-readmore {
    align-self: flex-start;
    display: inline-flex; align-items: center; gap: 7px;
    margin-top: 12px; padding: 8px 14px;
    border: 1px solid rgba(var(--a), .28); border-radius: 10px;
    background: rgba(var(--a), .06); cursor: pointer;
    font: inherit; font-size: 12.5px; font-weight: 700; color: rgb(var(--a));
    transition: background .18s var(--gd-ease), gap .18s var(--gd-ease);
}
.gd .cp-readmore:hover { background: rgba(var(--a), .12); gap: 11px; }

/* The About tab is prose, so it gets a reading measure rather than the full
   width of the page. */
.gd .cp-read { max-width: 78ch; }
.gd .cp-read .cp-prose + .cp-read-h { margin-top: 26px; }
.gd .cp-read-h {
    margin: 0 0 10px; font-size: 16px; font-weight: 800;
    letter-spacing: -.015em; color: var(--gd-ink);
}

/* The Overview gallery is a taste of the collection; the tab is the collection.
   No inner scroll on the card — the link is the way to the rest. */
.gd .cp-gal.is-brief .cp-gal-grid { max-height: none; overflow: visible; }

/* ── Touch targets ──────────────────────────────────────────────────────────
   On a pointer these read at the size they are drawn; on a finger a 15px-tall
   link is a miss waiting to happen. Each grows its HIT AREA with padding and
   pulls the same amount back as negative margin, so the text stays exactly
   where the layout put it and only the area that answers a tap changes.

   Applied at the touch widths only: on a desktop the extra padding would put
   air between a heading and its link for no benefit. */
@media (max-width: 820px) {
    /* VERTICAL only. A negative inline margin pushes the link past its
       container's content box, and a right-hand one adds 6px of scrollWidth to
       every card it sits in — which is exactly what it did. These links are
       already wide enough; it was only their height that failed a finger. */
    .gd .cp-more,
    .gd .cp-facts a,
    .gd .cp-time-rel a,
    .gd .cp-jt-rel a,
    .gd .cp-link {
        padding-block: 8px;
        margin-block: -8px;
    }
}

/* ── Tab panels ─────────────────────────────────────────────────────────────
   The section strip drives panels now rather than scrolling one very long
   page. Each panel is a destination, so it gets an entrance of its own — and
   because only one is in the layout at a time, a company with forty timeline
   events costs the reader nothing on the Overview tab. */

.gd .cp-tabwrap-top { display: block; height: 0; scroll-margin-top: 88px; }

/*
 * Switching tab.
 *
 * The panel arrives as one object — up, forward and into focus — and then its
 * own cards follow in a short stagger. Two timings, not one: if the whole panel
 * and everything in it moved together the change would read as a page load,
 * and if only the contents moved the panel would look like it had been there
 * all along. Arriving container, then contents, is what makes it read as a
 * drawer opening.
 *
 * All of it is animation-delay rather than a JS timeline. The browser owns the
 * scheduling, it costs nothing per frame, and it cannot desynchronise from the
 * panel the way a setTimeout chain can.
 */
@keyframes cp-panel-swap {
    from { opacity: 0; transform: translateY(14px) scale(.988); filter: blur(3px); }
    60%  { filter: blur(0); }
    to   { opacity: 1; transform: none; filter: blur(0); }
}
@keyframes cp-panel-item {
    from { opacity: 0; transform: translateY(16px); }
    to   { opacity: 1; transform: none; }
}

.gd .cp-panel { animation: cp-panel-swap .42s cubic-bezier(.22, .9, .3, 1) both; }

/* The panel's own blocks, in reading order. Six steps is enough for any panel
   here; past that they share the last delay rather than trailing indefinitely. */
.gd .cp-panel > *                { animation: cp-panel-item .46s cubic-bezier(.22, .9, .3, 1) both; }
.gd .cp-panel > *:nth-child(1)   { animation-delay: .06s; }
.gd .cp-panel > *:nth-child(2)   { animation-delay: .12s; }
.gd .cp-panel > *:nth-child(3)   { animation-delay: .18s; }
.gd .cp-panel > *:nth-child(4)   { animation-delay: .24s; }
.gd .cp-panel > *:nth-child(n+5) { animation-delay: .30s; }

/* Cards inside a row arrive left to right, so a three-card row reads as a row
   being dealt rather than three things appearing at once. */
.gd .cp-panel .cp-row > *              { animation: cp-panel-item .44s cubic-bezier(.22, .9, .3, 1) both; }
.gd .cp-panel .cp-row > *:nth-child(1) { animation-delay: .14s; }
.gd .cp-panel .cp-row > *:nth-child(2) { animation-delay: .21s; }
.gd .cp-panel .cp-row > *:nth-child(3) { animation-delay: .28s; }

/* The strip is buttons now, not links; nothing else about it changes. */
.gd .cp-nav-l button.cp-nav-i {
    border: 0; background: none; font: inherit; cursor: pointer;
}

/* A lone card in a panel is the panel — it should not sit in a 304px column
   with dead space beside it. */
.gd .cp-panel > .cp-card { width: 100%; }

/* Headquarters was drawn for a 280px column beside the gallery. Given the full
   width it stretched one photograph across the viewport; the picture takes a
   column and the details take the other, so the card reads as a card again. */
.gd .cp-hq.is-wide {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-rows: auto auto 1fr;
    column-gap: clamp(18px, 2vw, 30px);
    align-content: start;
}
.gd .cp-hq.is-wide > .cp-card-t { grid-column: 1 / -1; }
.gd .cp-hq.is-wide-pic { grid-row: 2 / span 2; aspect-ratio: 4 / 3; align-self: start; }
.gd .cp-hq.is-wide-b { margin-top: 0; }
.gd .cp-hq.is-wide-city { font-size: 17px; }
/* margin-top:auto pinned the office chips to the foot of a column card; in two
   columns that stranded them below a screenful of white. */
.gd .cp-hq.is-wide-more {
    align-self: start; margin-top: 0; padding-top: 16px;
}
.gd .cp-hq.is-wide-more span { font-size: 12.5px; padding: 7px 12px; }

@media (max-width: 720px) {
    .gd .cp-hq.is-wide { grid-template-columns: minmax(0, 1fr); }
    .gd .cp-hq.is-wide-pic { grid-row: auto; }
    .gd .cp-hq.is-wide-b { margin-top: 13px; }
}

/* The gallery grid capped its height for a side-by-side row; on its own tab it
   has the width for more of the collection at once. */
.gd .cp-panel#cp-panel-media .cp-gal-grid { max-height: min(70vh, 700px); }
/* Freed from a row, these two get the height their content wanted. */
.gd .cp-panel > .cp-scroller > .cp-time,
.gd .cp-panel > .cp-scroller > .cp-links { max-height: min(62vh, 620px); }
/* Official links tile across the full width instead of running as one column. */
.gd .cp-panel#cp-panel-links .cp-links {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 6px;
}

@media (prefers-reduced-motion: reduce) {
    .gd .cp-panel,
    .gd .cp-panel > *,
    .gd .cp-panel .cp-row > * { animation: none; }
    .gd .cp-nav-i::after,
    .gd .cp-card::after { animation: none !important; content: none; }
    .gd .cp-nav-ind { transition: none; }
    .gd .cp-card,
    .gd .cp-nav-i,
    .gd .cp-nav-b { transition: none; }
    .gd .cp-tabwrap-top { scroll-behavior: auto; }
}

/* ── Key people — the Overview card ──────────────────────────────────
   A compact read of who runs the place. These rules went out with the old
   sidebar card and come back with Overview; the name is a button now, because
   it opens the People tab rather than leaving the company. */

.gd .cp-people { display: flex; flex-direction: column; gap: 3px; }
.gd .cp-person {
    display: flex; align-items: center; gap: 11px;
    padding: 8px;
    border-radius: 12px;
    transition: background .16s var(--gd-ease);
}
.gd .cp-person:hover { background: var(--gd-canvas); }
.gd .cp-person img,
.gd .cp-person-ph {
    width: 42px; height: 42px; flex: none;
    border-radius: 50%; object-fit: cover;
    border: 1px solid var(--gd-line);
}
.gd .cp-person-ph {
    display: grid; place-items: center;
    background: rgba(var(--a), .12); color: rgb(var(--a));
    font-size: 16px; font-weight: 800;
}
.gd .cp-person-b {
    display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto;
    border: 0; background: none; padding: 0; font: inherit;
    text-align: left; cursor: pointer;
}
.gd .cp-person-b:focus-visible { outline: 3px solid rgba(var(--a), .35); outline-offset: 3px; border-radius: 6px; }
.gd .cp-person-b b {
    font-size: 13.5px; font-weight: 750; color: var(--gd-ink);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    transition: color .16s var(--gd-ease);
}
.gd .cp-person-b:hover b { color: rgb(var(--a)); }
.gd .cp-person-b small {
    font-size: 11.5px; color: var(--gd-muted);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gd .cp-person-s {
    flex: none; display: grid; place-items: center;
    width: 30px; height: 30px; border-radius: 8px;
    background: var(--gd-canvas); color: var(--gd-muted);
    border: 1px solid var(--gd-line);
}
.gd .cp-person-s:hover { background: rgb(var(--a)); border-color: rgb(var(--a)); color: #FFFFFF; }

/* ── People ─────────────────────────────────────────────────────────────────
   A list beside a detail panel. Selecting somebody is a class change, not a
   request, so the panel can animate and switching people transitions in place
   instead of closing and reopening.

   x-cloak keeps every unselected block out of the paint before Alpine boots;
   without it the page flashes all of them at once on first load. */

.gd [x-cloak] { display: none !important; }

.gd .cp-people-sec { margin-bottom: clamp(12px, 1.3vw, 18px); }

.gd .cp-people-t { display: flex; align-items: flex-start; gap: 12px; }
.gd .cp-people-ic {
    flex: none; display: grid; place-items: center;
    width: 40px; height: 40px; border-radius: 12px;
    background: rgba(var(--a), .1); color: rgb(var(--a));
}
.gd .cp-people-t h2 { margin: 0; font-size: clamp(18px, 1.5vw, 23px); font-weight: 850; letter-spacing: -.022em; color: var(--gd-ink); }
.gd .cp-people-t p  { margin: 3px 0 0; font-size: 13px; color: var(--gd-muted); }

.gd .cp-people-filter { position: relative; display: inline-flex; align-items: center; }
.gd .cp-people-filter select {
    appearance: none; -webkit-appearance: none;
    padding: 9px 34px 9px 14px;
    border: 1px solid var(--gd-line); border-radius: 10px;
    background: var(--gd-surface);
    font: inherit; font-size: 13px; font-weight: 650; color: var(--gd-body);
    cursor: pointer;
}
.gd .cp-people-filter select:focus-visible { outline: 3px solid rgba(var(--a), .35); outline-offset: 2px; }
.gd .cp-people-filter > svg { position: absolute; right: 12px; pointer-events: none; color: var(--gd-faint); transform: rotate(90deg); }

/* The list sits alone until somebody is selected, then makes room for the
   panel. One grid, two states — no reflow of anything outside it. */
.gd .cp-people-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(12px, 1.3vw, 18px);
    align-items: start;
    transition: grid-template-columns .4s var(--gd-ease);
}
.gd .cp-people-grid.is-open { grid-template-columns: minmax(300px, 0.92fr) minmax(0, 1.08fr); }

/* When nothing is selected the list tiles rather than running as one tall
   column — a single-column list of twelve people is a lot of page. */
.gd .cp-plist {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(272px, 1fr));
    gap: 8px;
    transition: grid-template-columns .4s var(--gd-ease);
}
.gd .cp-people-grid.is-open .cp-plist { grid-template-columns: minmax(0, 1fr); }

/* ── A person row ───────────────────────────────────────────────────────── */

.gd .cp-prow {
    display: flex; align-items: center; gap: 12px;
    width: 100%; padding: 11px 12px;
    border: 1px solid var(--gd-line); border-radius: 14px;
    background: var(--gd-surface);
    cursor: pointer; text-align: left; font: inherit;
    transition: border-color .2s var(--gd-ease), box-shadow .2s var(--gd-ease),
                transform .2s var(--gd-ease), background .2s var(--gd-ease);
}
.gd .cp-prow:hover {
    border-color: rgba(var(--a), .4);
    transform: translateY(-2px);
    box-shadow: 0 14px 28px -20px rgba(var(--a), .7);
}
.gd .cp-prow:focus-visible { outline: 3px solid rgba(var(--a), .4); outline-offset: 2px; }
.gd .cp-prow.is-active {
    border-color: rgb(var(--a));
    background: rgba(var(--a), .05);
    box-shadow: 0 14px 30px -22px rgba(var(--a), .8);
}

.gd .cp-prow img,
.gd .cp-prow-ph {
    width: 46px; height: 46px; flex: none;
    border-radius: 50%; object-fit: cover;
    border: 1px solid var(--gd-line);
}
.gd .cp-prow-ph {
    display: grid; place-items: center;
    background: rgba(var(--a), .12); color: rgb(var(--a));
    font-size: 17px; font-weight: 800;
}
.gd .cp-prow-b { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 auto; }
.gd .cp-prow-h { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; min-width: 0; }
.gd .cp-prow-h b { font-size: 14px; font-weight: 780; color: var(--gd-ink); }
.gd .cp-prow-h em {
    font-style: normal;
    padding: 2px 8px; border-radius: 999px;
    background: rgba(var(--a), .1); color: rgb(var(--a));
    font-size: 10.5px; font-weight: 750; white-space: nowrap;
}
.gd .cp-prow-b small {
    font-size: 12px; color: var(--gd-muted); line-height: 1.4;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.gd .cp-prow-go {
    flex: none; display: grid; place-items: center;
    width: 30px; height: 30px; border-radius: 50%;
    background: var(--gd-canvas); color: var(--gd-muted);
    transition: background .2s var(--gd-ease), color .2s var(--gd-ease), transform .2s var(--gd-ease);
}
.gd .cp-prow:hover .cp-prow-go { background: rgb(var(--a)); color: #FFFFFF; transform: translateX(3px); }
.gd .cp-prow.is-active .cp-prow-go { background: rgb(var(--a)); color: #FFFFFF; }

/* ── The detail panel ───────────────────────────────────────────────────── */

.gd .cp-pdetail {
    position: relative;
    padding: clamp(16px, 1.7vw, 24px);
    border: 1px solid var(--gd-line); border-radius: 18px;
    background: var(--gd-surface);
    box-shadow: 0 1px 2px rgba(16, 24, 40, .04), 0 20px 44px -30px rgba(16, 24, 40, .45);
}

/*
 * The entrance. The panel arrives first, then its contents follow in a short
 * stagger — the order a person actually reads them in.
 *
 * animation-delay on each block rather than a JS timeline: the browser owns the
 * scheduling, it costs nothing, and it cannot desynchronise from the panel.
 */
@keyframes cp-panel-in { from { opacity: 0; transform: translateY(10px) scale(.985); } to { opacity: 1; transform: none; } }
@keyframes cp-rise     { from { opacity: 0; transform: translateY(9px); }              to { opacity: 1; transform: none; } }
@keyframes cp-media-in { from { opacity: 0; transform: scale(.94); }                   to { opacity: 1; transform: none; } }

/* Driven by display, not by Alpine. x-transition would have to resolve these
   on transitionend, which a keyframe animation never fires — and toggling
   display restarts an animation for free, so the panel animates when it opens
   and the card re-animates every time the reader switches person. */
.gd .cp-pdetail        { animation: cp-panel-in .34s var(--gd-ease) both; }
.gd .cp-pcard > *      { animation: cp-rise .34s var(--gd-ease) both; }
.gd .cp-pbadge         { animation-delay: .05s; }
.gd .cp-pname          { animation-delay: .08s; }
.gd .cp-prole          { animation-delay: .10s; }
.gd .cp-pbody          { animation-delay: .13s; }
.gd .cp-pcols          { animation-delay: .18s; }
.gd .cp-pblock         { animation-delay: .22s; }
.gd .cp-pfull          { animation-delay: .28s; }
.gd .cp-pmedia img,
.gd .cp-pmedia-ph      { animation: cp-media-in .45s var(--gd-ease) both; animation-delay: .12s; }
.gd .cp-psocial a      { animation: cp-rise .3s var(--gd-ease) both; }
.gd .cp-psocial a:nth-child(1) { animation-delay: .20s; }
.gd .cp-psocial a:nth-child(2) { animation-delay: .25s; }
.gd .cp-psocial a:nth-child(3) { animation-delay: .30s; }
.gd .cp-psocial a:nth-child(4) { animation-delay: .35s; }
.gd .cp-pcon li,
.gd .cp-ptime li       { animation: cp-rise .3s var(--gd-ease) both; }
.gd .cp-pcon li:nth-child(1),  .gd .cp-ptime li:nth-child(1) { animation-delay: .26s; }
.gd .cp-pcon li:nth-child(2),  .gd .cp-ptime li:nth-child(2) { animation-delay: .31s; }
.gd .cp-pcon li:nth-child(3),  .gd .cp-ptime li:nth-child(3) { animation-delay: .36s; }
.gd .cp-pcon li:nth-child(n+4),.gd .cp-ptime li:nth-child(n+4) { animation-delay: .41s; }

.gd .cp-pclose {
    position: absolute; top: 14px; right: 14px; z-index: 2;
    display: grid; place-items: center;
    width: 32px; height: 32px;
    border: 1px solid var(--gd-line); border-radius: 50%;
    background: var(--gd-surface); color: var(--gd-muted);
    cursor: pointer;
    transition: background .18s var(--gd-ease), color .18s var(--gd-ease), transform .18s var(--gd-ease);
}
.gd .cp-pclose:hover { background: var(--gd-red); border-color: var(--gd-red); color: #FFFFFF; transform: rotate(90deg); }
.gd .cp-pclose:focus-visible { outline: 3px solid rgba(var(--a), .4); outline-offset: 2px; }

.gd .cp-pbadge {
    display: inline-block; margin-bottom: 9px;
    padding: 4px 11px; border-radius: 999px;
    background: rgb(var(--a)); color: #FFFFFF;
    font-size: 10px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
}
.gd .cp-pname { margin: 0; font-size: clamp(20px, 1.8vw, 27px); font-weight: 850; letter-spacing: -.024em; color: var(--gd-ink); }
.gd .cp-prole { margin: 4px 0 0; font-size: 13.5px; font-weight: 650; color: var(--gd-muted); }

.gd .cp-pbody { display: grid; grid-template-columns: minmax(0, 200px) minmax(0, 1fr); gap: 18px; margin-top: 16px; }
.gd .cp-pmedia img,
.gd .cp-pmedia-ph {
    width: 100%; aspect-ratio: 1;
    border-radius: 16px; object-fit: cover; display: block;
    border: 1px solid var(--gd-line);
}
.gd .cp-pmedia-ph {
    display: grid; place-items: center;
    background: rgba(var(--a), .12); color: rgb(var(--a));
    font-size: 54px; font-weight: 850;
}
.gd .cp-pinfo { display: flex; flex-direction: column; gap: 12px; min-width: 0; }

.gd .cp-pmeta { display: flex; flex-direction: column; gap: 6px; }
.gd .cp-pmeta span { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--gd-body); }
.gd .cp-pmeta svg { color: rgb(var(--a)); flex: none; }

.gd .cp-psocial { display: flex; flex-wrap: wrap; gap: 7px; }
.gd .cp-psocial a {
    display: grid; place-items: center;
    width: 36px; height: 36px; border-radius: 10px;
    border: 1px solid var(--gd-line);
    background: var(--gd-surface); color: var(--gd-body);
    transition: background .18s var(--gd-ease), color .18s var(--gd-ease), transform .18s var(--gd-ease);
}
.gd .cp-psocial a:hover { background: rgb(var(--a)); border-color: rgb(var(--a)); color: #FFFFFF; transform: translateY(-2px); }

.gd .cp-pbio b { display: block; margin-bottom: 5px; font-size: 13.5px; font-weight: 780; color: var(--gd-ink); }
.gd .cp-pbio p { margin: 0; font-size: 13px; line-height: 1.6; color: var(--gd-muted); }

.gd .cp-pcols {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 14px; margin-top: 16px; padding-top: 15px;
    border-top: 1px solid var(--gd-line-soft);
}
.gd .cp-pcols span { display: block; font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--gd-faint); }
.gd .cp-pcols b    { display: block; margin-top: 3px; font-size: 13.5px; font-weight: 750; color: var(--gd-ink); line-height: 1.35; }

.gd .cp-pblock { margin-top: 16px; }
.gd .cp-pblock > b { display: block; margin-bottom: 9px; font-size: 14px; font-weight: 800; color: var(--gd-ink); }

.gd .cp-pcon { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 7px; }
.gd .cp-pcon li { display: flex; align-items: flex-start; gap: 9px; font-size: 13px; line-height: 1.5; color: var(--gd-body); }
.gd .cp-pcon svg { flex: none; margin-top: 3px; color: rgb(var(--a)); }

.gd .cp-ptime { list-style: none; margin: 0; padding: 0 0 0 4px; }
.gd .cp-ptime li {
    position: relative;
    display: flex; align-items: baseline; gap: 14px;
    padding: 0 0 13px 20px;
    border-left: 2px solid var(--gd-line);
    margin-left: 4px;
}
.gd .cp-ptime li:last-child { padding-bottom: 0; border-left-color: transparent; }
.gd .cp-ptime-dot {
    position: absolute; left: -6px; top: 4px;
    width: 10px; height: 10px; border-radius: 50%;
    background: rgb(var(--a));
    box-shadow: 0 0 0 3px color-mix(in srgb, rgb(var(--a)) 18%, var(--gd-surface));
}
.gd .cp-ptime time { flex: none; font-size: 12px; font-weight: 800; color: rgb(var(--a)); }
.gd .cp-ptime li > span:last-child { font-size: 13px; color: var(--gd-body); line-height: 1.45; }

.gd .cp-pfull {
    display: inline-flex; align-items: center; gap: 8px;
    margin-top: 18px; padding: 10px 18px;
    border-radius: 11px;
    background: linear-gradient(140deg, #FF5E58, var(--gd-red));
    color: #FFFFFF; font-size: 13px; font-weight: 750; text-decoration: none;
    box-shadow: 0 10px 22px -12px rgba(229, 27, 35, .9);
}
.gd .cp-pfull:hover { transform: translateY(-1px); }

/* ── The three summary cards ────────────────────────────────────────────── */

.gd .cp-people-foot { margin-top: clamp(12px, 1.3vw, 18px); }
.gd .cp-people-foot .cp-card-t { display: flex; align-items: center; gap: 9px; }
.gd .cp-people-foot .cp-card-t svg { color: rgb(var(--a)); }

.gd .cp-depts { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.gd .cp-depts li {
    display: flex; align-items: center; gap: 9px;
    padding: 9px 0;
    border-top: 1px solid var(--gd-line-soft);
    font-size: 13px; color: var(--gd-body);
}
.gd .cp-depts li:first-child { border-top: 0; padding-top: 0; }
.gd .cp-depts li > svg { color: var(--gd-faint); flex: none; }
.gd .cp-depts li span { flex: 1 1 auto; min-width: 0; }
.gd .cp-depts li b {
    flex: none; min-width: 26px; padding: 2px 8px;
    border-radius: 999px; text-align: center;
    background: rgba(var(--a), .1); color: rgb(var(--a));
    font-size: 12px; font-weight: 800;
}

.gd .cp-snap { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.gd .cp-snap-i { display: flex; flex-direction: column; align-items: center; gap: 3px; text-align: center; }
.gd .cp-snap-i > span {
    display: grid; place-items: center;
    width: 46px; height: 46px; margin-bottom: 4px;
    border-radius: 50%;
    background: rgba(var(--a), .1); color: rgb(var(--a));
}
.gd .cp-snap-i b { font-size: 21px; font-weight: 850; letter-spacing: -.02em; color: var(--gd-ink); line-height: 1; }
.gd .cp-snap-i small { font-size: 11px; color: var(--gd-muted); line-height: 1.3; }

.gd .cp-quick { display: flex; flex-direction: column; gap: 2px; }
.gd .cp-quick a,
.gd .cp-quick button {
    display: flex; align-items: center; gap: 10px; width: 100%;
    padding: 10px 8px; border: 0; border-radius: 10px;
    background: none; font: inherit;
    font-size: 13px; font-weight: 650; color: var(--gd-body); text-decoration: none;
    text-align: left; cursor: pointer;
    transition: background .16s var(--gd-ease);
}
.gd .cp-quick a:hover,
.gd .cp-quick button:hover { background: var(--gd-canvas); }
.gd .cp-quick a:focus-visible,
.gd .cp-quick button:focus-visible { outline: 3px solid rgba(var(--a), .35); outline-offset: -2px; }
.gd .cp-quick a > span,
.gd .cp-quick button > span {
    flex: none; display: grid; place-items: center;
    width: 30px; height: 30px; border-radius: 9px;
    background: rgba(var(--a), .1); color: rgb(var(--a));
}
.gd .cp-quick a > svg:last-child,
.gd .cp-quick button > svg:last-child { margin-left: auto; color: rgb(var(--a)); }

/* ── Responsive ─────────────────────────────────────────────────────────── */

@media (max-width: 1080px) {
    /* The panel drops under the list rather than squeezing two columns into a
       tablet. The interaction is unchanged; only the arrangement is. */
    .gd .cp-people-grid.is-open { grid-template-columns: minmax(0, 1fr); }
    .gd .cp-people-grid.is-open .cp-plist { grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }
}

@media (max-width: 720px) {
    .gd .cp-pbody { grid-template-columns: minmax(0, 1fr); }
    .gd .cp-pmedia { max-width: 190px; }
    .gd .cp-snap { gap: 6px; }
    .gd .cp-snap-i > span { width: 40px; height: 40px; }
    .gd .cp-snap-i b { font-size: 18px; }
}

/* Reduced motion: the stagger is the first thing to go. The panel still
   appears and disappears — it just stops being a performance. */
@media (prefers-reduced-motion: reduce) {
    .gd .cp-pdetail,
    .gd .cp-pcard > *,
    .gd .cp-pmedia img,
    .gd .cp-pmedia-ph,
    .gd .cp-psocial a,
    .gd .cp-pcon li,
    .gd .cp-ptime li { animation: none !important; }
    .gd .cp-people-grid,
    .gd .cp-plist,
    .gd .cp-prow { transition: none; }
    .gd .cp-prow:hover { transform: none; }
}

/* ── Links ──────────────────────────────────────────────────────────────── */

.gd .cp-links { display: flex; flex-direction: column; gap: 2px; }
.gd .cp-link {
    display: flex; align-items: center; gap: 11px;
    padding: 9px 8px;
    border-radius: 10px;
    text-decoration: none;
    transition: background .16s var(--gd-ease);
}
.gd .cp-link:hover { background: var(--gd-canvas); }
.gd .cp-link-i {
    flex: none; display: grid; place-items: center;
    width: 30px; height: 30px; border-radius: 9px;
    background: rgba(var(--a), .1); color: rgb(var(--a));
}
.gd .cp-link-n { font-size: 13px; font-weight: 700; color: var(--gd-ink); flex: none; }
.gd .cp-link-h {
    margin-left: auto; min-width: 0;
    font-size: 12px; color: rgb(var(--a));
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: right;
}

/* ── CTA ────────────────────────────────────────────────────────────────── */

.gd .cp-cta {
    display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
    margin: clamp(14px, 1.6vw, 22px) 0 clamp(24px, 3vw, 40px);
    padding: clamp(16px, 1.6vw, 22px);
    border: 1px solid rgba(var(--a), .2); border-radius: 18px;
    background: linear-gradient(120deg, rgba(var(--a), .09), rgba(var(--a), .02));
}
.gd .cp-cta-i {
    flex: none; display: grid; place-items: center;
    width: 50px; height: 50px; border-radius: 15px;
    background: rgb(var(--a)); color: #FFFFFF;
    box-shadow: 0 10px 22px -10px rgba(var(--a), .9);
}
.gd .cp-cta > div { flex: 1 1 260px; min-width: 0; }
.gd .cp-cta b { display: block; font-size: 15.5px; font-weight: 800; color: var(--gd-ink); }
.gd .cp-cta p { margin: 3px 0 0; font-size: 13px; color: var(--gd-muted); }
.gd .cp-cta-b {
    flex: none;
    display: inline-flex; align-items: center; gap: 8px;
    padding: 12px 22px; border-radius: 12px;
    background: linear-gradient(140deg, #FF5E58, var(--gd-red));
    color: #FFFFFF; font-size: 13.5px; font-weight: 750; text-decoration: none;
    box-shadow: 0 12px 24px -12px rgba(229, 27, 35, .95);
    transition: transform .16s var(--gd-ease);
}
.gd .cp-cta-b:hover { transform: translateY(-1px); }

/* ══ RESPONSIVE ═════════════════════════════════════════════════════════════
   The hero is the only part with a bespoke arrangement; everything else is
   intrinsic and reflows on its own. */

@media (max-width: 1080px) {
    .gd .cp-row-hq { grid-template-columns: minmax(0, 1fr); }
    .gd .cp-hero-in { grid-template-columns: auto minmax(0, 1fr); }
    /* The owner card drops to a full-width row under the name rather than
       squeezing a third column into a tablet. */
    .gd .cp-owner { grid-column: 1 / -1; width: 100%; display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
    .gd .cp-owner-l { margin: 0; }
    .gd .cp-owner-since { margin: 0; }
    .gd .cp-owner-b { margin: 0 0 0 auto; }
}

@media (max-width: 720px) {
    .gd .cp-hero { min-height: 0; border-radius: 18px; }
    .gd .cp-hero-in { grid-template-columns: minmax(0, 1fr); gap: 14px; }
    .gd .cp-hero-mark { width: 78px; border-radius: 15px; }
    .gd .cp-hero-facts { gap: 6px 14px; font-size: 12.5px; }
    .gd .cp-nav { position: static; }
    .gd .cp-nav-b { display: none; }
    .gd .cp-gal-grid { max-height: 300px; grid-auto-rows: 92px; }
    .gd .cp-scroller > .cp-time,
    .gd .cp-scroller > .cp-links { max-height: 300px; }
    .gd .cp-cta { flex-direction: column; align-items: flex-start; }
    .gd .cp-cta-b { width: 100%; justify-content: center; }
}

@media (prefers-reduced-motion: reduce) {
    .gd .cp-gal-i img,
    .gd .cp-hero-soc,
    .gd .cp-cta-b { transition: none; }
    .gd .cp-gal-i:hover img { transform: none; }
}

/* ── Companies behind this game ──────────────────────────────────────────────
   The compact card the game page shows for each company credited on it. A mark,
   a name, the role played on THAT game, a place and a link — deliberately the
   smallest thing that identifies a company and gets the reader to its profile.
   Everything else about the studio lives there, not here. */

.gd .gd-cocards { display: flex; flex-direction: column; gap: 8px; }

.gd .gd-cocard {
    display: grid;
    grid-template-columns: 44px minmax(0, 1fr);
    grid-template-areas: 'mark body' 'go go';
    gap: 4px 11px; align-items: center;
    padding: 12px; border: 1px solid var(--gd-line); border-radius: 12px;
    background: var(--gd-surface); text-decoration: none;
    transition: border-color .2s var(--gd-ease), transform .2s var(--gd-ease);
}
.gd .gd-cocard:hover { border-color: var(--gd-red); transform: translateY(-2px); }

.gd .gd-cocard-mark {
    grid-area: mark;
    display: grid; place-items: center;
    width: 44px; height: 44px; border-radius: 11px; overflow: hidden;
    background: var(--gd-red-soft); color: var(--gd-red);
    font-size: 17px; font-weight: 800;
}
.gd .gd-cocard-mark img { width: 100%; height: 100%; object-fit: contain; padding: 6px; }

.gd .gd-cocard-b { grid-area: body; display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.gd .gd-cocard-b b {
    display: flex; align-items: center; gap: 5px;
    font-size: 14px; font-weight: 750; color: var(--gd-ink);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gd .gd-cocard-v {
    display: inline-grid; place-items: center; flex: none;
    width: 14px; height: 14px; border-radius: 50%;
    background: var(--gd-red); color: #fff;
}
.gd .gd-cocard-role { font-size: 12px; font-weight: 650; color: var(--gd-red); }
.gd .gd-cocard-b small { font-size: 11.5px; color: var(--gd-muted); }

.gd .gd-cocard-go {
    grid-area: go;
    display: inline-flex; align-items: center; gap: 5px; justify-content: flex-end;
    margin-top: 2px; font-size: 12px; font-weight: 700; color: var(--gd-muted);
}
.gd .gd-cocard:hover .gd-cocard-go { color: var(--gd-red); }
.gd .gd-cocard:hover .gd-cocard-go svg { transform: translateX(2px); }
.gd .gd-cocard-go svg { transition: transform .2s var(--gd-ease); }

/* ============================================================================
   GAME DETAIL — MOTION, DEPTH & WIDE-SCREEN LAYOUT
   ----------------------------------------------------------------------------
   Everything below is scoped to `.gd-detail`, a class carried only by
   /games/{slug}. The `gd-page` shell is shared with the directory, the company
   and the creator pages, so the scoping is what keeps a hero animation off a
   listing that never asked for one.

   THREE THINGS THIS SECTION DOES

   1. MOTION. The page had none. Sections rise as they enter view, the hero
      composes itself on load, the score ring draws to its value, counts tick
      up. All of it is decoration over content already in the document: nothing
      here creates, hides or delays a fact. The reveal state is gated behind
      `.gd-fx`, a class only the script adds, so a reader with no JS — or a
      crawler — gets the fully painted page with no opacity tricks in the way.

   2. LAYOUT. Two real faults are fixed. The sidebar rail was `position:sticky`
      while measuring 2258px tall in a 987px viewport, which pinned it on the
      first scroll and left its lower five cards unreachable. The language table
      declared `width:100%` but sized every column, leaving ~545px of dead space
      to the right of all fourteen rows.

   3. SCALE. `--bg-wrap-wide` is read by `.gd-wrap` but was never declared
      anywhere in the codebase, so every screen from a 1366 laptop to a 4K panel
      rendered into the same 1280px column. It is declared here per breakpoint,
      and the grids gain COLUMNS rather than the cards stretching.

   MOTION IS OPT-OUT. `prefers-reduced-motion` is honoured at the end of this
   file and checked again in the script, and the reveal system is built so that
   disabling animation leaves content visible rather than stuck at opacity 0.
   ========================================================================== */

/* ── Tokens ─────────────────────────────────────────────────────────────── */

.gd-detail {
    /* Overshoot for anything that should feel physical — badges, icons; the
       base --gd-ease stays for everything that should feel calm. */
    --gdx-spring: cubic-bezier(.34, 1.3, .64, 1);
    --gdx-out:    cubic-bezier(.16, 1, .3, 1);

    /* One dial for the reveal system, so the page's pace is tuned in a single
       place rather than across forty transition declarations. */
    --gdx-in:     .62s;

    --gdx-sheen:  rgba(255, 255, 255, .55);

    /* Where the rail docks: the global header (65px) plus the section rail
       (~53px) plus breathing room. */
    --gdx-dock:   132px;
}

@media (prefers-color-scheme: dark) {
    .gd-detail { --gdx-sheen: rgba(255, 255, 255, .10); }
}
.theme-light .gd-detail, .gd-detail.theme-light { --gdx-sheen: rgba(255, 255, 255, .55); }
.theme-dark  .gd-detail, .gd-detail.theme-dark  { --gdx-sheen: rgba(255, 255, 255, .10); }

/* ============================================================================
   1 — WIDE-SCREEN SCALE
   ----------------------------------------------------------------------------
   THE PAGE WIDTH IS NOT SET HERE, AND MUST NOT BE.

   `assets/css/responsive.css` already owns it, site-wide, on :root:

       --bg-wrap-wide: min(2400px, max(1280px, 66.7vw));

   That is a deliberate curve, not a placeholder: 1280px at Full HD and below,
   growing with the viewport past 1920, capped at 2400px so a directory never
   grows wider than the 1450px header sitting above it. `.gd-wrap` reads it with
   a 1280px fallback, which is why the variable looks unset when you grep only
   the game sheet.

   An earlier draft of this section redeclared it as a fixed ladder on
   `.gd-detail` — 1440 at 1600, 1600 at 1920, 1880 at 2400. That put the game
   page 320px wider than the games directory on the same 1920 screen and broke
   the header rule the curve exists to hold. It is gone. The width comes from
   the site system, and everything below responds to whatever width that gives.

   So this section only does the thing the site's own comment asks for — "more
   columns, not bigger cards". The grids are fluid rather than fixed counts, so
   they gain a column whenever the container has room for one, at any width,
   with no breakpoint guessing. Line length is protected separately: `.gd-prose`
   keeps its 72ch cap at every size, because a 2000px paragraph is unreadable
   however large the panel.
   ========================================================================== */

/*
 * Fluid where the base sheet was fixed. `.gd-gal` was `repeat(3, 1fr)`, which
 * meant three columns at 1280 and three columns at 4K — the cards simply grew.
 * `auto-fill` with a sensible floor turns extra width into extra tiles instead.
 */
.gd-detail .gd-gal { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }

@media (min-width: 1920px) {          /* where the site's curve starts moving */
    .gd-detail .gd-layout     { grid-template-columns: minmax(0, 1fr) 372px; gap: 30px; }
    .gd-detail .gd-stage-grid { grid-template-columns: minmax(0, 1fr) 372px; gap: 46px; }
}

@media (min-width: 2560px) {          /* 2K / QHD — the curve is at ~1700px   */
    .gd-detail { --gd-r-lg: 24px; }
    .gd-detail .gd-layout     { grid-template-columns: minmax(0, 1fr) 410px; gap: 36px; }
    .gd-detail .gd-stage-grid { grid-template-columns: minmax(0, 1fr) 410px; }
    .gd-detail .gd-stage-poster { width: 200px; }
    .gd-detail .gd-stage-id   { grid-template-columns: 200px minmax(0, 1fr); }

    /* Type steps up once rather than linearly: the reader sits further from a
       27" panel, so the base grows a point and the headings follow. */
    .gd-detail .gd-sec-h h2 { font-size: 17.5px; }
    .gd-detail .gd-prose    { font-size: 16.5px; }
    .gd-detail .gd-feat b   { font-size: 15.5px; }
}

@media (min-width: 3400px) {          /* 4K — the curve is at its 2400px cap  */
    .gd-detail .gd-layout     { grid-template-columns: minmax(0, 1fr) 440px; gap: 42px; }
    .gd-detail .gd-stage-grid { grid-template-columns: minmax(0, 1fr) 440px; }
    .gd-detail .gd-stage-poster { width: 224px; }
    .gd-detail .gd-stage-id   { grid-template-columns: 224px minmax(0, 1fr); gap: 32px; }

    /* The hero title is clamp(32px, 5vw, 60px) — at 3840px the 5vw middle term
       was capped long ago, so the ceiling is what needs raising. */
    .gd-detail .gd-stage-name h1 { font-size: clamp(48px, 3.4vw, 82px); }
    .gd-detail .gd-stage-lede    { font-size: 18px; max-width: 62ch; }
}

/* ============================================================================
   2 — SCROLL REVEAL
   ----------------------------------------------------------------------------
   Content is in the document and visible by default. The script adds `.gd-fx`
   to the page root only when it is actually going to animate, and only then
   does anything start hidden. A failed script, a blocked script and a reader
   who asked for reduced motion all end in the same place: everything visible.
   ========================================================================== */

/*
 * The hidden state is written STRUCTURALLY rather than against a data
 * attribute. The distinction matters: a deferred script that tags elements and
 * only then hides them is hiding content the browser has already painted, which
 * a reader sees as a flash followed by a re-entrance. Keying on the elements
 * themselves means the single class the inline boot adds takes effect during
 * parse, before first paint, and nothing ever appears twice.
 */
.gd-detail.gd-fx #gd-content > .gd-sec,
.gd-detail.gd-fx .gd-rail > .gd-rcard {
    opacity: 0;
    transform: translate3d(0, 26px, 0);
}
.gd-detail.gd-fx #gd-content > .gd-sec.is-in,
.gd-detail.gd-fx .gd-rail > .gd-rcard.is-in {
    opacity: 1;
    transform: none;
    transition:
        opacity   var(--gdx-in) var(--gdx-out) var(--gdx-delay, 0s),
        transform var(--gdx-in) var(--gdx-out) var(--gdx-delay, 0s);
}

/* Children that stagger inside a section that has already arrived — gallery
   tiles, feature cards, buy rows. A shorter travel than the section itself, so
   the two scales read as "the card landed, then its contents settled".
   `:is()` keeps the list readable; a browser without it drops the rule and the
   tiles simply appear with their section, which is a fine outcome. */
.gd-detail.gd-fx :is(.gd-feats, .gd-gal, .gd-shots-rest, .gd-videos, .gd-buys, .gd-credits, .gd-grid) > * {
    opacity: 0;
    transform: translate3d(0, 14px, 0);
}
.gd-detail.gd-fx :is(.gd-feats, .gd-gal, .gd-shots-rest, .gd-videos, .gd-buys, .gd-credits, .gd-grid).is-in > * {
    opacity: 1;
    transform: none;
    transition:
        opacity   .5s var(--gdx-out) calc(var(--gdx-step, 45ms) * var(--gdx-i, 0)),
        transform .5s var(--gdx-out) calc(var(--gdx-step, 45ms) * var(--gdx-i, 0));
}

/* ============================================================================
   3 — THE STAGE
   ----------------------------------------------------------------------------
   The hero was a still image behind a scrim. It keeps exactly that composition
   and gains three things it did not have: the art breathes, an aurora drifts
   behind the copy, and the block composes itself on load instead of appearing
   whole.

   Nothing here is a new claim. There is no "trending" ribbon, no fabricated
   player count and no invented badge — the same rule the markup follows.
   ========================================================================== */

/* A decorative layer between the scrim and the copy. Empty by design: three
   animated gradients and nothing a screen reader should ever meet, which is why
   the element carries aria-hidden in the markup. */
.gd-detail .gd-stage-fx {
    position: absolute; inset: 0; pointer-events: none; overflow: hidden;

    /* Aurora: two soft fields drifting across each other on a long cycle, so
       the loop never lands on an obvious beat. */
    background:
        radial-gradient(38% 52% at 18% 26%, rgba(255, 62, 70, .20) 0%, transparent 62%),
        radial-gradient(30% 44% at 76% 72%, rgba(150, 40, 220, .13) 0%, transparent 64%);
    animation: gdx-aurora 23s ease-in-out infinite alternate;
}

/* Scanlines, held at 3% so they read as panel texture rather than as a pattern,
   and masked away over the left third where the copy sits. */
.gd-detail .gd-stage-fx::before {
    content: ''; position: absolute; inset: -20% -10%;
    background: repeating-linear-gradient(
        180deg,
        rgba(255, 255, 255, .030) 0px,
        rgba(255, 255, 255, .030) 1px,
        transparent 1px,
        transparent 4px
    );
    -webkit-mask-image: radial-gradient(70% 90% at 82% 40%, #000 0%, transparent 76%);
            mask-image: radial-gradient(70% 90% at 82% 40%, #000 0%, transparent 76%);
    animation: gdx-scan 9s linear infinite;
}

/* One sheen crossing the stage as the page settles. It runs exactly once — a
   looping sweep across a hero is a distraction, not an effect. */
.gd-detail .gd-stage-fx::after {
    content: ''; position: absolute; top: -60%; bottom: -60%; left: -46%; width: 42%;
    background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .07), transparent);
    transform: skewX(-14deg);
    animation: gdx-sheen 1.9s .35s var(--gdx-out) 1 both;
}

@keyframes gdx-aurora {
    0%   { transform: translate3d(0, 0, 0)        scale(1);    }
    50%  { transform: translate3d(3%, -2%, 0)     scale(1.09); }
    100% { transform: translate3d(-2.5%, 2.5%, 0) scale(1.04); }
}
@keyframes gdx-scan  { to { transform: translateY(4px); } }
@keyframes gdx-sheen { from { left: -46%; } to { left: 124%; } }

/* The artwork breathes. 1.06 is where the existing rule parks it; this moves
   between 1.06 and 1.12 over 34 seconds, slow enough to register as depth
   rather than as movement. */
.gd-detail .gd-stage.has-art .gd-stage-art img {
    animation: gdx-drift 34s ease-in-out infinite alternate;
}
@keyframes gdx-drift {
    from { transform: scale(1.06) translate3d(0, 0, 0); }
    to   { transform: scale(1.12) translate3d(-1.4%, -1.2%, 0); }
}

/* A lit edge where the stage meets the page — the join every cinematic header
   needs and this one did not have. */
.gd-detail .gd-stage { box-shadow: inset 0 -1px 0 rgba(255, 255, 255, .07); }

/* ── Hero entrance ──────────────────────────────────────────────────────── */

/*
 * Runs on load rather than on scroll: the hero is already in view, so waiting
 * for an observer would only delay it. `both` fill means a reduced-motion
 * reader — whose duration the sheet clamps to ~0 — lands on the final frame
 * immediately rather than on a blank hero.
 */
.gd-detail.gd-fx .gd-crumbs,
.gd-detail.gd-fx .gd-flags,
.gd-detail.gd-fx .gd-stage-id,
.gd-detail.gd-fx .gd-stage-meta,
.gd-detail.gd-fx .gd-stage-main > .gd-chips,
.gd-detail.gd-fx .gd-stage-plats,
.gd-detail.gd-fx .gd-stage-cta,
.gd-detail.gd-fx .gd-scorecard,
.gd-detail.gd-fx .gd-strip {
    animation: gdx-rise .72s var(--gdx-out) both;
}
.gd-detail.gd-fx .gd-crumbs                 { animation-delay: .02s; }
.gd-detail.gd-fx .gd-flags                  { animation-delay: .08s; }
.gd-detail.gd-fx .gd-stage-id               { animation-delay: .14s; }
.gd-detail.gd-fx .gd-stage-meta             { animation-delay: .20s; }
.gd-detail.gd-fx .gd-stage-main > .gd-chips { animation-delay: .24s; }
.gd-detail.gd-fx .gd-stage-plats            { animation-delay: .28s; }
.gd-detail.gd-fx .gd-stage-cta              { animation-delay: .32s; }
.gd-detail.gd-fx .gd-scorecard              { animation-delay: .18s; }
.gd-detail.gd-fx .gd-strip                  { animation-delay: .40s; }

@keyframes gdx-rise {
    from { opacity: 0; transform: translate3d(0, 22px, 0); }
    to   { opacity: 1; transform: none; }
}

/* ── The poster ─────────────────────────────────────────────────────────── */

/*
 * Tilts toward the pointer. --gdx-rx / --gdx-ry are written by the script;
 * with no script they hold their 0deg initial values and the poster sits flat,
 * so the rule is inert rather than broken.
 *
 * No `preserve-3d`: the cover component sets `container-type: inline-size`,
 * which applies layout containment and forces transform-style back to flat.
 * The rotation itself is unaffected and nothing inside needs its own depth.
 */
.gd-detail .gd-stage-poster {
    --gdx-rx: 0deg;
    --gdx-ry: 0deg;
    position: relative;
    transform: perspective(900px) rotateX(var(--gdx-rx)) rotateY(var(--gdx-ry));
    transition: transform .4s var(--gdx-out), box-shadow .4s var(--gdx-out);
    overflow: hidden;
}
/* While the pointer is actually moving the transform must keep up with it; the
   longer easing above is for settling back. */
.gd-detail .gd-stage-poster.is-tilting { transition: transform .08s linear; }
.gd-detail .gd-stage-poster:hover {
    box-shadow: 0 30px 70px rgba(0, 0, 0, .62), 0 0 0 1px rgba(255, 255, 255, .16);
}

/* Glare tracking the pointer across the art. */
.gd-detail .gd-stage-poster::after {
    content: ''; position: absolute; inset: 0; pointer-events: none;
    border-radius: inherit;
    background: radial-gradient(
        34% 34% at var(--gdx-mx, 50%) var(--gdx-my, 0%),
        rgba(255, 255, 255, .34) 0%, transparent 70%
    );
    opacity: 0;
    transition: opacity .3s var(--gdx-out);
}
.gd-detail .gd-stage-poster:hover::after { opacity: 1; }

/* A red rim that wakes on hover — the one place on the page where the brand
   colour touches the artwork itself. */
.gd-detail .gd-stage-poster::before {
    content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none;
    border-radius: inherit;
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .10);
    transition: box-shadow .3s var(--gdx-out);
}
.gd-detail .gd-stage-poster:hover::before {
    box-shadow: inset 0 0 0 1px rgba(255, 81, 87, .70), inset 0 0 22px rgba(255, 81, 87, .18);
}

/* ── Flags, chips, platform pills ───────────────────────────────────────── */

.gd-detail .gd-flag,
.gd-detail .gd-plat,
.gd-detail .gd-stage .gd-chip {
    transition: background .2s var(--gdx-out), border-color .2s var(--gdx-out),
                transform .26s var(--gdx-spring), box-shadow .26s var(--gdx-out);
}
.gd-detail .gd-plat:hover {
    transform: translateY(-3px);
    box-shadow: 0 10px 24px rgba(0, 0, 0, .40), 0 0 0 1px rgba(255, 255, 255, .12);
}
.gd-detail a.gd-chip:hover { transform: translateY(-2px); }

/* The unreleased flag is the one badge that changes what a reader should do
   next, so it is the one badge that pulses. Everything else holds still. */
.gd-detail .gd-flag--red { animation: gdx-flagpulse 3.4s ease-in-out infinite; }
@keyframes gdx-flagpulse {
    0%, 100% { box-shadow: 0 6px 20px rgba(229, 27, 35, .38); }
    50%      { box-shadow: 0 6px 28px rgba(229, 27, 35, .62); }
}

/* ── The call to action ─────────────────────────────────────────────────── */

.gd-detail .gd-stage .gd-btn {
    transition: transform .24s var(--gdx-spring), background .2s var(--gdx-out),
                border-color .2s var(--gdx-out), box-shadow .24s var(--gdx-out);
}
.gd-detail .gd-stage .gd-btn:not(.gd-btn-primary):hover {
    transform: translateY(-2px);
    box-shadow: 0 10px 26px rgba(0, 0, 0, .38);
}

.gd-detail .gd-stage .gd-btn-primary {
    position: relative; overflow: hidden; isolation: isolate;
}
/*
 * A light sweep every seven seconds. Long enough between passes that it reads
 * as a highlight catching the button rather than as a progress bar. The
 * negative z-index puts it above the button's own gradient and behind its
 * label, which is why the parent isolates.
 */
.gd-detail .gd-stage .gd-btn-primary::before {
    content: ''; position: absolute; top: -50%; bottom: -50%; left: -50%; width: 40%;
    z-index: -1;
    background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .38), transparent);
    transform: skewX(-18deg);
    animation: gdx-sweep 7s 1.2s ease-in-out infinite;
}
@keyframes gdx-sweep {
    0%        { left: -50%; }
    26%, 100% { left: 130%; }
}
.gd-detail .gd-stage .gd-btn-primary:hover { transform: translateY(-2px) scale(1.015); }

/* ── Score panel ────────────────────────────────────────────────────────── */

/*
 * The ring is animated by transitioning --gd-pct, which requires the custom
 * property to be registered as a number: an unregistered one is a string and
 * interpolates as a discrete swap. Browsers without @property ignore the block
 * and the ring simply appears at its final value, which is what it did before.
 */
@property --gd-pct {
    syntax: '<number>';
    inherits: false;
    initial-value: 0;
}
.gd-detail .gd-ring {
    transition: --gd-pct 1.5s var(--gdx-out);
    box-shadow: 0 0 0 1px rgba(255, 255, 255, .07);
}
/* A halo under the ring, breathing with it. */
.gd-detail .gd-ring::before {
    content: ''; position: absolute; inset: -9px; border-radius: 50%;
    background: radial-gradient(closest-side, rgba(255, 81, 87, .30), transparent 72%);
    animation: gdx-halo 4.2s ease-in-out infinite;
    pointer-events: none;
}
@keyframes gdx-halo {
    0%, 100% { opacity: .45; transform: scale(.97); }
    50%      { opacity: .95; transform: scale(1.05); }
}

/* Stars fill left to right as the panel arrives, so the row reads as a value
   being counted out rather than as five glyphs appearing at once. */
.gd-detail.gd-fx .gd-stars span { animation: gdx-pop .42s var(--gdx-spring) both; }
.gd-detail.gd-fx .gd-stars span:nth-child(1) { animation-delay: .55s; }
.gd-detail.gd-fx .gd-stars span:nth-child(2) { animation-delay: .63s; }
.gd-detail.gd-fx .gd-stars span:nth-child(3) { animation-delay: .71s; }
.gd-detail.gd-fx .gd-stars span:nth-child(4) { animation-delay: .79s; }
.gd-detail.gd-fx .gd-stars span:nth-child(5) { animation-delay: .87s; }
@keyframes gdx-pop {
    from { opacity: 0; transform: scale(.4) rotate(-25deg); }
    to   { opacity: 1; transform: none; }
}

.gd-detail .gd-scorestat { transition: background .24s var(--gdx-out); }
.gd-detail .gd-scorestat:hover { background: rgba(255, 255, 255, .07); }
.gd-detail a.gd-critic {
    transition: transform .24s var(--gdx-spring), background .2s var(--gdx-out), border-color .2s var(--gdx-out);
}
.gd-detail a.gd-critic:hover { transform: translateY(-2px); }

/* ── Media strip ────────────────────────────────────────────────────────── */

.gd-detail .gd-thumb {
    transition: transform .26s var(--gdx-spring), border-color .22s var(--gdx-out), box-shadow .26s var(--gdx-out);
}
.gd-detail .gd-thumb:hover { transform: translateY(-5px) scale(1.03); }
.gd-detail .gd-thumb img { transition: transform .6s var(--gdx-out); }
.gd-detail .gd-thumb:hover img { transform: scale(1.08); }

/* The play badge grows on hover, which is what tells a video tile from a
   screenshot before the reader commits to a click. */
.gd-detail .gd-thumb-play span,
.gd-detail .gd-video-play span {
    transition: transform .3s var(--gdx-spring), box-shadow .3s var(--gdx-out);
}
.gd-detail .gd-thumb:hover .gd-thumb-play span { transform: scale(1.14); box-shadow: 0 0 0 8px rgba(229, 27, 35, .18); }
.gd-detail .gd-video:hover .gd-video-play span { transform: scale(1.12); box-shadow: 0 0 0 10px rgba(229, 27, 35, .18); }

.gd-detail .gd-strip-nav {
    transition: background .2s var(--gdx-out), border-color .2s var(--gdx-out), transform .24s var(--gdx-spring);
}
.gd-detail .gd-strip-nav:hover { transform: scale(1.1); }

/* ============================================================================
   4 — SECTION RAIL
   ----------------------------------------------------------------------------
   The bar keeps its anchors and its observer. What it gains is a reading
   progress line along its lower edge, driven from the main column's scroll
   position — a real measurement of how far through the page you are, not a
   decorative bar.
   ========================================================================== */

.gd-detail .gd-tabs-progress {
    position: absolute; left: 0; right: 0; bottom: -1px; height: 2px;
    pointer-events: none; overflow: hidden;
}
.gd-detail .gd-tabs-progress i {
    display: block; height: 100%; width: 0;
    background: linear-gradient(90deg, var(--gd-red), #FF6B70);
    box-shadow: 0 0 12px rgba(229, 27, 35, .7);
    transition: width .12s linear;
}

/* The active marker slides rather than jumping, which is the difference
   between "a tab lit up" and "the page moved". */
.gd-detail .gd-tab { position: relative; transition: color .2s var(--gdx-out); }
.gd-detail .gd-tab::after {
    content: ''; position: absolute; left: 12px; right: 12px; bottom: -1px;
    height: 2px; border-radius: 2px; background: var(--gd-red);
    transform: scaleX(0);
    transition: transform .3s var(--gdx-out);
}
.gd-detail .gd-tab.is-on::after { transform: scaleX(1); }
.gd-detail .gd-tab.is-on { border-bottom-color: transparent; }

/* ============================================================================
   5 — BODY SECTIONS
   ========================================================================== */

.gd-detail .gd-sec {
    transition: box-shadow .3s var(--gdx-out), border-color .3s var(--gdx-out);
}
.gd-detail .gd-sec:hover {
    border-color: color-mix(in srgb, var(--gd-red) 22%, var(--gd-line));
    box-shadow: var(--gd-shadow-lg);
}

/* The section icon lands with a small overshoot as its card arrives. */
.gd-detail.gd-fx .gd-sec.is-in .gd-sec-ic {
    animation: gdx-pop .5s var(--gdx-spring) .12s both;
}

/* A brand rule that draws itself across the header as the section arrives —
   the one flourish marking where a section begins. Held at scaleX(0) until the
   reveal fires, so with no script it is simply never drawn. */
.gd-detail .gd-sec-h { position: relative; }
.gd-detail .gd-sec-h::after {
    content: ''; position: absolute; left: 0; bottom: -1px; height: 2px; width: 100%;
    background: linear-gradient(90deg, var(--gd-red), transparent 62%);
    transform: scaleX(0); transform-origin: 0 50%;
    transition: transform .8s var(--gdx-out) .1s;
}
.gd-detail.gd-fx .gd-sec.is-in .gd-sec-h::after { transform: scaleX(1); }

/* ── Feature cards ──────────────────────────────────────────────────────── */

/*
 * The existing hover was a static red disc in the bottom corner. It becomes a
 * spotlight following the pointer: --gdx-mx / --gdx-my are written by the
 * script, and without one the gradient simply centres itself.
 *
 * `inset` is restated rather than only zeroing right/bottom, because the base
 * rule sets all four offsets plus a width and a height — leaving any of them in
 * place over-constrains the box and the browser drops the offset it likes least.
 */
.gd-detail .gd-feat::after {
    inset: 0; width: auto; height: auto; border-radius: inherit;
    background: radial-gradient(
        220px 220px at var(--gdx-mx, 50%) var(--gdx-my, 50%),
        var(--gd-red-soft) 0%, transparent 68%
    );
}
.gd-detail .gd-feat {
    transition: transform .28s var(--gdx-spring), box-shadow .28s var(--gdx-out), border-color .28s var(--gdx-out);
}
.gd-detail .gd-feat:hover { transform: translateY(-5px); }
.gd-detail .gd-feat-ic { transition: transform .3s var(--gdx-spring), box-shadow .3s var(--gdx-out); }
.gd-detail .gd-feat:hover .gd-feat-ic {
    transform: translateY(-2px) rotate(-6deg) scale(1.07);
    box-shadow: 0 10px 22px rgba(229, 27, 35, .42);
}

/* ── Gallery and screenshots ────────────────────────────────────────────── */

.gd-detail .gd-gal-item,
.gd-detail .gd-shot,
.gd-detail .gd-shots-lead {
    transition: transform .3s var(--gdx-out), border-color .24s var(--gdx-out), box-shadow .3s var(--gdx-out);
}
.gd-detail .gd-gal-item:hover,
.gd-detail .gd-shot:hover,
.gd-detail .gd-shots-lead:hover {
    transform: translateY(-5px);
    border-color: var(--gd-red);
    box-shadow: 0 18px 40px rgba(0, 0, 0, .22);
}

/*
 * An expand affordance, drawn in CSS from two crossed bars over a disc. Every
 * one of these tiles opens the lightbox on click and nothing said so; a badge
 * on hover is the cheapest way to make a clickable image look clickable.
 *
 * `inset` is written in full for the same reason as the feature spotlight —
 * `.gd-shot::after` already declares `inset: 0`, and setting only top/right
 * would leave left:0 in force and pin the badge to the wrong corner.
 */
.gd-detail .gd-gal-item::after,
.gd-detail .gd-shot::after,
.gd-detail .gd-shots-lead::after {
    content: '';
    position: absolute;
    inset: 10px 10px auto auto;
    width: 34px; height: 34px; border-radius: 50%;
    background:
        linear-gradient(currentColor, currentColor) center / 13px 2px no-repeat,
        linear-gradient(currentColor, currentColor) center / 2px 13px no-repeat,
        rgba(12, 14, 19, .72);
    color: #fff;
    -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
    opacity: 0; transform: scale(.6);
    transition: opacity .24s var(--gdx-out), transform .3s var(--gdx-spring);
    pointer-events: none;
}
.gd-detail .gd-gal-item:hover::after,
.gd-detail .gd-shot:hover::after,
.gd-detail .gd-shots-lead:hover::after,
.gd-detail .gd-gal-item:focus-visible::after,
.gd-detail .gd-shot:focus-visible::after,
.gd-detail .gd-shots-lead:focus-visible::after {
    opacity: 1; transform: scale(1);
}

/* The lead screenshot anchors its section, so it takes the larger badge. */
.gd-detail .gd-shots-lead::after {
    inset: 14px 14px auto auto;
    width: 42px; height: 42px;
    background-size: 16px 2px, 2px 16px, auto;
}

/* ── Cards, tiles, rows ─────────────────────────────────────────────────── */

.gd-detail .gd-tile { transition: transform .3s var(--gdx-out); }
.gd-detail .gd-tile:hover { transform: translateY(-2px); }
.gd-detail .gd-tile-score { transition: transform .26s var(--gdx-spring), box-shadow .26s var(--gdx-out); }
.gd-detail .gd-tile:hover .gd-tile-score { transform: scale(1.08); box-shadow: 0 6px 16px rgba(0, 0, 0, .3); }

/* Buy rows: a highlight wipes across on hover, so the row under the pointer is
   unmistakable in a stack of four near-identical ones. Delisted rows are
   excluded — they are deliberately dimmed and should not light up. */
.gd-detail .gd-buy { position: relative; overflow: hidden; }
.gd-detail .gd-buy::before {
    content: ''; position: absolute; inset: 0; pointer-events: none;
    background: linear-gradient(100deg, transparent, var(--gd-red-soft) 46%, transparent);
    transform: translateX(-100%);
    transition: transform .7s var(--gdx-out);
}
.gd-detail .gd-buy:not(.is-gone):hover::before { transform: translateX(100%); }
.gd-detail .gd-buy > * { position: relative; z-index: 1; }
.gd-detail .gd-buy-ic { transition: transform .3s var(--gdx-spring); }
.gd-detail .gd-buy:not(.is-gone):hover .gd-buy-ic { transform: scale(1.09) rotate(-4deg); }

.gd-detail .gd-credit,
.gd-detail .gd-cocard {
    transition: transform .26s var(--gdx-spring), border-color .22s var(--gdx-out), box-shadow .26s var(--gdx-out);
}
.gd-detail a.gd-credit:hover,
.gd-detail a.gd-cocard:hover {
    transform: translateY(-3px);
    border-color: var(--gd-red-ring);
    box-shadow: var(--gd-shadow-lg);
}
.gd-detail .gd-credit-av { transition: transform .3s var(--gdx-spring); }
.gd-detail a.gd-credit:hover .gd-credit-av { transform: scale(1.08); }

.gd-detail .gd-video {
    transition: transform .28s var(--gdx-spring), border-color .24s var(--gdx-out), box-shadow .28s var(--gdx-out);
}
.gd-detail .gd-video:hover { transform: translateY(-5px); }
.gd-detail .gd-video-poster img { transition: transform .6s var(--gdx-out); }
.gd-detail .gd-video:hover .gd-video-poster img { transform: scale(1.06); }

.gd-detail .gd-chiprow .gd-chip,
.gd-detail .gd-attrs-row .gd-chip {
    transition: transform .22s var(--gdx-spring), background .2s var(--gdx-out), color .2s var(--gdx-out);
}
.gd-detail .gd-chiprow .gd-chip:hover,
.gd-detail .gd-attrs-row .gd-chip:hover { transform: translateY(-2px); }

/* ============================================================================
   6 — LANGUAGE TABLE
   ----------------------------------------------------------------------------
   The three support columns were pinned at 108px each and the language column
   sized to its content, which came to 502px inside a 1047px table: every one of
   the fourteen rows ended two thirds of the way across with nothing beyond it.

   Giving the first column `width:100%` makes it absorb all the slack — the
   standard fix, and the one that keeps the support columns at a fixed width so
   the three ticks stay in a straight line down the table.
   ========================================================================== */

.gd-detail .gd-langs th:first-child,
.gd-detail .gd-langs td:first-child { width: 100%; }
.gd-detail .gd-langs th:not(:first-child),
.gd-detail .gd-langs td:not(:first-child) { width: 132px; white-space: nowrap; }

/* Zebra striping earns its place at fourteen rows: it is what stops the eye
   sliding a line while crossing that now much wider gap to the ticks. */
.gd-detail .gd-langs tbody tr { transition: background .16s var(--gdx-out); }
.gd-detail .gd-langs tbody tr:nth-child(even) { background: color-mix(in srgb, var(--gd-line-soft) 55%, transparent); }
.gd-detail .gd-langs tbody tr:hover { background: var(--gd-red-soft); }
.gd-detail .gd-langs th[scope="row"] { transition: color .16s var(--gdx-out); }
.gd-detail .gd-langs tbody tr:hover th[scope="row"] { color: var(--gd-red); }

/* The section body is `is-flush`, so the table was running to the very edge of
   the card. The outer cells put the card's own padding back. */
.gd-detail .gd-langs th:first-child,
.gd-detail .gd-langs td:first-child { padding-left: 22px; }
.gd-detail .gd-langs th:last-child,
.gd-detail .gd-langs td:last-child { padding-right: 22px; }

/* ── Requirements ───────────────────────────────────────────────────────── */

.gd-detail .gd-req {
    transition: transform .26s var(--gdx-out), border-color .22s var(--gdx-out), box-shadow .26s var(--gdx-out);
}
.gd-detail .gd-req:hover { transform: translateY(-3px); box-shadow: var(--gd-shadow); }
.gd-detail .gd-req.is-rec { border-color: var(--gd-red-ring); }

/* ============================================================================
   7 — THE SIDEBAR RAIL
   ----------------------------------------------------------------------------
   `position:sticky; top:86px` was applied to a column measuring 2258px tall in
   a 987px viewport. Sticky pins as soon as the element's top would pass the
   offset, so the rail pinned on the first scroll and everything below its own
   fold — age rating, platforms, connectivity, official links, tags — could
   never be reached. Five cards were unreadable.

   The script measures the rail against the viewport and picks one of two
   behaviours:

     .is-pinned   it fits — pin it, which is what the original rule wanted
     .is-docked   it does not fit — pin it AND give it its own scroll, so the
                  whole rail stays reachable and the long dead gutter beside the
                  main column disappears

   With no script the rail falls back to static flow: not the intended look, but
   nothing is ever hidden by it.
   ========================================================================== */

.gd-detail .gd-rail { position: static; align-self: start; }

.gd-detail .gd-rail.is-pinned { position: sticky; top: var(--gdx-dock); }

.gd-detail .gd-rail.is-docked {
    position: sticky;
    top: var(--gdx-dock);
    max-height: calc(100vh - var(--gdx-dock) - 24px);
    overflow-y: auto;
    /* Chains to the page at either end rather than trapping the wheel. */
    overscroll-behavior-y: auto;
    scrollbar-width: thin;
    scrollbar-color: var(--gd-line) transparent;
    padding-right: 6px;
    /* Fades the cut edges, so a card sliced by the dock's bottom reads as
       "there is more below" rather than as a rendering fault. */
    -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 18px, #000 calc(100% - 22px), transparent 100%);
            mask-image: linear-gradient(180deg, transparent 0, #000 18px, #000 calc(100% - 22px), transparent 100%);
}
/*
 * Load-bearing. `.gd-col` is `display:flex; flex-direction:column`, and a flex
 * item's default `flex-shrink:1` means that the moment the dock applies a
 * max-height the cards satisfy it by CRUSHING THEMSELVES rather than by
 * overflowing into the scroll that was the whole point.
 *
 * Measured live before this rule: the Platforms card rendered 122px tall around
 * 377px of content, every other card was squashed to roughly a third, and the
 * rail's scrollHeight equalled its clientHeight — so nothing scrolled and the
 * bodies were simply clipped away under their own headers.
 */
.gd-detail .gd-rail.is-docked > * { flex-shrink: 0; }

.gd-detail .gd-rail.is-docked::-webkit-scrollbar { width: 6px; }
.gd-detail .gd-rail.is-docked::-webkit-scrollbar-track { background: transparent; }
.gd-detail .gd-rail.is-docked::-webkit-scrollbar-thumb { background: var(--gd-line); border-radius: 99px; }
.gd-detail .gd-rail.is-docked::-webkit-scrollbar-thumb:hover { background: var(--gd-faint); }

.gd-detail .gd-rcard {
    transition: border-color .22s var(--gdx-out), box-shadow .26s var(--gdx-out);
}
.gd-detail .gd-rcard:hover {
    border-color: color-mix(in srgb, var(--gd-red) 20%, var(--gd-line));
    box-shadow: var(--gd-shadow);
}
.gd-detail .gd-rcard-h > .gd-i { transition: transform .3s var(--gdx-spring); }
.gd-detail .gd-rcard:hover .gd-rcard-h > .gd-i { transform: scale(1.15); }

/* ============================================================================
   8 — FLOATING CONTROLS
   ----------------------------------------------------------------------------
   Two additions, both revealed by the script only once the hero has left the
   screen, so neither covers the page a reader has just arrived on.
   ========================================================================== */

/* Back to the top. A page with a 6481px main column has a real journey back. */
.gd-detail .gd-totop {
    position: fixed; right: 22px; bottom: 22px; z-index: 60;
    display: grid; place-items: center; width: 46px; height: 46px;
    border-radius: 50%; border: 1px solid var(--gd-line);
    background: var(--gd-surface); color: var(--gd-ink);
    box-shadow: var(--gd-shadow-lg); cursor: pointer;
    opacity: 0; visibility: hidden; transform: translateY(14px) scale(.9);
    transition: opacity .3s var(--gdx-out), transform .34s var(--gdx-spring), visibility .3s,
                border-color .2s var(--gdx-out), color .2s var(--gdx-out);
}
.gd-detail .gd-totop.is-on { opacity: 1; visibility: visible; transform: none; }
.gd-detail .gd-totop.is-on:hover { border-color: var(--gd-red); color: var(--gd-red); transform: translateY(-3px); }
.gd-detail .gd-totop .gd-i { transform: rotate(-90deg); }

/*
 * The mobile action bar. On a phone the buy button scrolls away inside the
 * first screenful and never comes back; this keeps it — and only it —
 * reachable. It is built in the markup from the same records the hero uses, so
 * a game with no store link and no media has no bar at all.
 */
.gd-detail .gd-actionbar {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 58;
    display: none; gap: 10px;
    padding: 10px 14px calc(10px + env(safe-area-inset-bottom, 0px));
    background: color-mix(in srgb, var(--gd-surface) 92%, transparent);
    -webkit-backdrop-filter: saturate(160%) blur(14px); backdrop-filter: saturate(160%) blur(14px);
    border-top: 1px solid var(--gd-line);
    transform: translateY(110%);
    transition: transform .34s var(--gdx-out);
}
.gd-detail .gd-actionbar.is-on { transform: none; }
.gd-detail .gd-actionbar .gd-btn { flex: 1 1 0; min-width: 0; overflow: hidden; }

@media (max-width: 720px) {
    .gd-detail .gd-actionbar { display: flex; }
    /* Clears the bar, so the footer's last line never sits underneath it. */
    .gd-detail.gd-has-bar { padding-bottom: 72px; }
    .gd-detail .gd-totop { bottom: 86px; right: 14px; width: 42px; height: 42px; }
}

/* ============================================================================
   9 — RESPONSIVE REFINEMENT
   ----------------------------------------------------------------------------
   The existing breakpoints at 1180 / 900 / 620 stay and keep doing their work.
   These add the tablet and small-phone cases the page did not cover, and undo
   the effects that do not belong on a touch screen.
   ========================================================================== */

/* Tablet landscape — the rail stacks under the content, so it must stop being
   sticky or it pins to the top of a full-width block. */
@media (max-width: 1180px) {
    .gd-detail .gd-layout { grid-template-columns: minmax(0, 1fr); }
    .gd-detail .gd-rail,
    .gd-detail .gd-rail.is-pinned,
    .gd-detail .gd-rail.is-docked {
        position: static; max-height: none; overflow: visible; padding-right: 0;
        -webkit-mask-image: none; mask-image: none;
    }
    /* Two columns of rail cards rather than one full-width stack: a 900px-wide
       "Age rating" card holding two small badges is mostly empty. */
    .gd-detail .gd-rail {
        display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
        gap: 18px; align-items: start;
    }
}

/* Tablet portrait */
@media (max-width: 900px) {
    .gd-detail .gd-gal { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    /* The scanline layer costs more than it adds at this size. */
    .gd-detail .gd-stage-fx::before { display: none; }
    .gd-detail .gd-sec { scroll-margin-top: 84px; }
}

/* Phone */
@media (max-width: 620px) {
    .gd-detail .gd-rail { grid-template-columns: minmax(0, 1fr); }
    .gd-detail .gd-gal  { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 9px; }
    .gd-detail .gd-shots-rest { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 9px; }
    .gd-detail .gd-feats { grid-template-columns: minmax(0, 1fr); }

    /* A hover state cannot be dismissed on a touch screen, so the badges that
       depend on one are simply always on. */
    .gd-detail .gd-gal-item::after,
    .gd-detail .gd-shot::after {
        opacity: .82; transform: none;
        width: 28px; height: 28px;
        background-size: 11px 2px, 2px 11px, auto;
    }

    .gd-detail .gd-stage-poster { transform: none !important; }
    .gd-detail .gd-stage-poster::after { display: none; }

    .gd-detail .gd-langs th:first-child,
    .gd-detail .gd-langs td:first-child { padding-left: 14px; }
    .gd-detail .gd-langs th:last-child,
    .gd-detail .gd-langs td:last-child { padding-right: 14px; }
    .gd-detail .gd-langs th:not(:first-child),
    .gd-detail .gd-langs td:not(:first-child) { width: 58px; }
}

/* Very small phones — the 320–380px band the page had no case for at all. */
@media (max-width: 380px) {
    .gd-detail .gd-gal,
    .gd-detail .gd-shots-rest { grid-template-columns: minmax(0, 1fr); }
    .gd-detail .gd-stage-cta .gd-btn { font-size: 14px; padding: 13px 16px; }
    .gd-detail .gd-bigscore { flex-wrap: wrap; }
}

/* Coarse pointers get no hover-driven motion: on a touch screen these fire on
   tap and then stay stuck until something else is tapped. */
@media (hover: none) {
    .gd-detail .gd-feat:hover,
    .gd-detail .gd-video:hover,
    .gd-detail .gd-gal-item:hover,
    .gd-detail .gd-shot:hover,
    .gd-detail .gd-shots-lead:hover,
    .gd-detail a.gd-credit:hover,
    .gd-detail a.gd-cocard:hover,
    .gd-detail .gd-req:hover,
    .gd-detail .gd-plat:hover,
    .gd-detail .gd-thumb:hover { transform: none; }
}

/* ============================================================================
   10 — REDUCED MOTION
   ----------------------------------------------------------------------------
   The sheet already clamps durations inside `.gd`. Two things a clamp alone
   does not handle are handled here.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
    /* A clamped duration on an infinite animation still loops — thousands of
       times a second. Every looping effect on this page is decorative, so they
       are stopped outright rather than sped up. */
    .gd-detail .gd-stage-fx,
    .gd-detail .gd-stage-fx::before,
    .gd-detail .gd-stage.has-art .gd-stage-art img,
    .gd-detail .gd-flag--red,
    .gd-detail .gd-ring::before,
    .gd-detail .gd-stage .gd-btn-primary::before {
        animation: none !important;
    }
    .gd-detail .gd-stage-fx::after { display: none; }

    /* The reveal system's resting state is opacity 0, and with animation off
       nothing would ever clear it. The system is switched off rather than run
       at speed — which is the point of the preference, not a lesser version. */
    .gd-detail.gd-fx #gd-content > .gd-sec,
    .gd-detail.gd-fx .gd-rail > .gd-rcard,
    .gd-detail.gd-fx :is(.gd-feats, .gd-gal, .gd-shots-rest, .gd-videos, .gd-buys, .gd-credits, .gd-grid) > * {
        opacity: 1 !important;
        transform: none !important;
    }
    .gd-detail .gd-stage-poster { transform: none !important; }
}

/* ============================================================================
   CARD INTERACTION SYSTEM
   ----------------------------------------------------------------------------
   One hover language, shared by every card in the game UI:

       .gd-gc     the directory's game card, grid and list
       .gd-tile   the detail page's related / series / guide tiles

   Five layers, each doing one job, composited so they read as a single
   material rather than as five effects firing at once:

       1  RIM      a light travelling around the card's 1px border
       2  SHEEN    a specular band sweeping across the artwork
       3  SPOT     a soft glow under the pointer
       4  TILT     the card leaning toward the pointer in 3D
       5  ARROW    a go-affordance sliding in beside the title

   WHAT DRIVES THEM
   Layers 3 and 4 read --gdc-mx / --gdc-my / --gdc-rx / --gdc-ry, written by
   assets/js/game-cards.js from one delegated pointer listener. Every one of
   them has an initial value here, so with no script the card still lifts, still
   sheens and still lights its rim on hover — the pointer layers just centre
   themselves. Nothing is hidden or disabled when the script is absent.

   COST
   Only transform, opacity and one registered angle animate. No layout, no
   paint of text, and the rim's conic gradient spins only while a card is
   actually hovered — a directory of forty cards animates one of them at a time.
   ========================================================================== */

/* The rim's travelling angle. Registered so it interpolates: an unregistered
   custom property is a string and would jump from 0deg to 360deg in one frame
   instead of sweeping. Browsers without @property skip the spin and keep the
   static rim, which still reads correctly. */
@property --gdc-angle {
    syntax: '<angle>';
    inherits: false;
    initial-value: 0deg;
}

.gd .gd-gc,
.gd .gd-tile {
    --gdc-angle: 0deg;
    --gdc-rx: 0deg;
    --gdc-ry: 0deg;
    --gdc-mx: 50%;
    --gdc-my: 50%;
    --gdc-lift: 0px;

    /* The lift lives in the same transform as the tilt, because a second
       transform on a child would fight this one for the same matrix. */
    transform:
        perspective(1100px)
        rotateX(var(--gdc-rx))
        rotateY(var(--gdc-ry))
        translate3d(0, var(--gdc-lift), 0);
    transition:
        transform .38s var(--gdx-out, cubic-bezier(.16, 1, .3, 1)),
        box-shadow .38s var(--gdx-out, cubic-bezier(.16, 1, .3, 1)),
        border-color .3s ease;
}

/* While the pointer is moving the transform must track it; the longer easing
   above is for the settle when the pointer leaves. */
.gd .gd-gc.is-live,
.gd .gd-tile.is-live { transition: transform .09s linear, box-shadow .38s ease, border-color .3s ease; }

.gd .gd-gc:hover  { --gdc-lift: -7px; }
.gd .gd-tile:hover { --gdc-lift: -5px; }

/* The lift and the glow together. The red is held at low alpha and wide blur so
   it reads as the card being lit from behind rather than as a coloured ring. */
.gd .gd-gc:hover {
    border-color: transparent;
    box-shadow:
        0 22px 52px rgba(8, 10, 15, .20),
        0 0 38px -10px rgba(229, 27, 35, .55);
}
@media (prefers-color-scheme: dark) {
    .gd .gd-gc:hover { box-shadow: 0 22px 52px rgba(0, 0, 0, .55), 0 0 40px -8px rgba(229, 27, 35, .48); }
}
.theme-dark .gd .gd-gc:hover, .gd.theme-dark .gd-gc:hover {
    box-shadow: 0 22px 52px rgba(0, 0, 0, .55), 0 0 40px -8px rgba(229, 27, 35, .48);
}
.theme-light .gd .gd-gc:hover, .gd.theme-light .gd-gc:hover {
    box-shadow: 0 22px 52px rgba(8, 10, 15, .20), 0 0 38px -10px rgba(229, 27, 35, .55);
}

/* ── 1 · RIM ─────────────────────────────────────────────────────────────
   A light running around the card's own 1px border.

   Drawn as a conic gradient filling the card, then masked down to just the
   border ring: two stacked masks, one clipped to the content box, the other to
   the whole box, composited so only the difference — the 1px padding — paints.

   The @supports guard is load-bearing rather than defensive. Without mask
   compositing the gradient is NOT trimmed to the border; it floods the entire
   card and buries the artwork under a red wash. Browsers that cannot do the
   trick must get no rim at all, which is why the whole layer sits inside it.
   ------------------------------------------------------------------------ */

@supports ((-webkit-mask-composite: xor) or (mask-composite: exclude)) {
    .gd .gd-gc::before,
    .gd .gd-tile-cover::before {
        content: '';
        position: absolute; inset: 0; z-index: 4;
        border-radius: inherit;
        padding: 1px;
        pointer-events: none;
        opacity: 0;

        background: conic-gradient(
            from var(--gdc-angle),
            transparent 0deg,
            rgba(229, 27, 35, .10) 40deg,
            var(--gd-red) 74deg,
            #FFB3B6 92deg,
            var(--gd-red) 110deg,
            rgba(229, 27, 35, .10) 148deg,
            transparent 200deg,
            transparent 360deg
        );

        -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
                mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
        -webkit-mask-composite: xor;
                mask-composite: exclude;

        transition: opacity .3s ease;
    }

    .gd .gd-gc:hover::before,
    .gd .gd-tile:hover .gd-tile-cover::before {
        opacity: 1;
        animation: gdc-rim 2.6s linear infinite;
    }
}

@keyframes gdc-rim { to { --gdc-angle: 360deg; } }

/* ── 2 · SHEEN ───────────────────────────────────────────────────────────
   A specular band crossing the artwork once per hover.

   It is deliberately a one-shot on enter rather than a loop: a card that
   glints forever is a banner ad. The band is oversized and skewed so its
   leading edge clears the corner before the trailing edge arrives.
   ------------------------------------------------------------------------ */

.gd .gd-gc-art::before,
.gd .gd-tile-cover .gd-cover::after,
.gd .gd-tile-img-wrap::before {
    content: '';
    position: absolute; inset: -40% -70%;
    z-index: 3;
    pointer-events: none;
    background: linear-gradient(
        104deg,
        transparent 38%,
        rgba(255, 255, 255, .10) 46%,
        rgba(255, 255, 255, .48) 50%,
        rgba(255, 255, 255, .10) 54%,
        transparent 62%
    );
    transform: translate3d(-130%, 0, 0) skewX(-14deg);
    /*
     * NOT the page's --gdx-out expo curve. That one is built to settle a moving
     * element, so it spends ~90% of its distance in the first sixth of its
     * duration: measured live, the band was already 715px across at 110ms and
     * the remaining 700ms was imperceptible crawl — a sheen nobody could see.
     * A sweep wants near-even travel with a gentle landing instead.
     */
    transition: transform .85s cubic-bezier(.32, .5, .28, 1);
}
.gd .gd-gc:hover .gd-gc-art::before,
.gd .gd-tile:hover .gd-tile-cover .gd-cover::after {
    transform: translate3d(130%, 0, 0) skewX(-14deg);
}

/* The cover frame has to clip the band and establish its own stacking context,
   or the sheen escapes the artwork and crosses the card body too. */
.gd .gd-tile-cover .gd-cover,
.gd .gd-tile-cover { position: relative; overflow: hidden; }

/* ── 3 · SPOT ────────────────────────────────────────────────────────────
   A soft brand-coloured glow under the pointer, on the card body where the
   text is — so the pointer feels like it is lighting the surface it rests on.
   ------------------------------------------------------------------------ */

.gd .gd-gc-b { position: relative; z-index: 1; }
.gd .gd-gc-b::before {
    content: '';
    position: absolute; inset: 0;
    z-index: -1;
    pointer-events: none;
    opacity: 0;
    background: radial-gradient(
        200px 200px at var(--gdc-mx) var(--gdc-my),
        var(--gd-red-soft) 0%,
        transparent 72%
    );
    transition: opacity .32s ease;
}
.gd .gd-gc:hover .gd-gc-b::before { opacity: 1; }

/* ── 4 · ART DEPTH ───────────────────────────────────────────────────────
   The cover counter-shifts a little against the tilt. It is what separates a
   card that rotates from a card that has depth — the artwork sits behind the
   glass rather than being painted on it.
   ------------------------------------------------------------------------ */

.gd .gd-gc-art .gd-cover img {
    transition: transform .55s var(--gdx-out, cubic-bezier(.16, 1, .3, 1));
}
.gd .gd-gc:hover .gd-gc-art .gd-cover img {
    transform: scale(1.075) translate3d(calc(var(--gdc-ry) * -.34), calc(var(--gdc-rx) * .34), 0);
}

/* ── 5 · ARROW ───────────────────────────────────────────────────────────
   A go-affordance beside the title. The whole card is already one link — the
   stretched ::after on the title anchor covers it — and nothing said so.

   Drawn in CSS from a rotated square: two borders make the chevron, so there is
   no glyph to load and no icon markup to add to a component that renders
   thousands of times.
   ------------------------------------------------------------------------ */

.gd .gd-gc-t {
    display: flex; align-items: baseline; gap: 7px;
}
.gd .gd-gc-t::after {
    content: '';
    flex: 0 0 auto;
    align-self: center;
    width: 7px; height: 7px;
    border-top: 2px solid var(--gd-red);
    border-right: 2px solid var(--gd-red);
    border-radius: 1px;
    transform: rotate(45deg) translate3d(-6px, 0, 0);
    opacity: 0;
    transition: opacity .28s ease, transform .34s cubic-bezier(.34, 1.3, .64, 1);
}
.gd .gd-gc:hover .gd-gc-t::after {
    opacity: 1;
    transform: rotate(45deg) translate3d(0, 0, 0);
}

/* ── Badges and score ────────────────────────────────────────────────────
   They ride above the sheen rather than under it, and lift very slightly so
   they stay legible while the card tilts away from the pointer.
   ------------------------------------------------------------------------ */

.gd .gd-gc-badge,
.gd .gd-gc-score {
    z-index: 5;
    transition: transform .3s cubic-bezier(.34, 1.3, .64, 1), box-shadow .3s ease;
}
.gd .gd-gc:hover .gd-gc-score {
    transform: scale(1.08);
    box-shadow: 0 6px 18px rgba(0, 0, 0, .34);
}
.gd .gd-gc:hover .gd-gc-badge { transform: translateY(-1px); }

/* Platform glyphs settle in one after another instead of all recolouring at
   once — the same staggering idea the detail page uses for its grids. */
.gd .gd-gc-plat { transition: background .24s ease, color .24s ease, transform .3s cubic-bezier(.34, 1.3, .64, 1); }
.gd .gd-gc:hover .gd-gc-plat { transform: translateY(-2px); }
.gd .gd-gc:hover .gd-gc-plat:nth-child(1) { transition-delay: .02s; }
.gd .gd-gc:hover .gd-gc-plat:nth-child(2) { transition-delay: .06s; }
.gd .gd-gc:hover .gd-gc-plat:nth-child(3) { transition-delay: .10s; }
.gd .gd-gc:hover .gd-gc-plat:nth-child(4) { transition-delay: .14s; }

/* ── The list variant ────────────────────────────────────────────────────
   A 218px-wide strip of art beside a wide body. A tilt that reads well on a
   3:4 poster looks like a wobble on a shape this wide, so the list card keeps
   the rim, the sheen and the spotlight, and drops the rotation.
   ------------------------------------------------------------------------ */

.gd .gd-gc--list {
    --gdc-rx: 0deg !important;
    --gdc-ry: 0deg !important;
}
.gd .gd-gc--list:hover { --gdc-lift: -4px; }

/* ── Detail-page tiles ───────────────────────────────────────────────────
   The related / series / guides tiles are covers with a caption under them
   rather than full cards, so they take the rim and the depth and leave the
   spotlight and the arrow to the directory's larger surfaces.
   ------------------------------------------------------------------------ */

.gd .gd-tile-cover { border-radius: var(--gd-r); }
.gd .gd-tile:hover .gd-tile-cover img { transform: scale(1.08); }
.gd .gd-tile-img { transition: transform .5s var(--gdx-out, cubic-bezier(.16, 1, .3, 1)), box-shadow .38s ease; }
.gd .gd-tile:hover .gd-tile-img { box-shadow: 0 16px 36px rgba(8, 10, 15, .22); }

/* The detail sheet set its own lift on .gd-tile before this system existed;
   the transform above now owns that, so the older rule is neutralised rather
   than left to fight it for the same matrix. */
.gd-detail .gd-tile:hover { transform:
        perspective(1100px)
        rotateX(var(--gdc-rx))
        rotateY(var(--gdc-ry))
        translate3d(0, var(--gdc-lift), 0); }

/* ── Keyboard ────────────────────────────────────────────────────────────
   A card reached by Tab gets the same treatment a hovered one does. The focus
   lands on the title link, so the card is styled through :focus-within — the
   outline itself is left exactly as the base sheet draws it.
   ------------------------------------------------------------------------ */

.gd .gd-gc:focus-within { --gdc-lift: -7px; }
.gd .gd-gc:focus-within .gd-gc-t::after { opacity: 1; transform: rotate(45deg) translate3d(0, 0, 0); }
@supports ((-webkit-mask-composite: xor) or (mask-composite: exclude)) {
    .gd .gd-gc:focus-within::before { opacity: 1; animation: gdc-rim 2.6s linear infinite; }
}

/* ── Touch ───────────────────────────────────────────────────────────────
   On a coarse pointer every one of these is a trap: hover fires on tap and
   then sticks until something else is tapped. The card keeps its plain press
   feedback and nothing else.
   ------------------------------------------------------------------------ */

@media (hover: none) {
    .gd .gd-gc, .gd .gd-tile { transform: none; }
    .gd .gd-gc:hover, .gd .gd-tile:hover { transform: none; }
    .gd .gd-gc::before, .gd .gd-tile-cover::before { display: none; }
    .gd .gd-gc-art::before, .gd .gd-tile-cover .gd-cover::after { display: none; }
    .gd .gd-gc-b::before { display: none; }
    .gd .gd-gc-t::after { opacity: 1; transform: rotate(45deg); }
    .gd .gd-gc:active { transform: scale(.985); transition: transform .12s ease; }
}

/* ── Reduced motion ──────────────────────────────────────────────────────
   The rim spins forever, so a clamped duration would loop it thousands of
   times a second rather than slowing it. Every moving part is stopped; the
   card keeps its border colour and shadow so hover is still legible.
   ------------------------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
    .gd .gd-gc, .gd .gd-tile,
    .gd .gd-gc:hover, .gd .gd-tile:hover { transform: none !important; }
    .gd .gd-gc::before,
    .gd .gd-tile-cover::before { animation: none !important; }
    .gd .gd-gc-art::before,
    .gd .gd-tile-cover .gd-cover::after { display: none; }
    .gd .gd-gc-t::after { transition: none; }
}

/* =============================================================================
   TEXT FIELDS — FOCUS
   -----------------------------------------------------------------------------
   The blanket ring near the top of this sheet —

       .gd input:focus-visible { outline: 2px solid var(--gd-red);
                                 outline-offset: 2px; border-radius: 6px; }

   — is right for links, buttons and anything else reached by Tab. It is wrong
   for a text field, for two reasons that compound.

   FIRST: a text input matches :focus-visible on a PLAIN MOUSE CLICK, not only
   on keyboard focus. That is per spec — typing is the expected next action — so
   simply clicking a search box painted the ring.

   SECOND: it is drawn as an OFFSET rectangle with its own 6px radius, ignoring
   the field's real shape. Inside a pill-shaped search wrapper that already
   shows focus on its own border, the result was a hard red rounded box floating
   inside the pill: the "red box inside the box".

   It also silently outranked the fields' own focus styling — `.gd-input:focus`
   already sets `outline: none` and a ring that follows its border-radius, but
   at (0,2,0) it loses to the blanket rule's (0,3,0).

   FOCUS IS NOT REMOVED. It moves to the shape the field actually has: the
   field's own border plus a ring that hugs its radius. Where a wrapper already
   indicates focus, the field draws nothing and the wrapper keeps doing it —
   the same conclusion navigation.css reached for the header search.
   ============================================================================= */

.gd input[type="text"]:focus-visible,
.gd input[type="search"]:focus-visible,
.gd input[type="email"]:focus-visible,
.gd input[type="url"]:focus-visible,
.gd input[type="tel"]:focus-visible,
.gd input[type="number"]:focus-visible,
.gd input[type="password"]:focus-visible,
.gd input[type="date"]:focus-visible,
.gd input[type="datetime-local"]:focus-visible,
.gd input[type="month"]:focus-visible,
.gd input[type="time"]:focus-visible,
.gd input:not([type]):focus-visible,
.gd textarea:focus-visible {
    outline: 0;
    border-color: var(--gd-red);
    box-shadow: 0 0 0 3px var(--gd-red-ring);
}

/* Fields whose WRAPPER already lights up on focus. A ring on the field as well
   as the wrapper is the doubling this section exists to remove, so inside these
   the field draws nothing at all. */
.gd .co-search input:focus-visible,
.gd .co-quick-s input:focus-visible,
.gd .gd-field-search input:focus-visible,
.gd .gd-tok-field input:focus-visible {
    outline: 0;
    border-color: inherit;
    box-shadow: none;
}
