/* ============================================================
   Van Dyke Saddlery & Stock Horses
   Design system — palette, typography, layout primitives

   SECTION MAP
     1.  Tokens
     2.  Reset / base
     3.  Helpers (eyebrow, lead, skip link, visually-hidden)
     4.  Containers & sections
     5.  Buttons
     6.  Site header + nav
     7.  Hero
     8.  Creed band (the quote)
     9.  Path cards (the three ways to work with Paul)
     10. Work gallery
     11. Split feature (image + text)
     12. Testimonials
     13. Newsletter
     14. Contact band
     15. Inner-page pieces (text hero, duo cards, checklist)
     16. Footer
     17. Photo gallery + lightbox (Saddles page)
     18. Course cards + bundle (Online Courses page)
     19. Video embed + photo trio (School page)
     20. Merch cards (Merch page)
     21. Blog index (post list)
     22. Article prose (blog posts)
   ============================================================ */

/* -------- 1. Tokens -------- */
:root {
  /* Ink — warm walnut rather than a cold black, so it sits with the leather */
  --ink: #2c221b;
  --ink-soft: #56463a;
  --muted: #8a7868;

  /* Leather — the spine of the palette, taken from Paul's veg-tan work */
  --tan: #c08a4e;          /* saddle tan — the accent colour */
  --tan-deep: #9c6a35;     /* hover / link states */
  --tan-soft: #edd9b8;     /* tinted fills, borders on dark */
  --russet: #7a4526;       /* tooled shadow */
  --walnut: #4a2f1e;       /* dark bands — used sparingly */
  --walnut-deep: #33200f;

  /* Sage — Wyoming high country. The one cool note; keeps the page from
     turning into a single brown wash. */
  --sage: #8d9a84;
  --sage-deep: #64715c;
  --sage-mist: #e8ebe3;

  /* Neutrals */
  --bone: #faf6ee;         /* page background */
  --bone-deep: #f2e9da;
  --white: #ffffff;
  --line: #e3d8c6;

  /* Type */
  --font-display: "Source Serif 4", Georgia, "Times New Roman", serif;
  --font-body: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  /* Space & layout */
  --container: 1140px;
  --container-narrow: 720px;
  --section-y: clamp(3.5rem, 8vw, 6.5rem);

  /* Effects */
  --shadow-sm: 0 1px 2px rgba(44, 34, 27, 0.06);
  --shadow-md: 0 10px 30px -15px rgba(44, 34, 27, 0.28);
  --shadow-lg: 0 24px 60px -30px rgba(44, 34, 27, 0.45);
  --radius: 4px;
  --radius-lg: 8px;
}

/* -------- 2. Reset / base -------- */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.65;
  color: var(--ink);
  background: var(--bone);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img, svg { max-width: 100%; display: block; }

a {
  color: var(--russet);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
a:hover { color: var(--tan-deep); }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  color: var(--walnut-deep);
  font-weight: 600;
  line-height: 1.14;
  margin: 0 0 0.5em;
  letter-spacing: -0.015em;
}
h1 { font-size: clamp(2.4rem, 5.6vw, 4rem); }
h2 { font-size: clamp(1.85rem, 3.6vw, 2.6rem); }
h3 { font-size: clamp(1.25rem, 2vw, 1.45rem); }

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

:focus-visible {
  outline: 3px solid var(--tan);
  outline-offset: 3px;
  border-radius: 2px;
}

/* -------- 3. Helpers -------- */
.eyebrow {
  font-family: var(--font-body);
  font-size: 0.76rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--tan-deep);
  margin: 0 0 0.9rem;
}
.eyebrow--light { color: var(--tan-soft); }

.lead {
  font-size: 1.125rem;
  color: var(--ink-soft);
  max-width: 58ch;
}

.section-head { max-width: 62ch; margin: 0 0 2.75rem; }
.section-head--center { margin-inline: auto; text-align: center; }

.rule {
  width: 56px; height: 2px; border: 0;
  background: var(--tan);
  margin: 0 0 1.5rem;
}
.rule--center { margin-inline: auto; }

.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;
}

.skip-link {
  position: absolute; left: -9999px; top: 0;
  background: var(--walnut); color: #fff; padding: 0.75rem 1rem;
  text-decoration: none;
}
.skip-link:focus { left: 1rem; top: 1rem; z-index: 200; }

/* -------- 4. Containers & sections -------- */
.container { max-width: var(--container); margin: 0 auto; padding: 0 1.5rem; }
.container--narrow { max-width: var(--container-narrow); }

.section { padding-block: var(--section-y); }
/* The header is sticky (74px), so an in-page jump would land under it.
   Every anchor target on the site is a section, so set it here once. */
.section[id] { scroll-margin-top: 74px; }
.section--bone   { background: var(--bone); }
.section--white  { background: var(--white); }
.section--deep   { background: var(--bone-deep); }
.section--sage   { background: var(--sage-mist); }
.section--walnut { background: var(--walnut); color: var(--tan-soft); }
.section--walnut h2,
.section--walnut h3 { color: var(--white); }
.section--walnut .lead { color: rgba(255, 255, 255, 0.78); }

/* -------- 5. Buttons -------- */
.btn {
  display: inline-flex; align-items: center; gap: 0.5rem;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.94rem;
  letter-spacing: 0.02em;
  padding: 0.85rem 1.6rem;
  border-radius: var(--radius);
  border: 1.5px solid transparent;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.18s ease, color 0.18s ease,
              border-color 0.18s ease, transform 0.18s ease;
}
.btn:hover { transform: translateY(-1px); }

.btn--primary {
  background: var(--russet); border-color: var(--russet); color: var(--white);
}
.btn--primary:hover {
  background: var(--walnut); border-color: var(--walnut); color: var(--white);
}

.btn--ghost {
  background: transparent; border-color: var(--line); color: var(--ink);
}
.btn--ghost:hover {
  border-color: var(--russet); color: var(--russet); background: var(--white);
}

.btn--light {
  background: var(--tan); border-color: var(--tan); color: var(--walnut-deep);
}
.btn--light:hover {
  background: var(--tan-soft); border-color: var(--tan-soft); color: var(--walnut-deep);
}

.btn--outline-light {
  background: transparent;
  border-color: rgba(237, 217, 184, 0.45);
  color: var(--tan-soft);
}
.btn--outline-light:hover {
  border-color: var(--tan-soft); color: var(--white); background: rgba(255,255,255,0.06);
}

/* A text link that reads as an action */
.link-arrow {
  font-weight: 600; font-size: 0.94rem;
  text-decoration: none;
  color: var(--russet);
  display: inline-flex; align-items: center; gap: 0.4rem;
}
.link-arrow::after { content: "\2192"; transition: transform 0.18s ease; }
.link-arrow:hover::after { transform: translateX(3px); }

