﻿/* ============================================================
   POCKETMAGS DESIGN SYSTEM
   ------------------------------------------------------------
   Tokens, base styles, utilities, and component library.
   Structure mirrors the Pocketmags style-guide format so this
   file is a direct, portable handover. Values reflect the
   refreshed concept palette (orange / purple / cream).
   ============================================================ */


/* ============================================================
   1. DESIGN TOKENS
   ============================================================ */
:root {
    /* ---- Brand: orange (primary) ---- */
    --brand-50: #FEF4F1;
    --brand-100: #FDE5DF;
    --brand-200: #F6B6A5;
    --brand-300: #F19380;
    --brand-400: #EE6A4A;
    --brand-500: #e84a0e; /* primary brand */
    --brand-600: #e84a0e;
    --brand-700: #C52E14;
    --brand-800: #A22410;
    --brand-900: #6E180A;
    /* ---- Pocketmags Plus+: true brand colours
     Plus+ uses a navy-slate dark (not pure black) paired with a
     warm off-white for text. The warm/cool mix softens contrast
     vs. pure #000/#FFF. Orange accent stays unchanged.

     --plus-ink    : background on dark Plus+ surfaces
     --plus-paper  : body text / warm off-white on --plus-ink
     --plus-accent : orange highlight (buttons, active link, badge) */
    --plus-ink: #0F1425;
    --plus-paper: #F2EEE2;
    --plus-accent: #FC5C17;
    /* ---- Plus: purple (secondary accent, used by Puzzles) ---- */
    --plus-50: #F3EEFE;
    --plus-100: #EAE3FB;
    --plus-200: #CDBDF3;
    --plus-300: #A586E0;
    --plus-400: #6B50B9;
    --plus-500: #3D2A78; /* Plus+ brand */
    --plus-600: #352469;
    --plus-700: #2C1F5A;
    --plus-800: #1F1640;
    --plus-900: #100B22;
    /* ---- Teal: secondary accent ---- */
    --teal-50: #E8F5F3;
    --teal-100: #C4E6DF;
    --teal-200: #94D0C4;
    --teal-300: #5CB5A4;
    --teal-400: #349982;
    --teal-500: #1A7D66;
    --teal-600: #136554;
    --teal-700: #0D4E41;
    --teal-800: #07362D;
    --teal-900: #03221C;
    /* ---- Slate: neutrals / text / light-mode surfaces ---- */
    --slate-50: #FAF6EC; /* cream */
    --slate-100: #F4F3EF; /* tint */
    --slate-200: #E8E4DA; /* rule */
    --slate-300: #D6D1C5;
    --slate-400: #B4AEA5;
    --slate-500: #86807A;
    --slate-600: #6B655F;
    --slate-700: #4A4640;
    --slate-800: #2E2B27;
    --slate-900: #1F1D1A; /* ink */
    /* ---- Zinc: dark-mode surfaces ---- */
    --zinc-50: #F4F4F5;
    --zinc-100: #E4E4E7;
    --zinc-200: #D4D4D8;
    --zinc-300: #A1A1AA;
    --zinc-400: #71717A;
    --zinc-500: #52525B;
    --zinc-600: #3F3F46;
    --zinc-700: #27272A;
    --zinc-800: #18181B;
    --zinc-900: #0B0B0D;
    /* ---- Status ---- */
    --color-success: #2E8B57;
    --color-warning: #E8A53D;
    --color-error: #C43A2B;
    --color-info: #2E6DB4;
    /* ---- Semantic ---- */
    --color-bg: #FFFFFF;
    --color-bg-cream: var(--slate-50);
    --color-bg-muted: var(--slate-100);
    --color-surface: #FFFFFF;
    --color-border: var(--slate-200);
    --color-border-soft: #F0ECE2;
    --color-text: var(--slate-900);
    --color-text-soft: var(--slate-700);
    --color-text-muted: var(--slate-500);
    --color-text-faint: var(--slate-400);
    /* ---- Spacing scale ---- */
    --sp-1: 4px;
    --sp-2: 8px;
    --sp-3: 12px;
    --sp-4: 16px;
    --sp-5: 20px;
    --sp-6: 24px;
    --sp-7: 32px;
    --sp-8: 40px;
    --sp-9: 56px;
    --sp-10: 72px;
    /* ---- Font sizes ---- */
    --fs-xs: 13px;
    --fs-sm: 14px;
    --fs-body: 16px;
    --fs-lg: 17px;
    --fs-xl: 20px;
    --fs-xxl: 28px;
    --fs-xxxl: 40px;
    /* ---- Font weights ---- */
    --fw-300: 300;
    --fw-400: 400;
    --fw-500: 500;
    --fw-600: 600;
    --fw-700: 700;
    --fw-800: 800;
    --fw-900: 900;
    /* ---- Radius ---- */
    --radius-sm: 6px;
    --radius-md: 10px;
    --radius-lg: 14px;
    --radius-xl: 22px;
    --radius-full: 999px;
    /* ---- Shadows ---- */
    --shadow-sm: 0 1px 2px rgba(31,29,26,.04);
    --shadow-md: 0 2px 4px rgba(31,29,26,.04), 0 6px 18px rgba(31,29,26,.05);
    --shadow-lg: 0 2px 6px rgba(31,29,26,.05), 0 12px 28px rgba(31,29,26,.08);
    --shadow-2xl: 0 6px 14px rgba(40,15,18,.10), 0 24px 48px rgba(40,15,18,.12);
    /* ---- Cover lift - multi-layer stack inspired by Apple Books /
     News+ covers. Three shadows at graduated offsets/blurs so the
     cover reads as a physical object floating above the surface.
     Cool navy tint (not pure black) so it harmonises with dark
     Plus+ surfaces and still works on light. */
    --cover-shadow-sm: 0 1px 2px rgba(15,20,37,.08), 0 4px 10px rgba(15,20,37,.10), 0 12px 24px rgba(15,20,37,.10);
    --cover-shadow: 0 2px 4px rgba(15,20,37,.10), 0 10px 20px rgba(15,20,37,.14), 0 28px 56px rgba(15,20,37,.16);
    --cover-shadow-lg: 0 4px 8px rgba(15,20,37,.12), 0 16px 32px rgba(15,20,37,.16), 0 40px 72px rgba(15,20,37,.20);
    --cover-shadow-hover: 0 4px 8px rgba(15,20,37,.14), 0 18px 36px rgba(15,20,37,.18), 0 48px 84px rgba(15,20,37,.22);
    /* ---- Typography ---- */
    --font-body: "Hanken Grotesk", system-ui, -apple-system, sans-serif;
    --font-display: "Hanken Grotesk", system-ui, -apple-system, sans-serif;
    --font-serif: "Fraunces", Georgia, serif;
    --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Consolas, monospace;
    /* ---- Layout ---- */
    --page-max: 1280px;
    --page-pad: 32px;
    /* ---- Motion ---- */
    --ease-out: cubic-bezier(.2,.7,.2,1);
    --ease-spring: cubic-bezier(.34,1.56,.64,1);
    /* ============================================================
     LEGACY ALIASES - keep existing pages rendering during the
     migration. Removed once every page consumes the scale tokens.
     ============================================================ */
    --brand: var(--brand-500);
    --brand-deep: var(--brand-700);
    --brand-soft: var(--brand-100);
    --brand-tint: var(--brand-50);
    --brand-line: var(--brand-200);
    --plus: var(--plus-500);
    --plus-deep: var(--plus-700);
    --plus-soft: var(--plus-100);
    --cta: var(--brand-500);
    --cta-deep: var(--brand-700);
    --ink: var(--slate-900);
    --ink-soft: var(--slate-700);
    --ink-mute: var(--slate-500);
    --ink-faint: var(--slate-400);
    --rule: var(--slate-200);
    --rule-soft: var(--color-border-soft);
    --cream: var(--slate-50);
    --bg: var(--color-bg);
    --bg-card: var(--color-surface);
    --bg-tint: var(--slate-100);
    --shadow: var(--shadow-md);
    --shadow-cover: var(--shadow-2xl);
    --radius: var(--radius-lg);
    --radius-xs: var(--radius-sm);
    --font: var(--font-body);
    --max: var(--page-max);
    --pad: var(--page-pad);
}


/* ============================================================
   2. BASE / RESET
   ============================================================ */
*,
*::before,
*::after {
    box-sizing: border-box;
}

* {
    margin: 0;
    padding: 0;
}

html {
    scroll-behavior: smooth;
}

/* ── Custom scrollbars ─────────────────────────────────────────
   Slim, brand-consistent scrollbars on all browsers.
   Webkit (Chrome, Edge, Safari): ::-webkit-scrollbar pseudo-elements.
   Firefox: scrollbar-width / scrollbar-color properties.
   The dark-surface override covers Plus+ and selling pages. */
:root {
    scrollbar-width: thin;
    scrollbar-color: var(--color-border-strong, #b0b8c4) transparent;
}

::-webkit-scrollbar {
    width: 5px;
    height: 5px;
}

::-webkit-scrollbar-track {
    background: transparent;
}

::-webkit-scrollbar-thumb {
    background: var(--color-border-strong, #b0b8c4);
    border-radius: 99px;
}

    ::-webkit-scrollbar-thumb:hover {
        background: var(--color-text-muted, #888);
    }

/* Dark surfaces (Plus+, selling pages) */
.selling-body ::-webkit-scrollbar-thumb,
.plus-app ::-webkit-scrollbar-thumb,
.nav--on-dark ::-webkit-scrollbar-thumb,
.sell-cats-panel ::-webkit-scrollbar-thumb {
    background: rgba(242, 238, 226, 0.22);
}

    .selling-body ::-webkit-scrollbar-thumb:hover,
    .plus-app ::-webkit-scrollbar-thumb:hover,
    .nav--on-dark ::-webkit-scrollbar-thumb:hover,
    .sell-cats-panel ::-webkit-scrollbar-thumb:hover {
        background: rgba(242, 238, 226, 0.45);
    }

/* ── Consistent native select base ────────────────────────────
   Remove OS chrome from all <select> elements; individual
   components (sort-select, field__select etc.) layer on top. */
select {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
}

body {
    background: var(--color-bg);
    color: var(--color-text);
    font-family: var(--font-body);
    font-size: var(--fs-body);
    line-height: 1.55;
    min-height: 100vh;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

img {
    max-width: 100%;
    display: block;
    /* Anchor cropped images to the top - magazine covers put the
     masthead up there, so when object-fit: cover has to trim, we
     keep the top and lose the bottom. */
    object-position: top center;
    /* Subtle 10% white inset stroke to lift every cover away from
     whatever surface sits behind it. Inherits the container's
     border-radius via the overflow: hidden clip, so it reads as
     a rounded hairline on the visible edge. */
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1);
}

a {
    color: inherit;
    text-decoration: none;
}

button {
    font: inherit;
    color: inherit;
    cursor: pointer;
    background: none;
    border: 0;
}

input {
    font: inherit;
    color: inherit;
}


/* ============================================================
   3. TYPOGRAPHY
   ============================================================ */
h1 {
    font-family: var(--font-display);
    font-size: var(--fs-xxxl);
    font-weight: var(--fw-800);
    letter-spacing: -0.03em;
    line-height: 1.05;
}

h2 {
    font-family: var(--font-display);
    font-size: var(--fs-xxl);
    font-weight: var(--fw-700);
    letter-spacing: -0.025em;
    line-height: 1.1;
}

h3 {
    font-family: var(--font-display);
    font-size: var(--fs-xl);
    font-weight: var(--fw-700);
    letter-spacing: -0.02em;
    line-height: 1.15;
}

h4 {
    font-family: var(--font-display);
    font-size: var(--fs-lg);
    font-weight: var(--fw-700);
    letter-spacing: -0.015em;
    line-height: 1.2;
}

h5 {
    font-size: var(--fs-body);
    font-weight: var(--fw-700);
    letter-spacing: -0.005em;
    line-height: 1.3;
}

h6 {
    font-size: var(--fs-sm);
    font-weight: var(--fw-700);
    letter-spacing: 0.06em;
    line-height: 1.3;
    text-transform: uppercase;
}

@media (max-width: 640px) {
    h1 {
        font-size: 28px;
    }

    h2 {
        font-size: 22px;
    }

    h3 {
        font-size: 19px;
    }

    h4 {
        font-size: var(--fs-lg);
    }
}

.body-lg {
    font-size: var(--fs-lg);
    line-height: 1.55;
}

.body-st {
    font-size: var(--fs-body);
    line-height: 1.55;
}

.body-sm {
    font-size: var(--fs-sm);
    line-height: 1.5;
}

.text-secondary-st,
.text-secondary-sm {
    font-family: var(--font-mono);
    color: var(--color-text-muted);
}

.text-secondary-st {
    font-size: var(--fs-sm);
}

.text-secondary-sm {
    font-size: var(--fs-xs);
}

.label-upper {
    font-size: var(--fs-xs);
    font-weight: var(--fw-700);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--color-text-muted);
}

code {
    font-family: var(--font-mono);
    font-size: var(--fs-xs);
    color: var(--color-text-muted);
    background: var(--slate-100);
    padding: 2px 6px;
    border-radius: var(--radius-sm);
}


/* ============================================================
   4. UTILITIES (minimal - matches style-guide shorthand)
   ============================================================ */
.flex {
    display: flex;
}

.flex-wrap {
    flex-wrap: wrap;
}

.items-center {
    align-items: center;
}

.items-start {
    align-items: flex-start;
}

.justify-end {
    justify-content: flex-end;
}

.justify-between {
    justify-content: space-between;
}

.grid {
    display: grid;
}

.text-center {
    text-align: center;
}

.relative {
    position: relative;
}

.absolute {
    position: absolute;
}

.hidden {
    display: none;
}

[hidden] {
    display: none !important;
}

.min-h-screen {
    min-height: 100vh;
}

.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;
}

@media (min-width: 640px) {
    .sm\:block {
        display: block;
    }

    .sm\:flex {
        display: flex;
    }
}

@media (min-width: 768px) {
    .md\:block {
        display: block;
    }

    .md\:flex {
        display: flex;
    }
}

@media (min-width: 1024px) {
    .lg\:block {
        display: block;
    }

    .lg\:flex {
        display: flex;
    }
}

@media (min-width: 1280px) {
    .xl\:block {
        display: block;
    }

    .xl\:flex {
        display: flex;
    }
}

.page-shell {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

.page-holder {
    flex: 1;
}

.page-main {
    max-width: var(--page-max);
    margin: 0 auto;
    padding: var(--sp-8) var(--page-pad);
}

.page-body {
    display: flex;
    flex-direction: column;
    gap: var(--sp-8);
}


/* ============================================================
   5. BUTTONS
   ============================================================ */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-2);
    font-family: var(--font-body);
    font-weight: var(--fw-600);
    letter-spacing: -0.005em;
    border-radius: var(--radius-full);
    border: 1.5px solid transparent;
    cursor: pointer;
    white-space: nowrap;
    transition: background .2s, color .2s, border-color .2s, transform .1s;
    text-decoration: none;
    /* Smooth pill edges on Windows / lower-DPR screens */
    -webkit-backface-visibility: hidden;
    backface-visibility: hidden;
}

    .btn:active {
        transform: scale(.99);
    }

