/* -------------------------------------------------------------
   tomrankin.net - main.css
   Semantic, responsive, accessible, token-driven.
   Ships against squatch-c-c/design-engine-plugin rubric web.json.
   Rule references appear inline as bracketed [rule 1.1] comments.
   ------------------------------------------------------------- */

/* -- Reset (minimal, accessible) ----------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body, h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd, ol, ul {
  margin: 0;
}
ol[role="list"], ul[role="list"] { list-style: none; padding: 0; }
img, picture, svg, video { max-width: 100%; height: auto; display: block; } /* [rule 2.6] */
svg { fill: currentColor; }

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

/* -- Base typography ---------------------------------------- */
html {
  font-family: var(--font-serif);
  font-size: 100%;                     /* respect user root */
  color: var(--ink-strong);
  background: var(--surface-paper);
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body {
  font-family: var(--font-serif);      /* Lora -- body */
  font-size: var(--step-body);         /* >=16px [rule 1.3] */
  line-height: var(--leading-body);    /* 1.6 [rule 1.2] */
  letter-spacing: var(--track-body);
  color: var(--ink-strong);
  background: var(--surface-paper);
  min-height: 100vh;
  overflow-x: hidden;
  hyphens: manual;
}

/* Prose defaults -- measure governed [rule 1.1 / 2.4] */
p { max-width: var(--measure-body); }
p + p { margin-top: 1em; }

/* Headings -- Inter, tight leading */
h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-sans);
  font-weight: 700;
  line-height: var(--leading-heading); /* 1.15 [rule 1.2] */
  letter-spacing: -0.01em;
  color: var(--ink-strong);
  text-wrap: balance;
  margin-top: 0;
}
h1 { font-size: var(--step-h1); line-height: var(--leading-tight); letter-spacing: -0.02em; }
h2 { font-size: var(--step-h2); }
h3 { font-size: var(--step-h3); }
h4 { font-size: var(--step-h4); font-weight: 600; }
h5 { font-size: var(--step-h5); font-weight: 600; }
h6 { font-size: var(--step-h6); font-weight: 600; text-transform: uppercase; letter-spacing: var(--track-caps); }

/* Editorial serif for display heading option */
.h-display {
  font-family: var(--font-serif);
  font-weight: 500;
  font-style: normal;
  letter-spacing: -0.015em;
}

/* Anchor styling */
a {
  color: var(--ink-strong);
  text-decoration: underline;
  text-decoration-color: var(--rule-strong);
  text-underline-offset: 0.18em;
  text-decoration-thickness: 0.08em;
  transition: color var(--dur-fast) var(--ease-out),
              text-decoration-color var(--dur-fast) var(--ease-out);
}
a:hover, a:focus-visible { color: var(--color-dark); text-decoration-color: var(--color-accent); }
a:focus-visible {
  outline: var(--focus-ring);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* Small caps utility (Lora supports OpenType small caps) */
.smallcaps {
  font-variant-caps: all-small-caps;
  letter-spacing: var(--track-caps);
  font-family: var(--font-sans);
  font-weight: 600;
}

/* -- Layout primitives ------------------------------------- */
.wrap {
  width: 100%;
  max-width: var(--content-max);
  margin-inline: auto;
  padding-inline: var(--page-gutter);
}

.prose { max-width: var(--measure-body); }
.prose-narrow { max-width: var(--measure-narrow); }

.stack > * + * { margin-top: var(--stack, var(--space-s)); }
.stack-s > * + * { margin-top: var(--space-s); }
.stack-m > * + * { margin-top: var(--space-m); }
.stack-l > * + * { margin-top: var(--space-l); }

/* Skip link -- WCAG landmark navigation */
.skip-link {
  position: absolute; left: -9999px;
  background: var(--color-dark); color: var(--surface-paper);
  padding: var(--space-2xs) var(--space-s);
  border-radius: var(--radius-sm);
  z-index: 100;
  font-family: var(--font-sans);
}
.skip-link:focus {
  left: 1rem; top: 1rem;
  outline: var(--focus-ring);
}

/* -- Site header / nav ------------------------------------- */
.site-header {
  position: relative;
  z-index: 40;   /* lift the header (and its absolute mobile nav) above the
                    isolated .hero stacking context so the dropdown paints on top */
  padding-block: var(--space-s);
  border-bottom: var(--border-thin) solid var(--rule);
  background: color-mix(in oklab, var(--surface-paper) 90%, transparent);
  backdrop-filter: blur(6px);
}

.header-row {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--space-xs) var(--space-m);
  min-height: 3rem;
}

.wordmark {
  display: inline-flex; align-items: baseline;
  text-decoration: none;
  color: var(--ink-strong);
}
.wordmark:focus-visible { outline-offset: 4px; }
.wordmark-name {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: clamp(1.25rem, 1rem + 1.25vw, 2.5rem);     /* Lora 500 - 2x ratio [rule 1.7] */
  line-height: 1;
  letter-spacing: var(--track-mark);
  color: var(--ink-strong);
  white-space: nowrap;                                  /* the wordmark never breaks in two */
}

.primary-nav {
  display: flex; flex-wrap: wrap;
  gap: clamp(0.75rem, 0.5rem + 1vw, 2rem);
  align-items: center;
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 0.9375rem;
}
.primary-nav a {
  text-decoration: none;
  color: var(--ink-strong);
  padding: 0.5rem 0.25rem;
  min-height: 2.75rem;                    /* [rule 4.5] 44 AAA */
  display: inline-flex; align-items: center;
}
.primary-nav a:hover { color: var(--color-dark); }
.primary-nav .nav-cta {
  text-decoration: none;
  padding-inline: var(--space-s);
  background: var(--color-dark);
  color: var(--surface-paper);
  border-radius: 999px;
  border: 1px solid var(--color-dark);
}
.primary-nav .nav-cta:hover { background: var(--color-text-body); border-color: var(--color-text-body); color: var(--surface-paper); }

/* Mobile nav toggle (hamburger). Hidden on desktop; the nav is a plain
   inline row there. Below 44em the nav collapses behind this button so the
   header stops eating ~20% of the first mobile screen. */
.nav-toggle {
  display: none;
  align-items: center; justify-content: center; flex-direction: column;
  gap: 4px;
  width: 2.75rem; height: 2.75rem;          /* [rule 4.5] 44px tap target */
  padding: 0;
  background: transparent;
  border: var(--border-thin) solid var(--rule);
  border-radius: var(--radius-md);
  color: var(--ink-strong);
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out);
}
.nav-toggle:hover { border-color: var(--rule-strong); }
.nav-toggle-bar {
  display: block;
  width: 20px; height: 2px;
  background: currentColor;
  border-radius: 2px;
  transition: transform var(--dur-fast) var(--ease-out), opacity var(--dur-fast) var(--ease-out);
}
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