/* -------- 6. Site header + nav -------- */
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: rgba(250, 246, 238, 0.94);
  backdrop-filter: saturate(180%) blur(8px);
  border-bottom: 1px solid var(--line);
}
.site-header__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.5rem;
  min-height: 74px;
}

.brand {
  display: flex; flex-direction: column; gap: 0.3rem;
  text-decoration: none; color: var(--walnut-deep);
  line-height: 1.05;
}
.brand__name {
  font-family: var(--font-display);
  font-size: 1.32rem; font-weight: 600; letter-spacing: -0.01em;
}
.brand__sub {
  font-family: var(--font-body);
  font-size: 0.62rem; font-weight: 600;
  letter-spacing: 0.19em; text-transform: uppercase;
  color: var(--muted);
}

.site-header__nav ul {
  display: flex; align-items: center; gap: 1.45rem;
  list-style: none; margin: 0; padding: 0;
}
/* :not(.btn) matters — without it this rule wins over .btn--primary's white
   text (same specificity, later in the file) and the CTA goes brown-on-brown. */
.site-header__nav a:not(.btn) {
  text-decoration: none;
  font-size: 0.92rem; font-weight: 500;
  color: var(--ink-soft);
  padding-block: 0.35rem;
  border-bottom: 2px solid transparent;
}
.site-header__nav a:not(.btn):hover { color: var(--russet); }
.site-header__nav a:not(.btn)[aria-current="page"] {
  color: var(--walnut-deep); font-weight: 600; border-bottom-color: var(--tan);
}
.site-header__nav .btn { padding: 0.6rem 1.15rem; font-size: 0.88rem; }

.nav-toggle {
  display: none;
  background: transparent; border: 1.5px solid var(--line);
  border-radius: var(--radius);
  width: 44px; height: 42px;
  align-items: center; justify-content: center;
  cursor: pointer; color: var(--ink);
}
.nav-toggle__bars, .nav-toggle__bars::before, .nav-toggle__bars::after {
  display: block; width: 20px; height: 2px; background: currentColor;
  border-radius: 2px; content: "";
}
.nav-toggle__bars { position: relative; }
.nav-toggle__bars::before { position: absolute; top: -6px; }
.nav-toggle__bars::after  { position: absolute; top: 6px; }

/* 1024, NOT the site's usual 900. The nav carries six items plus the CTA since
   Merch was added (2 Sep 2026), and between 900 and ~1010 that no longer fits:
   "Online Courses", "The School" and "Get in touch" each wrap onto two lines
   inside a header that stays 74px tall. This is the ONLY breakpoint in the file
   that isn't 900 — every layout collapse still happens at 900. Drop a nav item
   and this can go back. */
@media (max-width: 1024px) {
  .nav-toggle { display: inline-flex; }
  .site-header__nav {
    position: absolute; left: 0; right: 0; top: 100%;
    background: var(--bone);
    border-bottom: 1px solid var(--line);
    box-shadow: var(--shadow-md);
    display: none;
  }
  .site-header__nav[data-open="true"] { display: block; }
  .site-header__nav ul {
    flex-direction: column; align-items: stretch; gap: 0;
    padding: 0.5rem 1.5rem 1.25rem;
  }
  .site-header__nav li { border-bottom: 1px solid var(--line); }
  .site-header__nav li:last-child { border-bottom: 0; padding-top: 1rem; }
  .site-header__nav a { display: block; padding: 0.9rem 0; font-size: 1rem; }
  .site-header__nav a[aria-current="page"] { border-bottom-color: transparent; }
  .site-header__nav .btn { justify-content: center; }
}

/* -------- 7. Hero -------- */
/* The band is dark walnut and the photo is lifted (contrast and colour) —
   "option D", picked by the owner and Amber 30 Sep 2026 after the bone band
   read as washed out. The photos themselves are pale, and pale on pale was
   the problem. Applies to every photo-hero page at once, so the text and
   buttons inside it are re-coloured for a dark ground here too.
   The walnut carries a faint PEBBLED leather grain (owner, 1 Oct 2026 —
   "option C" of three on a test page). It is an inline SVG tile: turbulence
   noise lit from the top left so it reads as raised pebbling, laid over the
   gradient with `overlay` so the colour itself doesn't shift. ~700 bytes, no
   image file. Keep it subtle: the tile's rect opacity (0.16) is the dial. */
.hero {
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='p'%3E%3CfeTurbulence type='turbulence' baseFrequency='0.11' numOctaves='2' seed='4' stitchTiles='stitch' result='t'/%3E%3CfeDiffuseLighting in='t' surfaceScale='1.6' diffuseConstant='1' lighting-color='%23fff'%3E%3CfeDistantLight azimuth='225' elevation='55'/%3E%3C/feDiffuseLighting%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23p)' opacity='0.16'/%3E%3C/svg%3E"),
    linear-gradient(180deg, var(--walnut) 0%, var(--walnut-deep) 100%);
  background-blend-mode: overlay, normal;
  padding-block: clamp(3rem, 7vw, 5.5rem) clamp(3.5rem, 8vw, 6rem);
  overflow: hidden;
}
/* Text gets the wider column — the hero photo is PORTRAIT, so giving it the
   larger share would make the whole band absurdly tall. */
.hero__inner {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}
.hero__title-line { display: block; }
.hero__title-line--accent { color: var(--tan); font-style: italic; }
.hero__lead { margin-top: 1.4rem; }
.hero h1 { color: var(--bone); }
.hero .eyebrow { color: var(--tan); }
.hero .lead { color: var(--tan-soft); }
/* Same pair as the walnut contact band: tan primary, outlined ghost. */
.hero .btn--primary { background: var(--tan); border-color: var(--tan); color: var(--walnut-deep); }
.hero .btn--primary:hover { background: var(--tan-soft); border-color: var(--tan-soft); color: var(--walnut-deep); }
.hero .btn--ghost { border-color: rgba(237, 217, 184, 0.45); color: var(--tan-soft); }
.hero .btn--ghost:hover { border-color: var(--tan-soft); color: var(--white); background: rgba(255, 255, 255, 0.06); }
.hero__actions {
  display: flex; flex-wrap: wrap; gap: 0.85rem;
  margin-top: 2rem;
}
/* PORTRAIT 2:3 — the native ratio of the hero photo, so nothing is cropped.
   Same ratio at every width (it used to switch ratios below 900px, which
   re-cropped the photo on phones). Export hero images at 2:3, 1600x2400. */
