/* ============================================================
   COMMONPLACE — commonplaceformation.org

   Mobile first. One column throughout; the bands that carry two
   photographs put them side by side beneath their copy.

   Type follows the brand: Bookmania Light carries the display
   lines and nothing else, DM Sans carries the reading, JetBrains
   Mono carries every label and link-tag. Colour is not decoration
   here — each band takes a different ground so the page reads as
   a sequence of rooms rather than one long scroll.
   ============================================================ */

/* ---------------- Typefaces ---------------- */
@font-face{ font-family:"Bookmania"; src:url("fonts/bookmania-light.woff2") format("woff2");
  font-weight:300; font-style:normal; font-display:swap; }
@font-face{ font-family:"Bookmania"; src:url("fonts/bookmania-regular.woff2") format("woff2");
  font-weight:400; font-style:normal; font-display:swap; }
@font-face{ font-family:"Bookmania"; src:url("fonts/bookmania-regular-italic.woff2") format("woff2");
  font-weight:400; font-style:italic; font-display:swap; }
@font-face{ font-family:"DM Sans"; src:url("fonts/dm-sans.woff2") format("woff2");
  font-weight:100 1000; font-style:normal; font-display:swap; }
@font-face{ font-family:"JetBrains Mono"; src:url("fonts/jetbrains-mono.woff2") format("woff2");
  font-weight:100 800; font-style:normal; font-display:swap; }

/* ---------------- Tokens ---------------- */
:root{
  /* Palette — Relic's, unchanged */
  --radiant:#DADCB8;
  --olive:#A6A87A;
  --mint:#E2EDE2;
  --evergreen:#3B4943;
  --steel-navy:#495678;
  --perry:#D3DBEE;
  --dusk:#9DA0C6;
  --mauve:#986881;
  --cream:#F4EFEC;
  --latte:#DBD3C6;
  --espresso:#3A281E;
  --ruby:#A54751;

  --black:#111010;
  --white:#FCFCFC;

  /* The ink ladder. Dark grounds redefine these three and everything follows. */
  --ink:#141312;
  --ink-70:rgba(20,19,18,.70);
  --ink-45:rgba(20,19,18,.45);
  --ink-16:rgba(20,19,18,.16);

  --serif:"Bookmania", Georgia, "Times New Roman", serif;
  --sans:"DM Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono:"JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --gutter:clamp(1.25rem, 5.5vw, 5rem);
  --measure:60ch;

  --ease:cubic-bezier(.22,.61,.36,1);
  --ease-out:cubic-bezier(.16,1,.3,1);
}

.on-dark{
  --ink:#F4EFEC;
  --ink-70:rgba(244,239,236,.72);
  --ink-45:rgba(244,239,236,.48);
  --ink-16:rgba(244,239,236,.20);
}

*,*::before,*::after{ box-sizing:border-box; margin:0; padding:0; }

html{ -webkit-text-size-adjust:100%; scroll-behavior:smooth; }
@media (prefers-reduced-motion:reduce){ html{ scroll-behavior:auto; } }

body{
  font-family:var(--sans);
  font-size:clamp(1rem, .97rem + .16vw, 1.075rem);
  line-height:1.6;
  color:var(--ink);
  background:var(--cream);
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  overflow-x:hidden;
}
body.is-locked{ overflow:hidden; }

img{ display:block; max-width:100%; height:auto; }
svg{ display:block; }
a{ color:inherit; }
button{ font:inherit; color:inherit; background:none; border:none; cursor:pointer; }
ul{ list-style:none; }

:focus-visible{ outline:2px solid currentColor; outline-offset:4px; }

.sr-only{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}
.skip-link{
  position:fixed; z-index:200; top:.6rem; left:.6rem;
  padding:.5rem .9rem; background:var(--ink); color:var(--cream);
  font-family:var(--mono); font-size:.7rem; text-transform:uppercase; letter-spacing:.08em;
  transform:translateY(-200%); transition:transform .3s var(--ease);
}
.skip-link:focus{ transform:none; }

