/*
  Asset Store Sales design system. Tokens follow handoff 01 "Color tokens" and
  "Typography, spacing, shape, and icons". Layers: foundations → components → pages → utilities.
*/
@layer foundations, components, pages, utilities;

/* ───────────────────────── Foundations ───────────────────────── */
@layer foundations {
    @font-face {
        font-family: "Schibsted Grotesk";
        src: url("/fonts/schibsted-grotesk-latin-wght-normal.woff2") format("woff2");
        font-weight: 400 900;
        font-style: normal;
        font-display: swap;
    }

    :root {
        color-scheme: dark;

        /* One warm graphite scale, matched to the warm text, so greys and type read as one palette. Layers are told
           apart by tone, not borders: canvas < surface (cards, panels) < raised (controls) < button. */
        --color-canvas: #141210;
        --color-surface: #1D1A17;
        --color-raised: #28241F;
        --color-raised-hover: #302B25;
        --color-button: #38322B;
        --color-button-hover: #403930;
        --color-divider: #2F2A25;
        /* Edges of controls that need to be seen (inputs, the toggle): 3:1 against the surface. */
        --color-control-border: #6E665C;
        /* Faint edges: raised buttons, pills, the search field. */
        --color-edge: rgb(255 240 220 / 0.16);
        --color-edge-strong: rgb(255 240 220 / 0.26);
        --color-text: #F4EFE7;
        --color-text-secondary: #B4ACA1;
        --color-text-tertiary: #8F877C;
        --color-red: #C9302C;
        --color-on-red: #FFFFFF;
        --color-red-mark: #D63A33;
        --color-red-text: #F26B5F;
        /* Tag tints: a soft fill plus lighter text, readable at small sizes (WCAG AA on the surface colour). */
        --color-red-tint: rgb(214 58 51 / 0.2);
        --color-red-tint-text: #FF9187;
        --color-neutral-tint: rgb(255 240 220 / 0.08);
        /* Mid-size discounts (20–49% off); red marks 50% and up. Dark text: 6.2:1. */
        --color-orange: #E8892B;
        --color-on-orange: #1A1408;
        --color-gold: #F5C518;
        --color-gold-hover: #F8CF3D;
        --color-on-gold: #1A1408;
        --color-star: #FFC45B;
        --color-star-empty: #4A433B;
        --color-focus: #F4EFE7;
        --shadow-button: inset 0 0 0 1px var(--color-edge-strong), inset 0 1px 0 rgb(255 255 255 / 0.07), 0 1px 2px rgb(0 0 0 / 0.45);
        --shadow-button-hover: inset 0 0 0 1px rgb(255 240 220 / 0.34), inset 0 1px 0 rgb(255 255 255 / 0.08), 0 1px 2px rgb(0 0 0 / 0.45);
        --shadow-gold: inset 0 -1px 0 rgb(0 0 0 / 0.18), 0 1px 2px rgb(0 0 0 / 0.45);

        /* Schibsted Grotesk, self-hosted (wwwroot/fonts, SIL Open Font License). */
        --font: "Schibsted Grotesk", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
        --text-xs: 0.75rem;
        --text-sm: 0.8125rem;
        --text-md: 0.875rem;
        --text-base: 1rem;
        --text-lg: 1.125rem;
        --text-xl: 1.375rem;
        --text-2xl: 1.75rem;

        --space-1: 4px;
        --space-2: 8px;
        --space-3: 12px;
        --space-4: 16px;
        --space-5: 24px;
        --space-6: 32px;
        --space-7: 48px;

        --radius-control: 10px;
        --radius-small: 6px;
        --radius-card: 14px;
        --hit: 44px;
        --page-max: 120rem;
        /* Wide screens share one grid: a sidebar column (logo, filters, details aside) and a main column (search,
           tabs, results, details), so the header, tabs and content line up on the same vertical lines. */
        --sidebar: 15rem;
        --column-gap: var(--space-4);
        /* The page's side margin grows with the window: 16px on phones, 32px at 1280, 48px from 1920. The page is
           as wide as the window up to 1920px, so without this a desktop page ran to 16px from each edge. */
        --gutter: clamp(var(--space-4), 2.5vw, var(--space-7));
    }

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

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

    body {
        margin: 0;
        min-height: 100vh;
        display: flex;
        flex-direction: column;
        background: var(--color-canvas);
        color: var(--color-text);
        font-family: var(--font);
        font-size: var(--text-base);
        line-height: 1.4;
    }

    h1, h2, h3, p { margin: 0; }
    h1, h2, h3 { line-height: 1.2; font-weight: 600; }

    a { color: inherit; }

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

    button, input, select { font: inherit; color: inherit; }

    :focus-visible {
        outline: 2px solid var(--color-focus);
        outline-offset: 2px;
    }

    /* Browser-drawn details in the palette too. */
    ::selection { background: rgb(245 197 24 / 0.35); color: var(--color-text); }
    html { scrollbar-color: var(--color-button) var(--color-canvas); accent-color: var(--color-gold); }
    input { caret-color: var(--color-gold); }

    @media (prefers-reduced-motion: reduce) {
        *, *::before, *::after {
            animation-duration: 0.01ms !important;
            transition-duration: 0.01ms !important;
            scroll-behavior: auto !important;
        }
    }
}

