/* ==========================================================================
   Ostgrove - site.css
   The single stylesheet for ostgrove.com. No frameworks, no CDNs, no JS hooks.
   Everything a page needs is in the class contract below; pages use these
   classes plus plain semantic tags and nothing else.

   Class contract implemented here:
   .wrap .nav .brand .nav-links .hero .hero-title .hero-support .hero-sub
   .band .band-cream .grid-2 .grid-4 .card .card-cover .card-title .card-meta
   .btn .btn-ghost .sadu-strip .footer .kicker .prose .small
   .skip-link .benefits .interior-figure .interior-shot
   (the last four added in the r1-critique P1 pass: a skip-to-content link,
   the home/product-page benefit-bullet list, and the full-width interior
   spread figure + its image, all cleanly extending the contract rather than
   overloading an existing class.)
   .interior-mobile-stack .interior-shot-desktop .interior-shot-mobile
   (added in the r2-critique P1 pass: the product page now shows BOTH pages
   of the example spread on mobile, stacked, instead of the right page only.
   Two real <img> elements per breakpoint - not one <img> whose <source>
   swaps by media query - is what lets the mobile crops keep their own
   correct width/height attributes, and it also means Chrome's native
   image lazy-loading simply never fetches whichever set is display:none,
   so a phone never downloads the desktop spread and a desktop never
   downloads the phone crops.)
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Fonts (self-hosted, Latin subset of Source Sans 3; see
      SourceSans3-LICENSE.txt in this folder)
   -------------------------------------------------------------------------- */

@font-face {
  font-family: "Source Sans 3";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("SourceSans3-Regular.woff2") format("woff2");
}

@font-face {
  font-family: "Source Sans 3";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("SourceSans3-Semibold.woff2") format("woff2");
}

@font-face {
  font-family: "Source Sans 3";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("SourceSans3-Bold.woff2") format("woff2");
}

/* --------------------------------------------------------------------------
   2. Design tokens
   -------------------------------------------------------------------------- */

:root {
  /* Brand colour tokens (from the Ostgrove brand guide) */
  --navy: #2c3e50;
  --navy-deep: #243342;
  --cream: #f5f1e8;
  --cream-strong: #faf8f2;
  --sadu: #8b2e2e;
  --ink: #1c1c1c;
  /* r1-appeal P1 contrast pass: darkened from #6b7280 (4.29:1 on cream, just
     under AA) to clear 4.5:1 on both cream and white with margin. */
  --gray: #5b6472;

  /* Derived surface tokens */
  --line: #e5e0d5;
  --line-strong: #d8d1c1;
  --sadu-deep: #742626;
  --white: #ffffff;

  /* Layout */
  --wrap-max: 1080px;
  --wrap-pad: 24px;
  --pad-section: 96px;
  --gap: 28px;

  /* Shape */
  --radius-btn: 8px;
  --radius-card: 12px;
  --radius-img: 8px;
  --shadow-card: 0 1px 2px rgba(28, 28, 28, 0.04);
  --shadow-card-hover: 0 12px 30px rgba(44, 62, 80, 0.15);

  /* Type scale: display 44/56, h1 36, h2 26, h3 20, body 17/1.65, small 14.
     Fluid below desktop, never above the values above. */
  --fs-display: clamp(2rem, 1.35rem + 2.7vw, 2.75rem); /* 32 -> 44 */
  --lh-display: 1.27;                                  /* 44 * 1.27 = 56 */
  --fs-h1: clamp(1.75rem, 1.35rem + 1.7vw, 2.25rem);   /* 28 -> 36 */
  --fs-h2: clamp(1.375rem, 1.2rem + 0.75vw, 1.625rem); /* 22 -> 26 */
  --fs-h3: 1.25rem;                                    /* 20 */
  --fs-body: 1.0625rem;                                /* 17 */
  --lh-body: 1.65;
  --fs-small: 0.875rem;                                /* 14 */

  --font-sans: "Source Sans 3", "Segoe UI", system-ui, -apple-system,
    "Helvetica Neue", Arial, sans-serif;

  /* Context tokens. Sections re-declare these so the same class behaves
     correctly on a light ground and on the navy ground. */
  --ctx-ink: var(--ink);
  --ctx-muted: var(--gray);
  --ctx-accent: var(--sadu);
  --ctx-link: var(--sadu);
  --ctx-outline: var(--navy);
  --ctx-rule: var(--line);
  --ctx-focus: var(--sadu);
}

