/* ==========================================================================
   OAW App Store — stylesheet
   --------------------------------------------------------------------------
   Hand-written on purpose. This page used to pull @tailwindcss/browser@4, a
   compiler that ships ~400 KB of JavaScript and builds the CSS in the visitor's
   browser on every load. Section 4 below provides the handful of utilities the
   markup actually uses, so the compiler is not needed.

   Sections
     1. Reset and base
     2. Tokens
     3. Typography
     4. Layout utilities (replaces the utility classes in the markup)
     5. Header
     6. Hero
     7. Catalogue: filters, search, grid, cards
     8. App detail
     9. Long-form: description, manual, policies
    10. Footer
    11. Motion
   ========================================================================== */

/* ---------- 1. Reset and base -------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

body {
    margin: 0;
    min-height: 100vh;
    /* Ambient wash, painted on the body itself. It was a fixed body::before at
       z-index:-1, which put it behind the body's own opaque background where
       nothing could ever see it. Layered gradients over the base colour need no
       stacking context and no extra element, and background-attachment keeps it
       still while the page scrolls.

       Glass needs this: over a flat colour a blurred panel is indistinguishable
       from a solid one. */
    background:
        radial-gradient(42rem 28rem at 8% -6%, color-mix(in srgb, var(--accent) 20%, transparent), transparent 60%),
        radial-gradient(46rem 30rem at 96% 2%, color-mix(in srgb, var(--brand) 24%, transparent), transparent 62%),
        radial-gradient(38rem 26rem at 50% 104%, color-mix(in srgb, var(--brand) 16%, transparent), transparent 60%),
        var(--bg);
    background-attachment: fixed;
    background-repeat: no-repeat;
    color: var(--ink);
    font-family: 'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    font-size: 1rem;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
}

img, svg { display: block; max-width: 100%; }
img { height: auto; }

a { color: inherit; }

button, input, select, textarea { font: inherit; color: inherit; }

/* One focus treatment for everything. Visible on both grounds. */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
    outline: 3px solid var(--focus);
    outline-offset: 3px;
    border-radius: 0.4rem;
}

