@charset "UTF-8";
/* =========================================================================
   ANCHISES -- Coffee House & Studio
   stylesheet
   v1.6 -- fix: closed mobile nav drawer no longer overlaps/covers the header
          wordmark (root cause: drawer used translateY hide, now visibility)
   ========================================================================= */

/* =========================================================================
   ANCHISES -- design tokens
   ========================================================================= */
:root {
  /* palette -- pulled from the logo concept sheet */
  --ink:          #1f1612;   /* warm near-black for body text */
  --ink-soft:     #4a3b32;   /* muted body for secondary text */
  --paper:        #f4ead4;   /* cream -- the badge background */
  --paper-warm:   #ebdfc3;   /* slightly deeper cream for section breaks */
  --paper-edge:   #d9c9a7;   /* rule/border on cream */
  --oxblood:      #6e2018;   /* primary brand burgundy */
  --oxblood-deep: #4f1610;   /* hover / pressed */
  --terracotta:   #c97a5a;   /* warm accent (used sparingly) */
  --gold:         #a8854e;   /* ornamental gold */

  /* type */
  --font-display: "Fraunces", "Apple Garamond", "Iowan Old Style", Georgia, serif;
  --font-body:    "Lora", Georgia, "Times New Roman", serif;

  /* spacing scale (rem) */
  --s-1: 0.5rem;
  --s-2: 1rem;
  --s-3: 1.5rem;
  --s-4: 2rem;
  --s-5: 3rem;
  --s-6: 4.5rem;
  --s-7: 7rem;

  /* layout */
  --measure: 36rem;          /* readable body column */
  --container: 78rem;        /* page max width */
  --gutter: clamp(1.25rem, 4vw, 3rem);
  --header-h: 4.5rem;        /* sticky-header height; mobile overrides below */

  /* motion */
  --ease:       cubic-bezier(.2,.7,.2,1);    /* general */
  --ease-expo:  cubic-bezier(0.16, 1, 0.3, 1); /* premium decel -- calm, never overshoots */
  --page-fade:  600ms;
  --reveal-duration: 800ms;
  --reveal-distance: 18px;
}

/* =========================================================================
   Base
   ========================================================================= */
*,*::before,*::after { box-sizing: border-box; }

/* iOS/Android -- suppress the default tap-flash. We provide our own :active
   states where tap feedback matters. */
* { -webkit-tap-highlight-color: transparent; }

/* Faster tap response on older mobile, no scroll-zoom on interactive bits */
a, button, [role="button"] { touch-action: manipulation; }

html { -webkit-text-size-adjust: 100%; }

/* Smooth in-page anchor scrolling -- gated by reduced-motion. The
   scroll-padding-top accounts for the sticky header so the section title
   doesn't end up tucked underneath it. */
@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
    scroll-padding-top: calc(var(--header-h) + 1rem);
  }
}

/* Skip-to-content for keyboard users -- visually hidden until focused. */
.skip-link {
  position: absolute;
  left: 1rem;
  top: -3rem;
  z-index: 200;
  padding: 0.6rem 1rem;
  background: var(--oxblood);
  color: var(--paper);
  font-family: var(--font-display);
  font-size: 0.85rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  border-radius: 2px;
  transition: top 0.2s var(--ease-expo);
}
.skip-link:focus-visible {
  top: 1rem;
  outline: 2px solid var(--paper);
  outline-offset: 2px;
}

/* Page fade-in. JS adds .is-loaded on DOMContentLoaded. The keyframe
   fallback below catches the case where JS doesn't run for any reason --
   the page still appears, just a fraction late. Never leaves a blank page. */
body {
  opacity: 0;
  transition: opacity var(--page-fade) var(--ease-expo);
}
body.is-loaded { opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
  body { animation: anchises-body-show 0ms calc(var(--page-fade) + 200ms) forwards; }
}
@keyframes anchises-body-show { to { opacity: 1; } }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 1.0625rem;       /* 17px */
  line-height: 1.65;
  font-feature-settings: "kern", "liga", "onum"; /* old-style figures */
  /* subtle paper grain -- done in CSS so there's no image dependency */
  background-image:
    radial-gradient(rgba(110,32,24,0.025) 1px, transparent 1px),
    radial-gradient(rgba(31,22,18,0.018) 1px, transparent 1px);
  background-size: 3px 3px, 7px 7px;
  background-position: 0 0, 1px 2px;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, svg { display: block; max-width: 100%; }

