/* ============================================================
   AGADA PUBLISHINGS — design system
   Dark-committed editorial theme on a deep royal blue ground.
   All colour pairs verified against WCAG 2.2 AA (ratios inline).
   ============================================================ */

/* ---------- 1. Tokens ---------- */
:root {
  /* Surfaces — deep royal blue ramp */
  --ink-900: #0B1B4D;   /* page background */
  --ink-800: #122560;   /* raised surface / cards */
  --ink-700: #18306F;   /* hover surface */
  --ink-600: #27409A;   /* hairline borders (decorative only) */
  --ink-500: #3A55B0;   /* stronger border */
  --ink-950: #050D26;   /* overlays / lightbox scrim */

  /* Translucent scrims built on the blue base */
  --scrim-nav:   rgba(11, 27, 77, 0.86);
  --scrim-deep:  rgba(5, 13, 38, 0.94);
  --scrim-solid: rgba(11, 27, 77, 0.94);

  /* Content */
  --bone:     #F4F1EA;  /* 14.57:1 on ink-900 */
  --bone-dim: #A8ADBE;  /*  7.34:1 on ink-900 */
  --placeholder: #8890AE; /* 5.20:1 on ink-900 */

  /* Brand */
  --crimson:      #C8102E;  /* fills; #FFF on it = 5.88:1 */
  --crimson-lift: #E01B3C;  /* hover fill */
  --crimson-text: #FF5C7A;  /*  5.53:1 on ink-900 — use for TEXT */
  --gold:         #D8A537;  /*  7.32:1 on ink-900 */

  /* Type */
  --font-display: 'Libre Bodoni', Georgia, 'Times New Roman', serif;
  --font-body: 'Public Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

  /* Fluid type scale */
  --fs-xs:   0.75rem;
  --fs-sm:   0.875rem;
  --fs-base: 1rem;
  --fs-lg:   clamp(1.0625rem, 0.4vw + 0.97rem, 1.1875rem);
  --fs-xl:   clamp(1.25rem, 0.7vw + 1.1rem, 1.5rem);
  --fs-2xl:  clamp(1.5rem, 1.4vw + 1.2rem, 2.125rem);
  --fs-3xl:  clamp(2rem, 3vw + 1.3rem, 3.25rem);
  --fs-4xl:  clamp(2.5rem, 6vw + 1rem, 5.5rem);

  /* Spacing — 4/8 rhythm */
  --space-1: 0.25rem;  --space-2: 0.5rem;   --space-3: 0.75rem;
  --space-4: 1rem;     --space-6: 1.5rem;   --space-8: 2rem;
  --space-12: 3rem;    --space-16: 4rem;    --space-24: 6rem;
  --space-32: 8rem;

  --container: 1200px;
  --gutter: clamp(1.25rem, 4vw, 3rem);

  /* Motion */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --dur-fast: 160ms;
  --dur-mid: 260ms;

  /* Layers */
  --z-nav: 100;
  --z-overlay: 1000;
}

/* ---------- 2. Reset & base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 88px;   /* clears the sticky nav on anchor jumps */
}

body {
  margin: 0;
  background: var(--ink-900);
  color: var(--bone);
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.1;
  margin: 0;
  letter-spacing: -0.01em;
}

p { margin: 0; }

/* Focus — gold at 7.32:1 clears the 3:1 non-text requirement */
:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: 3px;
  border-radius: 2px;
}
:focus:not(:focus-visible) { outline: none; }

.skip-link {
  position: absolute; top: -100px; left: var(--space-4);
  background: var(--gold); color: var(--ink-900);
  padding: var(--space-3) var(--space-6);
  font-weight: 700; text-decoration: none;
  z-index: calc(var(--z-overlay) + 10);
  transition: top var(--dur-fast) var(--ease-out);
}
.skip-link:focus { top: var(--space-4); }

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------- 3. Layout ---------- */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.section { padding-block: clamp(var(--space-16), 9vw, var(--space-32)); }
.section--tight { padding-block: clamp(var(--space-12), 6vw, var(--space-24)); }
.section--surface { background: var(--ink-800); }

/* Eyebrow label — the recurring "chapter marker" motif */
.eyebrow {
  display: flex; align-items: center; gap: var(--space-3);
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--crimson-text);
  margin-bottom: var(--space-4);
}
.eyebrow::before {
  content: ""; width: 28px; height: 2px;
  background: var(--crimson); flex: none;
}

.section-head { max-width: 62ch; margin-bottom: var(--space-12); }
.section-head h2 { font-size: var(--fs-3xl); }
.section-head p {
  color: var(--bone-dim);
  font-size: var(--fs-lg);
  margin-top: var(--space-4);
  max-width: 60ch;
}

/* ---------- 4. Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--space-2);
  min-height: 48px;                     /* ≥44px touch target */
  padding: var(--space-3) var(--space-8);
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;   /* a wrapped CTA label reads as a layout bug */
  border: 2px solid transparent;
  border-radius: 2px;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
}
.btn:active { transform: translateY(1px); }