/* --------------------------------------------------------------------------
   3. Base
   -------------------------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

/* Column layout so a short page (404) still pins the footer to the bottom of
   the viewport instead of leaving a bare strip of body ground beneath it. */
body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  margin: 0;
  background: var(--cream-strong);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1,
h2,
h3,
h4 {
  margin: 0 0 0.6em;
  font-weight: 700;
  color: inherit;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

h1 {
  font-size: var(--fs-h1);
  line-height: 1.2;
}

h2 {
  font-size: var(--fs-h2);
  line-height: 1.3;
}

h3 {
  font-size: var(--fs-h3);
  line-height: 1.35;
  letter-spacing: 0;
}

h4 {
  font-size: var(--fs-body);
  line-height: 1.4;
  letter-spacing: 0;
}

p {
  margin: 0 0 1em;
}

p:last-child {
  margin-bottom: 0;
}

a {
  color: var(--ctx-link);
  text-decoration: none;
  text-underline-offset: 0.18em;
  transition: color 0.15s ease, opacity 0.15s ease;
}

a:hover {
  text-decoration: underline;
}

ul,
ol {
  margin: 0 0 1em;
  padding-left: 1.25em;
}

li {
  margin-bottom: 0.4em;
}

img,
svg {
  max-width: 100%;
  height: auto;
}

/* main takes the slack in the body column; header and footer keep their size. */
body > main {
  flex: 1 0 auto;
}

body > .nav,
body > .footer {
  flex: none;
}

strong,
b {
  font-weight: 600;
}

hr {
  height: 1px;
  margin: 2.5rem 0;
  border: 0;
  background: var(--ctx-rule);
}

:focus-visible {
  outline: 2px solid var(--ctx-focus);
  outline-offset: 3px;
  border-radius: 3px;
}

::selection {
  background: rgba(139, 46, 46, 0.16);
}

/* --------------------------------------------------------------------------
   3b. .skip-link - visually hidden until keyboard focus, jumps to <main id="content">
   -------------------------------------------------------------------------- */

.skip-link {
  position: absolute;
  top: -60px;
  left: 12px;
  z-index: 1000;
  padding: 12px 20px;
  background: var(--sadu);
  color: var(--cream);
  font-weight: 600;
  font-size: 0.9375rem;
  border-radius: var(--radius-btn);
  transition: top 0.15s ease;
}

.skip-link:focus {
  top: 12px;
  outline: 2px solid var(--cream);
  outline-offset: 3px;
}

/* --------------------------------------------------------------------------
   4. .wrap - the max-width container
   -------------------------------------------------------------------------- */

.wrap {
  width: 100%;
  max-width: var(--wrap-max);
  margin-inline: auto;
  padding-inline: var(--wrap-pad);
}

/* --------------------------------------------------------------------------
   5. .nav / .brand / .nav-links - the shared header (navy ground)
   -------------------------------------------------------------------------- */

.nav {
  --ctx-ink: var(--cream);
  --ctx-muted: rgba(245, 241, 232, 0.72);
  --ctx-link: var(--cream);
  --ctx-outline: var(--cream);
  --ctx-rule: rgba(245, 241, 232, 0.16);
  --ctx-focus: var(--cream);
  background: var(--navy);
  color: var(--ctx-ink);
  border-bottom: 1px solid rgba(245, 241, 232, 0.14);
}

.nav > .wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px 24px;
  min-height: 68px;
  padding-block: 14px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--cream);
  font-size: 0.9375rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
}

.brand:hover {
  color: var(--white);
  text-decoration: none;
}

/* The shipped K1 files are navy, which would vanish on the navy nav. The brand
   guide allows a flat cream or white mono mark on a dark ground, so the mark is
   flipped to flat white here in CSS. The SVG file itself is never edited. */
.brand img,
.brand svg {
  display: block;
  width: 28px;
  height: 28px;
  flex: none;
  filter: brightness(0) invert(1);
}

.nav-links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 26px;
}

