/* ============================================================
   Anchor & Bean — styles.css (v3, scrollytelling build)
   Mobile-first. Base styles are for phones; the
   @media (min-width: ...) blocks add desktop layout on top.
   ============================================================ */

/* ---------- 1. Design tokens ---------- */
:root {
  --espresso: #251a10;
  --espresso-2: #2e2115;
  --crema: #f5ecdc;
  --caramel: #b96a32;
  --caramel-deep: #8a4a1d;
  --caramel-light: #e3a368;
  --olive: #5d6647;
  --sand: #ddc9a6;
  --card: #efe1c8;
  --muted: #6e6153;
  --muted-dark: #d8c7ab;

  --font-display: "Gloock", Georgia, serif;
  --font-body: "Epilogue", -apple-system, "Segoe UI", sans-serif;
  --font-mono: "Space Mono", "Courier New", monospace;

  --radius: 14px;
  --measure: 58ch;
  --header-h: 3.8rem;
}

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

html { scroll-behavior: smooth; }

body {
  margin: 0;
  /* soft warm wash instead of one flat cream, so light sections feel lit, not blocky.
     No fixed attachment: it causes scroll jank on mobile, and the scroll animation
     is the priority. A plain gradient gives the same warmth without the cost. */
  background: var(--crema);
  color: var(--espresso);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  font-weight: 380;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

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

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 400;
  line-height: 1.02;
  margin: 0 0 0.45em;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

h1 { font-size: clamp(2.9rem, 10.5vw, 5.8rem); }
h2 { font-size: clamp(2rem, 6vw, 3.3rem); }
h3 { font-size: 1.45rem; line-height: 1.15; }

.swash { font-style: italic; color: var(--caramel); }

p { margin: 0 0 1em; max-width: var(--measure); }

a { color: var(--caramel-deep); text-underline-offset: 3px; }
a:hover { color: var(--espresso); }

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

.skip-link {
  position: absolute; left: -9999px; top: 0;
  background: var(--espresso); color: #fff;
  padding: 0.6rem 1rem; z-index: 100;
}
.skip-link:focus { left: 0.5rem; top: 0.5rem; }

/* ---------- 3. Layout ---------- */
.wrap { width: min(100% - 2.5rem, 72rem); margin-inline: auto; }
.section { padding-block: 3.5rem; position: relative; }

/* Light sections get a whisper of warm gradient so cream areas feel lit
   rather than reading as one flat block. Dark/band/pour override this. */
.section:not(.dark):not(.band) {
  background: linear-gradient(178deg, #f7eeddff 0%, #f0e4cf 100%);
}

.dark {
  background: linear-gradient(165deg, var(--espresso-2) 0%, var(--espresso) 60%);
  color: var(--crema);
}
.dark h1, .dark h2, .dark h3 { color: var(--crema); }
.dark .swash { color: var(--caramel-light); }
.dark p { color: var(--muted-dark); }
.dark a { color: var(--caramel-light); }
.dark a:hover { color: #fff; }

/* Roast-batch label: the mono "stamp" above headings */
.stamp {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 400;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--caramel-deep);
  border: 1px solid currentColor;
  border-radius: 4px;
  padding: 0.3rem 0.6rem;
  margin-bottom: 1.2rem;
}
.dark .stamp, .band .stamp { color: var(--caramel-light); }

/* ---------- 4. Buttons: sliding-fill micro-interaction ---------- */
.btn {
  display: inline-block;
  font-weight: 700;
  font-size: 1rem;
  text-decoration: none;
  border-radius: 999px;
  padding: 0.85rem 1.6rem;
  border: 2px solid transparent;
  transition: background-position 0.35s ease, color 0.25s ease,
              transform 0.2s ease, box-shadow 0.2s ease,
              border-color 0.25s ease;
}
.btn:hover { transform: translateY(-2px); box-shadow: 0 6px 18px rgba(37, 26, 16, 0.18); }
.btn:active { transform: translateY(0); }

.btn-primary {
  color: #fff;
  background: linear-gradient(to right, var(--caramel-deep) 50%, var(--caramel) 50%);
  background-size: 205% 100%;
  background-position: 100% 0;
}
.btn-primary:hover { background-position: 0 0; color: #fff; }

.btn-ghost {
  border-color: var(--espresso);
  color: var(--espresso);
  background: linear-gradient(to right, var(--espresso) 50%, transparent 50%);
  background-size: 205% 100%;
  background-position: 100% 0;
}
.btn-ghost:hover { background-position: 0 0; color: var(--crema); }
.dark .btn-ghost, .band .btn-ghost {
  border-color: var(--crema); color: var(--crema);
  background: linear-gradient(to right, var(--crema) 50%, transparent 50%);
  background-size: 205% 100%; background-position: 100% 0;
}
.dark .btn-ghost:hover, .band .btn-ghost:hover { background-position: 0 0; color: var(--espresso); }

.btn-row { display: flex; flex-wrap: wrap; gap: 0.85rem; margin-top: 1.4rem; }

/* ---------- 5. Header and navigation ---------- */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: rgba(245, 236, 220, 0.92);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--sand);
}
.header-bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; padding-block: 0.8rem; min-height: var(--header-h);
}
.brand {
  display: inline-flex; align-items: center; gap: 0.55rem;
  font-family: var(--font-display); font-size: 1.45rem;
  color: var(--espresso); text-decoration: none; white-space: nowrap;
}
.brand .amp { font-style: italic; color: var(--caramel); }
.brand .mark { width: 26px; height: 26px; transition: transform 0.35s ease; }
.brand:hover .mark { transform: rotate(-12deg); }