.btn--primary { background: var(--crimson); color: #FFFFFF; }  /* 5.88:1 */
.btn--primary:hover { background: var(--crimson-lift); }

.btn--ghost { background: transparent; color: var(--bone); border-color: var(--ink-500); }
.btn--ghost:hover { border-color: var(--bone); background: rgba(244,241,234,0.06); }

.btn--gold { background: var(--gold); color: var(--ink-900); }  /* 7.32:1 */
.btn--gold:hover { background: #E8B94F; }

.btn[aria-disabled="true"], .btn:disabled {
  opacity: 0.45; pointer-events: none;
}

/* ---------- 5. Navigation ---------- */
.nav {
  position: sticky; top: 0; z-index: var(--z-nav);
  background: var(--scrim-nav);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--ink-600);
}
.nav__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-6);
  min-height: 68px;
}
.nav__brand {
  display: flex; align-items: center; gap: var(--space-3);
  text-decoration: none; font-family: var(--font-display);
  font-weight: 700; font-size: var(--fs-lg); letter-spacing: 0.02em;
  flex: none;
}
/* Brand mark — the etched-armour logo. It's a photographic asset, so it
   gets a hairline and slight rounding to read as a deliberate emblem
   rather than a stray image. */
.nav__brand .mark {
  width: 44px; height: 44px; flex: none;
  object-fit: cover;
  border-radius: 3px;
  border: 1px solid var(--ink-500);
  box-shadow: 0 1px 6px rgba(0,0,0,0.5);
}
.nav__brand span small {
  display: block; font-family: var(--font-body);
  font-size: 0.5625rem; letter-spacing: 0.28em; font-weight: 600;
  color: var(--bone-dim); text-transform: uppercase; line-height: 1;
  margin-top: 2px;
}

.nav__links { display: flex; align-items: center; gap: var(--space-2); }
.nav__link {
  position: relative;
  padding: var(--space-3) var(--space-4);
  min-height: 44px; display: inline-flex; align-items: center;
  font-size: var(--fs-sm); font-weight: 600;
  letter-spacing: 0.06em; text-transform: uppercase;
  text-decoration: none; color: var(--bone-dim);
  transition: color var(--dur-fast) var(--ease-out);
}
.nav__link:hover { color: var(--bone); }
.nav__link[aria-current="page"] { color: var(--bone); }
.nav__link[aria-current="page"]::after {
  content: ""; position: absolute; left: var(--space-4); right: var(--space-4);
  bottom: 12px; height: 2px; background: var(--crimson);
}

.nav__toggle {
  display: none;
  width: 48px; height: 48px;
  align-items: center; justify-content: center;
  background: transparent; border: 1px solid var(--ink-500);
  border-radius: 2px; color: var(--bone); cursor: pointer;
}
.nav__toggle svg { width: 22px; height: 22px; }
.nav__toggle .icon-close { display: none; }
.nav__toggle[aria-expanded="true"] .icon-close { display: block; }
.nav__toggle[aria-expanded="true"] .icon-open { display: none; }

@media (max-width: 920px) {
  .nav__toggle { display: inline-flex; }
  .nav__links {
    position: fixed; inset: 68px 0 auto 0;
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--ink-800);
    border-bottom: 1px solid var(--ink-600);
    padding: var(--space-2) var(--gutter) var(--space-6);
    transform: translateY(-8px);
    opacity: 0; visibility: hidden;
    transition: opacity var(--dur-mid) var(--ease-out),
                transform var(--dur-mid) var(--ease-out),
                visibility var(--dur-mid);
  }
  .nav__links[data-open="true"] { opacity: 1; visibility: visible; transform: translateY(0); }
  .nav__link { padding-block: var(--space-4); border-bottom: 1px solid var(--ink-600); }
  .nav__link[aria-current="page"]::after { display: none; }
  .nav__links .btn { margin-top: var(--space-4); }
}

/* ---------- 6. Hero ---------- */
.hero {
  position: relative;
  overflow: hidden;
  padding-block: clamp(var(--space-16), 10vw, var(--space-32));
  border-bottom: 1px solid var(--ink-600);
}
.hero__bg {
  position: absolute; inset: -8% 0 -8% 0;
  background-size: cover; background-position: center 30%;
  opacity: 0.22;
  filter: saturate(0.75);
  will-change: transform;
}
.hero__scrim {
  position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(11,27,77,0.70) 0%, rgba(11,27,77,0.90) 55%, var(--ink-900) 100%),
    radial-gradient(80% 60% at 20% 40%, rgba(200,16,46,0.16), transparent 70%);
}
.hero__inner { position: relative; }

/* ---- Banner hero: full-bleed artwork, copy on the left ----
   The artwork carries the section, so the scrim is directional: near-opaque
   under the text, clearing to the right so the knight stays visible. Even
   against the brightest pixel in the image the copy bed composites to
   ~10:1 against --bone, so text contrast never depends on the photo. */
.hero--banner { min-height: clamp(560px, 72vh, 780px); display: grid; align-items: center; }
.hero--banner .hero__bg {
  inset: -4% 0 -4% 0;
  opacity: 1;
  filter: none;
  /* Frames the helmet and the engraved pauldron, with the cape sweeping right. */
  background-position: 58% 6%;
}
/* The plateau holds ~0.86 alpha across the full width of the copy. There is a
   near-white cloud break in the artwork directly behind the text; measured
   against that worst-case pixel the bed still gives ~9.5:1 with --bone. Do not
   lower these first three stops without re-measuring. */
.hero--banner .hero__scrim {
  background:
    linear-gradient(90deg,
      rgba(11,27,77,0.96) 0%,
      rgba(11,27,77,0.94) 34%,
      rgba(11,27,77,0.86) 50%,
      rgba(11,27,77,0.34) 72%,
      rgba(11,27,77,0.12) 100%),
    linear-gradient(180deg,
      rgba(11,27,77,0.40) 0%,
      rgba(11,27,77,0.04) 28%,
      rgba(11,27,77,0.10) 60%,
      var(--ink-900) 100%);
}
.hero--banner .hero__copy { max-width: 42ch; }
/* The button row needs a little more room than the text measure, or the two
   CTAs wrap onto separate lines. */