.sr-only {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

.skip-link {
    position: absolute; left: 0.75rem; top: -4rem; z-index: 100;
    padding: 0.75rem 1.1rem; border-radius: 0 0 0.75rem 0.75rem;
    background: var(--brand); color: #fff; font-weight: 700; text-decoration: none;
    transition: top 160ms ease;
}
.skip-link:focus { top: 0; }

/* ---------- 2. Tokens ----------------------------------------------------- */

:root {
    --brand:        #003B49;
    --brand-600:    #005468;
    --accent:       #FF6600;

    /* Small orange text needs a darker ink: #FF6600 on white is only 3.0:1,
       which fails body-text contrast. Fills keep the bright brand orange. */
    --accent-ink:   #B34400;

    --bg:           #F5F8F9;
    --surface:      #FFFFFF;
    --surface-2:    #EEF3F5;
    --surface-3:    #E3ECEF;

    --ink:          #0A2730;
    --ink-soft:     #445D67;
    --ink-mute:     #5A737E;
    --on-accent:    #12242B;   /* dark label on the orange fill: 5.3:1 */

    --line:         rgba(0, 59, 73, 0.13);
    --line-strong:  rgba(0, 59, 73, 0.24);
    --focus:        #B34400;

    --shadow-sm:    0 1px 2px rgba(3, 32, 40, 0.06), 0 2px 8px rgba(3, 32, 40, 0.05);
    --shadow-md:    0 6px 16px rgba(3, 32, 40, 0.09), 0 2px 6px rgba(3, 32, 40, 0.06);
    --shadow-lg:    0 18px 42px rgba(3, 32, 40, 0.15);

    --r-sm: 0.55rem;
    --r-md: 0.85rem;
    --r-lg: 1.15rem;
    --r-xl: 1.5rem;

    --header-h: 4.5rem;
    --shell: 78rem;

    --ease: cubic-bezier(0.22, 0.61, 0.36, 1);

    /* Glass. The surface stays fairly opaque on purpose: below about 60% the
       body text on a card starts losing contrast against whatever sits behind
       it, and a panel stops being readable well before it stops looking like
       glass. */
    --glass:        rgba(255, 255, 255, 0.66);
    --glass-strong: rgba(255, 255, 255, 0.78);
    --glass-line:   rgba(255, 255, 255, 0.75);
    --glass-lip:    rgba(255, 255, 255, 0.85);
    --glass-blur:   blur(20px) saturate(170%);
}

html.dark {
    /* Both of these carry white labels (search button, active chip, pagination,
       skip link). The first pass used #0A8FAE, which puts white at 3.78:1 —
       under the 4.5:1 that 14-16px text needs. Hover goes darker, not lighter,
       so the contrast improves on interaction instead of degrading. */
    --brand:        #0B7590;
    --brand-600:    #095F76;
    --accent:       #FF6600;
    --accent-ink:   #FF9152;

    --bg:           #0B1116;
    --surface:      #131C23;
    --surface-2:    #18232B;
    --surface-3:    #1E2C35;

    --ink:          #E9F1F4;
    --ink-soft:     #AEC2CB;
    --ink-mute:     #94AAB4;
    --on-accent:    #12242B;

    --line:         rgba(255, 255, 255, 0.12);
    --line-strong:  rgba(255, 255, 255, 0.22);
    --focus:        #FF9152;

    --shadow-sm:    0 1px 2px rgba(0, 0, 0, 0.5);
    --shadow-md:    0 6px 18px rgba(0, 0, 0, 0.55);
    --shadow-lg:    0 20px 46px rgba(0, 0, 0, 0.6);

    --glass:        rgba(23, 33, 41, 0.62);
    --glass-strong: rgba(23, 33, 41, 0.80);
    --glass-line:   rgba(255, 255, 255, 0.14);
    --glass-lip:    rgba(255, 255, 255, 0.10);
    --glass-blur:   blur(20px) saturate(150%);
}

body { transition: background-color 300ms ease, color 300ms ease; }

/* ---------- 3. Typography ------------------------------------------------- */

h1, h2, h3, h4 { margin: 0; line-height: 1.18; font-weight: 800; letter-spacing: -0.015em; }
p { margin: 0 0 1rem; }
p:last-child { margin-bottom: 0; }

.eyebrow {
    display: block; margin: 0 0 0.5rem;
    color: var(--accent-ink);
    font-size: 0.75rem; font-weight: 800;
    letter-spacing: 0.14em; text-transform: uppercase;
}

.section-title,
.section-title_a {
    margin: 0 0 1.75rem;
    color: var(--ink);
    font-size: clamp(1.5rem, 1.2rem + 1.4vw, 2rem);
    font-weight: 800;
    letter-spacing: -0.02em;
}
.section-title_a { text-align: center; }

.section-intro {
    margin: -1.25rem 0 1.75rem;
    max-width: 44rem;
    color: var(--ink-mute);
}

.brand-text { color: var(--accent); }
.brand-desc { color: var(--ink-soft); }
.app-title  { color: var(--ink); }

/* ---------- 4. Layout utilities ------------------------------------------
   The subset of utility classes the markup uses. Kept deliberately small —
   new work should use the component classes below, not add more of these.
   -------------------------------------------------------------------------- */

.container { width: 100%; margin-inline: auto; padding-inline: 1.25rem; }
.mx-auto   { margin-inline: auto; }

.max-w-2xl { max-width: 42rem; }
.max-w-4xl { max-width: 56rem; }
.max-w-5xl { max-width: 64rem; }
.max-w-6xl { max-width: 72rem; }
.max-w-7xl { max-width: var(--shell); }

.flex        { display: flex; }
.inline-flex { display: inline-flex; }
.grid        { display: grid; }
.hidden      { display: none !important; }

.flex-col        { flex-direction: column; }
.items-center    { align-items: center; }
.items-start     { align-items: flex-start; }
.justify-between { justify-content: space-between; }
.justify-center  { justify-content: center; }

.gap-3 { gap: 0.75rem; }
.gap-4 { gap: 1rem; }
.gap-6 { gap: 1.5rem; }
.space-x-5 > * + * { margin-inline-start: 1.25rem; }

.grid-cols-1 { grid-template-columns: minmax(0, 1fr); }

.text-center { text-align: center; }
.text-sm  { font-size: 0.875rem; }
.text-2xl { font-size: 1.5rem; }
.text-3xl { font-size: clamp(1.6rem, 1.3rem + 1.4vw, 1.95rem); }
.text-4xl { font-size: clamp(1.85rem, 1.4rem + 2vw, 2.35rem); }
.font-semibold { font-weight: 600; }
.font-bold     { font-weight: 700; }
.font-black    { font-weight: 900; }
.leading-relaxed { line-height: 1.75; }

.mb-1  { margin-bottom: 0.25rem; }
.mb-3  { margin-bottom: 0.75rem; }
.mb-4  { margin-bottom: 1rem; }
.mb-5  { margin-bottom: 1.25rem; }
.mb-6  { margin-bottom: 1.5rem; }
.mb-8  { margin-bottom: 2rem; }
.mb-10 { margin-bottom: 2.5rem; }
.mb-16 { margin-bottom: 3.5rem; }
.mb-24 { margin-bottom: 4.5rem; }
.mt-2  { margin-top: 0.5rem; }
.mt-8  { margin-top: 2rem; }
.mt-12 { margin-top: 2.5rem; }

.p-6   { padding: 1.5rem; }
.px-4  { padding-inline: 1.25rem; }
.py-3  { padding-block: 0.75rem; }
.py-6  { padding-block: 1.5rem; }
.py-24 { padding-block: 4rem; }
.pt-28 { padding-top: calc(var(--header-h) + 2rem); }
.pt-32 { padding-top: calc(var(--header-h) + 2.5rem); }
.pb-4  { padding-bottom: 1rem; }
.pb-10 { padding-bottom: 2.5rem; }
.pb-14 { padding-bottom: 3rem; }
.pb-20 { padding-bottom: 3.5rem; }
.pb-24 { padding-bottom: 4rem; }

.w-full { width: 100%; }
.min-h-screen { min-height: 100vh; }
.overflow-x-auto { overflow-x: auto; }

.rounded-md  { border-radius: var(--r-sm); }
.rounded-lg  { border-radius: var(--r-md); }
.rounded-xl  { border-radius: var(--r-lg); }
.rounded-2xl { border-radius: var(--r-lg); }

.shadow-md  { box-shadow: var(--shadow-md); }
.shadow-2xl { box-shadow: var(--shadow-md); }

.fixed { position: fixed; }
.top-0 { top: 0; }
.z-50  { z-index: 50; }
.transition { transition: background-color 200ms ease, color 200ms ease, border-color 200ms ease; }

.text-white { color: #fff; }
.text-\[var\(--accent\)\] { color: var(--accent-ink); }
.bg-\[var\(--primary\)\]  { background: var(--brand); }
.bg-\[\#F3F4F6\]          { background: var(--surface-2); }
html.dark .dark\:bg-\[\#1A202C\] { background: var(--surface-2); }
.hover\:underline:hover { text-decoration: underline; }
.hover\:opacity-90:hover { opacity: 0.9; }
.hover\:bg-\[var\(--accent\)\]:hover { background: var(--accent); color: var(--on-accent); }

.w-6  { width: 1.5rem; }  .h-6  { height: 1.5rem; }
.w-10 { width: 2.5rem; }  .h-10 { height: 2.5rem; }
.w-20 { width: 5rem; }
.w-28 { width: 7rem; }    .h-28 { height: 7rem; }
.h-12 { height: 3rem; }
.h-20 { height: var(--header-h); }

@media (min-width: 640px) {
    .container { padding-inline: 1.5rem; }
    .sm\:gap-6 { gap: 1.5rem; }
    .sm\:px-6  { padding-inline: 1.5rem; }
    .sm\:pt-32 { padding-top: calc(var(--header-h) + 2.5rem); }
    .sm\:pt-40 { padding-top: calc(var(--header-h) + 3rem); }
    .sm\:pb-16 { padding-bottom: 3.5rem; }
    .sm\:pb-20 { padding-bottom: 4rem; }
    .sm\:mb-6  { margin-bottom: 1.5rem; }
    .sm\:w-32  { width: 8rem; }
    .sm\:h-32  { height: 8rem; }
    .sm\:text-4xl { font-size: clamp(1.85rem, 1.4rem + 2vw, 2.35rem); }
    .sm\:text-5xl { font-size: clamp(2.2rem, 1.6rem + 2.6vw, 3rem); }
}

@media (min-width: 768px) {
    .md\:flex-row     { flex-direction: row; }
    .md\:gap-8        { gap: 2rem; }
    .md\:grid-cols-2  { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .md\:w-48         { width: 9rem; }
    .md\:h-48         { height: 9rem; }
    .md\:text-7xl     { font-size: clamp(2.6rem, 1.6rem + 3.4vw, 3.6rem); }
}

@media (min-width: 1024px) {
    .container { padding-inline: 2rem; }
    .lg\:px-8  { padding-inline: 2rem; }
}

/* ---------- 5. Header ----------------------------------------------------- */

.nav-glass {
    background: var(--glass-strong);
    -webkit-backdrop-filter: var(--glass-blur);
    backdrop-filter: var(--glass-blur);
    border-bottom: 1px solid var(--glass-line);
    box-shadow: 0 1px 0 var(--line), inset 0 1px 0 var(--glass-lip);
}

.nav-inner { height: var(--header-h); }

.nav-brand img,
.footer-brand img { height: 2.6rem; width: auto; border-radius: var(--r-sm); }

/* Theme logo swap, done in CSS so neither variant flashes on load. Only one of
   the pair is ever laid out; the other is display:none from the first paint. */
html:not(.dark) .logo-dark,
html.dark .logo-light { display: none; }

.nav-actions { gap: 0.5rem; }

.nav-browse,
.pwa-install,
.icon-button {
    display: inline-flex; align-items: center; justify-content: center;
    gap: 0.4rem;
    min-height: 2.6rem;
    border-radius: var(--r-md);
    font-size: 0.875rem; font-weight: 700;
    text-decoration: none;
    transition: background-color 180ms ease, color 180ms ease, border-color 180ms ease;
}

.nav-browse {
    padding-inline: 0.85rem;
    color: var(--ink-soft);
    border: 1px solid transparent;
}
.nav-browse:hover { background: var(--surface-2); color: var(--ink); }

.pwa-install {
    padding-inline: 0.9rem;
    border: 1px solid var(--accent);
    background: var(--accent);
    color: var(--on-accent);
    cursor: pointer;
}
.pwa-install:hover { filter: brightness(1.06); }

.icon-button {
    width: 2.6rem; min-width: 2.6rem; padding: 0;
    border: 1px solid var(--glass-line);
    background: var(--glass);
    -webkit-backdrop-filter: var(--glass-blur);
    backdrop-filter: var(--glass-blur);
    box-shadow: inset 0 1px 0 var(--glass-lip);
    color: var(--ink);
    cursor: pointer;
}
.icon-button:hover { background: var(--surface-2); border-color: var(--accent); }
.icon-button svg { width: 1.15rem; height: 1.15rem; }

/* ---------- 6. Hero ------------------------------------------------------- */

.store-hero {
    position: relative;
    overflow: hidden;
    padding-block: calc(var(--header-h) + 2.75rem) 3rem;
    border-bottom: 1px solid var(--line);
    background:
        radial-gradient(80rem 30rem at 12% -20%, color-mix(in srgb, var(--accent) 15%, transparent), transparent 62%),
        radial-gradient(60rem 26rem at 92% 0%, color-mix(in srgb, var(--brand) 20%, transparent), transparent 60%),
        var(--surface-2);
}
@supports not (background: color-mix(in srgb, red 50%, blue)) {
    .store-hero { background: var(--surface-2); }
}

.hero-inner { max-width: var(--shell); margin-inline: auto; padding-inline: 1.25rem; }

.hero-title {
    margin: 0 0 0.9rem;
    font-size: clamp(2.1rem, 1.4rem + 3.4vw, 3.5rem);
    font-weight: 900;
    letter-spacing: -0.03em;
    color: var(--ink);
}
.hero-title em { font-style: normal; color: var(--accent-ink); }

.hero-lead {
    max-width: 38rem;
    margin: 0 0 1.75rem;
    color: var(--ink-soft);
    font-size: clamp(1rem, 0.95rem + 0.3vw, 1.15rem);
}

.hero-stats { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1.5rem; }

.hero-stat {
    display: inline-flex; align-items: baseline; gap: 0.4rem;
    padding: 0.45rem 0.8rem;
    border: 1px solid var(--glass-line);
    border-radius: 999px;
    background: var(--glass);
    -webkit-backdrop-filter: var(--glass-blur);
    backdrop-filter: var(--glass-blur);
    box-shadow: inset 0 1px 0 var(--glass-lip);
    font-size: 0.85rem;
    color: var(--ink-soft);
}
.hero-stat b { color: var(--ink); font-weight: 800; }

/* ---------- 7. Catalogue -------------------------------------------------- */

.catalogue-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 1.25rem;
    margin-bottom: 1.5rem;
}
.catalogue-head .section-title { margin: 0.25rem 0 0; text-align: left; }
.catalogue-count { margin: 0.4rem 0 0; color: var(--ink-mute); font-size: 0.9rem; }

.catalogue-search {
    display: flex;
    flex: 1 1 20rem;
    max-width: 26rem;
    overflow: hidden;
    border: 1px solid var(--glass-line);
    border-radius: var(--r-md);
    background: var(--glass-strong);
    -webkit-backdrop-filter: var(--glass-blur);
    backdrop-filter: var(--glass-blur);
    box-shadow: var(--shadow-sm), inset 0 1px 0 var(--glass-lip);
    transition: border-color 180ms ease, box-shadow 180ms ease;
}
.catalogue-search input {
    flex: 1; min-width: 0; width: 100%;
    border: 0; background: transparent; outline: 0;
    padding: 0.8rem 0.95rem;
    color: var(--ink);
}
.catalogue-search input::placeholder { color: var(--ink-mute); }
.catalogue-search button {
    flex: none; border: 0; cursor: pointer;
    padding-inline: 1.1rem;
    background: var(--brand); color: #fff;
    font-weight: 700;
    transition: background-color 180ms ease;
}
.catalogue-search button:hover { background: var(--brand-600); }
.catalogue-search:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 22%, transparent);
}

/* Category chips: wrap on desktop, scroll on a phone. */
.chip-row {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-bottom: 1.75rem;
}

.chip {
    display: inline-flex; align-items: center; gap: 0.4rem;
    padding: 0.5rem 0.85rem;
    border: 1px solid var(--glass-line);
    border-radius: 999px;
    background: var(--glass);
    -webkit-backdrop-filter: var(--glass-blur);
    backdrop-filter: var(--glass-blur);
    box-shadow: inset 0 1px 0 var(--glass-lip);
    color: var(--ink-soft);
    font-size: 0.85rem; font-weight: 700;
    text-decoration: none;
    white-space: nowrap;
    transition: background-color 160ms ease, color 160ms ease, border-color 160ms ease;
}
.chip:hover { border-color: var(--accent); color: var(--ink); }
.chip[aria-current="true"] {
    background: var(--brand); border-color: var(--brand); color: #fff;
}
.chip span {
    font-size: 0.75rem; font-weight: 800;
    opacity: 0.75;
}

/* Auto-fitting grid: 1 up on a phone, 2 on a tablet, 3-4 on a desktop,
   without a breakpoint per step. */
.app-grid {
    display: grid;
    gap: 1.15rem;
    /* 16.5rem is chosen, not guessed: it is the largest track that still fits
       two columns on a 600px-wide phone in landscape and four inside the 78rem
       shell on a desktop. At 19.5rem a 600px viewport got one 560px-wide card
       and a large desktop never went past three. */
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 16.5rem), 1fr));
}