.nav-links a {
  color: rgba(245, 241, 232, 0.86);
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  /* 10px top/bottom on a 26.4px line box (1rem * the body 1.65 line-height)
     clears the 44px minimum touch target from the r1 critique's a11y note. */
  padding-block: 10px;
  border-bottom: 2px solid transparent;
}

.nav-links a:hover,
.nav-links a:focus-visible {
  color: var(--cream);
  border-bottom-color: rgba(245, 241, 232, 0.55);
  text-decoration: none;
}

.nav-links a[aria-current="page"] {
  color: var(--cream);
  border-bottom-color: var(--cream);
}

/* --------------------------------------------------------------------------
   6. .band / .band-cream - full-width sections
      .band is the navy ground and carries the section padding.
      Pages combine them: class="band band-cream" flips the ground to cream.
   -------------------------------------------------------------------------- */

.band,
.band-cream {
  padding-block: var(--pad-section);
}

.band {
  --ctx-ink: var(--cream);
  --ctx-muted: rgba(245, 241, 232, 0.78);
  --ctx-accent: var(--cream);
  --ctx-link: var(--cream);
  --ctx-outline: var(--cream);
  --ctx-rule: rgba(245, 241, 232, 0.2);
  --ctx-focus: var(--cream);
  background: var(--navy);
  color: var(--ctx-ink);
}

.band-cream {
  --ctx-ink: var(--ink);
  --ctx-muted: var(--gray);
  --ctx-accent: var(--sadu);
  --ctx-link: var(--sadu);
  --ctx-outline: var(--navy);
  --ctx-rule: var(--line);
  --ctx-focus: var(--sadu);
  background: var(--cream);
  color: var(--ctx-ink);
}

.band h2,
.band-cream h2 {
  color: var(--ctx-ink);
}

.band > .wrap > h2:first-child,
.band-cream > .wrap > h2:first-child {
  margin-top: 0;
}

.band a:not(.btn):not(.btn-ghost) {
  color: var(--ctx-link);
  text-decoration: underline;
  text-decoration-color: rgba(245, 241, 232, 0.45);
}

.band-cream a:not(.btn):not(.btn-ghost) {
  color: var(--ctx-link);
}

/* --------------------------------------------------------------------------
   7. .hero - sits inside a band (class="band hero"), so it sets no ground and
      no section padding of its own. Type and rhythm only.
   -------------------------------------------------------------------------- */

.hero {
  text-align: center;
}

/* The full K1 (ring + Sadu diamond) standing over the hero on its navy ground.
   Flat mono reversed treatment via the same filter idiom as the nav mark: the
   two-colour mark must never show sadu red reversed on a dark ground, per the
   same brand rule that flattens the sadu-strip in section 12. The SVG file
   itself is never edited. */
.hero img {
  display: block;
  width: 120px;
  height: 120px;
  margin: 0 auto 32px;
  filter: brightness(0) invert(1);
}

.hero .kicker {
  margin-bottom: 20px;
}

.hero-title {
  margin: 0 0 18px;
  font-size: var(--fs-display);
  line-height: var(--lh-display);
  font-weight: 700;
  letter-spacing: -0.015em;
  color: var(--ctx-ink);
  text-wrap: balance;
}

/* .hero-support - a short, bright product line directly under an .hero-title
   that names a specific book. Sits between the title and the muted brand
   .hero-sub sentence; full ctx-ink weight so it reads as the main promise,
   not a footnote. */
.hero-support {
  max-width: 56ch;
  margin: 0 auto 18px;
  font-size: 1.1875rem; /* 19 */
  line-height: 1.5;
  font-weight: 600;
  color: var(--ctx-ink);
  text-wrap: pretty;
}

.hero-sub {
  max-width: 60ch;
  margin: 0 auto 34px;
  font-size: 1.1875rem; /* 19 */
  line-height: 1.6;
  color: var(--ctx-muted);
  text-wrap: pretty;
}

.hero .btn,
.hero .btn-ghost {
  margin-top: 4px;
}

/* --------------------------------------------------------------------------
   8. .kicker - small caps sadu label
   -------------------------------------------------------------------------- */

.kicker {
  display: block;
  margin: 0 0 14px;
  font-size: 0.8125rem; /* 13 */
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--ctx-accent);
}

