/* ============================================================
   LET MARK COOK — 03 sections
   reveals · intro · standard · about · experiences · rails
   book cta · finale · footer · media placeholders
   ============================================================ */

/* ---------- shared reveal ---------- */

[data-reveal] {
  opacity: 0;
  transform: translateY(1.6rem);
  transition: opacity .8s var(--ease) var(--d, 0s),
              transform .9s var(--ease) var(--d, 0s);
}
[data-reveal].is-in { opacity: 1; transform: none; }

/* headline split — each line wipes up from behind its own mask */
.line { display: block; overflow: hidden; }
.line > i {
  display: block;
  font-style: inherit;
  transform: translateY(102%);
  transition: transform .95s var(--ease) calc(var(--l, 0) * .085s);
  will-change: transform;
}
.is-in .line > i, .line.is-in > i { transform: none; }

/* ---------- intro ---------- */

.intro__line {
  font-size: clamp(2.3rem, 8vw, 6.2rem);
  max-width: 16ch;
}

.intro__body {
  margin-top: clamp(2rem, 5vw, 3.5rem);
  display: grid;
  gap: 1rem;
}

@media (min-width: 900px) {
  .intro .wrap {
    display: grid;
    grid-template-columns: 1.15fr .85fr;
    gap: clamp(2rem, 6vw, 6rem);
    align-items: end;
  }
  .intro__body { margin-top: 0; }
}

/* ---------- the standard — paper surface ---------- */

.standard {
  background: var(--bone);
  color: var(--ink);
}
.standard .eyebrow { color: #6d6055; }

.standard__title {
  font-size: clamp(2.6rem, 9vw, 7rem);
  margin-bottom: clamp(2rem, 5vw, 3.5rem);
}

.standard__list {
  display: grid;
  gap: 0;
  border-top: 1px solid var(--line-ink);
}

.standard__list li {
  padding-block: clamp(1.5rem, 3.5vw, 2.4rem);
  border-bottom: 1px solid var(--line-ink);
  display: grid;
  gap: .5rem;
  transition: padding-left .5s var(--ease);
}

.standard__list h3 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.4rem, 4vw, 2.4rem);
  line-height: 1.02;
  text-transform: uppercase;
  letter-spacing: -.02em;
}

.standard__list p {
  margin: 0;
  max-width: 46ch;
  color: #5d5148;
  font-size: clamp(.95rem, 1.6vw, 1.05rem);
}

@media (min-width: 820px) {
  .standard__list li {
    grid-template-columns: 1fr 1.1fr;
    gap: clamp(1.5rem, 5vw, 4rem);
    align-items: baseline;
  }
  .standard__list li:hover { padding-left: 1.25rem; }
  .standard__list li:hover h3 { color: var(--flame); }
  .standard__list h3 { transition: color .4s var(--ease); }
}

/* ---------- about mark ---------- */

.chef { background: var(--ink); }

.chef__grid {
  display: grid;
  gap: clamp(2.5rem, 7vw, 5rem);
}

@media (min-width: 950px) {
  .chef__grid {
    grid-template-columns: .95fr 1.05fr;
    align-items: center;
  }
}

/* the padding here used to hold space for an inset photograph that has
   since gone; the scribble still needs the positioning context */
.chef__stack { position: relative; }

.chef__shot {
  position: relative;
  overflow: hidden;
  border-radius: 2px;
  background: var(--oxblood);
  will-change: transform;
}
/* contain, not cover. The photograph is a tall 768x1344 and the card was
   a wide 4:5, so cover scaled it to the card's width and then cut the
   overflow off the top and bottom — which is exactly where his glasses
   and the hem of the coat are. The card now sits close to the picture's
   own proportions and the whole frame is shown inside it. */
.chef__shot img { width: 100%; height: 100%; object-fit: contain; }

.chef__shot--big {
  aspect-ratio: 5 / 8;
  /* Capped, or on a wide screen the 5:8 card is taller than the window —
     at a 600px column it works out near 960px, so the picture runs off
     both ends of the viewport and reads as cropped even though the box
     itself crops nothing. With contain, a shorter box just fits the
     picture by height and adds side margin; it never cuts. */
  max-height: min(74vh, 36rem);
  max-height: min(74svh, 36rem);
  box-shadow: 0 1.5rem 4rem rgba(0,0,0,.5);

  /* --par-y is the scroll parallax, --sp-x/--sp-y the spring bounce */
  transform:
    translate3d(var(--sp-x, 0px), calc(var(--par-y, 0px) + var(--sp-y, 0px)), 0);
}