.nav-toggle {
  display: inline-flex; flex-direction: column; justify-content: center;
  gap: 5px; width: 44px; height: 44px; padding: 10px;
  background: none; border: 1.5px solid var(--espresso);
  border-radius: 8px; cursor: pointer;
}
.nav-toggle span { display: block; height: 2px; background: var(--espresso); border-radius: 2px; }

.site-nav {
  display: none;
  position: absolute; left: 0; right: 0; top: 100%;
  background: var(--crema);
  border-bottom: 1px solid var(--sand);
  padding: 0.5rem 1.25rem 1.25rem;
}
.site-nav.is-open { display: block; }
.site-nav ul { list-style: none; margin: 0; padding: 0; }
.site-nav a {
  display: inline-block; padding: 0.7rem 0.25rem;
  font-weight: 700; text-decoration: none; color: var(--espresso);
  /* underline draws in from the left on hover */
  background: linear-gradient(currentColor, currentColor) no-repeat left bottom;
  background-size: 0% 2px;
  transition: background-size 0.3s ease, color 0.2s ease;
}
.site-nav li { border-bottom: 1px solid var(--sand); }
.site-nav a:hover { background-size: 100% 2px; }
.site-nav a[aria-current="page"] { color: var(--caramel-deep); background-size: 100% 2px; }

/* ---------- 6. Hero (12-column editorial grid) ---------- */
.hero {
  background:
    radial-gradient(120% 90% at 78% 0%, rgba(185,106,50,0.16), transparent 60%),
    linear-gradient(160deg, var(--espresso-2), var(--espresso) 65%);
  color: var(--crema);
  overflow: hidden;
  position: relative;
  padding-block: 3.5rem 4rem;
}
.hero h1 { color: var(--crema); }
.hero .lede { color: var(--muted-dark); font-size: 1.16rem; max-width: 44ch; }
.hero-grid { display: grid; gap: 2rem; position: relative; z-index: 1; }
/* Mobile: a small, centred hero photo. Deliberately modest so it sits
   under the headline as a supporting image, not something you scroll past. */
.hero-mark { width: 100%; margin-inline: auto; }
.hero-mark > .photo {
  width: min(88vw, 460px);
  height: min(52vw, 272px);   /* explicit height: cannot stretch tall */
  margin-inline: auto;
  border: 1px solid rgba(245, 236, 220, 0.25);
  border-radius: 12px;
  box-shadow: none;
  overflow: hidden;
}
/* Force the image to fill that box exactly, whatever its own shape is. */
.hero-mark > .photo img {
  width: 100% !important;
  height: 100% !important;
  aspect-ratio: auto !important;
  object-fit: cover;
  border-radius: inherit;
}
.hero-mark svg { width: 100%; height: auto; }

.amp-ghost {
  position: absolute; top: -0.18em; right: -0.12em;
  font-family: var(--font-display); font-style: italic;
  font-size: clamp(15rem, 40vw, 32rem); line-height: 1;
  color: rgba(227, 163, 104, 0.08);
  pointer-events: none; user-select: none; z-index: 0;
}