a {
  color: var(--oxblood);
  text-decoration: none;
  text-underline-offset: 0.2em;
  transition: color .2s var(--ease);
}
a:hover { color: var(--oxblood-deep); text-decoration: underline; }
a:focus-visible {
  outline: 2px solid var(--oxblood);
  outline-offset: 3px;
  border-radius: 2px;
}

h1,h2,h3,h4 {
  font-family: var(--font-display);
  font-weight: 500;
  color: var(--ink);
  letter-spacing: -0.01em;
  margin: 0;
}

p { margin: 0 0 1em; }

/* small-caps eyebrow / label */
.eyebrow {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--oxblood);
  font-feature-settings: "smcp";
}

.container {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Greek-key meander divider, built in pure CSS so it scales perfectly */
.meander {
  height: 16px;
  background-image:
    linear-gradient(90deg, var(--oxblood) 50%, transparent 50%),
    linear-gradient(90deg, var(--oxblood) 50%, transparent 50%),
    linear-gradient(0deg,  var(--oxblood) 50%, transparent 50%),
    linear-gradient(0deg,  var(--oxblood) 50%, transparent 50%);
  background-size: 16px 2px, 16px 2px, 2px 16px, 2px 16px;
  background-position: 0 0, 8px 14px, 0 0, 14px 0;
  background-repeat: repeat-x;
  opacity: .55;
}

/* =========================================================================
   Header / nav
   ========================================================================= */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--paper-edge);
  transition:
    background-color 0.35s var(--ease-expo),
    border-color     0.35s var(--ease-expo),
    box-shadow       0.35s var(--ease-expo);
  /* Notch-aware on iOS -- pulls right & left edges in past the safe area */
  padding-left:  env(safe-area-inset-left);
  padding-right: env(safe-area-inset-right);
}
/* JS adds .is-scrolled once the hero is out of view. Slightly more opaque
   backdrop + a hairline shadow signals "page is now scrolled". */
.site-header.is-scrolled {
  background: color-mix(in srgb, var(--paper) 96%, transparent);
  border-bottom-color: transparent;
  box-shadow: 0 4px 24px rgba(31, 22, 18, 0.06);
}
.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  height: var(--header-h);
}
.wordmark {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.25rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--oxblood);
  text-decoration: none;
  /* Overflow-proofing. As a flex item the wordmark defaults to min-width:auto,
     which refuses to shrink below its content width -- so a long wordmark with
     nowrap forces the whole header wider than the viewport and the page scrolls
     sideways (this is what emptied the mobile header in v1.3). Setting
     min-width:0 lets it shrink; max-width + overflow + ellipsis clip it instead
     of overflowing. On mobile the suffix span is hidden so "ANCHISES" shows in
     full; this is the safety net if that rule ever fails to apply. */
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.wordmark span { color: var(--ink-soft); font-weight: 400; }

.nav { display: flex; gap: var(--s-4); align-items: center; }
.nav a {
  position: relative;
  font-family: var(--font-display);
  font-size: 0.82rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink);
  font-weight: 500;
  text-decoration: none;
  padding-block: 0.4rem;       /* gives the underline rule space */
  transition: color 0.3s var(--ease-expo);
}
/* Animated under-rule: scales from 0 -> 1 from the LEFT on hover/focus,
   and back to 0 from the RIGHT on un-hover, so it "slides through" rather
   than just appearing/disappearing. */
.nav a::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -2px;
  height: 1px;
  background: var(--oxblood);
  transform: scaleX(0);
  transform-origin: right center;
  transition: transform 0.45s var(--ease-expo);
}
/* Active section (set by JS via aria-current). Always-on underline. */
.nav a[aria-current="true"] { color: var(--oxblood); }
.nav a[aria-current="true"]::after {
  transform: scaleX(1);
  transform-origin: left center;
}

/* Hover effects on devices that genuinely have hover -- never on touch.
   Without this gate, mobile users get a sticky underline after tapping
   that doesn't go away until they tap somewhere else. */