.btn-sm {
    padding: 7px 14px;
    font-size: var(--fs-sm);
}

.btn-md {
    padding: 11px 20px;
    font-size: var(--fs-body);
}

.btn-lg {
    padding: 14px 26px;
    font-size: var(--fs-lg);
}

.btn-full {
    width: 100%;
}

.btn-primary {
    background: var(--brand-500);
    color: #fff;
    border-color: var(--brand-500);
}

    .btn-primary:hover {
        background: var(--brand-700);
        border-color: var(--brand-700);
    }

.btn-plus {
    background: var(--plus-500);
    color: #fff;
    border-color: var(--plus-500);
}

    .btn-plus:hover {
        background: var(--plus-700);
        border-color: var(--plus-700);
    }

.btn-teal {
    background: var(--teal-500);
    color: #fff;
    border-color: var(--teal-500);
}

    .btn-teal:hover {
        background: var(--teal-700);
        border-color: var(--teal-700);
    }

.btn-outline {
    background: transparent;
    color: var(--color-text);
    border-color: var(--color-text);
}

    .btn-outline:hover {
        background: var(--color-text);
        color: #fff;
    }

.btn-ghost {
    background: transparent;
    color: var(--color-text);
    border-color: transparent;
}

    .btn-ghost:hover {
        background: var(--slate-100);
    }

/* Danger modifier - layer on top of .btn-outline (or .btn-ghost) to
   re-tint as a destructive action. Outline variant lands first; use
   --danger when a solid red primary is needed. */
.btn-outline.btn--danger {
    color: var(--color-error);
    border-color: var(--color-error);
}

    .btn-outline.btn--danger:hover {
        background: var(--color-error);
        color: #fff;
        border-color: var(--color-error);
    }

.btn-ghost.btn--danger {
    color: var(--color-error);
}

    .btn-ghost.btn--danger:hover {
        background: rgba(196,58,43,.08);
    }

/* On-dark modifier - use on .btn-outline / .btn-ghost when the
   button sits on a dark surface (Plus+ app, dark heroes). */
.btn-outline.btn--on-dark {
    color: #fff;
    border-color: rgba(255,255,255,.3);
    background: transparent;
}

    .btn-outline.btn--on-dark:hover {
        background: rgba(255,255,255,.1);
        border-color: rgba(255,255,255,.5);
        color: #fff;
    }

.btn-ghost.btn--on-dark {
    color: #fff;
}

    .btn-ghost.btn--on-dark:hover {
        background: rgba(255,255,255,.08);
    }


/* ============================================================
   6. CARDS
   ============================================================ */
.card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--sp-4);
    box-shadow: var(--shadow-sm);
}

.card-solid {
    background: var(--color-bg-cream);
    border-radius: var(--radius-lg);
    padding: var(--sp-5);
}

.card-xl {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: var(--sp-6);
    box-shadow: var(--shadow-sm);
}

.card-title {
    font-size: var(--fs-lg);
    font-weight: var(--fw-700);
    letter-spacing: -0.015em;
    color: var(--color-text);
    margin-bottom: var(--sp-2);
}

.section-title {
    font-size: var(--fs-body);
    font-weight: var(--fw-700);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--color-text);
}


/* ============================================================
   7. LINKS
   ============================================================ */
.text-link {
    color: var(--slate-700);
    border-bottom: 1px solid transparent;
    transition: color .15s, border-color .15s;
}

    .text-link:hover {
        color: var(--brand-600);
        border-bottom-color: currentColor;
    }

.brand-link {
    color: var(--brand-600);
    font-weight: var(--fw-600);
    transition: color .15s;
}

    .brand-link:hover {
        color: var(--brand-700);
    }

.footer-link {
    color: var(--color-text-muted);
    font-size: var(--fs-sm);
    transition: color .15s;
}

    .footer-link:hover {
        color: var(--color-text);
    }


/* ============================================================
   8. NOTIFICATION BANNERS
   ============================================================ */
.notification-banner {
    display: flex;
    align-items: flex-start;
    gap: var(--sp-3);
    padding: var(--sp-3) var(--sp-4);
    border-radius: var(--radius-md);
    border: 1px solid var(--color-border);
    background: var(--color-surface);
}

.notification-banner__icon {
    width: 22px;
    height: 22px;
    stroke: currentColor;
    stroke-width: 1.8;
    fill: none;
    flex-shrink: 0;
    margin-top: 2px;
}

.notification-banner__content {
    flex: 1;
    min-width: 0;
}

.notification-banner__title {
    font-size: var(--fs-body);
    font-weight: var(--fw-700);
    letter-spacing: -0.005em;
    color: inherit;
    margin-bottom: 2px;
}

.notification-banner__message {
    font-size: var(--fs-sm);
    color: inherit;
    opacity: 0.85;
}

.notification-banner__link {
    color: inherit;
    text-decoration: underline;
    font-weight: var(--fw-600);
}

.notification-banner__close {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: currentColor;
    opacity: 0.7;
    transition: background .15s, opacity .15s;
}

    .notification-banner__close:hover {
        background: rgba(0,0,0,.06);
        opacity: 1;
    }

    .notification-banner__close svg {
        width: 14px;
        height: 14px;
        stroke: currentColor;
        stroke-width: 2.2;
        fill: none;
    }

.notification-banner--info {
    background: #EEF4FC;
    border-color: #C9DBF0;
    color: var(--color-info);
}

.notification-banner--success {
    background: #E8F3EC;
    border-color: #B8D9C2;
    color: var(--color-success);
}

.notification-banner--warning {
    background: #FEF6E7;
    border-color: #F2D79A;
    color: #946418;
}

.notification-banner--error {
    background: #FBEAE7;
    border-color: #EBB8B0;
    color: var(--color-error);
}

.notification-banner--compact {
    padding: var(--sp-2) var(--sp-3);
    gap: var(--sp-2);
}

    .notification-banner--compact .notification-banner__title {
        display: none;
    }


/* ============================================================
   9. NAV PRIMITIVES
   ============================================================ */
.nav-icon-btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    color: var(--color-text);
    background: transparent;
    transition: background .2s, color .2s;
}

    .nav-icon-btn:hover {
        background: var(--slate-100);
        color: var(--brand-500);
    }

    .nav-icon-btn svg {
        width: 20px;
        height: 20px;
        stroke: currentColor;
        stroke-width: 1.8;
        fill: none;
    }

.nav-cat-link {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    padding: var(--sp-2) var(--sp-3);
    border-radius: var(--radius-sm);
    font-size: var(--fs-sm);
    font-weight: var(--fw-500);
    color: var(--color-text);
    transition: background .15s, color .15s;
}

    .nav-cat-link:hover {
        background: var(--slate-100);
        color: var(--brand-600);
    }

.sidebar-nav-link {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    padding: var(--sp-3) var(--sp-4);
    border-radius: var(--radius-md);
    font-size: var(--fs-body);
    font-weight: var(--fw-500);
    color: var(--color-text-soft);
    transition: background .15s, color .15s;
}

    .sidebar-nav-link:hover {
        background: var(--slate-100);
        color: var(--color-text);
    }


/* ============================================================
   10. FORM ELEMENTS
   ============================================================ */
.search-input {
    width: 100%;
    padding: 11px var(--sp-4);
    padding-right: var(--sp-8);
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    border-radius: var(--radius-full);
    font-size: var(--fs-body);
    color: var(--color-text);
    outline: none;
    transition: border-color .2s, box-shadow .2s;
}

    .search-input::placeholder {
        color: var(--color-text-muted);
    }

    .search-input:focus {
        border-color: var(--brand-500);
        box-shadow: 0 0 0 3px var(--brand-100);
    }


/* ============================================================
   11. UTILITY COMPONENTS
   ============================================================ */
.focus-ring:focus-visible {
    outline: 2px solid var(--brand-500);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}

.skeleton {
    background: linear-gradient(90deg, var(--slate-100) 0%, var(--slate-200) 50%, var(--slate-100) 100%);
    background-size: 200% 100%;
    border-radius: var(--radius-sm);
    animation: skeleton-shimmer 1.4s ease-in-out infinite;
}

@keyframes skeleton-shimmer {
    0% {
        background-position: 200% 0;
    }

    100% {
        background-position: -200% 0;
    }
}

.divider {
    height: 1px;
    background: var(--color-border);
    border: 0;
    width: 100%;
}

.breadcrumb-wrap {
    max-width: var(--page-max);
    margin: 0 auto;
    padding: 18px var(--page-pad) 0;
}

.breadcrumb ol {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    font-size: var(--fs-sm);
    color: var(--color-text-muted);
}

.breadcrumb li {
    display: inline-flex;
    align-items: center;
}

    .breadcrumb li + li::before {
        content: '/';
        margin: 0 var(--sp-2);
        color: var(--color-text-faint);
    }

.breadcrumb a {
    color: var(--color-text-muted);
    transition: color .15s;
}

    .breadcrumb a:hover {
        color: var(--brand-600);
    }

.breadcrumb [aria-current="page"] {
    color: var(--color-text);
    font-weight: var(--fw-600);
}

.payment-badge {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-1);
    padding: var(--sp-1) var(--sp-2);
    background: var(--slate-100);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    font-size: var(--fs-xs);
    font-weight: var(--fw-700);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--color-text-soft);
}


/* ============================================================
   12. DIALOG / MODAL
   ============================================================ */
.dialog-surface {
    background: var(--color-surface);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-2xl);
    border: 1px solid var(--color-border);
}


/* ============================================================
   13. ACCESSIBILITY BASELINE
   ------------------------------------------------------------
   Skip link, keyboard focus indicator, hit-area extension for
   icon-only controls, reduced-motion opt-out. These apply
   globally across every page that loads this sheet.
   ============================================================ */

/* Skip link - visible only on keyboard focus (WCAG 2.4.1). */
.skip-link {
    position: absolute;
    top: -48px;
    left: var(--sp-4);
    z-index: 1000;
    padding: var(--sp-3) var(--sp-5);
    background: var(--color-text);
    color: #fff;
    font-weight: var(--fw-600);
    font-size: var(--fs-sm);
    border-radius: var(--radius-sm);
    text-decoration: none;
    transition: top .15s;
}

    .skip-link:focus {
        top: var(--sp-3);
    }