/* ============================================================
   TYPE SCALE
   ============================================================ */
.d1{
  font-family:var(--serif); font-weight:300;
  line-height:1.06; letter-spacing:-.008em;
  font-size:clamp(2.1rem, 1.35rem + 3.6vw, 4.6rem);
  text-wrap:balance;
}
.d2{
  font-family:var(--sans); font-weight:400;
  text-transform:uppercase;
  line-height:1.12; letter-spacing:.005em;
  font-size:clamp(1.55rem, 1.15rem + 1.9vw, 2.7rem);
  text-wrap:balance;
}
.mono{
  font-family:var(--mono); text-transform:uppercase;
  letter-spacing:.11em; font-weight:400;
  font-size:clamp(.6rem, .56rem + .16vw, .72rem);
  line-height:1.4;
}
.lede{ font-size:clamp(1.02rem, .96rem + .38vw, 1.22rem); max-width:42ch; }
.body{ max-width:var(--measure); color:var(--ink-70); }

/* Mono link with a rule that sweeps in from the left */
.link-mono{
  display:inline-block; position:relative;
  font-family:var(--mono); text-transform:uppercase;
  letter-spacing:.12em; font-size:clamp(.64rem,.6rem + .16vw,.76rem);
  text-decoration:none; padding-bottom:.28rem;
}
.link-mono::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:1px;
  background:currentColor; transform-origin:left;
  transition:transform .45s var(--ease-out);
}
.link-mono:hover::after{ transform:scaleX(0); transform-origin:right; }

/* ============================================================
   FIXED CHROME
   ============================================================ */
.chrome{
  position:fixed; z-index:120;
  right:var(--gutter); bottom:clamp(1.1rem,3vw,2.2rem);
  display:flex; align-items:center; gap:clamp(.7rem,2vw,1.15rem);
  color:var(--cream);
  transition:color .5s var(--ease), opacity .45s var(--ease), transform .45s var(--ease);
}
.chrome.is-dark{ color:var(--ink); }
.chrome__label{
  white-space:nowrap;
  font-size:clamp(.66rem, .6rem + .28vw, .82rem);
}
.chrome__arrow{ width:clamp(22px,5vw,34px); }
.chrome__arrow svg{
  width:100%; height:auto;
  transition:transform .45s var(--ease-out);
  animation:arrow-nudge 2.6s var(--ease) infinite;
}
.chrome:hover .chrome__arrow svg{ animation:none; transform:translateX(7px); }
@keyframes arrow-nudge{
  0%, 62%, 100%{ transform:translateX(0); }
  28%{ transform:translateX(6px); }
}

.chrome__mark{
  position:relative; display:block;
  width:clamp(44px,11vw,58px); aspect-ratio:1;
  border:1px solid currentColor; border-radius:999px;
  transition:transform .55s var(--ease-out), background-color .35s var(--ease);
}
.chrome__mark::before{
  content:""; position:absolute; inset:24%;
  background:currentColor;
  -webkit-mask:url("brand/cp-mark.svg") center / contain no-repeat;
  mask:url("brand/cp-mark.svg") center / contain no-repeat;
  transition:opacity .3s var(--ease);
}
.chrome:hover .chrome__mark{ transform:rotate(90deg); }
.chrome[aria-expanded="true"] .chrome__mark{ opacity:0; }
.chrome.is-hidden{ opacity:0; pointer-events:none; transform:translateY(12px); }

/* Past the hero the label retires and the mark stands alone, as drawn. */
.chrome__label, .chrome__arrow{
  transition:opacity .5s var(--ease), transform .5s var(--ease), margin .5s var(--ease);
}
.chrome.is-bare .chrome__label,
.chrome.is-bare .chrome__arrow{
  opacity:0; transform:translateX(14px); pointer-events:none;
}
.chrome.is-bare .chrome__arrow{ margin-right:calc(-1 * clamp(22px,5vw,34px) - clamp(.7rem,2vw,1.15rem)); }