@media (max-width: 43.99em) {
  .nav-toggle { display: inline-flex; }
  .primary-nav {
    position: absolute;
    top: 100%; left: 0; right: 0;
    flex-direction: column;
    flex-wrap: nowrap;
    align-items: stretch;
    gap: 0;
    padding: var(--space-2xs) var(--page-gutter) var(--space-s);
    background: var(--surface-paper);
    border-bottom: var(--border-thin) solid var(--rule);
    box-shadow: var(--shadow-cover);
    transform: translateY(-8px);
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--dur-fast) var(--ease-out),
                transform var(--dur-fast) var(--ease-out),
                visibility 0s linear var(--dur-fast);
    z-index: 30;
  }
  .primary-nav[data-open="true"] {
    transform: translateY(0);
    opacity: 1;
    visibility: visible;
    transition: opacity var(--dur-fast) var(--ease-out),
                transform var(--dur-fast) var(--ease-out),
                visibility 0s linear 0s;
  }
  .primary-nav a {
    padding-block: var(--space-xs);
    border-bottom: var(--border-thin) solid var(--rule);
  }
  .primary-nav a:last-child { border-bottom: 0; }
  .primary-nav .nav-cta {
    margin-top: var(--space-2xs);
    justify-content: center;
  }
}

/* -- Buttons ----------------------------------------------- */
.btn {
  --btn-bg: var(--color-dark);
  --btn-fg: var(--surface-paper);
  --btn-border: var(--color-dark);
  display: inline-flex; align-items: center; justify-content: center;
  gap: 0.5rem;
  min-height: 2.75rem;                    /* [rule 4.5] 44px AAA */
  padding: 0.75rem clamp(1rem, 0.75rem + 0.6vw, 1.5rem);
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 0.9375rem;
  letter-spacing: 0.005em;
  color: var(--btn-fg);
  background: var(--btn-bg);
  border: 1px solid var(--btn-border);
  border-radius: 999px;
  text-decoration: none;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease-out),
              background var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}
.btn:hover  { transform: translateY(-1px); box-shadow: var(--shadow-cover); }
.btn:active { transform: translateY(0);    box-shadow: var(--shadow-flat); }
.btn:focus-visible {
  outline: var(--focus-ring);
  outline-offset: 2px;
  text-decoration: none;
}

.btn-secondary {
  --btn-bg: transparent;
  --btn-fg: var(--ink-strong);
  --btn-border: var(--color-dark);
}
.btn-secondary:hover { --btn-bg: var(--surface-adobe); }

.btn-ghost {
  --btn-bg: transparent;
  --btn-fg: var(--ink-strong);
  --btn-border: transparent;
  text-decoration: underline;
  text-underline-offset: 0.2em;
  min-height: 2.5rem;
  padding-inline: 0.5rem;
}
.btn-ghost:hover { text-decoration-color: var(--color-accent); }

/* -- Hero ------------------------------------------------- */
.hero {
  position: relative;
  isolation: isolate;
  min-height: min(90vh, 860px);
  display: flex;
  align-items: flex-end;                 /* content settles into the lower-left */
  overflow: hidden;
  background: var(--scan-void);           /* warm-black hold while the image loads */
}

/* Full-bleed real photograph behind the type. */
.hero-media { position: absolute; inset: 0; z-index: -2; }
.hero-media picture { display: block; width: 100%; height: 100%; }
.hero-media img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 68% 50%;               /* hold the lone saguaro in frame as it crops */
}

/* Legibility scrim: dark at the left + base, clearing to the saguaro on the right. */
.hero::after {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background:
    linear-gradient(96deg,
      color-mix(in oklab, var(--scan-void) 82%, transparent) 0%,
      color-mix(in oklab, var(--scan-void) 50%, transparent) 34%,
      transparent 62%),
    linear-gradient(0deg,
      color-mix(in oklab, var(--scan-void) 76%, transparent) 0%,
      transparent 48%);
}

.hero-inner { width: 100%; padding-block: clamp(2.75rem, 9vh, 6.5rem); }
.hero-content { max-width: 42rem; }

.hero-eyebrow {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: color-mix(in oklab, var(--surface-paper) 84%, transparent);
  margin-bottom: var(--space-s);
}
.hero-eyebrow-dot {
  display: inline-block;
  width: 0.35em; height: 0.35em; margin-inline: 0.6em 0.4em;
  background: var(--color-accent);
  border-radius: 999px;
  vertical-align: middle;
}

.hero-title {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: clamp(2.75rem, 1.5rem + 6vw, 6rem);
  line-height: 1.02;
  letter-spacing: -0.022em;
  color: var(--surface-paper);
  text-wrap: balance;
  text-shadow: 0 1px 32px rgba(0, 0, 0, 0.35);
}
.hero-title em, .hero-title .accent {
  font-style: italic;
  color: var(--color-accent);            /* terracotta italic pops on the dark image */
  font-weight: 500;
}

.hero-lede {
  font-family: var(--font-serif);
  font-size: var(--step-lede);
  line-height: var(--leading-lede);
  color: color-mix(in oklab, var(--surface-paper) 92%, transparent);
  max-width: 40ch;
  margin-block: var(--space-m) var(--space-l);
  text-shadow: 0 1px 20px rgba(0, 0, 0, 0.3);
}

.hero-ctas {
  display: flex; flex-wrap: wrap; gap: var(--space-s) var(--space-m);
  align-items: center;
}

/* Dark-surface button treatment (mirrors .section-dark). */
.hero .btn {
  --btn-bg: var(--color-accent); --btn-fg: var(--surface-paper); --btn-border: var(--color-accent);
}
.hero .btn-secondary {
  --btn-bg: transparent; --btn-fg: var(--surface-paper); --btn-border: var(--surface-paper);
}

/* -- Then & now: headshot (now) + Marine Corps photo (then) ------------ */
.portrait-pair {
  display: grid;
  gap: var(--space-l);
  margin-bottom: var(--space-xl);
  grid-template-columns: 1fr;
  align-items: end;
}
@media (min-width: 48em) {
  .portrait-pair { grid-template-columns: minmax(0, 0.6fr) minmax(0, 1fr); }
}
.portrait { margin: 0; }
.portrait picture {
  display: block;
  border-radius: var(--radius-md);
  overflow: hidden;
  box-shadow: var(--shadow-cover);
  background: var(--surface-adobe);
}
.portrait img {
  display: block; width: 100%; height: auto;
  transition: transform var(--dur-med) var(--ease-out);
}
.portrait:hover img { transform: scale(1.03); }
.portrait--now picture { aspect-ratio: 1 / 1; }
.portrait--now img { height: 100%; object-fit: cover; }
.portrait--then img { filter: grayscale(1) contrast(1.05); }   /* keep the B&W crisp */
.portrait figcaption {
  margin-top: var(--space-xs);
  font-family: var(--font-sans);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ink-strong);
}
.portrait figcaption span { font-weight: 400; color: var(--ink-soft); }

/* -- Full-bleed desert breath (panorama divider) ----------------------- */
.desert-band {
  position: relative;
  height: clamp(15rem, 42vh, 30rem);
  overflow: hidden;
  isolation: isolate;
  background: var(--scan-void);
}
.desert-band picture { position: absolute; inset: 0; display: block; }
.desert-band img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center 58%;
}
/* Fade the top + bottom edges into the cream sections (so it reads as a breath,
   not a hard-cut rectangle) + a soft base scrim for the caption. */
.desert-band::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    linear-gradient(var(--surface-paper), transparent 20% 80%, var(--surface-paper)),
    linear-gradient(0deg, color-mix(in oklab, var(--scan-void) 32%, transparent), transparent 55%);
}
.desert-band__caption {
  position: absolute; z-index: 2; left: 0; right: 0;
  bottom: clamp(1rem, 4vh, 2.5rem);
  margin: 0; text-align: center;
  font-family: var(--font-serif); font-style: italic;
  font-size: clamp(1.1rem, 0.9rem + 1vw, 1.6rem);
  letter-spacing: 0.01em;
  color: color-mix(in oklab, var(--surface-paper) 90%, transparent);
  text-shadow: 0 1px 18px rgba(0, 0, 0, 0.45);
}