/* Global keyboard-focus indicator. `:focus-visible` keeps mouse
   clicks from triggering the ring while ensuring every tabbable
   element shows it under keyboard navigation. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
    outline: 2px solid var(--brand-500);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}

/* Extend hit area of 36px icon buttons to 44×44 (WCAG 2.5.5 AAA)
   without changing their visual size. Relies on the button being
   position: relative (already the case for .nav-icon-btn and .nav-icon). */
.nav-icon-btn::after,
.nav-icon::after {
    content: '';
    position: absolute;
    inset: -4px;
    border-radius: inherit;
}

/* Respect OS preference: disable non-essential motion. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* Main content target for the skip link. Applied by the page;
   tabindex="-1" lets the anchor focus land without adding to
   the tab order. */
[id="main"]:focus {
    outline: none;
}


/* ============================================================
   14. MAGAZINE TILE (shared component - used on home, product,
       back-issue, and logged-in pages)
   ============================================================ */
.m-tile {
    display: flex;
    flex-direction: column;
    gap: var(--sp-3);
    text-decoration: none;
    color: inherit;
    min-width: 0;
}

.m-tile__cover {
    aspect-ratio: 3 / 4;
    border-radius: var(--radius-sm);
    overflow: hidden;
    background: var(--slate-100);
    box-shadow: var(--cover-shadow);
    transition: transform .2s var(--ease-out), box-shadow .25s;
}

    .m-tile__cover img {
        width: 100%;
        height: 100%;
        object-fit: cover;
    }

.m-tile:hover .m-tile__cover {
    transform: translateY(-3px);
    box-shadow: var(--cover-shadow-hover);
}

.m-tile__body {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 0 2px;
}

.m-tile__name {
    font-size: var(--fs-sm);
    font-weight: var(--fw-700);
    color: var(--color-text);
    letter-spacing: -0.005em;
    line-height: 1.25;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.m-tile__plus {
    font-size: var(--fs-xs);
    font-weight: var(--fw-500);
    color: var(--color-text-muted);
}

    .m-tile__plus b {
        color: var(--color-text);
        font-weight: var(--fw-700);
    }

    .m-tile__plus mark {
        color: var(--brand-500);
        background: transparent;
        font-weight: var(--fw-700);
    }

.m-tile__price {
    font-size: var(--fs-xs);
    color: var(--color-text-muted);
}

    .m-tile__price strong {
        color: var(--color-text-soft);
        font-weight: var(--fw-600);
    }


/* ============================================================
   15. SEGMENTED CONTROL
   ------------------------------------------------------------
   Mutually-exclusive option group. Use for view toggles, format
   switchers, display modes. BEM: .segmented > .segmented__btn.
   ============================================================ */
.segmented {
    display: inline-flex;
    padding: 3px;
    background: var(--slate-100);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-full);
}

.segmented__btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 6px 14px;
    border-radius: var(--radius-full);
    font-size: var(--fs-sm);
    font-weight: var(--fw-600);
    color: var(--color-text-soft);
    background: transparent;
    border: 0;
    cursor: pointer;
    transition: background .18s, color .18s, box-shadow .18s;
    white-space: nowrap;
}

    .segmented__btn svg {
        width: 14px;
        height: 14px;
        stroke: currentColor;
        stroke-width: 1.8;
        fill: none;
    }

    .segmented__btn:hover {
        color: var(--color-text);
    }

    .segmented__btn.is-active,
    .segmented__btn[aria-selected="true"] {
        background: var(--color-surface);
        color: var(--color-text);
        box-shadow: var(--shadow-sm);
    }


/* ============================================================
   16. FILTER CHIPS
   ------------------------------------------------------------
   Horizontal scrolling row of selectable pills.
   ============================================================ */
.chip-row {
    display: flex;
    gap: var(--sp-2);
    overflow-x: auto;
    padding: 2px 0;
    scrollbar-width: none;
}

    .chip-row::-webkit-scrollbar {
        display: none;
    }

.chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 14px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-full);
    font-size: var(--fs-sm);
    font-weight: var(--fw-500);
    color: var(--color-text-soft);
    cursor: pointer;
    white-space: nowrap;
    transition: background .15s, border-color .15s, color .15s;
}

    .chip:hover {
        border-color: var(--color-text);
        color: var(--color-text);
    }

    .chip.is-active,
    .chip[aria-pressed="true"] {
        background: var(--color-text);
        border-color: var(--color-text);
        color: #fff;
    }

.chip__count {
    font-size: var(--fs-xs);
    font-weight: var(--fw-600);
    opacity: .7;
}

/* --title: stronger chip used as a browseable interest/tag on a
   title. Filled cream, ink text. Hover darkens to ink-on-white.
   Pair with <a> for links (not filter buttons). */
.chip--title {
    background: var(--color-bg-cream);
    border-color: var(--color-border-soft);
    color: var(--color-text);
    font-weight: var(--fw-600);
    text-decoration: none;
}

    .chip--title:hover {
        background: var(--color-text);
        border-color: var(--color-text);
        color: #fff;
    }

/* --topic: quieter chip used for article-level topic tags and
   content filters ("BBQ", "Premier League", "Sourdough"). Smaller,
   outlined, sits beneath the primary content. */
.chip--topic {
    background: transparent;
    border-color: var(--slate-300);
    color: var(--color-text-soft);
    font-size: var(--fs-xs);
    font-weight: var(--fw-500);
    padding: 4px 10px;
    text-decoration: none;
}

    .chip--topic:hover {
        background: var(--color-bg-cream);
        border-color: var(--slate-400);
        color: var(--color-text);
    }

    .chip--topic.is-active,
    .chip--topic[aria-pressed="true"] {
        background: var(--color-text);
        border-color: var(--color-text);
        color: #fff;
    }


/* ============================================================
   17. SORT SELECT
   ------------------------------------------------------------
   Custom-styled native select. Label + caret on either side
   of a real <select> so we get free keyboard + screen-reader.
   ============================================================ */
.sort-select {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    padding: 7px var(--sp-3) 7px var(--sp-3);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-full);
    font-size: var(--fs-sm);
    color: var(--color-text);
    transition: border-color .15s;
    cursor: pointer;
}

    .sort-select:hover {
        border-color: var(--color-text);
    }

.sort-select__label {
    color: var(--color-text-muted);
    font-weight: var(--fw-500);
}

.sort-select select {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    background: transparent;
    border: 0;
    font: inherit;
    color: inherit;
    font-weight: var(--fw-600);
    padding-right: 18px;
    cursor: pointer;
    outline: none;
}

.sort-select__caret {
    position: absolute;
    right: 12px;
    top: 50%;
    transform: translateY(-50%);
    width: 10px;
    height: 7px;
    stroke: var(--color-text-muted);
    stroke-width: 2.2;
    fill: none;
    pointer-events: none;
}


/* ============================================================
   18. USER MENU (popover dropdown)
   ------------------------------------------------------------
   Trigger + floating panel with menu items. Closes on outside
   click / ESC (handled by scripts/user-menu.js).
   ============================================================ */
.user-menu {
    position: relative;
}

.user-menu__panel {
    position: absolute;
    top: calc(100% + var(--sp-2));
    right: 0;
    min-width: 220px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    padding: var(--sp-2);
    z-index: 60;
    opacity: 0;
    transform: translateY(-4px);
    pointer-events: none;
    transition: opacity .15s ease, transform .15s ease;
}

.user-menu.is-open .user-menu__panel {
    opacity: 1;
    transform: none;
    pointer-events: auto;
}

.user-menu__header {
    padding: var(--sp-2) var(--sp-3) var(--sp-3);
    border-bottom: 1px solid var(--color-border-soft);
    margin-bottom: var(--sp-2);
}

.user-menu__name {
    font-size: var(--fs-sm);
    font-weight: var(--fw-700);
    color: var(--color-text);
}

.user-menu__email {
    font-size: var(--fs-xs);
    color: var(--color-text-muted);
    margin-top: 2px;
}

.user-menu__item {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    width: 100%;
    padding: var(--sp-2) var(--sp-3);
    border-radius: var(--radius-sm);
    font-size: var(--fs-sm);
    font-weight: var(--fw-500);
    color: var(--color-text);
    background: transparent;
    border: 0;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
    transition: background .15s, color .15s;
}

    .user-menu__item:hover {
        background: var(--slate-100);
    }

    .user-menu__item svg {
        width: 16px;
        height: 16px;
        stroke: var(--color-text-muted);
        stroke-width: 1.8;
        fill: none;
        flex-shrink: 0;
    }

.user-menu__item--danger {
    color: var(--color-error);
}

    .user-menu__item--danger svg {
        stroke: var(--color-error);
    }

.user-menu__divider {
    height: 1px;
    background: var(--color-border-soft);
    border: 0;
    margin: var(--sp-2) 0;
}


/* ============================================================
   19. OPTIONS SHEET (mobile bottom sheet)
   ------------------------------------------------------------
   Full-width modal that slides up from the bottom on mobile.
   Same semantics as a dialog; wire with scripts/a11y.js.
   ============================================================ */
.options-sheet {
    position: fixed;
    inset: 0;
    z-index: 80;
    display: none;
    background: rgba(16,14,12,.45);
    backdrop-filter: blur(2px);
}

    .options-sheet.is-open {
        display: flex;
        align-items: flex-end;
    }

.options-sheet__panel {
    width: 100%;
    background: var(--color-surface);
    border-top-left-radius: var(--radius-xl);
    border-top-right-radius: var(--radius-xl);
    padding: var(--sp-3) var(--sp-5) var(--sp-7);
    box-shadow: var(--shadow-2xl);
    animation: options-sheet-in .25s var(--ease-out);
    max-height: 80vh;
    overflow-y: auto;
}

@keyframes options-sheet-in {
    from {
        transform: translateY(100%);
    }

    to {
        transform: translateY(0);
    }
}

.options-sheet__handle {
    width: 44px;
    height: 4px;
    background: var(--slate-300);
    border-radius: var(--radius-full);
    margin: 0 auto var(--sp-4);
}

.options-sheet__title {
    font-size: var(--fs-lg);
    font-weight: var(--fw-800);
    letter-spacing: -0.015em;
    color: var(--color-text);
    margin-bottom: var(--sp-5);
    text-align: center;
}

.options-sheet__group + .options-sheet__group {
    margin-top: var(--sp-5);
}

.options-sheet__group-label {
    display: block;
    font-size: var(--fs-xs);
    font-weight: var(--fw-700);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--color-text-muted);
    margin-bottom: var(--sp-2);
}

