/* template-stylist/assets/css/style.css — stylist single-page preset.
   Self-hosted fonts (no Google Fonts CDN — that leak-class is banned, see
   README). Brand colors are CSS custom properties; render.js sets their
   values on :root from site.config.js, so this file never hard-codes a
   client's hex values. */

@font-face {
  font-family: 'Cormorant Garamond'; font-style: normal; font-weight: 400 600;
  font-display: swap; src: url('../fonts/cormorant-garamond.woff2') format('woff2');
}
@font-face {
  font-family: 'Cormorant Garamond'; font-style: italic; font-weight: 400;
  font-display: swap; src: url('../fonts/cormorant-garamond-italic.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 300 600;
  font-display: swap; src: url('../fonts/inter.woff2') format('woff2');
}

:root {
  /* Overridden per-instance by render.js from config.brand — these are just
     safe fallbacks so the page never renders unstyled before JS runs. */
  --ink: #1A1410;
  --gold: #C7973F;
  --cream: #F1EADC;
  --backdrop: #0E0B08;
  --display-font: 'Cormorant Garamond', serif;
  --body-font: 'Inter', sans-serif;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  font-family: var(--body-font);
  color: var(--ink);
  background: var(--cream);
  line-height: 1.6;
}

.container { max-width: 1120px; margin: 0 auto; padding: 0 24px; }

a { color: inherit; text-decoration: none; }

/* Visually hidden but reachable by assistive tech — the standard clip-based
   pattern (display:none would hide it from screen readers too). Used for
   the hero photo reel's accessible twin (see render.js's
   data-bind="hero.photos" comment): createLookReel's canvas is
   aria-hidden, so the photos' alt text must exist somewhere real. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* ---------- header ---------- */
.site-header {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; justify-content: space-between;
  padding: 20px 24px;
  background: color-mix(in srgb, var(--cream) 88%, transparent);
  backdrop-filter: blur(8px);
}
.site-header .brand-name {
  font-family: var(--display-font); font-size: 22px; font-weight: 600;
}
.book-btn {
  /* WCAG 2.5.5 target size: this measured 42.4px tall on a Pixel 5 — under the 44px
     floor, and it is the money button. min-height + centring rather than more padding,
     so the visual weight of the button is unchanged on desktop. */
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 10px 22px; border-radius: 2px;
  background: var(--ink); color: var(--cream); font-size: 14px; letter-spacing: .04em;
  transition: opacity .2s ease;
}
.book-btn:hover { opacity: .82; }

/* ---------- hero (v2: gallery-first — her photos, not an abstract scene) ----------
   Mount mechanics (mount/canvas/img fade-in, focus ring, pointer-events) live in
   fx/engine-hero.css — this file only owns the SECTION layout + the text scrim. */
.hero {
  position: relative;
  /* Two declarations, in this order, on purpose: a browser that doesn't know dvh keeps
     the vh line, and one that does overrides it. dvh tracks the DYNAMIC viewport, so the
     hero stops jumping when the mobile address bar collapses on scroll. */
  min-height: 92vh;
  min-height: 92dvh;
  display: flex; align-items: center;
  justify-content: center; text-align: center; overflow: hidden;
  /* never-black poster: a CSS gradient on the mount itself, driven by brand
     colors. Now doing double duty as the loading-gap cover while BOTH hero
     photos decode (a real gap that didn't exist with a procedural shader) —
     the WebGL/img layer fades in on top once createBeforeAfter is ready. */
  background: radial-gradient(120% 90% at 50% 20%,
    color-mix(in srgb, var(--gold) 28%, var(--backdrop)) 0%,
    var(--backdrop) 62%);
}

/* TEXT SCRIM: a real photograph's brightness varies by shot in a way a tuned
   procedural scene never did — cream text on a bright crop of either hero
   photo would wash out without this. A constant radial scrim (not a per-
   photo tone system) keeps the wordmark/tagline/CTA legible regardless of
   which of the two photos is showing or mid-melt. Sits above the mount
   (z-index 0, same layer, later in DOM) and below the text (z-index 1). */
.hero::after {
  content: "";
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: radial-gradient(60% 56% at 50% 46%,
    rgba(0, 0, 0, 0.50) 0%,
    rgba(0, 0, 0, 0.30) 45%,
    rgba(0, 0, 0, 0.06) 72%,
    transparent 85%);
}

.hero-content { position: relative; z-index: 1; max-width: 640px; padding: 0 24px; }
.hero-eyebrow { color: var(--cream); letter-spacing: .18em; text-transform: uppercase; font-size: 13px; font-weight: 600; text-shadow: 0 1px 12px rgba(0,0,0,.5); }
.hero-name { font-family: var(--display-font); font-size: clamp(40px, 7vw, 72px); color: var(--cream); margin: 14px 0 10px; text-shadow: 0 2px 20px rgba(0,0,0,.55); }
.hero-tagline { color: color-mix(in srgb, var(--cream) 92%, transparent); font-size: 18px; margin-bottom: 28px; text-shadow: 0 1px 14px rgba(0,0,0,.5); }

/* ---------- section shell ---------- */
section { padding: 112px 0; } /* v2: more generous whitespace — editorial, not tech-minimal */
.section-header { text-align: center; max-width: 640px; margin: 0 auto 48px; }
.section-eyebrow { color: var(--gold); letter-spacing: .16em; text-transform: uppercase; font-size: 12px; font-weight: 600; }
.section-title { font-family: var(--display-font); font-size: clamp(28px, 4vw, 42px); margin-top: 10px; }

/* Honesty label for every sample-photo section (hero excluded — its own
   "Concept preview by LGR Web Studio" line, in seo.description, covers it). */
.sample-note { font-size: 13px; color: color-mix(in srgb, var(--ink) 55%, transparent); margin-top: 10px; font-style: italic; }

/* ---------- ⭐ transformations (the centerpiece) ----------
   A bounded, aspect-ratio'd frame — not full-bleed like the hero. Canvas/img
   mechanics live in fx/transformations.css; this owns the section layout. */
.transformations-frame {
  position: relative; width: 100%; max-width: 760px; margin: 0 auto;
  aspect-ratio: 4 / 5; border-radius: 8px; overflow: hidden;
  box-shadow: 0 20px 60px -20px color-mix(in srgb, var(--ink) 45%, transparent);
}
@media (min-width: 640px) { .transformations-frame { aspect-ratio: 3 / 2; } }
.transformations-hint {
  display: flex; justify-content: space-between; gap: 12px; max-width: 760px; margin: 14px auto 0;
  font-size: 13px; color: color-mix(in srgb, var(--ink) 60%, transparent); letter-spacing: .02em;
}
.transformations-hint span:nth-child(2) { text-align: center; flex: 1; opacity: .75; }

/* ---------- services ---------- */
.services-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 28px; }
.service-card { padding: 28px; border: 1px solid color-mix(in srgb, var(--ink) 12%, transparent); border-radius: 4px; }
.service-name { font-family: var(--display-font); font-size: 22px; margin-bottom: 6px; }
.service-price { color: var(--gold); font-weight: 600; margin-bottom: 10px; }
.service-desc { font-size: 14px; opacity: .82; }