.glass-card,
.glass-section {
    position: relative;
    background: var(--glass);
    -webkit-backdrop-filter: var(--glass-blur);
    backdrop-filter: var(--glass-blur);
    border: 1px solid var(--glass-line);
    border-radius: var(--r-lg);
    /* The inset line is the "lip": a 1px highlight along the top edge. It is
       what reads as thickness — without it a translucent box looks like a hole
       punched in the page rather than a pane sitting on it. */
    box-shadow: var(--shadow-sm), inset 0 1px 0 var(--glass-lip);
}
.glass-section { padding: clamp(1.25rem, 3vw, 1.85rem); }

.app-card {
    position: relative;
    display: flex; flex-direction: column;
    gap: 0.9rem;
    padding: 1.25rem;
    transition: transform 220ms var(--ease), box-shadow 220ms var(--ease), border-color 220ms var(--ease);
}
.app-card:hover {
    transform: translateY(-3px);
    border-color: var(--line-strong);
    box-shadow: var(--shadow-md);
}
.app-card:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 20%, transparent), var(--shadow-md);
}

.app-card-head { display: flex; align-items: center; gap: 0.9rem; }

.app-icon {
    flex: none;
    width: 3.75rem; height: 3.75rem;
    border-radius: 1rem;
    border: 1px solid var(--line);
    background: var(--surface-2);
    object-fit: cover;
    box-shadow: var(--shadow-sm);
}