.options-sheet__actions {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.options-sheet__action {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    width: 100%;
    padding: var(--sp-3) var(--sp-3);
    border-radius: var(--radius-sm);
    font-size: var(--fs-body);
    font-weight: var(--fw-500);
    color: var(--color-text);
    background: transparent;
    border: 0;
    text-align: left;
    cursor: pointer;
    transition: background .15s;
}

    .options-sheet__action:hover {
        background: var(--slate-100);
    }

    .options-sheet__action svg {
        width: 18px;
        height: 18px;
        stroke: var(--color-text-muted);
        stroke-width: 1.8;
        fill: none;
        flex-shrink: 0;
    }

.options-sheet__action-check {
    margin-left: auto;
    color: var(--brand-500);
    opacity: 0;
}

.options-sheet__action[aria-checked="true"] .options-sheet__action-check {
    opacity: 1;
}


/* ============================================================
   20. COVER STACK
   ------------------------------------------------------------
   Multi-issue library visual - front cover with up to two
   covers fan-stacked behind. Hover fans the stack further.
   Use .cover-stack--single when the user only owns one issue.
   ============================================================ */
.cover-stack {
    position: relative;
    display: block;
    aspect-ratio: 3 / 4;
    color: inherit;
    text-decoration: none;
    /* Reserve space on the right/bottom for fanning covers */
    padding-right: 14px;
    padding-bottom: 14px;
}

.cover-stack__layer {
    position: absolute;
    top: 0;
    left: 0;
    right: 14px;
    bottom: 14px;
    border-radius: var(--radius-sm);
    background: var(--slate-200);
    overflow: hidden;
    box-shadow: var(--cover-shadow);
    transition: transform .35s var(--ease-out), box-shadow .35s;
}

    .cover-stack__layer img {
        width: 100%;
        height: 100%;
        object-fit: cover;
        display: block;
    }

.cover-stack__layer--back-2 {
    z-index: 1;
    transform: translate(12px, 12px) rotate(4deg);
    opacity: .55;
    filter: brightness(.7) saturate(.85);
}

.cover-stack__layer--back-1 {
    z-index: 2;
    transform: translate(6px, 6px) rotate(2deg);
    opacity: .8;
    filter: brightness(.85) saturate(.9);
}

.cover-stack__layer--front {
    z-index: 3;
}

.cover-stack:hover .cover-stack__layer--front {
    transform: translate(-2px, -3px);
}

.cover-stack:hover .cover-stack__layer--back-1 {
    transform: translate(10px, 8px) rotate(5deg);
}

.cover-stack:hover .cover-stack__layer--back-2 {
    transform: translate(18px, 14px) rotate(8deg);
}

.cover-stack--single {
    padding-right: 0;
    padding-bottom: 0;
}

    .cover-stack--single .cover-stack__layer {
        right: 0;
        bottom: 0;
    }


/* ============================================================
   21. NEW SASH
   ------------------------------------------------------------
   Corner ribbon for unread content. Sits top-right on any
   positioned container (cover, tile, card).
   ============================================================ */
.new-sash {
    position: absolute;
    top: 10px;
    right: -4px;
    z-index: 6;
    padding: 3px 14px;
    background: var(--brand-500);
    color: #fff;
    font-size: 10px;
    font-weight: var(--fw-800);
    text-transform: uppercase;
    letter-spacing: 0.12em;
    border-radius: 2px;
    transform: rotate(6deg);
    box-shadow: 0 4px 10px rgba(232,58,30,.3);
    pointer-events: none;
}

    .new-sash::before {
        content: '';
        position: absolute;
        right: 0;
        top: 100%;
        border: 4px solid transparent;
        border-top-color: var(--brand-700);
        border-right-color: var(--brand-700);
    }


/* ============================================================
   22. STAT BADGE
   ------------------------------------------------------------
   Small count chip sat in the corner of content (e.g. issue
   count on a stack). Unlike .new-sash, it's informational.
   ============================================================ */
.stat-badge {
    position: absolute;
    bottom: 18px;
    left: 10px;
    z-index: 5;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px 9px;
    background: rgba(20,18,16,.78);
    color: #fff;
    font-size: 10.5px;
    font-weight: var(--fw-700);
    letter-spacing: 0.04em;
    border-radius: var(--radius-full);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
}

    .stat-badge svg {
        width: 10px;
        height: 10px;
        stroke: currentColor;
        stroke-width: 2;
        fill: none;
    }


/* ============================================================
   23. KEBAB MENU
   ------------------------------------------------------------
   Compact three-dot trigger with a small floating panel of
   actions. Same open/close behaviour as .user-menu - wired by
   scripts/user-menu.js (it matches both classes).

   Markup:
     <div class="kebab-menu">
       <button class="kebab-menu__trigger" aria-haspopup="menu"
               aria-expanded="false" aria-label="More actions">⋯</button>
       <div class="kebab-menu__panel" role="menu" aria-hidden="true">
         <a class="kebab-menu__item" role="menuitem">...</a>
       </div>
     </div>
   ============================================================ */
.kebab-menu {
    position: relative;
    display: inline-block;
}

.kebab-menu__trigger {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    color: var(--color-text-soft);
    border: 0;
    cursor: pointer;
    transition: background .15s, color .15s;
}

    .kebab-menu__trigger:hover {
        background: var(--slate-100);
        color: var(--color-text);
    }

    .kebab-menu__trigger svg {
        width: 16px;
        height: 16px;
        stroke: currentColor;
        stroke-width: 2;
        fill: none;
    }

.kebab-menu__panel {
    position: absolute;
    top: calc(100% + 4px);
    right: 0;
    min-width: 180px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    padding: 4px;
    z-index: 50;
    opacity: 0;
    transform: translateY(-4px);
    pointer-events: none;
    transition: opacity .15s ease, transform .15s ease;
}

.kebab-menu.is-open .kebab-menu__panel {
    opacity: 1;
    transform: none;
    pointer-events: auto;
}

.kebab-menu__item {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    width: 100%;
    padding: 8px 12px;
    border-radius: var(--radius-sm);
    font-size: var(--fs-sm);
    font-weight: var(--fw-500);
    color: var(--color-text);
    background: transparent;
    border: 0;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
    white-space: nowrap;
    transition: background .12s, color .12s;
}

    .kebab-menu__item:hover {
        background: var(--slate-100);
    }

    .kebab-menu__item svg {
        width: 14px;
        height: 14px;
        stroke: var(--color-text-muted);
        stroke-width: 1.8;
        fill: none;
        flex-shrink: 0;
    }

.kebab-menu__item--danger {
    color: var(--color-error);
}

    .kebab-menu__item--danger svg {
        stroke: var(--color-error);
    }


/* ============================================================
   24. SPLIT BUTTON
   ------------------------------------------------------------
   Compound control: a primary action on the left and a caret
   trigger on the right that opens a .kebab-menu__panel.
   Rendered as a single pill so they read as one control.

   Wraps a .kebab-menu so scripts/user-menu.js auto-wires the
   toggle. The panel sits beneath the whole pill.
   ============================================================ */
.split-button {
    display: inline-flex;
    align-items: stretch;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-full);
    background: var(--color-surface);
    position: relative;
    overflow: visible;
}

    .split-button .split-button__primary,
    .split-button .split-button__toggle {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: 6px;
        padding: 8px 16px;
        font-family: inherit;
        font-size: var(--fs-sm);
        font-weight: var(--fw-600);
        line-height: 1.2;
        color: var(--color-text);
        background: transparent;
        border: 0;
        text-decoration: none;
        cursor: pointer;
        transition: background .15s, color .15s;
        white-space: nowrap;
    }

.split-button__primary {
    border-right: 1px solid var(--color-border);
    border-top-left-radius: var(--radius-full);
    border-bottom-left-radius: var(--radius-full);
}

.split-button__toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    border-top-right-radius: var(--radius-full);
    border-bottom-right-radius: var(--radius-full);
}

    .split-button__toggle svg {
        width: 10px;
        height: 7px;
        stroke: currentColor;
        stroke-width: 2.2;
        fill: none;
        transition: transform .15s;
    }

.split-button.is-open .split-button__toggle svg {
    transform: rotate(180deg);
}

.split-button__primary:hover,
.split-button__toggle:hover {
    background: var(--slate-100);
}


/* ============================================================
   25. STATUS INDICATOR
   ------------------------------------------------------------
   Coloured dot + label. Use to show subscription, order or
   connection state. BEM + modifiers: --active, --paused,
   --cancelled, --inactive, --warning.
   ============================================================ */
.status-indicator {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: var(--fs-xs);
    font-weight: var(--fw-600);
    letter-spacing: 0.01em;
}

.status-indicator__dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
}

.status-indicator--active {
    color: var(--color-success);
}

    .status-indicator--active .status-indicator__dot {
        background: var(--color-success);
        box-shadow: 0 0 0 3px rgba(46,139,87,.18);
    }

.status-indicator--paused {
    color: #B46E0A;
}

    .status-indicator--paused .status-indicator__dot {
        background: var(--color-warning);
        box-shadow: 0 0 0 3px rgba(232,165,61,.20);
    }

.status-indicator--warning {
    color: #B46E0A;
}

    .status-indicator--warning .status-indicator__dot {
        background: var(--color-warning);
        box-shadow: 0 0 0 3px rgba(232,165,61,.20);
    }

.status-indicator--cancelled,
.status-indicator--inactive {
    color: var(--color-text-muted);
}

    .status-indicator--cancelled .status-indicator__dot,
    .status-indicator--inactive .status-indicator__dot {
        background: var(--slate-400);
        box-shadow: 0 0 0 3px rgba(180,174,165,.22);
    }

.status-indicator--error {
    color: var(--color-error);
}

    .status-indicator--error .status-indicator__dot {
        background: var(--color-error);
        box-shadow: 0 0 0 3px rgba(196,58,43,.22);
    }


/* ============================================================
   26. PAGE HERO
   ------------------------------------------------------------
   Cream-tinted page header used as a landing banner on library,
   subscriptions, account etc. Composes with .breadcrumb-wrap so
   the crumb sits inside the tint.

     <section class="page-hero page-hero--title">
       <div class="breadcrumb-wrap">...</div>
       <div class="page-hero-inner">
         <div class="page-hero-lead">
           <span class="label-upper">Kicker</span>
           <h1>Title</h1>
           <p>Optional copy</p>
         </div>
         <div class="page-hero-count">…</div>
       </div>
     </section>

   Variant: .page-hero--title tightens vertical rhythm for pages
   where the hero sits right below the breadcrumb.
   ============================================================ */
.page-hero {
    background: var(--color-bg-cream);
    border-bottom: 1px solid var(--color-border);
    padding: var(--sp-8) 0 var(--sp-4);
}

.page-hero-inner {
    max-width: var(--page-max);
    margin: 0 auto;
    padding: 0 var(--page-pad);
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--sp-5);
    flex-wrap: wrap;
}

.page-hero-lead .label-upper {
    display: block;
    margin-bottom: var(--sp-2);
}

.page-hero-lead h1 {
    font-size: var(--fs-xxl);
    font-weight: var(--fw-800);
    letter-spacing: -0.028em;
    line-height: 1.1;
    color: var(--color-text);
    margin-bottom: var(--sp-2);
}
/* h1 + follow-btn row at the top of a tag page hero. h1 line-height
   is dropped to 1 so its line box matches the visible cap height -
   align-items: center then truly centres the pill on the letters
   rather than on the leading. */
.page-hero-lead__top {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    flex-wrap: wrap;
    margin-bottom: var(--sp-2);
}

    .page-hero-lead__top h1 {
        margin-bottom: 0;
        line-height: 1;
    }

.page-hero-lead p {
    font-size: var(--fs-body);
    color: var(--color-text-soft);
    max-width: 540px;
}

.page-hero-count {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    padding: 8px 14px 8px 10px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-full);
    font-size: var(--fs-sm);
    color: var(--color-text-soft);
}

    .page-hero-count strong {
        color: var(--color-text);
        font-weight: var(--fw-700);
    }

    .page-hero-count svg {
        width: 16px;
        height: 16px;
        stroke: var(--plus-500);
        stroke-width: 1.8;
        fill: none;
    }

.page-hero--title {
    padding: var(--sp-4) 0 var(--sp-5);
}

    .page-hero--title .page-hero-lead h1 {
        margin-bottom: var(--sp-3);
    }

    .page-hero--title .breadcrumb-wrap {
        padding-top: 0;
        padding-bottom: 0;
    }

    .page-hero--title .page-hero-inner {
        padding-top: var(--sp-4);
    }

/* Wrapping chip row - override default single-line scroll on
   chip-row when the content is navigation rather than a filter bar. */
.chip-row--wrap {
    flex-wrap: wrap;
    overflow: visible;
    gap: 8px;
}

/* Hero trending - inline "TRENDING: <pills>" row that sits inside
   the page-hero-lead (or any compact context), below the description. */
/* Hero trending - right-column tag cloud that sits parallel to the
   hero description. Centred rows give the cloud ragged edges on
   both sides rather than a hard left-aligned column. */
.hero-trending {
    flex: 0 1 480px;
    min-width: 0;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 6px;
    align-content: flex-start;
}
/* When the hero uses the split layout, top-align the two columns
   so description and trending share the same baseline. */
.page-hero-inner--split {
    align-items: flex-start;
    gap: var(--sp-7);
}

/* Inline search pill - sits at the end of a .hero-trending cloud so
   it reads as "search this title" next to the topic shortcuts. */
.hero-search {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 12px 4px 10px;
    background: var(--color-surface);
    border: 1px solid var(--slate-300);
    border-radius: var(--radius-full);
    font-size: var(--fs-xs);
    font-weight: var(--fw-500);
    color: var(--color-text-soft);
    transition: border-color .15s, color .15s;
}

    .hero-search:focus-within {
        border-color: var(--color-text);
        color: var(--color-text);
    }

    .hero-search svg {
        width: 12px;
        height: 12px;
        stroke: currentColor;
        stroke-width: 2;
        fill: none;
        flex-shrink: 0;
    }

    .hero-search input {
        border: 0;
        background: transparent;
        font: inherit;
        color: inherit;
        outline: 0;
        width: 150px;
        padding: 0;
    }

        .hero-search input::placeholder {
            color: var(--color-text-muted);
        }


/* ============================================================
   27. PROMO BAND
   ------------------------------------------------------------
   Full-width announcement strip that sits directly beneath the
   global nav on a specific page (e.g. Puzzles). Plum gradient,
   white text, with a primary CTA on the right.
   ============================================================ */
.promo-band {
    background: radial-gradient(circle at 90% 50%, rgba(255,255,255,.08), transparent 60%), linear-gradient(135deg, var(--plus-700) 0%, var(--plus-500) 100%);
    color: #fff;
    border-bottom: 1px solid rgba(255,255,255,.12);
}

.promo-band__inner {
    max-width: var(--page-max);
    margin: 0 auto;
    padding: 10px var(--page-pad);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-4);
    font-size: var(--fs-sm);
}

.promo-band__message {
    display: inline-flex;
    align-items: baseline;
    gap: var(--sp-2);
    min-width: 0;
}

.promo-band__label {
    font-weight: var(--fw-800);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    font-size: var(--fs-xs);
    color: rgba(255,255,255,.88);
    flex-shrink: 0;
}