.hero__frame {
  position: relative;
  border-radius: var(--radius-lg);
  overflow: hidden;
  /* The site's --shadow-lg is too faint to see on the dark walnut band, so
     the hero photo gets its own: a tight dark shadow close to the edge, plus
     a softer one under it, for a little lift without a halo. */
  box-shadow:
    0 2px 6px rgba(0, 0, 0, 0.35),
    0 14px 28px -8px rgba(0, 0, 0, 0.6);
  aspect-ratio: 2 / 3;
}
.hero__frame img {
  width: 100%; height: 100%; object-fit: cover;
  /* brightness FIRST: contrast then pushes white back to pure white, so
     the Merch product plate stays white instead of going grey. */
  filter: brightness(0.96) contrast(1.12) saturate(1.25);
}

/* Merch's hero is a product plate exported on WHITE, and the owner wanted it
   on the menu bar's cream (30 Sep 2026). The transparent source mockups are
   gone, so rather than re-export, the image MULTIPLIES onto a --bone frame:
   white becomes exactly --bone, and the darker garment is all but unchanged.
   `isolation` keeps the blend inside the frame, off the walnut band. */
.hero__frame--plate { background: var(--bone); isolation: isolate; }
.hero__frame--plate img { mix-blend-mode: multiply; }

/* Small stat strip beneath the hero copy */
/* A 3-column GRID, not flex. Flex kept dropping the third stat onto a second
   row: the natural label widths total ~490px against a ~486px hero column, so
   it overflowed by a handful of pixels at exactly the desktop width. The grid
   pins all three to one row at any width and lets a long label wrap inside its
   own cell instead. Keep the labels short anyway. */
.hero__facts {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
  margin-top: 2.5rem; padding-top: 1.75rem;
  border-top: 1px solid var(--line);
}
.hero__fact { min-width: 0; }
.hero__fact strong {
  display: block;
  font-family: var(--font-display);
  font-size: 1.6rem; font-weight: 600; color: var(--walnut-deep);
  line-height: 1.1;
}
.hero__fact span {
  display: block;
  font-size: 0.72rem; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase;
  line-height: 1.35;
  color: var(--muted);
}

/* On phones the photo sits BETWEEN the headline and the lead paragraph:
     eyebrow → headline → photo → lead → buttons.

   `display: contents` on .hero__content is what makes that possible without
   touching the markup — it dissolves the wrapper so its four children become
   grid items of .hero__inner alongside .hero__frame, and `order` can then
   interleave the photo among them. Remove that line and the order values stop
   working, because the text pieces go back to being one single grid item.

   Gap is zeroed here so the five items are spaced by their own margins rather
   than by one uniform grid gap (grid-item margins never collapse, so what is
   written is what you get). */
@media (max-width: 900px) {
  .hero__inner { grid-template-columns: 1fr; gap: 0; }

  .hero__content { display: contents; }
  .hero__content .eyebrow { order: 1; }
  .hero__content h1      { order: 2; }
  .hero__frame           { order: 3; margin: 0.5rem 0 1.75rem; }
  .hero__lead            { order: 4; margin-top: 0; }
  /* Online Courses runs two lead paragraphs; the rule above zeroes both, so
     put the space back between them. */
  .hero__lead + .hero__lead { margin-top: 1rem; }
  /* Tighter than desktop's 2rem: the lead's own bottom margin no longer
     collapses into this one once these are grid items. */
  .hero__actions         { order: 5; margin-top: 1.25rem; }

  /* Full-width stacked buttons — a phone-width tap target rather than two
     small left-aligned pills. */
  .hero__actions {
    flex-direction: column;
    align-items: stretch;
  }
  .hero__actions .btn {
    width: 100%;
    justify-content: center;
  }
}

/* -------- 8. Creed band -------- */
/* LIGHT since 30 Sep 2026. It sits straight under the home hero, which went
   dark walnut that day; two dark bands in a row lost the seam. White, because
   the band under a hero is white on every page. Only the home page uses it. */
.creed {
  background: var(--white);
  color: var(--ink-soft);
  padding-block: clamp(3.25rem, 7vw, 5.25rem);
}
.creed__eyebrow, .creed__title { text-align: center; }
/* Only the three-rule version needs the big gap before the list. */
.creed__title { margin-bottom: 2.75rem; }

.creed__list {
  list-style: none; margin: 0; padding: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2.5rem;
}
.creed__list li {
  position: relative;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
}
.creed__num {
  display: block;
  font-family: var(--font-display);
  font-size: 0.95rem; font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--tan-deep);
  margin-bottom: 0.6rem;
}
.creed__list h3 {
  font-size: clamp(1.15rem, 1.9vw, 1.35rem);
  margin-bottom: 0.55rem;
}
.creed__list p {
  color: var(--ink-soft);
  font-size: 0.98rem;
  margin: 0;
}

@media (max-width: 900px) {
  .creed__list { grid-template-columns: 1fr; gap: 1.75rem; }
  .creed__title { margin-bottom: 2rem; }
}

/* -------- 9. Path cards -------- */
.paths {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.75rem;
}
.path-card {
  display: flex; flex-direction: column;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.path-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); }
.path-card__media { aspect-ratio: 4 / 3; overflow: hidden; background: var(--bone-deep); }
.path-card__media img { width: 100%; height: 100%; object-fit: cover; }
.path-card__body { padding: 1.6rem 1.5rem 1.75rem; display: flex; flex-direction: column; flex: 1; }
.path-card h3 { margin-bottom: 0.5rem; }
.path-card p { color: var(--ink-soft); font-size: 0.97rem; }
.path-card .link-arrow { margin-top: auto; padding-top: 1.25rem; align-self: flex-start; }

@media (max-width: 900px) {
  .paths { grid-template-columns: 1fr; gap: 1.25rem; }
  .path-card__media { aspect-ratio: 16 / 9; }
}

/* -------- 10. Work gallery -------- */
.gallery {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 1fr;
  gap: 0.85rem;
}
.gallery figure {
  margin: 0; overflow: hidden;
  border-radius: var(--radius);
  background: var(--bone-deep);
  aspect-ratio: 1 / 1;
}
.gallery img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 0.4s ease;
}
.gallery figure:hover img { transform: scale(1.04); }
.gallery figure.is-tall { grid-row: span 2; aspect-ratio: 1 / 2; }
.gallery figure.is-wide { grid-column: span 2; aspect-ratio: 2 / 1; }

@media (max-width: 900px) {
  .gallery { grid-template-columns: repeat(2, 1fr); }
  .gallery figure.is-tall { grid-row: span 1; aspect-ratio: 1 / 1; }
  .gallery figure.is-wide { grid-column: span 2; aspect-ratio: 2 / 1; }
}

/* -------- 11. Split feature -------- */
.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}
.split--reverse .split__media { order: 2; }
.split__media {
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-md);
  aspect-ratio: 4 / 5;
}
.split__media img { width: 100%; height: 100%; object-fit: cover; }