/* ---------- gallery (v2: big, editorial, texture-forward) ---------- */
.gallery-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 16px; }
.gallery-grid img {
  width: 100%; height: 380px; object-fit: cover; border-radius: 3px; display: block;
  transition: transform .5s cubic-bezier(.22,1,.36,1);
}
.gallery-grid img:hover { transform: scale(1.03); }
@media (max-width: 480px) { .gallery-grid img { height: 320px; } }

/* ---------- about ---------- */
.about-inner { display: grid; grid-template-columns: 1fr 1.3fr; gap: 48px; align-items: center; }
.about-inner img { width: 100%; border-radius: 4px; }
.about-bio { white-space: pre-line; opacity: .9; }
@media (max-width: 760px) { .about-inner { grid-template-columns: 1fr; } }

/* ---------- hours / contact ---------- */
.hours-contact { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 40px; text-align: center; }
.hours-list dt { font-weight: 600; }
.hours-list div { display: flex; justify-content: space-between; max-width: 260px; margin: 0 auto 6px; }

/* ---------- footer ---------- */
.site-footer { padding: 48px 0; background: var(--ink); color: var(--cream); text-align: center; }
.site-footer .brand-name { font-family: var(--display-font); font-size: 20px; }
.social-links { margin: 16px 0; display: flex; gap: 16px; justify-content: center; }
/* WCAG 2.5.5: these were raw 2-letter text links — 16.4 x 25.6px on a Pixel 5, far under
   the 44px floor and genuinely hard to hit. The HIT AREA grows to 44x44; the glyph itself
   is unchanged, so the footer looks identical while becoming tappable. */
.social-links a {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 44px; min-height: 44px;
}
/* Instagram icon (render.js swaps the "IN" text for real SVG art here — see
   SOCIAL_ICONS): a real, recognizable glyph instead of a cryptic 2-letter
   abbreviation. Sized generously within the 44px hit area, not shrunk to
   match the old text's visual footprint. */
.social-links a.social-icon { opacity: .85; transition: opacity .2s ease; }
.social-links a.social-icon:hover { opacity: 1; }
.social-links a.social-icon svg { width: 26px; height: 26px; }
.footer-fine { font-size: 12px; opacity: .6; margin-top: 18px; }


/* ---------- mobile sticky Book bar (mobile-only) ----------
   The header CTA scrolls away, and on a phone the thumb lives at the BOTTOM of the
   screen — so the money action is parked there permanently. Mobile-only by design:
   desktop keeps the header CTA and is untouched.

   env(safe-area-inset-bottom) is the load-bearing detail: on a notched iPhone the home
   indicator sits over the bottom ~34px, so a naive `bottom: 0` bar puts the tap target
   underneath the system gesture area, where it either can't be tapped or fires a swipe.
   The max() keeps a real 10px of breathing room on phones that report an inset of 0. */
.mobile-book-bar { display: none; }

@media (max-width: 760px) {
  .mobile-book-bar {
    display: block;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
    padding: 10px 16px max(10px, env(safe-area-inset-bottom));
    background: color-mix(in srgb, var(--cream) 92%, transparent);
    backdrop-filter: blur(8px);
    border-top: 1px solid color-mix(in srgb, var(--ink) 12%, transparent);
    transition: transform .25s ease;
  }
  /* Near the very bottom of the page the footer's own CTA is on screen — the bar would
     be duplicate chrome covering it, so it slides away instead of overlapping. */
  .mobile-book-bar[data-at-end="true"] { transform: translateY(110%); }

  .mobile-book-bar .book-btn {
    display: flex; width: 100%; min-height: 48px;   /* full-width thumb target */
    font-size: 15px;
  }
  /* Stop the fixed bar from covering the last of the footer's content. */
  .site-footer { padding-bottom: calc(72px + env(safe-area-inset-bottom)); }
}