.promo-band__body {
    color: rgba(255,255,255,.92);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.promo-band .btn {
    background: #fff;
    color: var(--plus-700);
    border-color: #fff;
}

    .promo-band .btn:hover {
        background: var(--brand-500);
        color: #fff;
        border-color: var(--brand-500);
    }

@media (max-width: 640px) {
    .promo-band__body {
        display: none;
    }
}


/* ============================================================
   28. PUZZLE BADGE
   ------------------------------------------------------------
   Category pill on a puzzle card (QUICK / WORD / NUMBER / LOGIC).
   Each variant sets its own colourway.
   ============================================================ */
.puzzle-badge {
    display: inline-flex;
    align-items: center;
    padding: 3px 9px 2px;
    background: var(--plus-100);
    color: var(--plus-800);
    font-size: 10px;
    font-weight: var(--fw-800);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    border-radius: var(--radius-full);
}

.puzzle-badge--quick {
    background: #FDF0D4;
    color: #7A5111;
}

.puzzle-badge--word {
    background: var(--plus-100);
    color: var(--plus-800);
}

.puzzle-badge--number {
    background: #D5EBDB;
    color: #1E5935;
}

.puzzle-badge--logic {
    background: var(--brand-100);
    color: var(--brand-800);
}


/* ============================================================
   29. PUZZLE CIRCLE (My Most Played item)
   ============================================================ */
.puzzle-circle {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--sp-2);
    text-decoration: none;
    color: inherit;
    flex-shrink: 0;
    min-width: 84px;
}

.puzzle-circle__art {
    width: 80px;
    height: 80px;
    border-radius: 50%;
    background: #fff;
    border: 2px solid var(--plus-300);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    box-shadow: 0 4px 10px rgba(61,42,120,.08);
    transition: transform .2s var(--ease-out), border-color .2s, box-shadow .2s;
}

.puzzle-circle:hover .puzzle-circle__art {
    transform: translateY(-2px);
    border-color: var(--plus-500);
    box-shadow: 0 6px 14px rgba(61,42,120,.15);
}

.puzzle-circle__art svg {
    width: 72%;
    height: 72%;
}

.puzzle-circle__name {
    font-size: var(--fs-xs);
    font-weight: var(--fw-600);
    color: var(--color-text);
    text-align: center;
    line-height: 1.2;
    max-width: 90px;
}


/* ============================================================
   30. PUZZLE CARD
   ------------------------------------------------------------
   Today's Puzzles grid card - puzzle preview in a tinted frame,
   title, and two stacked CTAs (Play + Past Puzzles).
   ============================================================ */
.puzzle-card {
    display: flex;
    flex-direction: column;
    padding: var(--sp-4);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    transition: transform .2s var(--ease-out), box-shadow .25s, border-color .2s;
}

    .puzzle-card:hover {
        transform: translateY(-2px);
        box-shadow: var(--shadow-md);
        border-color: var(--plus-300);
    }

.puzzle-card__art {
    position: relative;
    aspect-ratio: 4 / 3;
    background: var(--plus-50);
    border: 1px solid var(--plus-100);
    border-radius: var(--radius-md);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    margin-bottom: var(--sp-3);
}

    .puzzle-card__art svg {
        width: 62%;
        height: 82%;
    }

    .puzzle-card__art .puzzle-badge {
        position: absolute;
        top: 10px;
        right: 10px;
    }

.puzzle-card__title {
    font-size: var(--fs-xl);
    font-weight: var(--fw-800);
    letter-spacing: -0.015em;
    color: var(--color-text);
    text-align: center;
    margin-bottom: var(--sp-3);
}

.puzzle-card__actions {
    display: flex;
    flex-direction: column;
    gap: var(--sp-2);
}

/* Inline puzzle art - shared SVG styling used inside .puzzle-circle
   and .puzzle-card. Colours pick up the plum scale so previews sit
   comfortably on any tinted background. */
.puzzle-art {
    display: block;
}

.puzzle-art__grid rect {
    fill: #fff;
    stroke: var(--plus-300);
    stroke-width: 1;
}

.puzzle-art__grid .is-filled {
    fill: var(--plus-800);
}

.puzzle-art__grid .is-hl {
    fill: var(--plus-200);
}

.puzzle-art__grid text {
    font-family: var(--font-body);
    font-size: 7px;
    font-weight: var(--fw-700);
    fill: var(--plus-700);
}

    .puzzle-art__grid .is-filled + text,
    .puzzle-art__grid text.on-dark {
        fill: #fff;
    }

/* Wordy / Wordle-style colour squares */
.puzzle-art--wordy .sq-correct {
    fill: #5BA85F;
    stroke: #3E8443;
}

.puzzle-art--wordy .sq-partial {
    fill: #E5B94E;
    stroke: #BE8F28;
}

.puzzle-art--wordy .sq-miss {
    fill: #D2CABE;
    stroke: #AEA596;
}

.puzzle-art--wordy text {
    font-size: 7.5px;
    fill: #fff;
    text-anchor: middle;
    dominant-baseline: central;
}


/* ============================================================
   31. FOCUS NAV
   ------------------------------------------------------------
   Minimal nav for task-focused pages (activation, checkout,
   password reset). Drops search / categories / basket / account
   to remove distractions. Just the brand and a quiet "Help" link.
   ============================================================ */
.nav-focus {
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
}

.nav-focus__inner {
    max-width: var(--page-max);
    margin: 0 auto;
    padding: 18px var(--page-pad);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-4);
}

.nav-focus__help {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    font-size: var(--fs-sm);
    font-weight: var(--fw-500);
    color: var(--color-text-soft);
    padding: var(--sp-2) var(--sp-3);
    border-radius: var(--radius-sm);
    transition: color .15s, background .15s;
}

    .nav-focus__help:hover {
        color: var(--color-text);
        background: var(--slate-100);
    }

    .nav-focus__help svg {
        width: 16px;
        height: 16px;
        stroke: currentColor;
        stroke-width: 1.8;
        fill: none;
    }


/* ============================================================
   32. STEPPER
   ------------------------------------------------------------
   Progress indicator for multi-step flows. Ordered list where
   each step has a circle (number or check) + label, joined by
   a connecting rule. Modifiers: --done, --current.
   ============================================================ */
.stepper {
    list-style: none;
    display: inline-flex;
    align-items: center;
    gap: var(--sp-3);
    padding: 0;
    margin: 0;
    font-size: var(--fs-sm);
}

.stepper__step {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    color: var(--color-text-muted);
    font-weight: var(--fw-500);
}

    .stepper__step + .stepper__step::before {
        content: '';
        display: block;
        width: 36px;
        height: 1.5px;
        background: var(--color-border);
        margin-right: var(--sp-3);
    }

.stepper__circle {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--color-surface);
    border: 1.5px solid var(--color-border);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: var(--fs-xs);
    font-weight: var(--fw-800);
    color: var(--color-text-muted);
    flex-shrink: 0;
}

    .stepper__circle svg {
        width: 12px;
        height: 12px;
        stroke: currentColor;
        stroke-width: 2.5;
        fill: none;
    }

.stepper__label {
    line-height: 1;
}

.stepper__step--done .stepper__circle {
    background: var(--color-success);
    border-color: var(--color-success);
    color: #fff;
}

.stepper__step--done .stepper__label {
    color: var(--color-text-soft);
}

.stepper__step--done + .stepper__step::before {
    background: var(--color-success);
}

.stepper__step--current .stepper__circle {
    background: var(--color-text);
    border-color: var(--color-text);
    color: #fff;
}

.stepper__step--current .stepper__label {
    color: var(--color-text);
    font-weight: var(--fw-700);
}


/* ============================================================
   33. FIELD (form primitive)
   ------------------------------------------------------------
   Label + hint + input + error, stacked. Pair with <input>,
   <textarea> or <select>. Add aria-invalid="true" on the input
   to surface the --error styling.
   ============================================================ */
.field {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.field__label {
    font-size: var(--fs-sm);
    font-weight: var(--fw-700);
    letter-spacing: -0.005em;
    color: var(--color-text);
}

.field__hint {
    font-size: var(--fs-xs);
    color: var(--color-text-muted);
    margin-top: -2px;
}

.field__input,
.field__select,
.field__textarea {
    padding: 11px 14px;
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    border-radius: var(--radius-sm);
    font-family: inherit;
    font-size: var(--fs-body);
    color: var(--color-text);
    outline: none;
    transition: border-color .15s, box-shadow .15s;
    width: 100%;
}

    .field__input::placeholder {
        color: var(--color-text-muted);
    }

    .field__input:focus,
    .field__select:focus,
    .field__textarea:focus {
        border-color: var(--brand-500);
        box-shadow: 0 0 0 3px var(--brand-100);
    }

    .field__input[aria-invalid="true"],
    .field__select[aria-invalid="true"],
    .field__textarea[aria-invalid="true"] {
        border-color: var(--color-error);
        box-shadow: 0 0 0 3px rgba(196,58,43,.18);
    }

.field__error {
    font-size: var(--fs-xs);
    font-weight: var(--fw-600);
    color: var(--color-error);
    margin-top: 2px;
}

.field--full {
    grid-column: 1 / -1;
}


/* ============================================================
   34. FOOTER
   ------------------------------------------------------------
   Site-wide page footer. Centred within the page max-width,
   simple top rule, muted text. Works on any page.
   ============================================================ */
.footer {
    max-width: var(--page-max);
    margin: 48px auto 0;
    padding: 28px var(--page-pad) 32px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--sp-4);
    border-top: 1px solid var(--color-border);
    color: var(--color-text-muted);
    font-size: var(--fs-sm);
}

.footer-brand {
    font-weight: var(--fw-700);
    color: var(--color-text-soft);
    font-size: var(--fs-body);
}

    .footer-brand span {
        color: var(--brand-500);
    }


/* ============================================================
   35. TOGGLE SWITCH
   ------------------------------------------------------------
   Accessible switch built on a real <input type="checkbox">.
   The native input is visually hidden but keeps full keyboard
   and screen-reader support. Track + thumb are pure CSS.

     <label class="toggle">
       <input class="toggle__input" type="checkbox" checked>
       <span class="toggle__track" aria-hidden="true">
         <span class="toggle__thumb"></span>
       </span>
       <span class="toggle__label">Label</span>
     </label>
   ============================================================ */
.toggle {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-3);
    cursor: pointer;
    user-select: none;
}

.toggle__input {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.toggle__track {
    position: relative;
    display: inline-block;
    width: 40px;
    height: 22px;
    border-radius: var(--radius-full);
    background: var(--slate-300);
    transition: background .2s;
    flex-shrink: 0;
}

.toggle__thumb {
    position: absolute;
    top: 2px;
    left: 2px;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 1px 3px rgba(0,0,0,.2);
    transition: transform .2s var(--ease-out);
}

.toggle__input:checked + .toggle__track {
    background: var(--plus-500);
}

    .toggle__input:checked + .toggle__track .toggle__thumb {
        transform: translateX(18px);
    }

.toggle__input:focus-visible + .toggle__track {
    outline: 2px solid var(--brand-500);
    outline-offset: 2px;
}

.toggle__input:disabled + .toggle__track {
    opacity: .5;
    cursor: not-allowed;
}

.toggle__label {
    font-size: var(--fs-sm);
    font-weight: var(--fw-600);
    color: var(--color-text);
}


/* ============================================================
   36. SETTING ROW
   ------------------------------------------------------------
   Row inside a settings card: label + optional hint on the
   left, value + action on the right. Rows are expected to be
   separated by hairline dividers (use <hr class="divider">).
   ============================================================ */
.setting-row {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--sp-5);
    padding: var(--sp-4) 0;
}

    .setting-row:first-child {
        padding-top: 0;
    }

    .setting-row:last-child {
        padding-bottom: 0;
    }

.setting-row__body {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 3px;
    flex: 1;
}

.setting-row__label {
    font-size: var(--fs-sm);
    font-weight: var(--fw-700);
    letter-spacing: -0.005em;
    color: var(--color-text);
}

.setting-row__value {
    font-family: var(--font-mono);
    font-size: var(--fs-sm);
    color: var(--color-text-soft);
    word-break: break-all;
}

.setting-row__hint {
    font-size: var(--fs-sm);
    color: var(--color-text-soft);
    line-height: 1.5;
    max-width: 52ch;
}

.setting-row__action {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: var(--sp-2);
}

@media (max-width: 560px) {
    .setting-row {
        flex-direction: column;
        gap: var(--sp-3);
    }

    .setting-row__action {
        width: 100%;
    }

        .setting-row__action .btn {
            width: 100%;
        }
}

/* Inline variant — keeps the action pinned to the right on all screen
   sizes. Use on rows where the control is a toggle (not a button that
   needs full-width on mobile). */
.setting-row--inline {
    align-items: center;
}