/* Composed staggered entrance. Collapses to a static hero under the global
   prefers-reduced-motion rule (animation-duration -> ~0). */
@media (prefers-reduced-motion: no-preference) {
  .hero-content > * { animation: heroRise 0.85s var(--ease-out) both; }
  .hero-eyebrow { animation-delay: 0.05s; }
  .hero-title  { animation-delay: 0.16s; }
  .hero-lede   { animation-delay: 0.30s; }
  .hero-ctas   { animation-delay: 0.44s; }
}
@keyframes heroRise {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: none; }
}

/* -- Scroll-entry reveals -----------------------------------------------
   JS-gated: enhance.js adds .js-reveal to <html> only when IntersectionObserver
   is present and motion is allowed, then flips .is-visible per element as it
   enters the viewport. Without the class (no JS / reduced motion) nothing is
   hidden, so the page is fully visible by default. */
@media (prefers-reduced-motion: no-preference) {
  /* enhance.js tags each observed block with .reveal-item, so the state pair is
     class-only (.reveal-item vs .reveal-item.is-visible) and specificity is
     unambiguous regardless of the element's own tag. */
  .js-reveal .reveal-item {
    opacity: 0;
    transform: translateY(20px);
    transition: opacity 0.7s var(--ease-out), transform 0.7s var(--ease-out);
  }
  .js-reveal .reveal-item.is-visible { opacity: 1; transform: none; }

  /* subtle stagger inside the multi-item rows */
  .js-reveal .band-grid .band-item:nth-child(2),
  .js-reveal .books-grid .book:nth-child(2),
  .js-reveal .photo-strip figure:nth-child(2) { transition-delay: 0.08s; }
  .js-reveal .band-grid .band-item:nth-child(3),
  .js-reveal .photo-strip figure:nth-child(3) { transition-delay: 0.16s; }
  .js-reveal .band-grid .band-item:nth-child(4),
  .js-reveal .photo-strip figure:nth-child(4) { transition-delay: 0.24s; }
}

/* -- Micro-interactions: composed hovers --------------------------------
   Transitions collapse to instant under the global reduced-motion rule, so
   these stay as feedback without animation for those users. */
.photo-strip img { transition: transform var(--dur-med) var(--ease-out); }
.photo-strip figure:hover img { transform: scale(1.05); }

.scan-place__map {
  transition: transform var(--dur-med) var(--ease-out),
              box-shadow var(--dur-med) var(--ease-out);
}
.scan-place__map:hover { transform: translateY(-4px); box-shadow: var(--shadow-lift); }

/* Animated nav underline (grows from the left; skips the pill CTA). */
.primary-nav a:not(.nav-cta) { position: relative; }
.primary-nav a:not(.nav-cta)::after {
  content: "";
  position: absolute; left: 0.25rem; right: 0.25rem; bottom: 0.3rem;
  height: 2px; border-radius: 2px;
  background: var(--color-accent);
  transform: scaleX(0); transform-origin: left center;
  transition: transform var(--dur-med) var(--ease-out);
}
.primary-nav a:not(.nav-cta):hover::after,
.primary-nav a:not(.nav-cta):focus-visible::after { transform: scaleX(1); }

/* Designed "forthcoming" status pill (the [data-state] hook was unstyled). */
[data-state="draft"] {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  font-family: var(--font-sans);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
  background: color-mix(in oklab, var(--surface-adobe) 60%, transparent);
  border: 1px solid var(--rule);
  border-radius: 999px;
  padding: 0.25rem 0.7rem;
}
[data-state="draft"]::before {
  content: "";
  width: 0.4em; height: 0.4em;
  border-radius: 999px;
  background: var(--color-accent);
  flex: none;
}

/* -- Section framing --------------------------------------- */
.section {
  padding-block: var(--space-xl);
  position: relative;
}
.section + .section { border-top: 1px solid var(--rule); }
.section-header {
  display: grid; gap: var(--space-m);
  grid-template-columns: 1fr;
  margin-bottom: var(--space-l);
}
@media (min-width: 44em) {
  /* Fixed kicker column: every section title starts at the same x down the
     page (auto let each label's width push its content column around).
     Baseline alignment sets the roman-numeral label on the title's first
     baseline instead of hanging it off the lede's bottom edge. */
  .section-header {
    grid-template-columns: var(--kicker-col) 1fr;
    align-items: baseline;
    gap: var(--space-l);
  }
}
.section-kicker {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-dark);
}
.section-title {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: var(--step-h2);
  line-height: 1.1;
  letter-spacing: -0.015em;
  color: var(--ink-strong);
}
.section-lede { max-width: var(--measure-body); color: var(--ink-strong); margin-top: var(--space-s); }

/* -- Books ------------------------------------------------- */
.books-grid {
  display: grid; gap: var(--space-l);
  grid-template-columns: 1fr;
}
@media (min-width: 42em) { .books-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 68em) { .books-grid { grid-template-columns: repeat(3, 1fr); } }

.book {
  display: flex; flex-direction: column;
  gap: var(--space-s);
}
.book-cover {
  position: relative;
  aspect-ratio: 3 / 4;                                  /* [rule 5.3] */
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--surface-adobe);
  box-shadow: var(--shadow-cover);
  isolation: isolate;
  transition: transform var(--dur-med) var(--ease-out),
              box-shadow var(--dur-med) var(--ease-out);
}
/* Composed hover: the cover lifts and the art eases in a touch. focus-within
   makes it a keyboard affordance too (tabbing to the "Ask about" CTA). */
.book:hover .book-cover,
.book:focus-within .book-cover {
  transform: translateY(-6px);
  box-shadow: var(--shadow-lift);
}
.book-cover img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform var(--dur-med) var(--ease-out);
}
.book:hover .book-cover img,
.book:focus-within .book-cover img { transform: scale(1.04); }
.book-cover-overlay {
  position: absolute; inset: 0;
  display: grid;
  grid-template-rows: 1fr auto;
  padding: clamp(0.75rem, 0.5rem + 1vw, 1.5rem);
  color: var(--ink-strong);
  z-index: 2;
  pointer-events: none;
}
/* Typeset title/author, LORA -- over cover (no baked text on masters) */
.book-title {
  align-self: start;
  font-family: var(--font-serif);
  font-weight: 500;
  font-style: normal;
  font-size: clamp(1rem, 0.6rem + 1.6vw, 2rem);         /* 2x [rule 1.7] - 16->32 */
  line-height: 1.1;
  letter-spacing: -0.005em;
  color: var(--ink-strong);
  text-wrap: balance;
  max-width: 12ch;
  text-shadow: 0 1px 0 var(--paper-a35);
  margin: 0;
}
.book-author {
  align-self: end; justify-self: start;
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: clamp(0.875rem, 0.7rem + 0.7vw, 1.75rem);  /* 2x [rule 1.7] - 14->28 */
  letter-spacing: 0.02em;
  color: var(--ink-strong);
  padding-block: 0.15em;
  border-top: 1px solid var(--rule-strong);
  padding-top: 0.4em;
  min-width: 8ch;
}
.book-title--placeholder { opacity: 0.75; font-style: italic; }