/* A kicker is a label for the heading right under it, so kill that gap. */
.kicker + h1,
.kicker + h2,
.kicker + h3,
.kicker + .hero-title,
.kicker + .card-title {
  margin-top: 0;
}

/* --------------------------------------------------------------------------
   9. Grids. auto-fit so a .grid-4 holding three cards lands as a clean 3-up.
   -------------------------------------------------------------------------- */

.grid-2,
.grid-4 {
  display: grid;
  gap: var(--gap);
  align-items: stretch; /* cards in a row end level */
}

.grid-2 {
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}

.grid-4 {
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}

/* --------------------------------------------------------------------------
   10. .card and its parts
   -------------------------------------------------------------------------- */

.card {
  --ctx-ink: var(--ink);
  --ctx-muted: var(--gray);
  --ctx-accent: var(--sadu);
  --ctx-link: var(--sadu);
  --ctx-outline: var(--navy);
  --ctx-rule: var(--line);
  --ctx-focus: var(--sadu);
  display: flex;
  flex-direction: column;
  gap: 12px;
  height: 100%;
  padding: 24px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  color: var(--ink);
  transition: box-shadow 0.18s ease, transform 0.18s ease,
    border-color 0.18s ease;
}

.card:hover,
.card:focus-within {
  border-color: var(--line-strong);
  box-shadow: var(--shadow-card-hover);
  transform: translateY(-2px);
}

.card > :last-child {
  margin-bottom: 0;
}

.card p {
  margin: 0;
}

.card .btn,
.card .btn-ghost {
  align-self: flex-start;
  margin-top: auto;
}

.card .kicker {
  margin: 0;
}

.card-cover {
  display: block;
  width: 100%;
  max-width: 340px;
  aspect-ratio: 640 / 828;
  margin: 0 0 4px;
  object-fit: cover;
  background: var(--cream-strong);
  border: 1px solid var(--line);
  border-radius: var(--radius-img);
}

/* A cover shown straight on the navy band needs lifting off the ground.
   Covers inside a white .card keep the plain treatment (second rule wins on
   specificity: five classes against four). */
.band:not(.band-cream) > .wrap .card-cover {
  border-color: rgba(245, 241, 232, 0.32);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.28);
}

.band:not(.band-cream) > .wrap .card .card-cover {
  border-color: var(--line);
  box-shadow: none;
}

.card-title {
  margin: 0;
  font-size: var(--fs-h3);
  line-height: 1.3;
  font-weight: 700;
  letter-spacing: -0.005em;
  color: var(--navy);
  text-wrap: pretty;
}

.card-meta {
  margin: 0;
  font-size: var(--fs-small);
  line-height: 1.5;
  /* r1-appeal P1: was a hardcoded var(--gray), which is fine on a white card
     or cream band but drops to ~2.27:1 when this class is used directly on a
     navy .band (trim/page-count lines on the home and product pages). Follow
     the context token like every other muted-text class so it reads gray on
     light grounds and a bright translucent cream on navy. */
  color: var(--ctx-muted);
}

/* --------------------------------------------------------------------------
   10b. .benefits - short scannable bullet list for a featured book (replaces
        a dense paragraph; used on the index featured band and the product
        page). Marker colour follows --ctx-accent so it flips correctly on a
        navy band vs a cream ground, same idiom as .kicker.
   -------------------------------------------------------------------------- */

.benefits {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 0 0 1.1em;
  padding: 0;
  list-style: none;
}

.benefits li {
  position: relative;
  margin: 0;
  padding-left: 24px;
  font-weight: 600;
  color: var(--ctx-ink);
}

.benefits li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 0.5em;
  width: 8px;
  height: 8px;
  background: var(--ctx-accent);
  transform: translateY(-50%) rotate(45deg);
}

/* --------------------------------------------------------------------------
   10c. .interior-figure / .interior-shot - a full-width interior spread
        photo with a caption, used as proof-of-substance inside a .band or
        .band-cream. Border/shadow flips the same way .card-cover does: flat
        on a light ground, lifted off a navy one.
   -------------------------------------------------------------------------- */

.interior-figure {
  margin: 48px 0 0;
  text-align: center;
}

.interior-shot {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius-img);
  background: var(--cream-strong);
}

