/* ============================================================
   Components — grain, cursor, curtain, nav, menu, buttons, footer,
   reviews
   ============================================================ */

/* ---- film grain -------------------------------------------- */
.grain {
  position: fixed;
  inset: -50%;
  z-index: 80;
  pointer-events: none;
  opacity: 0.32;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.42'/%3E%3C/svg%3E");
  animation: grainShift 6s steps(6) infinite;
}

@keyframes grainShift {
  0%   { transform: translate3d(0, 0, 0); }
  20%  { transform: translate3d(-4%, 3%, 0); }
  40%  { transform: translate3d(3%, -4%, 0); }
  60%  { transform: translate3d(-3%, -2%, 0); }
  80%  { transform: translate3d(4%, 2%, 0); }
  100% { transform: translate3d(0, 0, 0); }
}


/* ---- custom cursor -----------------------------------------
   One circle, smoothed with a lerp in cursor.js (no separate dot).
   Colour is var(--page-fg) — the same ink the headings use, since
   that token is already the deliberately-legible colour against
   whatever the page background currently is, and it flips bone/night
   with the rest of the page across the theme turn, so the cursor
   never needs its own light/dark case. */
.cursor {
  position: fixed;
  top: 0; left: 0;
  z-index: var(--z-cursor);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.cursor.is-active { opacity: 1; }

.cursor__circle {
  position: absolute;
  top: 0; left: 0;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--page-fg);
  transform: translate(-50%, -50%);
}

@media (hover: none), (max-width: 900px) {
  .cursor { display: none; }
}


/* ---- page curtain ------------------------------------------ */
.curtain {
  position: fixed;
  inset: 0;
  z-index: var(--z-curtain);
  background: var(--bone);
  display: grid;
  place-items: center;
  transition: transform 1.1s var(--ease-in-out);
}

.curtain__mark {
  width: clamp(180px, 22vw, 320px);
  height: auto;
  opacity: 0;
  transform: translateY(0.6rem);
  transition: opacity 0.8s var(--ease-out), transform 0.8s var(--ease-out);
}

body.is-loading .curtain__mark { opacity: 1; transform: none; }

body.is-ready .curtain { transform: translate3d(0, -101%, 0); }
body.is-ready .curtain__mark { opacity: 0; transition-duration: 0.4s; }


/* ---- nav ---------------------------------------------------- */
.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: var(--z-nav);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-md);
  padding: clamp(1rem, 2.2vw, 1.75rem) var(--gutter);
  color: var(--page-fg);
  transition: color 0.5s var(--ease-out), background-color 0.5s var(--ease-out),
              border-color 0.5s var(--ease-out), padding 0.5s var(--ease-out);
  border-bottom: 1px solid transparent;
}

.nav.is-light { color: var(--paper); }

/* keeps the nav legible once the photograph is behind it */
.nav.is-light::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(to bottom, rgba(28, 25, 23, 0.4), transparent);
}

.nav.is-solid {
  background: var(--page-veil);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom-color: var(--page-line);
  color: var(--page-fg);
  padding-block: clamp(0.75rem, 1.4vw, 1.1rem);
}

.nav__logo {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 1.6vw, 1.55rem);
  letter-spacing: 0.01em;
}

.nav__logo-mark {
  width: 15px; height: 22px;
  border: 1px solid currentColor;
  border-radius: 999px 999px 1px 1px;
  flex: none;
  transition: background-color var(--dur-fast) var(--ease-out);
}

.nav__logo:hover .nav__logo-mark { background: var(--clay); border-color: var(--clay); }

.nav__links {
  display: flex;
  gap: clamp(1.25rem, 2.4vw, 2.75rem);
  font-size: var(--fs-small);
  letter-spacing: 0.01em;
}

.nav__links a {
  position: relative;
  padding-block: 0.25rem;
}

.nav__links a::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.5s var(--ease-out);
}

.nav__links a:hover::after { transform: scaleX(1); transform-origin: left; }

