/* Alma Spirit Inspired — the design system, second edition (editorial).
   Every colour is from the Alma Brand Board, exactly:
   Sand #EDE8D8 · Gray #CCC5BC · Clay #AB8E69 · Dirt #77624C
   Brick #B24A3B · Mustard #F8B935 · Cactus Green #778B55 · Blue #406E8B
   Alma Black #242121. Paper #F6EFE9 is the guidelines' lightest tone.
   No true white anywhere — Heidi's standing rule.

   The idea: a printed art catalogue, not a brochure. Photographs are set at
   different sizes and stagger instead of sitting in a column. Copy is short
   and set large. One dark "cellar" band per page. Nothing overlaps anything
   that has to be read. Photo slots that are still empty draw themselves as
   labelled frames so the page holds its shape before the shoot. */

:root {
  color-scheme: light;
  --sand: #ede8d8;
  --paper: #f6efe9;
  --gray: #ccc5bc;
  --clay: #ab8e69;
  --dirt: #77624c;
  --brick: #b24a3b;
  --brick-deep: #8d382c;
  --mustard: #f8b935;
  --cactus: #778b55;
  --blue: #406e8b;
  --alma-black: #242121;

  --bg: var(--sand);
  --bg-raise: var(--paper);
  --bg-sink: var(--gray);
  --fg: var(--alma-black);
  --fg-soft: #3b3330;
  --muted: var(--dirt);
  --line: rgba(36, 33, 33, 0.16);
  --line-strong: rgba(36, 33, 33, 0.34);
  --red: var(--brick);
  --red-deep: var(--brick-deep);
  --ember: #a8724a;
  --glow: rgba(178, 74, 59, 0.12);

  /* The cellar band: Alma Black ground, Sand type. */
  --cellar-bg: var(--alma-black);
  --cellar-fg: var(--sand);
  --cellar-muted: var(--gray);
  --cellar-line: rgba(237, 232, 216, 0.18);

  --header: "Cousine", ui-monospace, "Courier New", Courier, monospace;
  --body: "Courier Prime", "Cousine", ui-monospace, "Courier New", Courier, monospace;
  --serif: var(--header);
  --sans: var(--body);

  --s1: 0.25rem;
  --s2: 0.5rem;
  --s3: 0.75rem;
  --s4: 1rem;
  --s5: 1.5rem;
  --s6: 2rem;
  --s7: 3rem;
  --s8: 4.5rem;
  --s9: 6.5rem;
  --gutter: clamp(var(--s5), 5vw, var(--s9));
  --rhythm: clamp(56px, 8vw, 128px);
  --rhythm-tight: clamp(32px, 4vw, 64px);
  --col-gap: clamp(var(--s5), 4vw, var(--s8));
  --radius: 2px;
  --maxw: 84rem;
  --measure: 58ch;
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

html {
  background: var(--bg);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--fg-soft);
  font-family: var(--body);
  font-size: 1rem;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
}

#siteScroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}

::selection {
  background: var(--red);
  color: var(--sand);
}

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

a {
  color: var(--fg);
}

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

h1,
h2,
h3,
h4 {
  font-family: var(--header);
  font-weight: 400;
  color: var(--fg);
  margin: 0;
  line-height: 1.15;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

h2 {
  font-size: clamp(1.7rem, 3.2vw, 2.6rem);
}

h3 {
  font-size: 1.25rem;
  letter-spacing: -0.01em;
}

p {
  margin: 0;
}

p + p {
  margin-top: var(--s4);
}

p,
li,
h1,
h2,
h3,
h4,
dt,
dd,
figcaption {
  overflow-wrap: break-word;
}

.skip-link {
  position: absolute;
  left: -999rem;
  top: var(--s4);
}

.skip-link:focus {
  left: var(--s4);
  z-index: 40;
  background: var(--bg-raise);
  color: var(--fg);
  padding: var(--s2) var(--s3);
  border-radius: var(--radius);
}

/* ---- Announcement bar + header. The whole menu is always visible; on a
   phone it wraps beneath the mark instead of hiding behind a button. ---- */

/* The announcement bar: Alma Black under a woven, fibre-like grain (two
   directions of fine noise, like linen), so it reads as cloth, not a hard
   black stripe. */
.announce {
  background-color: var(--cellar-bg);
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='w'><feTurbulence type='fractalNoise' baseFrequency='0.02 0.9' numOctaves='2' seed='7' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.93 0 0 0 0 0.91 0 0 0 0 0.85 0 0 0 0.22 0'/></filter><rect width='100%25' height='100%25' filter='url(%23w)'/></svg>"),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='v'><feTurbulence type='fractalNoise' baseFrequency='0.9 0.02' numOctaves='2' seed='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.67 0 0 0 0 0.56 0 0 0 0 0.41 0 0 0 0.16 0'/></filter><rect width='100%25' height='100%25' filter='url(%23v)'/></svg>");
  background-repeat: repeat;
  color: var(--cellar-fg);
  font-family: var(--header);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-align: center;
  padding: var(--s2) var(--gutter);
  line-height: 1.5;
}

.announce a {
  color: var(--mustard);
  text-decoration: none;
  border-bottom: 1px solid currentColor;
}

.site-header {
  position: relative;
  z-index: 5;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s4) var(--s6);
  padding: var(--s4) var(--gutter);
  background: var(--bg);
  border-bottom: 1px solid var(--line);
  transition: padding 0.35s var(--ease);
}

.site-header[data-condensed] {
  padding-block: var(--s2);
}

.brand {
  display: inline-block;
  line-height: 0;
  border-radius: var(--radius);
}

.brand-mark {
  height: 3.2rem;
  width: auto;
  transition: height 0.35s var(--ease);
}

.site-header[data-condensed] .brand-mark {
  height: 2.3rem;
}

.site-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--s1) clamp(var(--s4), 2vw, var(--s6));
}

.site-link {
  color: var(--fg-soft);
  text-decoration: none;
  white-space: nowrap;
  font-family: var(--header);
  font-size: 0.74rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: var(--s1) 0;
  border-bottom: 1px solid transparent;
  transition: color 0.2s, border-color 0.2s;
}

.site-link:hover {
  color: var(--fg);
  border-bottom-color: var(--line-strong);
}

.site-link[aria-current="page"] {
  color: var(--fg);
  border-bottom-color: var(--red);
}

.menu-button {
  display: none;
}

@media (max-width: 760px) {
  .site-header {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--s3);
  }

  .site-nav {
    justify-content: flex-start;
    gap: var(--s1) var(--s4);
  }

  .site-link {
    font-size: 0.7rem;
    letter-spacing: 0.12em;
  }
}

/* ---- Layout and rhythm ---- */

.wrap {
  width: min(100% - 2 * var(--gutter), var(--maxw));
  margin-inline: auto;
}

.wrap-narrow {
  width: min(100% - 2 * var(--gutter), 60rem);
  margin-inline: auto;
}

.section {
  padding-block: var(--rhythm);
}

.section-tight {
  padding-block: var(--rhythm-tight);
}

.section-sink {
  background: var(--bg-sink);
  --muted: var(--fg-soft);
  --line: rgba(36, 33, 33, 0.24);
}

.section-raise {
  background: var(--bg-raise);
}

.hero-grid > *,
.row > *,
.menu-layout > *,
.form-layout > *,
.experience > *,
.site-header > *,
.spread > *,
.index > * {
  min-width: 0;
}

/* ---- Type roles ---- */

.eyebrow {
  font-family: var(--header);
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: var(--s4);
  display: flex;
  align-items: center;
  gap: var(--s3);
}

.eyebrow::before {
  content: "";
  width: 1.75rem;
  height: 1px;
  background: var(--red);
  flex: none;
}

.eyebrow-plain::before {
  display: none;
}

.display {
  font-size: clamp(2.4rem, 6.4vw, 5.4rem);
  line-height: 1.02;
  letter-spacing: -0.035em;
}

.title {
  font-size: clamp(2rem, 4.8vw, 3.8rem);
  line-height: 1.06;
  letter-spacing: -0.03em;
}

.statement {
  font-family: var(--header);
  font-size: clamp(1.5rem, 3vw, 2.5rem);
  line-height: 1.22;
  letter-spacing: -0.02em;
  color: var(--fg);
  text-wrap: balance;
}

.lede {
  font-size: clamp(1.05rem, 1.5vw, 1.25rem);
  line-height: 1.6;
  color: var(--fg);
  margin-top: var(--s5);
  max-width: 44ch;
}

.sub {
  font-family: var(--header);
  font-size: 1.15rem;
  line-height: 1.45;
  color: var(--fg);
  margin-top: var(--s4);
}

.gift-sub {
  font-size: clamp(1.3rem, 2.2vw, 1.8rem);
  color: var(--red);
  margin-top: var(--s4);
  margin-bottom: var(--s5);
}

.motto {
  font-style: italic;
  font-size: 1.1rem;
  color: var(--ember);
  margin-top: var(--s5);
}

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

.prose + .prose,
.prose + .actions,
.prose + .rows,
.prose + .note {
  margin-top: var(--s5);
}

.prose-lg p {
  font-family: var(--header);
  font-size: clamp(1.15rem, 1.7vw, 1.45rem);
  line-height: 1.45;
  color: var(--fg);
}

.prose-lg p + p {
  margin-top: var(--s5);
}

.prose-center {
  max-width: 58ch;
  margin-inline: auto;
  text-align: center;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3);
  margin-top: var(--s6);
}

.note {
  color: var(--muted);
  font-size: 0.95rem;
  border-left: 2px solid var(--red);
  padding-left: var(--s4);
  max-width: var(--measure);
}

.deadline {
  font-family: var(--header);
  font-size: 1.15rem;
  color: var(--red);
  margin-top: var(--s5);
}

.caption {
  font-size: 0.82rem;
  letter-spacing: 0.04em;
  color: var(--muted);
  margin-top: var(--s2);
}

/* ---- Controls ---- */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  padding: 0.9rem 1.6rem;
  border-radius: var(--radius);
  border: 1px solid var(--fg);
  background: transparent;
  color: var(--fg);
  font: 400 0.8rem var(--header);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.25s, border-color 0.25s, color 0.25s;
}

.button:hover {
  background: var(--fg);
  color: var(--sand);
}

.button-primary {
  background: var(--red);
  border-color: var(--red);
  color: var(--sand);
}

.button-primary:hover {
  background: var(--red-deep);
  border-color: var(--red-deep);
  color: var(--sand);
}

.text-link {
  color: var(--red);
  text-decoration: none;
  font-family: var(--header);
  font-size: 0.78rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  border-bottom: 1px solid currentColor;
  padding-bottom: 2px;
}

.text-link:hover {
  color: var(--fg);
}

/* ---- Photographs and the slots waiting for them ----
   .photo is the frame. With an image it shows the image at the ratio the
   slot asks for. Without one it draws a labelled placeholder: a dashed
   frame in Clay, the slot's name, and a small hand-drawn sun. Fill the slot
   in content.json and the placeholder disappears. */

.photo {
  position: relative;
  margin: 0;
  aspect-ratio: var(--ratio, 4 / 5);
  max-width: 100%;
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--bg-sink);
}

.photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--pos, center center);
}

.photo-empty {
  border: 1px dashed var(--clay);
  background:
    linear-gradient(135deg, transparent 0 46%, rgba(171, 142, 105, 0.22) 46% 54%, transparent 54%),
    var(--bg-sink);
}

.cellar .photo-empty {
  background:
    linear-gradient(135deg, transparent 0 46%, rgba(237, 232, 216, 0.12) 46% 54%, transparent 54%),
    rgba(237, 232, 216, 0.06);
  border-color: var(--cellar-muted);
}

.photo-label {
  position: absolute;
  left: var(--s4);
  bottom: var(--s4);
  right: var(--s4);
  font-family: var(--header);
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fg);
  line-height: 1.5;
}

.cellar .photo-label {
  color: var(--cellar-muted);
}

.photo-label small {
  display: block;
  font-size: 0.66rem;
  letter-spacing: 0.1em;
  text-transform: none;
}

.photo-sun {
  position: absolute;
  top: var(--s4);
  right: var(--s4);
  width: 1.6rem;
  aspect-ratio: 1;
  background: var(--mustard);
  border-radius: 56% 44% 49% 51% / 47% 53% 47% 53%;
  opacity: 0.85;
}

.photo figcaption {
  position: absolute;
  left: var(--s3);
  bottom: var(--s3);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sand);
  background: rgba(36, 33, 33, 0.6);
  padding: var(--s1) var(--s2);
  border-radius: var(--radius);
}

/* ---- The hero: full-bleed photograph, the mark and one sentence ---- */

.hero {
  position: relative;
  overflow: hidden;
}

.hero-bleed {
  display: grid;
}

.hero-bleed > * {
  grid-area: 1 / 1;
}

/* The photograph is a full-width band on its own, seen whole; the words sit
   beneath it on Sand. Nothing is laid over the picture. */
.hero-bleed .photo {
  aspect-ratio: auto;
  height: min(62vh, 38rem);
  min-height: 16rem;
  border-radius: 0;
}

.hero-bleed .photo-empty {
  border-width: 0 0 1px;
  border-style: solid;
}

.hero-bleed .photo-label {
  bottom: auto;
  top: var(--s4);
  right: auto;
}

.hero-bleed .photo-sun {
  top: auto;
  bottom: var(--s5);
}

.hero-veil {
  display: none;
}

/* The carousel: the photographs stacked in one frame, one showing at a time,
   crossfading slowly. Each slide keeps its own focal point (--pos). */
.hero-slides {
  position: relative;
  height: min(62vh, 38rem);
  min-height: 16rem;
  overflow: hidden;
  background: var(--bg-sink);
}

.hero-bleed .hero-slide {
  position: absolute;
  inset: 0;
  height: 100%;
  min-height: 0;
  margin: 0;
  opacity: 0;
  transition: opacity 1.6s var(--ease);
}

.hero-bleed .hero-slide.is-on {
  opacity: 1;
}

/* Every photograph is shown whole, at full height; the same picture, blurred
   and dimmed, fills whatever the frame has left over at the sides. */
.hero-bleed .hero-slide .hero-slide-bg {
  position: absolute;
  inset: -6%;
  width: 112%;
  height: 112%;
  object-fit: cover;
  object-position: var(--pos, center center);
  filter: blur(26px) saturate(0.85) brightness(0.72);
}

/* The photograph itself is sized to fit and centred, and its four edges are
   feathered into the blurred ground so the two read as one picture. */
.hero-bleed .hero-slide {
  display: flex;
  align-items: center;
  justify-content: var(--align, center);
}

@media (max-width: 760px) {
  .hero-bleed .hero-slide {
    justify-content: center;
  }
}

/* A slide marked "fit: cover" is widened to fill the whole frame instead. */
.hero-bleed .hero-slide-wide .hero-slide-img {
  width: 100% !important;
  height: 100% !important;
  object-fit: cover !important;
  object-position: var(--pos, center center) !important;
}