/* Flagship pair: two-up grid; square frontispiece masters (1:1, no crop) */
.books-grid--flagship { grid-template-columns: 1fr; }
@media (min-width: 42em) { .books-grid--flagship { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 68em) { .books-grid--flagship { grid-template-columns: repeat(2, 1fr); } }
.book-cover--frontispiece { aspect-ratio: 1 / 1; }
/* Ornate art behind the type: set the typeset overlay on a paper chip
   so the Lora title keeps AA contrast over the engraving. */
.book-cover--frontispiece .book-title,
.book-cover--frontispiece .book-author {
  justify-self: start;
  background: color-mix(in oklab, var(--surface-paper) 86%, transparent);
  padding: 0.3em 0.55em;
  border-radius: var(--radius-sm);
  text-shadow: none;
}
.book-cover--frontispiece .book-author { border-top: 0; min-width: 0; }

.book-series {
  font-family: var(--font-sans);
  font-size: 0.9375rem;
  color: var(--ink-soft);
}
.book-fulltitle {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: 1.25rem;
  line-height: 1.3;
  letter-spacing: -0.005em;
  max-width: var(--measure-narrow);
}
.book-subtitle {
  font-family: var(--font-sans);
  font-size: 0.9375rem;
  color: var(--ink-soft);
  max-width: var(--measure-narrow);
}

/* "In the works" teaser row -- real forthcoming titles, no covers */
.books-teasers { margin-top: var(--space-xl); }
.teasers-heading {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-dark);
  margin-bottom: var(--space-s);
}
.teasers-list { display: grid; }
.teasers-list li {
  display: grid;
  gap: var(--space-3xs);
  padding-block: var(--space-s);
  border-top: 1px solid var(--rule);
}
.teasers-list li:last-child { border-bottom: 1px solid var(--rule); }
@media (min-width: 54em) {
  .teasers-list li {
    grid-template-columns: minmax(18ch, 0.8fr) 1.4fr auto;
    gap: var(--space-m);
    align-items: baseline;
  }
}
.teaser-title {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: 1.125rem;
}
.teaser-sub { color: var(--ink-soft); max-width: var(--measure-narrow); }
.teaser-status {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 0.9375rem;
  color: var(--ink-soft);
  white-space: nowrap;
}

.book-meta {
  display: flex; flex-wrap: wrap; justify-content: space-between;
  gap: var(--space-xs) var(--space-s);
  align-items: baseline;
  font-family: var(--font-sans);
  font-size: 0.9375rem;
  color: var(--ink-strong);
}
.book-name {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: 1.125rem;
  color: var(--ink-strong);
}
.book-price {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 0.9375rem;
  color: var(--ink-soft);
}
/* Price-pending state announced via the semantic .visually-hidden span in
   the markup; no generated ::after content (avoids screen-reader
   double-announcement). */
.book-cta { align-self: flex-start; }
/* Sales not open yet: a quiet "Coming soon" pill replaces the buy CTA. */
.book-cta--soon { margin: 0; align-self: flex-start; }
.book-cta--soon .pill {
  display: inline-block;
  padding: 0.3em 0.85em;
  border: 1px solid var(--color-hairline, rgba(138,75,47,0.3));
  border-radius: 999px;
  font-size: 0.8rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-ink, #8A4B2F);
  background: transparent;
}

/* -- Build-with-me (dark section) --------------------------- */
.section-dark {
  background: var(--color-dark);
  color: var(--ink-invert);
  isolation: isolate;
  position: relative;
}
.section-dark::before {
  content: "";
  position: absolute; inset: 0;
  background:
    radial-gradient(
      ellipse at 90% 0%,
      var(--sunset-a35) 0%,
      transparent 60%
    );
  pointer-events: none;
  z-index: -1;
}
/* Unique banding for the "build" section: a faint hypervector flow field
   (generated SVG) — a geometry-first texture that echoes the HDC/FRT runtime
   and the topo map's contours. Sits behind the content, masked to fade at the
   edges so it reads as texture rather than a hard rectangle. */