/* Three CTAs need ~641px; 44rem leaves headroom for font-rendering variance. */
.hero--banner .hero__actions { width: max-content; max-width: min(100vw - 2 * var(--gutter), 44rem); }
/* The ghost button is transparent by default; over artwork it gets its own
   bed so its label never depends on whatever pixel sits behind it. */
.hero--banner .btn--ghost {
  background: rgba(11,27,77,0.78);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
}
.hero--banner .btn--ghost:hover { background: rgba(11,27,77,0.92); }

/* Below the split point the copy spans the full width, so the horizontal
   gradient can no longer protect it — go mostly uniform instead. */
@media (max-width: 900px) {
  .hero--banner { min-height: clamp(520px, 80vh, 680px); }
  .hero--banner .hero__bg { background-position: 56% 4%; }
  /* Vertical ramp: the artwork reads clear across the top, then the bed comes
     up to ~0.92 before the first line of copy. Measured against the brightest
     pixel behind each line — the eyebrow is the tightest, so do not move the
     46% stop later without re-checking it. */
  .hero--banner .hero__scrim {
    background:
      linear-gradient(180deg,
        rgba(11,27,77,0.58) 0%,
        rgba(11,27,77,0.32) 20%,
        rgba(11,27,77,0.95) 44%,
        var(--ink-900) 78%);
  }
  /* Copy drops below the artwork so the knight is never behind the text. */
  .hero--banner .hero__inner { align-self: end; }
  .hero--banner .hero__copy { padding-top: 40vh; max-width: none; }
  /* Reset the desktop max-content sizing — at this width the two CTAs must be
     free to wrap instead of forcing the hero wider than the viewport. */
  .hero--banner .hero__actions { width: auto; max-width: none; }
}

.hero__grid {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: clamp(var(--space-8), 5vw, var(--space-16));
  align-items: center;
}
@media (max-width: 900px) {
  .hero__grid { grid-template-columns: 1fr; }
  .hero__art { order: -1; max-width: 320px; }
}

.hero__title {
  font-size: var(--fs-4xl);
  line-height: 0.98;
  letter-spacing: -0.02em;
  margin-bottom: var(--space-6);
}
.hero__title em {
  display: block; font-style: normal;
  color: var(--crimson-text);
}
.hero__lede {
  font-size: var(--fs-lg);
  color: var(--bone-dim);
  max-width: 52ch;
  margin-bottom: var(--space-8);
}
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--space-4); }

/* Book cover presented as a physical object */
.book {
  position: relative;
  aspect-ratio: 619 / 810;
  border: 1px solid var(--ink-500);
  box-shadow:
    0 2px 0 rgba(0,0,0,0.5),
    0 24px 60px -12px rgba(0,0,0,0.85),
    0 0 0 1px rgba(244,241,234,0.04) inset;
  transform-origin: center;
}
.book img { width: 100%; height: 100%; object-fit: cover; }
.book::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, rgba(0,0,0,0.42) 0%, rgba(0,0,0,0) 7%, rgba(255,255,255,0.05) 52%, rgba(0,0,0,0.16) 100%);
  pointer-events: none;
}

/* ---------- 7. Stat strip ---------- */
.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr));
  border-top: 1px solid var(--ink-600);
  border-left: 1px solid var(--ink-600);
}
.stat {
  border-right: 1px solid var(--ink-600);
  border-bottom: 1px solid var(--ink-600);
  padding: var(--space-6);
}
.stat__num {
  font-family: var(--font-display);
  font-size: var(--fs-2xl);
  font-weight: 700;
  color: var(--gold);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.stat__label {
  font-size: var(--fs-xs); letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--bone-dim);
  margin-top: var(--space-2);
}

/* ---------- 8. Catalog cards ---------- */
.catalog {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(240px, 100%), 1fr));
  gap: clamp(var(--space-6), 2.5vw, var(--space-8));
}
.title-card {
  position: relative;
  display: flex; flex-direction: column;
  background: var(--ink-800);
  border: 1px solid var(--ink-600);
  text-decoration: none;
  transition: border-color var(--dur-mid) var(--ease-out),
              transform var(--dur-mid) var(--ease-out),
              box-shadow var(--dur-mid) var(--ease-out);
}
.title-card:hover {
  border-color: var(--crimson);
  transform: translateY(-4px);
  box-shadow: 0 18px 40px -16px rgba(0,0,0,0.9);
}
.title-card__media {
  position: relative; aspect-ratio: 619 / 810;
  overflow: hidden; background: var(--ink-700);
}
.title-card__media img {
  width: 100%; height: 100%; object-fit: cover;
  /* Covers vary in ratio (0.67–0.76). Anchoring to the top keeps the title
     and author intact and takes any crop off the bottom margin. */
  object-position: center top;
  transition: transform 600ms var(--ease-out);
}
.title-card:hover .title-card__media img { transform: scale(1.04); }
.title-card__body { padding: var(--space-5, 1.25rem) var(--space-6) var(--space-6); }
.title-card h3 { font-size: var(--fs-xl); margin-bottom: var(--space-2); }
.title-card__meta {
  font-size: var(--fs-sm); color: var(--bone-dim);
}

.badge {
  position: absolute; top: var(--space-3); left: var(--space-3);
  z-index: 2;   /* above .letter-cover, which creates its own stacking context */
  background: var(--crimson); color: #FFFFFF;
  font-size: 0.6875rem; font-weight: 700;
  letter-spacing: 0.12em; text-transform: uppercase;
  padding: var(--space-1) var(--space-3);
  border-radius: 2px;
}
.badge--muted { background: var(--ink-500); color: var(--bone); }
.badge--gold { background: var(--gold); color: var(--ink-900); }

