/* Rising Tide Salon Studio v9 MOCKUP layer.
   Loaded after /site.css. Everything the v9 mockup adds or overrides lives
   here, so production's site.css stays untouched and the mockup can be
   ported (or thrown away) as one file.

   Sections:
     1. Typography (Fraunces display serif + Kaushan Script accent)
     2. Hero: split layout with the logo, rise on load, parallax
     3. Section rhythm: sand / blue / white bands with wave edges
     3b. Gallery: carousel with no hover zoom
     4. Cut line: shears on a strip under the nav, snipped bits falling
     5. Service swatch fans
     6. The rising tide inside the Book card
     7. Hours: today highlighted
     8. Reduced motion
*/

/* ============================================================
   1. TYPOGRAPHY
   ============================================================ */
:root {
  --font-body: "DM Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-display: "Fraunces", Georgia, "Times New Roman", serif;
  --font-script: "Kaushan Script", "Brush Script MT", cursive;
  --steel-dark: #4b6275;
}

body { font-family: var(--font-body); }

h1, h2, h3 {
  font-family: var(--font-display);
  font-optical-sizing: auto;
}

h1 {
  font-weight: 500;
  font-size: clamp(30px, 5.4vw, 56px);
  line-height: 1.05;
  letter-spacing: -0.02em;
  max-width: 20ch;
}
h1 em {
  font-style: italic;
  font-weight: 400;
  color: var(--accent2);
}

.section-head h2 {
  font-weight: 500;
  font-size: clamp(26px, 3.6vw, 36px);
  letter-spacing: -0.015em;
}
.section-head .hint {
  font-family: var(--font-script);
  font-weight: 400;
  font-size: 19px;
  color: var(--accent);
}

.card h3 {
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.script {
  font-family: var(--font-script);
  font-weight: 400;
  letter-spacing: 0;
}
.section-head h2 .script { color: var(--accent); }

.cta-section h2 {
  font-weight: 500;
  font-size: clamp(28px, 4.6vw, 46px);
}
.cta-section h2 .script {
  display: inline-block;
  font-size: 1.12em;
  transform: rotate(-3deg);
  color: #e8f7ff;
}

/* ============================================================
   2. HERO (split)
   ============================================================ */
/* Headline on the left, the Rising Tide logo on the right, the
   watercolor banner as the backdrop to both. A white wash over the left
   side keeps the text on a clean ground. On phones the logo stacks above
   the text. The banner lives on a pseudo-element so it can drift
   behind the frame without the frame moving. */
.hero-card {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(0, 0.7fr);
  align-items: center;
  min-height: clamp(380px, 36vw, 470px);
  overflow: hidden;
}
.hero-media {
  position: absolute;
  inset: 0;
  height: auto;
  border-bottom: 0;
  overflow: hidden;
  background: none;
}
.hero-media::before {
  content: "";
  position: absolute;
  inset: -40px 0 -8px;
  background:
    radial-gradient(900px 420px at 70% 30%, rgba(58,159,216,0.18), transparent 60%),
    var(--hero-image, url("/Banner_image.jpg"));
  background-size: cover;
  background-position: center 30%;
}
.hero-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg,
    rgba(255,255,255,0.97) 0%,
    rgba(255,255,255,0.94) 46%,
    rgba(255,255,255,0.45) 66%,
    rgba(255,255,255,0) 84%);
}
/* z-index is explicit because on phones the logo moves first with
   `order`, which also moves it ahead of the backdrop in paint order. */
.hero-body {
  position: relative;
  z-index: 1;
  padding: clamp(24px, 4vw, 52px);
}
/* The logo sits straight on the watercolor, no frame. It uses
   /logo-hero.webp: the same logo with her face, neck and shoulder filled
   white (the hair stays transparent), so she stands out from the blue
   paint. Generated from /logo.png by make_logo_hero.py, which lives in
   the RisingTide_v9_Mockup_tools folder beside the site (not deployed). */