.section-dark::after {
  content: "";
  position: absolute; inset: 0;
  background: url("/assets/img/vector-field.svg") center / cover no-repeat;
  pointer-events: none;
  z-index: -1;
  -webkit-mask-image: radial-gradient(115% 115% at 58% 42%, #000 50%, transparent 100%);
  mask-image: radial-gradient(115% 115% at 58% 42%, #000 50%, transparent 100%);
}

/* -- Capabilities ticker: terminal-style "built with" marquee ---------- */
.capstrip {
  display: flex; align-items: center;
  background: var(--scan-void);
  color: color-mix(in oklab, var(--color-support) 72%, var(--surface-paper));
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  font-size: 0.8rem; letter-spacing: 0.03em;
  padding-block: 0.85rem;
  border-block: 1px solid color-mix(in oklab, var(--color-accent) 28%, transparent);
  overflow: hidden;
}
.capstrip__label {
  flex: none;
  padding-inline: clamp(1rem, 4vw, 3rem) 1.2rem;
  text-transform: uppercase; letter-spacing: 0.2em;
  font-size: 0.66rem;
  color: color-mix(in oklab, var(--color-accent) 82%, var(--surface-paper));
}
.capstrip__viewport {
  flex: 1 1 auto; overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 4%, #000 94%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 4%, #000 94%, transparent);
}
.capstrip__track { display: flex; width: max-content; animation: capscroll 48s linear infinite; }
.capstrip__seq { white-space: nowrap; }
.capstrip__seq b { color: var(--surface-paper); font-weight: 700; }
.capstrip:hover .capstrip__track { animation-play-state: paused; }
@keyframes capscroll { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
  .capstrip__track { animation: none; }
  .capstrip__viewport { -webkit-mask-image: none; mask-image: none; }
}
/* Sage on the terracotta dark section only hit 2.2:1 (WCAG AA fail for small
   text). Lift it to a sage-tinted cream so the accent survives at >=4.5:1. */
.section-dark .section-kicker { color: color-mix(in oklab, var(--surface-paper) 78%, var(--color-support)); }
.section-dark .section-title,
.section-dark h2, .section-dark h3, .section-dark p { color: var(--ink-invert); }
.section-dark .section-lede { color: color-mix(in oklab, var(--ink-invert) 92%, transparent); }
/* The HDC vector field behind this section adds faint figure-ground vibration;
   lift the text a hair so it pops. Warm near-black (not pure black), small +
   soft -- just enough to separate, not enough to read as a shadow. */
.section-dark .section-title,
.section-dark h2, .section-dark h3, .section-dark h4, .section-dark p,
.section-dark .section-kicker,
.section-dark .build-steps li::before {
  text-shadow: 0 1px 2px color-mix(in oklab, var(--scan-void) 60%, transparent);
}
.section-dark a { color: var(--ink-invert); text-decoration-color: var(--paper-a50); }
.section-dark a:hover { color: var(--surface-paper); text-decoration-color: var(--color-accent); }
.section-dark .btn { --btn-bg: var(--color-accent); --btn-fg: var(--surface-paper); --btn-border: var(--color-accent); }
.section-dark .btn:hover { --btn-bg: var(--sunset-hover); --btn-border: var(--sunset-hover); }
.section-dark .btn-secondary {
  --btn-bg: transparent; --btn-fg: var(--surface-paper); --btn-border: var(--surface-paper);
}
.section-dark .btn-secondary:hover { --btn-bg: var(--paper-a08); }

.build-grid {
  display: grid; gap: var(--space-l);
  grid-template-columns: 1fr;
}
@media (min-width: 58em) {
  .build-grid { grid-template-columns: 1.2fr 1fr; gap: var(--space-xl); align-items: center; }
}

.build-steps {
  display: grid; gap: var(--space-m);
  padding: 0; margin: 0; list-style: none;
  counter-reset: build;
}
.build-steps li {
  counter-increment: build;
  display: grid; grid-template-columns: auto 1fr; gap: var(--space-s);
  align-items: baseline;
  padding-block: var(--space-s);
  border-top: 1px solid var(--paper-a22);
}
.build-steps li:last-child { border-bottom: 1px solid var(--paper-a22); }
.build-steps li::before {
  content: "0" counter(build);
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  /* Same sage-on-terracotta contrast fix as the dark-section kicker (was 2.2:1). */
  color: color-mix(in oklab, var(--surface-paper) 78%, var(--color-support));
}
.build-steps p { color: var(--ink-invert); }

/* -- About / Writing preview ------------------------------- */
.split {
  display: grid; gap: var(--space-l);
  grid-template-columns: 1fr;
  align-items: start;
}
@media (min-width: 54em) {
  .split { grid-template-columns: 1fr 1fr; gap: var(--space-xl); }
}

.card {
  padding: var(--space-l);
  background: var(--surface-adobe);
  border: 1px solid var(--rule);
  border-radius: var(--radius-md);
}

/* -- Personality band ("the short version") ----------------- */
.band-grid {
  display: grid;
  gap: var(--space-l);
  grid-template-columns: 1fr;
}
@media (min-width: 42em) { .band-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 68em) { .band-grid { grid-template-columns: repeat(4, 1fr); gap: var(--space-m); } }

.band-item {
  border-top: var(--border-thick) solid var(--rule-strong);
  padding-top: var(--space-s);
}
.band-kicker {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-dark);
  margin-bottom: var(--space-2xs);
}
.band-title {
  font-size: var(--step-h4);
  margin-bottom: var(--space-xs);
}

.band-quote {
  margin-top: var(--space-xl);
  display: grid;
  gap: var(--space-m);
  grid-template-columns: 1fr;
  align-items: start;
}
@media (min-width: 54em) {
  .band-quote { grid-template-columns: auto 1fr; gap: var(--space-xl); }
}
.band-quote blockquote p {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 500;
  font-size: var(--step-h3);
  line-height: var(--leading-heading);
  color: var(--color-dark);
}
.band-quote cite {
  display: block;
  margin-top: var(--space-xs);
  font-family: var(--font-sans);
  font-style: normal;
  font-size: var(--step-meta);
  color: var(--ink-soft);
}
.band-aside { color: var(--ink-soft); max-width: var(--measure-narrow); }

/* -- Scan gallery switcher (Tucson / Sedona / Wilson's Creek) --------- */
.scan-gallery { display: grid; gap: var(--space-m); }

.scan-switcher {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
  border-bottom: 1px solid var(--rule);
  padding-bottom: var(--space-2xs);
}
.scan-switcher__tab {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.15em;
  padding: 0.55rem 0.9rem 0.45rem;
  font-family: var(--font-sans);
  color: var(--ink-strong);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
.scan-switcher__tab:hover {
  background: var(--surface-adobe);
}
.scan-switcher__tab[aria-selected="true"] {
  background: var(--color-dark);
  border-color: var(--color-dark);
  color: var(--ink-invert);
}
.scan-switcher__tab:focus-visible {
  outline: var(--focus-ring);
  outline-offset: 2px;
}
.scan-switcher__place {
  font-weight: 700;
  font-size: 0.9375rem;
  letter-spacing: 0.01em;
}
.scan-switcher__where {
  font-size: 0.75rem;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-soft);
}
.scan-switcher__tab[aria-selected="true"] .scan-switcher__where {
  color: color-mix(in oklab, var(--ink-invert) 78%, transparent);
}

.scan-captions { margin-top: var(--space-s); }
.scan-caption { margin: 0; max-width: var(--measure-body); }
.scan-caption figcaption { display: grid; gap: var(--space-2xs); }
.scan-caption__place {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-dark);
}
.scan-caption__body {
  font-family: var(--font-serif);
  color: var(--ink-strong);
}

/* -- Saguaro Splat (scan stage) ------------------------------ */
.scan-stage { display: grid; gap: var(--space-s); }

.scan-viewport {
  position: relative;
  aspect-ratio: 16 / 10;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--scan-void);
  box-shadow: var(--shadow-cover);
  isolation: isolate;
  touch-action: none;          /* pointer-drag orbit on touch devices */
}
.scan-viewport canvas {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  display: block;
}
.scan-poster {
  position: absolute; inset: 0;
  display: block;
  z-index: 2;
  margin: 0;
  pointer-events: none;
  transition: opacity 480ms var(--ease-out);
}
.scan-poster img { width: 100%; height: 100%; object-fit: cover; }
.scan-viewport.scan-ready .scan-poster { opacity: 0; }

.scan-loading {
  position: absolute;
  z-index: 3;
  left: 50%; bottom: var(--space-s);
  transform: translateX(-50%);
  font-family: var(--font-sans);
  font-size: var(--step-meta);
  color: var(--ink-invert);
  background: var(--scan-scrim);
  padding: 0.3rem 0.9rem;
  border-radius: 999px;
  opacity: 0;
  transition: opacity var(--dur-med) var(--ease-out);
}
.scan-viewport.live:not(.scan-ready):not(.scan-error) .scan-loading { opacity: 1; }

.scan-preset-ghost {
  position: absolute;
  z-index: 3;
  top: var(--space-s); left: var(--space-s);
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--ink-invert);
  background: var(--scan-scrim);
  padding: 0.25rem 0.7rem;
  border-radius: 999px;
  opacity: 0;
  transition: opacity var(--dur-med) var(--ease-out);
}
.scan-preset-ghost.visible { opacity: 1; }

.scan-controls {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-s);
}
.scan-presets { display: flex; flex-wrap: wrap; gap: var(--space-2xs); }
.scan-presets[hidden] { display: none; }
.scan-presets button {
  min-height: 2.25rem;
  padding: 0.25rem 0.9rem;
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-strong);
  background: transparent;
  border: 1px solid var(--rule-strong);
  border-radius: 999px;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.scan-presets button[aria-pressed="true"] {
  background: var(--color-dark);
  border-color: var(--color-dark);
  color: var(--ink-invert);
}
.scan-presets button:focus-visible {
  outline: var(--focus-ring);
  outline-offset: 2px;
}
/* "View full resolution" control -- offers the full-fidelity master splat on
   demand (Tucson ships a light preview cut first; the master upgrades lazily,
   and this lets a reader force it even on saveData / a throttled connection). */