/* Action row inside a card. Used when a card carries its own controls, which
   means the card itself must NOT be a wrapping <a> — nesting interactive
   elements is invalid and traps keyboard users. */
.title-card__actions {
  margin-top: var(--space-4);
  display: flex; flex-wrap: wrap; gap: var(--space-2);
}
.title-card__actions .btn {
  flex: 1 1 auto;
  padding-inline: var(--space-4);
  min-height: 44px;
}
/* The title is the link when the card is not one. */
.title-card__body h3 a { text-decoration: none; }
.title-card__body h3 a:hover { color: var(--crimson-text); }

/* Non-clickable card — must not imply a link it doesn't have */
.title-card--static:hover {
  transform: none;
  border-color: var(--ink-600);
  box-shadow: none;
}
.title-card--static:hover .title-card__media img { transform: none; }

/* Placeholder card for titles not yet published */
.title-card--upcoming { border-style: dashed; }
.title-card--upcoming .title-card__media {
  display: grid; place-items: center;
  background:
    repeating-linear-gradient(45deg, var(--ink-700) 0 12px, var(--ink-800) 12px 24px);
}
.title-card--upcoming .title-card__media svg { width: 48px; height: 48px; color: var(--ink-500); }
.title-card--upcoming:hover { transform: none; border-color: var(--ink-500); box-shadow: none; }

/* ---------- 9. Art gallery ---------- */
.gallery {
  columns: 4 220px;
  column-gap: var(--space-4);
}
@media (max-width: 640px) { .gallery { columns: 2 140px; } }

/* Fewer, larger columns — for sets of only a handful of images, where the
   default four columns would shrink each piece to a thumbnail. */
.gallery--wide { columns: 2 340px; column-gap: var(--space-6); }
.gallery--wide .gallery__item { margin-bottom: var(--space-6); }

/* Exactly three across for the home-page preview, so it never breaks to a
   lopsided 2 + 1. Collapses to one column on small screens. */
.gallery--trio { columns: 3 200px; column-gap: var(--space-4); }
@media (max-width: 560px) { .gallery--trio { columns: 1; } }

.gallery__item {
  display: block; width: 100%;
  margin: 0 0 var(--space-4);
  padding: 0; border: 1px solid var(--ink-600);
  background: var(--ink-800);
  break-inside: avoid;
  cursor: pointer; position: relative;
  transition: border-color var(--dur-mid) var(--ease-out),
              transform var(--dur-mid) var(--ease-out);
}
.gallery__item img { width: 100%; height: auto; }
.gallery__item:hover { border-color: var(--gold); transform: translateY(-3px); }
.gallery__item figcaption {
  position: absolute; inset: auto 0 0 0;
  padding: var(--space-6) var(--space-3) var(--space-3);
  background: linear-gradient(180deg, transparent, var(--scrim-solid));
  font-size: var(--fs-xs); font-weight: 600;
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--bone);
  opacity: 0; transform: translateY(6px);
  transition: opacity var(--dur-mid) var(--ease-out), transform var(--dur-mid) var(--ease-out);
  text-align: left;
}
.gallery__item:hover figcaption,
.gallery__item:focus-visible figcaption { opacity: 1; transform: translateY(0); }

/* Lightbox */
/* A <dialog> is display:none until opened — restate it, because the
   .lightbox display rule below would otherwise override the UA default. */
.lightbox:not([open]) { display: none; }

.lightbox {
  position: fixed; inset: 0; z-index: var(--z-overlay);
  /* Override the UA's width/height:fit-content so the dialog fills the
     viewport — otherwise the close/nav buttons anchor to the image box. */
  width: 100%; height: 100%;
  max-width: none; max-height: none;
  display: grid; place-items: center;
  padding: var(--gutter);
  background: var(--scrim-deep);
  backdrop-filter: blur(6px);
  border: 0;
}
.lightbox::backdrop { background: var(--scrim-deep); }
.lightbox__figure { margin: 0; max-width: min(92vw, 720px); text-align: center; }
.lightbox__figure img {
  width: 100%; height: auto;
  max-height: 76vh; object-fit: contain;
  border: 1px solid var(--ink-500);
}
.lightbox__caption {
  display: block;
  margin-top: var(--space-4);
  font-family: var(--font-display);
  font-size: var(--fs-xl); color: var(--bone);
}
.lightbox__counter {
  display: block;
  font-family: var(--font-body); font-size: var(--fs-sm);
  color: var(--bone-dim); letter-spacing: 0.1em;
  font-variant-numeric: tabular-nums;
  margin-top: var(--space-1);
}
.lightbox__close, .lightbox__nav {
  position: absolute;
  width: 52px; height: 52px;
  display: grid; place-items: center;
  background: rgba(18,37,96,0.92);
  border: 1px solid var(--ink-500);
  color: var(--bone); cursor: pointer; border-radius: 2px;
  transition: background var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.lightbox__close:hover, .lightbox__nav:hover { background: var(--ink-700); border-color: var(--bone); }
.lightbox__close { top: var(--gutter); right: var(--gutter); }
.lightbox__nav svg, .lightbox__close svg { width: 22px; height: 22px; }
.lightbox__nav--prev { left: var(--gutter); top: 50%; transform: translateY(-50%); }
.lightbox__nav--next { right: var(--gutter); top: 50%; transform: translateY(-50%); }
@media (max-width: 640px) {
  .lightbox__nav--prev { left: var(--space-2); }
  .lightbox__nav--next { right: var(--space-2); }
  .lightbox__figure img { max-height: 62vh; }
}

/* ---------- 10. Character strip ---------- */
.cast {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
  gap: var(--space-6);
}
.cast__member { border: 1px solid var(--ink-600); background: var(--ink-800); }
/* height:auto is required — the HTML height attribute is a presentational
   hint that otherwise wins over aspect-ratio and stretches the image. */
.cast__member img { width: 100%; height: auto; aspect-ratio: 576/792; object-fit: cover; }
.cast__body { padding: var(--space-4) var(--space-5, 1.25rem) var(--space-6); }
.cast__body h3 { font-size: var(--fs-lg); }
.cast__role {
  font-size: var(--fs-xs); letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--gold); margin-bottom: var(--space-2); display: block;
}
.cast__body p { font-size: var(--fs-sm); color: var(--bone-dim); margin-top: var(--space-2); }