.band:not(.band-cream) .interior-shot {
  border-color: rgba(245, 241, 232, 0.32);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.28);
}

.interior-figure figcaption {
  margin-top: 14px;
}

/* .interior-mobile-stack - product-page-only wrapper holding the left-page
   and right-page crops as two separate <picture> elements. Hidden by
   default (desktop shows the single wide spread instead); swapped in by
   the @media block below. .interior-shot-desktop / .interior-shot-mobile
   are the two sides of that swap. */
.interior-mobile-stack {
  display: none;
  flex-direction: column;
  gap: 16px;
}

/* --------------------------------------------------------------------------
   11. Buttons
   -------------------------------------------------------------------------- */

.btn,
.btn-ghost {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px 22px;
  border-radius: var(--radius-btn);
  font-family: inherit;
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.3;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.16s ease, color 0.16s ease,
    border-color 0.16s ease, transform 0.16s ease;
}

.btn:hover,
.btn-ghost:hover {
  text-decoration: none;
  transform: translateY(-1px);
}

.btn {
  background: var(--sadu);
  color: var(--cream);
  border: 1px solid var(--sadu);
}

.btn:hover {
  background: var(--sadu-deep);
  border-color: var(--sadu-deep);
  color: var(--cream-strong);
}

.btn-ghost {
  background: transparent;
  color: var(--ctx-outline);
  border: 1.5px solid var(--ctx-outline);
}

.btn-ghost:hover {
  background: var(--ctx-outline);
  color: var(--cream);
}

.band .btn-ghost:hover {
  color: var(--navy);
}

.btn + .btn,
.btn + .btn-ghost,
.btn-ghost + .btn,
.btn-ghost + .btn-ghost {
  margin-left: 12px;
}

/* --------------------------------------------------------------------------
   12. .sadu-strip - repeating stepped-diamond ornament.
       Geometry is the Sadu diamond from the K1 mark itself: a woven-pixel
       rhombus built in three discrete steps per side, on a 7.43-unit loom grid,
       with a single loom square between repeats. Sadu red on light grounds
       only; on the navy band the whole strip goes flat cream, per the brand
       rule that red never appears reversed on a dark ground.
   -------------------------------------------------------------------------- */

.sadu-strip {
  display: block;
  width: 100%;
  height: 18px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 74.29 52' width='74.29' height='52'%3E%3Cg fill='%238B2E2E'%3E%3Cpath d='M29.71 0L29.71 7.43L37.14 7.43L37.14 14.86L44.57 14.86L44.57 22.29L52 22.29L52 29.71L44.57 29.71L44.57 37.14L37.14 37.14L37.14 44.57L29.71 44.57L29.71 52L22.29 52L22.29 44.57L14.86 44.57L14.86 37.14L7.43 37.14L7.43 29.71L0 29.71L0 22.29L7.43 22.29L7.43 14.86L14.86 14.86L14.86 7.43L22.29 7.43L22.29 0Z'/%3E%3Cpath d='M59.43 22.29h7.43v7.43h-7.43z'/%3E%3C/g%3E%3C/svg%3E");
  background-repeat: space no-repeat;
  background-position: center center;
  background-size: auto 18px;
}

/* Reversed contexts: flat cream, never red on a dark ground. */
.band .sadu-strip,
.nav .sadu-strip {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 74.29 52' width='74.29' height='52'%3E%3Cg fill='%23f5f1e8'%3E%3Cpath d='M29.71 0L29.71 7.43L37.14 7.43L37.14 14.86L44.57 14.86L44.57 22.29L52 22.29L52 29.71L44.57 29.71L44.57 37.14L37.14 37.14L37.14 44.57L29.71 44.57L29.71 52L22.29 52L22.29 44.57L14.86 44.57L14.86 37.14L7.43 37.14L7.43 29.71L0 29.71L0 22.29L7.43 22.29L7.43 14.86L14.86 14.86L14.86 7.43L22.29 7.43L22.29 0Z'/%3E%3Cpath d='M59.43 22.29h7.43v7.43h-7.43z'/%3E%3C/g%3E%3C/svg%3E");
}