@media (hover: hover) {
  .nav a:hover { color: var(--oxblood); }
  .nav a:hover::after,
  .nav a:focus-visible::after {
    transform: scaleX(1);
    transform-origin: left center;
  }
}
/* :focus-visible always shows the rule (keyboard accessibility) */
.nav a:focus-visible::after {
  transform: scaleX(1);
  transform-origin: left center;
}

/* hamburger toggle -- hidden on desktop */
.nav-toggle {
  display: none;
  flex-shrink: 0;   /* never shrink the button; the wordmark shrinks instead */
  background: transparent;
  border: 1px solid var(--paper-edge);
  border-radius: 999px;
  padding: 0.5rem 0.9rem;
  font-family: var(--font-display);
  font-size: 0.78rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink);
  cursor: pointer;
  transition: border-color 0.3s var(--ease-expo), color 0.3s var(--ease-expo);
}
.nav-toggle:hover,
.nav-toggle:focus-visible { border-color: var(--oxblood); color: var(--oxblood); }
.nav-toggle:active { transform: scale(0.97); }

/* =========================================================================
   Hero
   ========================================================================= */
.hero {
  padding-block: clamp(3.5rem, 9vw, 7rem) clamp(3rem, 7vw, 5.5rem);
  position: relative;
  overflow: hidden;
}
.hero__grid {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: clamp(2rem, 6vw, 5rem);
  align-items: center;
}

/* Hero stagger -- distinct from the .reveal pattern used for below-fold
   content. Hero elements are in view on page load, so we don't need
   IntersectionObserver. Each element starts invisible + offset, then
   animates in on body.is-loaded with a per-element delay set inline as
   "--stagger: NNNms". The animation runs once and forwards stops it
   at the final state. */
.hero-stagger {
  opacity: 0;
  transform: translateY(20px);
}
/* Robustness: if JS never adds .is-loaded (script fails to load, JS off),
   hero items still come in after a slightly longer delay. The more
   specific .is-loaded rule below wins when JS is healthy. */
@media (prefers-reduced-motion: no-preference) {
  .hero-stagger {
    animation: anchises-rise 900ms var(--ease-expo) 1.2s forwards;
  }
}
body.is-loaded .hero-stagger {
  animation: anchises-rise 900ms var(--ease-expo) forwards;
  animation-delay: var(--stagger, 0ms);
}
@keyframes anchises-rise {
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .hero-stagger { opacity: 1; transform: none; animation: none; }
}

.hero__eyebrow { margin-bottom: var(--s-3); }
.hero__title {
  font-family: var(--font-display);
  font-weight: 400;
  /* fluid: 4rem -> 8rem */
  font-size: clamp(3.75rem, 9vw, 8rem);
  line-height: 0.92;
  letter-spacing: -0.025em;
  color: var(--oxblood);
  margin-bottom: var(--s-3);
  font-variation-settings: "SOFT" 30, "opsz" 144;
}
.hero__title em {
  font-style: italic;
  font-weight: 300;
  color: var(--ink);
  display: block;
  font-size: 0.42em;
  letter-spacing: 0.04em;
  margin-top: var(--s-2);
}
.hero__lede {
  font-size: clamp(1.15rem, 1.6vw, 1.4rem);
  line-height: 1.5;
  max-width: 32rem;
  color: var(--ink-soft);
  margin-bottom: var(--s-4);
}
.hero__keyline {
  display: inline-flex;
  align-items: center;
  gap: 0.85rem;
  font-family: var(--font-display);
  font-size: 0.82rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink-soft);
  font-feature-settings: "smcp";
}
.hero__keyline::before,
.hero__keyline::after {
  content: "";
  width: 2.5rem;
  height: 1px;
  background: var(--oxblood);
  opacity: .6;
}
.hero__keyline .dot {
  width: 4px; height: 4px; border-radius: 50%; background: var(--oxblood);
  display: inline-block;
}

/* badge column */
.hero__badge {
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
}
/* Subtle float -- once the load stagger completes, the badge rises and
   settles on a slow loop. Gated by reduced-motion. */