/* ---------- 11. Chapter list ---------- */
.chapters {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
  gap: 0;
  border-top: 1px solid var(--ink-600);
  border-left: 1px solid var(--ink-600);
}
.chapter {
  display: flex; align-items: baseline; gap: var(--space-4);
  padding: var(--space-4) var(--space-5, 1.25rem);
  border-right: 1px solid var(--ink-600);
  border-bottom: 1px solid var(--ink-600);
}
.chapter__num {
  font-family: var(--font-display); font-size: var(--fs-sm);
  color: var(--crimson-text); font-variant-numeric: tabular-nums;
  flex: none; min-width: 2.5ch;
}
.chapter__name {
  font-size: var(--fs-sm); letter-spacing: 0.02em;
  overflow-wrap: anywhere;
}

/* ---------- 11b. Brand mark, displayed large ---------- */
.brandmark { margin: 0; }
.brandmark img {
  width: 100%; height: auto;
  border: 1px solid var(--ink-600);
  border-radius: 3px;
}
.brandmark figcaption {
  margin-top: var(--space-4);
  font-size: var(--fs-sm);
  letter-spacing: 0.04em;
  color: var(--bone-dim);
}

/* ---------- 12. Prose ---------- */
.prose { max-width: 68ch; }
.prose p + p { margin-top: var(--space-6); }
.prose p { font-size: var(--fs-lg); color: var(--bone-dim); }
.prose strong { color: var(--bone); font-weight: 600; }
.pull-quote {
  border-left: 3px solid var(--crimson);
  padding-left: var(--space-6);
  margin: var(--space-12) 0;
  font-family: var(--font-display);
  font-size: var(--fs-2xl);
  line-height: 1.3;
  color: var(--bone);
}
.pull-quote cite {
  display: block; margin-top: var(--space-4);
  font-family: var(--font-body); font-style: normal;
  font-size: var(--fs-sm); letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--bone-dim);
}

/* ---------- 13. Buy panel ---------- */
.buy {
  display: grid;
  grid-template-columns: 0.8fr 1.2fr;
  gap: clamp(var(--space-8), 5vw, var(--space-16));
  align-items: center;
  border: 1px solid var(--ink-600);
  background: var(--ink-800);
  padding: clamp(var(--space-8), 4vw, var(--space-16));
}
@media (max-width: 820px) {
  .buy { grid-template-columns: 1fr; }
  .buy__art { max-width: 260px; margin-inline: auto; }
}
.price {
  display: flex; align-items: baseline; gap: var(--space-3);
  margin-block: var(--space-6);
}
.price__amount {
  font-family: var(--font-display); font-size: var(--fs-3xl);
  color: var(--bone); font-variant-numeric: tabular-nums;
}
.price__note { font-size: var(--fs-sm); color: var(--bone-dim); }
.formats { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-bottom: var(--space-6); }
.format-chip {
  border: 1px solid var(--ink-500); border-radius: 2px;
  padding: var(--space-2) var(--space-4);
  font-size: var(--fs-xs); letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--bone-dim);
}
.buy__actions { display: flex; flex-wrap: wrap; gap: var(--space-4); }
.buy__reassure {
  margin-top: var(--space-6); font-size: var(--fs-sm); color: var(--bone-dim);
  display: flex; align-items: center; gap: var(--space-2);
}
.buy__reassure svg { width: 16px; height: 16px; flex: none; color: var(--gold); }

/* ---------- 12b. Agadaverse: knight as a full-page backdrop ----------
   The artwork is fixed behind the entire page rather than confined to a hero.
   Two fixed layers (art + scrim) sit at z-index 0; every real element is
   lifted to z-index 1. A position:fixed element is used instead of
   background-attachment:fixed, which is unreliable on iOS. */
.verse-bg, .verse-scrim { position: fixed; inset: 0; z-index: 0; pointer-events: none; }
.verse-bg {
  background-image: url('../img/brand/agada-knight-banner.jpg');
  background-size: cover;
  background-position: 62% top;
}
.verse-scrim {
  background:
    linear-gradient(180deg,
      rgba(11,27,77,0.62) 0%,
      rgba(11,27,77,0.78) 34%,
      rgba(11,27,77,0.93) 62%,
      rgba(11,27,77,0.96) 100%);
}
.page--verse > main,
.page--verse > footer,
.page--verse > .skip-link { position: relative; z-index: 1; }
/* The nav must keep position:sticky — a blanket position:relative here would
   silently un-stick it on this page only. It just needs to sit above the
   fixed backdrop layers, which --z-nav already does. */
.page--verse > .nav { z-index: var(--z-nav); }

