/* ═══════════════════════════════════════════════════════════════════════
   DALFAST Marketplace — Design system
   Concept: a modern knowledge library. Clean white, deep navy structure,
   gold growth accents. Stripe-level clarity, premium rounded cards,
   mobile-first throughout.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Fonts (self-hosted) ─────────────────────────────────────────────── */
@font-face {
    font-family: 'Fraunces';
    src: url('../fonts/fraunces-var-latin.woff2') format('woff2');
    font-weight: 300 700;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Archivo';
    src: url('../fonts/archivo-var-latin.woff2') format('woff2');
    font-weight: 400 700;
    font-style: normal;
    font-display: swap;
}

/* ── Tokens ──────────────────────────────────────────────────────────── */
:root {
    --paper: #FFFFFF;        /* page background */
    --paper-deep: #F5F7FA;   /* soft grey alt sections */
    --white: #FFFFFF;        /* card surfaces */
    --ink: #14202E;          /* primary text */
    --ink-soft: #5B6B7E;     /* secondary text */
    --line: #E3E8EF;         /* hairlines */
    --navy: #0B1F3B;         /* brand primary */
    --navy-2: #143462;       /* hover / secondary navy */
    /* Gold for text on light grounds. Was #A87F1F, which measured 3.67:1 on
       white — below the 4.5:1 AA needs for normal text, despite the comment
       here claiming otherwise. Every gold link, breadcrumb, tick and price
       label on a light background reads through this token, so the shortfall
       was sitewide. #8D6A19 measures 4.99:1 and is a shade deeper, not a
       different colour. --gold stays as it was for fills and for dark grounds,
       where it is already well clear. */
    --brass: #8D6A19;        /* gold for text on light — 4.99:1 on white */
    --brass-deep: #8A6819;   /* gold hover */
    --brass-pale: #F3E7C9;   /* gold tint backgrounds */
    --gold: #C99B2E;         /* gold fills (with dark text) */
    --orange: #E8913A;       /* growth accent */
    --wood: var(--navy);     /* legacy alias: card image borders */
    --error: #A2372E;
    --error-bg: #FBEDEB;
    --sale: #A2372E;         /* discount badges + on-sale pricing accent */
    --success: #2E6B45;
    --success-bg: #E9F4EE;

    --font-display: 'Fraunces', Georgia, serif;
    --font-ui: 'Archivo', system-ui, sans-serif;

    --wrap: 74rem;
    --gutter: clamp(1.1rem, 4vw, 2.5rem);
    --radius: 14px;
    --radius-sm: 8px;

    --shadow-frame: 0 10px 30px -18px rgba(11, 31, 59, .25);
    --shadow-frame-hover: 0 22px 44px -20px rgba(11, 31, 59, .32);
    --focus-ring: 2px solid var(--navy-2);
}