/* ============================================================
   LAYOUT
   ============================================================ */
.wrap{ width:100%; max-width:74rem; margin-inline:auto; padding-inline:var(--gutter); }

.section{ padding-block:clamp(4rem,11vw,8.5rem); }
.community, .how{ padding-block:0; }   /* their inner columns carry the padding */
.band{ padding-block:clamp(4rem,11vw,8.5rem); }
.band--radiant{ background:var(--radiant); }
.band--dusk{ background:var(--dusk); }
.band--perry{ background:var(--perry); }
.band--evergreen{ background:var(--evergreen); }

/* ============================================================
   HERO
   ============================================================ */
.hero{
  position:relative; isolation:isolate;
  min-height:100svh;
  display:grid; align-content:end;
  padding:var(--gutter);
  padding-bottom:clamp(6rem,17vw,9rem);
  color:var(--cream);
  background:var(--black);
  overflow:hidden;
}
.hero__media{ position:absolute; inset:-8% 0; z-index:-2; }
.hero__media img{
  width:100%; height:100%; object-fit:cover; object-position:center 42%;
  transform:scale(1.1); opacity:0;
  transition:transform 2.4s var(--ease-out), opacity 1.4s ease;
}
.is-ready .hero__media img{ transform:scale(1); opacity:1; }
.hero::after{
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  background:
    linear-gradient(180deg, rgba(14,12,11,.42) 0%, rgba(14,12,11,.18) 34%, rgba(14,12,11,.72) 100%),
    radial-gradient(130% 90% at 25% 60%, rgba(16,14,12,.58) 0%, rgba(12,10,9,.80) 100%);
}

.hero__body{ max-width:min(100%, 58rem); }

/* The Commonplace accessory mark — COM MON / PLACE set around a
   diamond. Masked rather than inlined so it takes currentColor and
   can sit cream on the hero. */
.ring{
  display:block;
  width:clamp(104px,24vw,152px); aspect-ratio:1;
  margin-bottom:clamp(1.5rem,4.5vw,2.4rem);
  background:currentColor;
  -webkit-mask:url("brand/accessory-mark.svg") center / contain no-repeat;
  mask:url("brand/accessory-mark.svg") center / contain no-repeat;
  opacity:0; transform:scale(.94);
  transition:opacity 1s ease .25s, transform 1.2s var(--ease-out) .25s;
}
.is-ready .ring{ opacity:.95; transform:none; }

.hero__title{ font-size:clamp(2.15rem, 1.15rem + 4.6vw, 5rem); }


/* ---- The rotating word ----
   An inline-grid so both words share one cell. The padding /
   negative-margin pair keeps descenders out of the mask without
   moving the baseline of the line it sits in. ---- */
.rotator{
  display:inline-grid; position:relative;
  vertical-align:baseline;
  transition:width .4s var(--ease-out) .18s;
}
.rotator__word{
  grid-area:1/1; display:block; white-space:nowrap;
}
.rotator__sizer{
  position:absolute; left:0; top:0;
  visibility:hidden; pointer-events:none; white-space:nowrap;
}
/* Strictly one at a time: the old word is gone before the new one
   starts, so the two never sit on top of each other. */
.rotator__word.is-in{ animation:word-in .44s var(--ease-out) .32s backwards; }
.rotator__word.is-out{ animation:word-out .3s ease-in forwards; }
@keyframes word-out{ to{ transform:translateY(-.28em); opacity:0; } }
@keyframes word-in{ from{ transform:translateY(.28em); opacity:0; } to{ transform:none; opacity:1; } }

/* ============================================================
   WHAT A COMMUNITY LOOKS LIKE  +  HOW TO BUILD A COMMUNITY

   Both stack the same way at every width: the copy, then the pair
   of photographs side by side beneath it, full bleed. The earlier
   two-column desktop layout put the copy and the pictures in
   competition; stacked, the pictures read as the payoff.
   ============================================================ */