.scan-quality { display: flex; align-items: center; gap: var(--space-2xs); }
.scan-quality[hidden] { display: none; }
.scan-quality__btn {
  min-height: 2.25rem;
  padding: 0.25rem 0.9rem;
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-invert);
  background: var(--color-dark);
  border: 1px solid var(--color-dark);
  border-radius: 999px;
  cursor: pointer;
  transition: opacity var(--dur-fast) var(--ease-out);
}
.scan-quality__btn[hidden] { display: none; }
.scan-quality__btn:disabled { opacity: 0.6; cursor: progress; }
.scan-quality__btn:focus-visible { outline: var(--focus-ring); outline-offset: 2px; }
.scan-quality__state {
  font-family: var(--font-sans);
  font-size: var(--step-meta);
  letter-spacing: 0.02em;
  color: var(--ink-soft);
}
.scan-note {
  font-family: var(--font-sans);
  font-size: var(--step-meta);
  color: var(--ink-soft);
  max-width: var(--measure-narrow);
}

/* -- Photo strip (real Tucson photographs) ------------------- */
.strip-heading {
  font-size: var(--step-h4);
  margin-top: var(--space-xl);
  margin-bottom: var(--space-m);
}
.photo-strip {
  display: grid;
  gap: var(--space-s);
  grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 54em) { .photo-strip { grid-template-columns: repeat(3, 1fr); } }
.photo-strip figure {
  margin: 0;
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--surface-adobe);
  box-shadow: var(--shadow-flat);
}
.photo-strip picture { display: block; width: 100%; height: 100%; }
.photo-strip img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo-strip .strip-tall { grid-row: span 2; aspect-ratio: auto; }
.photo-strip .strip-wide { grid-column: span 2; aspect-ratio: auto; }

/* -- Where it stands: real topographic map of the scan location -------- */
.scan-place {
  margin-top: var(--space-xl);
  display: grid;
  gap: var(--space-l);
  align-items: center;
}
@media (min-width: 54em) {
  .scan-place {
    grid-template-columns: minmax(0, 1.08fr) minmax(0, 0.92fr);
    gap: var(--space-xl);
  }
}
.scan-place__map {
  margin: 0;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-cover);
  background: var(--surface-adobe);
}
.scan-place__map img { display: block; width: 100%; height: auto; }
.scan-place__note { max-width: var(--measure-body); }
.scan-place__coord {
  margin-top: var(--space-m);
  font-family: var(--font-sans);
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  color: color-mix(in oklab, var(--ink-strong) 62%, transparent);
}

/* -- Footer ----------------------------------------------- */
.site-footer {
  padding-block: var(--space-xl) var(--space-l);
  border-top: 1px solid var(--rule);
  color: var(--ink-strong);
  background: var(--surface-paper);
}
.footer-grid {
  display: grid; gap: var(--space-l);
  grid-template-columns: 1fr;
}
@media (min-width: 50em) { .footer-grid { grid-template-columns: 2fr 1fr 1fr; } }

.footer-word {
  font-family: var(--font-serif); font-weight: 500;
  font-size: 1.5rem;
}
.footer-heading {
  font-family: var(--font-sans); font-weight: 600;
  font-size: 0.8125rem; text-transform: uppercase;
  letter-spacing: var(--track-caps);
  color: var(--color-dark);
  margin-bottom: var(--space-s);
}
.footer-links { list-style: none; padding: 0; margin: 0; display: grid; gap: 0.5rem; }
.footer-links a { text-decoration: none; }
.footer-links a:hover { text-decoration: underline; text-decoration-color: var(--color-accent); }
.footer-fine {
  margin-top: var(--space-l);
  font-family: var(--font-sans); font-size: 0.8125rem;
  color: var(--ink-soft);
  display: flex; justify-content: space-between; flex-wrap: wrap; gap: var(--space-s);
  padding-top: var(--space-m);
  border-top: 1px solid var(--rule);
}

/* -- Newsletter form --------------------------------------- */
.newsletter { display: grid; gap: var(--space-s); }
.newsletter-row { display: grid; gap: 0.5rem; }
.newsletter label {
  font-family: var(--font-sans); font-weight: 600;
  font-size: 0.8125rem; letter-spacing: var(--track-caps);
  text-transform: uppercase; color: var(--color-dark);
}
.newsletter input[type="email"] {
  padding: 0.75rem 1rem;
  min-height: 2.75rem;                       /* [rule 4.5] */
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius-md);
  background: var(--surface-paper);
  font-family: var(--font-sans);
  font-size: 1rem;
  color: var(--ink-strong);
}
.newsletter input[type="email"]:focus-visible {
  outline: var(--focus-ring);
  outline-offset: 1px;
  border-color: var(--color-dark);
}
.newsletter .btn { align-self: start; }

/* -- Small utility: visually hidden but screen-reader available -- */
.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;
}

/* -- Print (light polish) ---------------------------------- */
@media print {
  .site-header, .site-footer, .hero-ctas, .btn { display: none !important; }
  body { background: white; color: black; }
  a { text-decoration: none; color: black; }
  /* Scroll-reveal blocks are opacity:0 until IntersectionObserver fires; print
     never scrolls, so force them visible or the printout loses whole sections. */
  .js-reveal .reveal-item { opacity: 1 !important; transform: none !important; }
}

/* -- Cookie consent (GDPR / ePrivacy) - PQ-24 UI ----------- */
/* Canonical logic contract: squatch-pinoccio/compliance/consent (key __scc_v1). */
/* Trauma-informed: Reject as prominent as Accept; nothing pre-ticked beyond */
/* strictly-necessary; no re-nag after a choice. Own desert palette. */
/* Bottom-RIGHT corner card, not a centred one. These layouts are left-aligned
   with empty space on the right, so this covers nothing. At 40rem centred this sat squarely on top
   of the primary CTA on every page. Same consent, out of the way. */
.consent {
  position: fixed;
  z-index: 60;
  left: auto;
  right: clamp(0.75rem, 2vw, 1.5rem);
  bottom: clamp(0.75rem, 2vw, 1.5rem);
  transform: none;
  width: min(24rem, calc(100vw - 2rem));
  background: var(--surface-paper);
  color: var(--ink-strong);
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-cover);
  padding: clamp(1.1rem, 1rem + 0.6vw, 1.5rem);
  font-family: var(--font-serif);
}
.consent[hidden] { display: none; }
.consent__title {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 1.05rem;
  margin: 0 0 0.4rem;
  color: var(--color-dark);
}
.consent__text {
  font-size: 0.95rem;
  line-height: 1.55;
  margin: 0 0 1rem;
  color: var(--ink-soft);
  max-width: 60ch;
}
.consent__text a { color: var(--color-accent); }
.consent__actions { display: flex; flex-wrap: wrap; gap: 0.65rem; }
.consent__actions .btn { flex: 1 1 auto; }
.consent__prefs-toggle {
  background: transparent;
  border: none;
  color: var(--color-accent);
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 0.9rem;
  cursor: pointer;
  padding: 0.5rem 0.25rem;
  text-decoration: underline;
  text-underline-offset: 3px;
  flex: 1 1 100%;
  text-align: center;
}
.consent__prefs-toggle:focus-visible { outline: var(--focus-ring); outline-offset: 2px; }
.consent__panel {
  display: grid;
  gap: 1rem;
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--rule);
}
.consent__panel[hidden] { display: none; }
.consent__cat {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.25rem 1rem;
  align-items: start;
}
.consent__cat-name { font-family: var(--font-sans); font-weight: 600; font-size: 0.95rem; color: var(--ink-strong); }
.consent__cat-desc { grid-column: 1 / 2; font-size: 0.85rem; line-height: 1.5; color: var(--ink-soft); margin: 0; }
.consent__badge {
  font-family: var(--font-sans);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-accent);
  align-self: center;
}
.consent__switch {
  position: relative;
  display: inline-flex;
  align-items: center;
  width: 3rem;
  height: 1.6rem;
  flex: 0 0 auto;
  align-self: center;
}
.consent__switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.consent__track {
  width: 100%; height: 100%;
  border-radius: 999px;
  background: var(--rule-strong);
  transition: background var(--dur-fast) var(--ease-out);
}
.consent__track::after {
  content: "";
  position: absolute;
  top: 3px; left: 3px;
  width: 1rem; height: 1rem;
  border-radius: 50%;
  background: var(--surface-paper);
  box-shadow: var(--shadow-flat);
  transition: transform var(--dur-fast) var(--ease-out);
}
.consent__switch input:checked + .consent__track { background: var(--color-accent); }
.consent__switch input:checked + .consent__track::after { transform: translateX(1.4rem); }
.consent__switch input:focus-visible + .consent__track { outline: var(--focus-ring); outline-offset: 2px; }
.consent__panel-actions { display: flex; flex-wrap: wrap; gap: 0.65rem; }
.consent__panel-actions .btn { flex: 1 1 auto; }
@media (max-width: 30em) {
  .consent__actions .btn, .consent__panel-actions .btn { flex: 1 1 100%; }
}
/* Reject solid variant - equal visual weight to Accept (D1 no dark patterns) */
.consent .btn--alt { --btn-bg: var(--color-accent); --btn-fg: var(--surface-paper); --btn-border: var(--color-accent); }
.consent .btn--alt:hover { --btn-bg: var(--sunset-hover); --btn-border: var(--sunset-hover); }