.hero-bleed .hero-slide .hero-slide-img {
  position: relative;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  -webkit-mask-image:
    linear-gradient(to right, transparent, #000 9%, #000 91%, transparent),
    linear-gradient(to bottom, transparent, #000 9%, #000 91%, transparent);
  mask-image:
    linear-gradient(to right, transparent, #000 9%, #000 91%, transparent),
    linear-gradient(to bottom, transparent, #000 9%, #000 91%, transparent);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}

@media (max-width: 760px) {
  .hero-slides {
    height: min(52vh, 24rem);
  }

  .hero-bleed .hero-slides .hero-slide {
    height: 100%;
    min-height: 0;
    max-height: none;
    aspect-ratio: auto;
  }
}

.hero-copy {
  grid-area: 2 / 1;
  position: relative;
  width: 100%;
  padding: var(--rhythm-tight) var(--gutter);
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}

.hero-copy .display {
  color: var(--fg);
  max-width: 14ch;
}

/* The real mark: al ma on its yellow sun, from the brand kit. On wide screens
   it sits in the soft left band of the carousel, clear of the photograph;
   on phones it heads the copy instead. */
.hero-logo {
  width: clamp(8.5rem, 15vw, 12.5rem);
  height: auto;
}

.hero-logo-over {
  position: absolute;
  left: calc(var(--gutter) * 0.55);
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  width: clamp(10rem, 19vw, 17.5rem);
  filter: drop-shadow(0 6px 18px rgba(36, 33, 33, 0.35));
}

.hero-logo-inline {
  display: none;
  margin-bottom: var(--s5);
}

.hero-copy .eyebrow {
  font-size: 1.44rem;
  letter-spacing: 0.14em;
}

.hero-copy .display {
  font-size: clamp(3rem, 8vw, 7rem);
}

.hero-copy .lede {
  margin-top: var(--s2);
}

@media (max-width: 760px) {
  .hero-logo-over {
    display: none;
  }

  .hero-logo-inline {
    display: block;
  }

  .hero-copy .eyebrow {
    font-size: 1.05rem;
  }
}

@media (max-width: 760px) {
  .hero-bleed .photo {
    height: auto;
    min-height: 16rem;
    max-height: 52vh;
    aspect-ratio: 4 / 3;
  }
}

/* The hero on inner pages: a statement set large, a photograph offset below
   and to the right so it crosses into the next band. */

.hero-inner {
  padding-top: var(--rhythm-tight);
}

.hero-inner .title {
  max-width: 16ch;
}

.hero-inner .lede {
  max-width: 50ch;
}

.hero-offset {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: var(--col-gap);
  align-items: end;
}

.hero-offset .photo {
  --ratio: 4 / 5;
  margin-bottom: calc(var(--rhythm) * -0.75);
  position: relative;
  z-index: 2;
}

.hero-offset + .section {
  padding-top: calc(var(--rhythm) * 0.75 + var(--rhythm-tight));
}

/* Photo level with the text (Gift Concierge) */
.hero-offset.hero-level {
  align-items: start;
}

.hero-offset.hero-level .photo {
  margin-bottom: 0;
  margin-top: 0;
}

.hero-offset.hero-level + .section {
  padding-top: calc(var(--rhythm-tight) * 2);
}

@media (max-width: 760px) {
  .hero-offset {
    grid-template-columns: 1fr;
  }

  .hero-offset.hero-level .photo {
    margin-top: var(--rhythm-tight);
    margin-bottom: 0;
  }

  .hero-offset .photo {
    --ratio: 16 / 10;
    margin-bottom: calc(var(--rhythm-tight) * -1);
    width: 88%;
    margin-left: auto;
  }

  .hero-offset + .section {
    padding-top: calc(var(--rhythm-tight) * 2);
  }
}

/* ---- The mark with its sun ---- */

.brand-stage {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--s5);
  width: fit-content;
  max-width: 100%;
  margin-bottom: var(--s6);
}

/* The sun stands beside the wordmark, never behind it, so every letter reads. */
.brand-sun {
  flex: none;
  width: clamp(3.5rem, 6vw, 5rem);
  aspect-ratio: 1;
  background: var(--mustard);
  border-radius: 56% 44% 49% 51% / 47% 53% 47% 53%;
  opacity: 0.95;
  pointer-events: none;
  position: relative;
}

.brand-sun::after {
  content: "";
  position: absolute;
  inset: -38%;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(248, 185, 53, 0.4), transparent 72%);
}

/* The wordmark is carried as a luminance mask (white letterforms on black)
   so it takes its colour from the page and stays exact at any size. */
.brand-lockup {
  position: relative;
  z-index: 1;
  display: block;
  width: clamp(12rem, 24vw, 19rem);
  aspect-ratio: 560 / 443;
  background-color: var(--red);
  -webkit-mask-source-type: luminance;
  mask-mode: luminance;
  -webkit-mask-image: url("/_next/image?url=https%3A%2F%2Flovable-crab-328.convex.cloud%2Fapi%2Fstorage%2F1bd799a7-9e5a-4385-8660-6741e4469082&w=1920&q=75");
  mask-image: url("/_next/image?url=https%3A%2F%2Flovable-crab-328.convex.cloud%2Fapi%2Fstorage%2F1bd799a7-9e5a-4385-8660-6741e4469082&w=1920&q=75");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}

[data-arrived] .brand-sun {
  animation: sunrise 9s ease-in-out infinite alternate;
}

@keyframes sunrise {
  from {
    transform: scale(0.96);
    opacity: 0.82;
  }
  to {
    transform: scale(1.04);
    opacity: 1;
  }
}

.brand-stage-small {
  margin-inline: auto;
  margin-bottom: var(--s7);
}

.brand-stage-small .brand-lockup {
  width: clamp(11rem, 22vw, 15rem);
}

.brand-stage-small .brand-sun {
  width: clamp(2.5rem, 5vw, 3.5rem);
}

/* ---- The welcome statement under the hero: words only, set narrow ---- */

.named {
  padding-top: var(--rhythm-tight);
}

.named .statement {
  font-size: clamp(1.9rem, 3.8vw, 3.2rem);
  font-weight: 700;
  max-width: none;
  text-wrap: initial;
}

.named .sub {
  max-width: 52ch;
}

.named .prose {
  max-width: 70ch;
}

#name-heading {
  font-weight: 400;
  font-size: clamp(1.7rem, 3.2vw, 2.6rem);
}

/* ---- Our story: the founders, then the pillars ---- */

/* Catherine on the left, Heidi on the right: each a column of photograph,
   name, and story. */
.founders {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--rhythm-tight) var(--col-gap);
  align-items: start;
  margin-top: var(--s7);
}

.founder {
  display: grid;
  gap: var(--s5);
  align-content: start;
}

.founder > * {
  min-width: 0;
}

.founder-photo {
  --ratio: 4 / 5;
}

.founder-copy h2 {
  font-size: clamp(1.6rem, 2.6vw, 2.2rem);
}

.founder-role {
  font-family: var(--header);
  font-size: 0.78rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--red);
  margin: var(--s2) 0 var(--s5);
}

.founder-copy .prose {
  max-width: 62ch;
}

/* Why handmade: the pillar photographs sit smaller beside short copy,
   and the text starts at the top of its photo rather than the middle. */
.route-why-handmade .founder-photo {
  max-width: 19rem;
}
@media (min-width: 761px) {
  .route-why-handmade .founder {
    grid-template-columns: minmax(0, 0.6fr) minmax(0, 1.4fr);
    align-items: start;
  }
  .route-why-handmade .founder-reverse .founder-photo {
    justify-self: end;
  }
}

.pillars {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
  gap: var(--col-gap);
  margin-top: var(--s7);
}

.pillar h3 {
  font-size: 1.35rem;
  margin-bottom: var(--s3);
}

.pillar p {
  max-width: 52ch;
}

/* Three across on a wide screen, one under another on a phone. */
.pillars-three {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(var(--s5), 3vw, var(--s8));
}

.pillars-three .pillar p {
  max-width: none;
}

/* The mission: each column opens with a small sun. */
.pillars-sun .pillar::before {
  content: "";
  display: block;
  width: 1.6rem;
  aspect-ratio: 1;
  background: var(--mustard);
  border-radius: 56% 44% 49% 51% / 47% 53% 47% 53%;
  margin-bottom: var(--s4);
}

/* The impact: each column opens with a brick rule. */
.pillars-ruled .pillar {
  border-top: 2px solid var(--red);
  padding-top: var(--s4);
}

/* The vision in the cellar band: the statement and its paragraph on the
   left, the two worlds stacked on the right under mustard rules. */
.vision {
  display: grid;
  grid-template-columns: minmax(0, 6fr) minmax(0, 5fr);
  gap: var(--col-gap);
  align-items: start;
}

.vision > * {
  min-width: 0;
}

.vision-intro {
  margin-top: var(--s5);
  max-width: 56ch;
  font-size: 1.05rem;
}

.vision-worlds {
  display: grid;
  gap: var(--s6);
  padding-top: var(--s7);
}

.vision-worlds .pillar {
  border-top: 1px solid var(--mustard);
  padding-top: var(--s4);
}

.vision-worlds .pillar h3 {
  color: var(--mustard);
  font-size: 1.2rem;
}

.vision-worlds .pillar p {
  max-width: none;
}

@media (max-width: 860px) {
  .pillars-three,
  .vision {
    grid-template-columns: 1fr;
  }

  .vision-worlds {
    padding-top: 0;
  }
}

.prose-wide {
  max-width: 72ch;
  margin-top: var(--s5);
  font-size: 1.05rem;
}

.route-story .hero-inner .title {
  max-width: 20ch;
}

@media (max-width: 760px) {
  .founders {
    grid-template-columns: 1fr;
    gap: var(--rhythm);
  }

  .founder-photo {
    max-width: 24rem;
  }
}

/* ---- The story band: a statement beside a stagger of photographs ----
   Three frames at three sizes that step down and across the band without
   ever covering one another. */

.story {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: var(--col-gap);
  align-items: start;
}

.story-copy {
  position: sticky;
  top: var(--s6);
}

.stagger {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  grid-auto-rows: minmax(0, auto);
  gap: var(--s4);
}

.stagger .photo:nth-child(1) {
  grid-column: 1 / 9;
  grid-row: 1 / 3;
  --ratio: 4 / 5;
}

.stagger .photo:nth-child(2) {
  grid-column: 9 / 13;
  grid-row: 2 / 4;
  --ratio: 1 / 1;
  align-self: start;
  margin-top: var(--s7);
}

.stagger .photo:nth-child(3) {
  grid-column: 3 / 8;
  grid-row: 3 / 5;
  --ratio: 5 / 4;
  margin-top: var(--s5);
}

.story-reverse {
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
}

.story-reverse .story-copy {
  order: 2;
}

@media (max-width: 860px) {
  .story,
  .story-reverse {
    grid-template-columns: 1fr;
  }

  .story-copy,
  .story-reverse .story-copy {
    position: static;
    order: 0;
  }
}

/* ---- The cellar band: one per page, Alma Black, a quotation set large ---- */

.cellar {
  background: var(--cellar-bg);
  color: var(--cellar-fg);
  --fg: var(--cellar-fg);
  --fg-soft: var(--cellar-fg);
  --muted: var(--cellar-muted);
  --line: var(--cellar-line);
  --line-strong: rgba(237, 232, 216, 0.4);
  --bg: var(--cellar-bg);
  --bg-raise: #2f2a29;
  --bg-sink: #1c1919;
  position: relative;
  overflow: hidden;
}

.cellar::before {
  content: "";
  position: absolute;
  left: -10%;
  right: -10%;
  bottom: -40%;
  height: 80%;
  background: radial-gradient(50% 60% at 50% 100%, rgba(178, 74, 59, 0.28), transparent 70%);
  pointer-events: none;
}

[data-arrived] .cellar::before {
  animation: candle 7s ease-in-out infinite alternate;
}

@keyframes candle {
  from {
    opacity: 0.55;
  }
  to {
    opacity: 1;
  }
}

.cellar .wrap,
.cellar .wrap-narrow {
  position: relative;
}

.cellar .eyebrow::before {
  background: var(--mustard);
}

.cellar .button {
  border-color: var(--sand);
  color: var(--sand);
}

.cellar .button:hover {
  background: var(--sand);
  color: var(--alma-black);
}

.cellar .text-link {
  color: var(--mustard);
}

.cellar .text-link:hover {
  color: var(--sand);
}

.quote {
  font-family: var(--body);
  font-style: italic;
  font-size: clamp(1.4rem, 3.2vw, 2.6rem);
  line-height: 1.3;
  max-width: 36ch;
  color: var(--cellar-fg);
  text-wrap: balance;
}

.quote-mark {
  display: block;
  font-family: var(--header);
  font-style: normal;
  font-size: 4rem;
  line-height: 0.6;
  color: var(--red);
  margin-bottom: var(--s5);
}

.quote-by + .prose {
  margin-top: var(--s6);
}

.quote-by {
  margin-top: var(--s6);
  font-family: var(--header);
  font-size: 0.74rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--cellar-muted);
}

.cellar-grid {
  display: grid;
  grid-template-columns: minmax(0, 8fr) minmax(0, 4fr);
  gap: var(--col-gap);
  align-items: center;
}

.route-home .cellar {
  padding-top: var(--rhythm-tight);
}

.route-home .cellar .prose {
  max-width: 68ch;
}

.quote-by-link {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid var(--mustard);
  padding-bottom: 2px;
}

.quote-by-link:hover {
  color: var(--mustard);
}

.cellar-grid .photo {
  --ratio: 4 / 5;
  width: 78%;
  margin-left: auto;
}

@media (max-width: 860px) {
  .cellar-grid {
    grid-template-columns: 1fr;
  }

  .cellar-grid .photo {
    width: 70%;
    margin-inline: auto 0;
  }
}

/* ---- The index: the ways in, as one tall photograph and a list ---- */

.index {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: var(--col-gap);
  align-items: start;
}

.index-photo {
  position: sticky;
  top: var(--s6);
  --ratio: 3 / 4;
}

.index-list {
  display: grid;
  border-top: 1px solid var(--line);
}

.index-item {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
  gap: var(--s5);
  padding-block: var(--s6);
  border-bottom: 1px solid var(--line);
  align-items: start;
}

.index-item h3 {
  font-size: clamp(1.4rem, 2.4vw, 1.9rem);
}

.index-item .index-meta {
  color: var(--muted);
  font-size: 0.92rem;
  margin-top: var(--s3);
}

.index-item .text-link {
  display: inline-block;
  margin-top: var(--s4);
}

@media (max-width: 860px) {
  .index {
    grid-template-columns: 1fr;
  }

  .index-photo {
    position: static;
    --ratio: 16 / 9;
  }

  .index-item {
    grid-template-columns: 1fr;
    gap: var(--s3);
  }
}

/* ---- The spread: two photographs and a short text between them ---- */

.spread {
  display: grid;
  grid-template-columns: minmax(0, 4fr) minmax(0, 4fr) minmax(0, 4fr);
  gap: var(--col-gap);
  align-items: center;
}

.spread .photo:first-child {
  --ratio: 3 / 4;
}

.spread .photo:last-child {
  --ratio: 1 / 1;
  margin-top: var(--s8);
}

.spread-copy .prose {
  max-width: 34ch;
}

@media (max-width: 860px) {
  .spread {
    grid-template-columns: 1fr 1fr;
  }

  .spread-copy {
    grid-column: 1 / -1;
    order: -1;
  }

  .spread .photo:last-child {
    margin-top: var(--s6);
  }
}

/* ---- The tagline strip ---- */

.strip {
  border-block: 1px solid var(--line);
  padding-block: var(--s5);
  font-family: var(--header);
  font-size: clamp(0.85rem, 1.6vw, 1.1rem);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--fg);
  text-align: center;
  overflow: hidden;
  white-space: nowrap;
}

.strip span + span::before {
  content: "\2609";
  color: var(--mustard);
  margin-inline: var(--s5);
}

@media (max-width: 760px) {
  .strip {
    white-space: normal;
    line-height: 2;
  }
}

/* ---- The signup band on every page ---- */

.signup {
  display: grid;
  grid-template-columns: minmax(0, 6fr) minmax(0, 6fr);
  gap: var(--col-gap);
  align-items: center;
}

.signup .statement {
  max-width: 18ch;
}