/* The hero copy sits directly on the artwork near the top of the page, where
   the page scrim is deliberately light so the knight reads. It therefore
   carries its own bed, bled off the left edge, holding ~0.96 alpha across the
   text. The eyebrow is the binding constraint: small crimson type over the
   bright sky, measured at ~5:1. Do not weaken this gradient. */
.verse-hero { position: relative; }
.verse-hero::before {
  content: "";
  position: absolute;
  /* Extends well past the copy so the vertical mask below can fade the bed
     out over empty artwork instead of cutting a hard band across the knight. */
  top: -60%; bottom: -60%;
  /* Spans the viewport exactly, so the gradient stops below are viewport
     fractions — the copy ends near 50%, well inside the 0.96 plateau. */
  left: 50%; transform: translateX(-50%); width: 100vw;
  background: linear-gradient(90deg,
    rgba(11,27,77,0.97) 0%,
    rgba(11,27,77,0.96) 54%,
    rgba(11,27,77,0.62) 76%,
    rgba(11,27,77,0) 94%);
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 26%, #000 74%, transparent 100%);
          mask-image: linear-gradient(180deg, transparent 0%, #000 26%, #000 74%, transparent 100%);
  pointer-events: none;
}
.verse-hero > * { position: relative; }

@media (max-width: 900px) {
  /* Full-width copy needs a full-width bed. */
  .verse-hero::before {
    right: -50vw;
    background: linear-gradient(180deg,
      rgba(11,27,77,0.80) 0%,
      rgba(11,27,77,0.96) 18%,
      rgba(11,27,77,0.96) 82%,
      rgba(11,27,77,0.80) 100%);
  }
}

/* Content panels stay translucent so the knight reads through them, but every
   one is opaque enough to carry body text on its own. */
.verse-panel {
  background: rgba(18,37,96,0.82);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--ink-600);
  padding: clamp(var(--space-6), 4vw, var(--space-12));
}
@supports not (backdrop-filter: blur(10px)) {
  .verse-panel { background: rgba(18,37,96,0.96); }
}

/* The three laws */
.laws { counter-reset: law; display: grid; gap: var(--space-6); }
.law {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-6);
  align-items: baseline;
  padding-block: var(--space-6);
  border-top: 1px solid var(--ink-600);
}
.law:first-child { border-top: 0; padding-top: 0; }
.law__num {
  font-family: var(--font-display);
  font-size: var(--fs-2xl);
  color: var(--gold);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.law h3 { font-size: var(--fs-lg); margin-bottom: var(--space-2); }
.law p { color: var(--bone-dim); font-size: var(--fs-sm); }

/* Who you meet there */
.denizens {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(160px, 100%), 1fr));
  gap: var(--space-6);
}
.denizen { border: 1px solid var(--ink-600); background: rgba(18,37,96,0.7); }
.denizen img {
  width: 100%; height: auto;      /* see note on .cast__member img */
  aspect-ratio: 3/4;
  object-fit: cover;
  object-position: center 22%;    /* these are scenes, not portraits — bias to the upper frame */
}
.denizen__body { padding: var(--space-4); }
.denizen__body h3 { font-size: var(--fs-base); margin-bottom: 2px; }
.denizen__from {
  font-size: 0.6875rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--gold);
}

/* ---------- 12c. Team ----------
   Photo-led rather than a grid of headshots — the source images are candid
   convention shots, so the layout leans into reportage instead of pretending
   they are studio portraits. */
.team-lead {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  gap: clamp(var(--space-6), 3vw, var(--space-12));
  align-items: start;
}
.team-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr));
  gap: clamp(var(--space-6), 3vw, var(--space-8));
  align-items: start;   /* short landscapes must not stretch to the portrait */
}
/* One portrait + two landscapes: give the portrait a tall left column and
   stack the landscapes beside it, rather than leaving a 2 + 1 orphan row. */
@media (min-width: 780px) {
  .team-strip { grid-template-columns: 0.92fr 1.08fr; }
  .team-strip > :first-child { grid-row: span 2; }
}
.team-shot { margin: 0; }
.team-shot img {
  width: 100%; height: auto;
  border: 1px solid var(--ink-600);
  box-shadow: 0 18px 44px -20px rgba(0,0,0,0.8);
}
.team-shot figcaption {
  margin-top: var(--space-3);
  font-size: var(--fs-sm);
  color: var(--bone-dim);
  max-width: 46ch;
}

/* Roster entries. Deliberately name-less until real names are supplied —
   a placeholder name on a photograph of a real person is worse than none. */
.roster {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
  gap: var(--space-6);
}
.roster__member {
  border: 1px solid var(--ink-600);
  background: var(--ink-800);
  padding: var(--space-6);
}
.roster__role {
  font-size: var(--fs-xs); letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--gold); display: block; margin-bottom: var(--space-2);
}
.roster__member h3 { font-size: var(--fs-lg); margin-bottom: var(--space-2); }
.roster__member p { font-size: var(--fs-sm); color: var(--bone-dim); }