/* -- Lightbox (full-res image viewer) ---------------------------------- */
/* Enhanced <picture>/<img> get a subtle affordance so users know they can
   open the full-res source. Base cursor + focus ring only -- no chrome. */
.has-lightbox { cursor: zoom-in; }
.has-lightbox:focus-visible {
  outline: var(--focus-ring);
  outline-offset: 4px;
  border-radius: var(--radius-md);
}

html.lightbox-open { overflow: hidden; }

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: color-mix(in oklab, var(--scan-void) 92%, transparent);
  backdrop-filter: blur(6px);
  display: grid;
  place-items: center;
  padding: clamp(0.75rem, 2vw, 2rem);
}
.lightbox[hidden] { display: none; }

.lightbox__close {
  position: absolute;
  top: clamp(0.75rem, 2vw, 1.25rem);
  right: clamp(0.75rem, 2vw, 1.25rem);
  min-width: 2.5rem;
  min-height: 2.5rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: color-mix(in oklab, var(--surface-paper) 92%, transparent);
  color: var(--ink-strong);
  border: 1px solid var(--rule-strong);
  border-radius: 999px;
  cursor: pointer;
  box-shadow: var(--shadow-cover);
}
.lightbox__close:hover { background: var(--surface-paper); }
.lightbox__close:focus-visible {
  outline: var(--focus-ring);
  outline-offset: 3px;
}

.lightbox__frame {
  display: grid;
  gap: var(--space-xs);
  justify-items: center;
  max-width: min(96vw, 1600px);
  max-height: 100%;
}
.lightbox__img {
  display: block;
  max-width: 96vw;
  max-height: calc(100vh - 6rem);
  width: auto;
  height: auto;
  border-radius: var(--radius-md);
  box-shadow: 0 30px 80px -20px rgba(0,0,0,0.6);
  background: var(--scan-void);
}
.lightbox__caption {
  font-family: var(--font-sans);
  font-size: 0.8125rem;
  color: color-mix(in oklab, var(--ink-invert) 84%, transparent);
  text-align: center;
  max-width: 60ch;
  margin: 0;
}

@media (prefers-reduced-motion: reduce) {
  .lightbox { backdrop-filter: none; }
}

/* -- Books gallery (library, POD flow) --------------------------------- */
.books-note {
  font-family: var(--font-sans);
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
  margin-top: var(--space-s);
  max-width: var(--measure-body);
}
.books-note strong { color: var(--color-dark); }

.books-shelf {
  margin-top: var(--space-xl);
  display: grid;
  gap: var(--space-l);
}
.books-shelf__group + .books-shelf__group { margin-top: var(--space-l); }
.books-shelf__heading {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-dark);
  margin-bottom: var(--space-s);
}
.books-shelf__sub {
  font-family: var(--font-serif);
  font-size: 1.0625rem;
  color: var(--ink-soft);
  max-width: var(--measure-body);
  margin-top: 0;
  margin-bottom: var(--space-m);
}

.library-grid {
  display: grid;
  gap: var(--space-m);
  grid-template-columns: 1fr;
}
@media (min-width: 42em) { .library-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 68em) { .library-grid { grid-template-columns: repeat(3, 1fr); } }

.library-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  padding: var(--space-m);
  background: color-mix(in oklab, var(--surface-adobe) 55%, var(--surface-paper));
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
  transition: transform var(--dur-med) var(--ease-out),
              box-shadow var(--dur-med) var(--ease-out),
              border-color var(--dur-med) var(--ease-out);
}
.library-card:hover,
.library-card:focus-within {
  transform: translateY(-3px);
  box-shadow: var(--shadow-lift);
  border-color: var(--rule-strong);
}
.library-card__kicker {
  font-family: var(--font-sans);
  font-size: 0.75rem;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  color: var(--color-accent);
}
.library-card__title {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: 1.25rem;
  line-height: 1.25;
  letter-spacing: -0.005em;
  color: var(--ink-strong);
  margin: 0;
}
.library-card__desc {
  font-family: var(--font-serif);
  color: var(--ink-strong);
  max-width: 40ch;
}
.library-card__actions {
  margin-top: auto;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
}
.library-card__actions .btn {
  flex: 0 0 auto;
  font-size: 0.8125rem;
  padding: 0.4rem 0.85rem;
}
.library-card__actions .library-buy {
  font-family: var(--font-sans);
  font-weight: 600;
}
.library-print-note {
  font-family: var(--font-sans);
  font-size: 0.75rem;
  color: var(--ink-soft);
  margin-top: 0.25rem;
}

/* -- Say-hello form (/say-hello/, formerly /lead/) ------------------------
   Warm, tactile fields with floating labels, honest inline validation, a
   composed send button, and a real success/error state with a touch of
   personality. Built entirely from the shared token set -- no new palette,
   no new easing curve, no new radius. */

.lead-form {
  gap: var(--space-m);
}

/* Floating label field: label sits inside the field at rest, lifts above it
   on focus/content. `:not(:placeholder-shown)` needs a placeholder, so every
   input/textarea ships `placeholder=" "` (invisible, just triggers the CSS). */
.field {
  position: relative;
}
.field input,
.field textarea {
  width: 100%;
  padding: 1.375rem 1rem 0.625rem;
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: 1.4;
  color: var(--ink-strong);
  background: var(--surface-paper);
  border: var(--border-thick) solid var(--rule);
  border-radius: var(--radius-md);
  transition: border-color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out),
              background var(--dur-fast) var(--ease-out);
}
.field textarea {
  padding-top: 1.5rem;
  resize: vertical;
  min-height: 6.5rem;
}
.field label {
  position: absolute;
  left: 1rem;
  top: 0.95rem;
  font-family: var(--font-sans);
  font-size: 1rem;
  color: var(--ink-soft);
  line-height: 1.4;
  pointer-events: none;
  transform-origin: left top;
  transition: transform var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              top var(--dur-fast) var(--ease-out);
}
/* Lift the label when the field has focus OR real content (placeholder=" "
   makes :placeholder-shown false the instant there's a value). */