.app-card-id { min-width: 0; }

.app-card h3 {
    margin: 0;
    font-size: 1.05rem;
    font-weight: 800;
    line-height: 1.3;
    /* Long store names must not push the card wider than its column. */
    overflow-wrap: anywhere;
}

/* The whole card is clickable, but only the title is a real link, so the
   accessible name stays the app name rather than the entire card. */
.app-card-link { text-decoration: none; color: var(--ink); }
.app-card-link::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
.app-card-link:hover { color: var(--accent-ink); }

.app-category {
    display: inline-block;
    margin-top: 0.3rem;
    color: var(--accent-ink);
    font-size: 0.75rem; font-weight: 800;
    letter-spacing: 0.06em; text-transform: uppercase;
}

.app-summary {
    margin: 0;
    color: var(--ink-soft);
    font-size: 0.925rem;
    line-height: 1.6;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.store-badges {
    display: flex; flex-wrap: wrap; align-items: center;
    gap: 0.5rem;
    margin-top: auto;
    padding-top: 0.25rem;
}

/* Badges sit above the card's full-card link overlay so they stay clickable. */
.store-badge {
    position: relative; z-index: 1;
    display: inline-flex; overflow: hidden;
    border-radius: var(--r-sm);
    transition: transform 180ms var(--ease), box-shadow 180ms var(--ease);
}
.store-badge:hover, .store-badge:focus-visible {
    transform: translateY(-2px);
    box-shadow: var(--shadow-md);
}
.store-badge img { height: 2.35rem; width: auto; }

/* Compact store marks (catalogue card).
   Sized so six fit one row inside the narrowest card the grid produces
   (~271px at a 600px viewport): 6 x 2rem + 5 x 0.4rem gap is about 224px. The
   track itself shrinks with the card via clamp, so nothing wraps or clips as
   more stores are added. */
.store-marks {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    margin: auto 0 0;
    padding: 0.25rem 0 0;
    list-style: none;
}
.store-marks li { display: flex; }

.store-mark {
    /* Above the card's full-card link overlay, so a store link still wins. */
    position: relative;
    z-index: 1;
    display: grid;
    place-items: center;
    width: clamp(1.75rem, 1.4rem + 1.1vw, 2.1rem);
    aspect-ratio: 1;
    overflow: hidden;
    border: 1px solid var(--line);
    border-radius: 30%;
    background: #111;
    box-shadow: var(--shadow-sm);
    transition: transform 180ms var(--ease), box-shadow 180ms var(--ease);
}
.store-mark img { width: 100%; height: 100%; object-fit: cover; }
.store-mark:hover, .store-mark:focus-visible {
    transform: translateY(-2px);
    box-shadow: var(--shadow-md);
}

/* Shown when a platform has no artwork on disk yet — a new store stays usable
   and merely looks unfinished, instead of rendering a broken image. */
.store-mark-fallback {
    color: #fff;
    font-size: 0.8rem;
    font-weight: 800;
    line-height: 1;
}

.catalogue-empty {
    grid-column: 1 / -1;
    padding: clamp(2rem, 6vw, 3.5rem);
    border: 1px dashed var(--line-strong);
    border-radius: var(--r-lg);
    text-align: center;
    color: var(--ink-soft);
}
.catalogue-empty h3 { margin-bottom: 0.5rem; color: var(--ink); font-size: 1.25rem; }

.catalogue-pagination {
    display: flex; align-items: center; justify-content: center;
    gap: 0.75rem;
    margin-top: 2.5rem;
    color: var(--ink-mute);
    font-size: 0.9rem;
}
.catalogue-pagination a,
.catalogue-empty a {
    display: inline-flex; align-items: center;
    min-height: 2.75rem;
    padding: 0.65rem 1.1rem;
    border-radius: var(--r-md);
    background: var(--brand); color: #fff;
    font-weight: 700; text-decoration: none;
    transition: background-color 180ms ease;
}
.catalogue-pagination a:hover,
.catalogue-empty a:hover { background: var(--brand-600); }
.catalogue-empty a { margin-top: 1rem; }

/* ---------- 8. App detail -------------------------------------------------- */

.breadcrumb {
    display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem;
    margin-bottom: 1.1rem;
    color: var(--ink-mute);
    font-size: 0.85rem; font-weight: 600;
}
.breadcrumb a { color: var(--ink-soft); text-decoration: none; }
.breadcrumb a:hover { color: var(--accent-ink); text-decoration: underline; }
.breadcrumb span[aria-hidden] { opacity: 0.5; }
.breadcrumb [aria-current] { color: var(--ink); }

.app-detail-lead {
    margin: 0.65rem 0 0;
    max-width: 44rem;
    color: var(--ink-soft);
    font-size: 1.02rem;
    line-height: 1.65;
}

.app-detail-hero {
    display: flex;
    align-items: flex-start;
    gap: clamp(1.25rem, 4vw, 2.25rem);
    padding: clamp(1.35rem, 4vw, 2.25rem);
}

.app-detail-icon {
    flex: none;
    width: clamp(5rem, 16vw, 8.5rem);
    height: clamp(5rem, 16vw, 8.5rem);
    border-radius: 1.35rem;
    border: 1px solid var(--line);
    background: var(--surface-2);
    object-fit: cover;
    box-shadow: var(--shadow-md);
}

.app-detail-summary { min-width: 0; flex: 1; }
.app-detail-summary > .app-category { margin: 0 0 0.4rem; }
.app-detail-summary h1 {
    margin: 0 0 0.35rem;
    color: var(--ink);
    font-size: clamp(1.5rem, 1.1rem + 2vw, 2.35rem);
    font-weight: 900;
    letter-spacing: -0.025em;
    overflow-wrap: anywhere;
}

.app-detail-meta {
    display: flex; flex-wrap: wrap; gap: 0.5rem;
    margin: 1rem 0 1.25rem;
    color: var(--ink-soft);
    font-size: 0.85rem;
}
.app-detail-meta > * {
    display: inline-flex; align-items: center; gap: 0.35rem;
    padding: 0.4rem 0.75rem;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: var(--surface-2);
}
.app-detail-meta b { color: var(--ink); font-weight: 800; }

.screenshot-rail {
    display: flex;
    gap: 1rem;
    overflow-x: auto;
    padding-bottom: 1rem;
    scroll-snap-type: x mandatory;
    scrollbar-color: var(--line-strong) transparent;
    /* Bleed to the viewport edge on a phone so the rail reads as scrollable. */
    scroll-padding-inline: 1.25rem;
}
.screenshot {
    flex: 0 0 auto;
    width: min(72vw, 15rem);
    max-height: 32rem;
    /* contain, not cover: a cropped app screenshot is worse than a letterboxed
       one, and these arrive at whatever aspect the publisher uploaded. */
    object-fit: contain;
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    background: var(--surface-2);
    box-shadow: var(--shadow-sm);
    scroll-snap-align: start;
}

.info-grid { display: grid; gap: 1.15rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); }