@media (prefers-reduced-motion: no-preference) {
  body.is-loaded .hero__badge .brand-mark {
    animation: anchises-float 7s ease-in-out 1.5s infinite;
  }
}
@keyframes anchises-float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-6px); }
}
.brand-mark {
  /* The supplied PNG has been cleaned: outer background made transparent,
     inner cream shifted to match the page exactly. So no clip-path needed
     (the image is already a clean circular silhouette) and no rectangular
     edge issues. Soft drop-shadow gives a subtle lift consistent with the
     feature-row photos elsewhere on the page. */
  width: min(100%, 22rem);
  aspect-ratio: 1;
  object-fit: contain;
  filter: drop-shadow(0 6px 18px rgba(78, 22, 16, 0.10));
}

/* =========================================================================
   Sections
   ========================================================================= */
section { padding-block: clamp(4rem, 9vw, 7rem); }
.section-title {
  font-size: clamp(2.25rem, 4.2vw, 3.5rem);
  line-height: 1.05;
  letter-spacing: -0.02em;
  margin-bottom: var(--s-2);
  max-width: 22ch;
}
.section-title em { font-style: italic; color: var(--oxblood); }

/* Story / manifesto */
.story {
  background: var(--paper-warm);
  border-block: 1px solid var(--paper-edge);
}
.story__inner {
  max-width: 48rem;
  margin-inline: auto;
  text-align: left;
}
.story__head { text-align: center; margin-bottom: var(--s-5); }
.story__head .eyebrow { margin-bottom: var(--s-2); }
.story__body {
  font-size: clamp(1.05rem, 1.3vw, 1.2rem);
  line-height: 1.75;
  color: var(--ink);
}
/* Drop cap on the first paragraph */
.story__body > p:first-of-type::first-letter {
  font-family: var(--font-display);
  font-weight: 500;
  float: left;
  font-size: 5.2em;
  line-height: 0.85;
  padding-right: 0.12em;
  padding-top: 0.06em;
  color: var(--oxblood);
}

.pullquote {
  margin: var(--s-6) 0;
  text-align: center;
  position: relative;
}
.pullquote blockquote {
  margin: 0;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(1.6rem, 3.2vw, 2.4rem);
  line-height: 1.25;
  color: var(--oxblood);
  letter-spacing: -0.01em;
  max-width: 28ch;
  margin-inline: auto;
}
.pullquote blockquote::before { content: "\201C"; }
.pullquote blockquote::after  { content: "\201D"; }
.pullquote cite {
  display: block;
  margin-top: var(--s-3);
  font-family: var(--font-display);
  font-size: 0.78rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink-soft);
  font-style: normal;
  font-feature-settings: "smcp";
}

/* The House -- five "rooms" */
.house__head {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-5);
  align-items: end;
  margin-bottom: var(--s-6);
}
.house__intro {
  max-width: 32rem;
  color: var(--ink-soft);
  font-size: 1.075rem;
  line-height: 1.65;
}

.rooms {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: var(--s-3);
}
/* deliberate asymmetric layout -- 5 cards across a 6-col grid */
.room:nth-child(1) { grid-column: span 3; }
.room:nth-child(2) { grid-column: span 3; }
.room:nth-child(3) { grid-column: span 2; }
.room:nth-child(4) { grid-column: span 2; }
.room:nth-child(5) { grid-column: span 2; }

.room {
  background: var(--paper-warm);
  border: 1px solid var(--paper-edge);
  padding: clamp(1.5rem, 2.5vw, 2.25rem);
  border-radius: 2px;
  position: relative;
  overflow: hidden;
  transition:
    transform     0.45s var(--ease-expo),
    border-color  0.45s var(--ease-expo),
    background    0.45s var(--ease-expo),
    box-shadow    0.45s var(--ease-expo);
}
/* Accent rule that slides in along the bottom on hover -- a small finishing
   touch that signals interactivity without shouting. */
.room::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%;
  height: 2px;
  background: var(--oxblood);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.55s var(--ease-expo);
}
/* Tap feedback -- universal (touch and mouse) */
.room:active {
  transform: scale(0.995);
}
/* Hover-only transforms (no sticky-hover on touch) */
@media (hover: hover) {
  .room:hover {
    transform: translateY(-4px);
    border-color: var(--oxblood);
    background: var(--paper);
    box-shadow: 0 14px 30px rgba(78, 22, 16, 0.09);
  }
  .room:hover::after { transform: scaleX(1); }
}
.room__num {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 300;
  font-size: 0.95rem;
  color: var(--terracotta);
  letter-spacing: 0.05em;
  margin-bottom: var(--s-2);
}
.room h3 {
  font-size: clamp(1.4rem, 2vw, 1.75rem);
  line-height: 1.15;
  margin-bottom: var(--s-2);
  color: var(--oxblood);
}
.room p {
  margin: 0;
  font-size: 1rem;
  line-height: 1.6;
  color: var(--ink-soft);
}