.hero-logo {
  position: relative;
  z-index: 1;
  justify-self: center;
  width: clamp(180px, 20vw, 250px);
  margin: 32px clamp(20px, 3vw, 44px) 32px 0;
}
.hero-logo img {
  width: 100%;
  height: auto;
}

@media (max-width: 760px) {
  .hero-card { grid-template-columns: 1fr; min-height: 0; }
  .hero-logo {
    order: -1;
    width: 170px;
    margin: 28px auto 0;
  }
  .hero-body { padding-top: 22px; }
  .hero-media::after {
    background: linear-gradient(180deg,
      rgba(255,255,255,0) 0,
      rgba(255,255,255,0.25) 120px,
      rgba(255,255,255,0.96) 250px,
      rgba(255,255,255,0.98) 100%);
  }
}

@keyframes rise-in {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}
@keyframes hero-drift {
  from { transform: translateY(-16px) scale(1.04); }
  to   { transform: translateY(26px) scale(1.04); }
}

@media (prefers-reduced-motion: no-preference) {
  .hero-body > *,
  .hero-logo { animation: rise-in 0.9s cubic-bezier(.2,.7,.2,1) both; }
  .hero-body > :nth-child(2) { animation-delay: 0.12s; }
  .hero-body > :nth-child(3) { animation-delay: 0.26s; }
  .hero-logo { animation-delay: 0.18s; }

  @supports (animation-timeline: scroll()) {
    .hero-media::before {
      animation-name: hero-drift;
      animation-duration: auto;
      animation-timing-function: linear;
      animation-fill-mode: both;
      animation-timeline: scroll(root block);
      animation-range: 0 520px;
    }
  }
}

/* ============================================================
   3. SECTION RHYTHM
   ============================================================ */
/* Full-width bands behind the sections alternate warm sand, pale blue
   (the page itself) and white, each with soft wave edges instead of a hard
   line. Cards lose their borders and rely on a softer shadow.
     About     sand
     Services  blue (no band)
     Gallery   white
     Reviews   sand
     Contact   blue (no band)
   main clips sideways overflow because the bands are 100vw wide, which
   includes the scrollbar. */
:root { --sand: #f6eee3; }

main { position: relative; z-index: 0; overflow-x: clip; }

#about, #services, #gallery, #reviews, #contact {
  position: relative;
  padding: clamp(44px, 6.5vw, 80px) 0;
}
#about   { --band: var(--sand); }
#gallery { --band: rgba(255,255,255,0.82); }
#reviews { --band: var(--sand); }