.community__grid, .how__grid{ display:block; }

.community__body, .how__body{
  padding:clamp(2.8rem,8vw,5rem) var(--gutter) clamp(2.4rem,7vw,4rem);
  display:grid; gap:clamp(1rem,2.4vw,1.5rem);
  max-width:74rem; margin-inline:auto;
}
.community__body{ justify-items:start; }
.community__body .d1{ max-width:13ch; margin-bottom:clamp(.4rem,1.4vw,.9rem); }

.how__body{ justify-items:center; text-align:center; }
.how__body .d2{ max-width:12ch; }
.how__copy{
  max-width:38ch; color:var(--ink);
  font-size:clamp(1rem, .95rem + .34vw, 1.2rem);
}

/* The five elements, set as a ruled index rather than a bullet list:
   a mono numeral, a hairline that draws itself in, and the text. It is
   the same device the brand uses for running heads and tables. */
.elements{ list-style:none; max-width:44ch; margin-top:.4rem; width:100%; }
.elements li{
  position:relative;
  display:grid; grid-template-columns:2.6rem 1fr;
  gap:0 .9rem; align-items:baseline;
  padding:clamp(.6rem,1.6vw,.8rem) 0;
}
/* The rule sits on top of each row and arrives with it. */
.elements li::before{
  content:""; position:absolute; left:0; right:0; top:0; height:1px;
  background:var(--ink-16);
  transform-origin:left;
  transition:transform .8s var(--ease-out) var(--d,0ms);
}
.js .elements li::before{ transform:scaleX(0); }
.elements li.is-in::before{ transform:scaleX(1); }
.elements li:last-child::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:1px;
  background:var(--ink-16);
  transform-origin:left;
  transition:transform .8s var(--ease-out) calc(var(--d,0ms) + 120ms);
}
.js .elements li:last-child::after{ transform:scaleX(0); }
.elements li.is-in:last-child::after{ transform:scaleX(1); }

.elements__n{
  color:var(--ink-45);
  font-variant-numeric:tabular-nums;
  transition:color .4s var(--ease);
}
.elements li:hover .elements__n{ color:var(--ink); }
.elements__t{
  font-size:clamp(1rem, .95rem + .32vw, 1.18rem);
  line-height:1.45;
}

/* The closing line is held out from the list by a rule of its own. */
.note{
  margin-top:clamp(.6rem,2vw,1rem);
  padding-left:clamp(.9rem,2.5vw,1.2rem);
  border-left:1px solid var(--ink);
  max-width:34ch;
  font-size:clamp(1rem, .96rem + .28vw, 1.14rem);
  line-height:1.5;
}

/* The pair, full bleed, divided by the same hairlines as the menu. */
.community__media, .how__media{
  display:grid; grid-template-columns:1fr 1fr;
  border-top:1px solid var(--ink);
}
.community__media figure, .how__media figure{
  overflow:hidden; min-height:0; aspect-ratio:3/4;
}
.community__media figure + figure,
.how__media figure + figure{ border-left:1px solid var(--ink); }
.community__media img, .how__media img{
  width:100%; height:100%; object-fit:cover;
}

@media (min-width:600px){
  .community__media figure, .how__media figure{ aspect-ratio:1; }
}
/* Past this width a square pair starts to swallow the screen, so the
   crop flattens rather than the photographs growing without end. */
@media (min-width:1100px){
  .community__media figure, .how__media figure{ aspect-ratio:4/3; }
}

/* ============================================================
   THE BELIEF
   ============================================================ */
.belief__inner{ display:grid; justify-items:center; text-align:center; gap:clamp(2rem,6vw,3.4rem); }
.venn{ display:block; width:clamp(96px,22vw,150px); color:var(--ink); }
.venn svg{ width:100%; height:auto; }
.venn circle{ fill:none; stroke:currentColor; stroke-width:1.4; }
.venn__t{
  font-family:var(--sans); font-size:16px; font-weight:400;
  fill:currentColor; text-anchor:middle;
}
.belief__text{ max-width:17ch; }