/* Visit */
.visit {
  background: var(--ink);
  color: var(--paper);
  position: relative;
  overflow: hidden;
}
.visit::before {
  /* same paper grain but inverted */
  content: "";
  position: absolute; inset: 0;
  background-image:
    radial-gradient(rgba(244,234,212,0.04) 1px, transparent 1px);
  background-size: 4px 4px;
  pointer-events: none;
}
.visit .eyebrow { color: var(--terracotta); }
.visit .section-title { color: var(--paper); }
.visit .section-title em { color: var(--terracotta); }

.visit__grid {
  display: grid;
  grid-template-columns: 1.1fr 1fr 1fr;
  gap: var(--s-5);
  margin-top: var(--s-5);
  position: relative;
}
.visit__col h4 {
  font-family: var(--font-display);
  font-size: 0.82rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--terracotta);
  margin-bottom: var(--s-2);
  font-weight: 600;
  font-feature-settings: "smcp";
}
.visit__col p, .visit__col li {
  color: color-mix(in srgb, var(--paper) 85%, transparent);
  font-size: 1.05rem;
  line-height: 1.7;
}
.visit__col ul { list-style: none; padding: 0; margin: 0; }
.visit__col li {
  display: flex; justify-content: space-between;
  padding: 0.35rem 0;
  border-bottom: 1px solid rgba(244,234,212,0.08);
}
.visit__col li:last-child { border-bottom: none; }
.visit__col li span:last-child { color: var(--paper); }

.visit a {
  color: var(--terracotta);
  text-decoration: none;
  background-image: linear-gradient(currentColor, currentColor);
  background-position: 0 100%;
  background-repeat: no-repeat;
  background-size: 100% 1px;
  transition:
    color           0.3s var(--ease-expo),
    background-size 0.5s var(--ease-expo);
}
@media (hover: hover) {
  .visit a:hover {
    color: var(--paper);
    background-size: 100% 2px;
  }
}

/* The mailto link in the Get-in-Touch column is the primary CTA of the
   Visit section -- give it a touch more weight than other links so the eye
   lands on it. Display serif, slightly larger, generous breathing room. */
.visit__email {
  margin-top: var(--s-2);
  margin-bottom: var(--s-2);
}
.visit__email a {
  font-family: var(--font-display);
  font-size: clamp(1.1rem, 1.6vw, 1.3rem);
  letter-spacing: -0.005em;
  font-weight: 500;
}

/* =========================================================================
   Feature rows -- asymmetric photo + copy
   Used once: the cup shot (image-right) before Visit. The image is portrait
   orientation so we lean into that rather than crop it to a landscape
   full-bleed. (The interior scene below, which IS landscape, uses .scene.)
   ========================================================================= */
.feature {
  padding-block: clamp(4rem, 8vw, 6.5rem);
}
.feature--cream { background: var(--paper-warm); border-block: 1px solid var(--paper-edge); }

.feature__grid {
  display: grid;
  grid-template-columns: 5fr 6fr;
  gap: clamp(2rem, 6vw, 5rem);
  align-items: center;
}
.feature__grid--reverse { grid-template-columns: 6fr 5fr; }
.feature__grid--reverse .feature__media { order: 2; }
.feature__grid--reverse .feature__copy  { order: 1; }

.feature__media {
  position: relative;
  overflow: hidden;
  border-radius: 2px;
}
.feature__media img {
  width: 100%;
  height: auto;
  /* portrait photos -- cap height so they don't dominate on tall viewports */
  max-height: 70vh;
  object-fit: cover;
  box-shadow: 0 18px 40px rgba(31, 22, 18, 0.18);
  /* a thin warm border so the photo feels framed, not just dropped in */
  outline: 1px solid var(--paper-edge);
  outline-offset: -1px;
  transition: transform 0.9s var(--ease-expo);
}
/* Slow zoom on hover (mouse only). 0.9s is intentionally long -- it feels
   considered, not gimmicky. */