/* hand-drawn stroke that draws itself when the block arrives */
.chef__scribble {
  position: absolute;
  left: -1rem;
  top: -1.25rem;
  width: 42%;
  max-width: 13rem;
  color: var(--flame);
  opacity: .9;
  pointer-events: none;
}
.chef__scribble svg { width: 100%; height: auto; overflow: visible; }
.chef__scribble path {
  stroke-dasharray: var(--len, 600);
  stroke-dashoffset: var(--len, 600);
  transition: stroke-dashoffset 1.6s var(--ease);
}
.chef__scribble.is-in path { stroke-dashoffset: 0; }

.chef__text .h2 { margin-top: .5rem; }

.chef__prose {
  margin-top: clamp(1.5rem, 3vw, 2rem);
  display: grid;
  gap: 1rem;
  max-width: 46ch;
}
.chef__prose p { margin: 0; }

.chef__facts {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
  margin-top: clamp(2rem, 4vw, 3rem);
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
}
.chef__facts dt {
  font-size: .66rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--smoke);
}
.chef__facts dd {
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 4.5vw, 2.6rem);
  line-height: 1;
  margin-top: .35rem;
  font-variant-numeric: tabular-nums;
}

/* ---------- experiences ---------- */

.exp { background: var(--char); }

.exp__title { max-width: 14ch; }
.exp__intro {
  margin: 1.25rem 0 0;
  max-width: 42ch;
  color: var(--smoke);
  font-size: clamp(1rem, 1.8vw, 1.15rem);
}

.exp__list {
  margin-top: clamp(2.5rem, 6vw, 4.5rem);
  display: grid;
  gap: clamp(2.5rem, 6vw, 5rem);
}

.exp__row {
  display: grid;
  gap: clamp(1.25rem, 3vw, 2.5rem);
  align-items: center;
}

@media (min-width: 820px) {
  .exp__row { grid-template-columns: 1.05fr .95fr; }
  .exp__row--flip .exp__media { order: 2; }
}

.exp__media {
  aspect-ratio: 16 / 11;
  border-radius: 2px;
  transform: perspective(900px) rotateX(var(--tx, 0deg)) rotateY(var(--ty, 0deg));
  transition: transform .5s var(--ease);
  will-change: transform;
}

.exp__copy h3 {
  margin: 0;
  font-size: clamp(1.9rem, 5vw, 3.2rem);
}
.exp__copy p { margin: .75rem 0 0; max-width: 42ch; color: #b9b1a8; }
.exp__copy .textlink { margin-top: 1.4rem; }

.exp__size {
  margin-top: .5rem !important;
  font-size: .74rem !important;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--flame) !important;
}

/* ---------- rails ---------- */

.rail-section {
  position: relative;
  padding-block: clamp(4rem, 10vw, 7rem);
  background: var(--ink);
}
.rail-section--reels { background: var(--char); }

/* A pinned rail: the section is made tall enough that scrolling through it
   maps one-to-one onto the cards' horizontal travel, and this pane sticks
   while that happens. Its height is written by js/04-rails.js from the real
   measured travel, so there is never dead scroll at either end. Note the
   section must NOT have overflow:hidden — that would make it a scroll
   container and position:sticky inside it would stop sticking. */
.rail-section[data-pin] { padding-block: 0; }

.rail-pin {
  position: sticky;
  top: 0;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-block: clamp(3rem, 8vw, 5rem);
  overflow: hidden;
}

/* reduced motion, or a rail short enough to fit: no runway, normal flow */
.rail-section.is-static { height: auto !important; }
.rail-section.is-static .rail-pin {
  position: relative;
  min-height: 0;
  overflow: visible;
}

/* ---------- phones ----------
   The sideways travel runs on a phone too: it is the same single vertical
   gesture as the rest of the page, so nothing new is asked of the reader,
   and the cards come past rather than needing to be swiped at. */

.rail__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.25rem;
  margin-bottom: clamp(1.75rem, 4vw, 2.75rem);
}

.rail__hint {
  margin: .75rem 0 0;
  font-size: .78rem;
  color: var(--smoke);
}