/* ============================================================
   WHAT COMMONPLACE IS
   First band under the hero. The paragraph sits in a cream block,
   the square photograph centred below it.
   ============================================================ */
/* One 46rem column, centred in the band, with the card and the
   photograph both filling it — same width, stacked, read as a single
   block. A max-width here would not do: .about__inner is also the .wrap
   element, so it would shrink the padding box and narrow the card too. */
.about__inner{
  display:grid;
  grid-template-columns:minmax(0, 46rem);
  justify-content:center;
  gap:clamp(1.4rem,4vw,2.4rem);
}
.about__card{
  background:var(--cream);
  padding:clamp(1.4rem,4.5vw,2.4rem);
  width:100%;
}
.about__card p{ font-size:clamp(1rem,.96rem + .3vw,1.18rem); line-height:1.6; }
/* Same box as the card. The width comes from the shared column; the
   height is set by site.js, because CSS has no way to measure a sibling.
   The ratio here is only the no-JS fallback. */
.about__photo{ width:100%; aspect-ratio:16/5; overflow:hidden; }
.about__photo img{ width:100%; height:100%; object-fit:cover; object-position:center 45%; }

/* ============================================================
   CTA
   Espresso, so the sage of the band above is not asked to do the
   same job twice. Swap --cta-ground to change it.
   ============================================================ */
.band--cta{ background:var(--cta-ground, var(--espresso)); }
.cta{ color:var(--cream); }
.cta__grid{ display:grid; gap:clamp(2.4rem,8vw,4rem); align-items:center; }
.cta__body{ display:grid; gap:clamp(1.2rem,3.4vw,1.9rem); justify-items:start; }
.cta__body .d2{ max-width:9ch; }
.cta__lede{
  font-size:clamp(1.35rem,1.05rem + 1.3vw,2.1rem);
  max-width:14ch; color:rgba(244,239,236,.88);
}
.cta__photo{
  width:min(100%, 30rem); overflow:hidden;
  transform:rotate(-2.2deg);
  box-shadow:0 22px 60px rgba(0,0,0,.30);
}
.cta__photo img{ width:100%; aspect-ratio:4/5; object-fit:cover; }

@media (min-width:820px){
  .cta__grid{ grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr); }
  .cta__photo{ justify-self:end; width:min(100%, 34rem); }
}


/* ============================================================
   ABOUT — the opening band
   ============================================================ */
.intro{ color:var(--cream); position:relative; }
.intro__inner{
  display:grid; justify-items:start;
  gap:clamp(1.1rem,3vw,1.8rem);
  min-height:min(88svh, 900px); align-content:center;
  padding-block:clamp(3rem,8vw,5rem);
}
/* The oval "common place" badge, top right — set level, and dipping over
   the head of the title beneath it. */
.intro__badge{
  justify-self:end; position:relative; z-index:1;
  width:clamp(120px,26vw,230px); aspect-ratio:1000/717;
  background:var(--cream);
  -webkit-mask:url("brand/badge.svg") center / contain no-repeat;
  mask:url("brand/badge.svg") center / contain no-repeat;
  margin-right:clamp(0rem,3vw,3rem);
  margin-bottom:clamp(-4.5rem,-7vw,-1.6rem);
  transform:rotate(0deg);
}
.intro__title{ font-size:clamp(3.4rem, 1.8rem + 9vw, 8rem); line-height:.98; }
.intro__lede{
  font-size:clamp(1.4rem, 1.05rem + 1.6vw, 2.4rem);
  line-height:1.16; max-width:18ch;
  color:rgba(244,239,236,.86);
}
.intro__body{
  margin-top:clamp(.6rem,2vw,1.2rem);
  font-size:clamp(1.05rem, .98rem + .5vw, 1.45rem);
  line-height:1.4;
  /* Wide enough to run on under the badge rather than stopping short. */
  max-width:min(100%, 38rem);
}