/* ───────────────────────── Components ───────────────────────── */
@layer components {
    .icon {
        width: 1.25em;
        height: 1.25em;
        flex: none;
        vertical-align: -0.25em;
        /* Lucide drawing defaults; set here (not on the symbols) so components can override fill. */
        fill: none;
        stroke: currentColor;
        stroke-width: 2;
        stroke-linecap: round;
        stroke-linejoin: round;
    }

    .skip-link {
        position: absolute;
        left: var(--space-2);
        top: -100px;
        z-index: 100;
        background: var(--color-gold);
        color: var(--color-on-gold);
        padding: var(--space-2) var(--space-3);
        border-radius: var(--radius-control);
        font-weight: 600;
    }
    .skip-link:focus { top: var(--space-2); }

    /* Asset Store event banner (Promotion settings) */
    .promo { background: var(--color-surface); border-bottom: 1px solid var(--color-divider); }
    .promo__inner {
        display: flex;
        align-items: center;
        gap: var(--space-2) var(--space-3);
        max-width: var(--page-max);
        margin: 0 auto;
        padding: var(--space-2) var(--gutter);
    }
    .promo__icon { flex: none; color: var(--color-gold); }
    .promo__text { flex: 1; min-width: 0; font-weight: 600; }
    .promo__link {
        flex: none;
        display: inline-flex;
        align-items: center;
        gap: var(--space-1);
        min-height: var(--hit);
        color: var(--color-gold);
        font-weight: 600;
        text-underline-offset: 3px;
        white-space: nowrap;
    }
    .promo__dismiss { flex: none; }
    @media (max-width: 599px) {
        .promo__inner { flex-wrap: wrap; }
        .promo__text { flex-basis: calc(100% - 3 * var(--hit)); }
        .promo__link { order: 3; flex-basis: 100%; min-height: 32px; }
    }
    .environment-ribbon {
        background: var(--color-gold);
        color: var(--color-on-gold);
        text-align: center;
        font-weight: 600;
        font-size: var(--text-sm);
        padding: var(--space-1);
    }

    /* Header */
    .site-header {
        background: var(--color-canvas);
        border-bottom: 1px solid var(--color-divider);
    }
    .site-header__top {
        display: grid;
        grid-template-columns: 1fr auto;
        grid-template-areas: "brand account" "search search";
        align-items: center;
        gap: var(--space-3) var(--space-4);
        max-width: var(--page-max);
        margin: 0 auto;
        padding: var(--space-3) var(--gutter);
    }
    .brand {
        grid-area: brand;
        display: inline-flex;
        align-items: center;
        gap: var(--space-2);
        min-height: var(--hit);
        text-decoration: none;
        font-size: var(--text-xl);
        font-weight: 600;
        white-space: nowrap;
    }
    .brand__mark { width: 32px; height: 32px; flex: none; }
    .brand__text { display: grid; line-height: 1.15; }
    /* What the site is, under the name: small and quiet, so the name still reads first. */
    .brand__tagline { font-size: var(--text-xs); font-weight: 500; color: var(--color-text-secondary); }
    .brand--small { font-size: var(--text-lg); }
    .brand--small .brand__mark { width: 26px; height: 26px; }

    /* Long enough for any query, short enough not to read as a bar across the page on wide screens. */
    .search {
        grid-area: search;
        position: relative;
        width: 100%;
        max-width: 40rem;
    }
    .search__icon {
        position: absolute;
        left: var(--space-3);
        top: 50%;
        translate: 0 -50%;
        color: var(--color-text-secondary);
        pointer-events: none;
    }
    .search__input {
        width: 100%;
        min-height: var(--hit);
        padding: 0 var(--space-3) 0 calc(var(--space-3) * 2 + 1.25rem);
        background: var(--color-surface);
        border: 1px solid var(--color-edge);
        border-radius: var(--radius-control);
    }
    .search__input:hover { border-color: var(--color-edge-strong); }
    /* Every placeholder at the secondary text colour (AA on the control backgrounds). */
    ::placeholder { color: var(--color-text-secondary); opacity: 1; }

    .account { grid-area: account; position: relative; }
    .account__button {
        display: grid;
        place-items: center;
        width: var(--hit);
        height: var(--hit);
        border-radius: 50%;
        cursor: pointer;
        list-style: none;
    }
    .account__button::-webkit-details-marker { display: none; }
    .account__button .icon { width: 28px; height: 28px; }
    .account__menu {
        position: absolute;
        right: 0;
        top: calc(100% + var(--space-2));
        z-index: 20;
        min-width: 14rem;
        padding: var(--space-3);
        background: var(--color-raised);
        border-radius: var(--radius-card);
        box-shadow: inset 0 0 0 1px var(--color-edge), 0 8px 24px rgb(0 0 0 / 0.45);
        display: grid;
        gap: var(--space-2);
    }
    .account__name { color: var(--color-text-secondary); font-size: var(--text-sm); overflow-wrap: anywhere; }

    /* Destination navigation */
    .site-header__tabs { border-top: 1px solid var(--color-divider); }
    .destinations__list {
        display: grid;
        grid-template-columns: repeat(5, 1fr);
        max-width: var(--page-max);
        margin: 0 auto;
        padding: 0;
        list-style: none;
    }
    .destinations__link {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: var(--space-1);
        min-height: 60px;
        padding: var(--space-2) var(--space-1);
        color: var(--color-text-secondary);
        text-decoration: none;
        font-size: var(--text-md);
        text-align: center;
        border-bottom: 3px solid transparent;
    }
    .destinations__icon { width: 24px; height: 24px; }
    .destinations__link:hover { color: var(--color-text); }
    .destinations__link[aria-current="page"] {
        color: var(--color-text);
        font-weight: 600;
        border-bottom-color: var(--color-red-mark);
    }
    .destinations__link[aria-current="page"] .destinations__icon { color: var(--color-red-mark); }

    /* Buttons */
    .button {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: var(--space-2);
        min-height: var(--hit);
        padding: 0 var(--space-4);
        border-radius: var(--radius-control);
        border: 0;
        font-weight: 600;
        text-decoration: none;
        cursor: pointer;
        white-space: nowrap;
        transition: background-color 0.15s ease-out, box-shadow 0.15s ease-out, transform 0.15s ease-out;
    }
    .button:active { transform: translateY(1px); }
    /* Colour roles: gold is the one action colour (primary buttons, View deal, verdicts); red marks discounts and
       the brand; selected controls invert to the text colour so they never compete with either. */
    .button--primary, .button--deal { background: var(--color-gold); color: var(--color-on-gold); box-shadow: var(--shadow-gold); }
    .button--primary:hover, .button--deal:hover { background: var(--color-gold-hover); }
    /* Raised neutral buttons: a lighter fill than the surface, a firm edge, a faint top highlight and a soft shadow, so
       they read as clickable at rest. Hover only brightens a little. */
    .button--secondary { background: var(--color-button); color: var(--color-text); box-shadow: var(--shadow-button); }
    .button--secondary:hover { background: var(--color-button-hover); box-shadow: var(--shadow-button-hover); }
    .button--plain { background: none; box-shadow: inset 0 0 0 1px var(--color-edge-strong); }
    .button--plain:hover { background: var(--color-neutral-tint); }
    .button[disabled], .button[aria-disabled="true"] { opacity: 0.6; cursor: default; transform: none; }

    .icon-button {
        display: inline-grid;
        place-items: center;
        width: var(--hit);
        height: var(--hit);
        background: none;
        border: 0;
        border-radius: 50%;
        cursor: pointer;
    }
    .icon-button:hover { background: var(--color-neutral-tint); }

    .select { position: relative; display: inline-flex; }
    .select select {
        appearance: none;
        min-height: var(--hit);
        padding: 0 calc(var(--space-3) + 1.5rem) 0 var(--space-3);
        background: var(--color-button);
        border: 0;
        border-radius: var(--radius-control);
        box-shadow: var(--shadow-button);
        cursor: pointer;
        transition: background-color 0.15s ease-out, box-shadow 0.15s ease-out;
    }
    .select select:hover { background: var(--color-button-hover); box-shadow: var(--shadow-button-hover); }
    .select__chevron {
        position: absolute;
        right: var(--space-2);
        top: 50%;
        translate: 0 -50%;
        pointer-events: none;
    }

    /* Tags (badges) are labels, not controls: pill-shaped, compact and without borders, unlike buttons, which are
       taller rounded rectangles. Discounts keep a solid fill as the main sale signal; other tags are tinted. */
    .badge {
        display: inline-flex;
        align-items: center;
        gap: var(--space-1);
        padding: 1px var(--space-2);
        border-radius: 999px;
        font-size: var(--text-sm);
        font-weight: 700;
        line-height: 1.4;
        white-space: nowrap;
    }
    .badge--discount { background: var(--color-red); color: var(--color-on-red); border-radius: var(--radius-small); font-variant-numeric: proportional-nums; }
    /* Discount tiers (the legacy site's thresholds): red from 50% off, orange from 20%, a quiet raised fill below. */
    .badge--discount-mid { background: var(--color-orange); color: var(--color-on-orange); }
    .badge--discount-low { background: var(--color-button); color: var(--color-text); }
    /* Why it's on sale: the store's own sale is tinted red; a publisher's announcement stays neutral. */
    .badge--sale { background: var(--color-neutral-tint); color: var(--color-text-secondary); font-weight: 600; }
    /* Sales the store lists (official, launch discount, flash deal); publisher-announced ones stay neutral. */
    .badge--sale-store { background: var(--color-red-tint); color: var(--color-red-tint-text); }
    .badge--sale .icon { width: 1em; height: 1em; }
    /* The price history's verdict ("Lowest recorded", "6-month low"): gold, the colour of good news. */
    .badge--verdict { background: rgb(245 197 24 / 0.12); color: var(--color-gold); font-weight: 600; }
    .badge--verdict .icon { width: 1em; height: 1em; flex: none; }

    .notice {
        max-width: var(--page-max);
        margin: 0 auto var(--space-3);
        padding: var(--space-3) var(--space-4);
        border-radius: var(--radius-card);
        background: var(--color-surface);
    }
    .notice--error { color: var(--color-red-text); }

    /* Filter controls */
    .pills { display: flex; flex-wrap: wrap; gap: var(--space-2); }
    .pill { position: relative; }
    .pill input {
        position: absolute;
        opacity: 0;
        inset: 0;
        margin: 0;
        cursor: pointer;
    }
    /* A pill keeps one width whether or not it's selected, so choosing one never reflows the row: unselected
       pills pad by half the check mark on each side, and each label reserves its bold width. */
    .pill > span {
        --check-space: calc(1em + var(--space-1));
        display: inline-flex;
        align-items: center;
        gap: var(--space-1);
        min-height: var(--hit);
        padding: 0 calc(var(--space-2) + var(--check-space) / 2);
        background: var(--color-raised);
        border: 1px solid var(--color-edge);
        border-radius: var(--radius-control);
        font-size: var(--text-md);
        transition: background-color 0.15s ease-out, border-color 0.15s ease-out;
    }
    .pill:hover > span { background: var(--color-raised-hover); border-color: var(--color-edge-strong); }
    .pill__check { display: none; width: 1em; height: 1em; flex: none; }
    .pill__label { display: inline-flex; flex-direction: column; align-items: center; }
    .pill__label::after {
        content: attr(data-label);
        font-weight: 600;
        height: 0;
        overflow: hidden;
        visibility: hidden;
        user-select: none;
    }
    .pill input:checked + span, .pill:hover input:checked + span {
        padding: 0 var(--space-2);
        background: var(--color-text);
        border-color: var(--color-text);
        color: var(--color-canvas);
        font-weight: 600;
    }
    .pill input:checked + span .pill__check { display: inline; }
    .pill input:focus-visible + span { outline: 2px solid var(--color-focus); outline-offset: 2px; }

    .field { display: grid; gap: var(--space-1); }
    .field__label { font-size: var(--text-sm); color: var(--color-text-secondary); }
    .field__input input {
        width: 100%;
        min-height: var(--hit);
        padding: 0 var(--space-3);
        background: var(--color-canvas);
        border: 1px solid var(--color-control-border);
        border-radius: var(--radius-control);
    }
    .field__input input:hover { border-color: var(--color-text-tertiary); }
    .field__input--currency { position: relative; display: block; }
    .field__input--currency::before {
        content: "$";
        position: absolute;
        left: var(--space-3);
        top: 50%;
        translate: 0 -50%;
        color: var(--color-text-secondary);
    }
    .field__input--currency input { padding-left: calc(var(--space-3) + 0.9em); }
    .field__error { color: var(--color-red-text); font-size: var(--text-sm); }

    .filters {
        background: var(--color-surface);
        border-radius: var(--radius-card);
    }
    .filters__form { display: grid; gap: var(--space-5); padding: var(--space-4); }
    .filters__header { display: flex; align-items: center; gap: var(--space-3); }
    .filters__title { font-size: var(--text-xl); margin-right: auto; }
    .filters__reset {
        color: var(--color-text-secondary);
        text-decoration: underline;
        text-underline-offset: 3px;
        min-height: var(--hit);
        display: inline-flex;
        align-items: center;
        padding: 0 var(--space-2);
    }
    .filters__status:empty { display: none; }
    .filters__status {
        font-size: var(--text-sm);
        color: var(--color-text-secondary);
    }
    .filters__status[data-state="pending"] { color: var(--color-gold); }
    .filters__group { border: 0; margin: 0; padding: 0; display: grid; gap: var(--space-3); min-width: 0; }
    .filters__group legend { font-weight: 600; padding: 0; margin-bottom: var(--space-3); }
    .price-range { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
    .filters__footer { display: flex; gap: var(--space-3); }
    .filters__apply { flex: 1; }

    /* Phone filter sheet (script-enhanced; without script the form follows the results) */
    .filters--sheet { display: none; }
    .filters--sheet.filters--open {
        display: block;
        position: fixed;
        inset: auto 0 0 0;
        z-index: 50;
        max-height: 88vh;
        overflow-y: auto;
        overscroll-behavior: contain;
        border-radius: 18px 18px 0 0;
        box-shadow: 0 -8px 32px rgb(0 0 0 / 0.5);
    }
    .filters__handle { display: none; }
    .filters--sheet.filters--open .filters__handle {
        display: block;
        height: 24px;
        cursor: grab;
        touch-action: none;
    }
    .filters--sheet.filters--open .filters__handle::before {
        content: "";
        display: block;
        width: 48px;
        height: 4px;
        margin: 10px auto 0;
        border-radius: 2px;
        background: var(--color-control-border);
    }
    .filters--sheet.filters--open .filters__header { touch-action: none; }
    .filters--sheet.filters--open { transition: transform 160ms ease-out; }
    .filters--sheet.filters--dragging { transition: none; }
    @media (prefers-reduced-motion: reduce) { .filters--sheet.filters--open { transition: none; } }
    .filters--sheet .filters__footer {
        position: sticky;
        bottom: 0;
        margin: 0 calc(var(--space-4) * -1) calc(var(--space-4) * -1);
        padding: var(--space-3) var(--space-4) calc(var(--space-3) + env(safe-area-inset-bottom));
        background: var(--color-surface);
        border-top: 1px solid var(--color-divider);
    }
    .sheet-backdrop { position: fixed; inset: 0; z-index: 40; background: rgb(0 0 0 / 0.6); }
    body.sheet-open { overflow: hidden; }

    /* Toolbar */
    /* Featured deals: above the list on the home page. The heading row matches the toolbar's height, so on desktop
       the sidebar still lines up with the first card. */
    .featured { display: grid; grid-template-columns: minmax(0, 1fr); min-width: 0; gap: var(--space-3); margin-bottom: var(--space-6); padding-bottom: var(--space-5); border-bottom: 1px solid var(--color-divider); }
    .featured[hidden] { display: none; }
    .featured__title {
        display: flex;
        align-items: center;
        gap: var(--space-2);
        min-height: var(--hit);
        font-size: var(--text-lg);
    }
    .featured__title .icon { color: var(--color-gold); }
    .toolbar {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        justify-content: space-between;
        gap: var(--space-3);
    }
    .toolbar__count { font-size: var(--text-sm); color: var(--color-text-secondary); }
    .toolbar__count:focus { outline: none; }
    /* Shrinks on the narrowest phones: the sort menu truncates rather than widening the page. */
    .toolbar__controls { display: flex; gap: var(--space-2); min-width: 0; max-width: 100%; }
    .toolbar__controls .select { min-width: 0; }
    .toolbar__controls .select select { min-width: 0; width: 100%; text-overflow: ellipsis; }
    .toolbar__filters { position: relative; padding: 0 var(--space-3); }
    .toolbar__filter-dot {
        position: absolute;
        top: 6px;
        right: 6px;
        width: 8px;
        height: 8px;
        border-radius: 50%;
        background: var(--color-red-mark);
    }

    /* Result cards: as many columns as fit at 500px or wider (3 on a full-width 1920px desktop, 1 on phones). The
       minimum matches the card's own wide-layout breakpoint, so a list of two or more columns never drops its cards
       into the narrow tile. Each card
       lays itself out from its own width, so featured, list and phone cards share one set of rules. */
    .card-list {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(min(100%, 31.25rem), 1fr));
        gap: var(--space-3);
        margin: 0;
        padding: 0;
        list-style: none;
    }
    .card-list__item { display: grid; container-type: inline-size; }
    /* Narrow cards (under 500px: phones and tablets) are a store-style tile: the image across the card, then the
       deal on one line, the tags, the title, the buttons and the pitch (see the tile rules below). */
    .asset-card {
        display: grid;
        grid-template-columns: minmax(0, 1fr);
        grid-template-areas: "image" "pricing" "tags" "head" "actions" "pitch";
        align-content: start;
        gap: var(--space-2) var(--space-3);
        padding: var(--space-3);
        background: var(--color-surface);
        border-radius: var(--radius-card);
        --sparkline-width: 40px;
    }
    /* The store's 3:2 card image, never cropped; the square icon is letterboxed when there's no card image. */
    .asset-card__image {
        grid-area: image;
        align-self: start;
        aspect-ratio: 3 / 2;
        border-radius: 8px;
        overflow: hidden;
        background: var(--color-raised);
    }
    .asset-card__image img { width: 100%; height: 100%; object-fit: cover; }
    .asset-card__image--icon img { object-fit: contain; }
    .asset-card__head { grid-area: head; display: grid; gap: 2px; align-content: start; min-width: 0; }
    /* At most two lines (full title on hover and on the details page) so cards stay compact. */
    .asset-card__title {
        font-size: 0.9375rem;
        line-height: 1.25;
        overflow-wrap: anywhere;
        display: -webkit-box;
        -webkit-box-orient: vertical;
        -webkit-line-clamp: 2;
        line-clamp: 2;
        overflow: hidden;
    }
    .asset-card__title a { text-decoration: none; }
    .asset-card__title a:hover { text-decoration: underline; }
    /* Rating, then category, on one line that truncates; the full category is in the tooltip. */
    .asset-card__meta {
        font-size: var(--text-sm);
        color: var(--color-text-secondary);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .asset-card__rating { color: var(--color-text); font-weight: 600; }
    .asset-card__star { color: var(--color-star); fill: var(--color-star); width: 1.05em; height: 1.05em; margin-right: 2px; vertical-align: -0.2em; }
    .asset-card__rating-count { color: var(--color-text-secondary); }
    /* The price block: discount and old price, then the price and when it changed, stacked at the top right. */
    .asset-card__pricing { grid-area: pricing; align-self: start; display: flex; flex-direction: column; align-items: flex-end; gap: var(--space-1); }
    .asset-card__deal {
        display: flex;
        flex-direction: column;
        align-items: flex-end;
        gap: 2px;
        font-variant-numeric: proportional-nums;
    }
    .asset-card__deal .badge--discount { font-size: var(--text-md); }
    .asset-card__baseline { color: var(--color-text-tertiary); font-size: var(--text-md); white-space: nowrap; }
    .asset-card__was { font-size: var(--text-xs); margin-right: 2px; text-decoration: none; display: inline-block; }
    .asset-card__now { display: flex; flex-direction: column; align-items: flex-end; gap: var(--space-1); }
    /* The price is the largest thing on the card. Proportional figures: Schibsted's tabular ones are very wide. */
    .asset-card__price { font-size: 1.375rem; font-weight: 700; letter-spacing: -0.02em; line-height: 1.1; white-space: nowrap; font-variant-numeric: proportional-nums; }
    .asset-card__since {
        padding: 1px var(--space-2);
        border-radius: 999px;
        background: var(--color-neutral-tint);
        color: var(--color-text-secondary);
        font-size: var(--text-xs);
        font-weight: 600;
        white-space: nowrap;
    }
    /* Narrow cards: a vertical list beside the price, anchored left. */
    .asset-card__tags { grid-area: tags; align-self: start; display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-1); margin: 0; padding: 0; list-style: none; }
    /* History and View deal share their own row, so the price column is only as wide as the prices. */
    /* Narrow cards split the row evenly between the two buttons; wide cards keep them content-sized at the right. */
    .asset-card__actions { grid-area: actions; display: grid; grid-template-columns: repeat(2, minmax(100px, 1fr)); gap: var(--space-2); }
    .asset-card__history { justify-content: center; min-width: 100px; }
    .asset-card__buy { min-width: 100px; padding: 0 var(--space-3); }
    /* A store sale's time left ("Ends in 4 days") is View deal's second line, inside the button's usual height, so
       the card keeps its height at every width and its tags stay one line each. */
    .asset-card__buy:has(.asset-card__buy-ends) {
        display: inline-grid;
        grid-template-columns: auto auto;
        justify-content: center;
        align-content: center;
        gap: 1px var(--space-2);
        padding-block: 3px;
        line-height: 1.15;
    }
    .asset-card__buy-ends { grid-row: 2; grid-column: 1 / -1; justify-self: center; font-size: var(--text-xs); font-weight: 500; opacity: 0.78; }
    /* The narrowest cards: the label keeps its room without the arrow. */
    @container (max-width: 17.5rem) {
        .asset-card__buy .icon { display: none; }
        .asset-card__buy:has(.asset-card__buy-ends) { grid-template-columns: auto; }
    }
    .asset-card__pitch {
        grid-area: pitch;
        padding-top: var(--space-2);
        border-top: 1px solid var(--color-divider);
        font-size: var(--text-sm);
        color: var(--color-text-secondary);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    /* The tile (cards under 500px): the deal on one line (discount, price, old price, and the time at the right),
       and the tags flowing left to right. */
    @container (width < 31.25rem) {
        .asset-card__image { width: 100%; }
        .asset-card__pricing { flex-direction: row; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
        .asset-card__deal, .asset-card__now { display: contents; }
        .asset-card__deal .badge--discount { order: 1; }
        .asset-card__price { order: 2; font-size: 1.5rem; }
        .asset-card__baseline { order: 3; }
        .asset-card__since { order: 4; margin-left: auto; }
        .asset-card__tags { flex-direction: row; flex-wrap: wrap; }
    }
    /* The narrowest tiles (phones under about 350px): the time's short form ("6d ago"), slightly tighter gaps and a
       smaller struck-out price keep the deal on one line even with three-digit prices. The price keeps its size. */
    .asset-card__since-short { display: none; }
    @container (max-width: 20rem) {
        .asset-card__since-long { display: none; }
        .asset-card__since-short { display: inline; }
        .asset-card__pricing { column-gap: 6px; }
        .asset-card__since { padding-inline: 6px; }
        .asset-card__baseline { font-size: var(--text-sm); }
    }
    /* Wider cards (500px and up): image | what it is | the deal, as sketched. The image is a fixed 243×162, pinned
       top-left: the height of a two-line title, two rows of tags and the buttons, so its top lines up with the title
       and its bottom with the buttons on every card with up to two tags (shorter content leaves the space between
       the tags and the buttons). Only a third tag that wraps runs taller. */
    @container (min-width: 31.25rem) {
        .asset-card {
            grid-template-columns: 243px minmax(0, 1fr) auto;
            grid-template-areas:
                "image head pricing"
                "image tags pricing"
                "image actions actions"
                "pitch pitch pitch";
            /* Extra height (from the price block or image) goes to the tags row, so the tags stay right under the
               title and the buttons at the bottom. */
            grid-template-rows: auto 1fr auto;
        }
        .asset-card__image { align-self: start; width: 100%; }
        /* Their own heights (not the rows'), which is what the image is matched to; the buttons sit at the bottom. */
        .asset-card__head, .asset-card__tags { align-self: start; }
        .asset-card__actions { align-self: end; }
        /* The buttons sit at the right, History beside View deal. */
        /* Wide cards: the tags flow left to right under the title, wrapping as needed. */
        .asset-card__tags { flex-direction: row; flex-wrap: wrap; }
        .asset-card__price { font-size: 1.5rem; }
        .asset-card__actions { display: flex; justify-content: flex-end; }
    }
    /* The narrowest wide cards (3 across: 500–560px) leave the title and tags as little as 120px. Tags stay one-line
       pills: they drop their icons and some padding, as View deal drops its arrow on the narrowest tiles, so the
       longest ("Lowest recorded") still fits beside the price. Every card in a row is the same width, so a row's tags
       all change together. */
    @container (31.25rem <= width < 35rem) {
        .asset-card__tags .badge .icon { display: none; }
        .asset-card__tags .badge { padding-inline: 6px; }
    }

    /* Price history: a raised neutral button beside View deal (the card's one gold button), led by the sparkline and
       ending in a chevron, so it reads as clickable at rest. */
    .history-link {
        display: inline-flex;
        align-items: center;
        gap: var(--space-2);
        min-height: var(--hit);
        padding: 0 var(--space-2) 0 var(--space-3);
        background: var(--color-button);
        border-radius: var(--radius-control);
        box-shadow: var(--shadow-button);
        color: var(--color-text);
        font-size: var(--text-md);
        font-weight: 600;
        text-decoration: none;
        white-space: nowrap;
        transition: background-color 0.15s ease-out, box-shadow 0.15s ease-out, transform 0.15s ease-out;
    }
    .history-link:hover { background: var(--color-button-hover); box-shadow: var(--shadow-button-hover); }
    .history-link:active { transform: translateY(1px); }
    .history-link__chevron { width: 16px; height: 16px; color: var(--color-text-secondary); margin-left: -2px; }
    /* On cards the button's fill and edge already read as clickable; the room goes to the label. */
    .asset-card .history-link__chevron { display: none; }
    .asset-card .history-link { padding: 0 var(--space-3); }

    /* The sparkline and its fallback icon share one slot, so every history link starts its label at the same place. */
    .sparkline { width: var(--sparkline-width); height: 20px; flex: none; overflow: visible; }
    .sparkline__line { fill: none; stroke: var(--color-text); stroke-width: 2; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
    .sparkline__end { fill: var(--color-red-mark); }
    /* Before tracking began (single-price assets only): dashed and dimmer, so it doesn't read as a known price. */
    .sparkline__untracked { fill: none; stroke: var(--color-text-tertiary); stroke-width: 1.5; stroke-dasharray: 2 3; vector-effect: non-scaling-stroke; }
    .asset-card__history-icon { color: var(--color-text-secondary); flex: none; width: var(--sparkline-width); height: 20px; }

    .batch-nav {
        display: grid;
        justify-items: center;
        gap: var(--space-2);
        padding: var(--space-5) 0 var(--space-2);
        color: var(--color-text-secondary);
        font-size: var(--text-md);
    }
    .batch-nav--previous { padding: 0 0 var(--space-3); justify-items: start; }
    .batch-nav__end { color: var(--color-text); }

    .empty-state {
        display: grid;
        justify-items: start;
        gap: var(--space-2);
        padding: var(--space-6) var(--space-4);
        background: var(--color-surface);
        border-radius: var(--radius-card);
    }

    /* Footer */
    .site-footer {
        margin-top: auto;
        border-top: 1px solid var(--color-divider);
    }
    .site-footer__inner {
        max-width: var(--page-max);
        margin: 0 auto;
        padding: var(--space-6) var(--gutter) var(--space-5);
        display: grid;
        gap: var(--space-4);
    }
    .site-footer__top { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-5); }
    .site-footer__links { display: flex; flex-wrap: wrap; gap: 0 var(--space-5); }
    .site-footer__links a {
        display: inline-flex;
        align-items: center;
        min-height: var(--hit);
        text-decoration-color: var(--color-text-tertiary);
        text-underline-offset: 3px;
    }
    .site-footer__disclaimers {
        display: grid;
        gap: var(--space-3);
        max-width: 70ch;
        color: var(--color-text-secondary);
        font-size: var(--text-sm);
        line-height: 1.55;
    }
    .site-footer__disclaimers strong { color: var(--color-text); }
    .site-footer__copyright {
        display: flex;
        flex-wrap: wrap;
        justify-content: space-between;
        gap: var(--space-2) var(--space-4);
        padding-top: var(--space-3);
        border-top: 1px solid var(--color-divider);
        color: var(--color-text-secondary);
        font-size: var(--text-sm);
    }

    /* Asset details */
    .details__section-title { font-size: var(--text-lg); }
    .details__crumbs {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: var(--space-1) var(--space-3);
        font-size: var(--text-md);
    }
    .details__back {
        display: inline-flex;
        align-items: center;
        gap: var(--space-2);
        min-height: var(--hit);
        text-decoration: none;
    }
    /* The category path, each part linking to that category's assets; wraps on phones. */
    .crumbs { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-2); margin: 0; padding: 0; list-style: none; color: var(--color-text-secondary); }
    .crumbs li::before { content: "/"; margin-right: var(--space-2); }
    .crumbs a { text-decoration: none; }
    .crumbs a:hover { text-decoration: underline; }

    .details__key-image {
        width: 100%;
        height: auto;
        aspect-ratio: 3 / 2;
        object-fit: cover;
        border-radius: var(--radius-card);
        background: var(--color-raised);
    }
    .details__store-link {
        display: inline-flex;
        align-items: center;
        gap: var(--space-1);
        min-height: var(--hit);
        font-weight: 600;
        text-underline-offset: 3px;
    }

    .details__summary {
        display: grid;
        grid-template-columns: auto minmax(0, 1fr);
        gap: var(--space-3) var(--space-4);
        align-items: start;
    }
    .details__icon { width: 104px; height: 104px; border-radius: var(--radius-card); object-fit: cover; }
    .details__heading { display: grid; gap: var(--space-1); }
    .details__title { font-size: var(--text-xl); overflow-wrap: anywhere; }
    .details__publisher a { text-underline-offset: 3px; }
    .details__rating { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
    .details__pitch { grid-column: 1 / -1; font-size: var(--text-md); line-height: 1.5; color: var(--color-text); max-width: 60ch; }
    .stars { --rating: 0; }
    .stars[data-half-stars="1"] { --rating: 0.5; }
    .stars[data-half-stars="2"] { --rating: 1; }
    .stars[data-half-stars="3"] { --rating: 1.5; }
    .stars[data-half-stars="4"] { --rating: 2; }
    .stars[data-half-stars="5"] { --rating: 2.5; }
    .stars[data-half-stars="6"] { --rating: 3; }
    .stars[data-half-stars="7"] { --rating: 3.5; }
    .stars[data-half-stars="8"] { --rating: 4; }
    .stars[data-half-stars="9"] { --rating: 4.5; }
    .stars[data-half-stars="10"] { --rating: 5; }
    .stars::before {
        content: "★★★★★";
        letter-spacing: 2px;
        font-size: var(--text-lg);
        background: linear-gradient(90deg, var(--color-star) calc(var(--rating) / 5 * 100%), var(--color-star-empty) 0);
        -webkit-background-clip: text;
        background-clip: text;
        color: transparent;
    }
    .details__badges {
        grid-column: 1 / -1;
        display: flex;
        flex-wrap: wrap;
        gap: var(--space-2);
        margin: 0;
        padding: 0;
        list-style: none;
    }
    .status-badge {
        display: inline-flex;
        align-items: center;
        gap: var(--space-1);
        min-height: 28px;
        padding: 0 var(--space-3) 0 var(--space-2);
        border-radius: 999px;
        background: var(--color-neutral-tint);
        color: var(--color-text-secondary);
        font-size: var(--text-sm);
        font-weight: 600;
    }
    .status-badge .icon { width: 16px; height: 16px; }
    .status-badge--pricedrop, .status-badge--officialsale, .status-badge--launchdiscount, .status-badge--flashdeal,
    .status-badge--launchsale, .status-badge--hiddensale {
        background: var(--color-red-tint);
        color: var(--color-red-tint-text);
    }

    .details__purchase {
        display: grid;
        gap: var(--space-2);
        padding: var(--space-4);
        background: var(--color-surface);
        border-radius: var(--radius-card);
        align-content: start;
    }
    .purchase__prices { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); font-variant-numeric: proportional-nums; }
    .badge--large { font-size: var(--text-md); padding: 2px var(--space-3); }
    .purchase__baseline { color: var(--color-text-tertiary); font-size: var(--text-lg); }
    .purchase__price { font-size: 2rem; font-weight: 700; letter-spacing: -0.02em; line-height: 1.1; }
    .purchase__since { color: var(--color-text-secondary); }
    /* The store's sale: its name, then when it ends. Plain secondary text: real times, no urgency styling. */
    .purchase__sale { display: grid; gap: 2px; margin: 0; color: var(--color-text-secondary); font-size: var(--text-md); }
    .purchase__sale-name { color: var(--color-text); font-weight: 600; }

    /* Ratings by stars: a quiet disclosure under the rating line. */
    .rating-breakdown { flex-basis: 100%; color: var(--color-text-secondary); font-size: var(--text-md); }
    .rating-breakdown summary { cursor: pointer; width: fit-content; min-height: 44px; display: flex; align-items: center; text-underline-offset: 3px; }
    .rating-breakdown summary:hover { color: var(--color-text); text-decoration: underline; }
    .rating-breakdown__table { border-collapse: collapse; width: min(100%, 22rem); }
    .rating-breakdown__table th { padding: 2px var(--space-2) 2px 0; font-weight: 400; text-align: left; white-space: nowrap; }
    .rating-breakdown__star { width: 0.9em; height: 0.9em; color: var(--color-star); vertical-align: -0.1em; }
    .rating-breakdown__bar { width: 100%; padding: 2px 0; }
    .rating-breakdown__bar svg { display: block; width: 100%; height: 8px; }
    .rating-breakdown__track { fill: var(--color-star-empty); }
    .rating-breakdown__fill { fill: var(--color-star); }
    .rating-breakdown__count { padding: 2px 0 2px var(--space-2); text-align: right; font-variant-numeric: tabular-nums; }
    /* The price history's verdict (positive news only): today's price is a recorded or recent low. */
    .verdict { display: flex; align-items: center; gap: var(--space-2); color: var(--color-gold); font-weight: 600; }
    .verdict .icon { flex: none; }
    .verdict--large { font-size: var(--text-lg); }
    .purchase__buy { font-size: var(--text-lg); min-height: 52px; }
    .purchase__note { text-align: center; color: var(--color-text-secondary); font-size: var(--text-sm); }

    .history, .viewer, .details__about, .details__package, .details__tracking, .details__keywords, .admin {
        display: grid;
        gap: var(--space-3);
        padding: var(--space-4);
        background: var(--color-surface);
        border-radius: var(--radius-card);
        min-width: 0;
    }
    .history__header { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3) var(--space-4); }
    .history__header .details__section-title { margin-right: auto; }
    .history__range, .history__currency { color: var(--color-text-secondary); font-size: var(--text-md); }
    .segmented { display: inline-flex; border-radius: var(--radius-control); overflow: hidden; box-shadow: inset 0 0 0 1px var(--color-edge-strong); }
    .segmented__item {
        display: inline-flex;
        align-items: center;
        min-height: 40px;
        padding: 0 var(--space-3);
        text-decoration: none;
        font-size: var(--text-md);
        background: var(--color-raised);
        transition: background-color 0.15s ease-out;
    }
    .segmented__item:hover { background: var(--color-raised-hover); }
    .segmented__item + .segmented__item { border-left: 1px solid var(--color-edge); }
    .segmented__item[aria-current="true"], .segmented__item[aria-current="true"]:hover { background: var(--color-text); color: var(--color-canvas); font-weight: 600; }

    .toggle { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--hit); cursor: pointer; position: relative; font-size: var(--text-md); }
    .toggle__input { position: absolute; opacity: 0; width: 1px; height: 1px; }
    .toggle__track {
        width: 44px;
        height: 24px;
        border-radius: 12px;
        background: var(--color-raised);
        border: 1px solid var(--color-control-border);
        position: relative;
        flex: none;
    }
    .toggle__track::after {
        content: "";
        position: absolute;
        top: 3px;
        left: 3px;
        width: 16px;
        height: 16px;
        border-radius: 50%;
        background: var(--color-text);
        transition: translate 0.15s;
    }
    .toggle__input:checked + .toggle__track { background: var(--color-gold); border-color: var(--color-gold); }
    .toggle__input:checked + .toggle__track::after { background: var(--color-on-gold); }
    .toggle__input:checked + .toggle__track::after { translate: 20px 0; }
    .toggle__input:focus-visible + .toggle__track { outline: 2px solid var(--color-focus); outline-offset: 2px; }
    .history:has([data-release-toggle]:not(:checked)) .chart__markers { display: none; }

    .chart { margin: 0; position: relative; }
    /* Admin view: price-change dots and their label */
    .chart__dot { fill: var(--color-surface); stroke: var(--color-text); stroke-width: 2; }
    .chart__dot[data-active] { fill: var(--color-gold); stroke: var(--color-gold); }
    .chart__dots { outline: none; }
    .chart__dots:focus-visible .chart__dot[data-active] { stroke: var(--color-focus); stroke-width: 3; }
    .chart__tip {
        position: absolute;
        z-index: 2;
        translate: -50% calc(-100% - 10px);
        padding: var(--space-1) var(--space-2);
        background: var(--color-raised);
        box-shadow: inset 0 0 0 1px var(--color-edge-strong), 0 4px 12px rgb(0 0 0 / 0.4);
        border-radius: var(--radius-small);
        font-size: var(--text-sm);
        font-variant-numeric: tabular-nums;
        white-space: nowrap;
        pointer-events: none;
    }
    .chart__tip--below { translate: -50% 10px; }
    .chart__svg { width: 100%; height: auto; display: block; overflow: visible; }
    .chart__grid line { stroke: var(--color-divider); stroke-width: 1; stroke-dasharray: 3 4; }
    .chart__grid text { fill: var(--color-text-secondary); font-size: 12px; font-family: var(--font); }
    .chart__y-label { text-anchor: end; dominant-baseline: middle; }
    .chart__x-label { text-anchor: middle; }
    .chart__area { fill: rgb(214 58 51 / 0.2); }
    .chart__line { fill: none; stroke: var(--color-text); stroke-width: 2.5; stroke-linejoin: round; }
    .chart__end { fill: var(--color-red-mark); stroke: var(--color-text); stroke-width: 2; }
    .chart__marker path { fill: var(--color-red-mark); stroke: var(--color-text); stroke-width: 1; }
    .chart__marker text { fill: var(--color-text); font-size: 12px; font-family: var(--font); text-anchor: middle; }
    .chart__marker-guide { stroke: var(--color-text-secondary); stroke-width: 1; stroke-dasharray: 2 3; }

    .history__empty { color: var(--color-text-secondary); font-size: var(--text-sm); }
    /* A readable measure, however wide the panel. */
    .description__body { display: grid; gap: var(--space-2); max-width: 75ch; line-height: 1.6; overflow-wrap: anywhere; }
    .description__body :is(p, ul, ol, h3, h4, blockquote, pre) { margin: 0; }
    .description__body :is(ul, ol) { padding-left: var(--space-5); }
    .description__body h3 { font-size: var(--text-md); }
    .description__body h4 { font-size: var(--text-md); color: var(--color-text-secondary); }
    .description__body pre { overflow-x: auto; white-space: pre-wrap; }
    .description__body blockquote { padding-left: var(--space-3); border-left: 2px solid var(--color-divider); color: var(--color-text-secondary); }
    .description__body a { text-underline-offset: 3px; }

    /* Render pipelines per Unity version, like the store's table: a column per pipeline, ticks where supported. */
    .table-scroll { overflow-x: auto; }
    .pipelines { border-collapse: collapse; width: 100%; max-width: 30rem; font-size: var(--text-md); }
    .pipelines :is(th, td) { padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--color-divider); text-align: center; }
    .pipelines thead th { color: var(--color-text-secondary); font-weight: 600; }
    .pipelines tbody th { text-align: left; font-weight: 400; font-variant-numeric: tabular-nums; white-space: nowrap; }
    .pipelines :is(th, td):first-child { padding-left: 0; }
    .pipelines tbody tr:last-child :is(th, td) { border-bottom: 0; }
    .pipelines__yes { width: 18px; height: 18px; vertical-align: -0.2em; }
    .pipelines__no { color: var(--color-text-tertiary); }
    .viewer__header { display: flex; align-items: baseline; justify-content: space-between; }
    .viewer__count { color: var(--color-text-secondary); }
    .viewer__stage {
        position: relative;
        aspect-ratio: 16 / 9;
        border-radius: var(--radius-control);
        overflow: hidden;
        background: #0A0908;
        display: grid;
        place-items: center;
    }
    /* Everything shown is pinned to the 16:9 stage: a percentage height alone didn't apply, so screenshots taller
       than 16:9 overflowed and had their bottom clipped. Images then fit inside it (letterboxed). */
    .viewer__stage > img, .viewer__stage > iframe { position: absolute; inset: 0; }
    .viewer__stage img, .viewer__stage iframe { width: 100%; height: 100%; object-fit: contain; border: 0; }
    /* Pinned to the 16:9 stage: store thumbnails aren't always 16:9, and a percentage height alone let taller ones
       overflow the stage and clip the play control. */
    .viewer__poster { position: absolute; inset: 0; display: block; }
    /* The poster is the store's small thumbnail (about 120px wide), so it's shown as a dimmed, softened backdrop
       rather than stretched sharp-edged across the stage, with the play control in the middle. */
    .viewer__poster img { object-fit: cover; filter: blur(12px) brightness(0.6); transform: scale(1.1); }
    .viewer__poster .viewer__play { left: 50%; bottom: 50%; transform: translate(-50%, 50%); }
    /* Thumbnail controls sit in the bottom-left corner: store thumbnails for YouTube videos already have YouTube's
       play logo in the middle of the image. */
    .viewer__play, .thumbs__play {
        position: absolute;
        left: var(--space-3);
        bottom: var(--space-3);
        display: inline-flex;
        align-items: center;
        gap: var(--space-2);
        min-height: var(--hit);
        padding: 0 var(--space-4) 0 var(--space-3);
        border-radius: 999px;
        background: rgb(20 18 16 / 0.85);
        border: 2px solid var(--color-text);
        color: var(--color-text);
        font-weight: 600;
    }
    .viewer__play .icon { width: 20px; height: 20px; fill: var(--color-text); }
    .viewer__poster:hover .viewer__play { background: rgb(20 18 16 / 0.95); }
    .viewer__caption { color: var(--color-text-secondary); font-size: var(--text-sm); }

    /* Preview thumbnails: one sideways strip under the preview, at every width. */
    .viewer__strip { position: relative; min-width: 0; }
    .thumbs {
        display: grid;
        grid-auto-flow: column;
        grid-auto-columns: 132px;
        gap: var(--space-2);
        margin: 0;
        padding: 0 0 var(--space-1);
        list-style: none;
        overflow-x: auto;
        overscroll-behavior-x: contain;
        scroll-snap-type: x proximity;
        scrollbar-width: thin;
    }
    .thumbs li { scroll-snap-align: start; }
    .strip-arrow {
        position: absolute;
        top: calc(50% - var(--space-1) / 2);
        translate: 0 -50%;
        z-index: 1;
        display: grid;
        place-items: center;
        width: 36px;
        height: 36px;
        border-radius: 50%;
        border: 0;
        box-shadow: inset 0 0 0 1px var(--color-edge-strong), 0 2px 8px rgb(0 0 0 / 0.5);
        background: rgb(20 18 16 / 0.85);
        color: var(--color-text);
        cursor: pointer;
    }
    .strip-arrow[hidden] { display: none; }
    .strip-arrow:hover { background: var(--color-button); }
    .strip-arrow--prev { left: var(--space-1); }
    .strip-arrow--next { right: var(--space-1); }
    .thumbs__item {
        position: relative;
        display: block;
        aspect-ratio: 16 / 9;
        border-radius: 8px;
        overflow: hidden;
        border: 2px solid transparent;
        background: var(--color-raised);
    }
    .thumbs__item img { width: 100%; height: 100%; object-fit: cover; }
    .thumbs__item[aria-current="true"] { border-color: var(--color-gold); box-shadow: 0 0 0 1px var(--color-gold); }
    .thumbs__play { left: 4px; bottom: 4px; min-height: 0; width: 26px; height: 26px; padding: 0; justify-content: center; border-width: 1px; }
    .thumbs__play .icon { width: 12px; height: 12px; fill: var(--color-text); }

    .facts { display: grid; margin: 0; }
    .facts div { display: flex; justify-content: space-between; gap: var(--space-3); padding: var(--space-2) 0; border-bottom: 1px solid var(--color-divider); }
    .facts div:last-child { border-bottom: 0; }
    .facts dt { color: var(--color-text-secondary); }
    .facts dd { margin: 0; text-align: right; }
    /* A fact with several values (Requires): one per line, right-aligned like the others. */
    .facts__list { display: grid; gap: var(--space-1); margin: 0; padding: 0; list-style: none; }
    .facts__list a { text-underline-offset: 3px; }
    /* Secondary detail under a value (the date of the lowest price), on its own line in the narrow column. */
    .facts__aside { display: block; color: var(--color-text-secondary); font-size: var(--text-sm); }
    .details__package, .details__tracking, .details__keywords { display: grid; gap: var(--space-2); align-content: start; }
    /* Keywords: the store's popular tags, each a search link; raised fill so they read as clickable at rest. */
    .keywords { display: flex; flex-wrap: wrap; gap: var(--space-2); margin: 0; padding: 0; list-style: none; }
    .keyword {
        display: inline-flex;
        align-items: center;
        min-height: 32px;
        padding: 0 var(--space-3);
        border-radius: 999px;
        background: var(--color-raised);
        box-shadow: inset 0 0 0 1px var(--color-edge);
        color: var(--color-text);
        font-size: var(--text-sm);
        text-decoration: none;
        transition: background-color 0.15s ease-out;
    }
    .keyword:hover { background: var(--color-raised-hover); }
    .muted { color: var(--color-text-secondary); font-size: var(--text-sm); }

    .admin { box-shadow: inset 0 0 0 1px var(--color-gold); }
    .admin__form { display: grid; gap: var(--space-2); }
    .admin__form--inline { display: flex; align-items: center; gap: var(--space-3); }

    /* Simple content pages */
    .prose { max-width: 44rem; display: grid; gap: var(--space-4); line-height: 1.55; }
    .prose h1 { font-size: var(--text-2xl); }
    .prose h2 { font-size: var(--text-lg); margin-top: var(--space-3); }
    .prose a { text-underline-offset: 3px; }
}