#about::before, #gallery::before, #reviews::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: 0; bottom: 0;
  left: calc(50% - 50vw);
  right: calc(50% - 50vw);
  background: var(--band);
  -webkit-mask:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 28' preserveAspectRatio='none'%3E%3Cpath d='M0 14 C240 0 480 26 720 12 S1200 2 1440 14 V28 H0Z'/%3E%3C/svg%3E") top / 100% 28px no-repeat,
    linear-gradient(#000, #000) 0 27px / 100% calc(100% - 54px) no-repeat,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 28' preserveAspectRatio='none'%3E%3Cpath d='M0 0 H1440 V14 C1200 26 960 2 720 16 S240 28 0 12Z'/%3E%3C/svg%3E") bottom / 100% 28px no-repeat;
          mask:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 28' preserveAspectRatio='none'%3E%3Cpath d='M0 14 C240 0 480 26 720 12 S1200 2 1440 14 V28 H0Z'/%3E%3C/svg%3E") top / 100% 28px no-repeat,
    linear-gradient(#000, #000) 0 27px / 100% calc(100% - 54px) no-repeat,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 28' preserveAspectRatio='none'%3E%3Cpath d='M0 0 H1440 V14 C1200 26 960 2 720 16 S240 28 0 12Z'/%3E%3C/svg%3E") bottom / 100% 28px no-repeat;
}

.card,
.quote {
  border-color: transparent;
  background: rgba(255,255,255,0.94);
  box-shadow: 0 10px 30px rgba(42,100,160,0.09), 0 1px 2px rgba(15,42,69,0.05);
}
.card:hover,
.quote:hover { background: #fff; }

/* ============================================================
   3b. GALLERY
   ============================================================ */
/* Production's carousel, restyled only: no hover zoom (it pushed the photo
   edges out of the frame) and a slighter corner radius, so every photo
   shows whole. */
.carousel-slide { border-radius: 6px; }
.carousel-slide img,
.carousel-slide:hover img { transform: none; transition: none; }

/* ============================================================
   4. CUT LINE
   ============================================================ */
/* A strip attached under the nav, so the shears never touch the logo. It
   carries a dashed "cut here" guide ahead of the shears; behind them the
   line is gone, and each dash they cut drops away as a small falling bit.

   Smoothness: the shears' position and the cut edge follow the scroll
   through CSS scroll-driven animations (below), which the compositor runs
   off the main thread, so they cannot stutter while the page scrolls. The
   cut edge is a cover sliding over the guide (a transform), not a
   clip-path redrawn every frame. Only the blade snip and the falling bits
   are driven by mockup.js, and those are composited transforms too.
   Browsers without scroll timelines get the same motion from mockup.js. */
:root { --cut-strip: 18px; }

.nav { border-bottom-color: transparent; }

.cutline {
  --sw: 34px;                          /* shears width */
  position: absolute;
  left: 0; right: 0;
  top: 100%;
  height: var(--cut-strip);
  /* Opaque (not see-through) so the cover can hide the cut part of the
     guide by matching it exactly; no backdrop blur to recompute while
     scrolling. */
  background: #fbfdfe;
  border-bottom: 1px solid var(--border);
  pointer-events: none;
  overflow: visible;
  container-type: inline-size;
}
@media (min-width: 821px) {
  .cutline { --sw: 40px; }
}

/* Dashes are a fixed 11px background pattern rather than a dashed border,
   so each falling bit (one per 11px cut) matches a dash's size and pitch. */
.cutline-guide {
  position: absolute;
  left: 0; right: 0;
  top: 50%;
  height: 1.5px;
  margin-top: -0.75px;
  background: repeating-linear-gradient(90deg, rgba(42,143,212,0.55) 0 6px, transparent 6px 11px);
}

/* Hides the part of the guide already cut: parked just off the left edge,
   its right edge slides to the cut point. */
.cutline-cover {
  position: absolute;
  top: 0; bottom: 0;
  right: 100%;
  width: 100%;
  background: #fbfdfe;
  will-change: transform;
}

/* A pool of these is created once; mockup.js animates them with the Web
   Animations API (transform and opacity only), so falling bits never add
   or remove elements while the page scrolls. Hidden until animated. */
.cutline-bit {
  position: absolute;
  top: 50%; left: 0;
  width: 6px;
  height: 1.5px;
  margin-top: -0.75px;
  background: rgba(42,143,212,0.7);
  opacity: 0;
}

.cutline-shears {
  position: absolute;
  top: 50%; left: 0;
  width: var(--sw);
  margin-top: calc(var(--sw) * -0.2);
  will-change: transform;
}

/* Scroll-driven: shears travel the full strip and the cover's edge tracks
   the cut point (70% along the blades) as the page scrolls top to bottom. */
@supports (animation-timeline: scroll()) {
  .cutline-shears,
  .cutline-cover {
    animation-duration: auto;
    animation-timing-function: linear;
    animation-fill-mode: both;
    animation-timeline: scroll(root block);
  }
  .cutline-shears { animation-name: cut-shears; }
  .cutline-cover  { animation-name: cut-cover; }
}
@keyframes cut-shears {
  from { transform: translateX(0); }
  to   { transform: translateX(calc(100cqw - 100%)); }
}
@keyframes cut-cover {
  from { transform: translateX(calc(var(--sw) * 0.7)); }
  to   { transform: translateX(calc(100cqw - var(--sw) * 0.3)); }
}
/* The strip deepens the header, so in-page jumps land that much lower.
   site.js honours an element's own scroll-margin-top. */
#about, #services, #gallery, #reviews, #contact {
  scroll-margin-top: calc(var(--nav-compact) + 16px + var(--cut-strip) + var(--alert-h, 0px));
}
.cta-section {
  scroll-margin-top: calc(var(--anchor-offset) + 18px + var(--cut-strip));
}

/* Scissors: three stacked SVGs (two blades and the pivot) in a box with the
   artwork's 160x64 proportions. Each blade rotates as a whole box about the
   pivot, at (62,32) of 160x64, so the compositor moves it without any
   layout or repaint. Each layer carries its own small shadow; filtering
   the static layer (not a parent whose children move) means the shadow is
   drawn once and then just moved with the layer. mockup.js sets the blade
   angles. */
.shears {
  position: relative;
  width: 100%;
  aspect-ratio: 160 / 64;
}
.shears svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  filter: drop-shadow(0 1px 1.5px rgba(15,42,69,0.22));
}
.shears .blade {
  transform-origin: 38.75% 50%;
  will-change: transform;
}
.cutline-shears.resting .blade { transition: transform 0.25s ease; }