.rail__nav { display: none; gap: .5rem; }
@media (hover: hover) and (pointer: fine) { .rail__nav { display: flex; } }

.rail__btn {
  width: 3rem; height: 3rem;
  display: grid; place-items: center;
  border-radius: 50%;
  border: 1px solid var(--line);
  font-size: 1rem;
  transition: background-color .3s var(--ease), color .3s var(--ease),
              border-color .3s var(--ease), transform .3s var(--ease);
}
.rail__btn:hover { background: var(--flame); border-color: var(--flame); color: #fff; }
.rail__btn:active { transform: scale(.92); }
.rail__btn[disabled] { opacity: .3; pointer-events: none; }

.rail {
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  -ms-overflow-style: none;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
  padding-inline: var(--gutter);
  padding-block: .5rem 1.25rem;
  /* Without this the snapport starts at the content edge, so mandatory
     snapping opens the rail already scrolled past its own left gutter and
     the first card sits flush against the screen edge. Written as physical
     longhands — the scroll-padding-inline shorthand is not honoured
     everywhere this has to run. */
  scroll-padding-left: var(--gutter);
  scroll-padding-right: var(--gutter);
  cursor: grab;
}
.rail::-webkit-scrollbar { display: none; }
.rail.is-dragging { cursor: grabbing; scroll-snap-type: none; scroll-behavior: auto; }
.rail.is-dragging * { pointer-events: none; }

.rail__track {
  display: flex;
  gap: clamp(.85rem, 2vw, 1.5rem);
  width: max-content;
}

/* browsers drop a scroller's trailing padding from its scrollable area, so
   the last card needs its own spacer to keep the gutter on the right */
.rail__track::after {
  content: "";
  flex: 0 0 1px;
  margin-right: calc(var(--gutter) - clamp(.85rem, 2vw, 1.5rem));
}

.rail__meter {
  margin-top: 1.25rem;
  height: 2px;
  background: var(--line);
  overflow: hidden;
}
.rail__meter span {
  display: block;
  height: 100%;
  width: 30%;
  background: var(--flame);
  transform: translateX(0);
  transition: transform .1s linear, width .3s var(--ease);
}

/* food cards */
.card, .reel {
  scroll-snap-align: start;
  flex: 0 0 auto;
  -webkit-tap-highlight-color: transparent;
  transition: transform .45s var(--ease);
  will-change: transform;
}
.card { width: clamp(15rem, 68vw, 24rem); }
.reel { width: clamp(11rem, 44vw, 15rem); }

.card:active, .reel:active { transform: scale(.975); }

.card__media {
  aspect-ratio: 4 / 5;
  border-radius: 2px;
  overflow: hidden;
}
.reel__media {
  aspect-ratio: 9 / 16;
  border-radius: 2px;
  overflow: hidden;
}

.card__foot {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-top: .9rem;
  padding-bottom: .35rem;
  border-bottom: 1px solid var(--line);
}
.card__foot h3 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.2rem, 3.2vw, 1.7rem);
  text-transform: uppercase;
  letter-spacing: -.01em;
}
.card__foot span {
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--smoke);
}

@media (hover: hover) and (pointer: fine) {
  .card:hover .card__media, .reel:hover .reel__media { transform: scale(1.02); }
  .card__media, .reel__media { transition: transform .6s var(--ease); }
}

/* ---------- media placeholders ----------
   Every slot the client still has to fill announces its own file path,
   so nothing ships as an anonymous grey box. */

.mood {
  position: relative;
  display: grid;
  place-items: center;
  overflow: hidden;
  background: var(--oxblood);
  isolation: isolate;
}
.mood::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background-size: 200% 200%;
  animation: moodDrift 18s ease-in-out infinite alternate;
}
@keyframes moodDrift {
  from { background-position: 0% 50%; }
  to   { background-position: 100% 50%; }
}