/* ---------- 13a. Best sellers ---------- */
.sellers {
  display: grid;
  /* Always one entry per row. Two-up looked fine until the covers grew: at
     1440px the cells were 523px, the cover took 293px and left the copy on a
     198px column — roughly 28 characters a line. Full width lets the cover be
     large AND the copy readable. */
  grid-template-columns: 1fr;
  gap: clamp(var(--space-10, 2.5rem), 5vw, var(--space-16));
}
.seller {
  display: grid;
  /* Covers carry this section, so they get real width — and scale with the
     row rather than sitting at a fixed cap. */
  grid-template-columns: minmax(200px, clamp(260px, 36%, 420px)) 1fr;
  gap: clamp(var(--space-6), 3vw, var(--space-8));
  align-items: start;
}
@media (max-width: 560px) {
  /* Cover stacks above the copy; it still gets most of the column so the
     art carries the section on a phone the way it does on desktop. */
  .seller { grid-template-columns: 1fr; }
  .seller__art { max-width: 280px; }
}
.seller__art {
  position: relative;
  display: block;
  border: 1px solid var(--ink-500);
  box-shadow:
    0 2px 0 rgba(0,0,0,0.45),
    0 20px 44px -14px rgba(0,0,0,0.7);
  transition: transform var(--dur-mid) var(--ease-out);
}
/* No forced aspect-ratio — the two covers ship at 0.764 and 0.750, and
   cropping either one to match the other trims artwork for no gain. */
.seller__art img { width: 100%; height: auto; }
a.seller__art:hover { transform: translateY(-4px); }
.seller__rank {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-sm);
  font-weight: 700;
  letter-spacing: 0.12em;
  color: var(--crimson-text);
  margin-bottom: var(--space-2);
}
.seller__body h3 { font-size: var(--fs-xl); margin-bottom: var(--space-2); }
.seller__body h3 a { text-decoration: none; }
.seller__body h3 a:hover { color: var(--crimson-text); }
.seller__meta {
  font-size: var(--fs-sm); color: var(--gold);
  letter-spacing: 0.04em; margin-bottom: var(--space-3);
}
.seller__blurb {
  font-size: var(--fs-sm); color: var(--bone-dim);
  margin-bottom: var(--space-6);
  max-width: 60ch;   /* the row is wide now; the line length should not be */
}

/* ---------- 13b. Pillars ---------- */
.pillars {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
  border-top: 1px solid var(--ink-600);
  border-left: 1px solid var(--ink-600);
}
.pillar {
  display: block; text-decoration: none;
  border-right: 1px solid var(--ink-600);
  border-bottom: 1px solid var(--ink-600);
  padding: var(--space-8);
  transition: background var(--dur-mid) var(--ease-out);
}
.pillar:hover { background: var(--ink-700); }
.pillar__num {
  font-family: var(--font-display);
  font-size: var(--fs-sm); font-weight: 700;
  color: var(--crimson-text);
  letter-spacing: 0.1em;
  display: block; margin-bottom: var(--space-4);
}
.pillar h2 { font-size: var(--fs-xl); margin-bottom: var(--space-2); }
.pillar p { font-size: var(--fs-sm); color: var(--bone-dim); }
.pillar__go {
  display: inline-flex; align-items: center; gap: var(--space-2);
  margin-top: var(--space-4);
  font-size: var(--fs-xs); font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--gold);
}
.pillar__go svg { width: 14px; height: 14px; }

/* ---------- 13c. Format tags ---------- */
.formats-list {
  display: flex; flex-wrap: wrap; gap: var(--space-2);
  list-style: none; margin: 0; padding: 0;
}
.formats-list li {
  border: 1px solid var(--ink-500);
  border-radius: 2px;
  padding: var(--space-2) var(--space-4);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--bone);
}

/* ---------- 13d. Numbered process ---------- */
.process {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
  border-top: 1px solid var(--ink-600);
  border-left: 1px solid var(--ink-600);
  counter-reset: step;
}
.process__step {
  border-right: 1px solid var(--ink-600);
  border-bottom: 1px solid var(--ink-600);
  padding: var(--space-8);
}
.process__num {
  font-family: var(--font-display);
  font-size: var(--fs-2xl);
  color: var(--gold);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  display: block; margin-bottom: var(--space-4);
}
.process__step h3 { font-size: var(--fs-lg); margin-bottom: var(--space-3); }
.process__step p { font-size: var(--fs-sm); color: var(--bone-dim); }

/* ---------- 13e. Benefit cards ---------- */
.benefits {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  gap: var(--space-6);
}
.benefit {
  border: 1px solid var(--ink-600);
  background: var(--ink-800);
  padding: var(--space-8);
  border-top: 3px solid var(--crimson);
}
.benefit__icon {
  width: 28px; height: 28px; color: var(--gold);
  margin-bottom: var(--space-4);
}
.benefit h3 { font-size: var(--fs-lg); margin-bottom: var(--space-3); }
.benefit p { font-size: var(--fs-sm); color: var(--bone-dim); }

/* ---------- 13f. Typographic cover (titles without art) ---------- */
.letter-cover {
  position: relative;
  display: grid; place-items: center;
  aspect-ratio: 619 / 810;
  background:
    radial-gradient(120% 90% at 50% 0%, var(--ink-700), var(--ink-900) 70%);
  border-bottom: 1px solid var(--ink-600);
  overflow: hidden;
}
.letter-cover::before {
  content: attr(data-letter);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(5rem, 18vw, 9rem);
  line-height: 1;
  color: var(--bone);
  opacity: 0.13;
  position: absolute;
}
.letter-cover span {
  position: relative;
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  text-align: center;
  padding-inline: var(--space-4);
  color: var(--bone);
}

/* ---------- 13g. Merchandise ---------- */
.products {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(240px, 100%), 1fr));
  gap: var(--space-6);
}
.product {
  border: 1px solid var(--ink-600);
  background: var(--ink-800);
  padding: var(--space-6);
  display: flex; flex-direction: column; gap: var(--space-2);
}
.product__cat {
  font-size: 0.6875rem; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--gold);
}
.product h3 { font-size: var(--fs-lg); }
.product p { font-size: var(--fs-sm); color: var(--bone-dim); flex: 1; }
.product__price {
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  color: var(--bone);
  font-variant-numeric: tabular-nums;
  margin-top: var(--space-2);
}