/* ============================================================
   5. SERVICE SWATCH FANS
   ============================================================ */
/* Each service card carries a salon swatch ring: five locks of hair hung
   from one ring, showing that service's finished result. They fan out as
   the card scrolls into view and further on hover.
   The locks are rendered images (/swatches/<service>.webp, five 32x106
   cells per sprite at 2x, each with its soft shadow baked in), drawn
   strand by strand with real shine by
   make_swatches.py (RisingTide_v9_Mockup_tools, beside the site, not
   deployed), so they read as hair rather than stripes. */
.swatch {
  position: relative;
  width: 156px;
  height: 118px;
  margin: 0 0 10px -10px;
  --spread: 3deg;
  /* No CSS filter here: a drop-shadow on the fan forced a full repaint on
     every frame the locks moved. The shadow is baked into the images. */
}
.swatch.in-view { --spread: 14deg; }
@media (hover: hover) {
  .card:hover .swatch { --spread: 19deg; }
}

.swatch b {
  position: absolute;
  top: 0; left: 50%;
  width: 18px; height: 18px;
  margin-left: -9px;
  border-radius: 50%;
  border: 3px solid #a9bccb;
  box-shadow: inset 0 1px 1px rgba(255,255,255,0.8), 0 1px 2px rgba(15,42,69,0.25);
  z-index: 2;
}