@media (hover: hover) {
  .feature__media:hover img { transform: scale(1.03); }
}

.feature__copy { max-width: 30rem; }
.feature__copy .eyebrow { margin-bottom: var(--s-2); }
.feature__copy h2 {
  font-size: clamp(2rem, 3.5vw, 3rem);
  line-height: 1.08;
  letter-spacing: -0.02em;
  margin-bottom: var(--s-3);
}
.feature__copy h2 em { font-style: italic; color: var(--oxblood); }
.feature__copy p {
  font-size: 1.075rem;
  line-height: 1.7;
  color: var(--ink-soft);
}

/* =========================================================================
   Scene -- full-bleed landscape illustration of the interior. Sits between
   Story and The House as the visual heart of the page. The image carries
   its own typography (signage, room labels), so no overlay or caption.
   ========================================================================= */
.scene {
  /* Full viewport width regardless of the container max-width above.
     Section element fills its own row in the document flow, no padding. */
  margin: 0;
  padding: 0;
  background: var(--ink);   /* warm fallback while the JPG decodes */
  overflow: hidden;
}
.scene img {
  display: block;
  width: 100%;
  height: auto;
  /* Cap height on very tall viewports so the scene doesn't dominate the
     whole screen -- feels like a band, not a hero takeover. */
  max-height: 80vh;
  object-fit: cover;
}
/* Subtle scale-in as the section enters view. Overrides the .reveal default
   transform so this image scales rather than translates -- the existing
   .reveal opacity transition still drives the fade. */
.scene.reveal { transform: none; }
.scene.reveal img {
  transform: scale(1.04);
  transition: transform 1.8s var(--ease-expo);
}
.scene.reveal.is-visible img { transform: scale(1); }

@media (prefers-reduced-motion: reduce) {
  .scene.reveal img,
  .scene.reveal.is-visible img { transform: none; transition: none; }
}

/* Footer */
.site-footer {
  padding-block: var(--s-5);
  background: var(--ink);
  color: color-mix(in srgb, var(--paper) 60%, transparent);
  border-top: 1px solid rgba(244,234,212,0.1);
}
.site-footer__inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--s-3);
  font-size: 0.85rem;
  letter-spacing: 0.06em;
}
.site-footer .wordmark { color: var(--terracotta); font-size: 1rem; }
.site-footer .wordmark span { color: color-mix(in srgb, var(--paper) 50%, transparent); }

/* =========================================================================
   Reveal animations -- gentle, respect prefers-reduced-motion
   ========================================================================= */
.reveal {
  opacity: 0;
  transform: translateY(var(--reveal-distance));
  transition:
    opacity var(--reveal-duration) var(--ease-expo),
    transform var(--reveal-duration) var(--ease-expo);
  transition-delay: var(--reveal-delay, 0ms);
  /* will-change deliberately NOT set in the default state -- it would keep
     EVERY revealable element on its own GPU compositing layer permanently,
     burning memory on mid-range Android. JS applies .is-revealing for the
     duration of the transition only, then removes it on transitionend. */
}
.reveal.is-revealing { will-change: opacity, transform; }
.reveal.is-visible {
  opacity: 1;
  transform: none;
}
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
  .hero-stagger { opacity: 1; transform: none; animation: none; }
  /* Only kill animation/transition on decorative elements -- not on every
     element in the DOM, which would break things like the mobile-nav
     slide-in (a functional transition, not decorative). */
  .room, .feature__media img, .nav a::after, .room::after {
    transition: none !important;
  }
}

/* =========================================================================
   Mobile Responsiveness
   ========================================================================= */