@media (max-width: 860px) {
  .signup {
    grid-template-columns: 1fr;
  }
}

/* ---- Cards (used sparingly now) ---- */

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: var(--s5);
}

.card {
  display: flex;
  flex-direction: column;
  gap: var(--s3);
  padding: var(--s6);
  background: var(--bg-raise);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.section-raise .card {
  background: var(--bg);
}

.card-heading {
  font-size: 1.55rem;
}

.card-meta {
  color: var(--muted);
  font-size: 0.95rem;
}

.card .text-link {
  margin-top: auto;
  align-self: flex-start;
  padding-top: var(--s3);
}

/* ---- Rows (hours, facts) ---- */

.rows {
  display: grid;
  border-top: 1px solid var(--line);
}

.row {
  display: grid;
  grid-template-columns: minmax(0, 12rem) minmax(0, 1fr);
  gap: var(--s4);
  padding-block: var(--s4);
  border-bottom: 1px solid var(--line);
}

.row-key {
  font-family: var(--header);
  font-size: 1.1rem;
  color: var(--fg);
}

.row-value {
  color: var(--fg-soft);
}

@media (max-width: 600px) {
  .row {
    grid-template-columns: 1fr;
    gap: var(--s1);
  }
}

/* ---- The week (Visit): every day once, set large, one link each ---- */

.week {
  margin-top: var(--s7);
  border-top: 1px solid var(--line);
}

.week-item {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: var(--col-gap);
  padding-block: var(--s6);
  border-bottom: 1px solid var(--line);
  align-items: start;
}

.week-item > * {
  min-width: 0;
}

.week-when {
  font-size: clamp(1.7rem, 3.2vw, 2.6rem);
  max-width: 14ch;
}

.week-note {
  font-family: var(--header);
  font-size: clamp(1rem, 1.6vw, 1.25rem);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--red);
  margin-top: var(--s3);
}

.week-title {
  font-family: var(--header);
  font-size: clamp(1.25rem, 2vw, 1.6rem);
  line-height: 1.3;
  color: var(--fg);
}

.week-text {
  max-width: var(--measure);
  margin-top: var(--s3);
}

.week-what .text-link {
  display: inline-block;
  margin-top: var(--s4);
}

.week-actions {
  margin-top: var(--s7);
}

@media (max-width: 760px) {
  .week-item {
    grid-template-columns: 1fr;
    gap: var(--s3);
  }
}

/* ---- Shop, while the online shop is still to come ---- */

.shop-note {
  max-width: 60ch;
}

.hero-inner .shop-title {
  max-width: none;
}

.shop-note .text-link {
  font-size: inherit;
  letter-spacing: 0;
  text-transform: none;
  font-family: inherit;
}

.shop-photo {
  padding-bottom: var(--rhythm);
}

/* The one photograph on the Shop page is shown whole, at its own shape,
   centred and generous — never cropped. */
.photo-wide {
  aspect-ratio: auto;
  width: min(100%, 44rem);
  margin-inline: auto;
}

.photo-wide img {
  height: auto;
  object-fit: contain;
}

/* The footer: one horizontal line of links (the same pages as the header,
   then Open in Maps, Instagram, Pinterest), and the base line beneath it. */
.footer-line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s2) clamp(var(--s4), 2vw, var(--s6));
  font-family: var(--header);
  font-size: 0.74rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.footer-line a {
  white-space: nowrap;
  padding: var(--s1) 0;
  border-bottom: 1px solid transparent;
}

.footer-line a:hover {
  border-bottom-color: var(--line-strong);
}

.footer-sep {
  width: 1px;
  height: 1rem;
  background: var(--line-strong);
}

.footer-base {
  margin-top: var(--s4);
  padding-top: var(--s4);
}

@media (max-width: 760px) {
  .footer-sep {
    display: none;
  }
}

/* ---- Menu ---- */

.menu-layout {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(var(--s6), 6vw, var(--s9));
  align-items: start;
}

.menu-side {
  position: sticky;
  top: var(--s6);
}

.menu-side .photo {
  --ratio: 4 / 5;
}

.menu-group + .menu-group {
  margin-top: var(--s7);
}

.menu-heading {
  font-family: var(--header);
  font-size: 0.74rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--red);
  margin-bottom: var(--s3);
}

.menu-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--line);
}

.menu-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--s4);
  padding-block: var(--s3);
  border-bottom: 1px solid var(--line);
}

.menu-name {
  font-family: var(--header);
  font-size: 1.15rem;
  color: var(--fg);
}

.menu-price {
  font-variant-numeric: tabular-nums;
  color: var(--fg-soft);
  flex: none;
}

@media (max-width: 860px) {
  .menu-layout {
    grid-template-columns: 1fr;
  }

  .menu-side {
    position: static;
  }
}

/* ---- Events ---- */

.events {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: var(--s5);
}

.event {
  display: flex;
  flex-direction: column;
  gap: var(--s3);
  padding: var(--s5);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg-raise);
}

.section-raise .event {
  background: var(--bg);
}

.event .photo {
  --ratio: 4 / 5;
}

.event-title {
  font-family: var(--header);
  font-weight: 700;
  font-size: clamp(1.35rem, 2.4vw, 1.75rem);
  letter-spacing: -0.01em;
  line-height: 1.15;
  margin: 0;
}

.event-sub {
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--dirt);
  margin: calc(var(--s2) * -1) 0 calc(var(--s2) * -1);
  max-width: 34ch;
}

/* Events: let the sand breathe, then melt into the dark Mondays band */
.route-gather .cellar {
  margin-top: var(--rhythm-tight);
  padding-top: calc(var(--rhythm) * 0.9);
}

.route-gather .cellar::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: clamp(5rem, 11vw, 9rem);
  background: linear-gradient(to bottom, #ede8d8 0%, rgba(120, 104, 90, 0.55) 45%, rgba(36, 33, 33, 0) 100%);
  pointer-events: none;
  z-index: 0;
}

.route-gather .cellar .cellar-fade-bottom {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: clamp(5rem, 11vw, 9rem);
  background: linear-gradient(to top, #ede8d8 0%, rgba(120, 104, 90, 0.55) 45%, rgba(36, 33, 33, 0) 100%);
  pointer-events: none;
  z-index: 0;
}

.route-gather .cellar {
  padding-bottom: calc(var(--rhythm) * 0.9);
  margin-bottom: var(--rhythm-tight);
}

.route-gather .cellar > .wrap {
  position: relative;
  z-index: 1;
}

/* The whole salon card is the button to the reservation form */
.event-card {
  color: inherit;
  text-decoration: none;
  cursor: pointer;
  transition: border-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}

.event-card:hover,
.event-card:focus-visible {
  border-color: var(--red);
  transform: translateY(-2px);
  box-shadow: 0 6px 18px rgba(36, 33, 33, 0.09);
}

.event-cue {
  margin-top: var(--s3);
  font-family: var(--header);
  font-size: 0.78rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--red);
}

.event-card:hover .event-cue,
.event-card:focus-visible .event-cue {
  text-decoration: underline;
  text-underline-offset: 4px;
}

.event-when {
  font-family: var(--header);
  font-size: 1.05rem;
  color: var(--red);
}

.event .note {
  margin-top: auto;
}

/* ---- Experiences (the rentals): a ledger, with a photograph beside each ---- */

.experience {
  display: grid;
  grid-template-columns: minmax(0, 3fr) minmax(0, 5fr) minmax(0, 4fr);
  gap: clamp(var(--s5), 4vw, var(--s8));
  padding-block: var(--s7);
  border-top: 1px solid var(--line);
  align-items: start;
}

.experience:last-child {
  border-bottom: 1px solid var(--line);
}

.experience-heading {
  font-size: clamp(1.6rem, 2.8vw, 2.3rem);
}

.experience-meta {
  color: var(--red);
  font-family: var(--header);
  font-size: 1rem;
  margin-top: var(--s4);
}

.experience .actions {
  margin-top: var(--s5);
}

.experience .photo {
  --ratio: 4 / 3;
}

.experience:nth-child(even) .photo {
  --ratio: 1 / 1;
  width: 80%;
  margin-left: auto;
}

@media (max-width: 860px) {
  .experience {
    grid-template-columns: 1fr;
    gap: var(--s4);
  }

  .experience:nth-child(even) .photo {
    width: 100%;
  }
}

/* ---- Forms and native embeds ---- */

.form-panel {
  padding: clamp(var(--s5), 3vw, var(--s7));
  background: var(--bg-raise);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.section-raise .form-panel {
  background: var(--bg);
}

.form-panel h2 {
  margin-bottom: var(--s5);
}

.form-layout {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(var(--s6), 5vw, var(--s9));
  align-items: start;
}

.form-layout > div:first-child {
  position: sticky;
  top: var(--s6);
}

@media (max-width: 860px) {
  .form-layout {
    grid-template-columns: 1fr;
  }

  .form-layout > div:first-child {
    position: static;
  }
}

.embed {
  min-height: 2rem;
}

.cloud-form {
  display: grid;
  gap: var(--s5);
}

.field {
  display: grid;
  gap: var(--s2);
}

.field-label {
  font-family: var(--header);
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

.field-input {
  width: 100%;
  font: inherit;
  color: var(--fg);
  background: var(--sand);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  padding: 0.8rem 1rem;
  transition: border-color 0.2s, box-shadow 0.2s;
}

.field-input::placeholder {
  color: var(--muted);
}

.field-input:focus {
  outline: none;
  border-color: var(--red);
  box-shadow: 0 0 0 3px var(--glow);
}

textarea.field-input {
  min-height: 8rem;
  resize: vertical;
}

select.field-input {
  appearance: none;
  -webkit-appearance: none;
}

input[type="checkbox"].field-input,
input[type="radio"].field-input {
  width: auto;
  accent-color: var(--red);
}

.field-note {
  color: var(--muted);
  font-size: 0.95rem;
}

.shop-table {
  min-height: 4rem;
}

.shop-empty {
  margin-top: var(--s5);
}

/* ---- Footer ---- */

.site-footer {
  border-top: 1px solid var(--line);
  background: var(--bg-sink);
  padding-block: var(--s5);
  color: var(--fg-soft);
  --muted: var(--fg-soft);
  font-size: 0.95rem;
}

.footer-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: var(--s5) var(--s6);
  align-items: start;
}

.footer-mark {
  display: inline-block;
  line-height: 0;
}

.footer-mark img {
  height: 4.25rem;
  width: auto;
}

.footer-tagline {
  font-family: var(--header);
  font-size: 1.05rem;
  color: var(--fg-soft);
  margin-top: var(--s4);
}

.footer-heading {
  font-family: var(--header);
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-soft);
  margin-bottom: var(--s3);
}

.site-footer a {
  color: var(--fg-soft);
  text-decoration: none;
}

.site-footer a:hover {
  color: var(--fg);
}

.site-footer p + p {
  margin-top: var(--s2);
}

.footer-nav {
  display: grid;
  gap: var(--s2);
  align-content: start;
}

.footer-base {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: var(--s4);
  margin-top: var(--s5);
  padding-top: var(--s4);
  border-top: 1px solid var(--line);
  font-size: 0.85rem;
}

.footer-name {
  color: var(--muted);
}

.footer-credit {
  font-size: 0.85rem;
  color: var(--muted);
}

.footer-small {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s4);
  font-size: 0.8rem;
}

.footer-small button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-decoration: underline;
}

/* ---- The invitation popup: the Join the Party form, once per visitor ---- */

/* A small card in the corner, NOT a full-screen modal. There is no scrim and
   the container never takes pointer events, so the page behind stays fully
   usable while the invitation is on screen — a visitor can keep reading,
   clicking and filling in other forms without closing it first. Only the card
   itself is interactive. */

.popup {
  position: fixed;
  inset: auto var(--s4) var(--s4) auto;
  z-index: 30;
  display: none;
  padding: 0;
  background: none;
  pointer-events: none;
}

.popup[data-open] {
  display: block;
}

.popup-card {
  position: relative;
  pointer-events: auto;
  width: min(calc(100vw - 2 * var(--s4)), 23rem);
  max-height: min(78vh, 34rem);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  background: var(--bg-raise);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: 0 18px 44px rgba(36, 33, 33, 0.28);
  animation: popup-in 0.45s var(--ease) both;
}