.nav__links a[aria-current="page"]::after,
.footer__nav a[aria-current="page"]::after {
  transform: scaleX(1);
  transform-origin: left;
}

.nav__toggle {
  display: none;
  width: 34px; height: 34px;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
}

.nav__toggle span {
  display: block;
  height: 1px;
  width: 100%;
  background: currentColor;
  transition: transform 0.45s var(--ease-in-out), opacity 0.3s;
}

body.is-menu-open .nav__toggle span:nth-child(1) { transform: translateY(3.5px) rotate(45deg); }
body.is-menu-open .nav__toggle span:nth-child(2) { transform: translateY(-3.5px) rotate(-45deg); }

@media (max-width: 900px) {
  .nav__links { display: none; }
  .nav__toggle { display: flex; }
}


/* ---- mobile menu ------------------------------------------- */
.menu {
  position: fixed;
  inset: 0;
  z-index: var(--z-menu);
  background: var(--ink);
  color: var(--paper);
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: var(--gutter);
  clip-path: inset(0 0 100% 0);
  transition: clip-path 0.9s var(--ease-in-out);
  pointer-events: none;
}

body.is-menu-open .menu {
  clip-path: inset(0 0 0% 0);
  pointer-events: auto;
}

.menu__inner {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.menu__inner a {
  font-family: var(--font-display);
  font-size: clamp(2.6rem, 11vw, 4.5rem);
  line-height: 1.2;
  display: flex;
  align-items: baseline;
  gap: 1rem;
  opacity: 0;
  transform: translateY(1.5rem);
  transition: opacity 0.7s var(--ease-out), transform 0.7s var(--ease-out);
}

body.is-menu-open .menu__inner a { opacity: 1; transform: none; }
body.is-menu-open .menu__inner a:nth-child(1) { transition-delay: 0.24s; }
body.is-menu-open .menu__inner a:nth-child(2) { transition-delay: 0.30s; }
body.is-menu-open .menu__inner a:nth-child(3) { transition-delay: 0.36s; }
body.is-menu-open .menu__inner a:nth-child(4) { transition-delay: 0.42s; }
body.is-menu-open .menu__inner a:nth-child(5) { transition-delay: 0.48s; }

.menu__inner a[aria-current="page"] { color: var(--clay); }

.menu__inner em {
  font-family: var(--font-body);
  font-style: normal;
  font-size: var(--fs-micro);
  letter-spacing: var(--track-eyebrow);
  color: var(--ember);
}

.menu__foot {
  margin-top: auto;
  font-family: var(--font-display);
  font-size: 1.15rem;
  color: rgba(244, 240, 232, 0.55);
}


/* ---- buttons & links --------------------------------------- */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 1.05rem 2.4rem;
  border-radius: 999px;
  overflow: hidden;
  isolation: isolate;
  font-size: var(--fs-small);
  font-weight: 400;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  background: var(--ink);
  color: var(--paper);
  will-change: transform;
}

.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--clay);
  transform: translate3d(0, 101%, 0);
  transition: transform 0.65s var(--ease-in-out);
}

.btn:hover::before { transform: translate3d(0, 0, 0); }

.btn span { position: relative; z-index: 1; }

/* outline pill — sits on a light ground */
.btn--ghost {
  background: transparent;
  color: var(--page-fg);
  border: 1px solid var(--page-fg);
  padding: 1.15rem 2.75rem;
  font-size: clamp(0.95rem, 1.15vw, 1.15rem);
  letter-spacing: 0.04em;
  text-transform: none;
}

.btn--ghost::before { background: var(--page-fg); }
.btn--ghost:hover { color: var(--page-bg); }
.btn--ghost span { transition: color 0.45s var(--ease-in-out); }

.btn--light {
  background: var(--paper);
  color: var(--ink);
}

.btn--light::before { background: var(--clay); }
.btn--light:hover { color: var(--paper); }
.btn--light span { transition: color 0.45s var(--ease-in-out); }