/* ============================================================
   HOW WE GOT STARTED
   ============================================================ */
.origin__inner{ display:grid; gap:clamp(2rem,6vw,3.5rem); }
.origin__photo{ width:100%; overflow:hidden; }
.origin__photo img{ width:100%; aspect-ratio:16/9; object-fit:cover; }

.origin__grid{ display:grid; gap:clamp(1.1rem,2.6vw,1.8rem); align-items:center; }
.origin__head{
  display:grid; justify-items:center; text-align:center;
  gap:clamp(.9rem,2.4vw,1.5rem);
}

/* The drawn oval label. */
.pill{
  display:inline-grid; place-items:center;
  padding:.75em 1.9em;
  border:1px solid var(--ink);
  border-radius:50%;
  font-size:clamp(.95rem,.9rem + .25vw,1.1rem);
  line-height:1;
}

.origin__copy{
  font-size:clamp(1rem, .95rem + .35vw, 1.2rem);
  line-height:1.5; max-width:38ch;
  /* Centred at every width, to sit with the centred head above it. */
  text-align:center; justify-self:center; margin-inline:auto;
}
.origin__copy em{ font-family:var(--serif); font-style:italic; }

@media (min-width:820px){
  .origin__grid{ grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr); }
}

/* ============================================================
   OUR TEAM — a card a person, swiped through

   Each card carries its own ground, so the colour changes as you
   move along. The fixed mark switches tone to match; that comes
   from data-tone on the card, which the carousel copies up to the
   section for the chrome observer to read.
   ============================================================ */
.team{ position:relative; overflow:hidden; }
.team__viewport{ overflow:hidden; touch-action:pan-y; cursor:grab; }
.team__viewport.is-dragging{ cursor:grabbing; }

.team__track{
  display:flex; list-style:none;
  will-change:transform;
  transition:transform .72s var(--ease-out);
}
.team__track.is-dragging{ transition:none; }

.member{
  flex:0 0 100%; min-width:0;
  display:grid; justify-items:center; align-content:center;
  gap:clamp(1.2rem,3.4vw,2rem);
  padding:clamp(3.4rem,9vw,5.5rem) var(--gutter) clamp(6rem,14vw,8rem);
  min-height:min(96svh, 940px);
  text-align:center;
  user-select:none;
}
.member--olive   { background:var(--olive);      color:var(--cream); }
.member--latte   { background:var(--latte);      color:var(--ink); }
.member--navy    { background:var(--steel-navy); color:var(--cream); }
.member--espresso{ background:var(--espresso);   color:var(--cream); }

.member__eyebrow{
  font-family:var(--sans); text-transform:uppercase;
  font-size:clamp(1.15rem,.95rem + .9vw,1.8rem);
  line-height:1; letter-spacing:.01em;
}
.member__figure{
  display:grid; justify-items:center;
  gap:clamp(1.1rem,3vw,1.8rem);
  width:min(72vw, 340px);
}
.member__figure img{
  width:100%; aspect-ratio:1; object-fit:cover;
  -webkit-user-drag:none; user-drag:none;
}
.member__name{
  font-family:var(--serif); font-weight:300; font-style:italic;
  font-size:clamp(2rem,1.25rem + 3.2vw,3.2rem);
  line-height:1.05; white-space:nowrap;
}
.member__role{
  font-family:var(--sans); text-transform:uppercase;
  font-size:clamp(1.15rem,.95rem + .9vw,1.8rem);
  line-height:1.1;
}

/* ---- The bar underneath ---- */
/* The bar sits over the card, so it has to take the card's own ink.
   Team.go copies the active card's computed colour into --bar-ink. */