@keyframes popup-in {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.popup-art {
  background: var(--cellar-bg);
  color: var(--cellar-fg);
  padding: var(--s4) var(--s5) var(--s4) var(--s4);
  display: flex;
  flex-direction: column;
  gap: var(--s2);
  position: relative;
  overflow: hidden;
}

/* The decorative mustard shape is dropped in the compact card: it sat where
   the close button now lives, and anywhere else in a panel this short it
   either clips at the edge or collides with the note. */
.popup-art::before {
  content: none;
}

.popup-art > * {
  position: relative;
}

.popup-art .eyebrow {
  color: var(--cellar-muted);
  padding-right: 3.25rem;
}

.popup-art .eyebrow::before {
  background: var(--mustard);
}

.popup-art .statement {
  color: var(--cellar-fg);
  font-size: clamp(1.2rem, 2vw, 1.6rem);
}

.popup-art .popup-note {
  color: var(--cellar-muted);
  font-size: 0.9rem;
}

.popup-body {
  padding: var(--s4);
  overflow: auto;
  overscroll-behavior: contain;
  flex: 1 1 auto;
  min-height: 0;
}

.popup-art {
  flex: 0 0 auto;
}

.popup-body .cloud-form {
  gap: var(--s4);
}

.popup-body .sub {
  margin-top: 0;
  margin-bottom: var(--s5);
}

/* A real ✕ in the corner, always on top of the card and never scrolled away,
   with a 44px tap target so it can be hit on a phone first time. */
.popup-close {
  position: absolute;
  top: var(--s2);
  right: var(--s2);
  z-index: 2;
  margin: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  font: 400 1.15rem/1 var(--header);
  letter-spacing: 0;
  text-transform: none;
  color: var(--cellar-fg);
  background: rgba(36, 33, 33, 0.55);
  border: 1px solid rgba(246, 239, 233, 0.35);
  border-radius: 50%;
  padding: 0;
  cursor: pointer;
}

.popup-close:hover,
.popup-close:focus-visible {
  background: var(--brick, #b24a3b);
  color: #f6efe9;
}

/* On a phone it sits along the bottom edge, full width, clear of the home bar,
   and still leaves the page above it live and scrollable. */
@media (max-width: 760px) {
  .popup {
    inset: auto 0 0 0;
  }

  .popup-card {
    width: 100%;
    max-height: 70vh;
    border-radius: var(--radius) var(--radius) 0 0;
    border-left: none;
    border-right: none;
    border-bottom: none;
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
}

/* ---- The cookie notice ---- */

.cookie {
  position: fixed;
  left: var(--s4);
  right: var(--s4);
  bottom: var(--s4);
  z-index: 25;
  display: none;
  justify-content: space-between;
  align-items: center;
  gap: var(--s4);
  flex-wrap: wrap;
  padding: var(--s3) var(--s4);
  background: var(--bg-raise);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: 0 16px 40px rgba(36, 33, 33, 0.2);
  font-size: 0.85rem;
  color: var(--fg-soft);
  max-width: 34rem;
  margin-inline: auto;
}

.cookie[data-open] {
  display: flex;
}

.cookie p {
  max-width: 34ch;
}

.cookie .actions {
  margin-top: 0;
}

.cookie .button {
  padding: 0.6rem 1rem;
  font-size: 0.7rem;
}

/* ---- While the first page is on its way: the sun and one line, never an
   empty room between the header and the footer. ---- */

.loading {
  min-height: 60vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--s5);
  text-align: center;
  padding: var(--rhythm) var(--gutter);
}

.loading .brand-sun {
  animation: sunrise 1.8s ease-in-out infinite alternate;
}

.loading p {
  font-family: var(--header);
  font-size: 0.78rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
}

/* ---- Route entrance and motion ---- */

.route[data-animate] {
  animation: route-in 0.5s var(--ease) both;
}

@keyframes route-in {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.not-found {
  padding-block: var(--s9);
  text-align: center;
}

/* ---- The September invitation pages ---- */

.gathering-card {
  max-width: 44rem;
  margin-inline: auto;
  text-align: center;
}

.gathering-when {
  font-family: var(--header);
  font-size: clamp(1.6rem, 3.4vw, 2.4rem);
  line-height: 1.2;
  letter-spacing: -0.02em;
  color: var(--red);
  margin-top: var(--s4);
}

.gathering-doors {
  font-size: 1.05rem;
  color: var(--muted);
  margin-top: var(--s2);
}

.gathering-card .lede {
  max-width: none;
  margin-inline: auto;
  margin-top: var(--s6);
}

.gathering-card .prose {
  max-width: 58ch;
  margin-inline: auto;
  margin-top: var(--s5);
}

.gathering-card .actions {
  justify-content: center;
  margin-top: var(--s6);
}

.gathering-sub {
  margin-top: var(--s6);
}

.gathering-card .eyebrow {
  justify-content: center;
}

@media (max-width: 700px) {
  .gathering-card {
    text-align: left;
  }

  .gathering-card .actions {
    justify-content: flex-start;
  }

  .gathering-card .eyebrow {
    justify-content: flex-start;
  }
}

@media (prefers-reduced-motion: reduce) {
  .route[data-animate],
  [data-arrived] .cellar::before,
  [data-arrived] .brand-sun,
  .popup-card {
    animation: none;
  }

  .site-header,
  .brand-mark,
  .button,
  .site-link {
    transition: none;
  }
}


/* Events: a quiet rule between the season listings and the Sunday section */
.route-gather .section-sunday { padding-top: 0; }
.route-gather .section-sunday > .wrap {
  border-top: 1px solid rgba(171, 142, 105, 0.32);
  padding-top: calc(var(--rhythm) * 0.75);
  margin-top: calc(var(--rhythm) * 0.35);
}


/* Salon pages: the topic, set to be read slowly */
.route-salon .section-topic { padding-top: calc(var(--rhythm) * 0.6); padding-bottom: calc(var(--rhythm) * 0.6); }
.route-salon .topic-copy { max-width: 62ch; }
.route-salon .topic-copy p {
  font-size: clamp(1.02rem, 1.5vw, 1.16rem);
  line-height: 1.75;
  margin: 0 0 var(--s5);
  color: var(--dirt);
}
.route-salon .topic-copy p:first-child { color: var(--ink, var(--dirt)); }
.route-salon .topic-copy p:last-child { margin-bottom: 0; font-style: italic; }

.route-salon .section-topic > .wrap { display: block; }

.route-salon .topic-copy { max-width: none; }
.route-salon .topic-copy p { max-width: 62ch; margin-right: auto; }


/* ============================================================
   September 17 — the warmth pass.
   Written after a photographer's first impression: too cold,
   too much typewriter, no texture, the founders too small.
   Everything here is an override appended at the end of the
   file. Delete this whole block and the site returns exactly
   to how it was. Nothing above was edited.
   ============================================================ */

/* 1. The reading face. Cousine stays everywhere it does brand
   work — headings, eyebrows, buttons, labels, dates. Long copy
   moves to a warm old-style serif, which is what actually makes
   a page feel like a room rather than a terminal. System fonts
   only, so nothing extra downloads and nothing gets slower. */
:root {
  --body: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua", Georgia, serif;
  --fg-soft: #453930;
  --muted: #6d5a49;
}

body {
  font-size: 1.06rem;
  line-height: 1.78;
  letter-spacing: 0.002em;
}

.prose p,
.prose-lg p,
.topic-copy p,
.founder-copy .prose p {
  font-family: var(--body);
}

.prose-lg p {
  line-height: 1.7;
}

/* 2. Texture. A fine paper grain over everything, fixed to the
   window so it reads as the surface of the page rather than as
   part of any photograph. Multiply keeps it in the sand and the
   clay instead of greying them. Invisible on its own; you feel
   it. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 9998;
  pointer-events: none;
  opacity: 0.055;
  mix-blend-mode: multiply;
  background-repeat: repeat;
  background-size: 200px 200px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23g)'/%3E%3C/svg%3E");
}

@media print {
  body::after { display: none; }
}

/* 3. The founders, twice the size. They were two narrow columns
   side by side, which made both portraits small. Now each woman
   gets a full row: a large portrait beside her own words, and
   the second one mirrored. */
@media (min-width: 761px) {
  .founders {
    grid-template-columns: 1fr;
    gap: var(--rhythm);
  }

  .founder {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
    gap: var(--col-gap);
    align-items: center;
  }

  .founder-reverse .founder-photo {
    order: 2;
  }

  .founder-reverse .founder-copy {
    order: 1;
  }

  .founder-photo {
    --ratio: 4 / 5;
  }
}


/* ============================================================
   September 17, second pass — earthier.
   Heidi on the live our-story page: the black is too black, the
   light is too shocking, and the cellar statement should carry
   the sun. Still all overrides at the end of the file.
   ============================================================ */

/* 1. The cellar band keeps its depth but stops being a hole in
   the page. A warm near-black with brown in it, not carbon. */
:root {
  --cellar-bg: #2d2521;
  --cellar-fg: #ece3d2;
  --cellar-muted: #c3b6a4;
  --cellar-line: rgba(236, 227, 210, 0.16);

  /* The lifted panels were reading as white. Warmed toward the
     sand so the page is one family of tones, not two. */
  --bg-raise: #f2e8dc;
  --bg-sink: #ded5c8;
}

/* 2. The sun, where the cellar speaks. */
.cellar .statement,
.section-sunday.cellar .statement {
  color: var(--mustard);
}

.cellar .eyebrow {
  color: var(--clay);
}

/* 3. The founders, on warm ground. Mustard laid thin over sand —
   the colour of the band without the shout of it. */
.section-founders {
  background: #f0e2c6;
}

.section-founders .statement {
  color: #6a4f2c;
}

.section-founders .eyebrow {
  color: var(--brick);
}

/* 4. Each portrait starts where her name starts, not floating in
   the middle of her story. */
.founder {
  align-items: start;
}

@media (min-width: 761px) {
  .founder {
    align-items: start;
  }
}


/* ============================================================
   September 17, third pass — the fonts come home.
   Cousine was being fetched from Google on every page load, which
   is a third-party request Safari's tracking protection flags
   ("reduce advanced privacy protections"). The same font files
   have been sitting in this app all along, unused. Now they are
   the source, and the site asks nothing of anyone else.
   ============================================================ */

@font-face {
  font-family: "Cousine";
  src: url("https://lovable-crab-328.convex.cloud/api/storage/9383253b-27af-48ed-bbea-d686cae92419") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Cousine";
  src: url("https://lovable-crab-328.convex.cloud/api/storage/f7326792-2e93-4085-9fd8-d9ce1a01f4e9") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: "Cousine";
  src: url("https://lovable-crab-328.convex.cloud/api/storage/97ffbe21-fa44-4a3f-83bb-d1faeedecb75") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}


/* ============================================================
   September 17, fourth pass — the cellar photograph, given room.
   It is the actual space, candles and all, and it was being shown
   at 78% of a narrow column with a wide gutter beside it. More
   picture, less air.
   ============================================================ */

.cellar-grid {
  grid-template-columns: minmax(0, 6.5fr) minmax(0, 5.5fr);
  gap: clamp(var(--s5), 3vw, var(--s7));
}

.cellar-grid .photo {
  width: 100%;
  margin-left: 0;
}

@media (max-width: 860px) {
  .cellar-grid {
    grid-template-columns: 1fr;
    gap: var(--s6);
  }

  .cellar-grid .photo {
    width: 100%;
    margin-inline: 0;
  }
}


/* ============================================================
   September 17, fifth pass — wider, and a size you can read.
   The old measure was 58 characters, set for the monospace the
   site used to read in. A serif fits more per line comfortably,
   so the limit moves out to 72 and the copy gets a little
   bigger everywhere.
   ============================================================ */

:root {
  --measure: 72ch;
}

.prose p,
.topic-copy p,
.founder-copy .prose p {
  font-size: clamp(1.06rem, 1.25vw, 1.16rem);
  line-height: 1.72;
}

/* The founders' stories sit in half-width columns already, so they
   take the full width of the column they are in. */
.founder-copy .prose,
.founder-copy .prose p {
  max-width: none;
}

/* The cellar band on the home page: this is the paragraph under the
   big quotation, and it was the smallest and narrowest text on the
   page sitting next to the largest. It now runs the full width of
   its column, at a size that matches its importance. */
.route-home .cellar .prose {
  max-width: none;
}

.route-home .cellar .prose p {
  font-size: clamp(1.1rem, 1.35vw, 1.24rem);
  line-height: 1.7;
  max-width: none;
}


/* ============================================================
   September 17, sixth pass — the real pinch, found.
   It was never the measure. The "nothing here is anonymous"
   block sits in .wrap-narrow, a 60rem column, while every other
   section uses .wrap at 84rem — and it is pinned left, so on a
   wide screen the right third is empty. That column is now the
   same width as the rest of the site, the copy is a size up, and
   the lines are allowed to run to 82 characters.
   ============================================================ */

:root {
  --measure: 82ch;
}

.route-home .named .wrap-narrow {
  width: min(100% - 2 * var(--gutter), var(--maxw));
}

.route-home .named p {
  max-width: 82ch;
  font-size: clamp(1.1rem, 1.35vw, 1.24rem);
  line-height: 1.72;
}

.route-home .named .sub {
  max-width: 82ch;
}

.route-home .named .motto {
  max-width: none;
}


/* Everywhere, not just the home page: the narrow wrapper was 60rem
   against 84rem for every other section, which is the pinch Heidi
   kept seeing on page after page. It now sits much closer to the
   rest of the site, and long copy inside it runs to 82 characters
   before it wraps. */
.wrap-narrow {
  width: min(100% - 2 * var(--gutter), 76rem);
}

.wrap-narrow p,
.wrap-narrow .prose,
.wrap-narrow .prose p,
.wrap-narrow .prose-lg,
.wrap-narrow .prose-lg p {
  max-width: 82ch;
}


/* ============================================================
   September 17, seventh pass — texture you can actually see.
   The grain was there, but set to multiply, which only darkens.
   On the dark cellar bands it showed (that is the weave in the
   announcement bar); on sand and paper it did almost nothing,
   which is why the light panes read flat. Soft-light works in
   both directions — it darkens the dark and lifts the light — so
   the same one overlay now textures the whole site.
   Then each pane gets a seam and a little light of its own.
   ============================================================ */

/* 1. The grain, made visible. */
body::after {
  opacity: 0.16;
  mix-blend-mode: soft-light;
  background-size: 150px 150px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='150' height='150'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='150' height='150' filter='url(%23g)'/%3E%3C/svg%3E");
}

/* 2. Every pane catches light at its top edge and settles into
   shadow at its foot, the way paper does on a table. Very slight —
   it should read as depth, never as a gradient. */
.section {
  position: relative;
  background-image: linear-gradient(
    180deg,
    rgba(255, 252, 245, 0.5) 0%,
    rgba(255, 252, 245, 0) 26%,
    rgba(119, 98, 76, 0) 78%,
    rgba(119, 98, 76, 0.05) 100%
  );
}

/* The dark bands get the same idea in their own register. */
.section.cellar,
.cellar {
  background-image: linear-gradient(
    180deg,
    rgba(237, 232, 216, 0.06) 0%,
    rgba(237, 232, 216, 0) 30%,
    rgba(0, 0, 0, 0) 76%,
    rgba(0, 0, 0, 0.16) 100%
  );
}

/* 3. The seam. Where one pane meets the next there is now a hairline
   of clay with a thread of light above it, so the join is a join
   rather than two colours happening to touch. */
.section + .section::before,
.section + .cellar::before,
.cellar + .section::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 1px;
  background: rgba(171, 142, 105, 0.3);
  pointer-events: none;
}

.section + .section::after {
  content: "";
  position: absolute;
  inset: 1px 0 auto 0;
  height: 1px;
  background: rgba(255, 253, 247, 0.5);
  pointer-events: none;
}

.cellar + .section::after,
.section + .cellar::after {
  content: none;
}

/* 4. The footer keeps its own edge rather than borrowing the seam. */
.site-footer {
  border-top: 1px solid rgba(171, 142, 105, 0.34);
}

@media print {
  .section,
  .cellar {
    background-image: none;
  }
}


/* ============================================================
   September 17, eighth pass — bigger reading copy, everywhere.
   The serif sits optically smaller than the monospace it
   replaced, so what was a comfortable size this morning reads
   small now. Everything that is meant to be READ goes up a
   step; headings, labels, prices and navigation are untouched.
   ============================================================ */

body {
  font-size: 1.16rem;
  line-height: 1.75;
}

.prose p,
.topic-copy p,
.founder-copy .prose p,
.wrap-narrow p {
  font-size: clamp(1.16rem, 1.4vw, 1.3rem);
  line-height: 1.72;
}

.route-home .named p,
.route-home .cellar .prose p {
  font-size: clamp(1.2rem, 1.5vw, 1.36rem);
  line-height: 1.7;
}

.prose-lg p {
  font-size: clamp(1.28rem, 1.8vw, 1.5rem);
  line-height: 1.66;
}

/* The small print stays small print, just not tiny: notes, captions
   and the lines under a heading come up with everything else. */
.note,
.row-note,
.event-note,
figcaption {
  font-size: 1rem;
  line-height: 1.6;
}

.sub {
  font-size: clamp(1.12rem, 1.4vw, 1.26rem);
}

.lede {
  font-size: clamp(1.22rem, 1.7vw, 1.44rem);
}


/* ============================================================
   September 18 — texture you can feel, not just measure.
   The grain was set so politely it was invisible on a bright
   screen. Handmade paper is not uniform: it has fine tooth AND
   large, soft unevenness where the pulp settled. This does both
   — a stronger fibre grain over everything, plus a slow mottle
   underneath it. Delete this block to return to flat colour.
   ============================================================ */

/* 1. The tooth of the paper. Roughly twice as present as before,
   and finer, so it reads as fibre rather than noise. */
body::after {
  opacity: 0.3;
  mix-blend-mode: soft-light;
  background-size: 120px 120px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='5' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23g)'/%3E%3C/svg%3E");
}

/* 2. The mottle. Large, soft, irregular pools of warmth and shade,
   the way pulp settles unevenly in a sheet. Fixed to the window so
   it never repeats visibly, and laid under the grain. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 9997;
  pointer-events: none;
  mix-blend-mode: multiply;
  opacity: 0.5;
  background-image:
    radial-gradient(60% 45% at 12% 18%, rgba(171, 142, 105, 0.13), rgba(171, 142, 105, 0) 70%),
    radial-gradient(48% 38% at 88% 30%, rgba(119, 98, 76, 0.1), rgba(119, 98, 76, 0) 72%),
    radial-gradient(55% 40% at 70% 82%, rgba(171, 142, 105, 0.12), rgba(171, 142, 105, 0) 70%),
    radial-gradient(42% 32% at 28% 72%, rgba(119, 98, 76, 0.09), rgba(119, 98, 76, 0) 74%),
    radial-gradient(38% 30% at 50% 48%, rgba(204, 197, 188, 0.14), rgba(204, 197, 188, 0) 76%);
}

/* 3. A second, coarser fibre laid only on the light panes, where a
   single fine grain disappears. Diagonal, very low contrast — it is
   the weave you see in good paper held to the light. */
.section:not(.cellar)::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.5;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='90' height='90'%3E%3Cfilter id='f'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.045 0.5' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='90' height='90' filter='url(%23f)' opacity='0.22'/%3E%3C/svg%3E");
  mix-blend-mode: multiply;
  height: auto;
  background-color: transparent;
}