.link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-size: var(--fs-small);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: inherit;      /* follows the page ground */
  padding-block: 0.3rem;
}

.link::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: currentColor;
  transform-origin: right;
  transition: transform 0.55s var(--ease-out);
}

.link:hover::after { transform: scaleX(0); }

.link span::after {
  content: "→";
  margin-left: 0.55rem;
  display: inline-block;
  transition: transform 0.5s var(--ease-out);
}

.link:hover span::after { transform: translateX(0.35rem); }

.link--light { color: var(--paper); }


/* ---- footer -------------------------------------------------
   Carries the closing call to action: an oversized wordmark-scale
   headline that runs the full measure, an outline pill beneath it,
   then a three-part base row.
   ------------------------------------------------------------- */
/* No ground of its own — the page is already dark down here. */
.footer {
  color: inherit;
  padding-block: clamp(4.5rem, 12vh, 9rem) clamp(1.75rem, 4vh, 2.75rem);
}

.footer__top {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: clamp(1.75rem, 4vh, 3rem);
}

.footer__tag {
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(1.2rem, 1.7vw, 1.7rem);
  color: var(--clay);
}

/* the big one — sized in vw so two balanced lines fill the measure
   edge to edge at any width ("LET'S CREATE" / "YOUR ARRIVAL") */
.footer__cta {
  /* Retuned for Cinzel, wider again than the face before it. Swept
     against real renders at 360 / 430 / 1024 / 1600: 11vw is the last
     value that still breaks as two lines, 12vw spills to three at
     every width. 10.5 leaves slack. Re-sweep on any heading-font
     change — see README. */
  font-size: clamp(2rem, 11vw, 13.5rem);
  line-height: 0.9;
  letter-spacing: var(--track-display);
  text-transform: uppercase;
  width: 100%;
}

.footer__nav {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(1.25rem, 2.4vw, 2.75rem);
  margin-top: clamp(2.5rem, 6vh, 4.5rem);
  padding-top: var(--sp-lg);
  border-top: 1px solid var(--page-line);
  font-size: var(--fs-small);
}

.footer__nav a {
  position: relative;
  padding-block: 0.2rem;
  color: var(--page-fg-mid);
  transition: color var(--dur-fast) var(--ease-out);
}

.footer__nav a::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.5s var(--ease-out);
}

.footer__nav a:hover { color: var(--clay); }
.footer__nav a:hover::after { transform: scaleX(1); transform-origin: left; }

.footer__base {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-md);
  margin-top: clamp(2.5rem, 7vh, 5rem);
}

.footer__inquiries {
  font-size: var(--fs-small);
  color: var(--page-fg-mid);
}

.footer__inquiries a {
  font-weight: 500;
  color: var(--page-fg);
  border-bottom: 1px solid var(--page-line);
  padding-bottom: 1px;
  transition: color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}

.footer__inquiries a:hover { color: var(--clay); border-color: var(--clay); }

.footer__legal {
  font-size: var(--fs-micro);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--page-fg-low);
}

/* circular outline social button */
.social {
  display: grid;
  place-items: center;
  width: clamp(48px, 4vw, 62px);
  aspect-ratio: 1;
  border: 1px solid var(--page-line);
  border-radius: 50%;
  flex: none;
  transition: background-color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}

.social svg {
  width: 44%;
  height: 44%;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
}

.social .social__dot { fill: currentColor; stroke: none; }

.social:hover {
  background: var(--page-fg);
  border-color: var(--page-fg);
  color: var(--page-bg);
}

@media (max-width: 760px) {
  .footer__base {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--sp-lg);
  }
}