/* ---------- 13h. Submission form ---------- */
.form {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-6);
  border: 1px solid var(--ink-600);
  background: var(--ink-800);
  padding: clamp(var(--space-6), 4vw, var(--space-12));
}
@media (max-width: 720px) { .form { grid-template-columns: 1fr; } }
.field { display: flex; flex-direction: column; gap: var(--space-2); }
.field--wide { grid-column: 1 / -1; }
.field label {
  font-size: var(--fs-xs); font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--bone);
}
.field .hint { font-size: var(--fs-xs); color: var(--bone-dim); }
.field input, .field select, .field textarea {
  min-height: 48px;                  /* comfortable touch target */
  padding: var(--space-3) var(--space-4);
  background: var(--ink-900);
  border: 1px solid var(--ink-500);
  border-radius: 2px;
  color: var(--bone);
  font-family: var(--font-body);
  font-size: var(--fs-base);         /* 16px — stops iOS auto-zoom */
  transition: border-color var(--dur-fast) var(--ease-out);
}
.field textarea { min-height: 140px; resize: vertical; line-height: 1.6; }
.field input::placeholder, .field textarea::placeholder { color: var(--placeholder); }
.field input:hover, .field select:hover, .field textarea:hover { border-color: var(--bone-dim); }
.field select {
  appearance: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239CA0AB' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-4) center;
  background-size: 18px;
  padding-right: var(--space-12);
}
.field .req { color: var(--crimson-text); }

/* ---------- 14. Footer ---------- */
.footer {
  border-top: 1px solid var(--ink-600);
  background: var(--ink-800);
  padding-block: var(--space-16) var(--space-8);
}
.footer__grid {
  display: grid;
  grid-template-columns: 1.4fr repeat(2, minmax(0, 1fr));
  gap: var(--space-12);
  margin-bottom: var(--space-12);
}
@media (max-width: 720px) { .footer__grid { grid-template-columns: 1fr; gap: var(--space-8); } }
.footer h3 {
  font-family: var(--font-body); font-size: var(--fs-xs);
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--bone-dim); margin-bottom: var(--space-4);
}
.footer ul { list-style: none; margin: 0; padding: 0; }
.footer li + li { margin-top: var(--space-1); }
.footer a {
  display: inline-flex; align-items: center; min-height: 44px;
  text-decoration: none; color: var(--bone);
  font-size: var(--fs-sm);
  transition: color var(--dur-fast) var(--ease-out);
}
.footer a:hover { color: var(--crimson-text); }
.footer__blurb { color: var(--bone-dim); font-size: var(--fs-sm); max-width: 42ch; margin-top: var(--space-4); }
.footer__base {
  border-top: 1px solid var(--ink-600);
  padding-top: var(--space-6);
  display: flex; flex-wrap: wrap; gap: var(--space-4);
  justify-content: space-between;
  font-size: var(--fs-xs); color: var(--bone-dim);
}

/* ---------- 14b. Line-reveal headlines ----------
   Headlines are split into lines and rise out from behind a mask. The
   opacity:0 below is applied ONLY after JS confirms SplitText loaded and the
   webfonts have settled (html.split-ready). If either fails, the headline
   never hides — it just renders normally. */
.js.split-ready [data-split] { opacity: 0; }
/* Set once the reveal has finished and the split has been reverted. */
.js.split-ready [data-split].is-revealed { opacity: 1; }

/* SplitText clips each line itself (inline overflow) so it emerges from a
   hard edge rather than fading in place; this just hints the compositor. */
[data-split] .split-line { will-change: transform; }

@media (prefers-reduced-motion: reduce) {
  .js.split-ready [data-split] { opacity: 1 !important; }
  [data-split] .split-line { transform: none !important; }
}

/* ---------- 14c. Pinned sequence (Agadaverse laws) ---------- */
.laws--pinned .law {
  border-top: 0;
  padding-block: 0;
}
.js .laws--pinned .law {
  opacity: 0.18;
  transition: opacity 400ms var(--ease-out);
}
.js .laws--pinned .law.is-current { opacity: 1; }
.laws--pinned .law__num {
  transition: color 400ms var(--ease-out), transform 400ms var(--ease-out);
}
.js .laws--pinned .law.is-current .law__num {
  color: var(--gold);
  transform: scale(1.35);
  transform-origin: left center;
}
.js .laws--pinned .law:not(.is-current) .law__num { color: var(--ink-500); }

@media (prefers-reduced-motion: reduce) {
  .js .laws--pinned .law { opacity: 1; }
  .js .laws--pinned .law .law__num { transform: none; color: var(--gold); }
}

/* ---------- 15. Scroll-reveal (progressive enhancement) ---------- */
/* Only hide content once JS confirms it can animate it back in. */
[data-reveal] { will-change: transform, opacity; }
.js [data-reveal] { opacity: 0; transform: translateY(24px); }
.js [data-reveal].is-visible { opacity: 1; transform: none; }

/* ---------- 16. Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .js [data-reveal] { opacity: 1 !important; transform: none !important; }
  .hero__bg { transform: none !important; }
  .title-card:hover { transform: none; }
  .gallery__item:hover { transform: none; }
}

/* ---------- 17. Print ---------- */
@media print {
  .nav, .hero__bg, .lightbox, .btn { display: none !important; }
  body { background: #fff; color: #000; }
}