/* The seam line above still has to win over the weave. */
.section + .section::before,
.section + .cellar::before,
.cellar + .section::before {
  z-index: 2;
}

@media print {
  body::before,
  .section::after {
    display: none;
  }
}


/* ============================================================
   September 18, second texture pass — further in.
   Heidi: "definitely not too much." So: the grain and the mottle
   both come up, the light panes get a warm edge-shade like paper
   curling away from a table, and the seams between panes get a
   soft shadow instead of a hairline alone.
   ============================================================ */

/* 1. More tooth. */
body::after {
  opacity: 0.42;
}

/* 2. More mottle, and deeper pools. */
body::before {
  opacity: 0.72;
  background-image:
    radial-gradient(62% 46% at 10% 16%, rgba(171, 142, 105, 0.2), rgba(171, 142, 105, 0) 70%),
    radial-gradient(50% 40% at 90% 28%, rgba(119, 98, 76, 0.16), rgba(119, 98, 76, 0) 72%),
    radial-gradient(58% 42% at 72% 84%, rgba(171, 142, 105, 0.19), rgba(171, 142, 105, 0) 70%),
    radial-gradient(44% 34% at 26% 74%, rgba(119, 98, 76, 0.15), rgba(119, 98, 76, 0) 74%),
    radial-gradient(40% 32% at 52% 46%, rgba(204, 197, 188, 0.2), rgba(204, 197, 188, 0) 76%),
    radial-gradient(30% 24% at 40% 12%, rgba(171, 142, 105, 0.12), rgba(171, 142, 105, 0) 78%),
    radial-gradient(34% 26% at 84% 62%, rgba(119, 98, 76, 0.11), rgba(119, 98, 76, 0) 78%);
}

/* 3. A warm shade down both edges of every light pane, the way a
   sheet of paper darkens where it lifts from the table. Keeps the
   middle of the page open and the edges soft. */
.section:not(.cellar) {
  background-image:
    linear-gradient(90deg, rgba(119, 98, 76, 0.07) 0%, rgba(119, 98, 76, 0) 14%, rgba(119, 98, 76, 0) 86%, rgba(119, 98, 76, 0.07) 100%),
    linear-gradient(
      180deg,
      rgba(255, 252, 245, 0.55) 0%,
      rgba(255, 252, 245, 0) 24%,
      rgba(119, 98, 76, 0) 74%,
      rgba(119, 98, 76, 0.08) 100%
    );
}

/* 4. A coarser weave. */
.section:not(.cellar)::after {
  opacity: 0.85;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='90' height='90'%3E%3Cfilter id='f'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.04 0.55' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='90' height='90' filter='url(%23f)' opacity='0.3'/%3E%3C/svg%3E");
}

/* 5. The seam gets depth: the hairline stays, and a soft shadow
   falls from it so one pane reads as laid over the next. */
.section + .section,
.section + .cellar,
.cellar + .section {
  box-shadow: inset 0 9px 14px -10px rgba(45, 37, 33, 0.22);
}

/* 6. The dark bands get their own grain lift so they do not go
   flat against all this. */
.cellar::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.4;
  mix-blend-mode: overlay;
  background-size: 110px 110px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='110' height='110'%3E%3Cfilter id='d'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.7' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='110' height='110' filter='url(%23d)'/%3E%3C/svg%3E");
}


/* ============================================================
   September 18 — how lines break.
   Two different problems were being solved by one blunt rule.
   LONG copy needs a width limit or the eye loses its place
   tracking back. SHORT copy — a lede, a subtitle, a note, a
   heading — does not: it just needs to fit. So the limit now
   applies only to real paragraphs, and everything short is set
   to break evenly instead.
   ============================================================ */

/* 1. Short display copy runs the full width of its column. */
.lede,
.sub,
.statement,
.note,
.motto,
.event-when,
h1,
h2,
h3,
h4 {
  max-width: none;
}

/* 2. Even lines, no stranded words. `balance` shares the words out
   across the lines so no line is a fragment; it is meant for short
   blocks and modern browsers apply it to the first few lines only. */
.lede,
.sub,
.statement,
.note,
.motto,
.pillar p,
.week-note,
.row-note,
figcaption,
h1,
h2,
h3,
h4,
.title,
.display,
.founder-copy h2,
.event-when {
  text-wrap: balance;
}

/* 3. Long paragraphs keep their width limit, but never end on a
   single small word. `pretty` looks ahead at the last lines and
   pulls a word down rather than leaving an orphan. */
p,
.prose p,
.prose-lg p,
.topic-copy p,
.founder-copy .prose p,
.wrap-narrow p {
  text-wrap: pretty;
  hyphens: none;
}

/* 4. Anything Safari has not caught up on still gets the old
   behaviour — nothing breaks, it just wraps as before. */
@supports not (text-wrap: balance) {
  .lede,
  .statement,
  .sub {
    text-wrap: initial;
  }
}


/* The actual culprit on the inner-page heroes: a 50-character cap
   on the lede, set when these pages were monospace. That is what was
   breaking "beauty is not a luxury" onto its own line while two
   thirds of the page sat empty beside it. */
.hero-inner .lede,
.hero-copy .lede,
.hero .lede,
.hero .sub {
  max-width: none;
}


/* ============================================================
   September 18 — the light-to-dark edge.
   The inner-page hero had no room beneath its lede, so the
   sentence sat flush against the cellar band: a guillotine cut.
   Three fixes: give the hero a floor, raise the lede, and let
   the dark rise out of the light instead of starting abruptly.
   ============================================================ */

/* 1. Room to breathe before the dark. */
.hero-inner {
  padding-bottom: calc(var(--rhythm) * 0.85);
}

/* 2. The lede, a size up — it is the first sentence anyone reads
   on these pages and it was the smallest thing on the screen. */
.hero-inner .lede,
.hero-copy .lede {
  font-size: clamp(1.32rem, 1.9vw, 1.62rem);
  line-height: 1.55;
  margin-top: var(--s5);
}

/* 3. The fade. The cellar band now opens with a soft rise out of
   the sand above it rather than a cut — about 130px of gradient,
   laid over its own colour, with the grain still on top. */
.cellar {
  background-image:
    linear-gradient(180deg, rgba(240, 233, 220, 0.96) 0%, rgba(240, 233, 220, 0.55) 34%, rgba(240, 233, 220, 0) 100%),
    linear-gradient(
      180deg,
      rgba(237, 232, 216, 0.06) 0%,
      rgba(237, 232, 216, 0) 30%,
      rgba(0, 0, 0, 0) 76%,
      rgba(0, 0, 0, 0.18) 100%
    );
  background-size: 100% 130px, 100% 100%;
  background-repeat: no-repeat, no-repeat;
  background-position: top left, top left;
}

/* 4. And the same on the way out, so the dark settles back into
   the light beneath it. */
.cellar::before {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 110px;
  pointer-events: none;
  background: linear-gradient(0deg, rgba(240, 233, 220, 0.9) 0%, rgba(240, 233, 220, 0) 100%);
  z-index: 1;
}

/* 5. No hairline seam where there is now a fade — a fade and a rule
   at the same join looks like an accident. */
.section + .cellar::before,
.cellar + .section::before {
  background: none;
}

.section + .cellar,
.cellar + .section {
  box-shadow: none;
}

/* Keep the cellar's copy above both fades. */
.cellar .wrap,
.cellar .wrap-narrow {
  position: relative;
  z-index: 2;
}


/* ============================================================
   September 18 — the mark, where the plain dot was.
   Each mission column opened with a mustard blob. It is now the
   actual Alma mark: the red a in its uneven sun.
   ============================================================ */

.pillars-sun .pillar::before {
  width: 2.5rem;
  background: transparent url("/_next/image?url=https%3A%2F%2Flovable-crab-328.convex.cloud%2Fapi%2Fstorage%2F78fe2dfb-cde5-4bb8-a858-0679b49e7ef0&w=1920&q=75") center / contain no-repeat;
  border-radius: 0;
  margin-bottom: var(--s4);
}


/* Heidi's own file: the red a in the uneven yellow sun. The version
   already in the app was the clay circle, which disappears against
   sand. This is the one from ALMA ENTERPRISES. */
.pillars-sun .pillar::before {
  background-image: url("/_next/image?url=https%3A%2F%2Flovable-crab-328.convex.cloud%2Fapi%2Fstorage%2Fcb1fa3cb-842a-4707-a917-17e45cc2d901&w=1920&q=75");
}


/* ============================================================
   September 18 — both edges, the same.
   The top fade ramped off fast in its first third while the
   bottom one was a smooth even wash, so the band looked cut at
   the top and feathered at the foot. Same height, same curve,
   both ends now.
   ============================================================ */

.cellar {
  background-image:
    linear-gradient(180deg, rgba(240, 233, 220, 0.9) 0%, rgba(240, 233, 220, 0) 100%),
    linear-gradient(
      180deg,
      rgba(237, 232, 216, 0.06) 0%,
      rgba(237, 232, 216, 0) 30%,
      rgba(0, 0, 0, 0) 76%,
      rgba(0, 0, 0, 0.18) 100%
    );
  background-size: 100% 140px, 100% 100%;
}

.cellar::before {
  height: 140px;
  background: linear-gradient(0deg, rgba(240, 233, 220, 0.9) 0%, rgba(240, 233, 220, 0) 100%);
}


/* ==========================================================================
   2026-09-18 — Vollkorn comes home
   Self-hosted, latin-subset woff2 (~78KB total, three files).
   Replaces the Iowan Old Style / Palatino system stack for body copy.
   Earthier, rounder, more humanist than Palatino; pairs with Cousine
   because both have visible tool-marks rather than polish.
   ========================================================================== */