.swatch i {
  position: absolute;
  top: 9px; left: 50%;
  width: 32px;
  height: 106px;
  margin-left: -16px;
  transform-origin: 50% 3px;
  transform: rotate(calc(var(--k) * var(--spread) * -1));
  transition: transform 0.65s cubic-bezier(.3,1.45,.5,1);
  transition-delay: calc(var(--n) * 30ms);
  background: var(--sprite) no-repeat;
  background-size: 160px 106px;
  background-position: calc(var(--n) * -32px) 0;
}
/* Metal clamp at the top of each lock. */
.swatch i::before {
  content: "";
  position: absolute;
  top: 0; left: 7px; right: 7px;
  height: 10px;
  border-radius: 2px;
  background: linear-gradient(180deg, #f2f6f9, #b4c5d2 60%, #8ea3b5);
  box-shadow: 0 1px 1px rgba(15,42,69,0.25);
}
.swatch i:nth-of-type(1) { --k: -2; --n: 0; }
.swatch i:nth-of-type(2) { --k: -1; --n: 1; }
.swatch i:nth-of-type(3) { --k:  0; --n: 2; }
.swatch i:nth-of-type(4) { --k:  1; --n: 3; }
.swatch i:nth-of-type(5) { --k:  2; --n: 4; }

.swatch--color      { --sprite: url("/swatches/color.webp"); }
.swatch--balayage   { --sprite: url("/swatches/balayage.webp"); }
.swatch--correction { --sprite: url("/swatches/correction.webp"); }
.swatch--cut        { --sprite: url("/swatches/cut.webp"); }
.swatch--keratin    { --sprite: url("/swatches/keratin.webp"); }
.swatch--blowout    { --sprite: url("/swatches/blowout.webp"); }

/* ============================================================
   6. THE RISING TIDE (Book card)
   ============================================================ */
/* A deep-water swell rises through the card as it scrolls into view. The
   water is darker than the card, so it adds contrast behind the white text
   rather than taking it away. mockup.js sets the water level directly as a
   transform on .tide-level (settling in the gap under the paragraph, so the
   crest line never runs through text). The drifting waves only run while
   the card is on screen (.tide-live, also set by mockup.js). */
.cta-section > h2,
.cta-section > p,
.cta-section > .cta-note { position: relative; z-index: 1; }

.tide {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  border-radius: inherit;
  pointer-events: none;
}
.tide-level {
  position: absolute;
  inset: 0;
  transform: translateY(100%);   /* below the card until mockup.js runs */
  will-change: transform;
}
.tide-wave {
  position: absolute;
  top: 0; left: 0;
  bottom: -40px;
  width: calc(100% + 600px);
  -webkit-mask:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 600 28' preserveAspectRatio='none'%3E%3Cpath d='M0 14 C100 2 200 2 300 14 S500 26 600 14 V28 H0Z'/%3E%3C/svg%3E") repeat-x 0 0 / 600px 28px,
    linear-gradient(#000, #000) no-repeat 0 27px / 100% 100%;
          mask:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 600 28' preserveAspectRatio='none'%3E%3Cpath d='M0 14 C100 2 200 2 300 14 S500 26 600 14 V28 H0Z'/%3E%3C/svg%3E") repeat-x 0 0 / 600px 28px,
    linear-gradient(#000, #000) no-repeat 0 27px / 100% 100%;
}
/* Crest line drawn on the same curve, so it sits exactly on the wave edge. */
.tide-wave::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 28px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 600 28' preserveAspectRatio='none'%3E%3Cpath d='M0 14 C100 2 200 2 300 14 S500 26 600 14' fill='none' stroke='%23ffffff' stroke-opacity='.45' stroke-width='3'/%3E%3C/svg%3E") repeat-x 0 0 / 600px 28px;
}
.tide-wave.w1 {
  background: linear-gradient(180deg, rgba(10,58,118,0.22), rgba(8,44,96,0.34));
  animation: tide-drift 17s linear infinite paused;
}
.tide-wave.w2 {
  top: 14px;
  background: linear-gradient(180deg, rgba(8,44,96,0.20), rgba(6,34,78,0.34));
  animation: tide-drift 24s linear infinite reverse paused;
  animation-delay: -6s;
}
.tide-live .tide-wave { animation-play-state: running; }
@keyframes tide-drift {
  to { transform: translateX(-600px); }
}

/* ============================================================
   7. HOURS: today highlighted
   ============================================================ */
/* mockup.js marks today's row (in Sarasota's time zone). */
.hours-row.is-today {
  background: rgba(42,143,212,0.08);
  box-shadow: inset 3px 0 0 var(--accent);
}
.hours-row.is-today dt,
.hours-row.is-today dd { color: var(--text); font-weight: 700; }
.today-tag {
  display: inline-block;
  margin-left: 8px;
  padding: 2px 7px 3px;
  border-radius: 20px;
  background: var(--accent);
  color: #fff;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  vertical-align: 1px;
}

/* ============================================================
   8. REDUCED MOTION
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .tide-wave.w1,
  .tide-wave.w2 { animation: none; }
  .swatch i { transition: none; }
}