@media (max-width: 900px) {
  .hero__grid {
    grid-template-columns: 1fr;
    gap: var(--s-5);
  }
  .hero__badge { order: -1; }
  .brand-mark { width: min(70%, 18rem); }
  .house__head { grid-template-columns: 1fr; gap: var(--s-3); }
  .visit__grid { grid-template-columns: 1fr; gap: var(--s-4); }

  /* Feature rows: stack image above copy, regardless of reverse order */
  .feature__grid,
  .feature__grid--reverse {
    grid-template-columns: 1fr;
    gap: var(--s-4);
  }
  .feature__grid--reverse .feature__media { order: -1; }
  .feature__grid--reverse .feature__copy  { order: 0; }
  .feature__media img { max-height: 60vh; }

  /* rooms collapse to 2 columns then 1 */
  .rooms { grid-template-columns: repeat(2, 1fr); }
  .room:nth-child(n) { grid-column: span 1; }
}

@media (max-width: 720px) {
  body { font-size: 1rem; }

  /* Smaller header on mobile -- keep --header-h in sync so scroll-padding-top
     still lines anchor targets up correctly. */
  :root { --header-h: 3.75rem; }
  .site-header__inner { height: var(--header-h); }

  /* Wordmark suffix " - Coffee House & Studio" doesn't fit in a phone
     header alongside the toggle. Hide it on mobile -- the full name stays
     in the aria-label, so screen readers still announce it correctly. The
     "ANCHISES" mark alone is plenty of brand stamp at this size. */
  .wordmark span { display: none; }

  /* Hamburger nav */
  .nav-toggle { display: inline-flex; align-items: center; }
  .nav {
    position: absolute;
    inset: 100% 0 auto 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--paper);
    border-bottom: 1px solid var(--paper-edge);
    padding: var(--s-2) var(--gutter) var(--s-3);
    /* iPhone notch / dynamic island: respect the safe area so the drawer
       doesn't tuck content under the status bar / home indicator. */
    padding-left:  max(var(--gutter), env(safe-area-inset-left));
    padding-right: max(var(--gutter), env(safe-area-inset-right));
    /* Hide the closed drawer with visibility+opacity, NOT a big translateY.
       The drawer is anchored at top:100% (the header's bottom edge) but is
       shorter than the header is tall, so translateY(-110%) didn't slide it
       clear of the header -- it landed overlapping it and painted its cream
       background over the wordmark. visibility:hidden guarantees the closed
       drawer never paints or hit-tests over the header. A small translateY
       keeps the open animation feeling like a slide-down. */
    opacity: 0;
    visibility: hidden;
    transform: translateY(-10px);
    transition:
      opacity 0.3s var(--ease-expo),
      transform 0.4s var(--ease-expo),
      visibility 0s linear 0.4s;
    box-shadow: 0 12px 24px rgba(31,22,18,0.08);
    /* Constrain height so very long nav lists on small screens become
       scrollable rather than overflowing the viewport. dvh gives us the
       *real* available viewport on iOS (not the static-100vh that ignores
       the address bar collapse/expand). */
    max-height: calc(100dvh - var(--header-h));
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
  .nav.is-open {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
    transition:
      opacity 0.3s var(--ease-expo),
      transform 0.4s var(--ease-expo),
      visibility 0s;
  }
  .nav a {
    padding: 0.95rem 0;
    border-bottom: 1px solid var(--paper-edge);
    font-size: 0.92rem;
    /* Mobile drawer doesn't need (or want) the animated under-rule from
       desktop -- the row already has a bottom border. Suppress the ::after. */
  }
  .nav a::after { display: none; }
  .nav a:last-child { border-bottom: none; }
  /* Tap feedback inside the drawer */
  .nav a:active { background: var(--paper-warm); color: var(--oxblood); }

  .hero { padding-block: var(--s-5) var(--s-5); }
  .hero__title { font-size: clamp(3rem, 14vw, 4.5rem); }
  .hero__lede { font-size: 1.05rem; }
  .hero__keyline { font-size: 0.72rem; letter-spacing: 0.18em; }
  .hero__keyline::before, .hero__keyline::after { width: 1.5rem; }

  /* Skip the subtle hero badge float on small screens -- saves a tiny bit
     of GPU work and looks calmer in a tight viewport. */
  body.is-loaded .hero__badge .brand-mark { animation: none; }

  .rooms { grid-template-columns: 1fr; }

  .pullquote blockquote { font-size: 1.4rem; }

  .site-footer__inner { flex-direction: column; text-align: center; gap: var(--s-2); }

  /* drop cap stays but tighter */
  .story__body > p:first-of-type::first-letter { font-size: 4.2em; }
}