/* hero entrance */
.rise { animation: riseIn 0.8s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
.r1 { animation-delay: 0.05s; } .r2 { animation-delay: 0.15s; }
.r3 { animation-delay: 0.3s; }  .r4 { animation-delay: 0.45s; }
.r5 { animation-delay: 0.55s; }
@keyframes riseIn { from { opacity: 0; transform: translateY(30px); } to { opacity: 1; transform: none; } }

/* ambient steam loop on the hero mark */
.hero-steam path {
  stroke-dasharray: 1; stroke-dashoffset: 1;
  animation: heroSteam 3.6s ease-in-out infinite;
}
.hero-steam path:nth-child(2) { animation-delay: 1.2s; }
.hero-steam path:nth-child(3) { animation-delay: 2.4s; }
@keyframes heroSteam {
  0% { stroke-dashoffset: 1; opacity: 0; }
  35% { opacity: 0.9; }
  70% { stroke-dashoffset: 0; opacity: 0; }
  100% { stroke-dashoffset: 0; opacity: 0; }
}

/* ---------- 7. Marquee ticker ---------- */
.ticker { background: var(--caramel); color: var(--espresso); overflow: hidden; padding-block: 0.75rem; }
.ticker-track {
  display: flex; gap: 3rem; width: max-content; white-space: nowrap;
  font-family: var(--font-mono); font-size: 0.78rem; letter-spacing: 0.2em;
  text-transform: uppercase;
  animation: tickerScroll 32s linear infinite;
}
.ticker-track > span { display: flex; gap: 3rem; }
.ticker:hover .ticker-track { animation-play-state: paused; }
@keyframes tickerScroll { to { transform: translateX(-50%); } }

/* ============================================================
   8. THE POUR — scroll-driven brew scene
   The tall .pour section owns a named view-timeline. Every
   animated part of the SVG carries class="scrub" and scrubs the
   shared keyframes below as you scroll (native scroll-timeline
   where supported; JS drives the same keyframes elsewhere).
   ============================================================ */
.pour {
  view-timeline: --pour block;
  background:
    linear-gradient(var(--crema), var(--crema));
  position: relative;
}
.pour-grid { display: grid; }

.pour-vis {
  position: sticky;
  top: var(--header-h);
  z-index: 2;
  /* about a third of the screen on mobile, so the story text stays readable
     beside it instead of being squeezed into the bottom half */
  height: 16vh; height: 16svh;
  display: grid; place-items: center;
  background: var(--crema);
  border-bottom: 1px solid var(--sand);
}
.pour-vis .pour-svg { height: 92%; width: auto; max-width: 52vw; }
.pour-svg { height: 92%; width: auto; max-width: 88vw; }

.pour-steps { padding-block: 2rem 4rem; }
.step {
  /* sized to content on mobile (was 78svh, which left big empty gaps under
     the shortened sticky visual); still tall enough to pace the animation */
  min-height: 48vh; min-height: 48svh;
  display: grid; align-content: center;
  padding-block: 1.25rem;
}
.step .stamp { margin-bottom: 0.9rem; }
.step p { color: var(--muted); }

/* --- shared scrub binding (native scroll-timeline path) --- */
.pour-svg .scrub {
  animation-duration: 1s;              /* nominal; the timeline replaces time */
  animation-timing-function: linear;
  animation-fill-mode: both;
  animation-timeline: --pour;
  animation-range: contain 0% contain 100%;
}

/* --- JS fallback: same keyframes, scrubbed by --p (0 to 1) --- */
.scrub-js .pour-svg .scrub {
  animation-timeline: auto;
  animation-range: normal;
  animation-play-state: paused;
  animation-delay: calc(var(--p, 0) * -1s);
}

/* --- parts --- */
.pour-svg .bean-1 { animation-name: beanDrop1; }
.pour-svg .bean-2 { animation-name: beanDrop2; }
.pour-svg .bean-3 { animation-name: beanDrop3; }
.pour-svg .stream { animation-name: streamPour; transform-origin: 160px 74px; }
.pour-svg .drip   { animation-name: dripFall; }
.pour-svg .coffee-g { animation-name: cupFill; }
.pour-svg .dripper, .pour-svg .kettle { animation-name: dripperAway; }
.pour-svg .steam path { animation-name: steamDraw; stroke-dasharray: 1; }

@keyframes beanDrop1 {
  0% { translate: 0 0; opacity: 0; }
  4% { opacity: 1; }
  16% { translate: 0 118px; opacity: 1; }
  20%, 100% { translate: 0 128px; opacity: 0; }
}
@keyframes beanDrop2 {
  0%, 3% { translate: 0 0; opacity: 0; }
  7% { opacity: 1; }
  19% { translate: 0 124px; opacity: 1; }
  23%, 100% { translate: 0 134px; opacity: 0; }
}
@keyframes beanDrop3 {
  0%, 6% { translate: 0 0; opacity: 0; }
  10% { opacity: 1; }
  22% { translate: 0 112px; opacity: 1; }
  26%, 100% { translate: 0 122px; opacity: 0; }
}
@keyframes streamPour {
  0%, 16% { transform: scaleY(0); }
  22% { transform: scaleY(1); }
  56% { transform: scaleY(1); }
  62%, 100% { transform: scaleY(0); }
}
@keyframes dripFall {
  0%, 20% { opacity: 0; }
  26% { opacity: 1; }
  72% { opacity: 1; }
  78%, 100% { opacity: 0; }
}
@keyframes cupFill {
  0%, 24% { translate: 0 84px; }
  78%, 100% { translate: 0 0; }
}
@keyframes dripperAway {
  0%, 80% { translate: 0 0; opacity: 1; }
  92%, 100% { translate: 0 -46px; opacity: 0; }
}
@keyframes steamDraw {
  0%, 86% { stroke-dashoffset: 1; opacity: 0; }
  90% { opacity: 1; }
  100% { stroke-dashoffset: 0; opacity: 1; }
}

/* ---------- 9. Line-art SVG defaults ---------- */
.lineart { stroke: var(--espresso); stroke-width: 3; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.dark .lineart, .band .lineart { stroke: var(--crema); }
.lineart .fill-caramel { fill: var(--caramel); stroke: none; }
.lineart .fill-crema { fill: #fdf8ee; stroke: none; }
.lineart .accent { stroke: var(--caramel); }
.art { width: min(60vw, 260px); margin-inline: auto; }

/* ---------- 10. Cards ---------- */
.card-grid { display: grid; gap: 1.1rem; margin-top: 1.5rem; }
.card {
  background: var(--card);
  border: 1px solid var(--sand);
  border-radius: var(--radius);
  padding: 1.6rem;
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}
.card:hover {
  transform: translateY(-4px);
  box-shadow: 0 10px 24px rgba(37, 26, 16, 0.12);
  border-color: var(--caramel);
}
.card h3 { color: var(--espresso); }
.card p { margin-bottom: 0; color: var(--muted); }
.card .stamp { font-size: 0.65rem; }

/* ---------- 11. Menu board ---------- */
.menu-list { list-style: none; margin: 0; padding: 0; max-width: 44rem; }
.menu-item {
  display: flex; flex-wrap: wrap; align-items: baseline;
  gap: 0.6rem; padding-block: 0.7rem;
}
.menu-item .name { font-weight: 700; }
.menu-item .dots { flex: 1; min-width: 1.5rem; border-bottom: 2px dotted var(--sand); transform: translateY(-4px); }
.menu-item .price { font-family: var(--font-mono); font-weight: 700; color: var(--caramel-deep); white-space: nowrap; }
/* A zero-height full-width break element could go here, but instead we
   force the description itself to claim a whole row and never shrink,
   so short descriptions (like Flat white) can't sit inline and cut the
   dotted line short. flex: 0 0 100% = grow 0, shrink 0, basis 100%. */
.menu-item .desc {
  flex: 0 0 100%;
  width: 100%;
  min-width: 100%;
  margin: 0.15rem 0 0;
  color: var(--muted); font-size: 0.95rem;
}
/* force the price to be the last thing on the top row so dots always stretch to it */
.menu-item .name { order: 0; }
.menu-item .dots { order: 1; }
.menu-item .price { order: 2; }
.menu-item .desc { order: 3; }

.dark .menu-item .dots { border-color: rgba(227, 163, 104, 0.35); }
.dark .menu-item .price { color: var(--caramel-light); }
.dark .menu-item .desc { color: var(--muted-dark); }

.diet {
  font-family: var(--font-mono); font-size: 0.68rem;
  color: var(--olive); border: 1px solid var(--olive);
  border-radius: 4px; padding: 0 0.3rem; vertical-align: 2px;
}
.dark .diet { color: var(--caramel-light); border-color: var(--caramel-light); }
.menu-note { color: var(--muted); font-size: 0.95rem; }
.dark .menu-note { color: var(--muted-dark); }
.sub { font-family: var(--font-mono); font-size: 0.4em; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); vertical-align: 0.5em; }

/* ---------- 12. Olive band ---------- */
.band {
  background: linear-gradient(165deg, #6b754f 0%, var(--olive) 55%);
  color: #f3efe3; position: relative; overflow: hidden;
}
.band h2 { color: #fff; }
.band .swash { color: #e8d9a8; }
.band p { color: #e6e3d2; }
.band .stamp { color: #e8d9a8; }
.band .btn-primary {
  color: var(--olive);
  background: linear-gradient(to right, #fff 50%, var(--crema) 50%);
  background-size: 205% 100%; background-position: 100% 0;
}
.band .btn-primary:hover { background-position: 0 0; color: var(--olive); }
.band .amp-ghost { color: rgba(245, 236, 220, 0.08); top: auto; bottom: -0.35em; }

/* ---------- 13. Hours, forms, map ---------- */
.hours { width: 100%; max-width: 26rem; border-collapse: collapse; }
.hours th, .hours td { text-align: left; padding: 0.55rem 0.25rem; border-bottom: 1px solid var(--sand); }
.hours th { font-weight: 700; }

.form-grid { display: grid; gap: 1.1rem; max-width: 34rem; }
label { font-weight: 700; display: block; margin-bottom: 0.35rem; }
input, textarea {
  width: 100%; font: inherit; color: var(--espresso);
  background: #fdf8ee; border: 1.5px solid var(--muted);
  border-radius: 10px; padding: 0.75rem 0.9rem;
  transition: border-color 0.2s ease;
}
input:focus, textarea:focus { border-color: var(--caramel); outline: 3px solid rgba(185, 106, 50, 0.25); }
.form-grid button { justify-self: start; cursor: pointer; font: inherit; }
.hidden-field { position: absolute; left: -9999px; }
.map-frame { width: 100%; height: 340px; border: 0; border-radius: var(--radius); }

/* ---------- 14. Media rows + pull quote ---------- */
.media-row { display: grid; gap: 1.75rem; align-items: center; margin-block: 3rem; }
.pullquote {
  margin: 3.5rem 0; padding-left: 1.4rem;
  border-left: 4px solid var(--caramel);
  font-family: var(--font-display); font-style: italic;
  font-size: clamp(1.5rem, 4.5vw, 2.3rem); line-height: 1.2;
  color: var(--espresso); max-width: 26ch;
}

/* ---------- 15. Footer ---------- */
.site-footer { background: var(--espresso); color: var(--muted-dark); padding-block: 3rem 2rem; font-size: 0.95rem; }
.footer-grid { display: grid; gap: 1.75rem; }
.site-footer h3 { color: var(--crema); font-size: 1.35rem; }
.site-footer a { color: var(--caramel-light); }
.site-footer a:hover { color: #fff; }
.site-footer ul { list-style: none; margin: 0; padding: 0; }
.site-footer li { margin-bottom: 0.4rem; }
.footer-legal { margin-top: 2.25rem; color: #a8977f; font-size: 0.85rem; font-family: var(--font-mono); }

/* ---------- 16. Scroll reveals (gated behind .js) ---------- */
.js .reveal {
  opacity: 0; transform: translateY(28px);
  transition: opacity 0.7s ease, transform 0.7s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.js .reveal.in-view { opacity: 1; transform: none; }
.js .card-grid .reveal:nth-child(2) { transition-delay: 0.12s; }
.js .card-grid .reveal:nth-child(3) { transition-delay: 0.24s; }

/* ---------- 17. Desktop (768px and up) ---------- */
@media (min-width: 768px) {
  .section { padding-block: 5rem; }

  .nav-toggle { display: none; }
  .site-nav { display: block; position: static; border: 0; padding: 0; background: none; }
  .site-nav ul { display: flex; gap: 1.9rem; }
  .site-nav li { border: 0; }
  .site-nav a { padding: 0.25rem 0; }

  .hero { padding-block: 5.5rem 6rem; }
  .hero-grid { grid-template-columns: repeat(12, 1fr); align-items: center; gap: 2rem; }
  .hero-copy { grid-column: 1 / 9; }
  .hero-mark { grid-column: 9 / 13; width: 100%; max-width: none; }
  /* undo the mobile full-bleed: back to a normal framed photo in the column */
  /* Desktop: back to a normal framed photo that sizes to its ratio,
     undoing the fixed mobile box above. */
  .hero-mark > .photo {
    width: 100%;
    height: auto;
    margin-left: 0;
    transform: none;
    border: 1.5px solid var(--sand);
    border-radius: 26px 10px 26px 10px;
    box-shadow: 0 10px 28px rgba(37, 26, 16, 0.11);
  }
  .hero-mark > .photo img {
    height: auto !important;
    aspect-ratio: 4 / 3 !important;
    border-radius: inherit;
  }

  .pour-grid { grid-template-columns: 1fr 1fr; }
  .pour-vis {
    top: 0; height: 100vh; height: 100svh;
    border-bottom: 0; background: transparent;
  }
  .pour-svg { height: min(78svh, 620px); max-width: 100%; }
  .pour-steps { padding-block: 6rem; }
  .step { min-height: 88vh; min-height: 88svh; padding-right: 8%; }

  .card-grid { grid-template-columns: repeat(3, 1fr); gap: 1.4rem; }
  .card-grid .card:nth-child(2) { transform: translateY(2rem); }
  .card-grid .card:nth-child(2):hover { transform: translateY(calc(2rem - 4px)); }

  .media-row { grid-template-columns: 1fr 1fr; gap: 3.5rem; }
  .media-row.flip .row-text { order: -1; }

  .footer-grid { grid-template-columns: 2fr 1fr 1fr; }
  .contact-grid { display: grid; grid-template-columns: 1fr 1.1fr; gap: 3.5rem; align-items: start; }
  .map-frame { height: 420px; }
}

/* ---------- 18. Reduced motion: everything still, scene finished ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { transition: none !important; }
  .rise, .ticker-track, .hero-steam path { animation: none !important; }
  .js .reveal { opacity: 1; transform: none; }

  /* The pour scene renders as a finished still: cup full, steam risen */
  .pour-svg .scrub { animation: none !important; }
  .pour-svg .bean-1, .pour-svg .bean-2, .pour-svg .bean-3,
  .pour-svg .stream, .pour-svg .drip { opacity: 0; }
  .pour-svg .coffee-g { translate: 0 0; }
  .pour-svg .steam path { stroke-dashoffset: 0; opacity: 1; }
  .hero-steam path { stroke-dashoffset: 0; opacity: 0.7; }
}

/* ---------- 19. Photography (added in v4) ----------
   Arched photo frames that match the doorway/dripper motif.
   The image sits behind a thin sand border; on hover it zooms
   gently. Kept compositor-only (transform/opacity) so it stays
   smooth on phones. */
.photo {
  /* gently asymmetric corners: two soft, two tighter, for a hand-cut
     coffee-bag feel rather than a uniform boxy or pill frame */
  border-radius: 26px 10px 26px 10px;
  overflow: hidden;
  border: 1.5px solid var(--sand);
  background: var(--card);
  position: relative;
  box-shadow: 0 10px 28px rgba(37, 26, 16, 0.11);
}
.photo img {
  width: 100%;
  aspect-ratio: 16 / 7;
  object-fit: cover;
  border-radius: inherit;
  transition: transform 0.6s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.photo:hover img { transform: scale(1.05); }

/* Warm duotone-ish wash so mixed stock photos feel like one set
   and sit inside the espresso/caramel palette. Sits above the
   image, below nothing interactive. */
.photo::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(37,26,16,0) 70%, rgba(37,26,16,0.14));
  pointer-events: none;
  border-radius: inherit;
}

/* A wide landscape variant for the morning-ritual band */
.photo-wide img { aspect-ratio: 3 / 1; }
/* No dark wash on the wide band photo: it sits on olive already, and the
   extra gradient was making it read as over-filtered. Keep it crisp. */
.photo-wide::after { display: none; }
.photo-wide { border-color: rgba(245, 236, 220, 0.4); }

/* Band photo variant for the uploaded pour-over shot.
   No frame at all: no border, no cream backing, no shadow, no forced box.
   The image simply shows at its own natural proportions, filling the
   available width up to a sensible cap, so it looks like the photo itself
   rather than a photo sitting inside a card. */
.photo-band {
  border: 0;
  background: none;
  box-shadow: none;
  border-radius: 12px;
  max-width: 40rem;
}
.photo-band::after { display: none; }
.photo-band img {
  aspect-ratio: auto;      /* use the image's real shape, no cropping */
  object-fit: fill;
  height: auto;
  border-radius: 12px;
}

/* Hero photo sizing lives with .hero-mark > .photo above (fixed box). */


/* On desktop the step photos are hidden (the sticky pour illustration
   is the visual there); they show on mobile where there is no room to
   place the illustration beside every step. */
@media (min-width: 768px) {
  .band .photo-wide { max-width: 30rem; }
}

/* Reduced motion: no zoom */
@media (prefers-reduced-motion: reduce) {
  .photo img { transition: none !important; }
}


/* ---------- 20. Continuous colour flow (v6) ----------
   The olive band, the dark menu section and the cream below used to be
   three separate colour blocks meeting at visible lines. Instead we wrap
   them in one .flow container carrying a single tall gradient that runs
   olive -> espresso -> cream with no internal edges, so there is no seam
   to see. As you scroll, the gradient drifts (background-position moves
   via a scroll-driven animation), so the colour shifts with the scroll.
   The band and dark sections go transparent and let the flow show through. */

.flow {
  position: relative;
  /* A long, many-stop gradient so no single point reads as a boundary,
     EXCEPT the bottom which is a deliberate hard block edge. The gradient
     itself ENDS on dark; the cream section directly below provides the
     cream, so the dark->cream boundary is the crisp edge between the two
     sections and never drifts on scroll. The top and olive->dark handoff
     stay softly blended. */
  background:
    linear-gradient(
      180deg,
      var(--crema) 0%,
      var(--crema) 5%,       /* cream cushion over the top seam */
      #b7b596 9%,            /* cream easing toward olive */
      #8d9070 13%,
      var(--olive) 18%,      /* olive, held briefly for the band heading + text */
      var(--olive) 27%,
      #565c44 33%,           /* olive -> mossy brown */
      #4a4a38 38%,
      #40382a 43%,           /* mossy -> warm brown */
      var(--espresso-2) 48%,
      var(--espresso) 54%,   /* full dark before the menu list */
      var(--espresso) 100%   /* HOLD dark to the very bottom: hard block edge below */
    );
  background-size: 100% 116%;   /* taller than the box: room to drift */
  background-position: 0% 0%;
}

/* Scroll-driven drift: the gradient eases DOWN a little as the run scrolls
   past, so the colour visibly shifts under you, but only within the 12% of
   slack from background-size. The flat cream cushions at each end stay
   pinned over the seams, so the drift never reveals a hard line.
   Native scroll-timeline where supported; JS fallback drives --flowp. */
@supports (animation-timeline: view()) {
  .flow {
    animation: flowDrift linear both;
    animation-timeline: view();
    animation-range: cover 0% cover 100%;
  }
}
.scrub-js .flow {
  background-position: 0% calc(var(--flowp, 0) * 100%);
}
@keyframes flowDrift {
  from { background-position: 0% 0%; }
  to   { background-position: 0% 100%; }
}

/* Sections inside the flow drop their own solid colour and sit on the
   shared gradient, so there are no block edges between them. */
.flow .band,
.flow .dark {
  background: transparent;
}
.flow .band::before,
.flow .dark::before { display: none; }

/* Readability safety net: a soft dark scrim sits behind the dark menu
   content so the light menu text stays legible even if the gradient
   drifts lighter under it. It fades out at top and bottom so it never
   creates its own visible edge against the flowing gradient. */
.flow .dark::after {
  content: "";
  display: block;
  position: absolute; left: 0; right: 0; top: 0; bottom: 0;
  background: linear-gradient(
    180deg,
    rgba(37,26,16,0) 0%,
    rgba(37,26,16,0.55) 18%,
    rgba(37,26,16,0.55) 72%,
    rgba(37,26,16,0) 100%
  );
  pointer-events: none;
  z-index: 0;
}

/* keep content above everything */
.band > .wrap, .dark > .wrap, .band > .amp-ghost { position: relative; z-index: 1; }

@media (prefers-reduced-motion: reduce) {
  .flow { animation: none !important; background-position: 0% 40% !important; }
}