@media (max-width: 900px) {
  .split { grid-template-columns: 1fr; }
  .split--reverse .split__media { order: 0; }
  .split__media { aspect-ratio: 4 / 3; }
  /* --natural keeps the photo's own 4:5 when stacked instead of squeezing it
     to 4:3, which cut the top and bottom off (the About page photo lost the
     top of Paul's head — owner, 25 Sep 2026). Capped in width so on a tablet
     a full-width 4:5 frame doesn't run a whole screen tall. */
  .split__media--natural {
    aspect-ratio: 4 / 5;
    width: 100%; max-width: 460px; margin-inline: auto;
  }
}

/* -------- 12. Testimonials -------- */
/* Editorial treatment, chosen by the owner 19 Aug 2026 over the earlier card
   version: no boxes, no shadows, no borders around the words. The quotes sit
   straight on the page and are divided by hairlines. The page already carries
   boxed path-cards and duo-cards, and a fourth set of boxes here read like a
   pricing grid rather than a saddle shop.

   One .quote-feature set large above a .quote-row of supporting quotes. The
   hierarchy is deliberate: on the home page the flagship product gets the
   loudest voice. Both pages share these classes — the About page uses them for
   Paul's own pull quote and the two horsemanship testimonials. */
.quote-feature {
  max-width: 780px;
  margin: 0 auto;
  text-align: center;
}
/* Gap belongs BETWEEN the feature and the row, not on the feature itself —
   on the About page the feature is the last thing in its section, and a
   trailing margin there just doubled the section's bottom padding. */
.quote-feature + .quote-row { margin-top: 3.5rem; }
.quote-feature p {
  font-family: var(--font-display);
  font-size: clamp(1.35rem, 2.8vw, 1.95rem);
  line-height: 1.45;
  color: var(--ink);
  margin: 0 0 1.5rem;
}

.quote-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0;                       /* the hairlines do the separating, not a gap */
}
.quote {
  margin: 0;
  padding: 0 2rem;
  border-left: 1px solid var(--line);
  display: flex; flex-direction: column;
}
.quote:first-child { border-left: 0; padding-left: 0; }
.quote:last-child  { padding-right: 0; }
.quote p {
  font-size: 0.95rem;
  color: var(--ink-soft);
  margin: 0 0 1.2rem;
}
/* Quotes are never the same length — push every attribution to a shared
   baseline so the names line up across the row. */
.quote footer { margin-top: auto; }

.quote footer,
.quote-feature footer { line-height: 1.5; }
.quote footer strong,
.quote-feature footer strong {
  display: block;
  font-family: var(--font-body);
  font-size: 0.9rem; font-weight: 600;
  color: var(--walnut-deep);
}
/* Says which side of the business the quote is about. With three revenue
   lines an untagged wall of praise tells the reader nothing — keep tagging
   them. Set as small caps rather than a chip: a pill would put a box back on
   the page, which is the thing this treatment exists to remove. */
.quote-tag {
  display: block;
  font-size: 0.72rem; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--tan-deep);
  margin-top: 0.3rem;
}

@media (max-width: 900px) {
  .quote-row { grid-template-columns: 1fr; gap: 2rem; }
  /* Hairlines turn from vertical dividers into horizontal ones */
  .quote {
    border-left: 0;
    border-top: 1px solid var(--line);
    padding: 2rem 0 0;
  }
  .quote:first-child { border-top: 0; padding-top: 0; }
}

/* -------- 13. Newsletter -------- */
.newsletter {
  background: var(--sage-mist);
  border: 1px solid #d9e0d3;
  border-radius: var(--radius-lg);
  padding: clamp(2rem, 4vw, 3rem);
  text-align: center;
}
.newsletter h2 { margin-bottom: 0.4rem; }
.newsletter .lead { margin-inline: auto; }
.newsletter__embed { margin-top: 1.75rem; }

/* The Flodesk form. Flodesk injects its own <style> AFTER this sheet, at
   specificity 0,3,0 ([data-ff-el="root"].ff-ID .ff-ID__x), so every rule
   here is prefixed `.newsletter .newsletter__embed` to reach 0,4,0 and win.
   Selectors use Flodesk's generic classes (.fd-form-control) or the `__x`
   suffix, never the form ID, so a replacement form picks the styling up.
   The form's own title and subtitle are hidden: the Musings heading and
   lead above already introduce it. Anything typed into those in the
   Flodesk editor will not show. */
.newsletter .newsletter__embed [data-ff-el="root"] { background: transparent; color: var(--ink); }
.newsletter .newsletter__embed [data-ff-el="root"] [class$="__form"] {
  padding: 0;
  font-family: var(--font-body);
  color: var(--ink);
}
.newsletter .newsletter__embed [data-ff-el="root"] [class$="__title"],
.newsletter .newsletter__embed [data-ff-el="root"] [class$="__subtitle"] { display: none; }
.newsletter .newsletter__embed [data-ff-el="root"] [class$="__content"] { margin-top: 0; }
.newsletter .newsletter__embed [data-ff-el="root"] .fd-form-control,
.newsletter .newsletter__embed [data-ff-el="root"] .fd-form-label {
  height: 48px;
  padding: 13px 16px;
  font-family: var(--font-body);
  font-size: 0.94rem;
  line-height: 20px;
  color: var(--ink);
}
.newsletter .newsletter__embed [data-ff-el="root"] .fd-form-control {
  background: var(--white);
  border: 1px solid #d9e0d3;
  border-radius: var(--radius);
  transition: border-color 0.18s ease;
}
.newsletter .newsletter__embed [data-ff-el="root"] .fd-form-control:focus {
  border-color: var(--russet);
  outline: none;
}
.newsletter .newsletter__embed [data-ff-el="root"] .fd-form-label { color: var(--muted); }
.newsletter .newsletter__embed [data-ff-el="root"] [class$="__footer"] { margin-top: 1rem; }
/* The button borrows .btn--primary's look and hover. */
.newsletter .newsletter__embed [data-ff-el="root"] [class*="__button"] {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.94rem;
  letter-spacing: 0.02em;
  line-height: 20px;
  padding: 0.85rem 1.6rem;
  background: var(--russet);
  border: 1.5px solid var(--russet);
  border-radius: var(--radius);
  color: var(--white);
  transition: background-color 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
}
.newsletter .newsletter__embed [data-ff-el="root"] [class*="__button"]:hover {
  background: var(--walnut);
  border-color: var(--walnut);
  transform: translateY(-1px);
}

