/* Aqua Aveda Salon & Spa — shared site styles (used on every page alongside Tailwind CDN) */

:root {
  color-scheme: light;
  /* Actual rendered height of #main-header (fixed, logo + py-4 at lg+).
     Used by the homepage hero to size itself to exactly one viewport. */
  --header-h: 77px;
}

html {
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* AVEDA brand mark — merchant-mandated global treatment (2026-08-31):
   "Anywhere it says Aveda, the A should be the pyramid over the dot."
   Reusable inline unit that swaps the leading "A" of every visible "Aveda"
   for the official Aveda symbol, while "veda" stays real, styled text.
   Markup pattern (repeated wherever "Aveda" appears on the page):
     <span class="aveda-brand"><span class="aveda-brand__a" aria-hidden="true"></span><span class="sr-only">A</span>veda</span>
   The icon is decorative (aria-hidden) and the sr-only "A" restores the
   accessible name, so screen readers still read "Aveda" and copy/paste
   still yields "Aveda". images/aveda-a-symbol.webp is a crop of the
   official transparent Aveda wordmark (images/aveda-logo-white.webp),
   masked (not redrawn) so it recolors via currentColor and works over
   both light body copy and the dark header/footer. Do NOT use this for
   <title>, meta/JSON-LD, canonical URLs, filenames, alt text, or
   aria-labels — those must stay plain "Aveda" text (SEO/a11y). */
.aveda-brand {
  white-space: nowrap;
}
.aveda-brand__a {
  display: inline-block;
  width: 0.76em;
  aspect-ratio: 116 / 110;
  vertical-align: -0.04em;
  background-color: currentColor;
  -webkit-mask-image: url("../../images/aveda-a-symbol.webp");
  mask-image: url("../../images/aveda-a-symbol.webp");
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: contain;
  mask-size: contain;
}

/* Accessible focus ring in brand color, visible on keyboard focus only */
:focus-visible {
  outline: 3px solid #2cb9b0;
  outline-offset: 2px;
  border-radius: 2px;
}

::selection {
  background-color: #ddf5f2;
  color: #176f6b;
}

/* Subtle scroll reveal, no external animation library */
.reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.6s ease-out, transform 0.6s ease-out;
}
.reveal.revealed {
  opacity: 1;
  transform: translateY(0);
}
.reveal.reveal-delay-1.revealed {
  transition-delay: 0.08s;
}
.reveal.reveal-delay-2.revealed {
  transition-delay: 0.16s;
}
.reveal.reveal-delay-3.revealed {
  transition-delay: 0.24s;
}

/* Sticky header: the site's strongest, darkest brand color (aqua-800 — see
   tailwind-config.js), deliberately deeper than the now-light hero field
   below it so the hierarchy reads dark branded header -> light hero ->
   white card. Not the near-black teal of the original build. Only the
   shadow strengthens on scroll, since the fill itself is already a
   deliberate brand color, not a neutral surface that needs a
   scroll-triggered border to separate it from content. */
#main-header {
  background-color: #176f6b;
  transition: box-shadow 0.3s ease;
}
#main-header.is-scrolled {
  box-shadow: 0 4px 16px rgba(12, 62, 60, 0.3);
}

/* Inner-page hero banner: shared botanical Aveda background for the
   services/about/booking/contact intro sections (the homepage split
   hero is unaffected — it has its own system; 404 uses a plain ivory
   background with a watermark numeral instead). center/35% keeps the
   image's dense leaf clusters framing the left/right edges rather than
   sitting under the title, using the source photo's own pale, open
   center band. The wash is a light readability aid only — kept low
   (~15%) so the leaves stay clearly visible instead of flattening into
   a plain ivory block; the source image's own pale center already does
   most of the contrast work for the text. */
.inner-hero {
  background-image: linear-gradient(rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0.15)),
    url("../../images/hero-aveda.webp");
  background-size: cover;
  background-position: center 35%;
  background-repeat: no-repeat;
}
/* On narrow phones the wrapped multi-line heading makes the banner tall
   relative to its width, so a centered cover crop trims BOTH of the
   source image's leaf clusters (parked at its far left/right edges)
   down to nothing. Anchoring left keeps one cluster fully in frame
   instead of losing the botanical cue entirely. */
@media (max-width: 639px) {
  .inner-hero {
    background-position: 0% 30%;
  }
}

/* Soft readability glow behind the inner-hero eyebrow/heading/copy: with
   the wash this low the source photo's leaves are sometimes dense
   enough to sit right under the (lighter-weight) paragraph text,
   especially once a long heading wraps to more lines on narrow phones.
   A blurred radial glow lifts contrast locally without a hard card
   edge or flattening the leaves elsewhere in the banner. w-fit keeps
   the glow's box tight around the actual text instead of the full
   section width, so leaves at the banner's edges stay untouched. */