/* A cream band is a light ground, so it keeps the sadu red. */
.band-cream .sadu-strip {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 74.29 52' width='74.29' height='52'%3E%3Cg fill='%238B2E2E'%3E%3Cpath d='M29.71 0L29.71 7.43L37.14 7.43L37.14 14.86L44.57 14.86L44.57 22.29L52 22.29L52 29.71L44.57 29.71L44.57 37.14L37.14 37.14L37.14 44.57L29.71 44.57L29.71 52L22.29 52L22.29 44.57L14.86 44.57L14.86 37.14L7.43 37.14L7.43 29.71L0 29.71L0 22.29L7.43 22.29L7.43 14.86L14.86 14.86L14.86 7.43L22.29 7.43L22.29 0Z'/%3E%3Cpath d='M59.43 22.29h7.43v7.43h-7.43z'/%3E%3C/g%3E%3C/svg%3E");
}

/* --------------------------------------------------------------------------
   13. .prose - long-form text
   -------------------------------------------------------------------------- */

.prose {
  max-width: 66ch;
  font-size: var(--fs-body);
  line-height: 1.75;
  color: var(--ctx-ink);
}

.prose > :first-child {
  margin-top: 0;
}

.prose > :last-child {
  margin-bottom: 0;
}

.prose h2 {
  margin-top: 2.2em;
  margin-bottom: 0.5em;
}

.prose h3 {
  margin-top: 1.8em;
  margin-bottom: 0.4em;
}

.prose p {
  margin: 0 0 1.15em;
  text-wrap: pretty;
}

.prose ul,
.prose ol {
  margin: 0 0 1.15em;
  padding-left: 1.3em;
}

.prose li {
  margin-bottom: 0.5em;
}

/* Buttons are excluded: a bare `.prose a` rule outranks `.btn` on specificity
   and would repaint a sadu button's label sadu-on-sadu. Same exclusion idiom
   as the .band / .band-cream link rules above. */
.prose a:not(.btn):not(.btn-ghost) {
  color: var(--ctx-link);
  text-decoration: underline;
}

/* A grid and a prose block are siblings with no margin between them: .prose
   zeroes its own first-child margin and the grids carry none. Give the seam
   air in both directions. */
.grid-2 + .prose,
.grid-4 + .prose {
  margin-top: 56px;
}

.prose + .grid-2,
.prose + .grid-4 {
  margin-top: 40px;
}

.prose .kicker + h2,
.prose .kicker + h3 {
  margin-top: 0;
}

/* --------------------------------------------------------------------------
   14. .small
   -------------------------------------------------------------------------- */

.small {
  font-size: var(--fs-small);
  line-height: 1.6;
  color: var(--ctx-muted);
}

/* --------------------------------------------------------------------------
   15. .footer - light ground, so the sadu red strip sits where it belongs
   -------------------------------------------------------------------------- */

.footer {
  --ctx-ink: var(--ink);
  --ctx-muted: var(--gray);
  --ctx-accent: var(--sadu);
  --ctx-link: var(--sadu);
  --ctx-rule: var(--line);
  background: var(--cream);
  border-top: 1px solid var(--line);
  padding-block: 52px 44px;
  color: var(--ctx-ink);
  text-align: center;
}

.footer .sadu-strip {
  max-width: 320px;
  margin: 0 auto 30px;
}

.footer p {
  margin: 0 0 8px;
}

.footer a {
  color: var(--sadu);
  font-weight: 600;
}

.footer .small {
  margin-top: 20px;
  margin-bottom: 0;
  color: var(--gray);
}

/* --------------------------------------------------------------------------
   16. Responsive
   -------------------------------------------------------------------------- */

/* Tablet band: below the width where four cards fit, land on an even two-up
   rather than a ragged 3 + 1. Still auto-fit, so a .grid-4 holding three cards
   simply fills both tracks and wraps the third. */
@media (min-width: 561px) and (max-width: 1060px) {
  .grid-4 {
    grid-template-columns: repeat(auto-fit, minmax(45%, 1fr));
  }
}