.team__bar{
  position:absolute; left:0; right:0; bottom:clamp(1.6rem,4.5vw,2.8rem);
  display:grid; justify-items:center; gap:.9rem;
  padding-inline:var(--gutter);
  pointer-events:none;
  color:var(--bar-ink, currentColor);
  transition:color .5s var(--ease);
}
.team__bar > *{ pointer-events:auto; }
.team__next{
  display:inline-flex; align-items:center; gap:.7rem;
  padding:.5rem .2rem;
  opacity:.75; transition:opacity .3s var(--ease);
}
.team__next:hover{ opacity:1; }
.team__next svg{ width:clamp(22px,5vw,32px); height:auto; transition:transform .45s var(--ease-out); }
.team__next:hover svg{ transform:translateX(5px); }

@media (prefers-reduced-motion:reduce){
  .team__track{ transition:none; }
}

/* ============================================================
   MENU — footer, and the panel behind the mark
   ============================================================ */
.menu{ background:var(--cream); }
.menu__inner{
  width:100%; max-width:74rem; margin-inline:auto;
  padding:clamp(2.6rem,8vw,5.5rem) var(--gutter) clamp(6rem,14vw,7rem);
}
.menu__title{
  text-transform:uppercase;
  font-size:clamp(3rem,1.6rem + 8vw,7rem);
  letter-spacing:.02em; line-height:.95;
  margin-bottom:clamp(2.4rem,9vw,5rem);
}

/* About carries Home under the title rather than in the foot — the same
   mono link as "Get started", moved to the top where it is the first
   thing the menu offers. It exists only on that page, so the title
   closes up only when it is there. */
.menu__title:has(+ .menu__home){ margin-bottom:clamp(1.1rem,3vw,1.7rem); }
.menu__home{ display:inline-block; margin-bottom:clamp(2.4rem,9vw,5rem); }

.menu__grid{
  display:grid; grid-template-columns:1fr;
  border-top:1px solid var(--ink);
}
/* Label in the first row, photograph in the second. It used to be
   positioned absolutely, which meant that on a wide, short screen —
   where min-height caps but the thumbnail does not — the photograph
   climbed over the label. "Startup Guide", the longest, went first. */
.menu__item{
  position:relative; display:grid;
  grid-template-rows:auto 1fr;
  gap:clamp(.9rem,2.4vw,1.4rem);
  text-decoration:none;
  border-bottom:1px solid var(--ink);
  padding:clamp(1.1rem,3.6vw,1.6rem) 0 clamp(1.4rem,3.6vw,2rem);
  min-height:clamp(8.5rem,30vw,13rem);
  overflow:hidden;
}
.menu__label{
  display:block;
  font-size:clamp(1.5rem,1.15rem + 1.7vw,2.1rem);
  line-height:1.1; font-weight:400; letter-spacing:-.01em;
  transition:transform .5s var(--ease-out);
}
.menu__item:hover .menu__label{ transform:translateX(.45rem); }

.menu__thumb{
  display:block;
  justify-self:end; align-self:end;
  margin-right:clamp(.6rem,3vw,1.4rem);
  width:clamp(58px,15vw,84px);
  box-shadow:0 6px 18px rgba(58,40,30,.18);
  transition:transform .6s var(--ease-out), box-shadow .5s var(--ease);
}
.menu__thumb img{ width:100%; aspect-ratio:2/3; object-fit:cover; }
.menu__item:hover .menu__thumb{
  transform:translateY(-6px) rotate(2deg) scale(1.05);
  box-shadow:0 14px 34px rgba(58,40,30,.26);
}
.menu__item[aria-current="page"] .menu__label{ text-decoration:underline; text-underline-offset:.28em; }

.menu__foot{
  margin-top:clamp(2rem,6vw,3rem);
  display:flex; flex-wrap:wrap; gap:1rem 2rem;
  align-items:center; justify-content:space-between;
}
.menu__foot-links{ display:flex; flex-wrap:wrap; gap:1rem 1.8rem; align-items:center; }
.menu__foot-links a[aria-current="page"]{ opacity:.5; }
.menu__email{ text-decoration:none; color:var(--ink-70); transition:color .3s var(--ease); }
.menu__email:hover{ color:var(--ink); }

