/* ============================================================
   The Refresh Clinic — shared styles
   Brand fonts + custom classes layered on top of Tailwind (CDN)
   ============================================================ */

/* ---- Brand display font (kept for reference; logo art already carries it) ---- */
@font-face {
  font-family: "Refresh Clinic";
  src: url("../fonts/RefreshClinic-Regular.otf") format("opentype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* ---- Heading font: Playfair Display (self-hosted variable font) ---- */
@font-face {
  font-family: "Playfair Display";
  src: url("../fonts/playfair-display.woff2") format("woff2");
  font-weight: 400 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Playfair Display";
  src: url("../fonts/playfair-display-italic.woff2") format("woff2");
  font-weight: 400 900;
  font-style: italic;
  font-display: swap;
}

/* ---- Body font: Gill Sans (Nova) family (woff2, ~67% smaller than the source otf/ttf) ---- */
@font-face {
  font-family: "Gill Sans Nova";
  src: url("../fonts/gillsans-light.woff2") format("woff2");
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Gill Sans Nova";
  src: url("../fonts/gillsans-book.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Gill Sans Nova";
  src: url("../fonts/gillsans-book-italic.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Gill Sans Nova";
  src: url("../fonts/gillsans-medium.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Gill Sans Nova";
  src: url("../fonts/gillsans-bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* ---- Base ---- */
html { scroll-behavior: smooth; }
body {
  font-family: "Gill Sans Nova", "Gill Sans", system-ui, sans-serif;
  font-weight: 400;
  font-size: 1.1875rem;   /* ~19px — comfortable body reading size (up from browser default 16px) */
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
h1, h2, h3, .font-heading {
  font-family: "Playfair Display", Georgia, serif;
  font-weight: 600;
  letter-spacing: 0;
}

/* ---- Reusable brand bits ---- */
.eyebrow {
  font-family: "Gill Sans Nova", sans-serif;
  font-weight: 500;
  font-size: 0.72rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #7A5B27; /* darker gold for legible small text on cream (brand gold #BB985E kept for graphics) */
}
/* Thin gold rule that echoes the printed treatment menu */
.rule-gold {
  height: 1px;
  background: linear-gradient(90deg, #BB985E 0%, rgba(187,152,94,0.25) 100%);
}
/* Small gold star divider using the brand mark */
.star-divider {
  width: 20px; height: 20px;
  background: url("../images/star-gold.png") center/contain no-repeat;
  opacity: 0.9;
}
/* Soft placeholder texture for image slots awaiting real photos */
.ph {
  background:
    linear-gradient(135deg, rgba(0,44,65,0.06), rgba(0,44,65,0.02)),
    repeating-linear-gradient(45deg, rgba(0,44,65,0.03) 0 12px, transparent 12px 24px);
}

/* Dotted leader for menu price rows (mirrors the printed menu) */
.menu-row {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
}
.menu-row .leader {
  flex: 1 1 auto;
  border-bottom: 1px dotted rgba(0,44,65,0.35);
  transform: translateY(-3px);
  margin: 0 2px;
}
.menu-row .price { white-space: nowrap; font-weight: 500; }

/* ---- Mobile menu ----
   The panel lives OUTSIDE <header> in the markup and is positioned as a fixed
   overlay. It used to sit inside the header, which meant opening it made a
   position:sticky element grow taller. On mobile a sticky element that changes
   height does not reliably repaint its background over the new area, so chunks
   of the menu background went see-through as you scrolled the page behind it.
   Keeping the header a constant height removes the cause rather than patching it.

   Data attribute, not a class: see the MOTION note about the Tailwind CDN
   re-scanning the DOM on every class change. */
.mobile-menu { display: none; }
.mobile-menu[data-open] {
  display: block;
  position: fixed;
  top: var(--header-h, 5rem);      /* set from the real header height in site.js */
  left: 0;
  right: 0;
  z-index: 45;                     /* under the header (z-50), over the page */
  background-color: #F8F5EE;       /* fully opaque, never translucent */
  border-top: 1px solid rgba(0, 44, 65, 0.10);
  border-bottom: 1px solid rgba(0, 44, 65, 0.10);
  padding: 1rem 1.5rem;
  max-height: calc(100vh - var(--header-h, 5rem));
  overflow-y: auto;
  overscroll-behavior: contain;    /* don't scroll-chain to the page behind */
  box-shadow: 0 12px 28px rgba(0, 44, 65, 0.10);
}
@supports (max-height: 100dvh) {
  .mobile-menu[data-open] { max-height: calc(100dvh - var(--header-h, 5rem)); }
}

/* backdrop-filter on the sticky header is a desktop nicety and a known source
   of repaint artifacts on mobile. Below md the header is simply solid. */
@media (max-width: 767px) {
  header.sticky {
    background-color: #F8F5EE;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}

/* Clear the fixed mobile "Book" bar so the page footer isn't hidden behind it.
   Bar height (~5rem) + the device home-indicator safe area. Only below md (bar is md:hidden). */
@media (max-width: 767px) {
  body { padding-bottom: calc(6rem + env(safe-area-inset-bottom)) !important; }
}

/* Menu price rows — stack cleanly on small screens (drop the dotted leader) */
@media (max-width: 639px) {
  .menu-row { flex-wrap: wrap; row-gap: 2px; }
  .menu-row .leader { display: none; }
  .menu-row .price { margin-left: auto; }
}

/* FAQ accordion (native <details>) */
.faq { border-top: 1px solid rgba(0,44,65,0.12); }
.faq details { border-bottom: 1px solid rgba(0,44,65,0.12); }
.faq summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.15rem 0;
  font-weight: 500;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary .icon {
  flex: none;
  width: 22px; height: 22px;
  position: relative;
  transition: transform 0.25s ease;
  color: #7A5B27;
}
.faq summary .icon::before,
.faq summary .icon::after {
  content: "";
  position: absolute;
  background: currentColor;
  border-radius: 2px;
}
.faq summary .icon::before { top: 10px; left: 3px; right: 3px; height: 2px; }
.faq summary .icon::after { left: 10px; top: 3px; bottom: 3px; width: 2px; transition: transform 0.25s ease; }
.faq details[open] summary .icon::after { transform: scaleY(0); }
.faq details > p { padding: 0 0 1.25rem; color: rgba(0,44,65,0.72); line-height: 1.65; max-width: 60ch; }

/* Nav link underline on hover / active */
.nav-link { position: relative; }
.nav-link::after {
  content: "";
  position: absolute; left: 0; bottom: -4px;
  width: 0; height: 1px; background: #BB985E;
  transition: width 0.25s ease;
}
.nav-link:hover::after,
.nav-link.active::after { width: 100%; }

/* Skip to content (keyboard users only, hidden until focused) */
.skip-link {
  position: absolute; left: 1rem; top: -100px;
  z-index: 100;
  background: #002C41; color: #F8F5EE;
  padding: 0.65rem 1.25rem;
  border-radius: 9999px;
  font-size: 0.9rem;
  transition: top 0.2s ease;
}
.skip-link:focus { top: 1rem; }
#main:focus { outline: none; }


/* ============================================================
   MOTION — scroll + load reveals
   Elements are tagged with [data-reveal] by site.js, so no markup
   depends on this. [data-motion] is set on <html> in the head, before
   first paint, so nothing flashes in before it animates.

   ⚠️ EVERY STATE HERE IS A DATA ATTRIBUTE, NOT A CLASS, AND MUST STAY THAT WAY.
   The Tailwind Play CDN registers:
     observe(document.documentElement,
             {attributes:true, attributeFilter:["class"], childList:true, subtree:true})
   so ANY class change anywhere in the document makes Tailwind re-scan the whole
   DOM and regenerate its stylesheet. Toggling a class per reveal meant a full
   document style recalc on the main thread at every step of the animation
   (8 times during the hero sequence alone), which is what made the hero stutter
   and jump. Data attributes are invisible to that observer.
   ============================================================ */

/* Hold the page until the reveal system is armed (JS sets data-motion-ready).
   If JS is off or errors, main is never hidden / is un-hidden by the failsafe. */
html[data-motion] main { opacity: 0; }
html[data-motion][data-motion-ready] main { opacity: 1; }

/* Motion feel, shared by every reveal below.
   NOTE: an expo-out curve like cubic-bezier(.16,1,.3,1) is wrong here. It covers
   49% of the distance in the first 10% of its duration, so elements snap into
   place and then sit still. That reads as a rush. This curve is much more even
   (24% at 10%), which is what makes a slow scroll feel calm. */
:root {
  --ease-reveal: cubic-bezier(0.25, 0.6, 0.35, 1);
}

/* --- base reveal: fade + rise --- */
[data-reveal] {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 1.1s var(--ease-reveal),
              transform 1.1s var(--ease-reveal);
  transition-delay: var(--reveal-delay, 0ms);
}
[data-reveal][data-in] { opacity: 1; transform: none; }

/* --- headings: rise out from behind a mask (Playfair looks best this way) --- */
[data-reveal="mask"] {
  opacity: 1;
  transform: none;
  overflow: hidden;
  /* room so descenders (g, y, p) on the last line aren't clipped */
  padding-bottom: 0.14em;
  margin-bottom: -0.14em;
}
[data-reveal="mask"] > .mask-inner {
  display: block;
  transform: translateY(105%);
  transition: transform 1.3s var(--ease-reveal);
  transition-delay: var(--reveal-delay, 0ms);
}
[data-reveal="mask"][data-in] > .mask-inner { transform: none; }

/* --- gold rule draws itself in (scaleX, so it works for both the w-16
       rules on the home page and the full-width ones on treatments) --- */
[data-reveal="rule"] {
  opacity: 1;
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform 1.2s var(--ease-reveal);
  transition-delay: var(--reveal-delay, 0ms);
}
[data-reveal="rule"][data-in] { transform: scaleX(1); }

/* --- media: settle in with a touch of scale ---
   Promoted to its own layer: scaling a <video> re-rasterises it every frame
   otherwise. Only 1 to 2 of these exist per page, so the cost is negligible. */
[data-reveal="media"] {
  transform: translateY(28px) scale(0.965);
  will-change: transform, opacity;
}
/* Drop the hint the moment the reveal is done. will-change is a temporary
   promise to the browser, not a setting. Leaving it on permanently keeps the
   element pinned in its own composited layer, and on a <video> that forces a
   slower render path and drops playback frames. */
[data-reveal="media"][data-in] {
  transform: none;
  will-change: auto;
}

/* --- navy bands wipe up like a curtain --- */
[data-reveal="curtain"] {
  opacity: 1;
  transform: none;
  clip-path: inset(100% 0 0 0);
  transition: clip-path 1.3s var(--ease-reveal);
  will-change: clip-path;
}
[data-reveal="curtain"][data-in] { clip-path: inset(0 0 0 0); will-change: auto; }

/* --- gold scroll-progress hairline --- */
.scroll-progress {
  position: fixed; top: 0; left: 0; right: 0;
  height: 2px;
  background: linear-gradient(90deg, #BB985E, #D8BC8A);
  transform: scaleX(0);
  transform-origin: 0 50%;
  z-index: 60;
  pointer-events: none;
}

/* --- header condenses once you scroll past the hero --- */
header.sticky > div { transition: height 0.35s ease; }
header.sticky img { transition: height 0.35s ease; }
header.sticky.scrolled { box-shadow: 0 1px 18px rgba(0, 44, 65, 0.07); }
header.sticky.scrolled > div { height: 4rem; }
header.sticky.scrolled img { height: 28px; }

/* --- respect the OS "reduce motion" setting: show everything, animate nothing --- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  html[data-motion] main { opacity: 1; }
  [data-reveal],
  [data-reveal="mask"] > .mask-inner,
  [data-reveal="media"],
  [data-reveal="curtain"] {
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
    transition: none !important;
  }
  [data-reveal="rule"] { transform: none !important; transition: none !important; }
  .scroll-progress { display: none; }
  header.sticky > div, header.sticky img { transition: none; }
}