/* -------- 14. Contact band -------- */
.contact-band { text-align: center; }
.contact-band__details {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 1rem 3rem;
  margin: 2.25rem 0 0;
  list-style: none; padding: 0;
}
.contact-band__details li { font-size: 0.95rem; }
.contact-band__details strong {
  display: block;
  font-size: 0.72rem; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--tan); margin-bottom: 0.3rem;
}
.contact-band__details a { color: var(--white); text-decoration-color: rgba(255,255,255,0.4); }
.contact-band__details a:hover { color: var(--tan-soft); }
.contact-band__actions {
  display: flex; flex-wrap: wrap; gap: 0.85rem; justify-content: center;
  margin-top: 2.25rem;
}

/* -------- 15. Inner-page pieces -------- */
/* Compact heading band for pages that don't need a hero photo. */
.text-hero {
  background: linear-gradient(180deg, var(--bone) 0%, var(--bone-deep) 100%);
  padding-block: clamp(3rem, 7vw, 4.75rem) clamp(2.5rem, 6vw, 4rem);
  text-align: center;
}
.text-hero .lead { margin-inline: auto; }
.text-hero h1 { margin-bottom: 0.6rem; }

/* Two side-by-side cards — the About page's "two halves of the year". */
.duo {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.75rem;
}
.duo-card {
  background: var(--white);
  border: 1px solid var(--line);
  border-top: 3px solid var(--tan);
  border-radius: var(--radius);
  padding: 2rem 1.85rem;
}
.duo-card h3 { margin-bottom: 0.55rem; }
.duo-card p { color: var(--ink-soft); font-size: 0.98rem; }
.duo-card__season {
  font-size: 0.72rem; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--tan-deep);
  display: block; margin-bottom: 0.75rem;
}

/* Two quotes instead of three (see section 12) */
.quote-row--two { grid-template-columns: repeat(2, 1fr); }

/* Bulleted list styled to match the site rather than the browser default */
.checklist { list-style: none; margin: 1.25rem 0 0; padding: 0; }
.checklist li {
  position: relative;
  padding-left: 1.6rem;
  margin-bottom: 0.7rem;
  color: var(--ink-soft);
}
.checklist li::before {
  content: ""; position: absolute;
  left: 0; top: 0.62em;
  width: 8px; height: 8px;
  background: var(--tan);
  border-radius: 50%;
}

@media (max-width: 900px) {
  .duo { grid-template-columns: 1fr; gap: 1.25rem; }
  .quote-row--two { grid-template-columns: 1fr; }
}

/* -------- 16. Footer -------- */
.site-footer {
  background: var(--walnut-deep);
  color: rgba(255, 255, 255, 0.72);
  padding-block: 3.5rem 2rem;
  font-size: 0.92rem;
}
.site-footer a { color: rgba(255, 255, 255, 0.82); text-decoration: none; }
.site-footer a:hover { color: var(--tan); text-decoration: underline; }
.site-footer h2 {
  font-family: var(--font-body);
  font-size: 0.74rem; font-weight: 600;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--tan);
  margin-bottom: 1rem;
}
.site-footer__grid {
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr;
  gap: 2.5rem;
}
.site-footer ul { list-style: none; margin: 0; padding: 0; }
.site-footer li { margin-bottom: 0.6rem; }
.site-footer__brand .brand__name { color: var(--white); font-size: 1.25rem; }
.site-footer__brand .brand__sub { color: var(--tan); }
.site-footer__blurb { margin-top: 1rem; max-width: 38ch; }
.site-footer__social { display: flex; gap: 1rem; margin-top: 1.25rem; }
.site-footer__social a {
  width: 38px; height: 38px;
  border: 1px solid rgba(255,255,255,0.22);
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
}
.site-footer__social a:hover { border-color: var(--tan); background: rgba(192,138,78,0.14); }
.site-footer__social svg { width: 17px; height: 17px; fill: currentColor; }
.site-footer__base {
  margin-top: 3rem; padding-top: 1.5rem;
  border-top: 1px solid rgba(255,255,255,0.12);
  display: flex; flex-wrap: wrap; gap: 0.5rem 1.5rem;
  justify-content: space-between;
  font-size: 0.84rem; color: rgba(255,255,255,0.5);
}

@media (max-width: 760px) {
  .site-footer__grid { grid-template-columns: 1fr; gap: 2rem; }
}

/* -------- 17. Photo gallery + lightbox -------- */
/* Masonry by CSS columns rather than a fixed grid: the photos come in
   portrait, landscape and square and cropping them all to one ratio throws
   away the composition. Columns keep every frame at its native shape.
   Reading order runs DOWN each column, not across — fine for a gallery. */
.photo-gallery {
  columns: 4;
  column-gap: 1rem;
}
.photo-gallery figure {
  break-inside: avoid;
  margin: 0 0 1rem;
}
.photo-gallery__item {
  display: block;
  position: relative;
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  background: var(--bone-deep);
}
.photo-gallery img {
  display: block;
  width: 100%; height: auto;
  transition: transform 0.5s ease;
}
.photo-gallery figcaption {
  position: absolute; inset: auto 0 0 0;
  padding: 2.25rem 0.9rem 0.75rem;
  background: linear-gradient(180deg, rgba(51,32,15,0) 0%, rgba(51,32,15,0.82) 65%);
  color: var(--white);
  font-size: 0.82rem; line-height: 1.35;
  opacity: 0; transform: translateY(6px);
  transition: opacity 0.25s ease, transform 0.25s ease;
}
/* Hover captions only where there is a real pointer — on a phone they would
   never be reachable, and the alt text carries the same information anyway. */
@media (hover: hover) and (pointer: fine) {
  .photo-gallery__item:hover img,
  .photo-gallery__item:focus-visible img { transform: scale(1.035); }
  .photo-gallery__item:hover figcaption,
  .photo-gallery__item:focus-visible figcaption { opacity: 1; transform: none; }
}
.photo-gallery__item:focus-visible {
  outline: 3px solid var(--tan);
  outline-offset: 3px;
}

/* Set by the script in saddles.njk, which deals the tiles into real column
   divs in reading order. Without it, the CSS columns above still work. */
.photo-gallery.is-dealt {
  columns: auto;
  display: flex; align-items: flex-start;
  gap: 1rem;
}
.photo-gallery__col { flex: 1 1 0; min-width: 0; }

@media (max-width: 1024px) { .photo-gallery { columns: 3; } }
@media (max-width: 760px)  { .photo-gallery { columns: 2; column-gap: 0.75rem; }
                             .photo-gallery.is-dealt { columns: auto; gap: 0.75rem; }
                             .photo-gallery figure { margin-bottom: 0.75rem; } }

/* ---- Lightbox. Progressive enhancement: with JS off, every tile is just a
   link straight to the large file, which is a perfectly good fallback. ---- */