.field input:focus + label,
.field input:not(:placeholder-shown) + label,
.field textarea:focus + label,
.field textarea:not(:placeholder-shown) + label {
  top: 0.4rem;
  transform: translateY(-0.15rem) scale(0.74);
  color: var(--color-dark);
}
.field textarea:focus + label,
.field textarea:not(:placeholder-shown) + label {
  top: 0.55rem;
}
.field input:hover,
.field textarea:hover {
  border-color: var(--rule-strong);
}
/* Brand-accent focus state: a warm ring + border, not the browser default. */
.field input:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--color-accent);
  box-shadow: 0 0 0 4px color-mix(in oklab, var(--color-accent) 22%, transparent);
  background: var(--surface-paper);
}
.field input:focus-visible,
.field textarea:focus-visible {
  outline: none; /* the box-shadow ring above already carries the affordance */
}
.field-hint {
  margin-top: 0.4rem;
  font-family: var(--font-sans);
  font-size: 0.8125rem;
  color: var(--ink-soft);
}
.field-err {
  margin-top: 0.4rem;
  min-height: 1.1em;
  font-family: var(--font-sans);
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--color-accent);
}
.field-err:empty { display: none; }
/* Honest error state: warm terracotta, never harsh red -- still reads as
   "something needs attention," on-brand. */
.field input[aria-invalid="true"],
.field textarea[aria-invalid="true"] {
  border-color: var(--color-accent);
}
.field input[aria-invalid="true"]:focus,
.field textarea[aria-invalid="true"]:focus {
  box-shadow: 0 0 0 4px color-mix(in oklab, var(--color-accent) 28%, transparent);
}
@media (prefers-reduced-motion: no-preference) {
  .field input[aria-invalid="true"],
  .field textarea[aria-invalid="true"] {
    animation: fieldShake 0.4s var(--ease-out);
  }
}
@keyframes fieldShake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-4px); }
  75% { transform: translateX(4px); }
}

/* Consent row: a real, tactile checkbox (not the bare browser default) --
   custom box + checkmark that draws in on check, built from tokens only. */
.consent-row {
  display: flex;
  align-items: flex-start;
  gap: 0.7em;
  font-family: var(--font-sans);
  font-size: 0.875rem;
  color: var(--ink-soft);
  cursor: pointer;
  line-height: 1.5;
}
.consent-row input[type="checkbox"] {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
}
.consent-box {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.35rem;
  height: 1.35rem;
  margin-top: 0.1em;
  border: var(--border-thick) solid var(--rule-strong);
  border-radius: 0.3rem;
  background: var(--surface-paper);
  color: var(--surface-paper);
  transition: background var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
.consent-check {
  width: 0.85rem;
  height: 0.85rem;
  stroke-dasharray: 20;
  stroke-dashoffset: 20;
  transition: stroke-dashoffset var(--dur-med) var(--ease-out);
}
.consent-row input[type="checkbox"]:checked + .consent-box {
  background: var(--color-accent);
  border-color: var(--color-accent);
}
.consent-row input[type="checkbox"]:checked + .consent-box .consent-check {
  stroke-dashoffset: 0;
}
.consent-row input[type="checkbox"]:focus-visible + .consent-box {
  outline: var(--focus-ring);
  outline-offset: 2px;
}
.consent-row:hover .consent-box {
  border-color: var(--color-dark);
}

.lead-form-actions { align-items: center; }

/* Send button: composed hover/active + a real sending state. The paper-plane
   glyph slides in on hover; a spinner swaps in while the request is in
   flight (own timer, not the shared .btn transition, so it can spin freely). */
.btn-send {
  position: relative;
  overflow: hidden;
  gap: 0.5rem;
}
.btn-send__icon,
.btn-send__spinner {
  width: 1.05rem;
  height: 1.05rem;
  flex: 0 0 auto;
}
.btn-send__icon {
  transform: translateX(-0.2rem);
  opacity: 0.85;
  transition: transform var(--dur-med) var(--ease-out), opacity var(--dur-med) var(--ease-out);
}
.btn-send:hover .btn-send__icon,
.btn-send:focus-visible .btn-send__icon {
  transform: translateX(0.15rem);
  opacity: 1;
}
.btn-send__spinner {
  display: none;
}
.btn-send.is-sending .btn-send__icon { display: none; }
.btn-send.is-sending .btn-send__spinner {
  display: block;
  animation: btnSpin 0.8s linear infinite;
}
.btn-send.is-sending .btn-send__label::after { content: '…'; }
@media (prefers-reduced-motion: reduce) {
  .btn-send.is-sending .btn-send__spinner { animation-duration: 0.01ms; }
}
@keyframes btnSpin { to { transform: rotate(360deg); } }

/* Result panel: a real success/error state with a little life to it, not a
   bare status line. Hidden by default; JS un-hides + fills it in. */
.lead-form-result {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: var(--space-s) var(--space-m);
  border-radius: var(--radius-md);
  border: var(--border-thick) solid var(--rule);
  background: var(--surface-adobe);
}
.lead-form-result[hidden] { display: none; }
.lead-form-result.is-ok {
  border-color: color-mix(in oklab, var(--color-support) 55%, var(--rule));
  background: color-mix(in oklab, var(--color-support) 16%, var(--surface-paper));
}
.lead-form-result.is-error {
  border-color: color-mix(in oklab, var(--color-accent) 45%, var(--rule));
  background: color-mix(in oklab, var(--color-accent) 10%, var(--surface-paper));
}
.lead-form-result__icon {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.75rem;
  height: 1.75rem;
  margin-top: 0.1em;
  border-radius: 999px;
  color: var(--surface-paper);
  background: var(--ink-soft);
}
.lead-form-result.is-ok .lead-form-result__icon { background: var(--color-support); }
.lead-form-result.is-error .lead-form-result__icon { background: var(--color-accent); }
.lead-form-result__icon svg { width: 1rem; height: 1rem; display: none; }
/* Show only the icon matching the current state -- a checkmark reads as
   dishonest UI on an error message, so each state gets its own honest glyph. */
.lead-form-result.is-ok .lead-form-result__icon--ok,
.lead-form-result.is-error .lead-form-result__icon--error { display: block; }
.lead-form-result__title {
  font-family: var(--font-sans);
  font-weight: 700;
  color: var(--ink-strong);
}
.lead-form-result__body {
  margin-top: 0.2em;
  color: var(--ink-strong);
}
@media (prefers-reduced-motion: no-preference) {
  .lead-form-result.is-animating {
    animation: resultIn 0.5s var(--ease-out);
  }
  .lead-form-result.is-animating .lead-form-result__icon {
    animation: resultPop 0.5s var(--ease-out) 0.1s both;
  }
}
@keyframes resultIn {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
@keyframes resultPop {
  0%   { transform: scale(0.4); opacity: 0; }
  60%  { transform: scale(1.15); opacity: 1; }
  100% { transform: scale(1); }
}