.mood--fire::before    { background-image: linear-gradient(130deg, #6b1408, #ff5a1f 45%, #2a0a0e); }
.mood--sea::before     { background-image: linear-gradient(130deg, #0c2b38, #3d7f9b 45%, #0a1418); }
.mood--land::before    { background-image: linear-gradient(130deg, #2d2110, #8a6a33 45%, #14090b); }
.mood--dessert::before { background-image: linear-gradient(130deg, #3a1526, #b8657f 45%, #1b0a12); }
.mood--dining::before  { background-image: linear-gradient(130deg, #2a0a0e, #7a3220 50%, #14090b); }
.mood--events::before  { background-image: linear-gradient(130deg, #17131f, #59486f 50%, #0d0a12); }
.mood--bespoke::before { background-image: linear-gradient(130deg, #1a1208, #a07636 50%, #120b06); }
.mood--reel::before    { background-image: linear-gradient(130deg, #14090b, #4a0d14 50%, #0a0506); }

.mood__tag {
  position: absolute;
  top: .85rem; left: .85rem;
  padding: .35rem .7rem;
  border-radius: 999px;
  background: rgba(10,5,6,.55);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  font-size: .62rem;
  font-weight: 800;
  letter-spacing: .12em;
  text-transform: uppercase;
}

/* once a real photograph or clip has loaded, the placeholder steps aside */
.mood__fill {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.mood.has-media::before { content: none; }
.mood.has-media .mood__slot { display: none; }

.mood__slot {
  padding: .4rem .7rem;
  border: 1px dashed rgba(247,244,238,.32);
  border-radius: 2px;
  font-size: .66rem;
  font-weight: 600;
  letter-spacing: .04em;
  color: rgba(247,244,238,.72);
  text-align: center;
  max-width: 88%;
}

/* ---------- booking cta ---------- */

.book-cta {
  position: relative;
  padding-block: clamp(5rem, 14vw, 10rem);
  background: var(--claret);
  text-align: center;
  overflow: hidden;
}
.book-cta::after {
  content: "";
  position: absolute;
  inset: auto 0 -40% 0;
  height: 80%;
  background: radial-gradient(60% 60% at 50% 50%, rgba(255,90,31,.35), transparent 70%);
  pointer-events: none;
}
.book-cta .wrap { position: relative; z-index: 1; }

.book-cta__title {
  font-size: clamp(2.1rem, 7vw, 5.4rem);
  max-width: 22ch;
  margin-inline: auto;
}
.book-cta p {
  margin: 1.25rem auto 2rem;
  max-width: 44ch;
  color: rgba(247,244,238,.78);
}

/* ---------- finale ---------- */

.finale {
  position: relative;
  min-height: 86vh;
  min-height: 86svh;
  display: grid;
  align-items: end;
  overflow: hidden;
}
.finale__media { position: absolute; inset: 0; }
.finale__media .mood__slot { transform: translateY(-2rem); }
.finale__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, var(--ink) 6%, rgba(10,5,6,.55) 45%, rgba(10,5,6,.2));
}
.finale__inner {
  position: relative;
  z-index: 1;
  padding-bottom: clamp(3rem, 9vw, 6rem);
}
.finale__title {
  font-size: clamp(2.2rem, 7.5vw, 5.8rem);
  max-width: 15ch;
  margin-bottom: 2rem;
}

/* ---------- footer ---------- */

.footer {
  padding-block: clamp(3rem, 8vw, 5rem) calc(clamp(2rem, 5vw, 3rem) + var(--dock-h));
  background: var(--ink);
  border-top: 1px solid var(--line);
}

.footer__top {
  display: grid;
  gap: 2rem;
  padding-bottom: 2.5rem;
  border-bottom: 1px solid var(--line);
}
@media (min-width: 760px) {
  .footer__top { grid-template-columns: 1fr auto; align-items: start; }
}

.footer__mark {
  margin: 0;
  font-size: clamp(2rem, 7vw, 4.2rem);
}

.footer__nav {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: .6rem 2rem;
  font-size: .85rem;
  font-weight: 600;
}
@media (min-width: 760px) { .footer__nav { grid-template-columns: 1fr; text-align: right; } }

.footer__nav a, .footer__nav button {
  color: var(--smoke);
  text-align: inherit;
  padding: 0;
  transition: color .3s var(--ease);
}
.footer__nav a:hover, .footer__nav button:hover { color: var(--flame); }

.footer__base {
  display: flex;
  flex-wrap: wrap;
  gap: .75rem 1.5rem;
  justify-content: space-between;
  margin-top: 1.75rem;
  font-size: .76rem;
  color: var(--smoke);
}
.footer__base a:hover { color: var(--flame); }