.lightbox {
  position: fixed; inset: 0; z-index: 200;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 1rem;
  padding: clamp(1rem, 4vw, 3rem);
  background: rgba(30, 19, 9, 0.95);
}
.lightbox[hidden] { display: none; }
.lightbox__figure {
  margin: 0;
  display: flex; flex-direction: column; align-items: center; gap: 0.9rem;
  max-width: 100%;
}
.lightbox__img {
  max-width: 100%; max-height: 78vh;
  width: auto; height: auto;
  object-fit: contain;
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
}
.lightbox__cap {
  color: var(--tan-soft);
  font-size: 0.9rem;
  text-align: center;
  max-width: 60ch;
}
.lightbox__count {
  color: rgba(255,255,255,0.45);
  font-size: 0.78rem; letter-spacing: 0.1em; text-transform: uppercase;
}
.lightbox button {
  position: absolute;
  display: grid; place-items: center;
  width: 46px; height: 46px;
  border: 1px solid rgba(255,255,255,0.25);
  border-radius: 50%;
  background: rgba(255,255,255,0.06);
  color: var(--white);
  font-size: 1.3rem; line-height: 1;
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease;
}
.lightbox button:hover { background: rgba(255,255,255,0.16); border-color: var(--tan); }
.lightbox button:focus-visible { outline: 3px solid var(--tan); outline-offset: 2px; }
.lightbox__close { top: 1rem; right: 1rem; }
.lightbox__prev  { left: 1rem;  top: 50%; transform: translateY(-50%); }
.lightbox__next  { right: 1rem; top: 50%; transform: translateY(-50%); }

@media (max-width: 620px) {
  .lightbox__img { max-height: 66vh; }
  .lightbox__prev { left: 0.5rem; }
  .lightbox__next { right: 0.5rem; }
  .lightbox__close { top: 0.5rem; right: 0.5rem; }
}

/* -------- 18. Course cards + bundle -------- */
/* Boxes are right here in a way they were not for the testimonials: these are
   priced products with their own call to action, so each one needs an edge you
   can point at. Same idiom as .duo-card — white, hairline, tan top rule. */
.courses {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.75rem;
}
.course-card {
  display: flex; flex-direction: column;
  /* Warm card on a WHITE section — the inverse of .duo-card, and deliberate.
     The section under the hero is white (chosen when the hero ended on
     --bone-deep, for the seam to read), and a white card on a white section
     disappears. This way the card edge is the full 37-step apart. */
  background: var(--bone-deep);
  border-top: 3px solid var(--tan);
  border-radius: var(--radius);
  padding: 2rem 1.85rem;
  overflow: hidden;   /* clips the photo to the card's rounded corners */
}
/* The course's own photo (the Teachable thumbnail), edge to edge under the
   tan rule — the negative margins cancel the card padding. Fixed 3:2 so the
   step labels and titles line up across a row; the files are pre-cropped to
   3:2 by tools/optimise-course-thumbs.js, so `cover` crops nothing. */
.course-card__media {
  margin: -2rem -1.85rem 1.5rem;
  aspect-ratio: 3 / 2;
  background: var(--bone);
}
.course-card__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.course-card__step {
  font-size: 0.72rem; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--tan-deep);
  margin-bottom: 0.75rem;
}
.course-card h3 { margin-bottom: 0.5rem; }
.course-card__meta {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.6rem;
  margin-bottom: 1rem;
}
.course-card__price {
  font-family: var(--font-display);
  font-size: 1.45rem; font-weight: 600;
  color: var(--walnut-deep);
}
.course-card__length { font-size: 0.85rem; color: var(--muted); }
.course-card p { color: var(--ink-soft); font-size: 0.96rem; }
/* Buttons line up across the row however uneven the copy above them is */
.course-card .btn { margin-top: auto; align-self: flex-start; }
.course-card__cta { margin-top: auto; padding-top: 1.5rem; }
.course-card__cta .btn { margin-top: 0; }

/* ---- The three-course bundle ---- */
/* White card — the bundle band itself is --bone-deep now, so a bone-deep card
   would vanish into it. */
.bundle {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: clamp(2rem, 4vw, 3rem);
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}
.bundle h2 { margin-bottom: 0.5rem; }
.bundle p { color: var(--ink-soft); }
.bundle__price {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 0.75rem;
  margin-bottom: 0.4rem;
}
.bundle__now {
  font-family: var(--font-display);
  font-size: clamp(2.4rem, 5vw, 3.1rem); font-weight: 600;
  line-height: 1;
  color: var(--walnut-deep);
}
.bundle__was {
  font-size: 1.05rem;
  color: var(--muted);
  text-decoration: line-through;
}
.bundle__save {
  font-size: 0.72rem; font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--white); background: var(--russet);
  border-radius: 100px;
  padding: 0.3rem 0.75rem;
}
.bundle__aside { text-align: center; }
.bundle__aside .btn { width: 100%; justify-content: center; }
.bundle__note { font-size: 0.85rem; color: var(--muted); margin-top: 0.9rem; }

@media (max-width: 1024px) {
  .courses { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 760px) {
  .courses { grid-template-columns: 1fr; gap: 1.25rem; }
  /* Stacked, the aside is no longer a column of its own — left-align it with
     everything above it or the note floats out of step with the price row. */
  .bundle { grid-template-columns: 1fr; }
  .bundle__aside { text-align: left; }
}

/* -------- 19. Video embed + photo trio -------- */
/* 16:9 wrapper so the YouTube iframe scales with the column instead of being
   pinned to fixed pixel dimensions. */
.video-frame {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-md);
  background: var(--walnut-deep);
}
.video-frame iframe {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border: 0;
}
.video-note {
  margin-top: 1.25rem;
  text-align: center;
  font-size: 0.9rem;
  color: var(--muted);
}

/* Three photos side by side. Not the home page's .gallery — that one is a
   fixed 12-cell tile puzzle and breaks if you change the count. */
.photo-trio {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.25rem;
}
.photo-trio figure {
  margin: 0;
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  aspect-ratio: 4 / 3;
}
.photo-trio img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Each photo is a link to its full-size file, opened by the shared lightbox
   (_includes/partials/lightbox.njk). Same hover and focus as the Saddles
   gallery tiles in section 17. */
.photo-trio__item { display: block; height: 100%; cursor: zoom-in; }
.photo-trio__item img { transition: transform 0.5s ease; }
@media (hover: hover) and (pointer: fine) {
  .photo-trio__item:hover img,
  .photo-trio__item:focus-visible img { transform: scale(1.035); }
}
.photo-trio figure:has(.photo-trio__item:focus-visible) {
  outline: 3px solid var(--tan);
  outline-offset: 3px;
}
.photo-trio__item:focus-visible { outline: none; }

@media (max-width: 760px) {
  .photo-trio { grid-template-columns: 1fr; gap: 1rem; }
}