.hero-text-glow {
  position: relative;
  z-index: 1;
}
.hero-text-glow::before {
  content: "";
  position: absolute;
  /* Stay inside the section's own px-5 (20px) mobile gutter so this
     never creates horizontal scroll on narrow phones. */
  inset: -1rem;
  background: radial-gradient(
    ellipse at 30% 35%,
    rgba(255, 255, 255, 0.8) 0%,
    rgba(255, 255, 255, 0.45) 50%,
    rgba(255, 255, 255, 0) 78%
  );
  filter: blur(6px);
  z-index: -1;
  pointer-events: none;
}
.hero-text-glow.hero-text-glow--center::before {
  background: radial-gradient(
    ellipse at 50% 35%,
    rgba(255, 255, 255, 0.8) 0%,
    rgba(255, 255, 255, 0.45) 50%,
    rgba(255, 255, 255, 0) 78%
  );
}

/* Post-hero brand band: shared deep-teal Aveda banner used as a background
   skin for the first section directly below the hero on index/services/
   about/booking/contact (see next-to-hero-banner.webp). It only supplies
   color/texture — the section's own padding and content keep driving its
   height; this never stretches to reveal the whole image. center works
   everywhere because the source photo is solid teal at its center, with
   leaf accents tucked into the far corners that only enter frame on
   wider/shorter crops (never behind text on narrow/tall mobile crops). */
.post-hero-band {
  background-color: #0c3e3c;
  background-image: url("../../images/next-to-hero-banner.webp");
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

/* Image slots: keep aspect ratio, avoid distortion, easy to swap later */
.media-slot {
  position: relative;
  overflow: hidden;
  background-color: #ddf5f2;
}
.media-slot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Homepage hero: autoplaying local brand film filling the right side of the
   split hero (see index.html + assets/js/hero-video.js). .hero-media is the
   aspect-ratio/overflow shell (sizing comes from Tailwind utility classes in
   index.html); the video fills it via object-cover (Tailwind utilities on
   the <video> itself) and its own `poster` attribute covers the
   before-playback/paused states natively — no extra layers needed. */
.hero-media {
  background-color: #ddf5f2;
}

/* Very subtle brand tint at the seam where the video meets the text panel —
   desktop only (mobile stacks, so there's no seam). Never a full overlay:
   the merchant wants the footage to stay bright and natural. */
.hero-video-edge {
  z-index: 3;
  pointer-events: none;
  background: linear-gradient(to right, rgba(19, 90, 87, 0.28), rgba(19, 90, 87, 0) 16%);
}

/* Homepage hero: circular Aqua salon badge pinned to the lower-left corner
   of the media card (see index.html). It lives as a sibling of
   .hero-media, not a child, so it isn't clipped by the card's own
   overflow-hidden — a negative bottom offset lets it hang half on/half off
   the card, reading as attached to the footage rather than floating
   above it. The ring + shadow give it a defined edge against any frame. */
.hero-brand-badge {
  border: 1px solid #ffffff;
  border-radius: 9999px;
  box-shadow: 0 8px 20px -6px rgba(12, 62, 60, 0.35);
  background-color: #ffffff;
}

/* Homepage service tiles: full-bleed real photography with a bottom scrim
   for text legibility, in place of a faded white image "veil" inside a
   bordered card. Flat editorial treatment — no border, no drop shadow. */
.service-tile-scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    rgba(12, 62, 60, 0) 35%,
    rgba(12, 62, 60, 0.55) 70%,
    rgba(12, 62, 60, 0.88) 100%
  );
}
.service-tile:focus-visible {
  outline-offset: 3px;
}

/* Placeholder tiles used where no real merchant photo exists yet */
.placeholder-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  color: #176f6b;
  background: linear-gradient(135deg, #ddf5f2 0%, #faf7f0 100%);
}

/* Booking page: Vagaro widget loading placeholder. Same soft pale-aqua ->
   Warm Ivory gradient as .placeholder-tile, kept as its own class so the
   placeholder's text colors (set via Tailwind utilities in the markup) don't
   have to fight .placeholder-tile's inherited color. */
.booking-placeholder {
  background: linear-gradient(135deg, #ddf5f2 0%, #faf7f0 100%);
}

/* Three softly pulsing dots — calm, premium, no external animation library.
   prefers-reduced-motion is handled globally above (animation-duration is
   forced to ~0 for everyone with that preference). */
.booking-loading-dots {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}
.booking-loading-dots span {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background-color: #22a29a;
  opacity: 0.35;
  animation: booking-dot-pulse 1.4s ease-in-out infinite;
}
.booking-loading-dots span:nth-child(2) {
  animation-delay: 0.2s;
}
.booking-loading-dots span:nth-child(3) {
  animation-delay: 0.4s;
}
@keyframes booking-dot-pulse {
  0%, 80%, 100% {
    opacity: 0.35;
    transform: scale(1);
  }
  40% {
    opacity: 1;
    transform: scale(1.15);
  }
}

/* Prevent any element from causing horizontal scroll */
img,
video,
iframe {
  max-width: 100%;
}

body {
  overflow-x: hidden;
}

/* Ensure hidden attribute always works, even with conflicting classes */
[hidden] {
  display: none !important;
}