/* ---- reviews -------------------------------------------------
   Rows with a dot marker, hairline dividers, and a tall blush pill
   that appears beside the row you are on. The dot is the state: it
   fills and grows on hover. Rows themselves stay at full brightness —
   dimming the others was an earlier pass and is not what the
   reference does.

   Moved here from home.css when hosts.html reused the same
   testimonial rows with a smaller, host-specific set of quotes —
   the markup and js/reviews.js behaviour are identical on both
   pages, so duplicating ~150 lines of hover-card positioning into a
   second page-specific file risked the two copies drifting apart on
   the next fix. It reads correctly on both the home page's dark
   ground and hosts.html's bone ground with no changes needed: every
   colour here is either a themed --page-* token (which already
   tracks whichever half of the page it's on) or one of the fixed
   --blush/--ink tokens the card itself always uses regardless of
   page background. */
.reviews {
  padding-block: var(--sp-section);
}

.reviews .eyebrow { margin-bottom: var(--sp-xl); }

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

.review {
  position: relative;
  display: flex;
  align-items: baseline;
  gap: clamp(1rem, 2vw, 2.25rem);
  padding-block: clamp(1.75rem, 5.5vh, 4.25rem);
  border-bottom: 1px solid var(--page-line);
  cursor: default;
}

/* opacity-only reveal: a transformed ancestor would become the
   containing block for the fixed-position card inside it */
.review[data-reveal] { transform: none; }

/* the marker carries the hover state */
.review__dot {
  flex: none;
  width: clamp(9px, 0.7vw, 12px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--page-fg);
  opacity: 0.4;
  transform: translateY(-0.3em);
  transition:
    width 0.45s var(--ease-out),
    background-color 0.45s var(--ease-out),
    opacity 0.45s var(--ease-out);
}

.review:hover .review__dot,
.review:focus-visible .review__dot {
  width: clamp(20px, 1.7vw, 30px);
  background: var(--blush);
  opacity: 1;
}

.review__name {
  font-family: var(--font-display);
  font-size: clamp(2rem, 4.6vw, 6.5rem);
  line-height: 1.08;
  letter-spacing: var(--track-display);
  color: var(--page-fg);
}

.review__name i {
  font-style: normal;
  opacity: 0.45;
  padding-inline: 0.15em;
}

.review:focus-visible { outline: none; }

/* ---- the card ---------------------------------------------- */
.review__card {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 55;
  display: flex;
  flex-direction: column;
  justify-content: center;
  width: min(330px, 25vw);
  min-height: 540px;
  padding: clamp(2.75rem, 3.6vw, 4rem) clamp(2rem, 2.6vw, 2.75rem);
  border-radius: 999px;
  background: var(--blush);
  color: var(--ink);
  text-align: center;
  pointer-events: none;
  opacity: 0;
  scale: 0.94;
  transform: translate3d(-100vw, -100vh, 0);
  transition: opacity 0.4s var(--ease-out), scale 0.5s var(--ease-out);
  will-change: transform;
  box-shadow: 0 40px 90px -30px rgba(0, 0, 0, 0.55);
}

.review__card.is-on { opacity: 1; scale: 1; }

.review__label {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: clamp(1.05rem, 1.25vw, 1.3rem);
  margin-bottom: 0.9rem;
}

.review__text {
  font-family: var(--font-body);
  font-weight: 300;
  font-size: var(--fs-small);
  line-height: 1.6;
  color: var(--ink-soft);
}

/* Touch and narrow screens have no hover: show the card inline
   under its row so the testimonial is never unreachable. */
@media (hover: none), (max-width: 900px) {
  .review {
    flex-wrap: wrap;
    align-items: flex-start;
  }

  .review__dot { transform: translateY(0.55em); }

  .review__card {
    position: static;
    order: 3;
    width: 100%;
    min-height: 0;
    margin-top: 0;
    padding: 0;
    border-radius: 0;
    background: none;
    box-shadow: none;
    color: var(--page-fg);
    text-align: left;
    opacity: 1;
    scale: 1;
    transform: none;
    transition: none;
  }

  .review__label { color: var(--page-fg-low); }
  .review__text { color: var(--page-fg-mid); }
  .review__name { font-size: clamp(1.75rem, 7vw, 2.6rem); }
}