@font-face {
  font-family: "Vollkorn";
  src: url("https://lovable-crab-328.convex.cloud/api/storage/f3e589c0-3037-46a5-abfe-348e9999c4a7") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Vollkorn";
  src: url("https://lovable-crab-328.convex.cloud/api/storage/9974c52d-530c-4e77-8a1e-e24895d56098") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: "Vollkorn";
  src: url("https://lovable-crab-328.convex.cloud/api/storage/49176e9b-97d6-4ff2-b598-d58d009f633a") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

:root {
  --body: "Vollkorn", "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
}

/* Vollkorn runs a touch wider and a touch larger on the eye than Palatino did,
   so the measure gets a hair more room and the leading opens slightly. */
body {
  font-size: 1.14rem;
  line-height: 1.72;
  font-synthesis-weight: none;
}

/* Bold in body copy resolves to the real 600 cut rather than a synthesised one. */
.prose strong,
.prose b,
p strong,
p b {
  font-weight: 600;
}


/* ==========================================================================
   2026-09-18 — the dark/light joins, properly this time.

   Two faults, and they stacked:

   1. The fade opened at 90% opacity, not 100%. A 90% cream veil laid over
      #2d2521 computes to about rgb(221,214,202) — which is roughly 25 points
      darker than the pane sitting directly above it. So even "faded", the
      join still began with a visible step. The fade was hiding the cut, not
      removing it.

   2. It was a straight linear ramp ending at zero. The eye reads the kink
      where a linear alpha ramp terminates as a hard edge (Mach banding) —
      which is the second horizontal line Heidi is seeing about 140px down
      inside every dark band. It is not a separate block set differently;
      it is the bottom of the fade announcing itself.

   The fix is three-part: the veil now opens fully opaque and rides an eased
   curve with no terminal kink; the LIGHT pane above and below also leans
   toward the dark across its last 110px, so the blend is met from both
   sides rather than done entirely by the dark; and a slow undulation is
   laid across the join so the boundary reads as an uneven edge rather than
   a ruled line.
   ========================================================================== */

/* ---- 1. The dark band's own fade, both ends, eased and opaque at the seam. */

.cellar {
  background-image:
    /* the join, laid across an uneven wash so it is never a straight line */
    radial-gradient(120% 90px at 18% 0%, rgba(240, 234, 223, 0.5), rgba(240, 234, 223, 0) 70%),
    radial-gradient(100% 70px at 74% 0%, rgba(240, 234, 223, 0.42), rgba(240, 234, 223, 0) 72%),
    linear-gradient(
      180deg,
      rgba(240, 234, 223, 1) 0%,
      rgba(240, 234, 223, 0.97) 8%,
      rgba(240, 234, 223, 0.9) 18%,
      rgba(240, 234, 223, 0.79) 28%,
      rgba(240, 234, 223, 0.64) 40%,
      rgba(240, 234, 223, 0.48) 52%,
      rgba(240, 234, 223, 0.33) 64%,
      rgba(240, 234, 223, 0.19) 76%,
      rgba(240, 234, 223, 0.08) 88%,
      rgba(240, 234, 223, 0.02) 95%,
      rgba(240, 234, 223, 0) 100%
    ),
    linear-gradient(
      180deg,
      rgba(237, 232, 216, 0.06) 0%,
      rgba(237, 232, 216, 0) 30%,
      rgba(0, 0, 0, 0) 76%,
      rgba(0, 0, 0, 0.18) 100%
    );
  background-size: 100% 150px, 100% 120px, 100% 190px, 100% 100%;
  background-repeat: no-repeat, no-repeat, no-repeat, no-repeat;
  background-position: top left, top left, top left, top left;
}

/* The way out, mirrored — same curve, same logic. */
.cellar::before {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 175px;
  pointer-events: none;
  z-index: 1;
  background-image:
    radial-gradient(120% 80px at 72% 100%, rgba(240, 234, 223, 0.46), rgba(240, 234, 223, 0) 70%),
    linear-gradient(
      0deg,
      rgba(240, 234, 223, 1) 0%,
      rgba(240, 234, 223, 0.97) 8%,
      rgba(240, 234, 223, 0.9) 18%,
      rgba(240, 234, 223, 0.79) 28%,
      rgba(240, 234, 223, 0.64) 40%,
      rgba(240, 234, 223, 0.48) 52%,
      rgba(240, 234, 223, 0.33) 64%,
      rgba(240, 234, 223, 0.19) 76%,
      rgba(240, 234, 223, 0.08) 88%,
      rgba(240, 234, 223, 0.02) 95%,
      rgba(240, 234, 223, 0) 100%
    );
  background-size: 100% 100px, 100% 100%;
  background-repeat: no-repeat, no-repeat;
  background-position: bottom left, bottom left;
}

/* ---- 2. The light pane meets it halfway.

   Until now the dark did all the work of blending and the light pane sat
   there flat right up to the edge. Now the last 110px of the pane above a
   dark band leans warm and slightly shaded, and the first 110px of the pane
   below one does the same — so the two sides arrive at the join already
   close to each other. This is what actually kills the remaining step,
   because it no longer matters exactly which cream the pane above is. */

.section:not(.cellar):has(+ .cellar) {
  background-image:
    linear-gradient(
      180deg,
      rgba(45, 37, 33, 0) 0%,
      rgba(45, 37, 33, 0.02) 34%,
      rgba(45, 37, 33, 0.06) 62%,
      rgba(45, 37, 33, 0.13) 86%,
      rgba(45, 37, 33, 0.19) 100%
    ),
    linear-gradient(90deg, rgba(119, 98, 76, 0.07) 0%, rgba(119, 98, 76, 0) 14%, rgba(119, 98, 76, 0) 86%, rgba(119, 98, 76, 0.07) 100%),
    linear-gradient(
      180deg,
      rgba(255, 252, 245, 0.55) 0%,
      rgba(255, 252, 245, 0) 24%,
      rgba(119, 98, 76, 0) 74%,
      rgba(119, 98, 76, 0.08) 100%
    );
  background-size: 100% 130px, auto, auto;
  background-repeat: no-repeat, repeat, repeat;
  background-position: bottom left, top left, top left;
}

.cellar + .section:not(.cellar) {
  background-image:
    linear-gradient(
      0deg,
      rgba(45, 37, 33, 0) 0%,
      rgba(45, 37, 33, 0.02) 34%,
      rgba(45, 37, 33, 0.06) 62%,
      rgba(45, 37, 33, 0.13) 86%,
      rgba(45, 37, 33, 0.19) 100%
    ),
    linear-gradient(90deg, rgba(119, 98, 76, 0.07) 0%, rgba(119, 98, 76, 0) 14%, rgba(119, 98, 76, 0) 86%, rgba(119, 98, 76, 0.07) 100%),
    linear-gradient(
      180deg,
      rgba(255, 252, 245, 0.55) 0%,
      rgba(255, 252, 245, 0) 24%,
      rgba(119, 98, 76, 0) 74%,
      rgba(119, 98, 76, 0.08) 100%
    );
  background-size: 100% 130px, auto, auto;
  background-repeat: no-repeat, repeat, repeat;
  background-position: top left, top left, top left;
}

/* Browsers without :has() simply keep the old flat pane — the dark band's
   own eased fade still does most of the work, so nothing looks broken. */

/* ---- 3. Texture carries all the way through the join.

   The grain on the dark bands stopped looking like grain in the fade zone,
   because the cream veil sat on top of it. The veil is background; the
   grain is a pseudo-element above it — so it now runs the full height of
   the band, fade included, and comes up a little so the transition has
   tooth rather than being a clean airbrush. */

.cellar::after {
  opacity: 0.52;
  background-size: 96px 96px;
}

/* And the weave on the light panes runs right to their edges, so the pane
   above a dark band is textured where it darkens rather than going smooth
   exactly where the eye is looking hardest. */
.section:not(.cellar):has(+ .cellar)::after,
.cellar + .section:not(.cellar)::after {
  opacity: 0.95;
}

/* ---- 4. No seam line, no drop shadow, anywhere a fade is doing the work.
   A rule and a fade at the same join is what made it read as a cut. */

/* NOTE — this is the bug that has been eating the bottom fade all along.
   The hairline seam and the cellar's outgoing fade were both written onto
   the SAME pseudo-element, ::before. An earlier rule said
   `.section + .cellar::before { background: none }` to kill the hairline,
   and because it came after the fade rule it silently killed the fade too —
   on every dark band that follows a section, which is all of them. So the
   band has been fading in at the top and stopping dead at the bottom this
   whole time. The seam is now cancelled only on light-to-light joins,
   where ::before is genuinely just a hairline. */

.cellar + .section:not(.cellar)::before {
  background: none;
  box-shadow: none;
}

.section + .cellar,
.cellar + .section,
.section:not(.cellar):has(+ .cellar) {
  box-shadow: none;
}

@media print {
  .cellar,
  .cellar::before,
  .section:not(.cellar):has(+ .cellar),
  .cellar + .section:not(.cellar) {
    background-image: none;
  }
}


/* ==========================================================================
   2026-09-18, later — the joins, moved somewhere they can't be argued with.

   The outgoing fade at the foot of the dark band worked immediately. The
   incoming one at the top did not, and the reason is worth writing down:
   the top fade was being painted into `.cellar`'s own `background-image`,
   a property that four separate earlier passes in this file also write to.
   Whichever of them lands last wins the whole declaration, and tracing that
   is a waste of an afternoon.

   So the top fade stops living in the section's background. Both fades now
   sit on ONE pseudo-element stretched over the whole band — above the
   section's background, below its copy — with the incoming fade anchored to
   the top edge and the outgoing one anchored to the foot. Two layers, one
   element, nothing else in the file touches it.

   `.cellar`'s own background goes back to doing one job: the faint interior
   shading. It no longer carries a fade, so nothing can conflict.
   ========================================================================== */

.cellar {
  background-image: linear-gradient(
    180deg,
    rgba(237, 232, 216, 0.06) 0%,
    rgba(237, 232, 216, 0) 30%,
    rgba(0, 0, 0, 0) 76%,
    rgba(0, 0, 0, 0.18) 100%
  );
  background-size: 100% 100%;
  background-repeat: no-repeat;
  background-position: top left;
}

/* Both joins, on one layer. Opaque at each edge so there is no step, and
   eased rather than linear so neither ramp ends on a visible kink. The two
   radial layers ride on top of the linear ones and make each boundary
   slightly uneven across its width, so it reads as a soft edge rather than
   a ruled line. */
.cellar::before {
  content: "";
  position: absolute;
  inset: 0;
  height: auto;
  pointer-events: none;
  z-index: 1;
  background-color: transparent;
  background-image:
    /* uneven wash along the top join */
    radial-gradient(130% 100px at 16% 0%, rgba(240, 234, 223, 0.42), rgba(240, 234, 223, 0) 72%),
    radial-gradient(110% 80px at 76% 0%, rgba(240, 234, 223, 0.34), rgba(240, 234, 223, 0) 74%),
    /* uneven wash along the bottom join */
    radial-gradient(130% 90px at 70% 100%, rgba(240, 234, 223, 0.38), rgba(240, 234, 223, 0) 72%),
    /* the incoming fade */
    linear-gradient(
      180deg,
      rgba(240, 234, 223, 1) 0%,
      rgba(240, 234, 223, 0.97) 8%,
      rgba(240, 234, 223, 0.9) 18%,
      rgba(240, 234, 223, 0.79) 28%,
      rgba(240, 234, 223, 0.64) 40%,
      rgba(240, 234, 223, 0.48) 52%,
      rgba(240, 234, 223, 0.33) 64%,
      rgba(240, 234, 223, 0.19) 76%,
      rgba(240, 234, 223, 0.08) 88%,
      rgba(240, 234, 223, 0.02) 95%,
      rgba(240, 234, 223, 0) 100%
    ),
    /* the outgoing fade */
    linear-gradient(
      0deg,
      rgba(240, 234, 223, 1) 0%,
      rgba(240, 234, 223, 0.97) 8%,
      rgba(240, 234, 223, 0.9) 18%,
      rgba(240, 234, 223, 0.79) 28%,
      rgba(240, 234, 223, 0.64) 40%,
      rgba(240, 234, 223, 0.48) 52%,
      rgba(240, 234, 223, 0.33) 64%,
      rgba(240, 234, 223, 0.19) 76%,
      rgba(240, 234, 223, 0.08) 88%,
      rgba(240, 234, 223, 0.02) 95%,
      rgba(240, 234, 223, 0) 100%
    );
  background-size:
    100% 170px,
    100% 140px,
    100% 150px,
    100% 190px,
    100% 175px;
  background-position:
    top left,
    top left,
    bottom left,
    top left,
    bottom left;
  background-repeat: no-repeat;
}

/* The grain has to sit ABOVE the fades, or the transition zones come out
   airbrushed while the middle of the band has tooth — which is exactly the
   smooth-then-textured mismatch that reads as a seam. */
.cellar::after {
  z-index: 2;
}

.cellar .wrap,
.cellar .wrap-narrow,
.cellar .wrap-wide {
  position: relative;
  z-index: 3;
}

/* A short dark band (a pull-quote, say) would otherwise have 365px of fade
   in 300px of band and never reach full colour. Below that height the fades
   shorten so the band still has a solid middle. */
@media (max-height: 100000px) {
  .cellar.cellar-short::before {
    background-size:
      100% 90px,
      100% 80px,
      100% 80px,
      100% 100px,
      100% 95px;
  }
}


/* --------------------------------------------------------------------------
   Same day, one tightening pass.

   With both fades finally painting, they turned out far too long: 190px in,
   the "OUR VISION" label was still sitting on a pale wash and losing its
   contrast, and the band never reached full colour in the middle. A fade
   should hand the eye from one pane to the next, then get out of the way.

   Fades come down to 100px in and 110px out, the washes with them, and the
   band gains a little extra padding so the fade zone stays empty and no
   copy ever sits on a gradient.
   -------------------------------------------------------------------------- */

.cellar::before {
  background-size:
    100% 95px,
    100% 80px,
    100% 90px,
    100% 100px,
    100% 110px;
  background-image:
    radial-gradient(130% 60px at 16% 0%, rgba(240, 234, 223, 0.3), rgba(240, 234, 223, 0) 74%),
    radial-gradient(110% 50px at 76% 0%, rgba(240, 234, 223, 0.24), rgba(240, 234, 223, 0) 76%),
    radial-gradient(130% 56px at 70% 100%, rgba(240, 234, 223, 0.27), rgba(240, 234, 223, 0) 74%),
    linear-gradient(
      180deg,
      rgba(240, 234, 223, 1) 0%,
      rgba(240, 234, 223, 0.96) 7%,
      rgba(240, 234, 223, 0.88) 16%,
      rgba(240, 234, 223, 0.75) 27%,
      rgba(240, 234, 223, 0.59) 39%,
      rgba(240, 234, 223, 0.42) 52%,
      rgba(240, 234, 223, 0.27) 65%,
      rgba(240, 234, 223, 0.14) 78%,
      rgba(240, 234, 223, 0.05) 90%,
      rgba(240, 234, 223, 0) 100%
    ),
    linear-gradient(
      0deg,
      rgba(240, 234, 223, 1) 0%,
      rgba(240, 234, 223, 0.96) 7%,
      rgba(240, 234, 223, 0.88) 16%,
      rgba(240, 234, 223, 0.75) 27%,
      rgba(240, 234, 223, 0.59) 39%,
      rgba(240, 234, 223, 0.42) 52%,
      rgba(240, 234, 223, 0.27) 65%,
      rgba(240, 234, 223, 0.14) 78%,
      rgba(240, 234, 223, 0.05) 90%,
      rgba(240, 234, 223, 0) 100%
    );
}

/* Clearance, so the label and the first line of copy always sit on solid
   colour rather than on the tail of a fade. */
.cellar {
  padding-top: calc(var(--rhythm) * 0.55 + 2.5rem);
  padding-bottom: calc(var(--rhythm) * 0.55 + 2.5rem);
}

@media (max-width: 860px) {
  .cellar::before {
    background-size:
      100% 70px,
      100% 60px,
      100% 66px,
      100% 74px,
      100% 80px;
  }

  .cellar {
    padding-top: calc(var(--rhythm) * 0.45 + 1.6rem);
    padding-bottom: calc(var(--rhythm) * 0.45 + 1.6rem);
  }
}


/* --------------------------------------------------------------------------
   And the colour of the transition itself.

   A pale cream fading into #2d2521 passes through grey on the way — the two
   colours are warm at either end but their midpoint is not, so the middle of
   every ramp came out faintly cool and slightly lavender. It reads as haze.

   The ramps now travel through clay rather than straight through cream, so
   the join warms as it darkens and lands in the band's own family. Same
   lengths, same easing — only the hue in the middle changes.
   -------------------------------------------------------------------------- */

.cellar::before {
  background-image:
    radial-gradient(130% 60px at 16% 0%, rgba(240, 234, 223, 0.3), rgba(240, 234, 223, 0) 74%),
    radial-gradient(110% 50px at 76% 0%, rgba(232, 219, 198, 0.24), rgba(232, 219, 198, 0) 76%),
    radial-gradient(130% 56px at 70% 100%, rgba(236, 226, 209, 0.27), rgba(236, 226, 209, 0) 74%),
    linear-gradient(
      180deg,
      rgba(240, 234, 223, 1) 0%,
      rgba(238, 230, 217, 0.96) 7%,
      rgba(233, 222, 204, 0.88) 16%,
      rgba(225, 210, 187, 0.75) 27%,
      rgba(213, 193, 165, 0.59) 39%,
      rgba(197, 174, 143, 0.42) 52%,
      rgba(179, 154, 122, 0.27) 65%,
      rgba(159, 133, 103, 0.14) 78%,
      rgba(139, 114, 87, 0.05) 90%,
      rgba(120, 98, 76, 0) 100%
    ),
    linear-gradient(
      0deg,
      rgba(240, 234, 223, 1) 0%,
      rgba(238, 230, 217, 0.96) 7%,
      rgba(233, 222, 204, 0.88) 16%,
      rgba(225, 210, 187, 0.75) 27%,
      rgba(213, 193, 165, 0.59) 39%,
      rgba(197, 174, 143, 0.42) 52%,
      rgba(179, 154, 122, 0.27) 65%,
      rgba(159, 133, 103, 0.14) 78%,
      rgba(139, 114, 87, 0.05) 90%,
      rgba(120, 98, 76, 0) 100%
    );
}


/* ==========================================================================
   2026-09-18 — every join, not just the dark ones. And all of them shallower.

   The dark bands could be faded by laying cream over them: there was a light
   side to fade toward. Between two light panes there isn't one. Sand
   (#EDE8D8), paper (#F6EFE9), the raised cream (#f2e8dc) and the founders'
   warmer cream (#f0e2c6) are all within about ten points of each other —
   close enough that a veil of either one over the other does nothing, and
   far enough apart that the join still reads as a drawn line.

   So these joins converge instead. A soft band of neutral cream straddles
   the boundary — strongest exactly at the seam, easing to nothing about
   55px into each pane. At the boundary both sides are wearing the same
   wash, so whatever difference existed between them is gone; 55px away
   each pane is fully itself again. Neither colour wins; they meet.

   One band per join, on the lower section, reaching up across the seam.
   And every fade on the site comes down by roughly a quarter — the dark
   ones included, which Heidi found a touch deep.
   ========================================================================== */

/* ---- 1. Light-to-light joins. */

.section:not(.cellar) + .section:not(.cellar)::before {
  content: "";
  position: absolute;
  top: -55px;
  left: 0;
  right: 0;
  bottom: auto;
  height: 110px;
  width: auto;
  pointer-events: none;
  z-index: 1;
  background: linear-gradient(
    180deg,
    rgba(241, 234, 224, 0) 0%,
    rgba(241, 234, 224, 0.2) 22%,
    rgba(241, 234, 224, 0.52) 38%,
    rgba(241, 234, 224, 0.78) 47%,
    rgba(241, 234, 224, 0.88) 50%,
    rgba(241, 234, 224, 0.78) 53%,
    rgba(241, 234, 224, 0.52) 62%,
    rgba(241, 234, 224, 0.2) 78%,
    rgba(241, 234, 224, 0) 100%
  );
}

/* The hairline and its thread of light are what the fade replaces — a rule
   and a fade at the same seam is what made these read as cuts. The drop
   shadow goes with them. */
.section:not(.cellar) + .section:not(.cellar)::after {
  content: "";
}

.section:not(.cellar) + .section:not(.cellar) {
  box-shadow: none;
}

/* The weave texture on light panes lives on ::after, which the seam rules
   also used. Restated here so the join band never costs a pane its tooth. */
.section:not(.cellar) + .section:not(.cellar)::after {
  position: absolute;
  inset: 0;
  height: auto;
  pointer-events: none;
  opacity: 0.85;
  background-color: transparent;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='90' height='90'%3E%3Cfilter id='f'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.04 0.55' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='90' height='90' filter='url(%23f)' opacity='0.3'/%3E%3C/svg%3E");
  mix-blend-mode: multiply;
  z-index: 2;
}

/* Copy sits above both. */
.section .wrap,
.section .wrap-narrow,
.section .wrap-wide {
  position: relative;
  z-index: 3;
}

/* ---- 2. Every fade, shallower.

   Dark bands: 100px in / 110px out becomes 76px / 84px. Still eased, still
   opaque at the seam — just less of the band given over to the transition,
   so each one holds its own colour for longer. */

.cellar::before {
  background-size:
    100% 72px,
    100% 60px,
    100% 68px,
    100% 76px,
    100% 84px;
}

.cellar {
  padding-top: calc(var(--rhythm) * 0.55 + 1.9rem);
  padding-bottom: calc(var(--rhythm) * 0.55 + 1.9rem);
}

@media (max-width: 860px) {
  .section:not(.cellar) + .section:not(.cellar)::before {
    top: -40px;
    height: 80px;
  }

  .cellar::before {
    background-size:
      100% 54px,
      100% 46px,
      100% 50px,
      100% 56px,
      100% 62px;
  }

  .cellar {
    padding-top: calc(var(--rhythm) * 0.45 + 1.2rem);
    padding-bottom: calc(var(--rhythm) * 0.45 + 1.2rem);
  }
}

@media print {
  .section:not(.cellar) + .section:not(.cellar)::before {
    display: none;
  }
}


/* ==========================================================================
   2026-09-18 — the candle was eating the fade.

   The dark bands have always had a warm brick-red glow at their foot with a
   slow 7-second flicker, like candlelight. That glow was painted on
   `.cellar::before` — the same element I moved both fades onto. So the
   flicker's keyframes, which animate opacity from 0.55 to 1, were being
   applied to the fades as well.

   That is why the joins looked fixed on one page and untouched on another:
   they were breathing. Catch the cycle at the top and the fade is at full
   strength; catch it at the bottom and the fade is at 55% and the join
   reads as a cut again. An animation overrides an ordinary declaration, so
   nothing I wrote on that element could win against it.

   The glow moves to its own element inside the band, keeping its flicker
   exactly as it was. The fades stay on `::before` and stop animating.
   ========================================================================== */

.cellar::before {
  animation: none;
}

[data-arrived] .cellar::before {
  animation: none;
}

/* The candle, rehoused. Same colour, same position at the foot of the band,
   same 7s flicker. It spills past the text column the way it used to spill
   past the section edges, and the band's own `overflow: hidden` keeps it
   inside. z-index -1 puts it behind the copy but in front of the fades, so
   it warms the outgoing transition rather than being cut off by it. */
.cellar .wrap::before,
.cellar .wrap-narrow::before,
.cellar .wrap-wide::before {
  content: "";
  position: absolute;
  left: -50vw;
  right: -50vw;
  bottom: -40%;
  height: 80%;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(50% 60% at 50% 100%, rgba(178, 74, 59, 0.28), transparent 70%);
}

[data-arrived] .cellar .wrap::before,
[data-arrived] .cellar .wrap-narrow::before,
[data-arrived] .cellar .wrap-wide::before {
  animation: candle 7s ease-in-out infinite alternate;
}

@media (prefers-reduced-motion: reduce) {
  [data-arrived] .cellar .wrap::before,
  [data-arrived] .cellar .wrap-narrow::before,
  [data-arrived] .cellar .wrap-wide::before {
    animation: none;
    opacity: 0.8;
  }
}


/* ==========================================================================
   2026-09-18 — the actual reason the home page never changed.

   Not ordering. Specificity.

   An early pass wrote `.section + .cellar::before { background: none }` to
   remove the hairline seam. That selector scores two classes. Every fade
   rule I have written since scores one — `.cellar::before` — so no matter
   how far down the file it sits, it loses. CSS does not care that mine came
   later; the more specific selector wins.

   And that is exactly why the two pages disagreed. On Our Story the dark
   band follows the page hero, which is not a `.section`, so the killer
   selector never matched and the fade worked. On the home page the dark
   band follows a `.section`, the selector matched, and `background: none`
   erased the whole thing. Same stylesheet, same band, opposite result,
   decided entirely by what happens to sit above it.

   Restated here at three classes so it outranks anything that came before,
   and written once as the single source of truth for both fades.
   ========================================================================== */

.cellar.cellar.cellar::before {
  content: "";
  position: absolute;
  inset: 0;
  height: auto;
  width: auto;
  pointer-events: none;
  z-index: 1;
  animation: none;
  background-color: transparent;
  background-image:
    radial-gradient(130% 60px at 16% 0%, rgba(240, 234, 223, 0.3), rgba(240, 234, 223, 0) 74%),
    radial-gradient(110% 50px at 76% 0%, rgba(232, 219, 198, 0.24), rgba(232, 219, 198, 0) 76%),
    radial-gradient(130% 56px at 70% 100%, rgba(236, 226, 209, 0.27), rgba(236, 226, 209, 0) 74%),
    linear-gradient(
      180deg,
      rgba(240, 234, 223, 1) 0%,
      rgba(238, 230, 217, 0.96) 7%,
      rgba(233, 222, 204, 0.88) 16%,
      rgba(225, 210, 187, 0.75) 27%,
      rgba(213, 193, 165, 0.59) 39%,
      rgba(197, 174, 143, 0.42) 52%,
      rgba(179, 154, 122, 0.27) 65%,
      rgba(159, 133, 103, 0.14) 78%,
      rgba(139, 114, 87, 0.05) 90%,
      rgba(120, 98, 76, 0) 100%
    ),
    linear-gradient(
      0deg,
      rgba(240, 234, 223, 1) 0%,
      rgba(238, 230, 217, 0.96) 7%,
      rgba(233, 222, 204, 0.88) 16%,
      rgba(225, 210, 187, 0.75) 27%,
      rgba(213, 193, 165, 0.59) 39%,
      rgba(197, 174, 143, 0.42) 52%,
      rgba(179, 154, 122, 0.27) 65%,
      rgba(159, 133, 103, 0.14) 78%,
      rgba(139, 114, 87, 0.05) 90%,
      rgba(120, 98, 76, 0) 100%
    );
  background-size:
    100% 72px,
    100% 60px,
    100% 68px,
    100% 76px,
    100% 84px;
  background-position:
    top left,
    top left,
    bottom left,
    top left,
    bottom left;
  background-repeat: no-repeat;
}

[data-arrived] .cellar.cellar.cellar::before {
  animation: none;
}

@media (max-width: 860px) {
  .cellar.cellar.cellar::before {
    background-size:
      100% 54px,
      100% 46px,
      100% 50px,
      100% 56px,
      100% 62px;
  }
}

/* The light-to-light join band, raised to the same rank for the same reason:
   `.section + .section::before` also scores two classes and also sets
   `background` to a hairline. */
.section:not(.cellar).section + .section:not(.cellar).section::before {
  background-color: transparent;
  background-image: linear-gradient(
    180deg,
    rgba(241, 234, 224, 0) 0%,
    rgba(241, 234, 224, 0.2) 22%,
    rgba(241, 234, 224, 0.52) 38%,
    rgba(241, 234, 224, 0.78) 47%,
    rgba(241, 234, 224, 0.88) 50%,
    rgba(241, 234, 224, 0.78) 53%,
    rgba(241, 234, 224, 0.52) 62%,
    rgba(241, 234, 224, 0.2) 78%,
    rgba(241, 234, 224, 0) 100%
  );
  top: -55px;
  height: 110px;
  z-index: 1;
}

@media (max-width: 860px) {
  .section:not(.cellar).section + .section:not(.cellar).section::before {
    top: -40px;
    height: 80px;
  }
}

@media print {
  .cellar.cellar.cellar::before,
  .section:not(.cellar).section + .section:not(.cellar).section::before {
    display: none;
  }
}


/* ==========================================================================
   2026-09-18 — the fades stop assuming what they are fading into.

   Heidi: "it's not doing it on the gray, and the black either."

   She is right, and the width was never the problem. Every fade I have
   written so far ends in a fixed cream, #F0EADF, because the first joins I
   fixed happened to have cream on the light side. But the site has four
   pane colours:

     --bg        #ede8d8   sand      the default pane
     --bg-raise  #f2e8dc   raised    warmer
     --bg-sink   #ded5c8   sink      the grey-taupe one
     --cellar-bg #2d2521   the dark band

   So a dark band that fades out to cream, sitting above a SINK pane, fades
   perfectly — and then steps straight from cream to grey-taupe at the seam.
   The fade was real; it was just landing on the wrong colour. Same story
   wherever a sink pane meets anything.

   The fix is to stop naming a colour at all. Each section now declares its
   own background as `--pane`, and the blend is painted by the LOWER section
   reaching up across the seam, fading from transparent into its own colour.
   A section only ever has to know what colour IT is. Whatever sits above it
   dissolves into it over 58px, and below the seam the gradient has already
   arrived at the pane's exact colour, so there is nothing to step to.

   One rule, every join, every colour pair, forever. Nothing to keep in sync.
   ========================================================================== */

/* ---- 1. Every pane declares itself. */

.section {
  --pane: var(--bg);
}

.section-sink {
  --pane: var(--bg-sink);
}

.section-raise {
  --pane: var(--bg-raise);
}

.section-founders {
  --pane: #f0e2c6;
}

.cellar {
  --pane: var(--cellar-bg);
}

/* The dark band clipped its own overflow, which would cut off a blend that
   reaches upward. It no longer needs to: the candle glow it was containing
   now sits inside the text column (below) rather than spilling past the
   section edges. */
.cellar {
  overflow: visible;
}

/* ---- 2. One blend, on every join. */

.section.section + .section.section::before,
.hero + .section.section::before {
  content: "";
  position: absolute;
  top: -58px;
  bottom: auto;
  left: 0;
  right: 0;
  width: auto;
  height: 58px;
  z-index: 1;
  pointer-events: none;
  animation: none;
  background-color: transparent;
  background-image: linear-gradient(
    180deg,
    color-mix(in srgb, var(--pane) 0%, transparent) 0%,
    color-mix(in srgb, var(--pane) 12%, transparent) 22%,
    color-mix(in srgb, var(--pane) 30%, transparent) 38%,
    color-mix(in srgb, var(--pane) 50%, transparent) 52%,
    color-mix(in srgb, var(--pane) 70%, transparent) 66%,
    color-mix(in srgb, var(--pane) 86%, transparent) 80%,
    color-mix(in srgb, var(--pane) 95%, transparent) 90%,
    var(--pane) 100%
  );
  background-size: 100% 100%;
  background-position: top left;
  background-repeat: no-repeat;
}

/* Anything without color-mix keeps a plain two-stop blend rather than
   nothing at all. */
@supports not (background-image: linear-gradient(180deg, color-mix(in srgb, red 50%, transparent), red)) {
  .section.section + .section.section::before,
  .hero + .section.section::before {
    background-image: linear-gradient(180deg, transparent 0%, var(--pane) 100%);
  }
}

/* ---- 3. The old fades stand down.

   Both of the dark band's own fades are now done for it — the incoming one
   by its own rule above, the outgoing one by whatever section follows it,
   reaching up. Leaving the old ones in place would double the transition. */

.cellar.cellar.cellar::before {
  background-image: none;
}

.cellar.cellar.cellar.cellar::before {
  content: "";
  position: absolute;
  top: -58px;
  bottom: auto;
  left: 0;
  right: 0;
  height: 58px;
  background-image: linear-gradient(
    180deg,
    color-mix(in srgb, var(--cellar-bg) 0%, transparent) 0%,
    color-mix(in srgb, var(--cellar-bg) 12%, transparent) 22%,
    color-mix(in srgb, var(--cellar-bg) 30%, transparent) 38%,
    color-mix(in srgb, var(--cellar-bg) 50%, transparent) 52%,
    color-mix(in srgb, var(--cellar-bg) 70%, transparent) 66%,
    color-mix(in srgb, var(--cellar-bg) 86%, transparent) 80%,
    color-mix(in srgb, var(--cellar-bg) 95%, transparent) 90%,
    var(--cellar-bg) 100%
  );
  background-size: 100% 100%;
  background-repeat: no-repeat;
  background-position: top left;
  z-index: 1;
}

/* The band's interior shading stays; it was never part of the problem. */
.cellar {
  padding-top: calc(var(--rhythm) * 0.55 + 1.1rem);
  padding-bottom: calc(var(--rhythm) * 0.55 + 1.1rem);
}

/* ---- 4. The candle, contained without clipping. */

.cellar .wrap::before,
.cellar .wrap-narrow::before,
.cellar .wrap-wide::before {
  left: 0;
  right: 0;
  background: radial-gradient(85% 60% at 50% 100%, rgba(178, 74, 59, 0.3), transparent 72%);
}

@media (max-width: 860px) {
  .section.section + .section.section::before,
  .hero + .section.section::before,
  .cellar.cellar.cellar.cellar::before {
    top: -42px;
    height: 42px;
  }
}

@media print {
  .section.section + .section.section::before,
  .hero + .section.section::before,
  .cellar.cellar.cellar.cellar::before {
    display: none;
  }
}


/* ==========================================================================
   2026-09-18 — the candle escaped.

   That rose-coloured rectangle behind "When our doors open" is the dark
   band's candle glow, leaking several sections down the page.

   My fault, and a direct consequence of the previous change. The glow was
   written as `bottom: -40%; height: 80%` — deliberately hanging 40% of its
   height BELOW the band, because `.cellar { overflow: hidden }` used to
   crop it into a soft pool of light at the band's foot. When I removed that
   clipping so the blends could reach up across the seam, I removed the only
   thing holding the glow in. It kept its old geometry and simply spilled,
   still drawn at the width of the text column, which is why it reads as a
   rectangle with edges rather than as light.

   The glow is now sized to sit entirely inside the band, so it needs no
   clipping from anything. Its falloff finishes well before the edges of its
   own box, which is what stops it having corners.
   ========================================================================== */

.cellar .wrap::before,
.cellar .wrap-narrow::before,
.cellar .wrap-wide::before {
  bottom: 0;
  top: auto;
  height: 52%;
  left: 0;
  right: 0;
  background: radial-gradient(78% 88% at 50% 100%, rgba(178, 74, 59, 0.3), rgba(178, 74, 59, 0) 68%);
}

/* Belt and braces: nothing inside a dark band may paint outside it, whatever
   geometry a future pass gives it. `clip-path` crops the children without
   creating a scroll container, so — unlike `overflow: hidden` — the band's
   own blend can still reach up across the seam above it. */
.cellar > .wrap,
.cellar > .wrap-narrow,
.cellar > .wrap-wide {
  clip-path: inset(0 -50vw 0 -50vw);
}


/* ==========================================================================
   2026-09-22 — words under the seam.

   Every join between two sections carries a soft colour blend that reaches
   58px UP into the section above it (42px on phones). It sat on top of that
   section's last line, so whatever ended a section — a salon date, a note,
   a button — was washed pale and looked blurred. The dark cellar band was
   already lifted above its fades; now every light section is too. The
   blend still softens the backgrounds; it just goes behind the words.
   ========================================================================== */
.hero > .wrap,
.hero > .wrap-narrow,
.hero > .wrap-wide,
.section:not(.cellar) > .wrap,
.section:not(.cellar) > .wrap-narrow,
.section:not(.cellar) > .wrap-wide {
  position: relative;
  z-index: 3;
}


/* Why handmade carousel: one reason at a time, words above, the whole
   photograph below (never cropped), round arrows and dots to move. */
.why-five { padding-block: 3rem 4rem; }
.why-car { max-width: 46rem; margin-inline: auto; outline: none; }
.why-car:focus-visible { outline: 2px solid var(--red); outline-offset: 8px; }
.why-car-bar { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 1.25rem; }
.why-count { margin: 0; font-size: 0.78rem; letter-spacing: 0.24em; text-transform: uppercase; color: var(--dirt); }
.why-arrows { display: flex; gap: 0.6rem; }
.why-arrow { width: 2.9rem; height: 2.9rem; border-radius: 50%; border: 1px solid var(--fg); background: transparent; color: var(--fg); font-size: 1.1rem; line-height: 1; cursor: pointer; display: grid; place-items: center; transition: background 0.2s, color 0.2s; }
.why-arrow:hover, .why-arrow:focus-visible { background: var(--fg); color: var(--sand); outline: none; }
.why-slides { display: grid; }
.why-slide { grid-area: 1 / 1; min-width: 0; visibility: hidden; opacity: 0; transition: opacity 0.45s ease, visibility 0s linear 0.45s; }
.why-slide.is-active { visibility: visible; opacity: 1; transition: opacity 0.45s ease; animation: whySlideIn 0.55s ease both; }
@keyframes whySlideIn { from { transform: translateX(18px); } to { transform: none; } }
.why-slide-title { margin: 0 0 0.75rem; font-size: clamp(1.6rem, 2.6vw, 2.2rem); text-wrap: balance; }
.why-slide-text { margin: 0 0 1.5rem; max-width: 62ch; }
.route-why-handmade .why-slide-photo { aspect-ratio: auto; height: clamp(18rem, 55vh, 34rem); background: transparent; border-radius: 0; display: flex; justify-content: flex-start; align-items: flex-start; overflow: visible; }
.route-why-handmade .why-slide-photo img { width: auto; max-width: 100%; height: 100%; object-fit: contain; object-position: left top; border-radius: var(--radius); }
.why-dots { display: flex; gap: 0.6rem; justify-content: center; margin-top: 1.5rem; }
.why-dot { width: 0.65rem; height: 0.65rem; border-radius: 50%; border: 1px solid var(--fg); background: transparent; padding: 0; cursor: pointer; }
.why-dot[aria-current="true"] { background: var(--red); border-color: var(--red); }
@media (max-width: 760px) {
  .route-why-handmade .why-slide-photo { height: auto; max-height: 70vh; }
  .route-why-handmade .why-slide-photo img { width: 100%; height: auto; max-height: 70vh; }
}
@media (prefers-reduced-motion: reduce) {
  .why-slide, .why-slide.is-active { transition: none; animation: none; }
}

/* A carousel photo with its own ratio (set in content.json) is trimmed to it,
   e.g. to leave out a phone's shadow along the bottom edge. */
.route-why-handmade .why-slide-photo[style*="--ratio"] { aspect-ratio: var(--ratio); width: auto; max-width: 100%; overflow: hidden; border-radius: var(--radius); }
.route-why-handmade .why-slide-photo[style*="--ratio"] img { width: 100%; height: 100%; object-fit: cover; object-position: var(--pos, center center); }
@media (max-width: 760px) {
  .route-why-handmade .why-slide-photo[style*="--ratio"] { width: 100%; height: auto; max-height: none; }
  .route-why-handmade .why-slide-photo[style*="--ratio"] img { max-height: none; }
}

/* =====================================================================
   DESIGN SERVICES + the Beattle titles (October 7, 2026).
   Beattle is the brand's display face (BRAND IDENTITY › 02 Fonts, "Logo
   and Special Use"). Heidi chose it for page titles and offer titles on
   the Design mockup and asked for the whole site to match. Everything
   below is scoped so it can be lifted out in one piece. --display is the
   one variable that decides it.
   ===================================================================== */
@font-face {
  font-family: "Beattle";
  src: url("https://lovable-crab-328.convex.cloud/api/storage/fe7f0337-fb5e-4e07-abbe-1a85e4658e50") format("opentype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  --display: "Beattle", "Vollkorn", "Iowan Old Style", Georgia, serif;
}

/* 1. Titles sitewide: page titles and the names of things (offers, cards,
   events, founders) wear Beattle; section statements wear Vollkorn; the
   eyebrows, labels and buttons stay Cousine. This is the mockup's system. */
h1,
.title,
.display,
.card-heading,
.event-title,
.founder-copy h2,
.form-panel h2,
.form-layout h2 {
  font-family: var(--display);
  font-weight: 400;
  letter-spacing: 0;
}

h2,
h3,
.statement {
  font-family: var(--body);
  font-weight: 400;
  letter-spacing: -0.01em;
}

/* 2. The linen weave from the announcement bar, as classes. The colour
   matrix MUST carry exactly 20 values or the browser drops the filter. */
.linen-sand {
  background-color: var(--sand);
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='w'><feTurbulence type='fractalNoise' baseFrequency='0.02 0.9' numOctaves='2' seed='7' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.47 0 0 0 0 0.38 0 0 0 0 0.30 0 0 0 0.12 0'/></filter><rect width='100%25' height='100%25' filter='url(%23w)'/></svg>"),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='v'><feTurbulence type='fractalNoise' baseFrequency='0.9 0.02' numOctaves='2' seed='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.47 0 0 0 0 0.38 0 0 0 0 0.30 0 0 0 0.09 0'/></filter><rect width='100%25' height='100%25' filter='url(%23v)'/></svg>");
  background-repeat: repeat;
}

.linen-clay {
  background-color: var(--clay);
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='w'><feTurbulence type='fractalNoise' baseFrequency='0.02 0.9' numOctaves='2' seed='7' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.93 0 0 0 0 0.91 0 0 0 0 0.85 0 0 0 0.20 0'/></filter><rect width='100%25' height='100%25' filter='url(%23w)'/></svg>"),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='v'><feTurbulence type='fractalNoise' baseFrequency='0.9 0.02' numOctaves='2' seed='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.47 0 0 0 0 0.38 0 0 0 0 0.30 0 0 0 0.12 0'/></filter><rect width='100%25' height='100%25' filter='url(%23v)'/></svg>");
  background-repeat: repeat;
}

/* 3. The Design page. */
.route-design .hero,
.route-design-service .hero {
  padding-bottom: var(--s6);
}

.design-hero {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 0.6fr);
  gap: var(--col-gap);
  align-items: start;
}

.design-hero .lede {
  max-width: 60ch;
  font-size: clamp(1.15rem, 1.7vw, 1.45rem);
  color: var(--dirt);
}

.design-mark {
  justify-self: end;
  width: clamp(9rem, 20vw, 17rem);
  height: auto;
}

.design-cards {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s5);
}