@media (min-width:640px){
  .menu__grid{ grid-template-columns:repeat(2,1fr); }
  .menu__item{ border-right:1px solid var(--ink); padding-left:clamp(.8rem,2.4vw,1.3rem); }
  .menu__item:nth-child(2n){ border-right:none; }
}
@media (min-width:980px){
  .menu__grid{ grid-template-columns:repeat(3,1fr); }
  .menu__item:nth-child(2n){ border-right:1px solid var(--ink); }
  .menu__item:nth-child(3n){ border-right:none; }
}

/* ============================================================
   THE OVERLAY — the same menu, opened from the mark
   ============================================================ */
.overlay{
  position:fixed; inset:0; z-index:150;
  overflow-y:auto; overscroll-behavior:contain;
  -webkit-overflow-scrolling:touch;
}
.overlay[hidden]{ display:none; }

/* The panel simply arrives: a short fade and a small rise. */
.overlay__sheet{
  min-height:100%;
  background:var(--cream);
  opacity:0; transform:translateY(14px);
  transition:opacity .34s var(--ease), transform .42s var(--ease-out);
}
.overlay.is-open .overlay__sheet{ opacity:1; transform:none; }

.overlay .menu__inner{ padding-bottom:clamp(3rem,10vw,6rem); }

.overlay .menu__title,
.overlay .menu__home,
.overlay .menu__item,
.overlay .menu__foot{
  opacity:0; transform:translateY(10px);
  transition:opacity .34s var(--ease), transform .4s var(--ease-out);
}
.overlay.is-open .menu__title,
.overlay.is-open .menu__home,
.overlay.is-open .menu__item,
.overlay.is-open .menu__foot{ opacity:1; transform:none; }
.overlay.is-open .menu__title{ transition-delay:.08s; }
.overlay.is-open .menu__home{ transition-delay:.1s; }
.overlay.is-open .menu__item{ transition-delay:calc(.12s + var(--i,0) * .035s); }
.overlay.is-open .menu__foot{ transition-delay:.34s; }

.overlay__close{
  position:fixed; z-index:160;
  right:var(--gutter); bottom:clamp(1.1rem,3vw,2.2rem);
  width:clamp(44px,11vw,58px); aspect-ratio:1;
  display:grid; place-items:center;
  border:1px solid var(--ink); border-radius:999px;
  color:var(--ink);
  opacity:0;
  transition:opacity .3s var(--ease) .18s, background-color .3s var(--ease),
             color .3s var(--ease), transform .5s var(--ease-out);
}
.overlay.is-open .overlay__close{ opacity:1; }
.overlay__close:hover{ background:var(--ink); color:var(--cream); transform:rotate(90deg); }
.overlay__close svg{ width:clamp(12px,3vw,15px); }

/* ============================================================
   REVEALS
   ============================================================ */
/* Scoped to .js: without scripting nothing is ever un-hidden, so
   the page must simply be visible. */
.js [data-reveal]{
  opacity:0; transform:translateY(24px);
  transition:opacity .85s var(--ease) var(--d,0ms), transform .95s var(--ease-out) var(--d,0ms);
}
.js [data-reveal].is-in{ opacity:1; transform:none; }

/* The mask needs room for ascenders and descenders, taken back
   again with a matching negative margin so the leading is unchanged. */
.split__line{
  display:block; overflow:hidden;
  padding-block:.06em .2em; margin-block:-.06em -.2em;
}
.split__line > span{
  display:block;
  transform:translateY(105%);
  transition:transform 1s var(--ease-out) var(--d,0ms);
}
.split.is-in .split__line > span{ transform:none; }
/* Once the lines have landed the mask has done its job. It has to go,
   or it clips the rotating word for the rest of the page's life. */
.split.is-done .split__line{ overflow:visible; }

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important; animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
  }
  .js [data-reveal], .split__line > span{ opacity:1 !important; transform:none !important; }
  .hero__media img{ opacity:1; transform:none; }
  .ring{ opacity:.95; transform:none; }
}