/* -------- 20. Merch cards -------- */
/* Same idiom as .course-card, for the same reason: these are priced products,
   so each needs an edge you can point at. Bone-deep card on a --white section
   (the band under the hero is white).

   The product images are EXPORTED on --bone-deep, so the photo and the card
   share one fill and the garment appears to float in the card rather than
   sitting in a pasted-in box. Change this background and the images have to be
   re-exported to match — see tools/optimise-merch.js. */
/* FOUR across — one card per product, and four is the whole range. Two-up
   below 1024 rather than the site's usual 900: four columns inside the 1140
   container are already only ~250px, and squeezing them further makes the
   price and its "Shown in ..." note wrap against each other. */
.merch-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1.5rem;
}
.merch-card {
  display: flex; flex-direction: column;
  background: var(--bone-deep);
  border-top: 3px solid var(--tan);
  border-radius: var(--radius);
  overflow: hidden;
  /* position: relative anchors the stretched link below. */
  position: relative;
  box-shadow: var(--shadow-sm);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
/* Same lift as .path-card on the home page — deliberately the same numbers, so
   a hoverable card behaves identically wherever it appears on the site. */
.merch-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); }

/* The WHOLE card is a link to the store. The <a> wraps only the heading, so the
   accessible name is "Hoodie" rather than the card's entire text, and its
   ::after is stretched over the card to catch the click. Nothing else in the
   card is a link, so there is no nested-interactive problem. */
.merch-card h3 a {
  text-decoration: none;
  color: inherit;
}
.merch-card h3 a::after { content: ""; position: absolute; inset: 0; }
.merch-card:hover h3 a { color: var(--russet); }
/* Outline the card, not the two words of the heading — the ::after is what the
   pointer actually hits, and an outline round the text alone reads as a bug. */
.merch-card h3 a:focus-visible { outline: none; }
.merch-card:has(h3 a:focus-visible) {
  outline: 3px solid var(--tan);
  outline-offset: 3px;
}
/* 1:1 — the source mockups are square, so nothing is cropped. */
.merch-card__img {
  aspect-ratio: 1 / 1;
  width: 100%;
  height: auto;
  object-fit: cover;
}
.merch-card__body { padding: 0.35rem 1.85rem 1.85rem; }
.merch-card h3 { margin-bottom: 0.5rem; }
/* Stacked, not inline. At four across a card is ~250px, and "Shown in charcoal
   heather" won't sit beside its price — it wrapped in some cards and not others,
   which stepped the rows out of line. */
.merch-card__meta {
  display: flex; flex-direction: column; align-items: flex-start; gap: 0.1rem;
  margin-bottom: 0.85rem;
}
.merch-card__price {
  font-family: var(--font-display);
  font-size: 1.45rem; font-weight: 600;
  color: var(--walnut-deep);
}
.merch-card__note { font-size: 0.85rem; color: var(--muted); }
.merch-card p { color: var(--ink-soft); font-size: 0.96rem; }

/* The store does the selling, so the page ends on one shared call to action
   rather than a button in every card. */
.merch-cta { margin-top: 2.75rem; text-align: center; }

/* Only while the row is four wide. "Crew Neck Sweatshirt" is the one name that
   takes two lines at that width, and without this its price sits a line lower
   than the other three. At two-up and one-up the names all fit, so the reserved
   space would just be a gap. */
@media (min-width: 1025px) {
  .merch-card h3 { min-height: 2.3em; }
}

@media (max-width: 1024px) {
  .merch-grid { grid-template-columns: repeat(2, 1fr); gap: 1.25rem; }
}
@media (max-width: 640px) {
  .merch-grid { grid-template-columns: 1fr; }
}

/* -------- 21. Blog index -------- */
/* A LIBRARY, not a feed. The first version of this page was Wix's own layout
   in better type — a reverse-chronological list of thirteen identical rows —
   and the owner was right to reject it (2 Sep 2026). Two things drive the
   rebuild:

     - the blog stopped in March 2020, so a dated feed makes "nothing since
       2020" the loudest thing on the page;
     - the writing is evergreen, so subject is the useful axis, not date.

   Hence: one featured post, then groups from _data/blogTopics.js, with dates
   present but quiet. No thumbnails — see the note in blog.njk. */

/* Shared meta line: small caps, tan, pieces divided by a hairline pip. Used on
   the index, in each entry, and at the head of a post. */
.post-meta {
  display: flex; flex-wrap: wrap; align-items: baseline;
  gap: 0 0.55rem;
  font-size: 0.72rem; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--tan-deep);
  margin: 0 0 0.6rem;
}
.post-meta--center { justify-content: center; }
.post-meta > * + *::before {
  content: "\00b7"; margin-right: 0.55rem; color: var(--muted);
}
.post-meta time { color: var(--muted); }

/* ---- The featured post ---- */
.feature {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: clamp(1.75rem, 4vw, 3.25rem);
  align-items: center;
}
.feature__media {
  aspect-ratio: 3 / 2;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-md);
  background: var(--bone-deep);
}
.feature__media img { width: 100%; height: 100%; object-fit: cover; }
.feature h2 {
  font-size: clamp(1.8rem, 3.4vw, 2.6rem);
  margin: 0 0 0.75rem;
}
.feature h2 a { color: inherit; text-decoration: none; }
.feature h2 a::after { content: ""; position: absolute; inset: 0; }
.feature:hover h2 a { color: var(--russet); }
.feature h2 a:focus-visible { outline: none; }
.feature:has(h2 a:focus-visible) { outline: 3px solid var(--tan); outline-offset: 6px; }
.feature__excerpt {
  font-size: 1.075rem; line-height: 1.7;
  color: var(--ink-soft);
  margin: 0 0 1.25rem;
}
/* The whole card is already the link, so this is a visual affordance only —
   a nested <a> would be a second tab stop to the same place. */
.feature .link-arrow { pointer-events: none; }

@media (max-width: 900px) {
  .feature { grid-template-columns: 1fr; gap: 1.5rem; }
  .feature__media { aspect-ratio: 16 / 9; }
}

/* ---- Subject groups ---- */
.topic + .topic { margin-top: clamp(2.75rem, 6vw, 4.5rem); }
.topic__head {
  border-bottom: 2px solid var(--tan);
  padding-bottom: 0.85rem;
  margin-bottom: 0.5rem;
}
.topic__head h3 {
  font-size: clamp(1.35rem, 2.4vw, 1.75rem);
  margin: 0 0 0.3rem;
}
.topic__head p { color: var(--ink-soft); font-size: 0.96rem; margin: 0; }

/* Two columns of entries. Not cards: the site already uses boxes for priced
   products, and boxing free writing would read like a pricing grid (the same
   call as the testimonials in section 12). Hairlines instead. */