.design-card {
  display: flex;
  flex-direction: column;
  gap: var(--s4);
  padding: var(--s6) var(--s5) var(--s5);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background-color: var(--paper);
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='w'><feTurbulence type='fractalNoise' baseFrequency='0.02 0.9' numOctaves='2' seed='7' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.47 0 0 0 0 0.38 0 0 0 0 0.30 0 0 0 0.10 0'/></filter><rect width='100%25' height='100%25' filter='url(%23w)'/></svg>"),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='v'><feTurbulence type='fractalNoise' baseFrequency='0.9 0.02' numOctaves='2' seed='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.47 0 0 0 0 0.38 0 0 0 0 0.30 0 0 0 0.08 0'/></filter><rect width='100%25' height='100%25' filter='url(%23v)'/></svg>");
  background-repeat: repeat;
}

.design-card-icon {
  width: 8.4rem;
  height: 8.4rem;
  object-fit: contain;
  display: block;
}

.design-card .eyebrow {
  margin-bottom: 0;
  font-size: 0.95rem;
  letter-spacing: 0.12em;
  color: var(--dirt);
}

.design-card .eyebrow::before {
  display: none;
}

.design-card-title {
  font-family: var(--display);
  font-size: clamp(2rem, 3vw, 3rem);
  line-height: 1;
  color: var(--dirt);
  margin: 0;
}