.info-list { margin: 0; display: grid; gap: 0.7rem; }
.info-list > div { display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.info-list dt { color: var(--ink-mute); font-size: 0.85rem; font-weight: 700; }
.info-list dd { margin: 0; color: var(--ink); font-weight: 600; text-align: right; overflow-wrap: anywhere; }
/* WCAG 2.2 SC 2.5.8 wants a 24px target. These links sat at 19px tall, so they
   get vertical padding rather than a larger font. */
.info-list dd a,
.footer-links a { display: inline-block; min-height: 24px; padding-block: 0.15rem; }

/* ---------- 9. Long-form content ------------------------------------------ */

.app-description,
.manual-content,
.policy-document {
    color: var(--ink);
    line-height: 1.8;
}
.app-description > :first-child,
.manual-content > :first-child,
.policy-document > :first-child { margin-top: 0; }

.app-description h2, .app-description h3, .app-description h4,
.manual-content h2, .manual-content h3, .manual-content h4,
.policy-document h2 {
    color: var(--ink);
    font-weight: 800;
    line-height: 1.3;
    margin: 1.9rem 0 0.75rem;
}
.app-description h2, .manual-content h2, .policy-document h2 { font-size: 1.35rem; }
.app-description h3, .manual-content h3 { font-size: 1.15rem; }

.app-description ul, .app-description ol,
.manual-content ul, .manual-content ol,
.policy-document ul { margin: 0 0 1rem; padding-left: 1.4rem; }
.app-description ul, .manual-content ul, .policy-document ul { list-style: disc; }
.app-description ol, .manual-content ol { list-style: decimal; }

.app-description a, .manual-content a,
.policy-document a, .policy-back a {
    color: var(--accent-ink); font-weight: 700; text-decoration: underline;
}

.manual-content blockquote {
    margin: 0 0 1rem;
    border-left: 4px solid var(--accent);
    color: var(--ink-soft);
    padding-left: 1rem;
}
.manual-content code, .manual-content pre {
    border-radius: 0.4rem;
    background: var(--surface-3);
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.9em;
}
.manual-content code { padding: 0.1rem 0.35rem; }
.manual-content pre { overflow-x: auto; padding: 0.9rem 1rem; white-space: pre-wrap; }

/* Policy pages */
.policy-page { color: var(--ink); }

.policy-hero {
    border: 1px solid var(--line);
    border-radius: var(--r-xl);
    background:
        radial-gradient(50rem 20rem at 8% -30%, color-mix(in srgb, var(--accent) 14%, transparent), transparent 60%),
        var(--surface-2);
    padding: clamp(1.4rem, 5vw, 2.75rem);
}
@supports not (background: color-mix(in srgb, red 50%, blue)) {
    .policy-hero { background: var(--surface-2); }
}
.policy-hero h1 {
    margin: 0.35rem 0 0.8rem;
    color: var(--ink);
    font-size: clamp(1.75rem, 1.2rem + 2.6vw, 2.9rem);
    font-weight: 900;
    letter-spacing: -0.025em;
}
.policy-hero > p:not(.eyebrow) { color: var(--ink-soft); max-width: 44rem; font-size: 1.02rem; }

.policy-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem; margin-top: 1.25rem; }
.policy-meta span, .policy-meta a {
    border-radius: 999px;
    font-size: 0.82rem; font-weight: 700;
    padding: 0.45rem 0.85rem;
}
.policy-meta span { background: var(--surface-3); color: var(--ink-soft); }
.policy-meta a { background: var(--brand); color: #fff; text-decoration: none; }
.policy-meta a:hover { background: var(--brand-600); }

.policy-tabs { display: flex; gap: 0.5rem; margin: 1.5rem 0; overflow-x: auto; padding-bottom: 0.35rem; }
.policy-tabs a {
    border: 1px solid var(--line-strong); border-radius: 999px;
    color: var(--ink-soft); font-size: 0.85rem; font-weight: 700;
    padding: 0.55rem 0.9rem; text-decoration: none; white-space: nowrap;
    transition: background-color 160ms ease, color 160ms ease, border-color 160ms ease;
}
.policy-tabs a.is-active, .policy-tabs a:hover {
    background: var(--brand); border-color: var(--brand); color: #fff;
}

.policy-document {
    background: var(--glass);
    -webkit-backdrop-filter: var(--glass-blur);
    backdrop-filter: var(--glass-blur);
    border: 1px solid var(--glass-line);
    border-radius: var(--r-xl);
    box-shadow: inset 0 1px 0 var(--glass-lip);
    padding: clamp(1.4rem, 4vw, 2.5rem);
}

.policy-link-grid,
.disclosure-grid {
    display: grid; gap: 1rem;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
}

.policy-link-card {
    display: flex; flex-direction: column; gap: 0.45rem;
    padding: 1.2rem;
    border: 1px solid var(--glass-line);
    border-radius: var(--r-lg);
    background: var(--glass);
    -webkit-backdrop-filter: var(--glass-blur);
    backdrop-filter: var(--glass-blur);
    box-shadow: inset 0 1px 0 var(--glass-lip);
    color: var(--ink);
    text-decoration: none;
    transition: transform 180ms var(--ease), border-color 180ms var(--ease), box-shadow 180ms var(--ease);
}
.policy-link-card:hover, .policy-link-card:focus-visible {
    transform: translateY(-3px);
    border-color: var(--accent);
    box-shadow: var(--shadow-md);
}
.policy-link-card span {
    color: var(--accent-ink);
    font-size: 0.72rem; font-weight: 800;
    letter-spacing: 0.1em; text-transform: uppercase;
}
.policy-link-card strong { line-height: 1.35; }
.policy-link-card i { color: var(--ink-mute); font-size: 0.85rem; font-style: normal; margin-top: auto; }

.policy-callout, .policy-status {
    border-left: 4px solid var(--accent);
    border-radius: var(--r-md);
    background: var(--surface-2);
    margin: 1.25rem 0;
    padding: 1rem 1.1rem;
}
.policy-callout ul { margin: 0.45rem 0 0; }
.policy-status { display: grid; gap: 0.2rem; }
.policy-status span, .disclosure-grid span {
    color: var(--ink-mute);
    font-size: 0.75rem; font-weight: 800;
    letter-spacing: 0.08em; text-transform: uppercase;
}
.policy-status.is-yes { border-left-color: #B54708; }
.policy-status.is-no  { border-left-color: #15803D; }

.disclosure-grid section { border: 1px solid var(--line); border-radius: var(--r-md); padding: 1rem; }
.disclosure-grid strong { display: block; line-height: 1.35; margin: 0.35rem 0; }
.disclosure-grid p { color: var(--ink-soft); font-size: 0.9rem; line-height: 1.6; margin: 0; }

.policy-contact {
    border-top: 1px solid var(--line);
    color: var(--ink-mute);
    font-size: 0.92rem;
    margin-top: 2rem; padding-top: 1.2rem;
}
.policy-back { margin: 1.5rem 0 0; }

/* ---------- 10. Footer ----------------------------------------------------- */

.site-footer {
    margin-top: 4rem;
    border-top: 1px solid var(--glass-line);
    background: var(--glass-strong);
    -webkit-backdrop-filter: var(--glass-blur);
    backdrop-filter: var(--glass-blur);
    color: var(--ink-soft);
}
.footer-inner {
    max-width: var(--shell);
    margin-inline: auto;
    padding: 3rem 1.25rem 2rem;
    display: grid;
    gap: 2rem;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
}
.footer-brand img { margin-bottom: 0.9rem; }
.footer-brand p { max-width: 24rem; font-size: 0.925rem; }

.site-footer h2 {
    margin: 0 0 0.85rem;
    color: var(--ink);
    font-size: 0.75rem; font-weight: 800;
    letter-spacing: 0.14em; text-transform: uppercase;
}
.footer-links { display: grid; gap: 0.55rem; list-style: none; margin: 0; padding: 0; }
.footer-links a { color: var(--ink-soft); font-size: 0.925rem; text-decoration: none; }
.footer-links a:hover { color: var(--accent-ink); text-decoration: underline; }

.footer-bottom {
    max-width: var(--shell);
    margin-inline: auto;
    padding: 1.25rem 1.25rem 2rem;
    border-top: 1px solid var(--line);
    display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
    gap: 0.75rem;
    font-size: 0.875rem;
}

/* ---------- 11. Motion ----------------------------------------------------- */

html { scroll-behavior: smooth; }

@keyframes fadeUp {
    from { opacity: 0; transform: translateY(14px); }
    to   { opacity: 1; transform: none; }
}
.fade-up { animation: fadeUp 620ms var(--ease) both; }

/* Respect the OS setting: no transforms, no smooth scroll, no fades. */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
        scroll-behavior: auto !important;
    }
    .app-card:hover, .store-badge:hover, .policy-link-card:hover { transform: none; }
}

/* ---------- 12. Narrow viewports ------------------------------------------ */

@media (max-width: 40rem) {
    :root { --header-h: 4rem; }

    .nav-brand img { height: 2.25rem; }
    .nav-browse { display: none; }
    .pwa-install { min-height: 2.4rem; padding-inline: 0.7rem; font-size: 0.8rem; }
    .icon-button { width: 2.4rem; min-width: 2.4rem; min-height: 2.4rem; }

    .catalogue-head { align-items: stretch; }
    .catalogue-search { max-width: none; }
    .catalogue-search input, .catalogue-search button { min-height: 2.9rem; }

    /* Chips scroll rather than wrapping into four stacked rows. */
    .chip-row {
        flex-wrap: nowrap;
        overflow-x: auto;
        margin-inline: -1.25rem;
        padding-inline: 1.25rem;
        padding-bottom: 0.5rem;
        scroll-snap-type: x proximity;
    }
    .chip { scroll-snap-align: start; }

    .app-card { padding: 1.1rem; }
    .app-icon { width: 3.25rem; height: 3.25rem; border-radius: 0.85rem; }
    .store-badge img { height: 2.15rem; }
    .store-mark { width: 1.9rem; }

    .app-detail-hero { flex-direction: column; align-items: center; text-align: center; }
    .app-detail-meta, .app-detail-hero .store-badges { justify-content: center; }
    .info-list > div { justify-content: flex-start; flex-direction: column; gap: 0.15rem; }
    .info-list dd { text-align: left; }

    .screenshot { width: 78vw; }

    .footer-bottom { justify-content: flex-start; }
}

/* ---------- 13. Glass fallbacks and cost control ---------------------------- */

/* Engines without backdrop-filter get an opaque surface rather than a
   washed-out translucent one that would be unreadable over the ambient wash. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .glass-card, .glass-section, .nav-glass, .site-footer,
    .catalogue-search, .chip, .icon-button, .hero-stat,
    .policy-document, .policy-link-card {
        background: var(--surface);
    }
}

/* color-mix drives the ambient wash and several accents; without it, fall back
   to the flat page colour. */
@supports not (background: color-mix(in srgb, red 50%, blue)) {
    body { background: var(--bg); }
    .store-hero, .policy-hero { background: var(--surface-2); }
    .app-card:focus-within, .catalogue-search:focus-within { box-shadow: var(--shadow-md); }
}

/* A dozen blurred cards is real GPU work. Phones get the panel styling without
   the per-card blur; the nav and footer keep theirs because there is only one
   of each and they sit over moving content. */
@media (max-width: 40rem) {
    .glass-card, .chip, .hero-stat, .policy-link-card {
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
        background: var(--glass-strong);
    }
}