/* ── Reset & base ────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
    margin: 0;
    background: var(--paper);
    color: var(--ink);
    font-family: var(--font-ui);
    font-size: 1rem;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; height: auto; display: block; }
a { color: inherit; }
button { font: inherit; cursor: pointer; }
input, select, textarea { font: inherit; color: inherit; }
:focus-visible { outline: var(--focus-ring); outline-offset: 2px; }

h1, h2, h3, h4 {
    font-family: var(--font-display);
    font-weight: 460;
    line-height: 1.12;
    margin: 0 0 .5em;
    letter-spacing: -0.01em;
    text-wrap: balance;
    color: var(--navy);
}
h1 { font-size: clamp(2.2rem, 5.2vw, 3.7rem); font-variation-settings: 'opsz' 100; }
h2 { font-size: clamp(1.7rem, 3.4vw, 2.4rem); font-variation-settings: 'opsz' 60; }
h3 { font-size: clamp(1.2rem, 2vw, 1.45rem); }
h4 { font-size: 1.05rem; }
p { margin: 0 0 1em; }

.wrap { max-width: var(--wrap); margin-inline: auto; padding-inline: var(--gutter); }

.eyebrow {
    display: inline-block;
    font-family: var(--font-ui);
    font-size: .7rem;
    font-weight: 700;
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--brass);
    margin-bottom: .9rem;
}
.section { padding-block: clamp(3.2rem, 8vw, 5.5rem); }
.section-alt { background: var(--paper-deep); }
.section-head { max-width: 38rem; margin-bottom: clamp(1.8rem, 4vw, 3rem); }
.section-head--split {
    max-width: none;
    display: flex; align-items: flex-end; justify-content: space-between; gap: 1.5rem; flex-wrap: wrap;
}
.section-head p { color: var(--ink-soft); }

.muted { color: var(--ink-soft); }
.small { font-size: .875rem; }
.center { text-align: center; }

/* ── Buttons ─────────────────────────────────────────────────────────── */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
    padding: .8rem 1.6rem;
    background: var(--navy); color: #fff;
    border: 1px solid var(--navy); border-radius: 10px;
    font-family: var(--font-ui); font-weight: 600; font-size: .92rem;
    letter-spacing: .02em; text-decoration: none;
    transition: background .18s ease, border-color .18s ease, color .18s ease, transform .18s ease, box-shadow .18s ease;
}
.btn:hover { background: var(--navy-2); border-color: var(--navy-2); color: #fff; box-shadow: 0 8px 18px -10px rgba(11,31,59,.5); }
.btn:active { transform: translateY(1px); }
.btn-brass { background: var(--gold); border-color: var(--gold); color: var(--navy); }
.btn-brass:hover { background: var(--orange); border-color: var(--orange); color: var(--navy); }
.btn-ghost { background: transparent; color: var(--navy); border-color: var(--navy); }
.btn-ghost:hover { background: var(--navy); color: #fff; }
.btn-quiet { background: transparent; border-color: var(--line); color: var(--ink-soft); font-weight: 500; }
.btn-quiet:hover { border-color: var(--navy); color: var(--navy); background: transparent; box-shadow: none; }
.btn-block { width: 100%; }
.btn-lg { padding: 1rem 2.1rem; font-size: 1rem; }
.btn-small { padding: .45rem .95rem; font-size: .82rem; }
.btn[disabled] { opacity: .5; cursor: not-allowed; }

/* The inline gold link, used in some thirty templates.
 *
 * It was a solid bottom border that changed colour on hover — the browser
 * default with a different palette. It now rests on a hairline and DRAWS a
 * second, heavier line across itself from the left, which is the detail that
 * separates a considered link from a styled one.
 *
 * Two gradients rather than a border, because a border cannot be animated
 * along its length: the lower layer is the resting rule and never moves, the
 * upper is the one that draws. Using currentColor for the drawn line means
 * this works unchanged on the dark sections, where the link is a lighter gold.
 *
 * The underline sits on the text's own baseline box rather than the element
 * edge, so it tracks the text instead of floating beneath a padded link. */
.text-link {
    color: var(--brass);
    font-weight: 600;
    text-decoration: none;
    padding-bottom: 2px;
    background-image:
        linear-gradient(currentColor, currentColor),
        linear-gradient(var(--brass-pale), var(--brass-pale));
    background-size: 0 1.5px, 100% 1px;
    background-position: 0 100%, 0 100%;
    background-repeat: no-repeat;
    transition: background-size .34s cubic-bezier(.22, .7, .28, 1), color .18s ease;
}
.text-link:hover,
.text-link:focus-visible {
    background-size: 100% 1.5px, 100% 1px;
    color: var(--gold);
}
/* Somebody who has asked for less motion gets the underline without the sweep. */
@media (prefers-reduced-motion: reduce) {
    .text-link { transition: none; }
    .text-link:hover, .text-link:focus-visible { background-size: 100% 1.5px, 100% 1px; }
}

/* On the dark sections the pale-gold resting rule disappears into the navy, so
   the lower layer is restated at an opacity that reads against it. */
.hero .text-link,
.editors-pick .text-link,
.admin-layout .admin-side .text-link {
    color: var(--gold);
    background-image:
        linear-gradient(currentColor, currentColor),
        linear-gradient(rgba(201, 155, 46, .38), rgba(201, 155, 46, .38));
}
.hero .text-link:hover,
.editors-pick .text-link:hover { color: #E8CD91; }

/* ── Product cover (signature element) ───────────────────────────────── */
/* The approved book images are shadow-free photographs on pure white. The card
   must not put a shadow back underneath them — a drop shadow on the frame reads
   as a shadow cast by the book. Border only, no shadow, pure white ground. */
.frame {
    position: relative;
    background: #FFFFFF;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: clamp(6px, 4%, 12px);
    transition: transform .25s ease, border-color .25s ease;
    overflow: hidden;
}
/* Catalogue card cover.
   `cover` cropped every mockup to fill a 4:5 box, slicing the title and author
   off the taller covers — a book you cannot read the title of does not sell.
   `contain` on a light ground keeps the whole cover visible at thumbnail size
   and lets covers of different proportions sit together tidily. */
.frame img {
    width: 100%;
    aspect-ratio: 4 / 5;
    object-fit: contain;
    border-radius: calc(var(--radius) - 6px);
    background: var(--paper, #F7F4ED);
}
.frame--brass { border-color: var(--gold); box-shadow: 0 10px 30px -18px rgba(201, 155, 46, .45); }
.frame--square img { aspect-ratio: 1 / 1; }
.frame--landscape img { aspect-ratio: 5 / 4; }

/* ── Product card ────────────────────────────────────────────────────── */
.grid-products {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(15.5rem, 1fr));
    gap: clamp(1.4rem, 3vw, 2.4rem);
}
@media (max-width: 560px) {
    .grid-products { grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr)); gap: 1rem; }
}
.card-product-wrap { position: relative; }
.card-product { position: relative; text-decoration: none; display: block; }
.card-product:hover .frame,
.card-product:focus-visible .frame { transform: translateY(-4px); border-color: var(--gold); }
.wish-form { position: absolute; top: .7rem; right: .7rem; z-index: 3; margin: 0; }
[dir="rtl"] .wish-form { right: auto; left: .7rem; }
.wish-toggle {
    width: 2.1rem; height: 2.1rem; border-radius: 50%; border: 0;
    background: rgba(255, 255, 255, .92); color: var(--ink-soft);
    display: flex; align-items: center; justify-content: center; cursor: pointer;
    box-shadow: 0 3px 10px -3px rgba(11, 31, 59, .35);
    transition: color .15s, transform .15s;
}
.wish-toggle svg { width: 1.05rem; height: 1.05rem; }
.wish-toggle:hover { transform: scale(1.08); color: var(--sale); }
.wish-toggle.is-active { color: var(--sale); }
.wish-btn.is-active { color: var(--sale); border-color: var(--sale); }
.placard { margin: .95rem auto 0; text-align: center; }
.placard .placard-title {
    font-family: var(--font-display);
    font-size: 1.08rem; font-weight: 500; line-height: 1.25;
    margin: 0 0 .15rem; color: var(--navy);
}
.placard .placard-medium {
    font-size: .7rem; font-weight: 600; letter-spacing: .14em; text-transform: uppercase;
    color: var(--ink-soft); margin: 0 0 .35rem;
}
.placard .placard-price { font-weight: 700; font-size: .95rem; color: var(--ink); }
.placard .placard-price s { color: var(--ink-soft); font-weight: 400; margin-left: .45rem; }

/* Badges */
.badge {
    position: absolute; top: .8rem; left: .8rem; z-index: 2;
    background: var(--navy); color: #fff;
    font-size: .64rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
    padding: .34rem .62rem; border-radius: 99px;
}
.badge-brass, .badge-bestseller { background: var(--gold); color: var(--navy); }
.badge-new { background: #fff; color: var(--navy); border: 1px solid var(--navy); }
.badge-bundle { background: var(--orange); color: var(--navy); }
.badge-sale { background: var(--sale); color: #fff; }
/* Free ebooks: a distinct, positive signal — deliberately not the sale red
   (nothing is discounted) and not the gold bestseller chip (not a ranking). */
.badge-free { background: var(--success); color: #fff; }
.placard-price.is-free, .price-now.is-free { color: var(--success); }
[dir="rtl"] .badge { left: auto; right: .8rem; }

.chip {
    display: inline-block; padding: .32rem .8rem;
    border: 1px solid var(--line); border-radius: 99px;
    font-size: .78rem; font-weight: 600; color: var(--ink-soft);
    text-decoration: none; background: var(--white);
    transition: border-color .15s, color .15s, background .15s;
}
.chip:hover, .chip.is-active { border-color: var(--navy); color: var(--navy); background: var(--paper-deep); }

/* ── Header ──────────────────────────────────────────────────────────── */
.topline {
    background: var(--navy); color: #E7EDF6;
    font-size: .78rem; text-align: center; padding: .5rem var(--gutter);
    letter-spacing: .04em;
}
.topline strong { color: var(--gold); font-weight: 700; }
.site-header {
    position: sticky; top: 0; z-index: 50;
    background: rgba(255, 255, 255, .92);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--line);
}
.header-bar {
    display: flex; align-items: center; gap: 1.2rem;
    padding-block: .85rem;
}
.logo {
    font-family: var(--font-display); font-weight: 600; font-size: 1.38rem;
    letter-spacing: .01em; text-decoration: none; line-height: 1; white-space: nowrap;
    color: var(--navy);
    /* The wordmark never compresses. As a flex item it was being shrunk ~23px
       below the width of its own text at every desktop size; because the text
       is nowrap it did not wrap or clip, it simply overflowed the box and ran
       into "Books" in the nav. Holding its intrinsic width is what restores the
       gap — the header has room for it. */
    flex-shrink: 0;
}
.logo .logo-art { color: var(--brass); font-weight: 460; }
.logo .logo-mark {
    display: inline-block; width: 1.05em; height: 1.05em;
    margin-right: .45rem; vertical-align: -0.18em;
}
[dir="rtl"] .logo .logo-mark { margin-right: 0; margin-left: .45rem; }
/* ── Primary navigation ─────────────────────────────────────────────────────
   Books · Categories · Collections · New Releases · Bundles · About.

   Navy type, generous spacing, one gold rule for the active item. No
   promotional colour anywhere: Special Offers used to sit here in red, which
   made a publishing house read as a shop running a sale. It now lives inside
   Books, and only while an offer is actually running. */
.nav-main { display: flex; gap: 1.6rem; margin-inline: auto; align-items: center; }
.nav-main > a, .nav-dropdown > summary {
    text-decoration: none; font-size: .9rem; font-weight: 600; color: var(--navy);
    letter-spacing: .008em;
    padding: .32rem 0; border-bottom: 2px solid transparent;
    transition: color .15s, border-color .15s;
    white-space: nowrap; flex-shrink: 0;
}
.nav-main > a:hover, .nav-main > a.is-active { color: var(--navy); border-bottom-color: var(--gold); }

/* Disclosure widgets, as elsewhere in the header: no JS, and keyboard and
   mobile behaviour come for free. main.js adds coordination on top — only one
   panel open at a time — without which the markup still works.

   The open animation is 110ms and 3px. Anything slower on a masthead makes the
   whole site feel sluggish, because this is the control people use most. */
@keyframes headerPanelIn {
    from { opacity: 0; transform: translateY(-3px); }
    to   { opacity: 1; transform: none; }
}
.nav-dropdown-panel, .account-panel, .locale-panel, .search-panel {
    animation: headerPanelIn .11s ease-out;
}
/* The mega panel is centred by a transform, so an animation that also sets
   transform would fight it — fade only. */
.nav-mega-panel { animation: none; }
.nav-mega[open] .nav-mega-panel { animation: megaPanelIn .11s ease-out; }
@keyframes megaPanelIn { from { opacity: 0; } to { opacity: 1; } }

.nav-dropdown { position: relative; }
.nav-dropdown summary {
    list-style: none; cursor: pointer;
    display: inline-flex; align-items: center; gap: .3rem;
}
.nav-dropdown summary::after {
    content: ''; width: .55rem; height: .55rem; flex-shrink: 0;
    background: currentColor;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") center / contain no-repeat;
    transition: transform .15s;
}
.nav-dropdown[open] summary::after { transform: rotate(180deg); }
.nav-dropdown summary::-webkit-details-marker { display: none; }
.nav-dropdown summary:hover, .nav-dropdown summary.is-active, .nav-dropdown[open] summary { color: var(--navy); border-bottom-color: var(--gold); }
.nav-dropdown-panel {
    position: absolute; top: calc(100% + .75rem); left: 0; z-index: 70;
    background: var(--white); border: 1px solid var(--line);
    /* Squarer than the rest of the UI on purpose: heavily rounded panels read
       as a SaaS product, not a publisher's imprint. */
    border-radius: 3px;
    box-shadow: 0 1px 2px rgba(11,31,59,.05), 0 22px 48px -20px rgba(11,31,59,.28);
    padding: .55rem;
    display: flex; flex-direction: column;
}
/* A hairline of DALFAST gold along the top edge — the only accent the panel
   gets, and it ties the open menu back to the active-item rule. */
.nav-dropdown-panel::before {
    content: ''; position: absolute; inset: -1px 0 auto 0; height: 2px;
    background: var(--gold); border-radius: 3px 3px 0 0;
}

/* Books panel: label over a one-line description, so each entry says what it
   leads to rather than making the reader guess from a noun. */
.nav-panel-books { width: 19.5rem; }
.nav-item {
    display: block; padding: .55rem .7rem; border-radius: 2px;
    text-decoration: none; border-bottom: 0;
    transition: background .15s;
}
.nav-item:hover, .nav-item:focus-visible { background: var(--paper-deep); }
.nav-item-label {
    display: block; font-size: .88rem; font-weight: 600; color: var(--navy); line-height: 1.35;
}
.nav-divider {
    display: block; height: 1px; background: var(--line);
    margin: .45rem .7rem;
}

/* Categories mega-menu. Anchored to the header rather than the summary so the
   panel can be wider than its trigger without hanging off the page. */
.nav-mega { position: static; }
.nav-mega-panel {
    left: 50%; transform: translateX(-50%);
    width: min(58rem, calc(100vw - 3rem));
    padding: 1.5rem 1.6rem 1.1rem;
}
.nav-mega-grid {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    gap: 1.4rem 1.8rem;
}
a.nav-mega-heading {
    display: block; margin: 0 0 .6rem; padding-bottom: .5rem;
    border-bottom: 1px solid var(--line);
    font-family: var(--font-display);
    font-size: .7rem; font-weight: 600; letter-spacing: .12em; text-transform: uppercase;
    color: var(--ink-soft); text-decoration: none;
}
a.nav-mega-heading:hover { color: var(--brass-deep); border-bottom-color: var(--gold); }
.nav-mega-col a {
    display: block; padding: .3rem 0;
    font-size: .86rem; font-weight: 500; color: var(--navy); text-decoration: none;
    border-bottom: 0; transition: color .15s;
}
.nav-mega-col a:hover { color: var(--brass-deep); text-decoration: underline; text-underline-offset: 3px; }
.nav-mega-all {
    display: inline-block; margin-top: 1.2rem; padding-top: .9rem;
    border-top: 1px solid var(--line); width: 100%;
    font-size: .82rem; font-weight: 600; letter-spacing: .04em;
    color: var(--navy); text-decoration: none;
}
.nav-mega-all:hover { color: var(--brass-deep); }

/* Account menu. Staff tooling belongs behind an authenticated control, not
   beside Cart where every customer reads it on every page. */
.account-menu { position: relative; }
.account-menu summary {
    list-style: none; cursor: pointer;
    display: inline-flex; align-items: center; gap: .3rem;
}
.account-menu summary::-webkit-details-marker { display: none; }
.account-menu summary::after {
    content: ''; width: .5rem; height: .5rem; flex-shrink: 0;
    background: currentColor;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") center / contain no-repeat;
    transition: transform .15s;
}
.account-menu[open] summary::after { transform: rotate(180deg); }
.account-panel {
    position: absolute; top: calc(100% + .7rem); right: 0; z-index: 70;
    background: var(--white); border: 1px solid var(--line); border-radius: 3px;
    box-shadow: 0 1px 2px rgba(11,31,59,.05), 0 22px 48px -20px rgba(11,31,59,.28);
    padding: .55rem; width: 15rem; max-width: calc(100vw - 2rem);
    display: flex; flex-direction: column;
}
.account-panel::before {
    content: ''; position: absolute; inset: -1px 0 auto 0; height: 2px;
    background: var(--gold); border-radius: 3px 3px 0 0;
}
.account-who {
    margin: .25rem .7rem .5rem; padding-bottom: .55rem;
    border-bottom: 1px solid var(--line);
    font-size: .74rem; color: var(--ink-soft);
    overflow: hidden; text-overflow: ellipsis;
}
.account-panel a, .account-signout {
    display: block; width: 100%; text-align: left;
    padding: .5rem .7rem; border: 0; border-radius: 2px; background: none;
    font: inherit; font-size: .86rem; font-weight: 600; color: var(--navy);
    text-decoration: none; cursor: pointer;
}
.account-panel a:hover, .account-signout:hover { background: var(--paper-deep); }
.account-signout { font-weight: 500; color: var(--ink-soft); }
/* Staff route: distinguished by a restrained gold marker rather than shouting
   in uppercase. It still reads as a different kind of destination, without
   looking like a warning label in the middle of a customer's account menu. */
.account-admin { color: var(--brass-deep) !important; display: flex !important; align-items: center; gap: .5rem; }
.account-admin::before {
    content: ''; width: 3px; height: 1em; flex-shrink: 0;
    background: var(--gold); border-radius: 1px;
}
.account-admin:hover { background: var(--brass-pale) !important; }

/* ── Categories page: the complete taxonomy the mega-menu links out to ───── */
.cat-families { display: grid; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); gap: 2.4rem 3rem; }
.cat-family-heading {
    margin: 0 0 .9rem; padding-bottom: .6rem; border-bottom: 1px solid var(--line);
    font-family: var(--font-display); font-size: .74rem; font-weight: 600;
    letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft);
}
.cat-family-list { list-style: none; margin: 0; padding: 0; }
.cat-family-list a {
    display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
    padding: .5rem 0; border-bottom: 1px solid var(--paper-deep);
    color: var(--navy); text-decoration: none; font-size: .95rem;
}
.cat-family-list a:hover .cat-family-name { color: var(--brass-deep); text-decoration: underline; text-underline-offset: 3px; }
.cat-family-count { font-size: .78rem; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.cat-family-more {
    display: inline-block; margin-top: .9rem;
    font-size: .82rem; font-weight: 600; letter-spacing: .03em;
    color: var(--navy); text-decoration: none;
}
.cat-family-more:hover { color: var(--brass-deep); }
.cat-families-note { margin-top: 2.6rem; padding-top: 1.4rem; border-top: 1px solid var(--line); max-width: 46rem; font-size: .9rem; }

/* ── Publishing family page ─────────────────────────────────────────────── */
.family-cats { display: flex; flex-wrap: wrap; gap: .5rem; margin-bottom: 2.2rem; }
.family-cats a {
    display: inline-flex; align-items: baseline; gap: .45rem;
    padding: .45rem .85rem; border: 1px solid var(--line); border-radius: 2px;
    font-size: .87rem; font-weight: 600; color: var(--navy); text-decoration: none;
    transition: border-color .15s, color .15s;
}
.family-cats a:hover { border-color: var(--gold); color: var(--brass-deep); }
.family-cat-count { font-size: .74rem; font-weight: 500; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.family-books-heading {
    font-size: 1.25rem; margin: 0 0 1.2rem; padding-bottom: .7rem;
    border-bottom: 1px solid var(--line);
    display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
}

/* Header search — same collapsed-icon-to-panel pattern as locale/dropdown. */
.search-menu { position: relative; }
.search-menu summary {
    list-style: none; cursor: pointer; width: 1.9rem; height: 1.9rem;
    display: flex; align-items: center; justify-content: center;
    border-radius: 50%; color: var(--ink-soft); transition: color .15s, background .15s;
}
.search-menu summary::before {
    content: ''; width: 1.05rem; height: 1.05rem;
    background: currentColor;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.5-3.5'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.5-3.5'/%3E%3C/svg%3E") center / contain no-repeat;
}
.search-menu summary::-webkit-details-marker { display: none; }
.search-menu summary:hover, .search-menu[open] summary { color: var(--navy); background: var(--paper-deep); }
.search-panel {
    position: absolute; top: calc(100% + .6rem); right: 0; z-index: 70;
    background: var(--white); border: 1px solid var(--line); border-radius: var(--radius);
    box-shadow: 0 18px 40px -18px rgba(11,31,59,.35);
    padding: .7rem; width: 16rem; display: flex; gap: .5rem;
}
[dir="rtl"] .search-panel { right: auto; left: 0; }
.search-panel input {
    flex: 1; min-width: 0; padding: .5rem .7rem; border: 1px solid var(--line);
    border-radius: 99px; background: var(--paper-deep); font-size: .88rem;
}

.header-actions { display: flex; align-items: center; gap: .9rem; margin-left: auto; padding-left: 1.4rem; border-left: 1px solid var(--line); }
.header-actions a { text-decoration: none; font-size: .9rem; font-weight: 600; color: var(--ink-soft); white-space: nowrap; }
.header-actions a:hover { color: var(--navy); }
.cart-link, .wish-link { position: relative; display: inline-flex; align-items: center; gap: .4rem; }
.wish-link svg { width: 1.05rem; height: 1.05rem; }
/* Wishlist is an icon on desktop, like Search. Spelling it out cost ~50px in a
   utility bar that has to hold Search, Wishlist, Cart, My Library, Account and
   the locale control — and the heart is unambiguous. The word is kept for
   screen readers (the link also carries aria-label) and returns in the mobile
   accordion, where there is room and no icon convention to lean on. */
.hdr-icon-label {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
@media (max-width: 1200px) {
    .site-header.nav-open .hdr-icon-label {
        position: static; width: auto; height: auto; margin: 0;
        overflow: visible; clip: auto; white-space: normal;
    }
}
.cart-count {
    background: var(--gold); color: var(--navy); border-radius: 99px;
    font-size: .68rem; font-weight: 700; min-width: 1.15rem; height: 1.15rem;
    display: inline-flex; align-items: center; justify-content: center; padding-inline: .25rem;
}
.wish-link .cart-count { background: var(--sale); color: #fff; }

/* Locale switcher — minimalist globe · language · currency */
.locale-menu { position: relative; }
.locale-menu summary {
    list-style: none; cursor: pointer;
    font-size: .78rem; font-weight: 700; letter-spacing: .06em; color: var(--ink-soft);
    padding: .38rem .7rem; border: 1px solid var(--line); border-radius: 99px;
    transition: border-color .15s, color .15s;
    white-space: nowrap;
    display: inline-flex; align-items: center; gap: .35rem;
}
.locale-menu summary::before { content: '🌐'; font-size: .85rem; }
.locale-menu summary::-webkit-details-marker { display: none; }
.locale-menu summary:hover, .locale-menu[open] summary { border-color: var(--navy); color: var(--navy); }
.locale-panel {
    /* Anchored under the EN · EUR control and right-aligned to it, so it never
       reaches across into the Account control. Width is capped against the
       viewport so it stays fully visible at narrow desktop and tablet widths. */
    position: absolute; top: calc(100% + .55rem); right: 0; z-index: 70;
    background: var(--white); border: 1px solid var(--line); border-radius: 3px;
    box-shadow: 0 1px 2px rgba(11,31,59,.05), 0 22px 48px -20px rgba(11,31,59,.28);
    padding: .9rem; width: 14rem; max-width: calc(100vw - 2rem);
}
/* Same gold hairline as the other header panels, so they read as one family. */
.locale-panel::before {
    content: ''; position: absolute; inset: -1px 0 auto 0; height: 2px;
    background: var(--gold); border-radius: 3px 3px 0 0;
}
/* Language and currency are independent settings and are labelled as such —
   choosing English must never silently imply EUR. */
.locale-panel label { margin-top: 0; }
[dir="rtl"] .locale-panel { right: auto; left: 0; }
.locale-panel label {
    display: block; font-size: .68rem; font-weight: 700; letter-spacing: .12em;
    text-transform: uppercase; color: var(--ink-soft); margin: 0 0 .3rem;
}
.locale-panel label + select { margin-bottom: .8rem; }
.locale-panel select {
    width: 100%; padding: .45rem .6rem; font-size: .88rem;
    border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--paper-deep);
}
.locale-panel select:last-child { margin-bottom: 0; }
@media (max-width: 1200px) {
    .site-header.nav-open .locale-menu { order: -1; }
    .site-header.nav-open .locale-panel { position: static; width: 100%; box-shadow: none; margin-top: .4rem; }
}

.nav-toggle { display: none; background: none; border: 0; padding: .4rem; margin-left: auto; }
.nav-toggle span { display: block; width: 22px; height: 2px; background: var(--navy); margin: 5px 0; transition: transform .2s, opacity .2s; }

/* Mobile nav.
   1200px. The desktop masthead needs ~1069px signed out (logo 255 + nav 357 +
   utilities 419 + gaps) and roughly 100px more once a signed-in reader adds My
   Library and Account — against a wrap that maxes out at 1184px. Below 1200 the
   bar overflowed its own wrap, pushing the right-aligned Language/Currency
   panel off the side of the viewport. The accordion now takes over before the
   squeeze rather than after it. main.js reads the same breakpoint — keep the
   two in step. */
@media (max-width: 1200px) {
    .nav-main, .header-actions { display: none; }
    .nav-toggle { display: block; }
    .site-header.nav-open .nav-main,
    .site-header.nav-open .header-actions {
        display: flex; flex-direction: column; align-items: flex-start; gap: .2rem;
        padding: .6rem 0 1.1rem; margin: 0;
    }
    .site-header.nav-open .header-bar { flex-wrap: wrap; }
    .site-header.nav-open .nav-main { order: 3; width: 100%; border-top: 1px solid var(--line); padding-top: 1rem; }
    .site-header.nav-open .header-actions { order: 4; width: 100%; border-left: 0; }
    .site-header.nav-open .nav-main a, .site-header.nav-open .header-actions a,
    .site-header.nav-open .nav-dropdown summary, .site-header.nav-open .search-menu summary { padding: .5rem 0; font-size: 1.05rem; }
    .site-header.nav-open .nav-dropdown, .site-header.nav-open .search-menu,
    .site-header.nav-open .account-menu { width: 100%; }
    /* The account menu joins the accordion rather than floating over it. */
    .site-header.nav-open .account-panel {
        position: static; width: 100%; box-shadow: none; border: 0;
        border-left: 2px solid var(--brass-pale); border-radius: 0;
        margin: .1rem 0 .5rem; padding: 0 0 0 .9rem;
    }
    .site-header.nav-open .account-panel::before { display: none; }
    .site-header.nav-open .account-panel a,
    .site-header.nav-open .account-signout { padding: .5rem 0; font-size: 1rem; }
    .site-header.nav-open .account-panel a:hover,
    .site-header.nav-open .account-signout:hover { background: none; }
    .site-header.nav-open .account-who { margin-inline: 0; }
    .site-header.nav-open .account-admin { font-size: .85rem !important; }
    /* Accordion, not a mega-menu. A 58rem grid of category columns cannot be
       squeezed onto a phone and stay legible, so the panels drop inline and
       Books and Categories simply expand in place. */
    .site-header.nav-open .nav-dropdown-panel, .site-header.nav-open .search-panel {
        position: static; transform: none; width: 100%; box-shadow: none; border: 0;
        margin: .1rem 0 .5rem; padding: 0 0 0 .9rem;
    }
    .site-header.nav-open .nav-dropdown-panel { border-left: 2px solid var(--brass-pale); border-radius: 0; }
    .site-header.nav-open .nav-dropdown-panel::before { display: none; }
    .site-header.nav-open .nav-item { padding: .45rem 0; }
    .site-header.nav-open .nav-item:hover { background: none; }
    .site-header.nav-open .nav-item-label { font-size: .98rem; }
    .site-header.nav-open .nav-divider { margin: .5rem 0; }
    .site-header.nav-open .nav-mega-grid { display: block; }
    .site-header.nav-open .nav-mega-heading { margin-top: .9rem; }
    .site-header.nav-open .nav-mega-col a { padding: .42rem 0; font-size: .95rem; }
    .site-header.nav-open .nav-mega-all { margin-top: .9rem; }
    .site-header.nav-open .search-menu summary { width: auto; height: auto; border-radius: 0; justify-content: flex-start; gap: .5rem; }
    .site-header.nav-open .search-menu summary::before { content: 'Search'; background: none; -webkit-mask: none; mask: none; font-size: 1.05rem; font-weight: 600; color: var(--ink-soft); width: auto; height: auto; }
    .site-header.nav-open .search-menu[open] summary::before { color: var(--navy); }
    .site-header.nav-open .search-panel { flex-direction: column; }
    .site-header.nav-open .nav-toggle span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
    .site-header.nav-open .nav-toggle span:nth-child(2) { opacity: 0; }
    .site-header.nav-open .nav-toggle span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
}

/* ── Hero ────────────────────────────────────────────────────────────── */
/* Spacious, not empty: the padding was set when the visual was a thin strip of
   thumbnails and the hero had to be tall to look intentional. The composition
   now carries the height itself, so the surrounding air comes down. */
/* ── Hero ────────────────────────────────────────────────────────────────
   Navy, matching the Editor's Pick further down the page. The hero and the
   pick are the two moments the page is asking to be taken seriously, and on
   white the books had no ground to stand on and no light to be lit by.

   The gradient is a lit room, not a fill: slightly lighter above and to the
   right where the key light sits, deepening into the corners. */
.hero {
    overflow: hidden;
    padding-block: clamp(2.6rem, 5vw, 4.6rem) clamp(3rem, 5.5vw, 5rem);
    background:
        radial-gradient(120% 90% at 72% 8%, #16305A 0%, rgba(22, 48, 90, 0) 58%),
        linear-gradient(180deg, #0D2445 0%, var(--navy) 46%, #081833 100%);
    color: var(--paper);
    position: relative;
}
/* A hairline of light where the hero meets the section beneath it, so the two
   surfaces read as separate planes rather than one block ending abruptly. */
.hero::after {
    content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
    background: linear-gradient(90deg,
        rgba(201, 155, 46, 0), rgba(201, 155, 46, .32) 30%,
        rgba(201, 155, 46, .32) 70%, rgba(201, 155, 46, 0));
    pointer-events: none;
}

/* The copy, inverted. Every colour below was tuned for navy-on-white and is
   unreadable the moment the ground goes dark, so each is restated rather than
   left to inherit something that no longer applies. */
.hero .eyebrow { color: var(--gold); }
.hero-copy h1 { color: #fff; }
.hero .hero-lede { color: rgba(247, 244, 237, .88); }
/* The dark-ground .text-link treatment is defined once with the component
   itself; nothing extra is needed here. */
/* The outline button had a navy border on navy — invisible. */
.hero .btn-ghost { color: #fff; border-color: rgba(247, 244, 237, .42); background: transparent; }
.hero .btn-ghost:hover { background: rgba(247, 244, 237, .10); border-color: #fff; color: #fff; }
.hero-grid {
    display: grid; gap: clamp(1.6rem, 3.5vw, 3rem);
    /* Even columns. The book composition needs real width to hold two large
       covers side by side; at 7fr/5fr they had to overlap by half to fit. */
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: center;
}
.hero-copy .btn { margin-right: .7rem; margin-top: .4rem; }
[dir="rtl"] .hero-copy .btn { margin-right: 0; margin-left: .7rem; }
.hero-lede { font-size: clamp(1rem, 1.6vw, 1.15rem); color: var(--ink-soft); max-width: 33rem; }
/* Hero shelf: three books standing on one baseline.
   No gradient panel, no cast shadow, no tilt — the approved images are already
   photographs on white, and anything added here reads as a fake shadow beneath
   books that were deliberately shot without one. The middle book stands slightly
   taller, which is what a real shelf looks like. */
.hero-shelf {
    display: flex;
    align-items: flex-end;
    justify-content: center;
    gap: clamp(.5rem, 2vw, 1.6rem);
    min-height: 20rem;
}
.hero-shelf-book {
    width: clamp(6rem, 27%, 12rem);
    height: auto;
    object-fit: contain;
    display: block;
}
.hero-shelf-book:nth-child(2) { width: clamp(7rem, 31%, 13.5rem); }
@media (max-width: 40rem) {
    /* One book on a phone. Three at this width becomes an unreadable smudge. */
    .hero-shelf { min-height: 0; margin-top: 1.5rem; }
    .hero-shelf-book:nth-child(n+2) { display: none; }
    .hero-shelf-book:first-child { width: min(58%, 14rem); }
}

.hero-wall { position: relative; min-height: 20rem; perspective: 1800px; }
/* A staged backdrop behind the books — plain white was making the dark
   navy covers/spines blend into the page instead of standing off it like an
   actual product display. Scoped to just this area, not the whole hero. */
.hero-wall::before {
    content: '';
    position: absolute;
    inset: -6% -3% -10%;
    z-index: 0;
    border-radius: 32px;
    background: radial-gradient(115% 95% at 50% 40%, rgba(11, 31, 59, .5) 0%, rgba(11, 31, 59, .28) 45%, rgba(11, 31, 59, 0) 80%);
}

/* Real 3D books — same construction as the product page's 360° viewer
   (front/spine/top faces on a preserve-3d cube, sized from measured pixels
   via --w/--h/--d), just resting at a fixed turned angle instead of being
   draggable, so the spine reads as genuine thickness rather than a flat
   cover with a fake gradient strip painted on. */
.hero-book { position: absolute; width: 58%; }
.hero-book-obj {
    position: relative; width: 100%; aspect-ratio: 4 / 5;
    transform-style: preserve-3d;
    /* rotateX first: a book viewed dead-on (no vertical tilt) never shows its
       top edge at all — this is what was making .hero-book-top render at
       zero height. A slight downward camera angle, as if the books were on
       a shelf below eye level, is what actually makes them read as objects
       with a top surface rather than a rotated flat photo. */
    transform: rotateX(8deg) rotateY(var(--ry, -24deg));
    transition: transform .45s cubic-bezier(.22,.61,.36,1);
}
.hero-book-face { position: absolute; inset: 0; backface-visibility: hidden; border-radius: 6px; }
.hero-book-face img {
    width: 100%; height: 100%; object-fit: cover; border-radius: 6px; pointer-events: none;
    /* A bolder, tighter-contact shadow than a flat cover needs — this is what
       actually reads as "an object sitting forward of the page" rather than
       a picture printed on it, especially against a light background. */
    box-shadow: 0 40px 70px -14px rgba(11, 31, 59, .78), 0 10px 20px -6px rgba(11, 31, 59, .6);
}
.hero-book-front { transform: translateZ(calc(var(--d, 15px) / 2)); background: var(--white); border: 3px solid rgba(11, 31, 59, .32); }
.hero-book-front--brass { border-color: var(--gold); }
/* Back cover — the book's own real back-cover image (same file the product
   page's 360° viewer uses), so a full turn shows the actual book, not a
   blank panel standing in for it. */
.hero-book-back {
    transform: rotateY(180deg) translateZ(calc(var(--d, 15px) / 2));
    background: var(--navy);
    border: 3px solid rgba(11, 31, 59, .32);
}
.hero-book-spine {
    top: 0; bottom: 0; width: var(--d, 15px); left: calc(50% - var(--d, 15px) / 2);
    background: var(--navy); border-radius: 2px;
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .06);
    transform: rotateY(-90deg) translateZ(calc(var(--w, 200px) / 2));
}
.hero-book-top {
    left: 0; right: 0; height: var(--d, 15px); top: calc(50% - var(--d, 15px) / 2);
    background: repeating-linear-gradient(0deg, #F2F0EA 0 2px, #E2DFD6 2px 3px);
    border-radius: 2px;
    transform: rotateX(90deg) translateZ(calc(var(--h, 250px) / 2));
}
.hero-wall--4 { min-height: 25rem; }
.hero-book:nth-child(1) { top: 0; left: 0; width: 52%; z-index: 2; }
.hero-book:nth-child(1) .hero-book-obj { --ry: -24deg; }
.hero-book:nth-child(2) { top: 2%; right: 0; width: 43%; z-index: 1; }
.hero-book:nth-child(2) .hero-book-obj { --ry: 20deg; }
.hero-book:nth-child(3) { bottom: 0; left: 25%; width: 39%; z-index: 4; }
.hero-book:nth-child(3) .hero-book-obj { --ry: -16deg; }
.hero-book:nth-child(4) { bottom: -8%; right: 4%; width: 41%; z-index: 3; }
.hero-book:nth-child(4) .hero-book-obj { --ry: 15deg; }
.hero-book:hover { z-index: 5; }
.hero-book:nth-child(1):hover .hero-book-obj { transform: rotateX(8deg) rotateY(-34deg) translateY(-8px) scale(1.04); }
.hero-book:nth-child(2):hover .hero-book-obj { transform: rotateX(8deg) rotateY(30deg) translateY(-8px) scale(1.04); }
.hero-book:nth-child(3):hover .hero-book-obj { transform: rotateX(8deg) rotateY(-26deg) translateY(-8px) scale(1.04); }
.hero-book:nth-child(4):hover .hero-book-obj { transform: rotateX(8deg) rotateY(25deg) translateY(-8px) scale(1.04); }
/* One primary action plus a quiet text link. Two buttons of equal weight made
   the visitor choose between two ways of saying "browse", and a pause is the
   thing that loses them. */
.hero-cta { display: flex; align-items: center; gap: 1.2rem; flex-wrap: wrap; margin-bottom: .9rem; }

.hero-proof { display: flex; gap: 1.6rem; flex-wrap: wrap; margin-top: 2.2rem; padding-top: 1.6rem; border-top: 1px solid var(--line); }
.hero-proof .proof { font-size: .85rem; color: var(--ink-soft); }
.hero-proof .proof strong { display: block; font-family: var(--font-display); font-size: 1.25rem; font-weight: 550; color: var(--navy); }

@media (max-width: 900px) {
    .hero-grid { grid-template-columns: 1fr; }
    .hero-wall { min-height: 17rem; margin-top: 1rem; }
    .hero-wall--4 { min-height: 19rem; }
}

/* Load-in settle */
@media (prefers-reduced-motion: no-preference) {
    .hero-copy > * {
        opacity: 0; transform: translateY(14px);
        animation: settle .7s cubic-bezier(.2,.7,.3,1) forwards;
    }
    .hero-copy > *:nth-child(2) { animation-delay: .08s; }
    .hero-copy > *:nth-child(3) { animation-delay: .16s; }
    .hero-copy > *:nth-child(4) { animation-delay: .24s; }
    .hero-copy > *:nth-child(5) { animation-delay: .32s; }
    @keyframes settle { to { opacity: 1; transform: none; } }

    /* The books fade in (outer element, opacity only) while the inner 3D
       object continuously turns all the way round — separate elements so
       the one-shot fade-in and the endless rotateY turn never fight over
       the same "transform" value. :not(:hover) hands "transform" back to
       the plain :hover rule above, so hovering interrupts the turn instead
       of fighting it. One shared keyframe (via var(--ry)) reused at four
       different speeds/directions keeps the books out of sync with each
       other rather than spinning like a synchronized set. */
    .hero-book { opacity: 0; animation: heroFadeIn .5s ease forwards; }
    .hero-book:nth-child(1) { animation-delay: .2s; }
    .hero-book:nth-child(2) { animation-delay: .34s; }
    .hero-book:nth-child(3) { animation-delay: .48s; }
    .hero-book:nth-child(4) { animation-delay: .62s; }
    @keyframes heroFadeIn { to { opacity: 1; } }

    .hero-book:nth-child(1) .hero-book-obj:not(:hover) { animation: bookTurn 15s linear infinite; }
    .hero-book:nth-child(2) .hero-book-obj:not(:hover) { animation: bookTurn 19s linear infinite reverse; }
    .hero-book:nth-child(3) .hero-book-obj:not(:hover) { animation: bookTurn 12s linear infinite; }
    .hero-book:nth-child(4) .hero-book-obj:not(:hover) { animation: bookTurn 21s linear infinite reverse; }
    /* A slow self-playing zoom is layered into the same turn (scale peaking
       at the midpoint) rather than a separate animation, so the two motions
       always agree on one "transform" value instead of one silently
       overwriting the other. */
    @keyframes bookTurn {
        0%   { transform: rotateX(8deg) rotateY(var(--ry, -24deg)) translateY(0) scale(1); }
        50%  { transform: rotateX(8deg) rotateY(calc(var(--ry, -24deg) + 180deg)) translateY(-9px) scale(1.08); }
        100% { transform: rotateX(8deg) rotateY(calc(var(--ry, -24deg) + 360deg)) translateY(0) scale(1); }
    }
}
@media (prefers-reduced-motion: reduce) {
    /* Still read as standing books at rest (the static --ry rules above already
       apply), just without the endless rocking motion. */
    .hero-book { opacity: 1; }
}

/* ── Trust bar ───────────────────────────────────────────────────────── */
.trust-bar {
    display: flex; flex-wrap: wrap; gap: .8rem 2rem; justify-content: center;
    padding: 1rem var(--gutter); border-block: 1px solid var(--line);
    font-size: .84rem; font-weight: 600; color: var(--ink-soft);
    background: var(--paper-deep);
}
.trust-bar span::before { content: '✓ '; color: var(--brass); font-weight: 700; }

/* ── Category grid ───────────────────────────────────────────────────── */
/* Compact horizontal cards — a real book cover per category (sampling the
   catalogue) instead of a generic icon, sized so the whole ten-category
   block reads as one row-dense strip rather than a tall stack of squares. */
.grid-categories {
    display: grid; gap: .65rem;
    grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
}
.card-category {
    position: relative; display: flex; align-items: center; gap: .8rem;
    text-decoration: none;
    background: var(--white); border: 1px solid var(--line); border-radius: var(--radius);
    padding: .6rem .7rem;
    transition: border-color .18s ease, transform .18s ease, box-shadow .18s ease;
}
.card-category:hover { border-color: var(--gold); transform: translateY(-2px); box-shadow: var(--shadow-frame); }
.card-category .cat-thumb {
    flex: 0 0 auto; width: 2.6rem; height: 3.5rem; border-radius: 4px; overflow: hidden;
    box-shadow: 0 3px 8px -3px rgba(11, 31, 59, .35);
}
.card-category .cat-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.card-category .cat-body { min-width: 0; padding-right: 1.4rem; }
.card-category h3 { font-size: .92rem; margin: 0 0 .12rem; }
.card-category p {
    font-size: .78rem; color: var(--ink-soft); margin: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.card-category .go { position: absolute; top: 50%; right: .8rem; transform: translateY(-50%); color: var(--brass); font-weight: 700; }
[dir="rtl"] .card-category .go { right: auto; left: .8rem; }
[dir="rtl"] .card-category .cat-body { padding-right: 0; padding-left: 1.4rem; }

/* ── Pricing tiers ───────────────────────────────────────────────────── */
.grid-tiers { display: grid; gap: 1.2rem; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); align-items: stretch; }
.card-tier {
    background: var(--white); border: 1px solid var(--line); border-radius: var(--radius);
    padding: 1.8rem 1.5rem; display: flex; flex-direction: column;
    transition: box-shadow .2s ease;
}
.card-tier:hover { box-shadow: var(--shadow-frame); }
.card-tier.is-featured { border: 2px solid var(--gold); position: relative; box-shadow: var(--shadow-frame); }
.card-tier .tier-flag {
    position: absolute; top: -0.75rem; left: 50%; transform: translateX(-50%);
    background: var(--gold); color: var(--navy); font-size: .62rem; font-weight: 700;
    letter-spacing: .14em; text-transform: uppercase; padding: .28rem .75rem; border-radius: 99px;
    white-space: nowrap;
}
.card-tier h3 { margin-bottom: .1rem; }
.card-tier .tier-tagline { color: var(--ink-soft); font-size: .85rem; margin-bottom: 1rem; }
.card-tier .tier-price { font-family: var(--font-display); font-size: 2rem; font-weight: 550; margin-bottom: .2rem; color: var(--navy); }
.card-tier .tier-price small { font-size: .85rem; font-family: var(--font-ui); color: var(--ink-soft); font-weight: 500; }
.card-tier ul { list-style: none; margin: 0 0 1.4rem; padding: 0; font-size: .88rem; color: var(--ink-soft); }
.card-tier li { padding: .32rem 0 .32rem 1.4rem; position: relative; }
.card-tier li::before { content: '✓'; position: absolute; left: 0; color: var(--brass); font-weight: 700; }
[dir="rtl"] .card-tier li { padding: .32rem 1.4rem .32rem 0; }
[dir="rtl"] .card-tier li::before { left: auto; right: 0; }
.card-tier .btn { margin-top: auto; }

/* ── Steps (how it works) ────────────────────────────────────────────── */
.grid-steps { display: grid; gap: 1.4rem; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); }
.step { border-top: 3px solid var(--gold); padding-top: 1rem; }
.step h3 { font-size: 1.12rem; }
.step p { color: var(--ink-soft); font-size: .9rem; margin: 0; }

/* ── Testimonials ────────────────────────────────────────────────────── */
.grid-quotes { display: grid; gap: 1.2rem; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); }
.quote {
    background: var(--white); border: 1px solid var(--line); border-radius: var(--radius);
    padding: 1.5rem;
}
.quote .stars { color: var(--gold); letter-spacing: .12em; font-size: .85rem; margin-bottom: .6rem; }
.quote blockquote { margin: 0 0 .9rem; font-family: var(--font-display); font-size: 1.04rem; font-weight: 440; line-height: 1.45; color: var(--ink); }
.quote figcaption { font-size: .8rem; color: var(--ink-soft); }

/* ── Blog cards ──────────────────────────────────────────────────────── */
.grid-posts { display: grid; gap: 1.6rem; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); }
.card-post { text-decoration: none; display: block; }
.card-post .post-cover {
    aspect-ratio: 16 / 9; object-fit: cover; width: 100%;
    border: 1px solid var(--line); border-radius: var(--radius); background: var(--paper-deep);
    margin-bottom: .9rem;
}
.card-post h3 { font-size: 1.15rem; }
.card-post:hover h3 { color: var(--brass); }
.card-post p { color: var(--ink-soft); font-size: .88rem; margin: 0; }
.post-meta { font-size: .74rem; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft); margin-bottom: .3rem; display: block; }

/* ── Newsletter / lead magnet band ───────────────────────────────────── */
.band-news { background: var(--navy); color: #DDE5F0; }
.band-news .eyebrow { color: var(--gold); }
.band-news h2 { color: #fff; }
.band-news p { color: #A9B8CD; }
.news-form { display: flex; gap: .6rem; max-width: 28rem; flex-wrap: wrap; }
.news-form input[type=email] {
    flex: 1 1 14rem; padding: .85rem 1rem; border-radius: 10px;
    border: 1px solid #2C4368; background: #122B4F; color: #fff;
}
.news-form input[type=email]::placeholder { color: #7E92AF; }

/* ── Shop filters ────────────────────────────────────────────────────── */
.filter-bar {
    display: flex; flex-wrap: wrap; gap: .55rem; align-items: center;
    padding-block: 1.1rem; border-block: 1px solid var(--line); margin-bottom: 2rem;
}
.filter-bar .spacer { flex: 1; }
.filter-bar select {
    padding: .5rem .8rem; border: 1px solid var(--line); border-radius: 99px;
    background: var(--white); font-size: .85rem;
}
.filter-check {
    display: flex; align-items: center; gap: .4rem;
    padding: .5rem .9rem; border: 1px solid var(--line); border-radius: 99px;
    font-size: .85rem; color: var(--ink-soft); cursor: pointer; user-select: none;
}
.filter-check:has(input:checked) { border-color: var(--sale); color: var(--sale); background: rgba(162, 55, 46, .06); }
.search-form { display: flex; gap: .5rem; }
.search-form input {
    padding: .5rem .9rem; border: 1px solid var(--line); border-radius: 99px;
    background: var(--white); font-size: .9rem; min-width: 11rem;
}

.empty-state {
    text-align: center; padding: 4rem 1rem; border: 1px dashed var(--line); border-radius: var(--radius);
    color: var(--ink-soft);
}

/* ── 360° product viewer ─────────────────────────────────────────────── */
/* ── Book gallery ─────────────────────────────────────────────────────────
   The approved images are shadow-free photographs of a real book on pure
   white. The gallery therefore adds NOTHING: no shadow, no gradient, no glow,
   no reflection, no tinted ground. Anything decorative here would reappear as
   a fake shadow under a book that was deliberately shot without one. */
.book-gallery { margin-bottom: 1rem; }
.bg-stage {
    position: relative;
    background: #FFFFFF;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    /* Reserving the square keeps the page from shifting while the image loads. */
    aspect-ratio: 1 / 1;
    display: grid;
    place-items: center;
    overflow: hidden;
}
.bg-stage > img {
    width: 100%; height: 100%;
    object-fit: contain;          /* never crop, never stretch */
    display: block;
    background: #FFFFFF;
}
.bg-stage > video {
    width: 100%; height: 100%;
    object-fit: contain;
    display: block;
    background: #000;             /* letterboxing a 16:9 clip, not a book */
}
.bg-nav {
    position: absolute; top: 50%; transform: translateY(-50%);
    width: 2.6rem; height: 2.6rem; border-radius: 50%;
    border: 1px solid var(--line); background: rgba(255, 255, 255, .94);
    font-size: 1.35rem; line-height: 1; cursor: pointer; color: var(--navy);
    display: grid; place-items: center;
    transition: background .15s, border-color .15s;
}
.bg-nav:hover, .bg-nav:focus-visible { background: #fff; border-color: var(--gold); }
.bg-prev { left: .7rem; }
.bg-next { right: .7rem; }
.bg-zoom {
    position: absolute; right: .7rem; bottom: .7rem;
    width: 2.4rem; height: 2.4rem; border-radius: 50%;
    border: 1px solid var(--line); background: rgba(255, 255, 255, .94);
    cursor: pointer; font-size: 1rem; display: grid; place-items: center;
}
.bg-zoom:hover, .bg-zoom:focus-visible { border-color: var(--gold); background: #fff; }
.bg-hint { font-size: .78rem; color: var(--ink-soft); text-align: center; margin: .5rem 0 0; }
@media (max-width: 34rem) {
    .bg-nav { width: 2.2rem; height: 2.2rem; font-size: 1.15rem; }
}

/* Website video clip — its own panel, not inside the 3D book.
   The footage is 16:9; the book face is portrait, so nesting the two cropped
   the clip to a sliver and left the rotate-drag handler over its controls. */
.gallery-video {
    background: #000;
    border-radius: var(--radius, 12px);
    overflow: hidden;
    margin-bottom: 1rem;
    aspect-ratio: 16 / 9;
}
.gallery-video[hidden] { display: none; }
.gallery-video video {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;   /* never crop the footage */
}

.viewer-3d {
    position: relative;
    background: var(--white);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow-frame);
    padding: clamp(1.2rem, 6%, 2.2rem) clamp(1.2rem, 6%, 2.2rem) 3.4rem;
    margin-bottom: 1rem;
    overflow: hidden;
    user-select: none;
    -webkit-user-select: none;
}
.v3d-stage {
    perspective: 1400px;
    display: flex;
    justify-content: center;
    align-items: center;   /* books stand on a common baseline */
    touch-action: pan-y pinch-zoom;   /* horizontal drag rotates; page still scrolls vertically */
    cursor: grab;
}
.v3d-stage.is-dragging { cursor: grabbing; }
.v3d-object {
    position: relative;
    /* Sized on HEIGHT, not width.
       Every book keeps its own printed proportions, but they all stand the same
       height — the way titles line up on a shelf. Fixing the width instead made
       height swing with the ratio: a 0.607 cover rendered 501px tall against
       342px for a 0.888 one, so the tall titles looked stretched and wrong.
       Height first, width follows from the cover's real shape. */
    height: min(52vh, 23rem);
    width: auto;
    max-width: 100%;
    aspect-ratio: var(--cover-ratio, 4 / 5);
    transform-style: preserve-3d;
    transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) scale(var(--zoom, 1));
    will-change: transform;
}
.v3d-object.is-settling { transition: transform .5s cubic-bezier(.2, .7, .3, 1); }

/* Continuous 360° idle spin — compositor-driven, pauses while exploring */
.v3d-spinner {
    position: absolute;
    inset: 0;
    transform-style: preserve-3d;
    /* Slow motion: one full turn every 60 seconds rather than 16.
       At 16s the book swept past the front cover too quickly for a shopper to
       take it in; at 60s the movement reads as a gentle presentation turn and
       the front cover stays legible for roughly 15 seconds at a time. */
    animation: v3d-spin 60s linear infinite;
}
.v3d-spinner.is-paused { animation-play-state: paused; }
/* A slow sway, not a full revolution.
   The cover is a photograph of a book, so at 90 degrees it would turn edge-on
   and disappear — a full turn only worked when CSS was drawing a solid box with
   its own spine. Swaying between -16 and +16 degrees keeps the book moving, and
   keeps the photograph facing the customer the whole time. This is what premium
   product pages actually do; a spinning cover is a games-console trick, not a
   bookshop one. Dragging still rotates freely, as far as the visitor wants. */
@keyframes v3d-spin {
    0%   { transform: rotateY(-16deg); }
    50%  { transform: rotateY(16deg); }
    100% { transform: rotateY(-16deg); }
}
@media (prefers-reduced-motion: reduce) {
    .v3d-spinner { animation: none; }
}
.v3d-face {
    position: absolute;
    inset: 0;
    backface-visibility: hidden;
    border-radius: 4px;
}
/* A bound book is square at the fold and rounded on the open side — the page
   corners wear, the spine cannot. Equal radius on all four corners is one of
   the quiet tells that something is a rectangle rather than a book. */
.v3d-front img, .v3d-front::after { border-radius: 1px 6px 6px 1px; }
.v3d-back  img, .v3d-back::after  { border-radius: 6px 1px 1px 6px; }

.v3d-face img {
    width: 100%; height: 100%;
    /* `contain`, never `cover`. A back cover carries body copy right to its
       margins; cropping it to fill the box loses words.
       The box is sized from the FRONT cover, and on five titles the back is a
       different shape — up to 29% on Professor Pebble — so a band of the face
       behind it is exposed. Filling that with paper-white made it look like a
       white card sticking out behind the book. It is filled with the book's own
       spine colour instead, so the gap reads as the binding rather than as a
       hole. Cropping the back to hide it is not an option: that deletes text. */
    object-fit: contain;
    background: var(--spine-dark, var(--paper, #F7F4ED));
    border-radius: 4px;
    /* A tight edge-darkening only. The big soft drop shadow that used to sit on
       the cover itself travelled round with the face as the book turned, so the
       "shadow" appeared on whichever side you were looking at — which is what
       made it read as a flat card. Grounding is done once, under the object. */
    box-shadow: inset 0 0 0 1px rgba(11, 31, 59, .08);
    pointer-events: none;
}

/* Contact shadow on the floor, cast by the object rather than by a face, so it
   stays put while the book turns.
   Offset to the right and tighter at the base than at its tail, because the
   light rakes from the upper left — the same direction as the sheen above. A
   symmetrical blob centred under the book is the giveaway of a fake shadow;
   real ones are directional and darkest where the object actually touches. */
.v3d-object::after {
    content: "";
    position: absolute;
    left: 2%; right: -4%;
    bottom: -5%;
    height: 7%;
    background:
        radial-gradient(ellipse 62% 100% at 42% 40%, rgba(32, 28, 22, .40) 0%, rgba(32, 28, 22, .16) 45%, rgba(32, 28, 22, 0) 78%),
        radial-gradient(ellipse 100% 90% at 55% 50%, rgba(32, 28, 22, .16) 0%, rgba(32, 28, 22, 0) 72%);
    filter: blur(2px);
    transform: translateZ(calc(var(--d, 16px) / -2 - 2px));
    pointer-events: none;
}
.v3d-front { transform: translateZ(calc(var(--d, 16px) / 2)); }
.v3d-front img[data-lightbox-open] { cursor: zoom-in; }

/* Lighting.
   A cover reproduced perfectly flat and evenly lit reads as a scan, not as an
   object — which is why the book still looked artificial after the geometry was
   right. Real book photography always carries three things, and these are them:
     1. the gutter — paper bends into the fold, so the spine edge falls into
        shade and lifts again a little further out;
     2. a broad, soft sheen raking across the cover from the light;
     3. a faint darkening at the outer edge where the cover turns away.
   Kept subtle on purpose. Overdone, it looks like a filter; at this strength it
   simply stops reading as a rectangle of pixels. */
.v3d-front::after,
.v3d-back::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 4px;
    pointer-events: none;
    background:
        /* sheen */
        linear-gradient(105deg,
            rgba(255, 255, 255, 0) 28%,
            rgba(255, 255, 255, .10) 43%,
            rgba(255, 255, 255, .02) 55%,
            rgba(255, 255, 255, 0) 68%),
        /* gutter shading, strongest at the fold */
        linear-gradient(90deg,
            rgba(0, 0, 0, .26) 0%,
            rgba(0, 0, 0, .10) 3.5%,
            rgba(0, 0, 0, .02) 9%,
            rgba(0, 0, 0, 0) 18%,
            rgba(0, 0, 0, 0) 88%,
            rgba(0, 0, 0, .07) 100%);
}
/* A back cover's fold is on the other side, so its shading mirrors. */
.v3d-back::after { transform: scaleX(-1); }
.v3d-back  { transform: rotateY(180deg) translateZ(calc(var(--d, 16px) / 2)); }
/* Spine (left, navy) and page edge (right, paper) */
.v3d-spine, .v3d-edge {
    top: 0; bottom: 0;
    width: var(--d, 16px);
    left: calc(50% - var(--d, 16px) / 2);
    border-radius: 2px;
}
/* The supplied covers are PHOTOGRAPHS of a book: they already carry their own
   spine, page block, page curvature and lighting. Drawing CSS faces as well
   gave every title two spines and two page blocks a few pixels apart, and the
   flat gradients read as plastic against the photography. The photograph wins —
   it is the thing that looks real — so the synthetic faces are switched off.
   They remain defined below for any future product supplied as a flat cover
   scan rather than a mockup; such a product would set .viewer-3d--flat. */
.v3d-spine, .v3d-edge, .v3d-top, .v3d-bottom { display: none; }
.viewer-3d--flat .v3d-spine,
.viewer-3d--flat .v3d-edge,
.viewer-3d--flat .v3d-top,
.viewer-3d--flat .v3d-bottom { display: block; }

.v3d-spine {
    background: linear-gradient(90deg,
        var(--spine-dark, var(--navy)) 0%,
        var(--spine, var(--navy)) 45%,
        var(--spine-dark, var(--navy)) 100%);
    transform: rotateY(-90deg) translateZ(calc(var(--w, 200px) / 2));
}
/* Page block: fine leaves, warm not grey, darker where they meet the cover.
   The old 2px stripes read as a barcode at this scale. */
/* Page block. #FBF8F1 was effectively paper-white, so at a glance it read as a
   white slab stuck behind the book rather than as page edges. Real trimmed
   leaves are cream going to tan, and they sit in shadow where they meet the
   cover — that shading is most of what makes them read as paper. */
.v3d-edge  {
    background:
        linear-gradient(90deg, rgba(60,44,24,.42) 0%, rgba(60,44,24,.10) 30%, rgba(60,44,24,.04) 62%, rgba(60,44,24,.24) 100%),
        repeating-linear-gradient(90deg, #EFE6D2 0 1px, #DCCFB4 1px 2px);
    transform: rotateY(90deg) translateZ(calc(var(--w, 200px) / 2));
}
.v3d-top, .v3d-bottom {
    left: 0; right: 0;
    height: var(--d, 16px);
    top: calc(50% - var(--d, 16px) / 2);
    background:
        linear-gradient(0deg, rgba(60,44,24,.30) 0%, rgba(60,44,24,.04) 40%, rgba(60,44,24,.14) 100%),
        repeating-linear-gradient(90deg, #EFE6D2 0 1px, #DCCFB4 1px 2px);
    border-radius: 1px;
}
.v3d-top    { transform: rotateX(90deg) translateZ(calc(var(--h, 250px) / 2)); }
.v3d-bottom { transform: rotateX(-90deg) translateZ(calc(var(--h, 250px) / 2)); }
.viewer-3d--bundle .v3d-spine { background: linear-gradient(180deg, var(--navy) 0%, var(--navy-2) 100%); border-left: 2px solid var(--gold); }

/* Minimalist controls: three quiet circles, bottom centre */
.v3d-controls {
    position: absolute;
    bottom: .9rem; left: 50%;
    transform: translateX(-50%);
    display: flex; gap: .45rem;
    z-index: 3;
}
.v3d-controls button {
    width: 2rem; height: 2rem;
    border: 1px solid var(--line);
    border-radius: 50%;
    background: var(--white);
    color: var(--ink-soft);
    font-size: .95rem; line-height: 1;
    display: inline-flex; align-items: center; justify-content: center;
    transition: border-color .15s, color .15s;
}
.v3d-controls button:hover { border-color: var(--navy); color: var(--navy); }
.v3d-hint {
    position: absolute;
    bottom: .2rem; left: 0; right: 0;
    margin: 0;
    text-align: center;
    font-size: .66rem;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--ink-soft);
    opacity: .75;
    pointer-events: none;
    transition: opacity .4s ease;
}
.viewer-3d.has-interacted .v3d-hint { opacity: 0; }
@media (max-width: 560px) {
    .v3d-object { width: 74%; }
}
@media (prefers-reduced-motion: reduce) {
    .v3d-object.is-settling { transition: none; }
}

/* ── Product page ────────────────────────────────────────────────────── */
.breadcrumbs { font-size: .8rem; color: var(--ink-soft); margin-bottom: 1.6rem; }
.breadcrumbs a { color: inherit; text-decoration: none; }
.breadcrumbs a:hover { color: var(--brass); }
.product-layout { display: grid; gap: clamp(2rem, 5vw, 4rem); grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); align-items: start; }
@media (max-width: 900px) { .product-layout { grid-template-columns: 1fr; } }

.product-gallery .frame { margin-bottom: 1rem; }
.gallery-thumbs { display: flex; gap: .7rem; flex-wrap: wrap; }
.gallery-thumbs button {
    border: 1px solid var(--line); background: var(--white); padding: 3px; border-radius: var(--radius-sm); line-height: 0;
}
.gallery-thumbs button.is-active { border-color: var(--gold); }
.gallery-thumbs img,
.gallery-thumbs video { width: 3.6rem; height: 3.6rem; object-fit: cover; border-radius: 5px; display: block; }

/* Video thumbnails carry a play badge so a clip is recognisable before it is
   opened — the first frame alone often looks identical to a still. */
.gallery-thumbs button.is-video { position: relative; }
.gallery-thumbs .thumb-play {
    position: absolute; inset: 0; display: grid; place-items: center;
    font-size: .95rem; color: #fff; text-shadow: 0 1px 4px rgba(0, 0, 0, .65);
    background: rgba(11, 31, 59, .28); border-radius: 5px; pointer-events: none;
}

/* The clip sits in the 3D viewer's front face, so it must fill that face the
   same way the still does or the object's proportions change when switching. */
[data-gallery-video] { width: 100%; height: 100%; object-fit: cover; display: block; background: #000; }
[data-gallery-video][hidden], [data-gallery-main][hidden] { display: none; }

/* ── Full-resolution zoom lightbox ───────────────────────────────────── */
.v3d-controls [data-lightbox-open] { font-size: .85rem; }
.lightbox {
    position: fixed; inset: 0; z-index: 200;
    display: flex; align-items: center; justify-content: center;
}
.lightbox[hidden] { display: none; }
.lightbox-backdrop { position: absolute; inset: 0; background: rgba(11, 20, 33, .92); }
.lightbox-shell {
    position: relative; z-index: 1;
    width: min(94vw, 78rem); height: min(90vh, 60rem);
    display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.lightbox-stage {
    position: relative; width: 100%; flex: 1;
    overflow: hidden; cursor: zoom-in; touch-action: none;
}
.lightbox-stage.is-zoomed { cursor: grab; }
.lightbox-stage.is-panning { cursor: grabbing; }
.lightbox-stage img {
    position: absolute; top: 50%; left: 50%;
    max-width: 100%; max-height: 100%;
    width: auto; height: auto;
    transform: translate(-50%, -50%) translate(var(--px, 0px), var(--py, 0px)) scale(var(--lz, 1));
    transform-origin: center center;
    user-select: none; -webkit-user-drag: none;
    box-shadow: 0 30px 70px -30px rgba(0, 0, 0, .6);
    border-radius: 4px;
    transition: transform .15s ease-out;
}
.lightbox-stage.is-panning img { transition: none; }
.lightbox-close, .lightbox-nav {
    position: absolute; z-index: 2;
    background: rgba(255, 255, 255, .12); color: #fff;
    border: 1px solid rgba(255, 255, 255, .3);
    border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    transition: background .15s, border-color .15s;
}
.lightbox-close:hover, .lightbox-nav:hover { background: rgba(255, 255, 255, .22); border-color: rgba(255, 255, 255, .6); }
.lightbox-close { top: -.2rem; right: 0; width: 2.6rem; height: 2.6rem; font-size: 1.1rem; }
.lightbox-nav { top: 50%; transform: translateY(-50%); width: 3rem; height: 3rem; font-size: 1.6rem; line-height: 1; }
.lightbox-prev { left: -.5rem; }
.lightbox-next { right: -.5rem; }
@media (max-width: 720px) {
    .lightbox-close { top: -2.4rem; right: -.2rem; }
    .lightbox-prev { left: .2rem; }
    .lightbox-next { right: .2rem; }
}
.lightbox-hint {
    margin: .8rem 0 0; text-align: center; font-size: .72rem;
    letter-spacing: .06em; text-transform: uppercase; color: rgba(255, 255, 255, .7);
}
.lightbox-count {
    position: absolute; top: -.05rem; left: 0; margin: 0;
    font-size: .78rem; font-weight: 600; color: rgba(255, 255, 255, .85);
    background: rgba(255, 255, 255, .12); border-radius: 99px; padding: .3rem .8rem;
}

.product-info h1 { font-size: clamp(1.8rem, 3.4vw, 2.4rem); margin-bottom: .3rem; }
.product-sub { color: var(--ink-soft); margin-bottom: .5rem; }

/* Author / imprint line — the publisher's signature on the page. */
.byline {
    font-family: var(--font-display); font-size: 1rem; color: var(--ink-soft);
    margin: 0 0 1.1rem; font-style: italic;
}
.byline span { color: var(--navy); font-style: normal; font-weight: 550; }

/* Edition details, set like a colophon rather than a spec sheet. */
.edition { margin: 1.6rem 0 1.5rem; }
.edition-head {
    font-family: var(--font-ui); font-size: .72rem; font-weight: 700;
    letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft);
    margin: 0 0 .9rem; padding-bottom: .55rem; border-bottom: 1px solid var(--navy);
}
.edition-grid { margin: 0; display: grid; gap: 0; }
.edition-grid > div {
    display: grid; grid-template-columns: 8.5rem 1fr; gap: 1rem;
    padding: .5rem 0; border-bottom: 1px solid var(--line);
}
.edition-grid > div:last-child { border-bottom: 0; }
.edition-grid dt { color: var(--ink-soft); font-size: .84rem; }
.edition-grid dd { margin: 0; font-size: .88rem; color: var(--ink); font-weight: 500; }
@media (max-width: 480px) {
    .edition-grid > div { grid-template-columns: 1fr; gap: .1rem; }
    .edition-grid dt { font-size: .72rem; text-transform: uppercase; letter-spacing: .06em; }
}
.rating-row { display: flex; align-items: center; gap: .6rem; font-size: .85rem; color: var(--ink-soft); margin-bottom: 1.2rem; }
.rating-row .stars { color: var(--gold); letter-spacing: .1em; }
.price-row { display: flex; align-items: baseline; gap: .8rem; margin-bottom: 1.3rem; }
.price-row .price-now { font-family: var(--font-display); font-size: 2.1rem; font-weight: 560; color: var(--navy); }
.price-row s { color: var(--ink-soft); }
.price-row .save-tag { background: var(--brass-pale); color: var(--brass-deep); font-size: .72rem; font-weight: 700; padding: .27rem .6rem; border-radius: 99px; letter-spacing: .06em; }

.buy-box { display: flex; gap: .7rem; flex-wrap: wrap; margin-bottom: 1.2rem; }
.buy-box form { flex: 1 1 14rem; }
/* Two even columns rather than free-flowing flex: wrapping left a ragged
   3 + 2 split with the last item stranded, and the ticks did not line up. */
.trust-row {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: .55rem 1.4rem;
    font-size: .8rem;
    color: var(--ink-soft);
    padding: 1rem 0;
    border-block: 1px solid var(--line);
    margin-bottom: 1.4rem;
}
.trust-row span { display: flex; align-items: baseline; gap: .4rem; }
.trust-row span::before { content: '✓'; color: var(--brass); font-weight: 700; flex: none; }
@media (max-width: 26rem) { .trust-row { grid-template-columns: 1fr; } }

.spec-table { width: 100%; border-collapse: collapse; font-size: .88rem; margin-bottom: 1.5rem; }
.spec-table th, .spec-table td { text-align: left; padding: .55rem 0; border-bottom: 1px solid var(--line); vertical-align: top; }
.spec-table th { color: var(--ink-soft); font-weight: 550; width: 38%; padding-right: 1rem; }
[dir="rtl"] .spec-table th, [dir="rtl"] .spec-table td { text-align: right; }

/* "About this book" — set like the opening of a book, not a form field:
   a larger serif lede, a labelled feature list standing in for what a print
   book would set as a boxed "what's inside" panel, and a closing line that
   reads like a jacket-copy sign-off rather than another paragraph. */
.prose { max-width: 44rem; }
.prose h2, .prose h3 { margin-top: 1.6em; }
.prose p { color: var(--ink-soft); line-height: 1.75; }
.prose strong { color: var(--navy); font-weight: 650; }
.prose a { color: var(--brass); text-underline-offset: .18em; }

.prose > p:first-of-type {
    font-family: var(--font-display);
    font-size: 1.2rem;
    font-weight: 380;
    line-height: 1.6;
    color: var(--ink);
}

.prose ul {
    list-style: none;
    margin: 1.9rem 0 1.7rem;
    padding: .2rem 1.1rem;
    background: var(--paper-deep);
    border-radius: var(--radius-sm);
}
.prose li {
    position: relative;
    margin: 0;
    padding: .7rem 0 .7rem 1.7rem;
    color: var(--ink);
    line-height: 1.5;
    border-bottom: 1px solid var(--line);
}
.prose li:last-child { border-bottom: 0; }

/* A list item that's just a bold lead-in ("**What's inside:**", written with
   no blank line before the list it introduces) renders as the list's own
   label row instead of another checkable line. */
.prose li:first-child:has(> strong:only-child) {
    padding-left: 0;
    font-family: var(--font-ui);
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--brass-deep);
}
.prose li:first-child:has(> strong:only-child) strong { color: inherit; font-weight: inherit; }
.prose li:first-child:has(> strong:only-child)::before { content: none; }

.prose li::before {
    content: '';
    position: absolute;
    left: 0;
    top: .95rem;
    width: 1rem;
    height: 1rem;
    border-radius: 50%;
    background-color: var(--brass-pale);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23A87F1F' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.5 8.5l3 3 6-7'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 60%;
}

/* The last paragraph, when there's more than the lede alone, reads as a
   closing line rather than more body copy. */
.prose > p:last-of-type:not(:first-of-type) {
    margin-top: 1.9rem;
    padding-top: 1.6rem;
    border-top: 1px solid var(--line);
    font-family: var(--font-display);
    font-style: italic;
    font-size: 1.05rem;
    color: var(--ink-soft);
}

/* Standalone FAQ section: hold a readable measure instead of running the
   full page width now that it sits below the description, not in the rail. */
.faq-list { max-width: 44rem; }
details.faq-item { border-bottom: 1px solid var(--line); }
details.faq-item summary {
    cursor: pointer; padding: 1rem 0; font-weight: 600; font-size: .95rem; list-style: none;
    display: flex; justify-content: space-between; align-items: center; gap: 1rem;
}
details.faq-item summary::after { content: '+'; font-family: var(--font-display); font-size: 1.3rem; color: var(--brass); }
details.faq-item[open] summary::after { content: '–'; }
details.faq-item p { color: var(--ink-soft); font-size: .92rem; margin: 0 0 1.1rem; }

/* Bundle contents list */
.bundle-items { list-style: none; margin: 0 0 1.5rem; padding: 0; }
.bundle-items li {
    display: flex; align-items: center; gap: .9rem;
    padding: .75rem 0; border-bottom: 1px solid var(--line);
}
.bundle-items img { width: 3rem; height: 3.7rem; object-fit: cover; border-radius: 6px; border: 1px solid var(--line); }
.bundle-items .bi-title { font-weight: 600; text-decoration: none; color: var(--ink); }
.bundle-items .bi-title:hover { color: var(--brass); }
.bundle-items .bi-meta { font-size: .78rem; color: var(--ink-soft); }
.bundle-items .bi-price { margin-left: auto; font-size: .85rem; color: var(--ink-soft); }
[dir="rtl"] .bundle-items .bi-price { margin-left: 0; margin-right: auto; }

/* Sticky mobile buy bar */
.sticky-buy { display: none; }
@media (max-width: 900px) {
    .sticky-buy {
        display: flex; position: fixed; bottom: 0; left: 0; right: 0; z-index: 60;
        background: var(--white); border-top: 1px solid var(--line);
        padding: .7rem var(--gutter) calc(.7rem + env(safe-area-inset-bottom));
        gap: 1rem; align-items: center;
        box-shadow: 0 -8px 24px -16px rgba(11,31,59,.4);
    }
    .sticky-buy .sb-price { font-family: var(--font-display); font-weight: 600; font-size: 1.25rem; color: var(--navy); }
    .sticky-buy form { flex: 1; }
    body.has-sticky-buy { padding-bottom: 4.6rem; }
}

/* ── Cart & checkout ─────────────────────────────────────────────────── */
.cart-layout { display: grid; gap: 2.5rem; grid-template-columns: minmax(0, 7fr) minmax(0, 4fr); align-items: start; }
@media (max-width: 900px) { .cart-layout { grid-template-columns: 1fr; } }
.cart-line {
    display: grid; grid-template-columns: 4.6rem 1fr auto; gap: 1.1rem; align-items: center;
    padding-block: 1.1rem; border-bottom: 1px solid var(--line);
}
.cart-line img { width: 4.6rem; height: 4.6rem; object-fit: cover; border-radius: var(--radius-sm); border: 1px solid var(--line); background: var(--white); }
.cart-line .line-title { font-weight: 600; text-decoration: none; }
.cart-line .line-title:hover { color: var(--brass); }
.cart-line .line-meta { font-size: .78rem; color: var(--ink-soft); }
.cart-line .line-price { font-weight: 700; }
.cart-line .line-remove { background: none; border: 0; color: var(--ink-soft); font-size: .78rem; text-decoration: underline; padding: 0; margin-top: .2rem; }
.cart-line .line-remove:hover { color: var(--error); }

.order-summary {
    background: var(--white); border: 1px solid var(--line); border-radius: var(--radius);
    padding: 1.5rem; box-shadow: var(--shadow-frame);
}
.summary-row { display: flex; justify-content: space-between; font-size: .92rem; padding: .35rem 0; }
.summary-row.total { border-top: 1px solid var(--line); margin-top: .6rem; padding-top: .9rem; font-weight: 700; font-size: 1.05rem; }
.summary-row .disc { color: var(--success); }
.coupon-form { display: flex; gap: .5rem; margin-top: 1rem; }
.coupon-form input { flex: 1; padding: .55rem .8rem; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--paper-deep); text-transform: uppercase; }
.coupon-tag { display: inline-flex; align-items: center; gap: .5rem; background: var(--success-bg); color: var(--success); font-size: .8rem; font-weight: 650; padding: .32rem .75rem; border-radius: 99px; margin-top: .8rem; }
.coupon-tag button { background: none; border: 0; color: inherit; font-weight: 700; padding: 0; }

/* Forms */
.form-card { max-width: 26rem; background: var(--white); border: 1px solid var(--line); border-radius: var(--radius); padding: 2rem; margin-inline: auto; box-shadow: var(--shadow-frame); }
.form-card-wide { max-width: 36rem; }
.field { margin-bottom: 1.05rem; }
.field label { display: block; font-size: .82rem; font-weight: 600; margin-bottom: .3rem; }
.field input, .field select, .field textarea {
    width: 100%; padding: .68rem .85rem;
    border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--paper-deep);
}
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--gold); outline: none; box-shadow: 0 0 0 3px var(--brass-pale); background: #fff; }
.field .hint { font-size: .76rem; color: var(--ink-soft); margin-top: .25rem; }
/* A value the form derives rather than asks for. Deliberately not styled as a
   disabled input: a greyed-out control reads as "you may be able to change
   this", and this one is a consequence, not a setting. */
.field .static-value {
    margin: 0; padding: .55rem .7rem;
    font-size: .9rem; font-weight: 600;
    background: var(--paper-deep); border: 1px solid var(--line); border-radius: 6px;
}

/* ── HR calendar ─────────────────────────────────────────────────────────── */

.admin-layout .cal-kinds {
    display: flex; flex-wrap: wrap; gap: .5rem 1rem;
    width: 100%; margin-top: .4rem;
}
.admin-layout .cal-kind { font-size: .78rem; }
.admin-layout .cal-kind span::before {
    content: ''; display: inline-block; width: .5rem; height: .5rem;
    border-radius: 50%; margin-right: .4rem; background: var(--c-ink-3);
    vertical-align: baseline;
}
/* One colour per event kind, used on both the filter dot and the event's left
   rule, so the filter legend and the list teach each other. */
.admin-layout .cal-leave span::before,       .admin-layout li.cal-leave       { --cal: #3B6EA5; }
.admin-layout .cal-onboarding span::before,  .admin-layout li.cal-onboarding  { --cal: #2E7D5B; }
.admin-layout .cal-probation span::before,   .admin-layout li.cal-probation   { --cal: #B0641C; }
.admin-layout .cal-review span::before,      .admin-layout li.cal-review      { --cal: #6A4C9C; }
.admin-layout .cal-training span::before,    .admin-layout li.cal-training    { --cal: #1F7A8C; }
.admin-layout .cal-contract span::before,    .admin-layout li.cal-contract    { --cal: #A33; }
.admin-layout .cal-interview span::before,   .admin-layout li.cal-interview   { --cal: #8A6D1F; }
.admin-layout .cal-anniversary span::before, .admin-layout li.cal-anniversary { --cal: #B5852A; }
.admin-layout .cal-holiday span::before,     .admin-layout li.cal-holiday     { --cal: #7A7A7A; }
.admin-layout .cal-kind span::before { background: var(--cal, var(--c-ink-3)); }

.admin-layout .cal-list {
    border: 1px solid var(--c-line); border-radius: 8px; overflow: hidden;
    background: var(--c-surface);
}
.admin-layout .cal-day {
    display: grid; grid-template-columns: 9rem minmax(0, 1fr);
    border-top: 1px solid var(--c-line);
}
.admin-layout .cal-day:first-child { border-top: 0; }
.admin-layout .cal-day.is-past { opacity: .62; }
.admin-layout .cal-day.is-today { background: #FBFAF6; }
.admin-layout .cal-date {
    padding: .7rem .9rem; font-size: .82rem; color: var(--c-ink-2);
    border-right: 1px solid var(--c-line);
}
.admin-layout .cal-badge {
    display: inline-block; margin-left: .35rem; padding: 0 .35rem;
    font-size: .64rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
    color: #7A5B12; background: #F6EDD8; border-radius: 3px;
}
.admin-layout .cal-events { list-style: none; margin: 0; padding: .45rem .6rem; }
.admin-layout .cal-event {
    padding: .3rem .6rem; margin: .15rem 0; font-size: .84rem;
    border-left: 3px solid var(--cal, var(--c-ink-3));
}
.admin-layout .cal-event.needs-action { background: #FDF6EC; }
.admin-layout .cal-kind-tag {
    display: inline-block; min-width: 8.5rem;
    font-size: .68rem; font-weight: 600; letter-spacing: .05em; text-transform: uppercase;
    color: var(--c-ink-3);
}
@media (max-width: 760px) {
    .admin-layout .cal-day { grid-template-columns: 1fr; }
    .admin-layout .cal-date { border-right: 0; border-bottom: 1px solid var(--c-line); }
    .admin-layout .cal-kind-tag { min-width: 0; display: block; }
}

/* Checkbox lists. Each label is sized to its own content — a full-width label
   lets the box and its text drift to opposite ends of a wide field, which is
   exactly what happened to the Future editions block. */
.field .check-list { display: flex; flex-direction: column; gap: .35rem; margin-top: .2rem; }
.field .check-item {
    display: inline-flex; align-items: center; gap: .5rem;
    width: fit-content; max-width: 100%;
    font-weight: 500; font-size: .85rem; cursor: pointer;
}
.field .check-item input { flex: 0 0 auto; margin: 0; }
.field .check-item span { flex: 1 1 auto; }
.field-consent { display: flex; gap: .6rem; align-items: flex-start; font-size: .82rem; color: var(--ink-soft); }
.field-consent input { width: auto; margin-top: .22rem; }
.form-foot { font-size: .85rem; color: var(--ink-soft); text-align: center; margin-top: 1.1rem; }

/* Contact page */
.contact-layout { display: grid; gap: 2.5rem; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); align-items: start; }
@media (max-width: 900px) { .contact-layout { grid-template-columns: 1fr; } }
.contact-card { background: var(--white); border: 1px solid var(--line); border-radius: var(--radius); padding: 1.5rem 1.6rem; margin-bottom: 1.1rem; }
.contact-card h3 { font-size: 1.02rem; margin-bottom: .35rem; }
.contact-card p { font-size: .88rem; color: var(--ink-soft); margin: 0 0 .4rem; }
.contact-card a { color: var(--brass); font-weight: 600; text-decoration: none; }
.contact-card a:hover { text-decoration: underline; }
.form-tabs { display: flex; gap: .5rem; flex-wrap: wrap; margin-bottom: 1.6rem; }

/* Flash messages */
.flash-stack { position: fixed; top: 4.6rem; right: 1rem; z-index: 100; display: flex; flex-direction: column; gap: .6rem; max-width: 23rem; }
[dir="rtl"] .flash-stack { right: auto; left: 1rem; }
.flash {
    padding: .8rem 2.4rem .8rem 1rem; border-radius: var(--radius-sm); font-size: .88rem; font-weight: 550;
    box-shadow: 0 10px 30px -12px rgba(11,31,59,.4); position: relative;
    animation: flash-in .3s ease;
}
.flash-success { background: var(--success-bg); color: var(--success); border: 1px solid #BAD8C6; }
.flash-error { background: var(--error-bg); color: var(--error); border: 1px solid #E8C4BF; }
.flash .flash-close { position: absolute; top: .35rem; right: .55rem; background: none; border: 0; color: inherit; font-size: 1rem; }
@keyframes flash-in { from { opacity: 0; transform: translateX(12px); } }
@media (prefers-reduced-motion: reduce) { .flash { animation: none; } }

/* ── Download / success ──────────────────────────────────────────────── */
.download-card {
    display: flex; align-items: center; gap: 1.1rem; flex-wrap: wrap;
    background: var(--white); border: 1px solid var(--line); border-radius: var(--radius);
    padding: 1.1rem 1.3rem; margin-bottom: .8rem;
}
.download-card img { width: 3.8rem; height: 3.8rem; object-fit: cover; border-radius: var(--radius-sm); border: 1px solid var(--line); }
.download-card .dl-info { flex: 1 1 12rem; }
.download-card .dl-info strong { display: block; }
.download-card .dl-info span { font-size: .78rem; color: var(--ink-soft); }

.download-file-list { list-style: none; margin: 1.4rem 0 0; padding: 0; }
.download-file-list li {
    display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
    background: var(--white); border: 1px solid var(--line); border-radius: var(--radius);
    padding: .9rem 1.2rem; margin-bottom: .7rem;
}
.download-file-list .download-file-name { font-weight: 600; flex: 1 1 14rem; }
.download-file-list .btn { margin-left: auto; }
[dir="rtl"] .download-file-list .btn { margin-left: 0; margin-right: auto; }

/* ── Account ─────────────────────────────────────────────────────────── */
.account-grid { display: grid; gap: 2rem; grid-template-columns: minmax(0, 8fr) minmax(0, 4fr); align-items: start; }
@media (max-width: 900px) { .account-grid { grid-template-columns: 1fr; } }
.order-block { background: var(--white); border: 1px solid var(--line); border-radius: var(--radius); padding: 1.3rem 1.4rem; margin-bottom: 1.2rem; }
.order-block .order-head { display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; font-size: .85rem; color: var(--ink-soft); border-bottom: 1px solid var(--line); padding-bottom: .8rem; margin-bottom: .8rem; }
.order-block .order-head strong { color: var(--ink); }

.status-pill { display: inline-block; font-size: .68rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; padding: .22rem .6rem; border-radius: 99px; }
.status-paid { background: var(--success-bg); color: var(--success); }
.status-pending { background: var(--brass-pale); color: var(--brass-deep); }
.status-demo { background: #E8E9F6; color: #3D4785; }
.status-sale { background: var(--error-bg); color: var(--sale); }

/* ── Ecosystem / related brands ──────────────────────────────────────── */
.grid-brands { display: grid; gap: 1.2rem; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); }
.card-brand {
    display: block; text-decoration: none;
    background: var(--white); border: 1px solid var(--line); border-radius: var(--radius);
    padding: 1.5rem 1.5rem 1.4rem;
    transition: border-color .18s ease, transform .18s ease, box-shadow .18s ease;
}
.card-brand:hover { border-color: var(--gold); transform: translateY(-2px); box-shadow: var(--shadow-frame); }
.card-brand h3 { font-size: 1.1rem; margin-bottom: .25rem; }
.card-brand h3 span { color: var(--brass); }
.card-brand p { font-size: .86rem; color: var(--ink-soft); margin: 0 0 .7rem; }
.card-brand .go { color: var(--brass); font-weight: 700; font-size: .84rem; }

/* ── Cookie consent ──────────────────────────────────────────────────── */
#mpConsent {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 10000;
  background: var(--navy); border-top: 1px solid rgba(201,155,46,0.4);
  box-shadow: 0 -8px 30px rgba(0,0,0,0.25);
}
.mp-consent-inner {
  max-width: 1200px; margin: 0 auto; padding: 1.1rem 5vw;
  display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; flex-wrap: wrap;
}
.mp-consent-text { font-size: 0.85rem; line-height: 1.55; color: #A9B8CD; margin: 0; max-width: 62ch; }
.mp-consent-text a { color: var(--gold); text-decoration: underline; }
.mp-consent-actions { display: flex; gap: 0.7rem; flex-shrink: 0; }
.mp-consent-decline, .mp-consent-accept {
  font-family: inherit; font-size: 0.85rem; font-weight: 700; cursor: pointer;
  border-radius: 99px; padding: 0.6rem 1.3rem; transition: all 0.18s;
}
.mp-consent-decline { background: transparent; border: 1.5px solid rgba(255,255,255,0.3); color: #E4E9F0; }
.mp-consent-decline:hover { border-color: rgba(255,255,255,0.55); }
.mp-consent-accept { background: var(--gold); border: 1.5px solid var(--gold); color: var(--navy); }
.mp-consent-accept:hover { filter: brightness(1.08); }
@media (max-width: 640px) { .mp-consent-inner { flex-direction: column; align-items: stretch; } .mp-consent-actions { justify-content: flex-end; } }

/* ── Footer ──────────────────────────────────────────────────────────── */
.site-footer { background: var(--navy); color: #A9B8CD; margin-top: auto; }
.footer-grid { display: grid; gap: 2rem; grid-template-columns: 2fr 1fr 1fr 1fr 1fr; padding-block: 3.2rem 2.4rem; }
@media (max-width: 900px) { .footer-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 520px) { .footer-grid { grid-template-columns: 1fr; } }
.site-footer .logo { color: #fff; }
.site-footer .logo .logo-art { color: var(--gold); }
.site-footer h4 { color: #fff; font-family: var(--font-ui); font-size: .76rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; margin-bottom: .9rem; }
.site-footer ul { list-style: none; margin: 0; padding: 0; }
.site-footer li { margin: .45rem 0; }
.site-footer a { color: #A9B8CD; text-decoration: none; font-size: .9rem; }
.site-footer a:hover { color: #fff; }
.footer-legal {
    border-top: 1px solid #22385C; padding-block: 1.2rem;
    display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
    font-size: .78rem;
}

/* Floating contact widget — a real message form, not a chat simulation.
   Disclosure-widget based, so it works with no JS and is keyboard-accessible. */
.chat-widget { position: fixed; bottom: 1.2rem; right: 1.2rem; z-index: 55; }
[dir="rtl"] .chat-widget { right: auto; left: 1.2rem; }
.chat-widget summary {
    list-style: none; cursor: pointer;
    width: 3.2rem; height: 3.2rem; border-radius: 50%;
    background: var(--navy); color: #fff;
    display: flex; align-items: center; justify-content: center;
    box-shadow: 0 12px 28px -10px rgba(11, 31, 59, .55);
    transition: transform .18s ease, background .18s ease;
}
.chat-widget summary::-webkit-details-marker { display: none; }
.chat-widget summary:hover { transform: translateY(-2px); background: var(--navy-2); }
.chat-widget[open] summary { background: var(--navy-2); }
.chat-widget-panel {
    position: absolute; bottom: calc(100% + .7rem); right: 0;
    width: min(20rem, calc(100vw - 2.4rem));
    background: var(--white); border: 1px solid var(--line); border-radius: var(--radius);
    box-shadow: 0 22px 50px -18px rgba(11, 31, 59, .45);
    padding: 1.1rem;
    /* Short viewports (landscape phones) can't fit the full form — cap it
       and scroll inside rather than letting it run off the top of the screen. */
    max-height: min(70vh, 26rem); overflow-y: auto;
}
[dir="rtl"] .chat-widget-panel { right: auto; left: 0; }
.chat-widget-panel h4 { margin: 0 0 .2rem; font-size: 1rem; }

/* ── Shop assistant ──────────────────────────────────────────────────────
   The log has a fixed height rather than growing the panel: a floating
   widget that lengthens with every reply eventually pushes its own input
   off the bottom of a phone screen, which is where people use it. */
.asst-log { max-height: 16rem; overflow-y: auto; display: flex; flex-direction: column; gap: .5rem;
            margin: .2rem 0 .7rem; padding-right: .2rem; }
.asst-log:empty { display: none; }
.asst-msg { font-size: .86rem; line-height: 1.45; padding: .5rem .65rem; border-radius: .6rem; max-width: 92%; }
.asst-you { align-self: flex-end; background: var(--navy); color: #fff; }
.asst-you a { color: #fff; }
.asst-bot { align-self: flex-start; background: var(--paper-deep); color: var(--ink); border: 1px solid var(--line); }
.asst-msg a { text-decoration: underline; }
.asst-row { display: flex; gap: .4rem; }
.asst-row input { flex: 1 1 auto; min-width: 0; }
.asst-row .btn { flex: 0 0 auto; }
@media (prefers-reduced-motion: no-preference) { .asst-log { scroll-behavior: smooth; } }

.chat-widget-panel .field { margin-bottom: .5rem; }
.chat-widget-panel input[type=text],
.chat-widget-panel input[type=email],
.chat-widget-panel textarea {
    width: 100%; padding: .5rem .7rem; font-size: .88rem;
    border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--paper-deep);
}
.chat-widget-panel textarea { resize: vertical; }
@media (max-width: 900px) {
    body.has-sticky-buy .chat-widget { bottom: 5.4rem; }
}

/* ── Admin ───────────────────────────────────────────────────────────── */
.admin-layout { display: grid; grid-template-columns: 13rem 1fr; min-height: 100vh; }
@media (max-width: 900px) { .admin-layout { grid-template-columns: 1fr; } }
.admin-side { background: var(--navy); color: #A9B8CD; padding: 1.4rem 1.2rem; }
.admin-side .logo { color: #fff; font-size: 1.1rem; display: block; margin-bottom: 1.6rem; }
.admin-side nav a { display: block; color: #A9B8CD; text-decoration: none; font-size: .9rem; padding: .5rem .6rem; border-radius: 6px; }
.admin-side nav a:hover { color: #fff; background: var(--navy-2); }
.admin-side nav a.is-active { color: #fff; background: var(--navy-2); border-left: 3px solid var(--gold); }
.admin-main { padding: clamp(1.2rem, 3vw, 2.4rem); background: var(--paper-deep); }
.admin-head { display: flex; justify-content: space-between; align-items: center; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.6rem; }
.admin-head h1 { font-size: 1.6rem; margin: 0; }

.stat-grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); margin-bottom: 2rem; }
.stat-card { background: var(--white); border: 1px solid var(--line); border-radius: var(--radius); padding: 1.1rem 1.2rem; }
.stat-card .stat-label { font-size: .72rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft); }
/* Qualifier under a stat, for when the number alone would be read as more than
   it is ("subscribers" that have not confirmed, for instance). */
.stat-card .stat-note { display: block; margin-top: .3rem; font-size: .72rem; color: var(--ink-soft); }
.stat-card .stat-value { font-family: var(--font-display); font-size: 1.7rem; font-weight: 560; color: var(--navy); }

.data-table { width: 100%; border-collapse: collapse; background: var(--white); border: 1px solid var(--line); border-radius: var(--radius); font-size: .88rem; }
.data-table th { text-align: left; font-size: .72rem; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft); padding: .7rem .9rem; border-bottom: 1px solid var(--line); }
.data-table td { padding: .7rem .9rem; border-bottom: 1px solid var(--paper-deep); vertical-align: middle; }
.data-table tr:last-child td { border-bottom: 0; }
.data-table a { color: var(--brass); text-decoration: none; font-weight: 600; }
.data-table .thumb { width: 2.6rem; height: 2.6rem; object-fit: cover; border-radius: 6px; border: 1px solid var(--line); }
.table-scroll { overflow-x: auto; }
.data-table th:first-child, .data-table td:first-child { width: 1.6rem; padding-right: 0; }

/* Bulk-select action bar — sticky under the admin header while any row is
   checked, so "how many am I about to delete" stays visible while scrolling
   a long list. */
.bulk-bar {
    position: sticky; top: 0; z-index: 5;
    display: flex; align-items: center; gap: 1rem;
    background: var(--navy); color: #fff;
    border-radius: var(--radius-sm);
    padding: .7rem 1rem; margin-bottom: .9rem;
    font-size: .86rem;
    box-shadow: 0 10px 24px -14px rgba(11, 31, 59, .5);
}
.bulk-bar strong { color: var(--gold); font-family: var(--font-display); font-size: 1.05rem; }
.bulk-bar .btn { margin-left: auto; }

/* ── Reports dashboard ──────────────────────────────────────────────── */
.reports-card {
    background: var(--white); border: 1px solid var(--line); border-radius: var(--radius);
    padding: 1.4rem 1.5rem; margin-bottom: 1.4rem;
}
.reports-card h3 { font-size: 1.05rem; margin: 0 0 .3rem; color: var(--navy); }
.reports-tabs { display: flex; gap: 1.5rem; border-bottom: 1px solid var(--line); margin-bottom: 1.3rem; flex-wrap: wrap; }
.reports-tab {
    background: none; border: none; padding: 0 0 .7rem; font: 600 .88rem var(--font-ui); color: var(--ink-soft);
    cursor: pointer; text-decoration: none; border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.reports-tab:hover { color: var(--navy); }
.reports-tab.is-active { color: var(--navy); border-bottom-color: var(--gold); }
.reports-dot { display: inline-block; width: .55rem; height: .55rem; border-radius: 50%; margin-right: .4rem; vertical-align: middle; }
.reports-range-picker { display: flex; gap: 1.5rem; flex-wrap: wrap; align-items: flex-end; margin-bottom: .9rem; }
.reports-range-form { display: flex; gap: .6rem; align-items: flex-end; }
.reports-range-form label { display: flex; flex-direction: column; gap: .3rem; font-size: .74rem; font-weight: 600; color: var(--ink-soft); }
.reports-range-form select, .reports-range-form input[type="date"] {
    border: 1px solid var(--line); border-radius: 8px; padding: .4rem .6rem; font: 500 .84rem var(--font-ui);
    color: var(--ink); background: var(--white);
}
.reports-range-form--custom { gap: .5rem; }
.reports-current-range { font-size: .82rem; color: var(--ink-soft); margin: 0 0 1.2rem; }
.reports-current-range strong { color: var(--navy); }
.reports-stat-row { display: grid; gap: 1.5rem; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); }
.reports-stat { display: flex; flex-direction: column; }
.reports-stat-label { font-size: .78rem; font-weight: 700; color: var(--ink); margin-bottom: .4rem; }
.reports-stat-value { font-family: var(--font-display); font-size: 2rem; font-weight: 560; color: var(--navy); line-height: 1.1; }
.reports-stat-sub { font-size: .78rem; color: var(--ink-soft); margin: .2rem 0 .8rem; }
.reports-stat-link { font-size: .82rem; font-weight: 600; color: var(--brass); text-decoration: none; padding-top: .6rem; border-top: 1px solid var(--paper-deep); }
.reports-stat-link:hover { text-decoration: underline; }
.reports-chart-head { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: .8rem; margin-bottom: .6rem; }
.reports-chart-head h3 { margin: 0; }
.reports-chart-toggle { display: flex; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
.reports-chart-toggle button {
    background: var(--white); border: none; padding: .35rem .8rem; font-size: .8rem; font-weight: 600;
    color: var(--ink-soft); cursor: pointer;
}
.reports-chart-toggle button.is-active { background: var(--navy); color: #fff; }
.reports-chart { margin-top: .5rem; }
.reports-chart svg { overflow: visible; }
.reports-hover-line { stroke: var(--line); stroke-width: 1; opacity: 0; transition: opacity .1s ease; pointer-events: none; }
.reports-hover-line.is-visible { opacity: 1; }

/* Custom tooltip — replaces the browser's native SVG <title> tooltip, which
   has an inconsistent, slow hover delay and can't be styled, so it read as
   "nothing happens" on hover rather than a working chart. */
.reports-tooltip {
    position: fixed; z-index: 60; pointer-events: none;
    background: var(--navy); color: #fff;
    font: 600 .78rem var(--font-ui);
    padding: .5rem .75rem; border-radius: 9px;
    box-shadow: 0 14px 30px -12px rgba(11, 31, 59, .5);
    opacity: 0; transform: translate(-50%, calc(-100% - 12px)) scale(.96);
    transition: opacity .12s ease, transform .12s ease;
    white-space: nowrap;
}
.reports-tooltip.is-visible { opacity: 1; transform: translate(-50%, calc(-100% - 12px)) scale(1); }
.reports-tooltip-date {
    display: block; color: var(--gold); font-size: .64rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: .07em; margin-bottom: .2rem;
}
.reports-tooltip-value { font-family: var(--font-display); font-size: .95rem; font-weight: 560; }
.reports-tooltip::after {
    content: ''; position: absolute; left: 50%; top: 100%; transform: translateX(-50%);
    border: 5px solid transparent; border-top-color: var(--navy);
}
@keyframes reportsGrowUp { from { transform: scaleY(0); } to { transform: scaleY(1); } }
@keyframes reportsFadeIn { from { opacity: 0; } to { opacity: 1; } }
.reports-bar {
    transform-origin: bottom;
    transform-box: fill-box;
    animation: reportsGrowUp .35s cubic-bezier(.25, .8, .35, 1) backwards;
    transition: opacity .15s ease, filter .15s ease;
    cursor: pointer;
}
.reports-bar:hover { opacity: .82; filter: brightness(1.12); }
.reports-line {
    stroke-dasharray: 6000;
    stroke-dashoffset: 6000;
    animation: reportsDraw .7s ease-out forwards;
}
@keyframes reportsDraw { to { stroke-dashoffset: 0; } }
.reports-area { animation: reportsFadeIn .5s ease-in .2s backwards; }
.reports-point {
    animation: reportsFadeIn .3s ease backwards;
    transition: r .15s ease, filter .15s ease;
    cursor: pointer;
}
.reports-point:hover { r: 5.5; filter: brightness(1.15); }
.reports-books { display: grid; gap: 1.2rem; grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr)); margin-top: 1rem; }
.reports-book { display: flex; gap: 1rem; border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 1rem; }
.reports-book-cover { width: 4.5rem; height: 6rem; object-fit: cover; border-radius: 4px; border: 1px solid var(--line); flex-shrink: 0; }
.reports-book-info { flex: 1; min-width: 0; }
.reports-book-metric { display: inline-block; margin-right: 1.3rem; font-family: var(--font-display); font-size: 1.15rem; font-weight: 560; color: var(--navy); }
.reports-book-metric span { display: block; font-family: var(--font-ui); font-size: .68rem; font-weight: 600; color: var(--ink-soft); text-transform: uppercase; letter-spacing: .04em; }
.reports-book-title { margin: .7rem 0 0; font-size: .88rem; color: var(--ink-soft); }
.reports-book-title a { color: var(--navy); font-weight: 600; text-decoration: none; }
.reports-book-title a:hover { text-decoration: underline; }
.reports-donut-grid { display: grid; gap: 1.4rem; grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); }
.reports-donut-row { display: flex; align-items: center; gap: 1.6rem; margin: 1rem 0; }
.reports-donut { width: 9rem; height: 9rem; border-radius: 50%; flex-shrink: 0; position: relative; }
.reports-donut::after { content: ''; position: absolute; inset: 22%; background: var(--white); border-radius: 50%; }
.reports-legend { list-style: none; margin: 0; padding: 0; font-size: .88rem; }
.reports-legend li { display: flex; align-items: center; gap: .5rem; margin-bottom: .6rem; color: var(--ink); }
.reports-swatch { width: .7rem; height: .7rem; border-radius: 50%; flex-shrink: 0; }
@media (max-width: 640px) {
    .reports-donut-row { flex-direction: column; align-items: flex-start; }
}

/* ── Misc ────────────────────────────────────────────────────────────── */
.page-head { padding-block: clamp(2.2rem, 5vw, 3.6rem) 0; }
.divider { border: 0; border-top: 1px solid var(--line); margin-block: clamp(2rem, 5vw, 3rem); }
.demo-note {
    background: #E8E9F6; color: #3D4785; border: 1px solid #CBCEEA; border-radius: var(--radius-sm);
    font-size: .85rem; padding: .8rem 1rem; margin-bottom: 1.2rem;
}
body { display: flex; flex-direction: column; min-height: 100vh; }
main { flex: 1; }

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

/* ═══════════════════════════════════════════════════════════════════════
   Future Harmony redesign — hero accent, feature strip, stats band, icons
   ═══════════════════════════════════════════════════════════════════════ */

/* Hero gold underline accent under the display heading */
.hero-copy h1 { position: relative; }
.hero-underline { display: block; width: 15rem; max-width: 68%; height: .7rem; margin: .3rem 0 0; }

/* Premium icon feature strip (replaces the plain trust bar) */
.feature-strip { padding-block: 0 clamp(2rem, 5vw, 3rem); }
.feature-row {
    background: var(--white); border: 1px solid var(--line); border-radius: var(--radius);
    box-shadow: var(--shadow-frame);
    display: grid; grid-template-columns: repeat(5, 1fr); gap: 1.3rem;
    padding: 1.4rem 1.6rem; max-width: var(--wrap);
}
.feature { display: flex; align-items: center; gap: .75rem; min-width: 0; }
.feature .fi {
    flex: 0 0 auto; width: 2.5rem; height: 2.5rem; border-radius: 11px;
    background: var(--brass-pale); color: var(--brass);
    display: flex; align-items: center; justify-content: center;
}
.feature .fi svg { width: 1.35rem; height: 1.35rem; }
.feature b { display: block; font-family: var(--font-ui); font-size: .9rem; font-weight: 700; color: var(--navy); }
.feature > div > span { display: block; font-size: .75rem; color: var(--ink-soft); line-height: 1.35; }
@media (max-width: 1000px) { .feature-row { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .feature-row { grid-template-columns: 1fr; gap: 1rem; } }

/* Dark stats band */
.stats-band { background: var(--navy); color: #fff; padding-block: clamp(2.4rem, 5vw, 3.4rem); }
.stats-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.5rem; text-align: center; }
.stat { display: flex; flex-direction: column; align-items: center; gap: .3rem; }
.stat .si { width: 2.6rem; height: 2.6rem; color: var(--gold); display: flex; align-items: center; justify-content: center; }
.stat .si svg { width: 1.75rem; height: 1.75rem; }
.stat b { font-family: var(--font-display); font-size: clamp(1.6rem, 3vw, 2.15rem); font-weight: 500; color: #fff; line-height: 1; }
.stat > span { font-size: .85rem; color: #A9B8CD; }
@media (max-width: 860px) { .stats-row { grid-template-columns: repeat(2, 1fr); gap: 1.9rem; } }
@media (max-width: 420px) { .stats-row { grid-template-columns: 1fr; gap: 1.6rem; } .stat { flex-direction: row; justify-content: center; gap: .7rem; text-align: left; } .stat .si { flex: 0 0 auto; } }

/* Footer trust + payment strip */
.footer-trust {
    display: flex; align-items: center; justify-content: space-between; gap: 1.2rem; flex-wrap: wrap;
    padding-block: 1.4rem; border-top: 1px solid rgba(255,255,255,.10);
}
.footer-trust .ft-items { display: flex; gap: 1.8rem; flex-wrap: wrap; }
.footer-trust .ft { display: inline-flex; align-items: center; gap: .5rem; font-size: .82rem; color: #A9B8CD; }
.footer-trust .ft svg { width: 1.2rem; height: 1.2rem; color: var(--gold); flex: 0 0 auto; }
.footer-trust .ft b { color: #fff; font-family: var(--font-ui); font-weight: 700; }
.footer-trust .ft em { font-style: normal; color: #7E92AF; }
.footer-trust .pay-badges { display: flex; gap: .5rem; flex-wrap: wrap; }
.footer-trust .pay {
    font-size: .62rem; font-weight: 800; letter-spacing: .06em; color: #C6D2E2;
    border: 1px solid rgba(255,255,255,.18); border-radius: 6px; padding: .35rem .55rem; background: rgba(255,255,255,.04);
}
@media (max-width: 640px) { .footer-trust .ft em { display: none; } }

/* Keyboard skip link — visually hidden until focused, then pinned top-left
   so a keyboard or screen-reader user can jump straight past the nav. */
.skip-link {
    position: absolute; left: -9999px; top: 0; z-index: 100;
    background: var(--navy); color: #fff; text-decoration: none;
    padding: .7rem 1.1rem; border-radius: 0 0 var(--radius) 0; font-weight: 600;
}
.skip-link:focus { left: 0; outline: 3px solid var(--gold); outline-offset: 2px; }

/* ---- Pagination -------------------------------------------------------
   Listings are capped at 24 cards per page; at 1,500 titles that is ~63
   pages, so the control shows a window (first … current-1 current current+1
   … last) rather than every page number. */
.pagination {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: .4rem;
    margin-top: 2.5rem;
}

.pagination .page-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2.75rem;
    min-height: 2.75rem;    /* comfortable touch target */
    padding: 0 .75rem;
    border: 1px solid var(--line, #e2e2e6);
    border-radius: .5rem;
    font-size: .92rem;
    line-height: 1;
    text-decoration: none;
    color: inherit;
    background: transparent;
    transition: background-color .15s ease, border-color .15s ease;
}

.pagination a.page-link:hover,
.pagination a.page-link:focus-visible {
    background: var(--surface-2, #f4f4f6);
    border-color: var(--ink, #111);
}

.pagination .page-link.is-current {
    background: var(--ink, #111);
    border-color: var(--ink, #111);
    color: #fff;
    font-weight: 600;
}

.pagination .page-link.is-disabled {
    opacity: .4;
    cursor: default;
}

.pagination .page-gap {
    padding: 0 .25rem;
    opacity: .55;
}

@media (max-width: 30rem) {
    /* Keep Previous/Next reachable on narrow screens by dropping the numbers. */
    .pagination .page-link:not([rel]):not(.is-current),
    .pagination .page-gap { display: none; }
}

/* ---- Admin: search / filter bar ---------------------------------------- */
.admin-filter {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    align-items: center;
}

.admin-filter input[type="search"] {
    flex: 1 1 18rem;
    min-width: 0;
    padding: .55rem .75rem;
    border: 1px solid var(--line, #e2e2e6);
    border-radius: .5rem;
    font: inherit;
    font-size: .9rem;
}

/* ---- Publishing Office pipeline ---------------------------------------
   Eleven stages, so this scrolls horizontally rather than wrapping into an
   unreadable block on narrow screens. */
.pipeline {
    display: flex;
    gap: .5rem;
    overflow-x: auto;
    padding: .2rem .2rem .8rem;
    margin-bottom: 1.4rem;
    scrollbar-width: thin;
}

.pipeline-stage {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .15rem;
    min-width: 5.5rem;
    padding: .6rem .7rem;
    border: 1px solid var(--line, #e2e2e6);
    border-radius: .6rem;
    text-decoration: none;
    color: inherit;
    text-align: center;
    transition: border-color .15s ease, background-color .15s ease;
}

.pipeline-stage:hover,
.pipeline-stage:focus-visible {
    border-color: var(--ink, #111);
    background: var(--surface-2, #f4f4f6);
}

.pipeline-stage.is-active {
    border-color: var(--ink, #111);
    background: var(--ink, #111);
    color: #fff;
}

.pipeline-stage.is-empty:not(.is-active) { opacity: .5; }

.pipeline-count { font-size: 1.15rem; font-weight: 700; line-height: 1; }
.pipeline-label { font-size: .68rem; text-transform: uppercase; letter-spacing: .04em; }

/* ---- Stage chips -------------------------------------------------------
   Only Published is green: the whole point of the pipeline is that a title
   is either live or it is not, and no pre-publication stage should read as
   "done" at a glance. */
.stage-chip {
    display: inline-block;
    padding: .18rem .5rem;
    border-radius: 1rem;
    font-size: .72rem;
    font-weight: 600;
    letter-spacing: .02em;
    white-space: nowrap;
    background: var(--surface-2, #f0f0f3);
    color: var(--ink-soft, #55555f);
    border: 1px solid var(--line, #e2e2e6);
}

.stage-chip.stage-published  { background: #e7f6ed; color: #12643f; border-color: #b9e3cb; }
.stage-chip.stage-scheduled  { background: #e8f0fd; color: #1c4b93; border-color: #c2d7f7; }
.stage-chip.stage-qa,
.stage-chip.stage-translation{ background: #fdf3e3; color: #8a5a12; border-color: #f2ddb8; }
.stage-chip.stage-archived   { background: #f3f3f5; color: #7a7a85; border-color: #e2e2e6; text-decoration: line-through; }

/* ---- Translation states ------------------------------------------------
   Only Published is green. "Needs update" is red rather than amber on
   purpose: it means live customer-facing content has drifted from its
   source, which is a correctness problem, not a queue position. */
.stage-chip.tstate-published    { background: #e7f6ed; color: #12643f; border-color: #b9e3cb; }
.stage-chip.tstate-approved     { background: #e8f0fd; color: #1c4b93; border-color: #c2d7f7; }
.stage-chip.tstate-in_review    { background: #fdf3e3; color: #8a5a12; border-color: #f2ddb8; }
.stage-chip.tstate-draft        { background: #f0f0f3; color: #55555f; border-color: #e2e2e6; }
.stage-chip.tstate-needs_update { background: #fdeaea; color: #96261f; border-color: #f5c6c3; }
.stage-chip.tstate-missing      { background: transparent; color: #9a9aa4; border-style: dashed; }

/* ---- Progress bars ----------------------------------------------------- */
.progress-track {
    position: relative;
    height: .5rem;
    border-radius: 1rem;
    background: var(--surface-2, #ececed);
    overflow: hidden;
}

.progress-fill {
    height: 100%;
    border-radius: 1rem;
    background: #12643f;
    transition: width .2s ease;
}

.progress-fill.is-source { background: #b9b9c2; }

/* ---- Future editions ---------------------------------------------------
   Planning, not merchandising: styled as an informational note rather than
   a product block, so it never reads as something to buy. */
.future-editions {
    margin-top: 1.4rem;
    padding: 1rem 1.1rem;
    border: 1px dashed var(--line, #e2e2e6);
    border-radius: .6rem;
    background: var(--surface-2, #fafafb);
}

.future-editions h3 {
    margin: 0 0 .4rem;
    font-size: .95rem;
    letter-spacing: .01em;
}

.future-editions p { margin: 0 0 .5rem; font-size: .88rem; }

.future-editions ul {
    margin: 0 0 .5rem;
    padding-left: 1.1rem;
    font-size: .88rem;
}

.future-editions li { margin-bottom: .15rem; }
.future-editions .small { margin-bottom: 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   DALFAST Publishing — homepage
   Editorial, not SaaS: fine gold rules rather than gold fills, restrained
   shadows, generous white space, and book covers carrying all the colour.
   Gold appears as accent only — eyebrows, rules, one primary button.
   ═══════════════════════════════════════════════════════════════════════ */

.section-lede { color: var(--ink-soft); max-width: 40rem; margin: .5rem 0 0; font-size: .95rem; line-height: 1.65; }
.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;
}

/* ── Hero showcase: a layered publishing composition ────────────────────────
   Three depth layers, no row, no card, no grey panel. The container is square
   so every book is sized as a percentage of one dimension and the whole picture
   scales with the column — a book that is 54% tall at 1440px is still 54% tall
   at 1100px, and the composition never has to be re-tuned per breakpoint.

   --h  book height, % of the container
   --x  horizontal centre of the book, % of the container
   --r  rotation; front books stay square to the page, supporting books tilt
   Books are anchored by their centre so growing one does not shift the others.
*/
.hero-showcase {
    position: relative;
    aspect-ratio: 1 / 1;
    width: 100%;
    max-width: 34rem;
    margin-inline: auto;
    isolation: isolate;
}

/* ── The stage ───────────────────────────────────────────────────────────
   The books used to sit on white, lit from nowhere, with navy shadows that
   the page background swallowed — a photograph of covers rather than a
   publisher's display.

   They now stand on the same deep navy the Editor's Pick uses, under a single
   overhead light. Three layers do the whole job and they are all one light
   source, which is what keeps it from looking like effects:

     ::before   the light itself — a warm pool above and behind the books
     ::after    the vignette that closes the corners so the eye stays centre
     .hs-rule   the floor the front books stand on

   Nothing here is a border, a card or a container. The section has no edges;
   it reads as a lit space that happens to end. */
.hero-showcase::before {
    content: ''; position: absolute; inset: -14% -10% -6%;
    background:
        /* the key light, warm and high */
        radial-gradient(46% 40% at 50% 30%, rgba(232, 205, 145, .17), rgba(232, 205, 145, 0) 70%),
        /* the pool it throws on the floor, cooler and wider */
        radial-gradient(70% 46% at 50% 88%, rgba(120, 165, 225, .13), rgba(120, 165, 225, 0) 74%);
    z-index: 0; pointer-events: none;
}
/* Closes the corners. Without it the navy reads as a flat panel; with it the
   space has depth and the books sit inside it. */
.hero-showcase::after {
    content: ''; position: absolute; inset: -14% -10% -6%;
    background: radial-gradient(78% 70% at 50% 52%, rgba(0, 0, 0, 0) 42%, rgba(0, 0, 0, .34) 100%);
    z-index: 0; pointer-events: none;
}

/* The floor. A lit edge rather than a drawn line — brightest directly under
   the front book, falling away to nothing, so it reads as the light catching
   a surface instead of a rule somebody added. */
.hs-rule {
    position: absolute; left: 4%; right: 4%; bottom: 1.5%; height: 1px; z-index: 0;
    background: linear-gradient(90deg,
        rgba(201, 155, 46, 0),
        rgba(201, 155, 46, .28) 18%,
        rgba(235, 205, 140, .78) 42%,
        rgba(201, 155, 46, .28) 76%,
        rgba(201, 155, 46, 0));
    box-shadow: 0 0 22px 2px rgba(201, 155, 46, .16);
}

.hs-book {
    position: absolute;
    left: var(--x); transform: translateX(-50%) rotate(var(--r, 0deg));
    height: var(--h);
    /* Widest a cover may be for its height. Most covers sit near 0.68–0.81, but
       a couple of the picture books are almost square; without this cap one of
       them would render half again as wide as its neighbours and wreck the
       overlap. object-fit letterboxes those down instead. */
    width: calc(var(--h) * 0.82);
    display: block;
    transform-origin: 50% 100%;
    transition: transform .35s cubic-bezier(.2, .7, .3, 1), filter .35s ease;
}
.hs-book picture, .hs-book img { display: block; width: 100%; height: 100%; }
.hs-book img { object-fit: contain; object-position: bottom center; }
/* No cutout available: the cover is opaque white, so a cast shadow would draw a
   rectangle. Give it a soft edge instead of a fake shadow. */
.hs-book.is-flat img { border-radius: 2px; box-shadow: 0 10px 24px rgba(11, 31, 59, .10); }

/* Every layer overlaps the next: the back row tucks behind the middle pair, the
   middle pair behind the front two, so the whole thing groups into one mass
   with no band of white running through it — an earlier pass without this read
   as books floating in space. Supporting covers are only ever occluded from
   below, which keeps their titles clear.

   No cover is more than ~20% occluded, and no two books share a centre line: a
   book sitting dead-centre behind another reads as one growing out of the other
   rather than as depth, so every overlap is offset both horizontally and
   vertically.

   Shadows step evenly with the layer (.20 / .16 / .13 / .10) — one light source
   at four distances, low opacity and large blur, not four separate treatments. */
/* Shadows are BLACK, not navy. On the old white ground a navy shadow read as
   soft grey; on navy it disappears entirely and every book looks pasted on.
   Each layer gets the same light at a greater distance — longer throw, wider
   blur, lower opacity — plus a tight contact shadow on the two front books so
   they sit ON the floor rather than hovering above it.

   Depth is also carried by LIGHT, not only by size: the back rows are dimmed
   and very slightly desaturated, so the front book is the one the eye reads
   first. That is what the Editor's Pick does with its ghost covers, and it is
   the difference between a stack of images and a lit display. */
/* Sizes: the falloff from front to back was too steep — the back row at 25%
   against a 54% anchor read as thumbnails scattered behind a book rather than
   as a shelf with depth. Raised so the supporting titles are legible covers in
   their own right, while the front book still clearly leads.

   Depth now comes mostly from LIGHT and overlap rather than from size alone,
   which is why the range could close from 54→25 to 54→33 without the
   composition flattening. */
.hs-1 { --h: 54%;   --x: 37%; --r: 0deg;    bottom: 0;    z-index: 5;
        filter: drop-shadow(0 34px 46px rgba(0, 0, 0, .52))
                drop-shadow(0 6px 10px rgba(0, 0, 0, .40))
                brightness(1.04); }
.hs-2 { --h: 43%;   --x: 75%; --r: 0deg;    bottom: 4%;   z-index: 4;
        filter: drop-shadow(0 26px 38px rgba(0, 0, 0, .46))
                drop-shadow(0 4px 8px rgba(0, 0, 0, .34)); }
.hs-3 { --h: 38%;   --x: 25%; --r: -2.5deg; top: 18%;     z-index: 3;
        filter: drop-shadow(0 20px 32px rgba(0, 0, 0, .40)) brightness(.94) saturate(.96); }
.hs-4 { --h: 37%;   --x: 79%; --r: 3deg;    top: 24%;     z-index: 3;
        filter: drop-shadow(0 20px 32px rgba(0, 0, 0, .40)) brightness(.94) saturate(.96); }
.hs-5 { --h: 32%;   --x: 16%; --r: -4deg;   top: 0;       z-index: 1;
        filter: drop-shadow(0 16px 28px rgba(0, 0, 0, .36)) brightness(.86) saturate(.9); }
.hs-6 { --h: 34%;   --x: 45%; --r: 2deg;    top: 0;       z-index: 2;
        filter: drop-shadow(0 16px 28px rgba(0, 0, 0, .36)) brightness(.88) saturate(.92); }
.hs-7 { --h: 33%;   --x: 74%; --r: 4.5deg;  top: 2%;      z-index: 1;
        filter: drop-shadow(0 16px 28px rgba(0, 0, 0, .36)) brightness(.86) saturate(.9); }

/* One book leaving, another arriving. It sinks slightly and fades rather than
   simply vanishing, so the eye reads a book being taken off the shelf instead
   of an image being swapped. The transform keeps the slot's own rotation, or
   the book would snap square on its way out. */
.hs-book.is-turning {
    opacity: 0;
    transform: translateX(-50%) rotate(var(--r, 0deg)) translateY(10px) scale(.97);
}
@media (prefers-reduced-motion: reduce) {
    .hs-book { transition: none; }
    .hs-book.is-turning { opacity: 1; transform: translateX(-50%) rotate(var(--r, 0deg)); }
}

/* The floor catches the two front books.
   A very short, heavily faded reflection — the thing that separates a book
   standing on a surface from a book pasted onto a background. Kept under a
   fifth of the cover's height and barely visible: a mirror-finish reflection
   is a 2008 product page, a hint of one is a lit display.

   -webkit-box-reflect is Blink and WebKit only. Firefox simply renders no
   reflection, which is the unreflected design and perfectly fine — this is an
   enhancement, and nothing depends on it. */
@supports (-webkit-box-reflect: below) {
    .hs-1, .hs-2 {
        -webkit-box-reflect: below 2px linear-gradient(to bottom,
            rgba(0, 0, 0, 0) 82%, rgba(0, 0, 0, .13) 100%);
    }
}

/* Desktop only, and deliberately small: lift and deepen, nothing else. No
   scaling, no bounce, no idle animation — this is a publisher's catalogue. */
@media (hover: hover) and (min-width: 64rem) {
    .hs-book:hover, .hs-book:focus-visible {
        transform: translateX(-50%) rotate(var(--r, 0deg)) translateY(-7px);
        z-index: 6;
        /* Brighter as it lifts, as though moving into the key light. */
        filter: drop-shadow(0 40px 54px rgba(0, 0, 0, .58))
                drop-shadow(0 8px 14px rgba(0, 0, 0, .44))
                brightness(1.1);
    }
}
.hs-book:focus-visible { outline: 2px solid var(--gold); outline-offset: 6px; border-radius: 3px; }

/* Tablet: five books, recomposed rather than shrunk — the survivors move into
   the vacated positions and grow, so the composition still fills its area.
   Which two go is a content decision, not a spatial one: slots 4 and 6 repeat
   themes already carried by slots 3 and 1, while 5 and 7 are the only family
   and children's titles on show. Dropping those would leave a hero claiming
   "every stage of life" with nothing but career and technology on it. */
@media (max-width: 64rem) {
    .hero-showcase { max-width: 30rem; }
    .hs-4, .hs-6 { display: none; }
    /* Same closing of the size range as the desktop composition — the back
       book was the smallest thing on the page and read as an afterthought. */
    .hs-1 { --h: 56%; --x: 38%; bottom: 0; }
    .hs-2 { --h: 46%; --x: 76%; bottom: 4%; }
    .hs-3 { --h: 40%; --x: 21%; top: 18%; }
    .hs-5 { --h: 38%; --x: 78%; --r: 3deg; top: 24%; z-index: 3; }
    .hs-7 { --h: 36%; --x: 50%; --r: 2deg; top: 0;   z-index: 2; }
}
.hero-tertiary { margin: .1rem 0 .8rem; }

/* ── Assurance strip: editorial, no icons, no boxes ─────────────────────── */
.assurance { border-block: 1px solid var(--line); background: var(--white); }
.assurance-row {
    display: grid; grid-template-columns: repeat(4, 1fr);
    gap: clamp(1.2rem, 4vw, 3rem); padding-block: clamp(1.6rem, 4vw, 2.4rem);
}
.assurance-item h3 {
    font-size: .82rem; letter-spacing: .08em; text-transform: uppercase;
    color: var(--navy); margin: 0 0 .35rem; font-weight: 650;
}
.assurance-item h3::before {
    content: ""; display: block; width: 1.6rem; height: 2px;
    background: var(--gold); margin-bottom: .6rem;
}
.assurance-item p { font-size: .88rem; color: var(--ink-soft); margin: 0; line-height: 1.55; }
@media (max-width: 62rem) { .assurance-row { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 30rem) { .assurance-row { grid-template-columns: 1fr; } }


/* ── The Library: discovery by publishing family ─────────────────────────────
   An asymmetric editorial layout, not a grid of equal tiles. One family holds
   the left at full weight; the rest read as an index on the right. The
   asymmetry is the hierarchy — it tells the reader where the depth is before
   they have read a single word.

   Spacing runs on a 4px base (.25rem steps). Type runs on the site's existing
   display/sans pair; no new families are introduced. */
.lib-head { max-width: 42rem; margin-bottom: clamp(2rem, 4vw, 3.2rem); }
.lib-head h2 { margin: .3rem 0 .6rem; font-size: clamp(1.9rem, 4vw, 3rem); line-height: 1.1; letter-spacing: -.015em; }
.lib-head .section-lede { font-size: clamp(1rem, 1.4vw, 1.1rem); line-height: 1.65; }

.lib-layout {
    display: grid; gap: clamp(1.6rem, 3vw, 2.8rem);
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
    align-items: start;
}

/* ── Lead family ─────────────────────────────────────────────────────────── */
.lib-lead {
    display: flex; flex-direction: column;
    border: 1px solid var(--line); border-radius: 3px;
    background: var(--white); text-decoration: none; overflow: hidden;
    transition: border-color .3s ease, transform .3s cubic-bezier(.2,.7,.3,1), box-shadow .3s ease;
}
.lib-lead:hover, .lib-lead:focus-visible {
    border-color: var(--gold); transform: translateY(-3px);
    box-shadow: 0 22px 44px -26px rgba(11, 31, 59, .4);
}
/* Covers on a soft ground so the cutouts read as objects on a shelf. */
.lib-lead-covers {
    display: flex; align-items: flex-end; justify-content: center;
    gap: clamp(.5rem, 1.6vw, 1.1rem);
    padding: clamp(1.8rem, 4vw, 3rem) 1.5rem clamp(1.4rem, 3vw, 2.2rem);
    background:
        radial-gradient(70% 60% at 50% 100%, rgba(201, 155, 46, .10), rgba(201, 155, 46, 0) 70%),
        var(--paper-deep);
    border-bottom: 1px solid var(--line);
}
.lib-lead-covers img {
    display: block; width: clamp(3.4rem, 8vw, 5.6rem); height: auto; object-fit: contain;
    filter: drop-shadow(0 12px 22px rgba(11, 31, 59, .18));
    transition: transform .35s cubic-bezier(.2,.7,.3,1);
}
/* The stack fans on hover — a small, quiet reward, no bounce. */
.lib-lead:hover .lib-lead-covers img:nth-child(1) { transform: translateY(-4px) rotate(-2deg); }
.lib-lead:hover .lib-lead-covers img:nth-child(2) { transform: translateY(-7px); }
.lib-lead:hover .lib-lead-covers img:nth-child(3) { transform: translateY(-5px) rotate(1.5deg); }
.lib-lead:hover .lib-lead-covers img:nth-child(4) { transform: translateY(-3px) rotate(3deg); }

.lib-lead-body { display: flex; flex-direction: column; padding: clamp(1.3rem, 2.6vw, 1.9rem); }
.lib-lead-name {
    font-family: var(--font-display); font-size: clamp(1.15rem, 2vw, 1.5rem);
    line-height: 1.25; color: var(--navy); margin-bottom: .4rem;
}
.lib-lead-blurb { font-size: .95rem; line-height: 1.6; color: var(--ink-soft); margin-bottom: .9rem; }
.lib-meta {
    font-size: .78rem; letter-spacing: .06em; text-transform: uppercase;
    color: var(--ink-soft); margin-bottom: 1.1rem;
}
.lib-go {
    margin-top: auto; font-size: .9rem; font-weight: 600; color: var(--navy);
    display: inline-flex; align-items: center; gap: .4rem;
}
.lib-go i { font-style: normal; transition: transform .25s ease; }
.lib-lead:hover .lib-go { color: var(--brass-deep); }
.lib-lead:hover .lib-go i { transform: translateX(4px); }

/* ── Index of the remaining families ─────────────────────────────────────── */
.lib-index { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }
.lib-index li { border-bottom: 1px solid var(--line); }
.lib-index a {
    display: grid; grid-template-columns: 2.6rem minmax(0, 1fr) auto;
    align-items: center; gap: 1rem;
    padding: .95rem .6rem .95rem .25rem; text-decoration: none;
    position: relative; transition: background .25s ease, padding-left .25s ease;
}
/* A gold rule slides in on hover rather than the row changing colour — the
   quieter signal, and it keeps the navy type at full contrast. */
.lib-index a::before {
    content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
    background: var(--gold); transform: scaleY(0); transform-origin: 50% 50%;
    transition: transform .25s ease;
}
.lib-index a:hover, .lib-index a:focus-visible { background: var(--paper-deep); padding-left: .8rem; }
.lib-index a:hover::before, .lib-index a:focus-visible::before { transform: scaleY(1); }
.lib-index-art img {
    display: block; width: 100%; height: auto; object-fit: contain;
    filter: drop-shadow(0 6px 12px rgba(11, 31, 59, .16));
}
.lib-index-name { display: block; font-family: var(--font-display); font-size: 1.02rem; color: var(--navy); line-height: 1.3; }
.lib-index-blurb {
    display: block; font-size: .82rem; color: var(--ink-soft); line-height: 1.45; margin-top: .15rem;
    /* One line: the index is for scanning, not reading. */
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lib-index-count {
    font-size: .82rem; color: var(--ink-soft); font-variant-numeric: tabular-nums;
    min-width: 1.5rem; text-align: right;
}

/* The tally sits under the lede, above the shelves — the size of the catalogue
   is context for what follows, so it reads before the browsing rather than
   after it. The rule divides it from the lede instead of closing the section. */
.lib-tally {
    margin: 1.1rem 0 0; padding-top: 1.1rem;
    border-top: 1px solid var(--line);
    font-size: .9rem; color: var(--ink-soft);
}
.lib-tally .text-link { margin-left: .4rem; }

@media (max-width: 60rem) {
    .lib-layout { grid-template-columns: 1fr; }
}
@media (max-width: 40rem) {
    .lib-lead-covers { padding: 1.6rem 1rem 1.2rem; gap: .45rem; }
    .lib-lead-covers img { width: 3.2rem; }
    /* The blurb wraps rather than truncating once there is a full row for it. */
    .lib-index-blurb { white-space: normal; }
    .lib-index a { grid-template-columns: 2.2rem minmax(0, 1fr) auto; gap: .8rem; }
}
@media (prefers-reduced-motion: reduce) {
    .lib-lead, .lib-lead-covers img, .lib-go i, .lib-index a, .lib-index a::before { transition: none; }
    .lib-lead:hover { transform: none; }
    .lib-lead:hover .lib-lead-covers img { transform: none; }
}


/* ── Editor's Pick: the lead title, in the context of its series ─────────────
   Navy ground, one gold accent, real book covers doing the work. The panel is
   composed of parts that each appear only when their data exists, so it holds
   together whether the book is a standalone with no offer or a series title
   with a complete-set price. */
.editors-pick { background: var(--navy); color: var(--paper); overflow: hidden; }
.ep-grid {
    display: grid; gap: clamp(2rem, 5vw, 4rem);
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
    align-items: center;
}
.ep-grid:has(.ep-offer) { grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr) minmax(0, 16rem); }

/* Stage: the pick, with its companions ranged behind it. */
.ep-stage { position: relative; display: flex; justify-content: center; align-items: center; min-height: 20rem; }

/* The turn between one book and the next. Both panels fade and lift very
   slightly, the content is swapped while they are invisible, and they settle
   back — so the change reads as the shelf turning rather than the page
   glitching. Held to under half a second: this is a transition, not an
   animation somebody has to wait through. */
.ep-stage, .ep-copy {
    transition: opacity .38s ease, transform .38s ease;
}
.ep-stage.is-turning, .ep-copy.is-turning {
    opacity: 0;
    transform: translateY(6px);
}
@media (prefers-reduced-motion: reduce) {
    .ep-stage, .ep-copy { transition: none; }
    .ep-stage.is-turning, .ep-copy.is-turning { opacity: 1; transform: none; }
}

.ep-companions {
    position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
    gap: clamp(4rem, 12vw, 9rem); pointer-events: none;
}
.ep-companions img {
    width: clamp(6rem, 14vw, 10rem); height: auto; object-fit: contain;
    /* Held back so they read as depth, not as competing covers. */
    opacity: .3; filter: blur(1px) drop-shadow(0 14px 26px rgba(0, 0, 0, .5));
}
.ep-cover { position: relative; z-index: 2; display: block; }
.ep-cover img {
    display: block; width: clamp(11rem, 22vw, 17rem); height: auto; object-fit: contain;
    filter: drop-shadow(0 26px 46px rgba(0, 0, 0, .55));
    transition: transform .35s cubic-bezier(.2, .7, .3, 1);
}
.ep-cover:hover img { transform: translateY(-6px); }
.ep-badge {
    position: absolute; top: 4%; right: 8%; z-index: 3;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    width: 4.6rem; height: 4.6rem; border-radius: 50%;
    background: var(--gold); color: var(--navy);
    font-size: .74rem; line-height: 1.25; text-align: center;
    box-shadow: 0 10px 22px rgba(0, 0, 0, .35);
}
.ep-badge strong { display: block; font-size: .82rem; font-weight: 700; }

/* Copy */
.ep-pill {
    display: inline-block; padding: .3rem .75rem; border-radius: 99px;
    border: 1px solid rgba(201, 155, 46, .55); background: rgba(201, 155, 46, .12);
    color: var(--gold); font-size: .68rem; font-weight: 700;
    letter-spacing: .14em; text-transform: uppercase;
}
.editors-pick .editors-cat {
    font-size: .74rem; letter-spacing: .1em; text-transform: uppercase;
    color: rgba(247, 244, 237, .82); margin: .9rem 0 .3rem;
}
.editors-pick h2 { color: #fff; margin: 0 0 .5rem; font-size: clamp(1.5rem, 3vw, 2.2rem); line-height: 1.18; }
.ep-author { margin: 0 0 .8rem; font-size: .95rem; color: rgba(247, 244, 237, .86); }
.ep-author span { color: var(--gold); font-weight: 600; }

.ep-facts { display: flex; flex-wrap: wrap; gap: .5rem; list-style: none; margin: 0 0 1.1rem; padding: 0; }
.ep-facts li {
    font-size: .78rem; letter-spacing: .04em; color: rgba(247, 244, 237, .94);
    border: 1px solid rgba(247, 244, 237, .34); border-radius: 2px; padding: .28rem .6rem;
}
.editors-pick .editors-blurb { color: rgba(247, 244, 237, .9); line-height: 1.7; max-width: 34rem; margin: 0 0 1.4rem; }

/* Series strip */
.ep-series {
    border: 1px solid rgba(247, 244, 237, .14); border-radius: 3px;
    padding: .9rem 1rem; margin-bottom: 1.4rem; max-width: 34rem;
}
.ep-series-label {
    margin: 0 0 .7rem; font-size: .76rem; letter-spacing: .1em;
    text-transform: uppercase; color: rgba(247, 244, 237, .8);
}
.ep-series-row { display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; }
.ep-series-book { display: block; border-radius: 2px; }
.ep-series-book img {
    display: block; width: 2.9rem; height: auto; object-fit: contain;
    opacity: .62; transition: opacity .2s, transform .2s;
}
.ep-series-book:hover img { opacity: 1; transform: translateY(-2px); }
/* The book being featured is marked so the strip reads as "you are here". */
.ep-series-book.is-current img { opacity: 1; outline: 2px solid var(--gold); outline-offset: 2px; }
.ep-series-all { margin-left: auto; font-size: .82rem; font-weight: 600; color: var(--gold); text-decoration: none; white-space: nowrap; }
.ep-series-all:hover { text-decoration: underline; text-underline-offset: 3px; }

.ep-price { font-family: var(--font-display); font-size: 1.9rem; color: #fff; margin: 0 0 1rem; }
.ep-cta { display: flex; align-items: center; gap: .9rem; flex-wrap: wrap; }
.ep-cta form { margin: 0; }
.ep-cta .text-link { color: var(--gold); }
/* A ghost button that reads on navy — the page's default ghost is navy-on-white. */
.btn-ghost-light {
    background: transparent; color: #fff; border: 1px solid rgba(247, 244, 237, .38);
}
.btn-ghost-light:hover { border-color: var(--gold); color: var(--gold); }

/* Complete-series offer */
.ep-offer {
    border: 1px solid rgba(201, 155, 46, .35); border-radius: 3px;
    background: rgba(255, 255, 255, .04); padding: 1.3rem;
}
.ep-offer h3 { margin: 0 0 .2rem; font-size: 1.05rem; color: var(--gold); }
.ep-offer-count { margin: 0 0 .9rem; font-size: .82rem; color: rgba(247, 244, 237, .6); }
.ep-offer-covers { display: flex; gap: .35rem; margin-bottom: 1rem; }
.ep-offer-covers img { width: 100%; max-width: 3.2rem; height: auto; object-fit: contain; opacity: .9; }
.ep-offer-price { display: grid; grid-template-columns: 1fr auto; gap: .3rem .8rem; margin: 0 0 .6rem; font-size: .88rem; }
.ep-offer-price dt { color: rgba(247, 244, 237, .65); }
.ep-offer-price dd { margin: 0; text-align: right; color: rgba(247, 244, 237, .8); }
.ep-offer-now { font-family: var(--font-display); font-size: 1.35rem; color: var(--gold) !important; }
.ep-offer-save {
    display: inline-block; margin: 0 0 1rem; padding: .25rem .6rem; border-radius: 99px;
    background: rgba(46, 107, 69, .3); border: 1px solid rgba(46, 107, 69, .6);
    color: #9BD6B0; font-size: .76rem; font-weight: 700;
}
.ep-offer-link { display: inline-block; margin-top: .7rem; font-size: .82rem; font-weight: 600; color: var(--gold); text-decoration: none; }
.ep-offer-link:hover { text-decoration: underline; text-underline-offset: 3px; }

/* Editor's Picks row */
.ep-row { margin-top: clamp(2.5rem, 5vw, 4rem); padding-top: 2rem; border-top: 1px solid rgba(247, 244, 237, .14); }
.ep-row-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.4rem; }
.ep-row-head h3 { margin: 0; color: #fff; font-size: 1.35rem; }
.ep-row-all { font-size: .84rem; font-weight: 600; color: var(--gold); text-decoration: none; }
.ep-row-all:hover { text-decoration: underline; text-underline-offset: 3px; }
/* A scroller, not a JS carousel: it works with a trackpad, a touch swipe and a
   keyboard, and needs nothing to initialise. */
.ep-row-scroll {
    display: grid; grid-auto-flow: column; grid-auto-columns: minmax(9.5rem, 1fr);
    gap: 1.2rem; overflow-x: auto; padding-bottom: .6rem;
    scroll-snap-type: x proximity; scrollbar-width: thin;
}
.ep-card { scroll-snap-align: start; }
.ep-card img {
    display: block; width: 100%; height: auto; aspect-ratio: 4 / 5;
    object-fit: contain; object-position: bottom center;
    filter: drop-shadow(0 12px 22px rgba(0, 0, 0, .45)); margin-bottom: .7rem;
}
.ep-card-cat { margin: 0; font-size: .68rem; letter-spacing: .08em; text-transform: uppercase; color: rgba(247, 244, 237, .5); }
.ep-card-title { display: block; margin: .2rem 0 .3rem; font-family: var(--font-display); font-size: .95rem; line-height: 1.3; color: #fff; text-decoration: none; }
.ep-card-title:hover { color: var(--gold); }
.ep-card-price { margin: 0; font-size: .85rem; font-weight: 600; color: var(--gold); }

@media (max-width: 68rem) {
    .ep-grid, .ep-grid:has(.ep-offer) { grid-template-columns: 1fr; }
    .ep-offer { max-width: 24rem; }
}
@media (max-width: 40rem) {
    .ep-stage { min-height: 15rem; }
    /* Companions crowd the cover on a phone; the series strip below still
       shows every book, so nothing is lost by dropping them here. */
    .ep-companions { display: none; }
    .ep-badge { width: 4rem; height: 4rem; top: 0; right: 2%; }
    .ep-cta { gap: .6rem; }
    .ep-row-scroll { grid-auto-columns: minmax(8rem, 1fr); }
}
/* ── Editorial collections ─────────────────────────────────────────────── */
.collection-grid { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); }
.collection-tile {
    display: flex; flex-direction: column; gap: .3rem;
    padding: 1.4rem; text-decoration: none;
    border: 1px solid var(--line); border-radius: var(--radius);
    background: var(--white); transition: border-color .2s ease;
}
.collection-tile:hover { border-color: var(--gold); }
.collection-name { font-family: var(--font-display); font-size: 1.15rem; color: var(--navy); }
.collection-count { font-size: .8rem; color: var(--ink-soft); margin-bottom: .6rem; }

/* ── Publishing statement ──────────────────────────────────────────────── */
.statement-inner { max-width: 44rem; }
.statement-inner p { color: var(--ink-soft); line-height: 1.8; font-size: 1.02rem; }
.statement-inner h2::after {
    content: ""; display: block; width: 3rem; height: 2px;
    background: var(--gold); margin: 1rem 0 1.4rem;
}

/* ── Why DALFAST ───────────────────────────────────────────────────────── */
.why-grid { display: grid; gap: clamp(1.2rem, 3vw, 2.4rem); grid-template-columns: repeat(4, 1fr); }
.why-item h3 { font-size: 1rem; color: var(--navy); margin: 0 0 .4rem; }
.why-item p { font-size: .9rem; color: var(--ink-soft); line-height: 1.6; margin: 0; }
@media (max-width: 62rem) { .why-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 30rem) { .why-grid { grid-template-columns: 1fr; } }

/* ── Reading list ──────────────────────────────────────────────────────── */
.reading-list { border-top: 1px solid var(--line); }
.reading-inner {
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: clamp(1.4rem, 4vw, 3rem); align-items: center;
}
.reading-inner p { color: var(--ink-soft); margin: .4rem 0 0; }
/* The form is now two rows: the address and button, then the consent line.
   The checkbox is not tucked away small and grey — it is the thing that makes
   the signup lawful, so it is legible and sits directly under the control it
   qualifies. */
.reading-form { display: flex; flex-direction: column; gap: .7rem; }
.reading-row { display: flex; gap: .6rem; flex-wrap: wrap; }
.reading-form input[type="email"] {
    flex: 1 1 14rem; min-height: 2.9rem; padding: .6rem .9rem;
    border: 1px solid var(--line); border-radius: var(--radius-sm, 8px);
    font: inherit; background: var(--white);
}
.reading-form input:focus-visible { outline: 2px solid var(--gold); outline-offset: 1px; }

.reading-consent {
    display: flex; gap: .55rem; align-items: flex-start;
    font-size: .8rem; line-height: 1.5; color: var(--ink-soft);
    max-width: 34rem; cursor: pointer;
}
/* Big enough to hit on a phone, and nudged onto the first line of text. */
.reading-consent input {
    flex: 0 0 auto; width: 1.05rem; height: 1.05rem; margin: .15rem 0 0;
    accent-color: var(--gold); cursor: pointer;
}
.reading-consent input:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
@media (max-width: 52rem) { .reading-inner { grid-template-columns: 1fr; } }

/* ── Mobile: three books, one dominant, beneath the copy ────────────────── */
@media (max-width: 52rem) {
    /* Wider than tall: a square block of books below the CTA pushes everything
       else off the first screen. */
    /* The grid's row gap already separates this from the CTA; a margin on top
       of it left ~90px of dead air between the copy and the books. */
    .hero-showcase { aspect-ratio: 1 / .78; max-width: 24rem; margin-top: .6rem; }
    .hs-3, .hs-4, .hs-6, .hs-7 { display: none; }
    .hs-1 { --h: 80%; --x: 50%; --r: 0deg;  bottom: 0; }
    .hs-2 { --h: 52%; --x: 18%; --r: -4deg; bottom: 6%; z-index: 2; }
    /* Slot 5 rather than 3, so three books still cover career, technology and
       family instead of career, technology and a second wellbeing title. */
    .hs-5 { --h: 50%; --x: 82%; --r: 4deg;  bottom: 8%; top: auto; z-index: 2; }
    .hs-rule { bottom: 0; left: 4%; right: 4%; }
}

/* ── Series ────────────────────────────────────────────────────────────────
   A series is a reason to buy more than one book, so it is shown as a row of
   covers rather than a text label. Restrained: covers carry the interest. */
.series-row { margin-bottom: clamp(1.6rem, 4vw, 2.6rem); }
.series-row-head {
    display: flex; align-items: baseline; gap: .8rem;
    padding-bottom: .6rem; margin-bottom: 1rem;
    border-bottom: 1px solid var(--line);
}
.series-row-head h3 { font-family: var(--font-display); font-size: 1.25rem; color: var(--navy); margin: 0; }
.series-count { font-size: .8rem; color: var(--ink-soft); }
.series-strip {
    display: grid; gap: 1rem;
    grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr));
}
.series-book { text-decoration: none; display: block; }
.series-book img {
    width: 100%; height: auto; display: block; background: #fff;
    border: 1px solid var(--line); border-radius: 4px;
    transition: transform .2s ease, border-color .2s ease;
}
.series-book:hover img, .series-book:focus-visible img { transform: translateY(-3px); border-color: var(--gold); }
.series-book-title {
    display: block; margin-top: .5rem; font-size: .85rem;
    color: var(--navy); line-height: 1.35;
}

/* Series block on a product page */
.series-note {
    border: 1px solid var(--line); border-radius: var(--radius);
    padding: 1.1rem 1.2rem; margin: 1.4rem 0; background: var(--white);
}
.series-label { margin: 0 0 .8rem; font-size: .9rem; color: var(--ink-soft); }
.series-label strong { color: var(--navy); }
.series-list { list-style: none; margin: 0; padding: 0; display: grid; gap: .8rem;
               grid-template-columns: repeat(auto-fill, minmax(6.5rem, 1fr)); }
.series-list a { text-decoration: none; display: block; }
.series-list img {
    width: 100%; height: auto; display: block; background: #fff;
    border: 1px solid var(--line); border-radius: 3px;
}
.series-list a:hover img { border-color: var(--gold); }
.series-title { display: block; font-size: .78rem; color: var(--navy); margin-top: .35rem; line-height: 1.3; }
.series-price { display: block; font-size: .76rem; color: var(--ink-soft); }

/* Series name on a catalogue card */
.placard-series {
    font-size: .72rem; letter-spacing: .06em; text-transform: uppercase;
    color: var(--gold-text, #A87F1F); margin: .15rem 0 0;
}

/* ── My Library & Account Settings ──────────────────────────────────────────
   A reader's room and a control panel, styled as one family: white ground,
   navy type, gold only where it marks the primary action. No dashboard cards,
   no charts, no badges — this is a publisher, not a SaaS console. */

.lib-head, .set-head { padding-block: clamp(1.8rem, 4vw, 3rem) 0; }
.lib-head h1, .set-head h1 { margin: .2rem 0 .4rem; }
.lib-head .muted, .set-head .muted { max-width: 40rem; }

/* Library ------------------------------------------------------------------ */
.lib-shell { padding-block: 1.6rem clamp(3rem, 6vw, 5rem); }
.lib-nav {
    display: flex; flex-wrap: wrap; gap: 1.6rem;
    border-bottom: 1px solid var(--line); margin-bottom: 1.8rem;
}
.lib-nav a {
    padding: .6rem 0; margin-bottom: -1px;
    border-bottom: 2px solid transparent;
    font-size: .92rem; font-weight: 600; color: var(--ink-soft); text-decoration: none;
    display: inline-flex; align-items: baseline; gap: .4rem;
}
.lib-nav a:hover { color: var(--navy); }
.lib-nav a.is-active { color: var(--navy); border-bottom-color: var(--gold); }
.lib-nav span { font-size: .74rem; font-weight: 500; color: var(--ink-soft); font-variant-numeric: tabular-nums; }

.lib-controls {
    display: flex; flex-wrap: wrap; gap: 1rem; align-items: center;
    justify-content: space-between; margin-bottom: 1.4rem;
}
/* align-items:center, not the default stretch: otherwise the button takes the
   full height of the row rather than its own. */
.lib-search { display: flex; align-items: center; gap: .5rem; flex: 1 1 18rem; max-width: 26rem; }
.lib-search input {
    flex: 1; min-width: 0; padding: .55rem .8rem; font-size: .92rem;
    border: 1px solid var(--line); border-radius: 2px; background: var(--white);
}
/* The input flexes; the button keeps its natural width. Without this the
   button was the thing that shrank on a phone and "Search" broke across two
   lines. min-width:0 above lets the input actually give way instead. */
.lib-search .btn { flex-shrink: 0; white-space: nowrap; }
.lib-search input:focus-visible { outline: 2px solid var(--gold); outline-offset: 1px; }
.lib-filters { display: flex; gap: .6rem; flex-wrap: wrap; }
.lib-filters select {
    padding: .5rem .7rem; font-size: .88rem;
    border: 1px solid var(--line); border-radius: 2px; background: var(--white); color: var(--navy);
}
.lib-count, .lib-note { font-size: .88rem; margin: 0 0 1.2rem; }

.lib-grid {
    display: grid; gap: clamp(1.4rem, 3vw, 2.2rem) clamp(1rem, 2.2vw, 1.8rem);
    grid-template-columns: repeat(auto-fill, minmax(10.5rem, 1fr));
}
.lib-book { display: flex; flex-direction: column; }
.lib-book-cover { display: block; margin-bottom: .8rem; }
.lib-book-cover img {
    display: block; width: 100%; height: auto; aspect-ratio: 4 / 5;
    object-fit: contain; object-position: bottom center;
    filter: drop-shadow(0 10px 20px rgba(11, 31, 59, .14));
    transition: transform .25s ease;
}
.lib-book-cover:hover img { transform: translateY(-4px); }
.lib-book-title {
    font-family: var(--font-display); font-size: 1rem; font-weight: 550;
    line-height: 1.3; margin: 0 0 .2rem; color: var(--navy);
}
.lib-book-author, .lib-book-format { margin: 0; font-size: .78rem; color: var(--ink-soft); }
.lib-book-format { letter-spacing: .06em; margin-top: .15rem; }
/* margin-top:auto pins the actions to the bottom of the card. Grid stretches
   every cell to the row height, so Download and View Book line up across a row
   even when one title wraps to two lines and its neighbour does not. */
.lib-book-actions { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: auto; padding-top: .7rem; }

.lib-list { list-style: none; margin: 0; padding: 0; }
.lib-row {
    display: grid; grid-template-columns: 4.5rem 1fr auto; gap: 1.2rem;
    align-items: center; padding: 1.1rem 0; border-bottom: 1px solid var(--line);
}
.lib-row-cover img { display: block; width: 100%; height: auto; object-fit: contain; }
.lib-row-title { font-family: var(--font-display); font-size: 1.05rem; color: var(--navy); text-decoration: none; }
.lib-row-title:hover { color: var(--brass-deep); }
.lib-row-meta, .lib-row-price { margin: .15rem 0 0; font-size: .85rem; color: var(--ink-soft); }
.lib-row-price { color: var(--navy); font-weight: 600; }
.lib-row-actions { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.lib-remove {
    /* Sits in a row with two btn-small controls and is tapped with a thumb, so
       it matches their height rather than being a 31px text link. */
    background: none; border: 0; cursor: pointer;
    padding: .5rem .45rem; min-height: 2.25rem;
    font: inherit; font-size: .82rem; color: var(--ink-soft); text-decoration: underline;
}
.lib-remove:hover { color: var(--error); }

.lib-empty { padding: clamp(2.5rem, 6vw, 4.5rem) 0; max-width: 34rem; }
.lib-empty h2 { font-size: clamp(1.4rem, 3vw, 1.9rem); margin: 0 0 .6rem; }
.lib-empty p { color: var(--ink-soft); }
.lib-empty-actions { display: flex; flex-wrap: wrap; gap: .8rem; margin-top: 1.6rem; }
.lib-pager { display: flex; align-items: center; gap: 1.2rem; margin-top: 2.5rem; }

/* Account Settings --------------------------------------------------------- */
.set-shell {
    display: grid; grid-template-columns: minmax(0, 13rem) minmax(0, 1fr);
    gap: clamp(2rem, 5vw, 4rem);
    padding-block: 1.8rem clamp(3rem, 6vw, 5rem);
    align-items: start;
}
.set-nav { display: flex; flex-direction: column; }
.set-nav a {
    padding: .6rem .8rem; border-left: 2px solid var(--line);
    font-size: .92rem; font-weight: 600; color: var(--ink-soft); text-decoration: none;
}
.set-nav a:hover { color: var(--navy); background: var(--paper-deep); }
.set-nav a.is-active { color: var(--navy); border-left-color: var(--gold); }
.set-title { font-size: 1.5rem; margin: 0 0 1.4rem; }
.set-sub {
    font-family: var(--font-display); font-size: .78rem; font-weight: 600;
    letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft);
    margin: 2rem 0 1rem; padding-bottom: .5rem; border-bottom: 1px solid var(--line);
}
.set-form .set-sub:first-child { margin-top: 0; }
.set-form { max-width: 30rem; }
.set-form .field { margin-bottom: 1.1rem; }
.set-form label { display: block; font-size: .84rem; font-weight: 600; color: var(--navy); margin-bottom: .35rem; }
.set-form input, .set-form select {
    width: 100%; padding: .55rem .75rem; font-size: .95rem;
    border: 1px solid var(--line); border-radius: 2px; background: var(--white); color: var(--navy);
}
.set-form input:disabled { background: var(--paper-deep); color: var(--ink-soft); }
.set-form input:focus-visible, .set-form select:focus-visible { outline: 2px solid var(--gold); outline-offset: 1px; }
.field-help { margin: .35rem 0 0; font-size: .8rem; color: var(--ink-soft); line-height: 1.5; }
.set-check { display: flex; gap: .7rem; align-items: flex-start; max-width: 34rem; }
.set-check input { width: auto; margin-top: .25rem; flex-shrink: 0; }
.set-check span { font-size: .9rem; color: var(--ink-soft); line-height: 1.55; }
.set-check strong { display: block; color: var(--navy); font-weight: 600; }

.set-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); gap: 1.4rem; }
.set-card { border: 1px solid var(--line); border-radius: 2px; padding: 1.2rem; background: var(--white); }
.set-card h3 {
    font-family: var(--font-display); font-size: .72rem; font-weight: 600;
    letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft); margin: 0 0 .6rem;
}
.set-card-value { font-family: var(--font-display); font-size: 1.15rem; color: var(--navy); margin: 0 0 .2rem; word-break: break-word; }
.set-card-sub { font-size: .82rem; color: var(--ink-soft); margin: 0 0 .9rem; }
.set-card .btn { margin-top: .6rem; }

.set-orders { list-style: none; margin: 0; padding: 0; }
.set-order { padding: 1.1rem 0; border-bottom: 1px solid var(--line); }
.set-order-head { display: flex; align-items: baseline; gap: .8rem; flex-wrap: wrap; }
.set-order-ref { font-family: var(--font-display); font-size: 1.05rem; color: var(--navy); text-decoration: none; }
.set-order-ref:hover { color: var(--brass-deep); }
.set-order-meta { margin: .3rem 0 .7rem; font-size: .86rem; color: var(--ink-soft); }
.set-order-actions { display: flex; gap: .5rem; flex-wrap: wrap; }
/* Status comes from the order row, never from the view. */
.set-status { font-size: .72rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; }
.set-status-paid { color: var(--success); }
.set-status-pending { color: var(--brass-deep); }
.set-status-failed, .set-status-refunded { color: var(--error); }

.order-detail { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 18rem); gap: clamp(2rem, 4vw, 3.5rem); align-items: start; }
.order-items { list-style: none; margin: 0; padding: 0; }
.order-item { display: grid; grid-template-columns: 4rem 1fr auto; gap: 1.2rem; align-items: center; padding: 1rem 0; border-bottom: 1px solid var(--line); }
.order-item-cover img { display: block; width: 100%; height: auto; object-fit: contain; }
.order-item-title { font-family: var(--font-display); font-size: 1rem; color: var(--navy); text-decoration: none; }
.order-item-price { margin: .2rem 0 0; font-size: .85rem; color: var(--ink-soft); }
.order-totals { display: grid; grid-template-columns: 1fr auto; gap: .5rem 1rem; margin: 0; font-size: .92rem; }
.order-totals dt { color: var(--ink-soft); }
.order-totals dd { margin: 0; text-align: right; color: var(--navy); font-variant-numeric: tabular-nums; }
.order-totals .order-total { font-weight: 700; padding-top: .6rem; border-top: 1px solid var(--line); }

/* "In Your Library" — quiet, so it informs without shouting, and stops a
   reader paying twice for the same digital edition. */
.owned-flag {
    display: inline-flex; align-items: center; gap: .45rem;
    font-size: .78rem; font-weight: 600; letter-spacing: .04em; color: var(--brass-deep);
}
.owned-flag::before { content: ''; width: 3px; height: 1em; background: var(--gold); border-radius: 1px; }

@media (max-width: 60rem) {
    /* Sidebar becomes a scroller — a fixed column beside nothing is wasted space. */
    .set-shell { grid-template-columns: 1fr; gap: 1.4rem; }
    .set-nav { flex-direction: row; overflow-x: auto; border-bottom: 1px solid var(--line); gap: .2rem; }
    .set-nav a { white-space: nowrap; border-left: 0; border-bottom: 2px solid transparent; margin-bottom: -1px; }
    .set-nav a.is-active { border-left: 0; border-bottom-color: var(--gold); }
    .order-detail { grid-template-columns: 1fr; }
}
@media (max-width: 40rem) {
    .lib-grid { grid-template-columns: repeat(auto-fill, minmax(8.5rem, 1fr)); }
    .lib-controls { flex-direction: column; align-items: stretch; }
    /* flex-grow:1 was written for a row. Once .lib-controls turns into a column
       it grows vertically instead, which stretched the search row — and the
       button inside it — to the full height of the block. */
    .lib-search { flex: 0 0 auto; max-width: none; }
    .lib-row { grid-template-columns: 3.5rem 1fr; }
    .lib-row-actions { grid-column: 1 / -1; }
    .order-item { grid-template-columns: 3.5rem 1fr; }
    .order-item .btn { grid-column: 1 / -1; justify-self: start; }
}

/* Was the "Instant digital download" line under the buy button. Removed at the
   owner's request — the button already carries the action and the price, and
   the page says elsewhere what the customer receives. The rule stays because
   it is the slot for supporting microcopy under a primary CTA, not because
   anything currently uses it. */
.buy-note {
    margin: .55rem 0 0; text-align: center;
    font-size: .82rem; color: var(--ink-soft); letter-spacing: .01em;
}

/* ── About ──────────────────────────────────────────────────────────────────
   An About page is a piece of writing, so the type does the work and there is
   almost no furniture. The first draft of this section was a dashboard —
   counters, a stat grid, an "at a glance" table — which is the wrong genre
   twice over: it reads as a report rather than a publisher, and it sets the
   size of the list in the largest type on the page.

   What replaced it: one measure, generous leading, a shelf of real covers, and
   a single gold rule per section. No numbers anywhere except the company
   registration block. */

/* One measure for the whole page. 34rem is roughly 65 characters at this size —
   the width at which the eye finds the next line without hunting. */
.ab-column { max-width: 34rem; }

/* ── Opening ─────────────────────────────────────────────────────────────── */
.ab-open { padding: clamp(3.5rem, 8vw, 7rem) 0 clamp(1.5rem, 3vw, 2.5rem); }
.ab-open h1 {
    margin: .5rem 0 1.2rem; max-width: 20ch;
    font-size: clamp(2.1rem, 5.2vw, 4rem); line-height: 1.06; letter-spacing: -.022em;
}
.ab-standfirst {
    max-width: 38rem; margin: 0;
    font-size: clamp(1.1rem, 1.9vw, 1.4rem); line-height: 1.55; color: var(--ink-soft);
}

/* ── The shelf: the catalogue as a picture, not a count ──────────────────── */
.ab-shelf {
    display: flex; align-items: flex-end; justify-content: flex-start;
    gap: clamp(.8rem, 2.4vw, 2rem);
    padding: clamp(1.5rem, 4vw, 3rem) 0 clamp(2rem, 5vw, 3.5rem);
    border-bottom: 1px solid var(--line);
}
.ab-shelf img {
    display: block; width: clamp(3.6rem, 9vw, 7rem); height: auto; object-fit: contain;
    filter: drop-shadow(0 14px 26px rgba(11, 31, 59, .16));
}
/* Slight stagger so it reads as books standing on a surface rather than a row
   of thumbnails. Nothing rotates — a publisher's shelf is not a carousel. */
.ab-shelf img:nth-child(2n) { transform: translateY(-.5rem); }
.ab-shelf img:nth-child(3n) { transform: translateY(-.25rem); }

/* ── Body ────────────────────────────────────────────────────────────────── */
.ab-body { padding-top: clamp(2.5rem, 6vw, 4.5rem); }
.ab-body p { font-size: 1.06rem; line-height: 1.78; margin: 0 0 1.35rem; }
/* The opening line is set larger and given a gold rule — the standard editorial
   signal that this is the entry point to the argument. */
.ab-first {
    font-family: var(--font-display);
    font-size: clamp(1.25rem, 2.2vw, 1.6rem) !important;
    line-height: 1.4 !important; color: var(--navy);
    padding-left: 1.2rem; border-left: 2px solid var(--gold);
    margin-bottom: 2rem !important;
}
.ab-body h2 {
    margin: 2.6rem 0 1rem;
    font-size: clamp(1.3rem, 2.2vw, 1.7rem); line-height: 1.25; letter-spacing: -.01em;
}

/* ── Beliefs ─────────────────────────────────────────────────────────────── */
.ab-beliefs { background: var(--paper-deep); }
.ab-beliefs h2 { margin: .3rem 0 0; font-size: clamp(1.5rem, 3vw, 2.2rem); line-height: 1.2; letter-spacing: -.015em; }
.ab-belief-list {
    list-style: none; margin: clamp(2rem, 4vw, 3rem) 0 0; padding: 0;
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(1.6rem, 3.5vw, 3rem);
}
.ab-belief-list li { border-top: 2px solid var(--gold); padding-top: 1.1rem; }
.ab-belief-list h3 { margin: 0 0 .5rem; font-size: 1.15rem; line-height: 1.3; }
.ab-belief-list p { margin: 0; color: var(--ink-soft); line-height: 1.7; }

/* ── Close ───────────────────────────────────────────────────────────────── */
.ab-close-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(2rem, 5vw, 4rem); }
.ab-close-grid h2 { margin: 0 0 .7rem; font-size: clamp(1.4rem, 2.6vw, 2rem); line-height: 1.2; }
.ab-close-grid p { color: var(--ink-soft); line-height: 1.7; max-width: 28rem; }
.ab-actions { display: flex; flex-wrap: wrap; gap: .7rem; margin-top: 1.3rem; }

.ab-registration { margin-top: clamp(3rem, 6vw, 5rem); padding-top: 1.6rem; border-top: 1px solid var(--line); }
.ab-reg-head { margin: 0 0 .7rem; font-size: .74rem; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-soft); font-family: inherit; font-weight: 600; }
.ab-registration p { margin: 0; font-size: .88rem; line-height: 1.85; color: var(--ink-soft); }

/* ── Responsive ──────────────────────────────────────────────────────────── */
@media (max-width: 60rem) {
    .ab-belief-list, .ab-close-grid { grid-template-columns: 1fr; }
}
@media (max-width: 40rem) {
    /* Four covers, not six — six at phone width leaves each too small to read
       as a book. The last two are dropped rather than shrunk. */
    .ab-shelf img:nth-child(n+5) { display: none; }
    .ab-shelf img { width: 4.2rem; }
    .ab-first { padding-left: .9rem; }
    .ab-actions .btn { width: 100%; min-height: 48px; }
}
@media (prefers-reduced-motion: reduce) {
    .ab-shelf img { transform: none; }
}

/* ── Order licence ──────────────────────────────────────────────────────────
   A disclosure, not a wall of text. Almost nobody opens a licence; the ones
   who do want the exact wording, so the body is preformatted and scrolls
   inside its own box rather than pushing the page to arm's length. */
.ord-licence {
    max-width: 46rem; margin: clamp(1.5rem, 3vw, 2.5rem) 0 0;
    border: 1px solid var(--line); border-radius: 3px; background: var(--paper-deep);
}
.ord-licence > summary {
    display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
    padding: .9rem 1.1rem; cursor: pointer; font-weight: 600; color: var(--navy);
}
.ord-licence > summary:hover { color: var(--brass-deep); }
.ord-licence > summary code {
    font-size: .78rem; font-weight: 500; color: var(--ink-soft);
    letter-spacing: .04em; white-space: nowrap;
}
.ord-licence > p { margin: 0 1.1rem; }
.ord-licence-body {
    margin: .8rem 1.1rem 1.1rem; padding: 1rem;
    background: var(--white); border: 1px solid var(--line); border-radius: 2px;
    font-family: inherit; font-size: .85rem; line-height: 1.7; color: var(--ink-soft);
    white-space: pre-wrap; word-break: break-word;
    max-height: 26rem; overflow-y: auto;
}
@media (max-width: 40rem) {
    .ord-licence > summary { flex-direction: column; gap: .25rem; }
}

/* ── Operations ─────────────────────────────────────────────────────────────
   Queues, not charts. Each tile is work someone has to do; a tile at zero is
   greyed rather than hidden, because an empty queue is information and a
   disappearing tile makes the grid jump. */
.ops-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr)); gap: .8rem; margin-bottom: 1.6rem; }
.ops-tile { display: block; padding: .9rem 1rem; border: 1px solid var(--line); border-radius: 3px;
            background: var(--white); text-decoration: none; color: var(--navy); transition: border-color .2s ease; }
.ops-tile:hover { border-color: var(--gold); }
.ops-tile strong { display: block; font-family: var(--font-display); font-size: 1.7rem; line-height: 1; font-variant-numeric: tabular-nums; }
.ops-tile span { display: block; margin-top: .3rem; font-size: .78rem; color: var(--ink-soft); }
.ops-tile.is-empty { opacity: .5; }
.ops-tile.is-urgent:not(.is-empty) { border-color: #A33; }
.ops-tile.is-urgent:not(.is-empty) strong { color: #A33; }

.ops-new { margin-bottom: 1.4rem; border: 1px solid var(--line); border-radius: 3px; background: var(--paper-deep); }
.ops-new > summary { padding: .8rem 1rem; cursor: pointer; font-weight: 600; }
.ops-new form { padding: 0 1rem 1rem; }
.ops-new-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); gap: .8rem; margin-bottom: .8rem; }
.ops-new label, .ops-edit label, .ops-side label { display: block; margin-bottom: .7rem; font-size: .82rem; color: var(--ink-soft); }
.ops-new input, .ops-new select, .ops-new textarea,
.ops-edit input, .ops-edit select, .ops-edit textarea,
.ops-side select { width: 100%; margin-top: .25rem; padding: .45rem .55rem; border: 1px solid var(--line); border-radius: 3px; font: inherit; font-size: .9rem; }

.ops-filters { display: flex; flex-wrap: wrap; gap: .5rem; margin-bottom: 1rem; }
.ops-filters select, .ops-filters input { padding: .45rem .55rem; border: 1px solid var(--line); border-radius: 3px; font: inherit; font-size: .88rem; }
.ops-filters input[type=search] { flex: 1 1 14rem; }

.ops-table { width: 100%; border-collapse: collapse; font-size: .9rem; }
.ops-table th { text-align: left; padding: .5rem; border-bottom: 1px solid var(--line); font-size: .72rem; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-soft); }
.ops-table td { padding: .6rem .5rem; border-bottom: 1px solid var(--line); vertical-align: top; }
.ops-table tr.is-closed { opacity: .55; }
.ops-table code { font-size: .82rem; }
.ops-pri { display: inline-block; padding: .1rem .4rem; border-radius: 2px; font-size: .72rem; font-weight: 600; }
.ops-p1 { background: #FBE9E9; color: #A33; }
.ops-p2 { background: #FDF3E3; color: #8A6819; }
.ops-p3, .ops-p4 { background: var(--paper-deep); color: var(--ink-soft); }
.ops-status { font-size: .82rem; color: var(--ink-soft); }

.ops-empty { padding: 2rem; text-align: center; border: 1px dashed var(--line); border-radius: 3px; }
.ops-warn { padding: .8rem 1rem; margin-bottom: 1.2rem; border-left: 3px solid #A33; background: #FBE9E9; font-size: .9rem; }
.ops-detail { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: 2rem; align-items: start; }
.ops-side { border: 1px solid var(--line); border-radius: 3px; padding: 1rem; background: var(--paper-deep); }
.ops-times { margin: 0 0 1.2rem; font-size: .85rem; }
.ops-times > div { display: flex; justify-content: space-between; gap: 1rem; padding: .25rem 0; }
.ops-times dt { color: var(--ink-soft); } .ops-times dd { margin: 0; }
.ops-related { list-style: none; margin: 0 0 1rem; padding: 0; font-size: .85rem; }
.ops-related li { padding: .5rem 0; border-bottom: 1px solid var(--line); }
.ops-comments { list-style: none; margin: 0 0 1rem; padding: 0; }
.ops-comments li { padding: .6rem 0; border-bottom: 1px solid var(--line); }
.ops-comments p { margin: .2rem 0 0; font-size: .9rem; }
.ops-recent { list-style: none; margin: 0; padding: 0; font-size: .88rem; }
.ops-recent li { padding: .4rem 0; border-bottom: 1px solid var(--line); }
.link-btn { background: none; border: 0; padding: 0; color: var(--ink-soft); font-size: .78rem; text-decoration: underline; cursor: pointer; }
@media (max-width: 60rem) { .ops-detail { grid-template-columns: 1fr; } }

/* Three-way match verdicts. Colour carries meaning here, so the label always
   spells the verdict out as well - a red chip alone is not an explanation. */
.pm-match { display: inline-block; padding: .1rem .4rem; border-radius: 2px; font-size: .72rem; font-weight: 600; text-transform: capitalize; }
.pm-matched  { background: #E6F4EC; color: #1B7A4B; }
.pm-mismatch { background: #FBE9E9; color: #A33; }
.pm-partial  { background: #FDF3E3; color: #8A6819; }
.pm-no_po, .pm-none { background: var(--paper-deep); color: var(--ink-soft); }
.num-col { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Admin nav group headings. Small caps, generous space above, no box — the
   grouping should read as structure, not as six nested panels. */
.admin-nav-group {
    margin: 1.4rem 0 .3rem; padding: 0 0 0 .1rem;
    font-size: .66rem; letter-spacing: .13em; text-transform: uppercase;
    color: rgba(255,255,255,.42); font-weight: 600;
}
.admin-nav-group:first-of-type { margin-top: 1rem; }

/* Document and cross-link panels — shared by ops records and purchase orders.
   Both reuse the ops list rhythm so a purchase order and an incident look like
   the same application rather than two that happen to share a stylesheet. */
.doc-list,
.cross-link-list { list-style: none; margin: 0 0 1rem; padding: 0; font-size: .85rem; }
.doc-list li { padding: .5rem 0; border-bottom: 1px solid var(--line); }
.doc-list li:last-child,
.cross-link-list li:last-child { border-bottom: 0; }
.doc-list a { font-weight: 600; }
/* The remove/unlink buttons sit at the end of the row, not under it: they are
   secondary to the record they belong to and should never read as the action. */
.doc-list form,
.cross-link-list form { float: right; margin-left: .8rem; }
.doc-list li::after,
.cross-link-list li::after { content: ""; display: block; clear: both; }

/* Help centre and knowledge base. The help list reuses the ops list rhythm so
   a customer-facing answer and an internal one are the same document type
   wearing different clothes, not two separate implementations. */
.help-list { list-style: none; margin: 0 0 1.6rem; padding: 0; }
.help-list li { padding: .7rem 0; border-bottom: 1px solid var(--line); }
.help-list li:last-child { border-bottom: 0; }
.help-list a { font-weight: 600; }
.help-body { max-width: 42rem; line-height: 1.7; }
.help-feedback { display: flex; align-items: center; gap: .6rem; margin-top: 2rem;
                 padding-top: 1rem; border-top: 1px solid var(--line); }

/* ── Financial Command Centre ─────────────────────────────────────────────
   Every figure carries its classification inline. The colours are a shortcut
   for people who already know the scheme; the text label is what actually
   communicates, which is why it is always present and never replaced by a
   colour alone. */
.fig { display: inline-flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; }
.fig-amount { font-variant-numeric: tabular-nums; font-weight: 600; }
.fig-badge { font-size: .68rem; text-transform: uppercase; letter-spacing: .04em;
             padding: .1rem .4rem; border-radius: 3px; border: 1px solid; white-space: nowrap; }
.fig-note { font-size: .78rem; color: var(--ink-soft); line-height: 1.45; }

.fig-verified-actual .fig-badge      { color: #1B6B45; border-color: #A8D5BE; background: #EEF7F2; }
.fig-management-estimate .fig-badge  { color: #7A5A12; border-color: #E0CB92; background: #FBF6E9; }
.fig-valuation-assumption .fig-badge { color: #5A4B8A; border-color: #C6BCE0; background: #F3F0FA; }
.fig-forecast .fig-badge             { color: #2A5F86; border-color: #A9C9E0; background: #EEF4FA; }
/* Missing data is greyed, never red: it is not an error, it is an absence. */
.fig-missing-data .fig-amount        { font-weight: 500; color: var(--ink-soft); font-style: italic; }
.fig-missing-data .fig-badge         { color: #6B6B6B; border-color: #D4D4D4; background: #F5F5F5; }

.val-disclaimer { border-left-color: #8A6819; background: #FDF3E3; }
.val-headline { display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
                gap: 1rem; margin: 1rem 0 .6rem; }
.val-head-tile { border: 1px solid var(--line); border-radius: 6px; padding: 1rem 1.2rem; }
.val-head-tile.is-primary { border-width: 2px; border-color: var(--ink); }
.val-head-tile span { display: block; font-size: .78rem; color: var(--ink-soft);
                      text-transform: uppercase; letter-spacing: .05em; margin-bottom: .4rem; }
.val-nohead { border-left: 3px solid var(--line); }

.val-confidence { border: 1px solid var(--line); border-radius: 6px; padding: 1rem 1.2rem; margin: 1.4rem 0; }
.val-confidence h3 { margin: 0 0 .3rem; font-size: 1rem; }
.val-confidence.conf-low { border-left: 3px solid #8A6819; }
.val-confidence.conf-moderate { border-left: 3px solid #2A5F86; }
.val-confidence.conf-high { border-left: 3px solid #1B6B45; }
.val-factors { list-style: none; margin: .6rem 0 0; padding: 0; font-size: .82rem;
               display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: .2rem .8rem; }
.val-factors .is-absent { color: var(--ink-soft); }

.val-overlap.sev-high { border-left-color: #9B2C2C; }
.val-methods .is-inapplicable td { background: #FAFAFA; }
.val-two-col { display: grid; grid-template-columns: repeat(auto-fit, minmax(22rem, 1fr)); gap: 1.6rem; }
.val-sub { font-size: .95rem; margin: 1.2rem 0 .4rem; }
.val-total td { border-top: 2px solid var(--ink); }
.val-disclaimer-list { font-size: .84rem; line-height: 1.6; color: var(--ink-soft); max-width: 46rem; }
.val-disclaimer-list li { margin-bottom: .5rem; }

/* ── Governance & Compliance Centre ───────────────────────────────────────
   The permission matrix is the one table here that genuinely needs to be wide.
   It scrolls inside its own container rather than forcing the page sideways. */
.gov-state { font-size: .72rem; text-transform: uppercase; letter-spacing: .04em;
             padding: .12rem .45rem; border-radius: 3px; border: 1px solid; white-space: nowrap; }
.gov-state.is-on  { color: #1B6B45; border-color: #A8D5BE; background: #EEF7F2; }
.gov-state.is-off { color: #9B2C2C; border-color: #E8B4B4; background: #FBEFEF; }
.gov-controls td { vertical-align: top; }

.gov-finding.sev-high { border-left-color: #9B2C2C; }
.gov-finding.sev-medium { border-left-color: #8A6819; }
.gov-finding.sev-low { border-left-color: var(--line); }

.gov-matrix-wrap { overflow-x: auto; margin-bottom: 1.6rem; }
.gov-matrix { min-width: 44rem; }
.gov-matrix .gov-cell { text-align: center; }
.gov-yes { color: #1B6B45; font-weight: 700; }
/* Role names are long and columns are narrow; rotating keeps the header
   readable without making every column as wide as its label. */
.gov-rot { height: 8rem; vertical-align: bottom; padding: 0; }
.gov-rot span { display: block; writing-mode: vertical-rl; transform: rotate(180deg);
                font-size: .78rem; font-weight: 600; white-space: nowrap; padding: .4rem .2rem; }

.gov-role-chip { display: inline-flex; align-items: center; gap: .25rem; font-size: .74rem;
                 border: 1px solid var(--line); border-radius: 3px; padding: .1rem .35rem;
                 margin: 0 .2rem .2rem 0; }
/* Security-relevant rows are tinted, never coloured red — they are records to
   read, not errors to fix. */
.gov-sec td { background: #FCFAF4; }

/* Data room. Download buttons sit together so the format choice reads as one
   control rather than two competing actions. */
.exp-table td { vertical-align: top; }
.exp-table .btn-small + .btn-small { margin-left: .3rem; }

/* ── Reporting suite ──────────────────────────────────────────────────────
   Document styling, not dashboard styling. These get printed, emailed to an
   accountant and attached to board packs; tiles and colour do not survive
   that journey and an accountant is not reading for visual interest. */
.rep-tabs { display: flex; flex-wrap: wrap; gap: .3rem; margin-bottom: 1.6rem;
            border-bottom: 1px solid var(--line); padding-bottom: .6rem; }
.rep-tab { font-size: .82rem; padding: .35rem .7rem; border: 1px solid var(--line);
           border-radius: 4px; text-decoration: none; color: var(--ink-soft); }
.rep-tab.is-current { border-color: var(--ink); color: var(--ink); font-weight: 600; }

.rep-doc { max-width: 58rem; }
.rep-head { border-bottom: 2px solid var(--ink); padding-bottom: 1rem; margin-bottom: 1.6rem; }
.rep-head h2 { margin: 0 0 .5rem; }
.rep-entity { margin: 0 0 .5rem; font-size: .92rem; }
.rep-meta { margin: 0; font-size: .82rem; color: var(--ink-soft); line-height: 1.6; }

.rep-section { margin-bottom: 2rem; }
.rep-section h3 { font-size: .92rem; text-transform: uppercase; letter-spacing: .06em;
                  border-bottom: 1px solid var(--line); padding-bottom: .3rem; margin-bottom: .7rem; }
.rep-note { font-size: .82rem; color: var(--ink-soft); margin: 0 0 .7rem; line-height: 1.55; }
.rep-footer { font-size: .82rem; margin: .6rem 0 0; padding-top: .5rem;
              border-top: 1px solid var(--line); }

.rep-table { width: 100%; border-collapse: collapse; font-size: .85rem; }
.rep-table th, .rep-table td { text-align: left; padding: .4rem .6rem .4rem 0;
                               border-bottom: 1px solid var(--line); vertical-align: top; }
.rep-table thead th { font-weight: 600; border-bottom-width: 2px; }
.rep-table tbody th { font-weight: 500; width: 18rem; }

.rep-basis ol { font-size: .8rem; line-height: 1.6; color: var(--ink-soft); padding-left: 1.2rem; }
.rep-basis li { margin-bottom: .45rem; }
.rep-actions { margin-top: 2rem; display: flex; align-items: center; gap: .8rem; flex-wrap: wrap; }

@media print {
  .rep-tabs, .rep-actions, .admin-nav, .admin-head { display: none; }
  .rep-doc { max-width: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   ADMIN CONSOLE
   ═══════════════════════════════════════════════════════════════════════════

   The admin had been inheriting storefront styling: serif display faces,
   marketing-weight cards, generous whitespace. That is right for a bookshop
   and wrong for an operations console, which is a different product with a
   different user — somebody who is here for hours, already knows where things
   are, and is reading numbers rather than being persuaded by them.

   The principles, applied consistently below:

     Density over comfort. An operator wants more rows visible, not more air.
     Numbers are the interface. Tabular figures everywhere, right-aligned, so
       columns of money scan vertically without the eye re-anchoring.
     Colour is semantic only. Nothing is coloured for decoration; if something
       is red it is because it needs attention.
     One accent. Restraint reads as expensive; a second accent reads as a
       template.
     Hairlines, not shadows. Shadows suggest depth for its own sake; rules
       organise information.

   Everything is scoped under .admin-layout, so the storefront is untouched. */

.admin-layout {
    /* A console palette of its own. Deliberately not the brand navy: the
       storefront colours are chosen to sell books, these are chosen to be
       looked at all day without fatigue. */
    --c-bg:        #0F1115;
    --c-surface:   #FFFFFF;
    --c-canvas:    #F6F7F9;
    --c-line:      #E3E6EB;
    --c-line-soft: #EDEFF3;
    --c-ink:       #14171F;
    --c-ink-2:     #4A5160;
    --c-ink-3:     #7A8394;
    --c-accent:    #C89B3C;
    --c-ok:        #1B6B45;
    --c-warn:      #8A6819;
    --c-bad:       #9B2C2C;
    --c-side-ink:  #9AA3B2;
    --c-side-hov:  #1A1D24;

    --c-gutter: clamp(1rem, 2.5vw, 1.9rem);

    grid-template-columns: 15rem 1fr;
    background: var(--c-canvas);
    font-feature-settings: "tnum" 1;
}

/* ── Sidebar ─────────────────────────────────────────────────────────────── */

.admin-layout .admin-side {
    background: var(--c-bg);
    color: var(--c-side-ink);
    padding: 0;
    /* Sticks while the working area scrolls: navigation that scrolls away is
       navigation you have to scroll back up to find. */
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
    border-right: 1px solid #000;
    scrollbar-width: thin;
    scrollbar-color: #2A2E37 transparent;
}
.admin-layout .admin-side::-webkit-scrollbar { width: 8px; }
.admin-layout .admin-side::-webkit-scrollbar-thumb { background: #2A2E37; border-radius: 4px; }

.admin-layout .admin-side .logo {
    display: flex; align-items: center; gap: .5rem;
    font-family: var(--font-display);
    font-size: .98rem; letter-spacing: -.01em;
    color: #fff; margin: 0;
    padding: 1.15rem 1.1rem;
    border-bottom: 1px solid #1E222A;
}
.admin-layout .admin-side .logo-mark { width: 20px; height: 20px; }
.admin-layout .admin-side .logo-art { color: var(--c-accent); }

.admin-layout .admin-side nav { padding: .5rem .6rem; }

.admin-layout .admin-nav-group {
    font-size: .64rem; font-weight: 700; letter-spacing: .13em; text-transform: uppercase;
    color: #5C6373;
    margin: 1.1rem 0 .3rem; padding: 0 .5rem;
}
.admin-layout .admin-nav-group:first-of-type { margin-top: .4rem; }

.admin-layout .admin-side nav a {
    display: flex; align-items: center; justify-content: space-between; gap: .5rem;
    font-size: .82rem; line-height: 1.3;
    color: var(--c-side-ink);
    padding: .38rem .5rem;
    border-radius: 5px;
    border-left: 0;
    transition: background .12s ease, color .12s ease;
}
.admin-layout .admin-side nav a:hover { background: var(--c-side-hov); color: #E8EBF0; }

/* The active item carries a rail, not a filled block: a block competes with
   the content area for weight, a rail simply says "you are here". */
.admin-layout .admin-side nav a.is-active {
    background: var(--c-side-hov);
    color: #fff;
    font-weight: 600;
    border-left: 0;
    box-shadow: inset 2px 0 0 var(--c-accent);
}

.admin-layout .admin-side .cart-count {
    background: var(--c-bad); color: #fff;
    font-size: .65rem; font-weight: 700;
    min-width: 1.15rem; height: 1.15rem;
    padding: 0 .3rem; border-radius: 999px;
    display: inline-flex; align-items: center; justify-content: center;
}

/* ── Working area ────────────────────────────────────────────────────────── */

.admin-layout .admin-main {
    background: var(--c-canvas);
    min-width: 0;   /* lets wide tables scroll instead of stretching the grid */
}
/* A table that genuinely cannot fit scrolls inside its own box. The page
   body must never scroll sideways. */
.admin-layout .gov-matrix-wrap,
.admin-layout .table-scroll { overflow-x: auto; }

/* The page header is a bar, not a hero. It stays put so an operator scrolling
   a long register always knows which screen they are on. */
.admin-layout .admin-head {
    position: sticky; top: 0; z-index: 20;
    background: rgba(255,255,255,.92);
    backdrop-filter: saturate(180%) blur(8px);
    border-bottom: 1px solid var(--c-line);
    /* Breaks out of the container padding so the rule under it spans the
       full working area, then re-applies the gutter to its own contents. */
    margin: 0 calc(-1 * var(--c-gutter)) 1.4rem;
    padding: .95rem var(--c-gutter);
    align-items: flex-start;
}
.admin-layout .admin-head h1 {
    font-family: var(--font-display);
    font-size: 1.12rem; font-weight: 600; letter-spacing: -.01em;
    color: var(--c-ink); margin: 0;
}
.admin-layout .admin-head p { margin: .18rem 0 0; font-size: .8rem; color: var(--c-ink-3); max-width: 62ch; }

/* The gutter lives on the container as padding, not on children as margins:
   a width:100% table inside a margined child is 100% of the container PLUS
   the margin, which is wider than the container and scrolls the page. */
.admin-layout .admin-main { padding: 0 var(--c-gutter) 2.5rem; }
.admin-layout .admin-main > *:last-child { margin-bottom: 0; }

/* ── Section headings ────────────────────────────────────────────────────── */

.admin-layout .set-sub {
    font-family: var(--font-body);
    font-size: .7rem; font-weight: 700; letter-spacing: .11em; text-transform: uppercase;
    color: var(--c-ink-3);
    margin: 1.9rem 0 .6rem;
    padding-bottom: .35rem;
    border-bottom: 1px solid var(--c-line);
}

/* ── Metric tiles ────────────────────────────────────────────────────────── */

.admin-layout .stat-grid,
/* Position cards: like ops-tiles but each carries a sentence saying what the
   figure means. The whole point of the accounting-position screen is that the
   numbers are unreadable without their definitions, so the definition is part
   of the card rather than a footnote under the row. */
.admin-layout .pos-grid {
    display: grid; gap: 1px;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    background: var(--c-line); border: 1px solid var(--c-line);
    border-radius: 8px; overflow: hidden; margin-bottom: 1.4rem;
}
.admin-layout .pos-card {
    background: var(--c-surface); padding: 1rem 1.1rem 1.1rem;
    display: flex; flex-direction: column; gap: .3rem;
}
.admin-layout .pos-label {
    font-size: .68rem; font-weight: 600; letter-spacing: .08em;
    text-transform: uppercase; color: var(--c-ink-3);
}
.admin-layout .pos-value {
    font-size: 1.5rem; font-weight: 600; letter-spacing: -.02em;
    font-variant-numeric: tabular-nums; color: var(--c-ink); line-height: 1.15;
}
.admin-layout .pos-card.is-empty .pos-value { color: var(--c-ink-3); font-weight: 500; }
.admin-layout .pos-means { font-size: .74rem; line-height: 1.45; color: var(--c-ink-3); }

/* One-line settings form: labels sit beside their inputs rather than above. */
.admin-layout .ops-inline-form {
    display: flex; flex-wrap: wrap; align-items: flex-end; gap: .8rem;
    background: var(--c-surface); border: 1px solid var(--c-line);
    border-radius: 8px; padding: .9rem 1rem; margin-bottom: .6rem;
}
.admin-layout .ops-inline-form label { display: flex; flex-direction: column; gap: .25rem; }
.admin-layout .ops-inline-form label.check {
    flex-direction: row; align-items: center; gap: .4rem; padding-bottom: .45rem;
}
.admin-layout .ops-inline-form input[type="number"] { width: 8rem; }

.admin-layout .ops-tiles {
    display: grid; gap: 1px;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    /* Hairline gaps over a ruled background: tiles read as one instrument
       panel rather than as separate floating cards. */
    background: var(--c-line);
    border: 1px solid var(--c-line);
    border-radius: 8px;
    overflow: hidden;
    margin-bottom: 1.6rem;
}
.admin-layout .stat-card,
.admin-layout .ops-tile {
    background: var(--c-surface);
    border: 0; border-radius: 0;
    padding: .85rem 1rem 1rem;
    display: flex; flex-direction: column-reverse; gap: .15rem;
    text-decoration: none;
    transition: background .12s ease;
}
.admin-layout a.ops-tile:hover { background: #FAFBFC; }
.admin-layout .stat-card .stat-label,
.admin-layout .ops-tile span {
    font-family: var(--font-body);
    font-size: .68rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
    color: var(--c-ink-3);
}
.admin-layout .stat-card .stat-value,
.admin-layout .ops-tile strong {
    font-family: var(--font-body);
    font-size: 1.5rem; font-weight: 600; letter-spacing: -.02em;
    font-variant-numeric: tabular-nums;
    color: var(--c-ink); line-height: 1.15;
}
.admin-layout .ops-tile.is-empty strong { color: var(--c-ink-3); font-weight: 500; }
.admin-layout .ops-tile.is-urgent strong { color: var(--c-bad); }
.admin-layout .ops-tile.is-urgent { box-shadow: inset 0 2px 0 var(--c-bad); }

/* ── Tables ──────────────────────────────────────────────────────────────── */

.admin-layout .ops-table,
.admin-layout .data-table {
    width: 100%; border-collapse: separate; border-spacing: 0;
    background: var(--c-surface);
    border: 1px solid var(--c-line);
    border-radius: 8px;
    overflow: hidden;
    font-size: .82rem;
    margin-bottom: 1.4rem;
}
.admin-layout .ops-table thead th,
.admin-layout .data-table thead th {
    background: #FBFBFC;
    font-size: .68rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
    color: var(--c-ink-3);
    padding: .55rem .8rem;
    border-bottom: 1px solid var(--c-line);
    text-align: left; white-space: nowrap;
}
.admin-layout .ops-table td,
.admin-layout .data-table td {
    padding: .55rem .8rem;
    border-bottom: 1px solid var(--c-line-soft);
    color: var(--c-ink-2);
    vertical-align: top;
}
.admin-layout .ops-table tbody tr:last-child td,
.admin-layout .data-table tbody tr:last-child td { border-bottom: 0; }
.admin-layout .ops-table tbody tr:hover td,
.admin-layout .data-table tbody tr:hover td { background: #FAFBFC; }
.admin-layout .ops-table strong { color: var(--c-ink); font-weight: 600; }

/* Money and counts line up vertically. This single change does more than any
   other to make a financial table look professional. */
.admin-layout .num-col,
.admin-layout .ops-table .num-col,
.admin-layout .data-table .num-col {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.admin-layout code {
    font-size: .78em; background: #F4F5F7; border: 1px solid var(--c-line-soft);
    padding: .05rem .3rem; border-radius: 3px; color: var(--c-ink-2);
}

/* ── Controls ────────────────────────────────────────────────────────────── */

.admin-layout .ops-filters {
    display: flex; flex-wrap: wrap; gap: .4rem; align-items: center;
    background: var(--c-surface);
    border: 1px solid var(--c-line); border-radius: 8px;
    padding: .6rem .7rem; margin-bottom: 1.2rem;
}
.admin-layout .ops-filters select,
.admin-layout .ops-filters input {
    font-size: .8rem; padding: .32rem .5rem;
    border: 1px solid var(--c-line); border-radius: 5px;
    background: var(--c-surface); color: var(--c-ink);
}
.admin-layout .ops-filters input[type="search"] { min-width: 14rem; }

.admin-layout .btn {
    font-size: .8rem; font-weight: 600; letter-spacing: 0;
    padding: .42rem .8rem; border-radius: 6px;
}
.admin-layout .btn-small { font-size: .74rem; padding: .28rem .55rem; }
.admin-layout .btn-quiet {
    background: var(--c-surface); color: var(--c-ink);
    border: 1px solid var(--c-line);
}
.admin-layout .btn-quiet:hover { background: #F4F5F7; border-color: #D2D7DE; }
.admin-layout .link-btn { font-size: .74rem; color: var(--c-ink-3); }
.admin-layout .link-btn:hover { color: var(--c-bad); }

.admin-layout .ops-new {
    background: var(--c-surface); border: 1px solid var(--c-line);
    border-radius: 8px; padding: 0; margin-bottom: 1.2rem;
}
.admin-layout .ops-new summary {
    padding: .6rem .8rem; font-size: .82rem; font-weight: 600; cursor: pointer;
    color: var(--c-ink);
}
.admin-layout .ops-new[open] summary { border-bottom: 1px solid var(--c-line); }
.admin-layout .ops-new > form { padding: .9rem .8rem; }
.admin-layout .ops-new-grid { gap: .7rem; }
.admin-layout label { font-size: .76rem; font-weight: 600; color: var(--c-ink-2); }
.admin-layout input, .admin-layout select, .admin-layout textarea { font-size: .82rem; }

/* Two panels of equal weight, side by side, stacking on a narrow window.
   For a pair of things being compared or edited together — the personal and
   commercial licence wordings — where neither is subordinate to the other. */
.admin-layout .licence-pair {
    display: grid; gap: 1.4rem;
    grid-template-columns: repeat(auto-fit, minmax(min(24rem, 100%), 1fr));
    align-items: start;
}

/* A textarea with no width falls back to HTML's cols="20" — about 167px,
   whatever the container. `.field`, `.ops-new` and `.ops-edit` each set
   width:100%, so a textarea inside one is fine; a bare one is not, and the
   licence editor was a 167px column inside a 741px card, wrapping the wording
   every three words.
   Width only, so padding, borders and fonts still come from whichever form
   pattern the control sits in. Vertical resize because a textarea that can be
   dragged wider than its column breaks the layout it lives in. */
.admin-layout textarea { width: 100%; resize: vertical; }

/* ── Notices ─────────────────────────────────────────────────────────────── */

.admin-layout .ops-warn,
.admin-layout .demo-note {
    background: var(--c-surface);
    border: 1px solid var(--c-line);
    border-left: 3px solid var(--c-warn);
    border-radius: 6px;
    padding: .7rem .9rem; font-size: .82rem;
    margin-bottom: 1.2rem; color: var(--c-ink-2);
}
.admin-layout .ops-warn strong { color: var(--c-ink); }
/* A neutral explanatory panel. Distinct from ops-warn because explaining why a
   figure is what it is must not read as an alert — nothing here is wrong. */
.admin-layout .ops-note {
    background: var(--c-surface); border: 1px solid var(--c-line);
    border-left: 3px solid var(--c-ink-3); border-radius: 6px;
    padding: .8rem 1rem; margin: 1.4rem 0; color: var(--c-ink-2);
}
.admin-layout .ops-note p { margin: 0 0 .4rem; }
.admin-layout .ops-note p:last-child { margin-bottom: 0; }
.admin-layout .ops-note strong { color: var(--c-ink); }
.admin-layout .ops-empty {
    background: var(--c-surface); border: 1px dashed var(--c-line);
    border-radius: 8px; padding: 1.8rem 1.2rem; text-align: center;
    color: var(--c-ink-3); font-size: .85rem; margin-bottom: 1.4rem;
}
.admin-layout .ops-empty strong { color: var(--c-ink-2); }
.admin-layout .small { font-size: .78rem; }
.admin-layout .muted { color: var(--c-ink-3); }

/* ── Detail layout ───────────────────────────────────────────────────────── */

.admin-layout .ops-detail,
.admin-layout .account-grid {
    display: grid; gap: 1.4rem;
    grid-template-columns: minmax(0, 1fr) minmax(0, 20rem);
}
@media (max-width: 1100px) {
    .admin-layout .ops-detail,
    .admin-layout .account-grid { grid-template-columns: minmax(0, 1fr); }
}
.admin-layout .val-two-col {
    display: grid; gap: 1.4rem;
    grid-template-columns: repeat(auto-fit, minmax(21rem, 1fr));
}

/* ── Financial figures on the console ────────────────────────────────────── */

.admin-layout .fig-amount { font-variant-numeric: tabular-nums; color: var(--c-ink); }
.admin-layout .fig-badge { font-size: .62rem; padding: .05rem .32rem; }
.admin-layout .val-head-tile {
    background: var(--c-surface); border: 1px solid var(--c-line); border-radius: 8px;
    padding: 1rem 1.1rem;
}
.admin-layout .val-head-tile.is-primary {
    border-color: var(--c-accent); box-shadow: inset 0 2px 0 var(--c-accent);
}
.admin-layout .val-head-tile span {
    font-size: .66rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
    color: var(--c-ink-3);
}
.admin-layout .val-pending {
    background: var(--c-surface); border: 1px solid var(--c-line);
    border-left: 3px solid var(--c-accent);
    border-radius: 6px; padding: .8rem 1rem; margin-bottom: 1.4rem; font-size: .84rem;
}
.admin-layout .val-confidence { background: var(--c-surface); border-color: var(--c-line); border-radius: 8px; }
.admin-layout .rep-doc { background: var(--c-surface); border: 1px solid var(--c-line);
                          border-radius: 8px; padding: 1.6rem 1.8rem; max-width: none; }
.admin-layout .gov-state { font-size: .64rem; }
.admin-layout .rep-tab { font-size: .78rem; background: var(--c-surface); }

@media (max-width: 900px) {
    .admin-layout { grid-template-columns: 1fr; }
    .admin-layout .admin-side { position: static; height: auto; }
    .admin-layout .admin-head { position: static; }
}

/* ── Admin menu search ───────────────────────────────────────────────────────
   Fifty-odd links across eleven groups is past the point where scanning beats
   typing. The box sits directly under the logo and above the menu, always
   visible: a search the operator has to open first is one they forget exists.

   Styled to belong to the sidebar rather than to sit on top of it — the same
   dark ground, a hairline border, and the gold only on focus, where it is
   doing work. */
.admin-search { position: relative; margin: .9rem 0 .2rem; }

.admin-search input {
    width: 100%;
    background: rgba(0, 0, 0, .22);
    border: 1px solid rgba(255, 255, 255, .12);
    border-radius: 7px;
    color: #E8EBF0;
    font: inherit;
    font-size: .82rem;
    padding: .46rem 2rem .46rem .6rem;
    transition: border-color .14s ease, background .14s ease, box-shadow .14s ease;
    -webkit-appearance: none;
    appearance: none;
}
.admin-search input::placeholder { color: rgba(255, 255, 255, .38); }
.admin-search input:hover { border-color: rgba(255, 255, 255, .2); }
.admin-search input:focus {
    outline: 0;
    background: rgba(0, 0, 0, .34);
    border-color: var(--gold);
    box-shadow: 0 0 0 3px rgba(197, 154, 61, .16);
}
/* The browser's own clear button is invisible on a dark ground. */
.admin-search input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }

/* The shortcut hint, shown only while the box is idle — once someone is typing
   they have plainly found it, and a key badge over their text is clutter. */
.admin-search kbd {
    position: absolute; right: .5rem; top: 50%; transform: translateY(-50%);
    font: 600 .64rem/1 ui-monospace, SFMono-Regular, Menlo, monospace;
    color: rgba(255, 255, 255, .4);
    background: rgba(255, 255, 255, .07);
    border: 1px solid rgba(255, 255, 255, .1);
    border-radius: 4px;
    padding: .18rem .32rem;
    pointer-events: none;
    transition: opacity .14s ease;
}
.admin-search input:focus ~ kbd,
.admin-search input:not(:placeholder-shown) ~ kbd { opacity: 0; }

.admin-search-empty {
    margin: .5rem 0 0; padding: 0 .1rem;
    font-size: .76rem; color: rgba(255, 255, 255, .45);
}

/* The keyboard cursor. Distinct from :hover and from .is-active, because all
   three can be on screen at once — the page you are on, the item under the
   mouse, and the item Enter would open. */
.admin-layout .admin-side nav a.is-cursor,
.admin-side nav a.is-cursor {
    background: rgba(197, 154, 61, .18);
    color: #fff;
    box-shadow: inset 2px 0 0 var(--gold);
}

@media (prefers-reduced-motion: reduce) {
    .admin-search input, .admin-search kbd { transition: none; }
}

/* Filtering must actually hide things.
   The menu sets `display: block` (and `display: flex` in the admin layout) on
   its links, and an explicit display beats the user agent's
   `[hidden] { display: none }`. So setting the hidden attribute changed
   nothing: a search for "incident" matched one item and still showed all
   fifty. !important is warranted — this has to win against any later display
   rule on the same elements, and losing means the search silently does
   nothing at all. */
.admin-nav a[hidden],
.admin-nav p[hidden],
.admin-layout .admin-side nav a[hidden] { display: none !important; }

/* ── Collapsible menu sections ───────────────────────────────────────────────
   The heading became a button, so it has to look like one you can press —
   without becoming a heavy control that competes with the links beneath it.
   The whole affordance is a chevron that rotates and a ground that appears on
   hover. */
.admin-nav-section { margin: 0; }

button.admin-nav-group {
    display: flex; align-items: center; justify-content: space-between; gap: .5rem;
    width: 100%;
    background: none; border: 0; cursor: pointer;
    text-align: left;
    font-family: inherit;
    border-radius: 5px;
    transition: color .12s ease, background .12s ease;
}
button.admin-nav-group:hover { color: rgba(255,255,255,.75); background: rgba(255,255,255,.05); }
button.admin-nav-group:focus-visible {
    outline: 2px solid var(--gold); outline-offset: 1px;
}

/* The chevron points down when open and right when closed — the direction the
   content will travel, which is the convention every operating system uses. */
.admin-nav-chev {
    flex: 0 0 auto;
    opacity: .55;
    transition: transform .18s ease, opacity .12s ease;
}
button.admin-nav-group:hover .admin-nav-chev { opacity: .9; }
.admin-nav-section.is-closed .admin-nav-chev { transform: rotate(-90deg); }

/* Height is animated from a measured pixel value, set by the script — auto
   cannot be transitioned. overflow hidden is what makes the clip work. */
.admin-nav-items {
    overflow: hidden;
    transition: height .2s cubic-bezier(.4, 0, .2, 1);
}

/* A closed section still shows a hint that something lives there: the heading
   dims slightly rather than the section vanishing into the background. */
.admin-nav-section.is-closed > button.admin-nav-group { color: rgba(255,255,255,.32); }

@media (prefers-reduced-motion: reduce) {
    .admin-nav-items { transition: none; }
    .admin-nav-chev { transition: none; }
}

/* Spacing normalisation for the section headings.
   The pre-existing rules targeted a <p> and included `:first-of-type`. Now
   that each heading is a button inside its own section, every one of them is
   the first of its type in its parent, so that rule fired for all eleven
   instead of one. Rhythm is set explicitly here rather than left to a selector
   that no longer means what it used to. Specificity is deliberately high
   enough to beat `.admin-layout .admin-nav-group`. */
.admin-layout .admin-nav-section > button.admin-nav-group,
.admin-side .admin-nav-section > button.admin-nav-group {
    margin: .9rem 0 .25rem;
    padding: .34rem .5rem;
}
.admin-layout .admin-nav-section:first-of-type > button.admin-nav-group,
.admin-side .admin-nav-section:first-of-type > button.admin-nav-group {
    margin-top: .5rem;
}

/* ── Install app ─────────────────────────────────────────────────────────────
   Hidden until the browser confirms the app is genuinely installable, so this
   is styled for a control that appears rather than one that is always there. */
.install-app { position: relative; }

.install-app-btn {
    display: inline-flex; align-items: center; gap: .45rem;
    padding: .4rem .8rem;
    background: none;
    border: 1px solid currentColor;
    border-radius: 999px;
    color: inherit;
    font: 600 .78rem/1 ui-sans-serif, system-ui, -apple-system, sans-serif;
    cursor: pointer;
    opacity: .75;
    transition: opacity .14s ease, background .14s ease;
}
.install-app-btn:hover { opacity: 1; background: rgba(255,255,255,.08); }
.install-app-btn:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; opacity: 1; }
.install-app-btn svg { flex: 0 0 auto; }

/* iOS has no install prompt, so it gets the three steps instead of a button
   that would do nothing. */
.install-app-ios {
    position: absolute; bottom: calc(100% + .6rem); right: 0; z-index: 40;
    width: min(19rem, 78vw);
    background: var(--white, #fff); color: var(--ink, #14243D);
    border: 1px solid var(--line, #E3E0D8); border-radius: 10px;
    padding: .9rem 1rem;
    box-shadow: 0 12px 30px rgba(0,0,0,.18);
    font: 400 .82rem/1.5 ui-sans-serif, system-ui, -apple-system, sans-serif;
    text-align: left;
}
.install-app-ios p { margin: 0 0 .5rem; }
.install-app-ios ol { margin: 0 0 .7rem; padding-left: 1.1rem; }
.install-app-ios li { margin: .25rem 0; }
.install-app-close {
    background: var(--brass, #8D6A19); color: #fff;
    border: 0; border-radius: 6px; padding: .38rem .8rem;
    font: 600 .78rem/1 inherit; cursor: pointer;
}

/* In the admin sidebar it sits under the menu, quiet and full width. */
.admin-side .install-app { margin-top: 1rem; }
.admin-side .install-app-btn { width: 100%; justify-content: center; font-size: .74rem; }
.admin-side .install-app-ios { right: auto; left: 0; }

/* ── The ecosystem page ──────────────────────────────────────────────────────
   Four sister brands presented as a family of specialists. The whole design
   rests on one device: every card carries its own --brand-accent, set inline
   from config, and every accented detail on that card derives from it. One
   variable per brand, and the page cannot drift out of step with the data. */

.brand-hero {
    position: relative;
    background: var(--navy);
    color: #fff;
    padding: clamp(3rem, 8vw, 5.5rem) 0 clamp(2.6rem, 6vw, 4rem);
    overflow: hidden;
}
/* A single light source behind the headline, the same staging the home hero
   uses — depth from light rather than from borders. */
.brand-hero::before {
    content: "";
    position: absolute; inset: -30% 20% auto -10%;
    height: 130%;
    background: radial-gradient(60% 55% at 30% 30%, rgba(201,155,46,.20), transparent 70%);
    pointer-events: none;
}
/* A hairline of gold along the foot, reading as the edge of a lit floor. */
.brand-hero::after {
    content: "";
    position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
    background: linear-gradient(90deg, transparent, rgba(201,155,46,.55) 30%, rgba(201,155,46,.55) 70%, transparent);
}
.brand-hero-inner { position: relative; z-index: 1; max-width: 46rem; }
.brand-hero .eyebrow { color: var(--gold); }
.brand-hero h1 {
    color: #fff;
    font-size: clamp(2rem, 5.2vw, 3.4rem);
    line-height: 1.08;
    letter-spacing: -.015em;
    margin: .5rem 0 1rem;
}
.brand-hero-lede {
    color: rgba(255,255,255,.78);
    font-size: clamp(1rem, 1.9vw, 1.12rem);
    line-height: 1.65;
    max-width: 40rem;
    margin: 0;
}

/* ── The four cards ── */
.brand-grid {
    display: grid;
    gap: clamp(1rem, 2vw, 1.4rem);
    grid-template-columns: repeat(auto-fit, minmax(15.5rem, 1fr));
}

.brand-card {
    position: relative;
    display: flex; flex-direction: column;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 14px;
    padding: 1.5rem 1.4rem 1.3rem;
    text-decoration: none;
    color: var(--ink);
    overflow: hidden;
    transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
/* The accent enters as a rule along the top edge — present but not shouting,
   and the one thing that differs between the four. */
.brand-card::before {
    content: "";
    position: absolute; top: 0; left: 0; right: 0; height: 3px;
    background: var(--brand-accent);
    opacity: .85;
}
a.brand-card:hover {
    transform: translateY(-3px);
    border-color: var(--brand-accent);
    box-shadow: 0 14px 34px rgba(11,31,59,.12);
}
a.brand-card:focus-visible { outline: 2px solid var(--brand-accent); outline-offset: 3px; }

.brand-card-top {
    display: flex; align-items: center; justify-content: space-between;
    gap: .75rem; margin-bottom: 1.1rem;
}
/* A monogram tile rather than a logo: we do not host the sister brands'
   artwork, and a wrong logo is worse than an honest initial. */
.brand-mark {
    display: inline-flex; align-items: center; justify-content: center;
    width: 2.6rem; height: 2.6rem;
    border-radius: 9px;
    /* Fallback first: color-mix is unsupported on older Safari, where an
       unparsed background would leave the monogram floating with no tile. */
    background: rgba(11, 31, 59, .06);
    background: color-mix(in srgb, var(--brand-accent) 12%, transparent);
    color: var(--brand-accent);
    font: 700 .74rem/1 ui-sans-serif, system-ui, sans-serif;
    letter-spacing: .04em;
}
.brand-role {
    font-size: .66rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
    color: var(--brand-accent);
}
.brand-card h2 { font-size: 1.22rem; margin: 0 0 .4rem; letter-spacing: -.01em; }
.brand-card p {
    font-size: .89rem; line-height: 1.6; color: var(--ink-soft);
    margin: 0 0 1.2rem; flex: 1 1 auto;
}
.brand-go {
    font-size: .84rem; font-weight: 700; color: var(--brand-accent);
    display: inline-flex; align-items: center; gap: .2rem;
}
a.brand-card:hover .brand-go span { transform: translateX(3px); display: inline-block; }
.brand-go span { transition: transform .18s ease; }

/* The current brand is a statement of fact, not a destination. */
.brand-card.is-current { background: var(--paper-deep); }
.brand-here {
    font-size: .72rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
    color: var(--ink-soft);
    display: inline-flex; align-items: center; gap: .4rem;
}
.brand-here::before {
    content: ""; width: 6px; height: 6px; border-radius: 50%;
    background: var(--brand-accent);
}

/* ── "Where to start" ── */
.brand-paths {
    display: grid; gap: clamp(1rem, 2vw, 1.3rem);
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}
.brand-path {
    background: var(--paper);
    border: 1px solid var(--line);
    border-left: 3px solid var(--brand-accent);
    border-radius: 10px;
    padding: 1.2rem 1.2rem 1.1rem;
}
.brand-path h3 { font-size: 1rem; margin: 0 0 .4rem; }
.brand-path p { font-size: .87rem; line-height: 1.6; color: var(--ink-soft); margin: 0; }

/* ── The company block ── */
.brand-trust { max-width: 42rem; }
.brand-trust h2 { font-size: clamp(1.4rem, 3vw, 1.9rem); margin: .4rem 0 .8rem; }

@media (prefers-reduced-motion: reduce) {
    .brand-card, .brand-go span { transition: none; }
    a.brand-card:hover { transform: none; }
}