.design-card-price {
  font-family: var(--body);
  font-size: 1.9rem;
  color: var(--red);
  margin: 0;
}

.design-card-text {
  font-family: var(--body);
  font-size: 1.2rem;
  line-height: 1.55;
  margin: 0;
}

.design-card ul {
  margin: 0;
  padding-left: 1.2rem;
  font-family: var(--body);
  font-size: 1.05rem;
  line-height: 1.6;
}

.design-card .button {
  margin-top: auto;
  align-self: stretch;
  font-size: 1.05rem;
  letter-spacing: 0;
}

/* The clay band, with the fades into and out of it as on the rest of the site. */
.design-how {
  position: relative;
  color: var(--fg);
}

.design-fade-in,
.design-fade-out {
  height: clamp(2.5rem, 5vw, 4.5rem);
}

.design-fade-in {
  background: linear-gradient(to bottom, var(--sand) 0%, rgba(171, 142, 105, 0.45) 55%, var(--clay) 100%);
}

.design-fade-out {
  background: linear-gradient(to top, var(--sand) 0%, rgba(171, 142, 105, 0.45) 55%, var(--clay) 100%);
}

.design-how .wrap {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
  gap: var(--col-gap);
  align-items: start;
}

.design-how .eyebrow {
  color: var(--red);
  font-weight: 700;
  font-size: 1.5rem;
  letter-spacing: 0.12em;
}

.design-how .eyebrow::before {
  display: none;
}

.design-how h2 {
  font-size: clamp(1.7rem, 3vw, 2.4rem);
  line-height: 1.1;
}

.design-how ol {
  margin: 0;
  padding-left: 1.4rem;
  font-family: var(--body);
  font-size: 1.3rem;
  line-height: 1.5;
  display: flex;
  flex-direction: column;
  gap: var(--s3);
}

.design-bigger-head {
  max-width: 48rem;
}

.design-bigger-head .eyebrow {
  color: var(--red);
  font-weight: 700;
  font-size: 1.6rem;
  letter-spacing: 0.12em;
}

.design-bigger-head .eyebrow::before {
  display: none;
}

.design-bigger-head h2 {
  font-size: clamp(1.6rem, 2.6vw, 2.2rem);
  line-height: 1.15;
}

.design-bigger {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--col-gap);
  margin-top: var(--s7);
}

.design-option {
  display: flex;
  flex-direction: column;
  gap: var(--s4);
}

.design-option .photo {
  --ratio: 16 / 10;
}

.design-option h3 {
  font-family: var(--display);
  font-size: clamp(1.8rem, 2.6vw, 2.5rem);
  line-height: 1;
  color: var(--dirt);
}

.design-option p {
  font-family: var(--body);
  font-size: 1.2rem;
  line-height: 1.55;
  margin: 0;
}

.design-option .button {
  margin-top: auto;
  align-self: flex-start;
  font-size: 1.05rem;
  letter-spacing: 0;
}

/* Service pages: the price sits under the title, the form on the right. */
.design-price {
  font-family: var(--body);
  font-size: clamp(1.6rem, 2.4vw, 2.2rem);
  color: var(--red);
  margin-top: var(--s3);
}

.design-service-list {
  margin: var(--s5) 0 0;
  padding-left: 1.2rem;
  font-family: var(--body);
  font-size: 1.05rem;
  line-height: 1.6;
}

@media (max-width: 860px) {
  .design-hero,
  .design-cards,
  .design-how .wrap,
  .design-bigger {
    grid-template-columns: 1fr;
  }
  .design-mark {
    justify-self: start;
    width: 9rem;
  }
}

/* The note beside a design form reads in Vollkorn, like the service copy above it. */
.route-design-service .form-layout .sub {
  font-family: var(--body);
  font-size: 1.15rem;
  line-height: 1.55;
}

/* Oct 7, late: Heidi's Mac showed /design with only the eyebrows and the mark
   painted. The headless checks could not reproduce it, so the heaviest new
   paint work (the SVG-filter linen on the whole route and on the cards) is
   switched off until the cause is known. The clay band keeps its weave. */
.design-card {
  background-image: none;
}

/* Oct 7 (Heidi): on every hero that pairs text with a photo (Visit, Rentals,
   Events, the salons...), the words sit level with the top of the photo
   instead of dropping to its foot. The photo keeps its overhang into the
   next section. */
.hero-offset {
  align-items: start;
}

/* Oct 7 (Heidi): The Whole Picture and The Hunt are tiles like the three
   above, no photos. Two across, same card, same type. */
.design-bigger {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s5);
  margin-top: var(--s6);
}

.design-card-bigger .button {
  align-self: stretch;
}

@media (max-width: 860px) {
  .design-bigger {
    grid-template-columns: 1fr;
  }
}

/* "Something bigger" headline: full width so it sits on one line on a desktop;
   each sentence is an unbreakable phrase, so on a narrower screen the break
   falls after "rebirth." and never inside a sentence. */
.design-bigger-head {
  max-width: none;
}

.design-bigger-head h2 .phrase {
  display: inline-block;
}

.design-bigger-head h2 .phrase {
  vertical-align: top;
}

/* Oct 7 (Heidi): Events page. The hero carries no photo; the brass sculpture
   moved into the Mondays band in place of the archway, and the salon heading
   sits at the top of the band rather than floating mid-photo. */
.route-gather .cellar-grid {
  align-items: start;
}

.route-gather .cellar-grid .photo {
  --ratio: 4 / 5;
  max-width: 26rem;
  justify-self: end;
}

/* Oct 7 (Heidi): Our Vision band. No mustard rules above the two "A world"
   statements, and they start level with the headline beside them. */
.vision-worlds {
  padding-top: 0;
  gap: var(--s5);
}

.vision-worlds .pillar {
  border-top: 0;
  padding-top: 0;
}

/* Oct 7 (Heidi): Events page, tighter. The Mondays band meets the sand with
   one clean seam, no melt bands above and below, and the space between the
   hero, the band and "The season ahead" is halved. */
.route-gather .cellar {
  margin-top: 0;
  margin-bottom: 0;
  padding-top: calc(var(--rhythm) * 0.6);
  padding-bottom: calc(var(--rhythm) * 0.6);
}

.route-gather .cellar::after,
.route-gather .cellar .cellar-fade-bottom {
  display: none;
}

.route-gather .hero-inner {
  padding-bottom: calc(var(--rhythm) * 0.5);
}

.route-gather .cellar + .section {
  padding-top: calc(var(--rhythm) * 0.6);
}

/* Oct 7 (Heidi): a smaller sculpture in the Mondays band, so the band is
   only as tall as its words, and "The season ahead" follows straight after. */
.route-gather .cellar-grid {
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
}

.route-gather .cellar-grid .photo {
  --ratio: 1 / 1;
  max-width: 18rem;
  justify-self: end;
}

.route-gather .cellar {
  padding-bottom: calc(var(--rhythm) * 0.45);
}

.route-gather .cellar + .section {
  padding-top: calc(var(--rhythm) * 0.4);
}

/* Oct 8 (Heidi): salon cards. The description takes up the slack, so the red
   dates, the seats note and "Reserve your seat" line up across every card. */
.route-gather .event-card {
  display: flex;
  flex-direction: column;
}

.route-gather .event-card .event-sub {
  flex: 1 0 auto;
}


/* Oct 8, 2026: nine salons on /events — three rows of three on wide screens
   instead of 4 + 4 + 1 with Play alone on the last row. */
@media (min-width: 60rem) {
  .route-gather .events {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}


/* Oct 8, 2026 (Heidi): "When the door is open" sat too far below the hero —
   trim the top of the week section on /visit. */
.route-visit .section[aria-labelledby="week-heading"] {
  padding-top: var(--s6);
}


/* Oct 8, 2026: Mothers, Daughters & the Women Who Raised Us — one card in its
   own section on /events, wider than a salon card, never stretched full-width. */
.route-gather .events.events-one {
  grid-template-columns: minmax(0, 34rem);
}
.route-gather .section-mothers {
  padding-top: 0;
}