@media (max-width: 768px) {
  :root {
    --pad-section: 56px;
    --wrap-pad: 20px;
    --gap: 22px;
  }

  .nav > .wrap {
    min-height: 0;
    gap: 10px 18px;
    padding-block: 12px;
  }

  .nav-links {
    gap: 6px 20px;
  }

  .nav-links a {
    font-size: 0.9375rem;
  }

  .brand {
    font-size: 0.875rem;
    letter-spacing: 0.14em;
  }

  .hero img {
    width: 96px;
    height: 96px;
    margin-bottom: 26px;
  }

  .hero-sub {
    font-size: 1.0625rem;
    margin-bottom: 28px;
  }

  .card {
    padding: 20px;
  }

  .card-cover {
    max-width: none;
  }

  /* r1-appeal P1: below 768px the home page's single-<img> <picture> swaps
     its <source> to the portrait single-page crop (interior-example-mobile,
     600x811) instead of the 1940x600 wide spread, but the <img>'s own
     width/height attributes still describe the desktop spread (they cannot
     vary per <source>). Without this the reserved space would use the wrong
     (very short) aspect ratio until the mobile image finishes loading, then
     jump tall. Match the mobile crop's real ratio so there is no layout
     shift. Scoped off the r2-critique product-page images below: those use
     a separate <img> per breakpoint, each with its own correct width/height
     already, so forcing one shared ratio here would squash them instead. */
  .interior-shot:not(.interior-shot-desktop):not(.interior-shot-mobile) {
    aspect-ratio: 600 / 811;
  }

  /* r2-critique P1: product page - swap the single wide spread for the
     stacked left/right mobile crops. */
  .interior-shot-desktop {
    display: none;
  }

  .interior-mobile-stack {
    display: flex;
  }

  .footer {
    padding-block: 40px 36px;
  }
}

@media (max-width: 420px) {
  .brand span {
    letter-spacing: 0.1em;
  }

  .btn,
  .btn-ghost {
    width: 100%;
  }

  .btn + .btn,
  .btn + .btn-ghost,
  .btn-ghost + .btn,
  .btn-ghost + .btn-ghost {
    margin-left: 0;
    margin-top: 12px;
  }

  .card .btn,
  .card .btn-ghost {
    align-self: stretch;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}

/* --------------------------------------------------------------------------
   17. Print. The sadu strip is a background image, so it needs an explicit
       colour-adjust to survive printing; navy bands are flattened to ink on
       white so a printed page stays readable and does not flood with toner.
   -------------------------------------------------------------------------- */

@media print {
  html,
  body {
    background: #ffffff;
    color: #000000;
    font-size: 11pt;
  }

  .nav,
  .nav-links {
    display: none;
  }

  .band,
  .band-cream,
  .footer {
    --ctx-ink: #000000;
    --ctx-muted: #444444;
    --ctx-accent: var(--sadu);
    --ctx-link: #000000;
    --ctx-outline: #000000;
    background: #ffffff !important;
    color: #000000 !important;
    padding-block: 18pt;
    border: 0;
  }

  .card {
    background: #ffffff;
    border: 1px solid #999999;
    box-shadow: none;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  .btn,
  .btn-ghost {
    background: transparent !important;
    color: #000000 !important;
    border: 1px solid #000000 !important;
    padding: 4pt 8pt;
  }

  /* Keep the ornament: force the browser to print the background image. */
  .sadu-strip,
  .band .sadu-strip,
  .band-cream .sadu-strip,
  .footer .sadu-strip {
    display: block;
    height: 14pt;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 74.29 52' width='74.29' height='52'%3E%3Cg fill='%238B2E2E'%3E%3Cpath d='M29.71 0L29.71 7.43L37.14 7.43L37.14 14.86L44.57 14.86L44.57 22.29L52 22.29L52 29.71L44.57 29.71L44.57 37.14L37.14 37.14L37.14 44.57L29.71 44.57L29.71 52L22.29 52L22.29 44.57L14.86 44.57L14.86 37.14L7.43 37.14L7.43 29.71L0 29.71L0 22.29L7.43 22.29L7.43 14.86L14.86 14.86L14.86 7.43L22.29 7.43L22.29 0Z'/%3E%3Cpath d='M59.43 22.29h7.43v7.43h-7.43z'/%3E%3C/g%3E%3C/svg%3E");
    background-size: auto 14pt;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 9pt;
    color: #444444;
    word-break: break-all;
  }

  h1,
  h2,
  h3 {
    break-after: avoid;
    page-break-after: avoid;
  }
}