@media (max-width: 560px) {
    .setting-row--inline {
        flex-direction: row;
        gap: var(--sp-5);
    }

        .setting-row--inline .setting-row__action {
            width: auto;
        }
}


/* ============================================================
   37. DRAWER
   ------------------------------------------------------------
   Right-side slide-in panel. Used for the basket and any other
   on-demand overlay that needs more vertical room than a kebab
   menu. Carries role="dialog" aria-modal="true"; wire to the
   a11y.js focus-trap helpers.
   ============================================================ */
.drawer {
    position: fixed;
    inset: 0;
    z-index: 90;
    background: rgba(16,14,12,.45);
    display: none;
    justify-content: flex-end;
}

    .drawer.is-open {
        display: flex;
        animation: drawer-fade-in .2s ease-out;
    }

@keyframes drawer-fade-in {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

.drawer__panel {
    width: min(420px, 100vw);
    max-width: 100%;
    background: var(--color-surface);
    display: flex;
    flex-direction: column;
    box-shadow: -12px 0 40px rgba(20,15,10,.2);
    animation: drawer-slide-in .28s var(--ease-out);
}

@keyframes drawer-slide-in {
    from {
        transform: translateX(100%);
    }

    to {
        transform: translateX(0);
    }
}

.drawer__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--sp-5) var(--sp-5) var(--sp-4);
    border-bottom: 1px solid var(--color-border);
    flex-shrink: 0;
}

.drawer__title {
    font-size: var(--fs-xl);
    font-weight: var(--fw-800);
    letter-spacing: -0.02em;
    color: var(--color-text);
    display: inline-flex;
    align-items: baseline;
    gap: var(--sp-2);
}

.drawer__count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 22px;
    height: 22px;
    padding: 0 6px;
    border-radius: var(--radius-full);
    background: var(--color-text);
    color: #fff;
    font-size: 11px;
    font-weight: var(--fw-800);
    line-height: 1;
}

.drawer__close {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 0;
    cursor: pointer;
    color: var(--color-text-muted);
    transition: background .15s, color .15s;
}

    .drawer__close:hover {
        background: var(--slate-100);
        color: var(--color-text);
    }

    .drawer__close svg {
        width: 14px;
        height: 14px;
        stroke: currentColor;
        stroke-width: 2.2;
        fill: none;
    }

.drawer__body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: var(--sp-4) var(--sp-5);
    display: flex;
    flex-direction: column;
    gap: var(--sp-4);
}

.drawer__footer {
    flex-shrink: 0;
    padding: var(--sp-4) var(--sp-5) var(--sp-5);
    border-top: 1px solid var(--color-border);
    background: var(--color-surface);
    display: flex;
    flex-direction: column;
    gap: var(--sp-3);
}


/* ============================================================
   38. BASKET ITEM
   ------------------------------------------------------------
   Row used in the basket drawer: cover + title/issue + price
   + secondary actions. Stacks cleanly on narrow screens.
   ============================================================ */
.basket-items {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--sp-4);
}

.basket-item {
    display: grid;
    grid-template-columns: 56px 1fr auto;
    gap: var(--sp-4);
    align-items: flex-start;
}

.basket-item__cover {
    aspect-ratio: 3 / 4;
    border-radius: var(--radius-sm);
    overflow: hidden;
    background: var(--slate-200);
    box-shadow: var(--cover-shadow-sm);
}

    .basket-item__cover img {
        width: 100%;
        height: 100%;
        object-fit: cover;
        display: block;
    }

.basket-item__body {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.basket-item__name {
    font-size: var(--fs-sm);
    font-weight: var(--fw-700);
    color: var(--color-text);
    line-height: 1.25;
}

.basket-item__issue {
    font-size: var(--fs-xs);
    color: var(--color-text-muted);
}

.basket-item__actions {
    display: flex;
    gap: var(--sp-3);
    margin-top: 4px;
    font-size: var(--fs-xs);
}

    .basket-item__actions button,
    .basket-item__actions a {
        background: transparent;
        border: 0;
        padding: 0;
        cursor: pointer;
        color: var(--color-text-muted);
        font-weight: var(--fw-500);
        border-bottom: 1px solid transparent;
        transition: color .15s, border-color .15s;
    }

        .basket-item__actions button:hover,
        .basket-item__actions a:hover {
            color: var(--color-text);
            border-bottom-color: currentColor;
        }

.basket-item__price {
    font-size: var(--fs-sm);
    font-weight: var(--fw-800);
    color: var(--color-text);
    text-align: right;
    white-space: nowrap;
}


/* ============================================================
   39. UPSELL CARD
   ------------------------------------------------------------
   Small promotional card - cover thumbnail + copy + CTA.
   --plus variant for Pocketmags Plus+ upsells (purple accent).
   ============================================================ */
.upsell-card {
    display: grid;
    grid-template-columns: 44px 1fr auto;
    gap: var(--sp-3);
    align-items: center;
    padding: var(--sp-3);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
}

.upsell-card--plus {
    background: var(--plus-50);
    border-color: var(--plus-200);
}

.upsell-card__cover {
    aspect-ratio: 3 / 4;
    border-radius: var(--radius-sm);
    overflow: hidden;
    background: var(--slate-200);
}

    .upsell-card__cover img {
        width: 100%;
        height: 100%;
        object-fit: cover;
        display: block;
    }

.upsell-card__body {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.upsell-card__title {
    font-size: var(--fs-sm);
    font-weight: var(--fw-800);
    color: var(--color-text);
    line-height: 1.2;
}

    .upsell-card__title b,
    .upsell-card__title strong {
        font-weight: var(--fw-800);
    }

.upsell-card--plus .upsell-card__title em {
    font-style: normal;
    color: var(--plus-700);
}

.upsell-card__body p {
    font-size: var(--fs-xs);
    color: var(--color-text-soft);
    line-height: 1.35;
}

.upsell-card__body a {
    color: var(--plus-700);
    font-weight: var(--fw-600);
}

    .upsell-card__body a:hover {
        color: var(--plus-800);
    }


/* ============================================================
   40. PAYMENT ICONS
   ------------------------------------------------------------
   Small horizontal row of payment-method chips. Reads as a row
   of quiet logos. Each chip is just a styled span - easy to
   swap for real brand SVGs when licensing is cleared.
   ============================================================ */
.payment-icons {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
}

.payment-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 3px 8px;
    background: #fff;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    font-size: 10px;
    font-weight: var(--fw-800);
    letter-spacing: 0.04em;
    color: var(--color-text-soft);
    min-height: 22px;
}


/* ============================================================
   41. LOYALTY LINE
   ------------------------------------------------------------
   Small pill-dot callout used in the basket / order summary to
   highlight loyalty-points earned on the purchase.
   ============================================================ */
.loyalty-line {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: var(--fs-xs);
    color: var(--color-text-muted);
}

    .loyalty-line::before {
        content: '';
        width: 8px;
        height: 8px;
        border-radius: 50%;
        background: #E8A53D;
        box-shadow: 0 0 0 3px rgba(232,165,61,.18);
        flex-shrink: 0;
    }

    .loyalty-line strong {
        color: var(--color-text);
        font-weight: var(--fw-700);
    }

    .loyalty-line a {
        color: var(--color-text-soft);
        text-decoration: underline;
    }

/* Basket total line used inside the drawer footer and on the
   order-summary panel. Label left, price right, big bold type. */
.basket-total {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--sp-3);
    font-size: var(--fs-body);
    color: var(--color-text-soft);
}

    .basket-total strong {
        font-size: var(--fs-xl);
        font-weight: var(--fw-800);
        color: var(--color-text);
        letter-spacing: -0.015em;
    }


/* ============================================================
   42. TRUST SIGNALS
   ------------------------------------------------------------
   Horizontal row of small reassurance items ("3m readers",
   "Instant Access", "Secure Checkout"). Usually sat in a focus
   nav on a conversion-critical page.
   ============================================================ */
.trust-signals {
    display: flex;
    align-items: center;
    gap: var(--sp-4);
    list-style: none;
    margin: 0;
    padding: 0;
    font-size: var(--fs-xs);
    color: var(--color-text-muted);
}

    .trust-signals li {
        display: inline-flex;
        align-items: center;
        gap: 6px;
        white-space: nowrap;
    }

    .trust-signals svg {
        width: 14px;
        height: 14px;
        stroke: currentColor;
        stroke-width: 1.8;
        fill: none;
    }

.trust-signals--centered {
    justify-content: center;
    margin-top: var(--sp-3);
}
/* Narrow viewports: keep the trust row single-line. At common phone
   widths (~375-414px) Cancel + 3m+ + Secure still fit with a
   smaller font/gap. Below ~400px drop "3m+ readers" so the two most
   trust-critical signals (Cancel + Secure) stay visible. */
@media (max-width: 560px) {
    .trust-signals {
        gap: var(--sp-3);
        flex-wrap: nowrap;
        font-size: 11.5px;
    }

        .trust-signals li {
            gap: 4px;
        }

        .trust-signals svg {
            width: 12px;
            height: 12px;
        }
}

@media (max-width: 400px) {
    .trust-signals {
        gap: 10px;
        font-size: 11px;
    }

        .trust-signals li:nth-child(2) {
            display: none;
        }
}


/* ============================================================
   43. PAYMENT OPTION
   ------------------------------------------------------------
   Radio-card selector for a payment method. Wraps a real radio
   input; the visual is the whole card. Add .is-selected or
   :checked+label CSS hooks for active state.
   ============================================================ */
.payment-option {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    padding: var(--sp-4);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: border-color .15s, background .15s, box-shadow .15s;
}

    .payment-option:hover {
        border-color: var(--color-text);
    }

.payment-option__radio {
    width: 18px;
    height: 18px;
    border-radius: 50%;
    border: 2px solid var(--color-border);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    background: var(--color-surface);
    transition: border-color .15s;
}

    .payment-option__radio::after {
        content: '';
        width: 8px;
        height: 8px;
        border-radius: 50%;
        background: var(--brand-500);
        transform: scale(0);
        transition: transform .15s;
    }

.payment-option__input {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

    .payment-option__input:checked ~ .payment-option__radio {
        border-color: var(--brand-500);
    }

        .payment-option__input:checked ~ .payment-option__radio::after {
            transform: scale(1);
        }

    .payment-option__input:checked ~ .payment-option__label {
        color: var(--color-text);
        font-weight: var(--fw-700);
    }

.payment-option:has(.payment-option__input:checked) {
    border-color: var(--brand-500);
    background: var(--brand-50);
    box-shadow: 0 0 0 1px var(--brand-500);
}

.payment-option__label {
    flex: 1;
    font-size: var(--fs-body);
    font-weight: var(--fw-600);
    color: var(--color-text-soft);
    display: flex;
    align-items: center;
    gap: var(--sp-2);
}

.payment-option__icons {
    display: flex;
    gap: 4px;
    align-items: center;
}


/* ============================================================
   44. BENEFIT LIST
   ------------------------------------------------------------
   Stacked list with a soft-filled icon circle per item. Used in
   Plus+ value panels, paywalls, onboarding moments.
   ============================================================ */
.benefit-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--sp-3);
}

.benefit-item {
    display: flex;
    align-items: flex-start;
    gap: var(--sp-3);
}

.benefit-item__icon {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--plus-100);
    color: var(--plus-700);
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

    .benefit-item__icon svg {
        width: 14px;
        height: 14px;
        stroke: currentColor;
        stroke-width: 2.4;
        fill: none;
    }

.benefit-item__body {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    padding-top: 3px;
}

    .benefit-item__body strong {
        font-size: var(--fs-sm);
        font-weight: var(--fw-700);
        color: var(--color-text);
        letter-spacing: -0.005em;
    }

    .benefit-item__body span {
        font-size: var(--fs-xs);
        color: var(--color-text-soft);
        line-height: 1.4;
    }


/* ============================================================
   45. PLUS SUMMARY (value panel)
   ------------------------------------------------------------
   Marketing aside for the Plus+ funnel - sits in the checkout
   right rail in place of .order-summary. Cream-plum gradient,
   cover stack, benefit list, trial pricing, rating.
   ============================================================ */