/* ───────────────────────── Pages ───────────────────────── */
@layer pages {
    .site-main {
        width: 100%;
        max-width: var(--page-max);
        margin: 0 auto;
        padding: var(--space-4) var(--gutter) var(--space-6);
    }
    .site-main:focus { outline: none; }

    .browse__intro { color: var(--color-text-secondary); margin-bottom: var(--space-3); }
    .browse__layout { display: grid; gap: var(--space-4); }
    .browse__results { min-width: 0; }

    /* Phones: featured deals scroll sideways and the header gets compact. */
    @media (max-width: 479px) {
        /* Featured deals scroll sideways in one row, so they don't push the list below the first screen. With more
           than one, each card is a little narrower than the screen so the next one peeks in from the edge. */
        .featured__list {
            grid-template-columns: none;
            grid-auto-flow: column;
            grid-auto-columns: calc(100% - 32px);
            min-width: 0;
            /* Contains the cards' absolutely positioned screen-reader text; otherwise it escapes the scroller's
               clipping and widens the page. */
            position: relative;
            margin-inline: calc(-1 * var(--gutter));
            padding: 0 var(--gutter) var(--space-1);
            scroll-padding-inline: var(--gutter);
            overflow-x: auto;
            overscroll-behavior-x: contain;
            scroll-snap-type: x mandatory;
            scrollbar-width: none;
        }
        .featured__list::-webkit-scrollbar { display: none; }
        .featured__list:has(> li:only-child) { grid-auto-columns: 100%; }
        .featured__list > li { scroll-snap-align: start; display: grid; }
        /* A compact header so deals start higher on the first screen. */
        .site-header__top { gap: var(--space-2); padding-block: var(--space-2); }
        .brand { font-size: var(--text-lg); }
        .brand__mark { width: 28px; height: 28px; }
        .destinations__link { min-height: 52px; padding-block: var(--space-1); font-size: var(--text-sm); white-space: nowrap; }
        .destinations__icon { width: 20px; height: 20px; }
    }

    /* Narrow screens: filters follow the results (no script) or open as a sheet (script). */
    .browse__layout > .filters { order: 2; }

    @media (min-width: 900px) {
        /* Logo over the sidebar; the search is centred over the results (account icon after it, for admins). */
        .site-header__top {
            grid-template-columns: var(--sidebar) minmax(0, 1fr);
            grid-template-areas: "brand search";
            column-gap: var(--column-gap);
        }
        .site-header__top:has(.account) {
            grid-template-columns: var(--sidebar) minmax(0, 1fr) auto;
            grid-template-areas: "brand search account";
        }
        /* Inset on both sides, so it stays clear of the tagline (a little wider than the sidebar) at the narrowest
           widths without leaving the results' centre line. */
        .search { justify-self: center; width: calc(100% - 2 * var(--space-4)); }
        .account { justify-self: end; }
        /* Tabs are centred over the results they switch, on the same axis as the search. */
        .destinations__list {
            display: flex;
            justify-content: center;
            gap: var(--space-2);
            padding: 0 var(--gutter) 0 calc(var(--gutter) + var(--sidebar) + var(--column-gap));
        }
        .destinations__link {
            flex-direction: row;
            gap: var(--space-2);
            min-height: 52px;
            padding: 0 var(--space-5);
            font-size: var(--text-base);
        }
    }
    /* Up to 1440px: tighter tabs, so all five fit over the results column from 900px. */
    @media (min-width: 900px) and (max-width: 1439px) {
        .destinations__list { gap: var(--space-1); }
        .destinations__link { padding: 0 var(--space-3); white-space: nowrap; }
    }
    @media (min-width: 900px) {

        /* Sidebar: the count and sort, then the filters (which stay in view while the results scroll). */
        .browse__layout {
            grid-template-columns: var(--sidebar) minmax(0, 1fr);
            grid-template-rows: auto 1fr;
            column-gap: var(--column-gap);
            row-gap: var(--space-3);
            align-items: start;
        }
        .browse__layout > .toolbar { grid-column: 1; grid-row: 1; }
        .browse__layout > .filters {
            grid-column: 1;
            grid-row: 2;
            order: 0;
            position: sticky;
            top: var(--space-4);
        }
        .browse__results { grid-column: 2; grid-row: 1 / span 2; }
        .toolbar { flex-direction: column; align-items: stretch; gap: var(--space-2); }
        .toolbar__count { padding-inline: var(--space-1); }
        .toolbar__controls .select { flex: 1; }
        .toolbar__filters { display: none; }
    }


    /* Details: one column on phones in the mockup's order; two columns on wide screens. */
    .details { display: flex; flex-direction: column; gap: var(--space-4); scroll-margin-top: var(--space-3); }
    .details__aside, .details__main { display: contents; }
    .details__crumbs { order: 0; }
    .details__summary { order: 1; }
    .details__purchase { order: 2; }
    .history { order: 3; }
    .viewer { order: 4; }
    .details__about { order: 5; }
    .details__package { order: 6; }
    .details__tracking { order: 7; }
    .details__keywords { order: 8; }
    .admin { order: 9; }
    .details__key-image, .details__store-link { display: none; }

    @media (max-width: 599px) {
        .chart__grid text, .chart__marker text { font-size: 22px; }
        /* Too close to the previous release at phone text size: keep the star and its tooltip. */
        .chart__marker--no-phone-label .chart__marker-callout { display: none; }
        .chart__line { stroke-width: 4; }
        .details__icon { width: 88px; height: 88px; }
    }

    @media (min-width: 1000px) {
        /* The asset page keeps the original 80rem width (the lists go wider for three card columns), centred in the
           page, so the chart and previews don't outgrow the screen. */
        .details {
            max-width: 80rem;
            margin-inline: auto;
            display: grid;
            grid-template-columns: var(--sidebar) minmax(0, 1fr);
            grid-template-areas: "crumbs crumbs" "aside main";
            gap: var(--space-4) var(--column-gap);
            align-items: start;
        }
        .details__crumbs { grid-area: crumbs; }
        .details__aside { grid-area: aside; display: grid; gap: var(--space-4); }
        .details__aside > * { order: 0; }
        .details__key-image, .details__store-link { display: block; }
        .details__store-link { display: inline-flex; }
        /* The aside is a facts column on the canvas, not panels. */
        .details__package, .details__tracking, .details__keywords { padding: 0; background: none; }
        .details__main {
            grid-area: main;
            display: grid;
            grid-template-columns: minmax(0, 1fr) 20rem;
            grid-template-areas:
                "summary purchase"
                "history history"
                "viewer viewer"
                "about about"
                "technical technical"
                "compatibility compatibility"
                "admin admin";
            gap: var(--space-4);
            align-items: start;
        }
        .details__summary { grid-area: summary; grid-template-columns: minmax(0, 1fr); }
        .details__icon { display: none; }
        .details__title { font-size: var(--text-2xl); }
        .details__purchase { grid-area: purchase; }
        .history { grid-area: history; }
        .viewer { grid-area: viewer; }
        .details__about { grid-area: about; }
        .details__technical { grid-area: technical; }
        .details__compatibility { grid-area: compatibility; }
        .admin { grid-area: admin; }
    }
}

/* ───────────────────────── Utilities ───────────────────────── */
@layer utilities {
    .visually-hidden {
        position: absolute !important;
        width: 1px !important;
        height: 1px !important;
        padding: 0 !important;
        margin: -1px !important;
        overflow: hidden !important;
        clip: rect(0, 0, 0, 0) !important;
        white-space: nowrap !important;
        border: 0 !important;
    }
    [hidden] { display: none !important; }
}