.topic__list {
  list-style: none; margin: 0; padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: clamp(1.5rem, 4vw, 3rem);
}
.entry {
  position: relative;
  padding: 1.6rem 0;
  border-bottom: 1px solid var(--line);
  transition: background-color 0.18s ease;
}
/* Warms rather than lifts — a row on a hairline has no edge to raise. The
   inset stretches the tint past the text so it doesn't look clipped. */
.entry:hover { background: var(--white); box-shadow: 0 0 0 0.9rem var(--white); }
.entry h4 {
  font-family: var(--font-display);
  font-size: 1.12rem; font-weight: 600; line-height: 1.25;
  color: var(--walnut-deep);
  margin: 0 0 0.4rem;
}
.entry h4 a { color: inherit; text-decoration: none; }
.entry h4 a::after { content: ""; position: absolute; inset: 0; }
.entry:hover h4 a { color: var(--russet); }
.entry h4 a:focus-visible { outline: none; }
.entry:has(h4 a:focus-visible) { outline: 3px solid var(--tan); outline-offset: -2px; }
.entry__excerpt {
  color: var(--ink-soft); font-size: 0.94rem; line-height: 1.6;
  margin: 0 0 0.7rem;
}
/* Date last and quiet: honest and good for search engines, but not the thing
   the page is organised around. */
.entry .post-meta { margin: 0; font-size: 0.68rem; }

@media (max-width: 760px) {
  .topic__list { grid-template-columns: 1fr; }
  .entry { padding: 1.35rem 0; }
  .entry:hover { box-shadow: 0 0 0 0.6rem var(--white); }
}

/* ---- "More on this", at the foot of a post ---- */
.more-posts {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.75rem;
}
.more-post { position: relative; border-top: 2px solid var(--tan); padding-top: 1.1rem; }
.more-post h3 { font-size: 1.1rem; margin: 0 0 0.45rem; }
.more-post h3 a { color: inherit; text-decoration: none; }
.more-post h3 a::after { content: ""; position: absolute; inset: 0; }
.more-post:hover h3 a { color: var(--russet); }
.more-post p { color: var(--ink-soft); font-size: 0.92rem; margin: 0 0 0.6rem; }
.more-post .post-meta { margin: 0; font-size: 0.68rem; }

@media (max-width: 760px) {
  .more-posts { grid-template-columns: 1fr; gap: 1.35rem; }
}

/* -------- 22. Article prose -------- */
/* The site's first long-form text. Every other page is hand-built sections, so
   nothing here existed before the blog: these rules style whatever Markdown
   produces, and they are the only place that has to cope with content the
   templates never see. */
.article__head {
  background: linear-gradient(180deg, var(--bone) 0%, var(--bone-deep) 100%);
  padding-block: clamp(2.75rem, 6vw, 4.25rem) clamp(2.25rem, 5vw, 3.25rem);
  text-align: center;
}
.article__head h1 {
  font-size: clamp(2rem, 4.4vw, 3rem);
  margin: 0;
}
.article__kicker {
  font-size: 0.72rem; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--tan-deep);
  margin: 0 0 0.9rem;
}
.article__kicker span + time::before {
  content: "\00b7"; margin: 0 0.55rem; color: var(--muted);
}
.article__byline {
  margin: 1rem 0 0;
  font-size: 0.9rem; color: var(--muted);
}

/* --deep, because .article__head ends on --bone-deep and bone against either
   of its neighbours is too close a step to read (see the section-background
   note in CLAUDE.md). White would read too, but a full page of body copy on
   pure white is harsher than the rest of this site. */
.article__body {
  padding-block: clamp(2.5rem, 6vw, 4rem);
}
.article {
  background: var(--bone-deep);
}
.article__head { background: linear-gradient(180deg, var(--bone) 0%, var(--bone-deep) 100%); }

/* Reading measure and rhythm. Slightly larger and looser than .lead — this is
   1,000 words at a time, not a two-line introduction. */
.article__body p,
.article__body li {
  font-size: 1.075rem;
  line-height: 1.78;
  color: var(--ink);
}
.article__body p { margin: 0 0 1.5rem; }
.article__body > p:first-child { margin-top: 0; }

.article__body h2,
.article__body h3 {
  margin: 2.75rem 0 1rem;
  font-size: clamp(1.25rem, 2.2vw, 1.55rem);
}
.article__body h2:first-child,
.article__body h3:first-child { margin-top: 0; }

.article__body ul,
.article__body ol { margin: 0 0 1.5rem; padding-left: 1.35rem; }
.article__body li { margin-bottom: 0.9rem; }
.article__body li::marker { color: var(--tan-deep); font-weight: 600; }

.article__body blockquote {
  margin: 2rem 0;
  padding-left: 1.5rem;
  border-left: 3px solid var(--tan);
  font-family: var(--font-display);
  font-size: 1.2rem; font-style: italic;
  color: var(--walnut-deep);
}
.article__body a { color: var(--russet); }

/* Images come from Markdown, so they carry no width/height. Leaving `width`
   unset means each one renders at its NATURAL size, capped here — which is
   what the step-by-step photos in "Tied-Off With Rose" need, since those
   originals are only ~250px wide and stretching them to the column would just
   make them blurry. Wide photos still fill the measure. */
.article__body img {
  max-width: min(100%, 640px);
  height: auto;
  margin: 2rem auto;
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}
.article__body p:has(> img) { margin-bottom: 0; text-align: center; }

/* Optional lead photograph. Sits between the header and the body, at the
   reading measure rather than full-bleed — this is an essay, not a magazine
   spread, and a full-width photo would overpower 600 words of text. */
.article__lead {
  margin: 0;
  padding-top: clamp(1.75rem, 4vw, 2.5rem);
}
/* No forced ratio and no cropping: the image keeps its own shape, scaled to
   fit the measure and capped in height so a tall portrait can't run off the
   screen before the writing starts. This matters for what comes NEXT — post
   photos will be taken on a phone, and a phone shoots portrait as often as
   landscape. A fixed 3:2 frame would throw half of those away. */
.article__lead img {
  display: block;
  width: auto; height: auto;
  max-width: 100%;
  max-height: 600px;
  margin-inline: auto;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}

/* Who wrote this. A reader arriving from a search result has no idea any of
   this connects to a working shop. */
.article__author {
  border-top: 1px solid var(--line);
  padding: 1.5rem 0;
  margin-bottom: 1.75rem;
}
.article__author p { color: var(--ink-soft); font-size: 0.97rem; margin: 0; }
.article__author strong { color: var(--walnut-deep); }
.article__back { padding-bottom: clamp(2.5rem, 6vw, 4rem); margin: 0; }

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