.plus-summary {
    color: var(--plus-paper, #F2EEE2);
    background-color: var(--plus-ink, #0F1425);
    background-image: radial-gradient(circle at 92% 6%, rgba(252,92,23,.12), transparent 55%), linear-gradient(160deg, var(--plus-ink, #0F1425) 0%, #181F36 100%);
    border: 1px solid rgba(242,238,226,.06);
    border-radius: var(--radius-lg);
    padding: var(--sp-5);
    box-shadow: 0 4px 14px rgba(0,0,0,.18);
    display: flex;
    flex-direction: column;
    gap: var(--sp-5);
}

.plus-summary__kicker {
    display: block;
    font-size: var(--fs-xs);
    font-weight: var(--fw-800);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--plus-accent);
    margin-bottom: var(--sp-2);
}

.plus-summary__title {
    font-size: var(--fs-xl);
    font-weight: var(--fw-800);
    letter-spacing: -0.02em;
    color: var(--plus-paper, #F2EEE2);
    line-height: 1.15;
}

    .plus-summary__title em {
        font-style: normal;
        color: var(--plus-accent);
    }

.plus-summary__pricing {
    padding: var(--sp-4);
    background: rgba(242,238,226,.06);
    border: 1px solid rgba(242,238,226,.12);
    border-radius: var(--radius-md);
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.plus-summary__price-now {
    display: flex;
    align-items: baseline;
    gap: var(--sp-2);
}

    .plus-summary__price-now strong {
        font-size: 42px;
        font-weight: var(--fw-800);
        color: var(--plus-paper, #F2EEE2);
        letter-spacing: -0.025em;
        line-height: 1;
    }

    .plus-summary__price-now span {
        font-size: var(--fs-body);
        color: rgba(242,238,226,.72);
        font-weight: var(--fw-500);
    }

.plus-summary__price-after {
    font-size: var(--fs-sm);
    color: rgba(242,238,226,.8);
}

    .plus-summary__price-after strong {
        color: var(--plus-accent);
        font-weight: var(--fw-700);
    }

.plus-summary__cancel {
    font-size: var(--fs-xs);
    color: rgba(242,238,226,.72);
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-top: 4px;
}

    .plus-summary__cancel svg {
        width: 12px;
        height: 12px;
        stroke: var(--plus-accent);
        stroke-width: 2.2;
        fill: none;
    }

.plus-summary__rating {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    padding-top: var(--sp-3);
    border-top: 1px solid rgba(242,238,226,.1);
    font-size: var(--fs-sm);
    color: rgba(242,238,226,.85);
}

.plus-summary__rating-stars {
    color: #E8A53D;
    font-size: var(--fs-lg);
    letter-spacing: 1px;
    line-height: 1;
}

.plus-summary__rating strong {
    color: var(--plus-paper, #F2EEE2);
    font-weight: var(--fw-700);
}

/* Benefit list inside a dark plus-summary: re-tint icons + text
   so they read cleanly against the navy background. */
.plus-summary .benefit-item__icon {
    background: rgba(252, 92, 23, 0.15);
    color: var(--plus-accent);
}

.plus-summary .benefit-item__body strong {
    color: var(--plus-paper, #F2EEE2);
}

.plus-summary .benefit-item__body span {
    color: rgba(242, 238, 226, 0.68);
}


/* ============================================================
   46. FAQ LIST
   ------------------------------------------------------------
   Accordion built on native <details>/<summary>. No JS needed -
   browsers handle expand/collapse. Custom chevron indicator.
   ============================================================ */
.faq-list {
    display: flex;
    flex-direction: column;
    gap: var(--sp-2);
}

.faq-item {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: 0;
    transition: border-color .15s;
}

    .faq-item[open] {
        border-color: var(--slate-400);
    }

    .faq-item summary {
        list-style: none;
        padding: var(--sp-4) var(--sp-4);
        font-size: var(--fs-sm);
        font-weight: var(--fw-700);
        color: var(--color-text);
        cursor: pointer;
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--sp-3);
    }

        .faq-item summary::-webkit-details-marker {
            display: none;
        }

        .faq-item summary::after {
            content: '';
            width: 9px;
            height: 9px;
            border-right: 2px solid var(--color-text-muted);
            border-bottom: 2px solid var(--color-text-muted);
            transform: rotate(45deg);
            transition: transform .2s;
            flex-shrink: 0;
            margin-top: -3px;
        }

    .faq-item[open] summary::after {
        transform: rotate(-135deg);
        margin-top: 3px;
    }

.faq-item__body {
    padding: 0 var(--sp-4) var(--sp-4);
    font-size: var(--fs-sm);
    color: var(--color-text-soft);
    line-height: 1.55;
}

    .faq-item__body p + p {
        margin-top: var(--sp-3);
    }


/* ============================================================
   47. COVER REEL
   ------------------------------------------------------------
   Dense brick-offset grid of cover tiles with a soft radial
   mask that fades the edges - communicates "600+ titles" far
   better than a single hero cover. Columns drift slowly to
   hint at more content beyond the frame (honours
   prefers-reduced-motion via the global reset).

     <div class="cover-reel" aria-hidden="true">
       <div class="cover-reel__col">...<img>...</div>
       <div class="cover-reel__col cover-reel__col--offset">…</div>
       <div class="cover-reel__col">…</div>
       <div class="cover-reel__col cover-reel__col--offset">…</div>
     </div>
   ============================================================ */
.cover-reel {
    position: relative;
    height: 300px;
    overflow: hidden;
    border-radius: var(--radius-md);
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 8px;
    padding: 0;
    /* Rectangular fade: strong top/bottom cut, lighter side fade.
     Dual linear gradients composited so each axis is independent. */
    -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 14%, #000 72%, transparent 100%), linear-gradient(to right, transparent 0%, #000 10%, #000 90%, transparent 100%);
    -webkit-mask-composite: source-in;
    mask-image: linear-gradient(to bottom, transparent 0%, #000 14%, #000 72%, transparent 100%), linear-gradient(to right, transparent 0%, #000 10%, #000 90%, transparent 100%);
    mask-composite: intersect;
}

.cover-reel__col {
    display: flex;
    flex-direction: column;
    gap: 8px;
    animation: cover-reel-drift 28s linear infinite alternate;
    will-change: transform;
}

.cover-reel__col--offset {
    margin-top: 26px;
    animation-duration: 34s;
    animation-direction: alternate-reverse;
}

.cover-reel__col img {
    width: 100%;
    aspect-ratio: 3 / 4;
    object-fit: cover;
    display: block;
    border-radius: 3px;
    box-shadow: var(--cover-shadow-sm);
    background: var(--slate-200);
}

@keyframes cover-reel-drift {
    from {
        transform: translateY(0);
    }

    to {
        transform: translateY(-48px);
    }
}

/* Compact variant - shorter band for use beside a form */
.cover-reel--compact {
    height: 260px;
}

/* Three-column variant - fewer columns when the container is narrow */
.cover-reel--3col {
    grid-template-columns: repeat(3, 1fr);
}


/* ============================================================
   48. COVER CASCADE
   ------------------------------------------------------------
   Full-width brick-offset band that sits between main content
   and the footer, like a cascade of covers falling into the
   footer. Wider + shorter than .cover-reel, with a fade top
   and bottom so it dissolves into whatever's above/below.
   ============================================================ */
.cover-cascade {
    width: 100%;
    height: 280px;
    overflow: hidden;
    display: grid;
    grid-template-columns: repeat(10, minmax(0, 1fr));
    gap: 10px;
    padding: 0 var(--page-pad);
    margin-top: var(--sp-8);
    /* Top edge is hard - offset columns already give a naturally uneven
     top line. Only the bottom fades so the cascade falls into the footer. */
    -webkit-mask-image: linear-gradient(to bottom, #000 60%, transparent 100%);
    mask-image: linear-gradient(to bottom, #000 60%, transparent 100%);
}

.cover-cascade__col {
    display: flex;
    flex-direction: column;
    gap: 10px;
}
    /* Static offsets - no animation, so tops stay visible. Three steps
   (0 / 24px / 48px) rotated across columns give a richer, less
   metronomic staggered top line than a simple alternate. */
    .cover-cascade__col:nth-child(3n+2) {
        margin-top: 24px;
    }

    .cover-cascade__col:nth-child(3n+3) {
        margin-top: 48px;
    }

.cover-cascade__col--offset {
    margin-top: 36px;
}

.cover-cascade__col img {
    width: 100%;
    aspect-ratio: 3 / 4;
    object-fit: cover;
    display: block;
    border-radius: 4px;
    box-shadow: var(--cover-shadow-sm);
    background: var(--slate-200);
}

@media (max-width: 900px) {
    .cover-cascade {
        grid-template-columns: repeat(7, minmax(0, 1fr));
        height: 240px;
    }
}

@media (max-width: 560px) {
    .cover-cascade {
        grid-template-columns: repeat(5, minmax(0, 1fr));
        height: 200px;
    }
}


/* ============================================================
   49. OFFER STEP (numbered)
   ------------------------------------------------------------
   Small step marker - numbered circle + title - used above
   selectors on product pages and forms.
   ============================================================ */
.offer-step {
    display: flex;
    flex-direction: column;
    gap: var(--sp-3);
}

.offer-step__head {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    flex-wrap: wrap;
}

.offer-step__num {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--color-text);
    color: #fff;
    font-size: var(--fs-xs);
    font-weight: var(--fw-800);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.offer-step__title {
    font-size: var(--fs-lg);
    font-weight: var(--fw-800);
    letter-spacing: -0.015em;
    color: var(--color-text);
    margin: 0;
}

.offer-step__aside {
    margin-left: auto;
    font-size: var(--fs-sm);
    color: var(--color-text-muted);
}


/* ============================================================
   50. INSTANT BADGE
   ------------------------------------------------------------
   Lightning + label chip - signals immediate digital access.
   ============================================================ */
.instant-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: var(--fs-xs);
    font-weight: var(--fw-700);
    color: var(--teal-700);
}

    .instant-badge svg {
        width: 12px;
        height: 12px;
        fill: currentColor;
        stroke: none;
    }


/* ============================================================
   51. OFFER LIST / OFFER OPTION
   ------------------------------------------------------------
   Radio-card selector - big, clickable, with an embedded
   native radio input for keyboard + screen-reader support.
   Stack vertically by default; use --row for 2-across format
   choices. --plus modifier lights the card up in the Plus+
   dark brand treatment.

     <ul class="offer-list">
       <li>
         <label class="offer-option">
           <input class="offer-option__input" type="radio" name="offer">
           <span class="offer-option__radio"></span>
           <div class="offer-option__body">
             <div class="offer-option__title">…<span class="offer-option__badge">Save 58%</span></div>
             <div class="offer-option__meta">…</div>
           </div>
           <div class="offer-option__price"><strong>£84.99</strong><span>£1.67 / issue</span></div>
         </label>
       </li>
     </ul>
   ============================================================ */
.offer-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--sp-3);
}

.offer-list--row {
    flex-direction: row;
}

    .offer-list--row > li {
        flex: 1;
    }

.offer-option {
    position: relative;
    display: grid;
    grid-template-columns: auto 1fr auto;
    gap: var(--sp-4);
    align-items: center;
    padding: var(--sp-4) var(--sp-5);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: border-color .15s, background .15s, box-shadow .15s;
}

    .offer-option:hover {
        border-color: var(--color-text);
    }

.offer-option__input {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.offer-option__radio {
    width: 20px;
    height: 20px;
    border-radius: 50%;
    border: 2px solid var(--color-border);
    background: var(--color-surface);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    transition: border-color .15s;
}

    .offer-option__radio::after {
        content: '';
        width: 10px;
        height: 10px;
        border-radius: 50%;
        background: var(--brand-500);
        transform: scale(0);
        transition: transform .15s;
    }

.offer-option__input:checked ~ .offer-option__radio {
    border-color: var(--brand-500);
}

    .offer-option__input:checked ~ .offer-option__radio::after {
        transform: scale(1);
    }

.offer-option:has(.offer-option__input:checked) {
    border-color: var(--brand-500);
    background: var(--brand-50);
    box-shadow: 0 0 0 1px var(--brand-500);
}

.offer-option__input:focus-visible ~ .offer-option__radio {
    outline: 2px solid var(--brand-500);
    outline-offset: 2px;
}

.offer-option__body {
    min-width: 0;
}

.offer-option__title {
    font-size: var(--fs-body);
    font-weight: var(--fw-800);
    letter-spacing: -0.01em;
    color: var(--color-text);
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    flex-wrap: wrap;
}

.offer-option__badge {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    background: var(--teal-100);
    color: var(--teal-700);
    font-size: 10px;
    font-weight: var(--fw-800);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    border-radius: var(--radius-full);
}

/* Plus+ brand-gradient badge - navy fading to the Plus+ orange
   accent. Use for "Best value" on Plus+ offers to give them a
   distinct endorsement without dominating the card. */
.offer-option__badge--plus {
    color: var(--plus-paper, #F2EEE2);
    background: linear-gradient(100deg, var(--plus-ink, #0F1425) 0%, #3A1E12 60%, var(--plus-accent) 115%);
}

.offer-option__meta {
    font-size: var(--fs-sm);
    color: var(--color-text-soft);
    margin-top: 2px;
    line-height: 1.4;
}

.offer-option__price {
    text-align: right;
    white-space: nowrap;
}

    .offer-option__price strong {
        display: block;
        font-size: var(--fs-xl);
        font-weight: var(--fw-800);
        color: var(--color-text);
        letter-spacing: -0.02em;
        line-height: 1.1;
    }

    .offer-option__price span {
        font-size: var(--fs-xs);
        color: var(--color-text-muted);
    }

.offer-option__strike {
    font-size: var(--fs-xs);
    text-decoration: line-through;
    color: var(--color-text-muted);
    margin-right: 4px;
}


/* ============================================================
   52. HERO PRICE SUMMARY
   ------------------------------------------------------------
   Single-line price call-out on product pages ("From £1.67 per
   issue"). Sits between the meta row and the description.
   ============================================================ */
.hero-price-summary {
    font-size: var(--fs-lg);
    font-weight: var(--fw-700);
    color: var(--brand-600);
    letter-spacing: -0.01em;
    margin: var(--sp-3) 0 var(--sp-2);
}

    .hero-price-summary strong {
        font-size: var(--fs-xl);
        font-weight: var(--fw-800);
        color: var(--brand-600);
    }



/* ============================================================
   POCKETMAGS · ACTIVATE PAGE
   ------------------------------------------------------------
   Task-focused activation flow. Product-page-style layout:
   cover stack on the left, stepper + form on the right.
   Minimal nav (see .nav-focus in pocketmags.css) removes the
   usual search / basket / categories noise so the user stays
   on task.

   Load order: pocketmags.css, activate.css.
   ============================================================ */

body {
    background: #fff;
}

.activate-layout {
    max-width: 640px;
    margin: 0 auto;
    padding: var(--sp-8) var(--page-pad) var(--sp-9);
    display: flex;
    flex-direction: column;
    gap: var(--sp-6);
}

/* ------------------------------- LEFT: cover stack + titles */
.activate-aside {
    position: sticky;
    top: var(--sp-6);
    display: flex;
    flex-direction: column;
    gap: var(--sp-5);
}

.activate-aside__stack {
    max-width: 220px;
    margin: 0 auto;
    width: 100%;
}

.activate-aside__kicker {
    display: block;
    text-align: center;
    font-size: var(--fs-xs);
    font-weight: var(--fw-800);
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--color-text-muted);
}

.activate-aside__publisher {
    text-align: center;
    font-size: var(--fs-lg);
    font-weight: var(--fw-800);
    letter-spacing: -0.015em;
    color: var(--color-text);
    margin-top: 2px;
}

.activate-aside__summary {
    text-align: center;
    font-size: var(--fs-sm);
    color: var(--color-text-soft);
    margin-top: -6px;
}

.activate-aside__titles {
    list-style: none;
    padding: var(--sp-4);
    margin: 0;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    display: flex;
    flex-direction: column;
    gap: var(--sp-2);
}

    .activate-aside__titles li {
        display: flex;
        align-items: center;
        gap: var(--sp-2);
        font-size: var(--fs-sm);
        color: var(--color-text);
    }

        .activate-aside__titles li::before {
            content: '';
            width: 6px;
            height: 6px;
            border-radius: 50%;
            background: var(--plus-500);
            flex-shrink: 0;
        }

/* ------------------------------- RIGHT: stepper + form */
.activate-main {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: var(--sp-6);
}

.activate-main__lead {
    margin-bottom: var(--sp-2);
}

.activate-main__kicker {
    display: block;
    font-size: var(--fs-xs);
    font-weight: var(--fw-800);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--color-text-muted);
    margin-bottom: var(--sp-2);
}

.activate-main__lead h1 {
    font-size: clamp(30px, 3.6vw, 40px);
    font-weight: var(--fw-800);
    letter-spacing: -0.03em;
    line-height: 1.05;
    color: var(--color-text);
    margin-bottom: var(--sp-3);
}

.activate-main__lead p {
    font-size: var(--fs-lg);
    color: var(--color-text-soft);
    max-width: 520px;
    line-height: 1.5;
}

/* Form card */
.activate-form {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: var(--sp-6);
    box-shadow: var(--shadow-sm);
    display: flex;
    flex-direction: column;
    gap: var(--sp-5);
}

.activate-form__submit {
    margin-top: var(--sp-2);
}

.activate-help {
    font-size: var(--fs-sm);
    color: var(--color-text-muted);
    padding: var(--sp-4) var(--sp-5);
    background: var(--color-surface);
    border: 1px dashed var(--color-border);
    border-radius: var(--radius-md);
}
.diverrorbox {
    font-size: var(--fs-sm);
    color: var(--color-text-muted);
    padding: var(--sp-4) var(--sp-5);
    background: var(--color-surface);
    border: 1px dashed red;
    border-radius: var(--radius-md);
}


    .activate-help strong {
        color: var(--color-text);
        font-weight: var(--fw-700);
    }

    .activate-help a {
        color: var(--brand-600);
        font-weight: var(--fw-600);
    }

        .activate-help a:hover {
            color: var(--brand-700);
        }

/* ------------------------------- RESPONSIVE */
@media (max-width: 820px) {
    .activate-layout {
        grid-template-columns: 1fr;
        gap: var(--sp-6);
    }

    .activate-aside {
        position: static;
        flex-direction: row;
        align-items: center;
        gap: var(--sp-4);
        justify-content: center;
        text-align: left;
    }

    .activate-aside__stack {
        max-width: 120px;
        margin: 0;
    }

    .activate-aside__kicker,
    .activate-aside__publisher,
    .activate-aside__summary {
        text-align: left;
    }

    .activate-aside__titles {
        display: none;
    }
}

@media (max-width: 480px) {
    .activate-layout {
        padding: var(--sp-6) var(--page-pad) var(--sp-7);
    }

    .activate-form {
        padding: var(--sp-4);
    }

    .stepper {
        font-size: var(--fs-xs);
    }

    .stepper__step + .stepper__step::before {
        width: 20px;
    }
}


/* ── Cover mosaic (fixed background) ── */
.av2-mosaic {
    position: fixed;
    top: -80px;
    left: -40px;
    right: -40px;
    bottom: 0;
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 8px;
    transform: rotate(-4deg);
    transform-origin: center center;
    z-index: 0;
    pointer-events: none;
}

    .av2-mosaic img {
        width: 100%;
        aspect-ratio: 3/4;
        object-fit: cover;
        border-radius: 4px;
    }

/* ── White semi-opaque layer over mosaic ── */
.av2-overlay {
    position: fixed;
    inset: 0;
    background: rgba(255,255,255,0.84);
    z-index: 1;
    pointer-events: none;
}

/* ── Stacking: page chrome above the overlay ── */
.nav-focus {
    position: relative;
    z-index: 10;
    background: #fff;
    box-shadow: 0 1px 0 rgba(0,0,0,0.08);
}

body {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

main.activate-layout {
    position: relative;
    z-index: 2;
    max-width: none;
    margin: 0;
    padding: var(--sp-8) var(--page-pad) 80px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0;
    flex: 1;
}

.activate-band {
    position: relative;
    z-index: 2;
}

.footer {
    position: relative;
    z-index: 2;
    background: #fff;
    width: 100%;
    max-width: none;
    margin: 0;
}

.footer-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 24px;
    font-size: 13px;
    color: var(--color-text-muted, #888);
    gap: 16px;
    flex-wrap: wrap;
}

    .footer-bar .footer-brand {
        font-weight: 700;
        color: var(--color-text, #1a1a1a);
        font-size: 15px;
    }

        .footer-bar .footer-brand span {
            color: var(--brand-600, #e84a0e);
        }

.footer-proto {
    font-size: 12px;
    color: #bbb;
    display: flex;
    align-items: center;
    gap: 8px;
}

    .footer-proto button {
        font-size: 12px;
        padding: 3px 8px;
        border: 1px solid #ddd;
        border-radius: 4px;
        background: #f9f9f9;
        cursor: pointer;
        color: #999;
    }

/* ── White content panel ── */
.av2-panel {
    width: 100%;
    max-width: 620px;
    background: #fff;
    border-radius: 20px;
    box-shadow: 0 4px 64px rgba(0,0,0,0.13);
    padding: 48px;
}

    .av2-panel .activate-main {
        gap: var(--sp-5);
    }

/* ── Nav brand group ── */
.nav-focus__logo {
    height: 28px;
    width: auto;
    display: block;
}

.nav-focus__brand-group {
    display: flex;
    align-items: center;
    gap: 10px;
}

.nav-focus__x {
    font-size: 16px;
    color: #bbb;
    line-height: 1;
}

.nav-focus__publisher {
    display: flex;
    align-items: center;
}

    .nav-focus__publisher img {
        height: 26px;
        width: auto;
        object-fit: contain;
    }

    .nav-focus__publisher strong {
        font-size: 15px;
        font-weight: 700;
        color: var(--color-text, #1a1a1a);
    }

/* ── Full-width cover band ── */
.activate-band {
    height: 130px;
    overflow: hidden;
    background: transparent;
}

.activate-band__inner {
    display: flex;
    align-items: flex-start;
    gap: 5px;
    padding: 0 12px;
    height: 100%;
}

    .activate-band__inner img {
        width: 185px;
        flex-shrink: 0;
        aspect-ratio: 3/4;
        object-fit: cover;
        border-radius: 4px;
        box-shadow: 0 4px 16px rgba(0,0,0,0.20);
        transform: rotate(8deg);
        transform-origin: top left;
    }

.activate-band::before {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(to top, #fff 0%, transparent 40%);
    pointer-events: none;
    z-index: 1;
}

/* ── Mobile ── */
@media (max-width: 640px) {
    .av2-mosaic,
    .av2-overlay {
        display: none;
    }

    main.activate-layout {
        padding: 0;
        align-items: stretch;
    }

    .av2-panel {
        border-radius: 0;
        padding: var(--sp-6) var(--page-pad);
        box-shadow: none;
        max-width: none;
        width: 100%;
    }

    .activate-band {
        height: calc(25vw * 1.334 + 24px);
    }

    .activate-band__inner {
        gap: 4px;
        padding: 0;
    }

        .activate-band__inner img {
            width: calc(25% - 3px);
            flex-shrink: 0;
            transform: none;
            border-radius: 3px;
        }

    .activate-band::before {
        background: linear-gradient(to top, #fff 0%, transparent 40%);
    }
}

/* ── Prototype toggle ── */
.activate-proto-toggle {
    margin-top: 32px;
    padding-top: 16px;
    border-top: 1px dashed #ddd;
    font-size: 12px;
    color: #999;
    display: flex;
    align-items: center;
    gap: 10px;
}

    .activate-proto-toggle button {
        font-size: 12px;
        padding: 4px 10px;
        border: 1px solid #ccc;
        border-radius: 4px;
        background: #f5f5f5;
        cursor: pointer;
    }

/* ── Multi-step form steps ── */
.aform__step {
    display: none;
}

    .aform__step.is-active {
        display: flex;
        flex-direction: column;
        gap: var(--sp-5, 20px);
    }

/* ── Email display (read-only) ── */
.aform__email-display {
    font-size: var(--fs-base, 15px);
    font-weight: 600;
    color: var(--color-text, #1a1a1a);
    padding: 10px 14px;
    background: var(--color-surface, #f5f5f5);
    border: 1px solid var(--color-border, #e0e0e0);
    border-radius: var(--radius-sm, 6px);
    margin-bottom: 4px;
    word-break: break-all;
}

/* ── Opt-in text ── */
.aform__optin {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    font-size: 12px;
    color: var(--color-text-muted, #888);
    line-height: 1.5;
}

    .aform__optin input[type="checkbox"] {
        margin-top: 2px;
        flex-shrink: 0;
    }

/* ── Reset flow link ── */
.aform__reset {
    display: block;
    text-align: center;
    font-size: var(--fs-sm, 13px);
    color: var(--color-text-muted, #888);
    margin-top: var(--sp-2, 8px);
}

    .aform__reset a {
        color: var(--brand-600, #e84a0e);
        font-weight: 600;
        text-decoration: none;
    }

        .aform__reset a:hover {
            text-decoration: underline;
        }

/* ── Forgot password ── */
.aform__forgot {
    display: block;
    font-size: var(--fs-sm, 13px);
    color: var(--brand-600, #e84a0e);
    font-weight: 600;
    text-decoration: none;
    margin-top: 6px;
}

    .aform__forgot:hover {
        text-decoration: underline;
    }

/* ── Spinner ── */
.aform__btn {
    position: relative;
}

.aform__btn-text {
    transition: opacity 0.15s;
}

.aform__btn.is-loading .aform__btn-text {
    opacity: 0;
}

.aform__spinner {
    display: none;
    position: absolute;
    top: 50%;
    left: 50%;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    border: 2px solid rgba(255,255,255,0.35);
    border-top-color: #fff;
    animation: afspin 0.7s linear infinite;
    transform: translate(-50%, -50%);
}

.aform__btn.is-loading .aform__spinner {
    display: block;
}

@keyframes afspin {
    to {
        transform: translate(-50%, -50%) rotate(360deg);
    }
}

.success-cover {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    margin: 8px 0;
}