// Desert — full-bleed prototype with Tweaks.
// Hero, animated booking flow, about, portfolio, services, testimonials, FAQ, CTA.

const { useState: uS, useEffect: uE, useRef: uR } = React;

// Tweakable defaults — host rewrites between EDITMODE markers.
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "palette": "warm",
  "displayFont": "Fraunces",
  "headingScale": 1,
  "heroVariant": "split",
  "portfolioLayout": "masonry",
  "density": "regular"
}/*EDITMODE-END*/;

const PALETTES = {
  warm:   { cream: '#f4e8dc', sand: '#e8d5c4', terra: '#c97b5e', rust: '#a0522d', ink: '#3a2820', sun: '#e8b8a0' },
  bone:   { cream: '#ede6dc', sand: '#dcd2c2', terra: '#a08672', rust: '#75604c', ink: '#2a221c', sun: '#d4c4ad' },
  ember:  { cream: '#f6ece1', sand: '#ecdac8', terra: '#b85a3c', rust: '#7d2e1a', ink: '#2c1510', sun: '#f0a878' },
  dusk:   { cream: '#ebe5e0', sand: '#d8cec7', terra: '#8e6f6c', rust: '#5d4441', ink: '#241c1c', sun: '#c8a8a4' },
};

const FONT_OPTIONS = ['Fraunces', 'Bodoni Moda', 'Instrument Serif'];

// Image set (Unsplash hair photos)
const U = (id) => id;
const IMG = {
  portrait: 'harlee-portrait.jpg',
  work: [
    'images/work-1.jpg', 'images/work-2.jpg', 'images/work-3.jpg', 'images/work-9.jpg',
    'images/work-4.jpg', 'images/work-5.jpg', 'images/work-6.jpg', 'images/work-7.jpg',
    'images/work-8.jpg',
  ],
};

const HER_SERVICES = {
  'Lived-In Color': [
    ['Lived-In Balayage', '$275+'],
    ['Hand-Painted Highlights', '$250+'],
    ['Soft Blonding', '$275+'],
    ['Color Refresh / Glaze', '$95+'],
    ['Root Smudge & Toner', '$110+'],
    ['Color Correction', '$300+'],
  ],
  'Cuts': [
    ['Pixie Cut', '$85+'],
    ['Long Layered Cut', '$85+'],
    ['Bob / Lob', '$80+'],
    ['Bang Trim', '$25+'],
    ['Blowout', '$55+'],
  ],
  'Specialty': [
    ['Bridal Styling', '$200+'],
    ['Brazilian Blowout', '$250+'],
    ['Olaplex Treatment', '$50+'],
    ['Extensions Consult', 'Varies'],
  ],
};

const TESTIMONIALS = [
  { body: 'I highly recommend this salon! Harlee was so amazing, friendly and caring. She listened to what I wanted and made my 1st experience so great. Thank you for your service and I will be back soon.', name: 'Galilea V.', service: 'First-time client · Yelp', source: 'yelp' },
  { body: 'Harlee is a blonde color queen!!!!! She spent 5 hours working SO hard to give me a complete hair transformation and I am OBSESSED!!! Couldn’t be happier with the results. Everyone at No Name was SO nice and the place is such a vibe.', name: 'Ryann M.', service: 'Blonde transformation · Yelp', source: 'yelp' },
  { body: 'Finally found someone who understands curly hair. Harlee’s approach is so thoughtful — she explained every step and gave me a cut that actually works with my texture.', name: 'Jessica T.', service: 'Curly Cut & Color' },
];

const FAQ = [
  ['What should I expect during my first visit?', 'A thorough consultation — your hair history, lifestyle, and vision. I’ll assess your hair’s condition and create a customized plan. Please arrive with hair in its natural state if possible.'],
  ['How far in advance should I book?', '2–3 weeks ahead for regular appointments and 2–3 months for bridal. Last-minute openings happen — follow on Instagram for those.'],
  ['What are your hours?', 'Wednesday & Friday: 9am – 5pm. Bridal and special events available off-hours by request.'],
  ['Where is your studio located?', '75 N 100 E, St. George, UT 84770 — downtown, with street parking.'],
  ['Do you offer extension consults?', 'Yes — complimentary, to determine the best method, length, and color match.'],
  ['What’s your cancellation policy?', '48 hours notice please. Cancellations within 24 hours may incur a fee.'],
];

// ── Scroll reveal ──
function useReveal(opts = {}) {
  const ref = uR(null);
  const [shown, setShown] = uS(false);
  uE(() => {
    const el = ref.current;
    if (!el) return;
    if (typeof IntersectionObserver === 'undefined') { setShown(true); return; }
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => {
        if (e.isIntersecting) { setShown(true); io.unobserve(el); }
      });
    }, { threshold: opts.threshold ?? 0.12, rootMargin: opts.rootMargin ?? '0px 0px -8% 0px' });
    io.observe(el);
    return () => io.disconnect();
  }, []);
  return [ref, shown];
}

function Reveal({ children, delay = 0, y = 32, duration = 800, as = 'div', style, ...rest }) {
  const [ref, shown] = useReveal();
  const Tag = as;
  return (
    <Tag ref={ref} style={{
      opacity: shown ? 1 : 0,
      transform: shown ? 'translate3d(0,0,0)' : `translate3d(0, ${y}px, 0)`,
      transition: `opacity ${duration}ms cubic-bezier(.2,.7,.3,1) ${delay}ms, transform ${duration}ms cubic-bezier(.2,.7,.3,1) ${delay}ms`,
      willChange: 'opacity, transform',
      ...style,
    }} {...rest}>{children}</Tag>
  );
}

function App() {
  const [tw, setTw] = useTweaks(TWEAK_DEFAULTS);
  const C = PALETTES[tw.palette] || PALETTES.warm;
  const FF = {
    display: `'${tw.displayFont}', serif`,
    body: `'Inter', sans-serif`,
    mono: `'DM Mono', monospace`,
    script: `'Caveat', cursive`,
  };
  const HS = tw.headingScale; // 0.85..1.2
  const dens = tw.density; // compact / regular / spacious
  const padY = dens === 'compact' ? 80 : dens === 'spacious' ? 160 : 120;

  const rootRef = uR(null);
  const [scroll, setScroll] = uS(0);
  uE(() => {
    const onScroll = () => setScroll(window.scrollY);
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);

  // ── Custom cursor — desktop only, imperative for zero re-renders
  const dotRef = uR(null);
  const ringRef = uR(null);
  uE(() => {
    if (typeof window === 'undefined') return;
    const fine = window.matchMedia('(hover: hover) and (pointer: fine)').matches;
    if (!fine) return;
    document.documentElement.classList.add('hs-cursor-on');

    let rx = window.innerWidth / 2, ry = window.innerHeight / 2;
    let tx = rx, ty = ry;
    let raf = 0;

    const move = (e) => {
      tx = e.clientX; ty = e.clientY;
      if (dotRef.current) {
        dotRef.current.style.transform = `translate3d(${tx}px, ${ty}px, 0) translate(-50%, -50%)`;
        dotRef.current.style.opacity = '1';
      }
      if (!raf) raf = requestAnimationFrame(tick);
    };
    const tick = () => {
      rx += (tx - rx) * 0.18; ry += (ty - ry) * 0.18;
      if (ringRef.current) ringRef.current.style.transform = `translate3d(${rx}px, ${ry}px, 0) translate(-50%, -50%)`;
      if (Math.abs(tx - rx) > 0.3 || Math.abs(ty - ry) > 0.3) raf = requestAnimationFrame(tick);
      else raf = 0;
    };
    const leave = () => {
      if (dotRef.current) dotRef.current.style.opacity = '0';
      if (ringRef.current) ringRef.current.style.opacity = '0';
    };
    const enter = () => {
      if (dotRef.current) dotRef.current.style.opacity = '1';
      if (ringRef.current) ringRef.current.style.opacity = '0.4';
    };
    const over = (e) => {
      const t = e.target.closest && e.target.closest('a, button, [role="button"], summary, [data-c]');
      if (ringRef.current) {
        ringRef.current.style.width = t ? '52px' : '34px';
        ringRef.current.style.height = t ? '52px' : '34px';
        ringRef.current.style.opacity = t ? '0.7' : '0.4';
      }
    };

    window.addEventListener('mousemove', move, { passive: true });
    window.addEventListener('mouseover', over, { passive: true });
    window.addEventListener('mouseleave', leave);
    document.addEventListener('mouseenter', enter);
    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener('mousemove', move);
      window.removeEventListener('mouseover', over);
      window.removeEventListener('mouseleave', leave);
      document.removeEventListener('mouseenter', enter);
      document.documentElement.classList.remove('hs-cursor-on');
    };
  }, []);

  return (
    <div ref={rootRef} style={{ background: C.cream, color: C.ink, fontFamily: FF.body, position: 'relative', overflowX: 'clip' }}>
      {/* Custom cursor — desktop only via media query class on <html> */}
      <div ref={ringRef} aria-hidden="true" style={{
        position: 'fixed', left: 0, top: 0, width: 34, height: 34,
        border: `1.5px solid ${C.terra}`, borderRadius: '50%',
        pointerEvents: 'none', zIndex: 9998, opacity: 0,
        transition: 'width .25s cubic-bezier(.2,.7,.3,1), height .25s cubic-bezier(.2,.7,.3,1), opacity .2s, border-color .25s',
        willChange: 'transform',
      }} />
      <div ref={dotRef} aria-hidden="true" style={{
        position: 'fixed', left: 0, top: 0, width: 6, height: 6,
        background: C.terra, borderRadius: '50%',
        pointerEvents: 'none', zIndex: 9999, opacity: 0,
        transition: 'opacity .15s, background .25s',
        willChange: 'transform',
      }} />

      <Nav C={C} FF={FF} />
      <Hero C={C} FF={FF} HS={HS} variant={tw.heroVariant} scroll={scroll} />
      <Marquee C={C} FF={FF} />
      <Booking C={C} FF={FF} HS={HS} padY={padY} />
      <About C={C} FF={FF} HS={HS} padY={padY} />
      <Portfolio C={C} FF={FF} HS={HS} padY={padY} layout={tw.portfolioLayout} />
      <Press C={C} FF={FF} HS={HS} padY={padY} />
      <Wallet C={C} FF={FF} HS={HS} padY={padY} />
      <Services C={C} FF={FF} HS={HS} padY={padY} />
      <Testimonials C={C} FF={FF} HS={HS} padY={padY} />
      <FAQSection C={C} FF={FF} HS={HS} padY={padY} />
      <CTA C={C} FF={FF} HS={HS} />
      <Footer C={C} FF={FF} />

      <TweaksPanel>
        <TweakSection label="Palette" />
        <TweakRadio label="Tone" value={tw.palette} options={['warm', 'bone', 'ember', 'dusk']} onChange={v => setTw('palette', v)} />
        <TweakSection label="Typography" />
        <TweakSelect label="Display font" value={tw.displayFont} options={FONT_OPTIONS} onChange={v => setTw('displayFont', v)} />
        <TweakSlider label="Heading scale" value={tw.headingScale} min={0.8} max={1.3} step={0.05} onChange={v => setTw('headingScale', v)} />
        <TweakSection label="Layout" />
        <TweakRadio label="Hero" value={tw.heroVariant} options={['split', 'centered', 'fullbleed']} onChange={v => setTw('heroVariant', v)} />
        <TweakRadio label="Portfolio" value={tw.portfolioLayout} options={['masonry', 'grid', 'film']} onChange={v => setTw('portfolioLayout', v)} />
        <TweakRadio label="Density" value={tw.density} options={['compact', 'regular', 'spacious']} onChange={v => setTw('density', v)} />
      </TweaksPanel>
    </div>
  );
}

// ── NAV ──
function Nav({ C, FF }) {
  return (
    <header className="m-nav" style={{
      position: 'sticky', top: 0, zIndex: 50, padding: '20px 56px',
      display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      background: `${C.cream}cc`, backdropFilter: 'blur(12px)',
      borderBottom: `1px solid ${C.terra}22`,
    }}>
      <div style={{ display: 'flex', flexDirection: 'column', lineHeight: 1 }}>
        <span className="m-logo" style={{ fontFamily: FF.display, fontWeight: 500, fontSize: 22, fontStyle: 'italic', letterSpacing: '-0.01em' }}>
          Harlee Showalter<span style={{ color: C.terra }}>.</span>
        </span>
        <span style={{ fontFamily: FF.mono, fontSize: 9, letterSpacing: '0.24em', textTransform: 'uppercase', color: C.rust, marginTop: 4 }}>
          at Desert Lounge Salon
        </span>
      </div>
      <nav className="m-nav-links" style={{ display: 'flex', gap: 36, fontSize: 13, letterSpacing: '0.04em' }}>
        {[
          ['Studio',   '#studio'],
          ['Work',     '#work'],
          ['Press',    '#press'],
          ['Services', '#services'],
          ['Reviews',  '#reviews'],
          ['Visit',    '#wallet'],
        ].map(([label, href]) => (
          <a key={label} href={href} data-c="" style={{ color: C.ink, textDecoration: 'none', cursor: 'pointer' }}>{label}</a>
        ))}
      </nav>
      <a className="m-nav-cta" href="#book" data-c="book" style={{
        background: C.ink, color: C.cream, border: 'none',
        padding: '10px 20px', borderRadius: 999, fontSize: 13, letterSpacing: '0.04em',
        lineHeight: 1, fontWeight: 500, whiteSpace: 'nowrap',
        cursor: 'pointer', textDecoration: 'none',
        display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 6,
      }}>Book my chair →</a>
    </header>
  );
}

// ── HERO ──
function Hero({ C, FF, HS, variant, scroll }) {
  if (variant === 'centered') return <HeroCentered C={C} FF={FF} HS={HS} scroll={scroll} />;
  if (variant === 'fullbleed') return <HeroFullbleed C={C} FF={FF} HS={HS} scroll={scroll} />;
  return <HeroSplit C={C} FF={FF} HS={HS} scroll={scroll} />;
}

function HeroSplit({ C, FF, HS, scroll }) {
  return (
    <section className="m-section m-hero" style={{ position: 'relative', padding: '40px 56px 80px', minHeight: '90vh' }}>
      <div style={{
        position: 'absolute', inset: 0, pointerEvents: 'none',
        background: `radial-gradient(circle at 70% 0%, ${C.sun}88 0%, transparent 50%), radial-gradient(circle at 20% 90%, ${C.terra}22 0%, transparent 60%)`,
      }} />
      <div className="m-hero-eyebrow" style={{
        fontFamily: FF.mono, fontSize: 11, letterSpacing: '0.24em', textTransform: 'uppercase',
        color: C.rust, marginBottom: 24, position: 'relative',
        display: 'flex', alignItems: 'center', gap: 14, flexWrap: 'wrap',
      }}>
        <span style={{ color: C.terra, fontSize: 13 }}>✺</span>
        <span>Harlee Showalter at Desert Lounge Salon</span>
        <span className="m-hero-eyebrow-sep" style={{ opacity: 0.5 }}>·</span>
        <span className="m-hero-eyebrow-loc">St. George, Utah</span>
      </div>
      <h1 className="m-h1" style={{
        fontFamily: FF.display, fontWeight: 300, fontStyle: 'italic',
        fontSize: 200 * HS, lineHeight: 0.92, margin: 0, letterSpacing: '-0.04em', position: 'relative',
      }}>
        Hair, like<br/>
        <span style={{ position: 'relative', display: 'inline-block' }}>
          <span style={{ fontWeight: 600, fontStyle: 'normal', color: C.terra }}>sunlight,</span>
          <svg viewBox="0 0 600 24" style={{ position: 'absolute', left: 0, bottom: -10 * HS, width: '100%', height: 24 }}>
            <path d="M 0 12 Q 150 0 300 12 T 600 12" stroke={C.terra} strokeWidth="2" fill="none" />
          </svg>
        </span>
        <br/><span style={{ fontWeight: 300 }}>moves through</span><br/>
        <span style={{ fontWeight: 600, fontStyle: 'normal' }}>seasons.</span>
      </h1>
      <div className="m-grid-stack" style={{ display: 'grid', gridTemplateColumns: '1fr 480px', gap: 64, alignItems: 'end', marginTop: 64, position: 'relative' }}>
        <div>
          <p className="m-display-lg" style={{ fontFamily: FF.display, fontSize: 22, fontStyle: 'italic', lineHeight: 1.45, margin: 0, maxWidth: 520 }}>
            Desert Lounge. Slow color, unhurried cuts, and the kind of finish you don’t need to think about for the next three months.
          </p>
          <div className="m-stack" style={{ display: 'flex', gap: 16, marginTop: 36 }}>
            <a className="m-btn" href="#book" data-c="reserve" style={{
              background: C.terra, color: C.cream, border: 'none', borderRadius: 999,
              padding: '18px 32px', fontSize: 14, letterSpacing: '0.04em', cursor: 'pointer', textDecoration: 'none', display: 'inline-block',
            }}>Reserve a visit</a>
            <a className="m-btn" href="#work" data-c="see" style={{
              background: 'transparent', color: C.ink, border: `1px solid ${C.ink}`, borderRadius: 999,
              padding: '18px 32px', fontSize: 14, letterSpacing: '0.04em', cursor: 'pointer', textDecoration: 'none', display: 'inline-block',
            }}>See recent work →</a>
          </div>
        </div>
        <div className="m-hero-portrait" data-c="open" style={{
          position: 'relative', aspectRatio: '4/5',
          borderRadius: '50% 50% 50% 50% / 30% 30% 30% 30%', overflow: 'hidden',
          background: C.sun, boxShadow: `0 30px 80px -20px ${C.terra}55`,
        }}>
          <img src={IMG.portrait} alt="" style={{
            width: '100%', height: '100%', objectFit: 'cover',
            transform: `translateY(${scroll * -0.08}px) scale(1.15)`, filter: 'sepia(0.15) saturate(1.05)',
          }} />
          <div style={{ position: 'absolute', inset: 0, background: `linear-gradient(180deg, transparent 50%, ${C.terra}33 100%)` }} />
          <div style={{ position: 'absolute', bottom: 24, left: 24, fontFamily: FF.script, fontSize: 32, color: C.cream, textShadow: '0 2px 12px rgba(0,0,0,.3)' }}>— h.s.</div>
        </div>
      </div>
    </section>
  );
}

function HeroCentered({ C, FF, HS, scroll }) {
  return (
    <section style={{ position: 'relative', padding: '80px 56px 120px', minHeight: '90vh', textAlign: 'center' }}>
      <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none',
        background: `radial-gradient(circle at 50% 30%, ${C.sun}88 0%, transparent 60%)` }} />
      <div style={{ fontFamily: FF.mono, fontSize: 11, letterSpacing: '0.24em', textTransform: 'uppercase', color: C.rust, marginBottom: 32, position: 'relative' }}>
        ✺ &nbsp; Desert Lounge Salon &nbsp; · &nbsp; St. George, Utah &nbsp; ✺
      </div>
      <h1 style={{ fontFamily: FF.display, fontWeight: 300, fontStyle: 'italic', fontSize: 200 * HS, lineHeight: 0.92, margin: 0, letterSpacing: '-0.04em', position: 'relative' }}>
        Hair, like <span style={{ fontWeight: 600, fontStyle: 'normal', color: C.terra }}>sunlight,</span><br/>
        <span style={{ fontWeight: 300 }}>moves through</span> <span style={{ fontWeight: 600, fontStyle: 'normal' }}>seasons.</span>
      </h1>
      <div data-c="open" style={{
        position: 'relative', aspectRatio: '5/4', maxWidth: 720, margin: '56px auto 0',
        borderRadius: '50% 50% 50% 50% / 60% 60% 40% 40%', overflow: 'hidden', background: C.sun,
        boxShadow: `0 30px 80px -20px ${C.terra}66`,
      }}>
        <img src={IMG.portrait} alt="" style={{
          width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'center 30%',
          transform: `translateY(${scroll * -0.05}px) scale(1.1)`, filter: 'sepia(0.15)',
        }} />
      </div>
      <div style={{ marginTop: 48, display: 'flex', gap: 16, justifyContent: 'center', position: 'relative' }}>
        <a href="#book" data-c="reserve" style={{ background: C.terra, color: C.cream, borderRadius: 999, padding: '18px 32px', fontSize: 14, letterSpacing: '0.04em', cursor: 'pointer', textDecoration: 'none' }}>Reserve a visit</a>
        <a href="#work" data-c="" style={{ background: 'transparent', color: C.ink, border: `1px solid ${C.ink}`, borderRadius: 999, padding: '18px 32px', fontSize: 14, letterSpacing: '0.04em', cursor: 'pointer', textDecoration: 'none' }}>See recent work →</a>
      </div>
    </section>
  );
}

function HeroFullbleed({ C, FF, HS, scroll }) {
  return (
    <section style={{ position: 'relative', height: '100vh', overflow: 'hidden' }}>
      <img src={IMG.portrait} alt="" style={{
        position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'center 25%',
        transform: `translateY(${scroll * 0.3}px) scale(1.1)`, filter: 'sepia(0.15) brightness(0.9)',
      }} />
      <div style={{ position: 'absolute', inset: 0, background: `linear-gradient(180deg, ${C.cream}66 0%, transparent 30%, ${C.ink}aa 100%)` }} />
      <div style={{ position: 'relative', height: '100%', padding: '40px 56px 80px', display: 'flex', flexDirection: 'column', justifyContent: 'flex-end' }}>
        <div style={{ fontFamily: FF.mono, fontSize: 11, letterSpacing: '0.24em', textTransform: 'uppercase', color: C.cream, marginBottom: 24 }}>
          ✺ &nbsp; Desert Lounge Salon &nbsp; · &nbsp; St. George, Utah
        </div>
        <h1 style={{ fontFamily: FF.display, fontWeight: 300, fontStyle: 'italic', fontSize: 200 * HS, lineHeight: 0.92, margin: 0, letterSpacing: '-0.04em', color: C.cream }}>
          Hair, like <span style={{ fontWeight: 600, fontStyle: 'normal', color: C.sun }}>sunlight.</span>
        </h1>
        <div style={{ display: 'flex', gap: 16, marginTop: 32 }}>
          <a href="#book" data-c="reserve" style={{ background: C.terra, color: C.cream, borderRadius: 999, padding: '18px 32px', fontSize: 14, letterSpacing: '0.04em', cursor: 'pointer', textDecoration: 'none' }}>Reserve a visit</a>
        </div>
      </div>
    </section>
  );
}

// ── MARQUEE ──
function Marquee({ C, FF }) {
  return (
    <section style={{ padding: '32px 0', background: C.sand, overflow: 'hidden', position: 'relative' }}>
      <div style={{ display: 'flex', gap: 16, animation: 'slideL 60s linear infinite', width: 'max-content' }}>
        {[...IMG.work, ...IMG.work].map((src, i) => (
          <div key={i} className="m-marquee-img" style={{ width: 200, height: 260, flexShrink: 0, overflow: 'hidden', borderRadius: 4 }}>
            <img src={src} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover', filter: 'sepia(0.1)' }} />
          </div>
        ))}
      </div>
      <style>{`@keyframes slideL { to { transform: translateX(-50%); } }`}</style>
    </section>
  );
}

// ── BOOKING SECTION ──
function Booking({ C, FF, HS, padY }) {
  return (
    <section id="book" className="m-section m-section-y" style={{ padding: `${padY}px 56px`, background: C.cream, position: 'relative' }}>
      <Reveal style={{ textAlign: 'center', marginBottom: 64 }}>
        <div className="m-eyebrow" style={{ fontFamily: FF.mono, fontSize: 11, letterSpacing: '0.24em', textTransform: 'uppercase', color: C.rust, marginBottom: 16 }}>
          ✦ Book your visit ✦
        </div>
        <h2 className="m-h2" style={{ fontFamily: FF.display, fontWeight: 300, fontStyle: 'italic', fontSize: 96 * HS, margin: 0, letterSpacing: '-0.03em', lineHeight: 0.95 }}>
          A few questions,<br/><span style={{ fontWeight: 600, fontStyle: 'normal', color: C.terra }}>then we begin.</span>
        </h2>
      </Reveal>
      <Reveal delay={150}><BookingFlow palette={C} fonts={FF} /></Reveal>
    </section>
  );
}

// ── ABOUT ──
function Palm({ C }) {
  // Classic palm silhouette — tall slim trunk + drooping coconut-palm fronds.
  return (
    <svg width="120" height="170" viewBox="0 0 120 170" style={{ display: 'block', flexShrink: 0 }}>
      {/* Tall trunk — narrow, with gentle taper; spans most of the height */}
      <path
        d="M 56 54 C 53 90 51 132 52 168 L 64 168 C 65 132 63 90 60 54 Z"
        fill={C.terra} opacity="0.94"
      />

      {/* Bark rings */}
      <g stroke={C.rust} strokeWidth="0.6" opacity="0.55" fill="none" strokeLinecap="round">
        <path d="M 53 74  Q 58 72  64 74" />
        <path d="M 52 90  Q 58 88  64 90" />
        <path d="M 52 106 Q 58 104 65 106" />
        <path d="M 51 122 Q 58 120 65 122" />
        <path d="M 51 138 Q 58 136 66 138" />
        <path d="M 51 154 Q 58 152 66 154" />
      </g>

      {/* Crown coconut cluster (drawn behind fronds) */}
      <g>
        <circle cx="56" cy="58" r="2.4" fill={C.rust} opacity="0.9" />
        <circle cx="61" cy="58" r="2.4" fill={C.rust} opacity="0.9" />
        <circle cx="58" cy="61" r="2.4" fill={C.rust} opacity="0.9" />
      </g>

      {/* Fronds — 6 lance-shaped curves emanating from the crown (~58, 56),
          arching up and drooping at the tips */}
      <g fill={C.terra} opacity="0.92">
        {/* Far-left, drooping outward and down */}
        <path d="M 58 56 Q 30 50 4 64 Q 32 56 60 60 Z" />
        {/* Upper-left arching up */}
        <path d="M 58 56 Q 36 32 14 18 Q 38 36 60 60 Z" />
        {/* Upper-center-left, near-vertical */}
        <path d="M 58 56 Q 52 26 46 4 Q 56 26 60 58 Z" />
        {/* Upper-center-right, near-vertical */}
        <path d="M 58 56 Q 64 26 72 4 Q 60 26 58 58 Z" />
        {/* Upper-right arching up */}
        <path d="M 58 56 Q 80 32 106 18 Q 80 36 58 60 Z" />
        {/* Far-right, drooping outward and down */}
        <path d="M 58 56 Q 86 50 116 64 Q 84 56 60 60 Z" />
      </g>

      {/* Faint midribs to read as feathered fronds */}
      <g stroke={C.rust} strokeWidth="0.55" opacity="0.45" fill="none" strokeLinecap="round">
        <path d="M 58 56 Q 30 50 4 64" />
        <path d="M 58 56 Q 36 32 14 18" />
        <path d="M 58 56 Q 52 26 46 4" />
        <path d="M 58 56 Q 64 26 72 4" />
        <path d="M 58 56 Q 80 32 106 18" />
        <path d="M 58 56 Q 86 50 116 64" />
      </g>

      {/* Ground line */}
      <line x1="6" y1="166" x2="114" y2="166" stroke={C.rust} strokeWidth="0.8" opacity="0.4" strokeDasharray="2 3" />
    </svg>
  );
}

function Saguaro({ C }) {
  // Tasteful saguaro silhouette built from clean rounded rectangles.
  return (
    <svg width="120" height="170" viewBox="0 0 120 170" style={{ display: 'block', flexShrink: 0 }}>
      <defs>
        <clipPath id="saguaro-clip">
          {/* Trunk */}
          <rect x="48" y="20" width="24" height="150" rx="12" />
          {/* Right arm: vertical riser + horizontal connector */}
          <rect x="86" y="50" width="18" height="70" rx="9" />
          <rect x="64" y="62" width="40" height="14" rx="7" />
          {/* Left arm */}
          <rect x="16" y="76" width="16" height="50" rx="8" />
          <rect x="22" y="84" width="34" height="12" rx="6" />
        </clipPath>
      </defs>

      {/* Filled body (union of all shapes) */}
      <g fill={C.terra} opacity="0.92">
        <rect x="48" y="20" width="24" height="150" rx="12" />
        <rect x="86" y="50" width="18" height="70" rx="9" />
        <rect x="64" y="62" width="40" height="14" rx="7" />
        <rect x="16" y="76" width="16" height="50" rx="8" />
        <rect x="22" y="84" width="34" height="12" rx="6" />
      </g>

      {/* Vertical ribbing — clipped to body */}
      <g clipPath="url(#saguaro-clip)" stroke={C.rust} strokeWidth="0.7" opacity="0.45" fill="none">
        <line x1="54" y1="20" x2="54" y2="170" />
        <line x1="60" y1="20" x2="60" y2="170" />
        <line x1="66" y1="20" x2="66" y2="170" />
        <line x1="92" y1="50" x2="92" y2="120" />
        <line x1="98" y1="50" x2="98" y2="120" />
        <line x1="22" y1="76" x2="22" y2="126" />
        <line x1="28" y1="76" x2="28" y2="126" />
      </g>

      {/* Subtle outline for crispness */}
      <g fill="none" stroke={C.rust} strokeWidth="1" opacity="0.35">
        <rect x="48" y="20" width="24" height="150" rx="12" />
        <rect x="86" y="50" width="18" height="70" rx="9" />
        <rect x="16" y="76" width="16" height="50" rx="8" />
      </g>

      {/* Bloom on the tallest tip */}
      <g>
        <circle cx="95" cy="50" r="4" fill={C.sun} />
        <circle cx="95" cy="50" r="1.6" fill={C.cream} />
      </g>

      {/* Ground line */}
      <line x1="6" y1="166" x2="114" y2="166" stroke={C.rust} strokeWidth="0.8" opacity="0.4" strokeDasharray="2 3" />
    </svg>
  );
}

function About({ C, FF, HS, padY }) {
  return (
    <section id="studio" className="m-section m-section-y" style={{ padding: `${padY}px 56px`, position: 'relative' }}>
      <div className="m-grid-stack" style={{ display: 'grid', gridTemplateColumns: '1fr 1.4fr', gap: 80, alignItems: 'start' }}>
        <Reveal>
          <div className="m-eyebrow" style={{ fontFamily: FF.mono, fontSize: 11, letterSpacing: '0.24em', textTransform: 'uppercase', color: C.rust, marginBottom: 24 }}>About</div>
          <h2 className="m-h2" style={{ fontFamily: FF.display, fontWeight: 300, fontStyle: 'italic', fontSize: 80 * HS, lineHeight: 0.95, margin: 0, letterSpacing: '-0.03em' }}>
            Color that<br/>makes sense<br/>
            <span style={{ fontWeight: 600, fontStyle: 'normal', color: C.terra }}>six weeks later.</span>
          </h2>
          <p style={{ fontFamily: FF.body, fontSize: 13, lineHeight: 1.7, marginTop: 32, color: C.ink + 'aa', maxWidth: 320 }}>
            Not just day one.
          </p>
          {/* Palm + saguaro + St. George label */}
          <div style={{ marginTop: 56, display: 'flex', alignItems: 'flex-end', gap: 18 }}>
            <Palm C={C} />
            <Saguaro C={C} />
            <div style={{ paddingBottom: 8 }}>
              <div style={{ fontFamily: FF.mono, fontSize: 9, letterSpacing: '0.24em', textTransform: 'uppercase', color: C.rust }}>St. George, UT</div>
              <div style={{ fontFamily: FF.script, fontSize: 30, color: C.terra, marginTop: 4, lineHeight: 1 }}>desert grown</div>
            </div>
          </div>
        </Reveal>
        <Reveal delay={120} style={{ paddingTop: 16 }}>
          <p className="m-display-md" style={{ fontFamily: FF.display, fontSize: 21, lineHeight: 1.5, margin: 0 }}>
            Many of my clients come to me after a color experience that didn't quite go their way — uneven highlights, harsh lines from at-home color, or a finish that looked beautiful in the salon but fell flat in natural light.
          </p>
          <p className="m-display-md" style={{ fontFamily: FF.display, fontSize: 21, lineHeight: 1.5, marginTop: 20, fontStyle: 'italic', color: C.terra }}>
            I fix those — but more importantly, I make sure they don't happen again.
          </p>
          <p className="m-display-sm" style={{ fontFamily: FF.display, fontSize: 19, lineHeight: 1.55, marginTop: 28 }}>
            I trained at Aveda, built two salons, and founded <span style={{ fontStyle: 'italic' }}>No Name Salon</span> in downtown LA — voted Best Salon in DTLA in 2022 and 2023. I love the community here in St. George, and I brought everything I learned with me.
          </p>

          {/* Pull quote */}
          <figure className="m-quote" style={{
            margin: '48px 0 0', padding: '36px 40px',
            background: C.sand,
            borderRadius: '4px 32px 4px 32px',
            position: 'relative',
            borderLeft: `2px solid ${C.terra}`,
          }}>
            <div style={{
              position: 'absolute', top: -8, left: 24,
              fontFamily: FF.display, fontSize: 96, lineHeight: 1, color: C.terra,
            }}>“</div>
            <blockquote style={{
              fontFamily: FF.display, fontSize: 28, fontStyle: 'italic', fontWeight: 300,
              lineHeight: 1.3, margin: 0, letterSpacing: '-0.01em',
              color: C.ink,
            }}>
              I want you to leave looking like yourself on your <span style={{ fontWeight: 600, fontStyle: 'normal', color: C.terra }}>best day</span> — not like someone else entirely.
            </blockquote>
            <figcaption style={{
              marginTop: 20, fontFamily: FF.script, fontSize: 26, color: C.rust,
            }}>— Harlee</figcaption>
          </figure>

          <div style={{ marginTop: 48, display: 'flex', gap: 56, flexWrap: 'wrap' }}>
            {[['Aveda', 'trained'], ['No Name', 'founded LA']].map(([n, l], i) => (
              <div key={i}>
                <div style={{ fontFamily: FF.display, fontStyle: 'italic', fontSize: 44, lineHeight: 1, color: C.terra, fontWeight: 400 }}>{n}</div>
                <div style={{ fontFamily: FF.mono, fontSize: 10, letterSpacing: '0.2em', textTransform: 'uppercase', marginTop: 8 }}>{l}</div>
              </div>
            ))}
          </div>

          {/* Awards — Best of Downtown */}
          <div className="m-awards" style={{
            marginTop: 56, padding: '36px 36px 32px',
            background: C.cream,
            borderRadius: '4px 32px 4px 32px',
            border: `1px solid ${C.terra}33`,
            position: 'relative',
          }}>
            <div style={{ fontFamily: FF.mono, fontSize: 10, letterSpacing: '0.24em', textTransform: 'uppercase', color: C.rust, marginBottom: 24 }}>
              ✺ Awards
            </div>
            <div className="m-awards-row" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 28 }}>
              {[
                { src: 'images/best-of-downtown-2022.webp', fallback: 'images/best-of-downtown-2022.png', year: '2022' },
                { src: 'images/best-of-downtown-2023.webp', fallback: 'images/best-of-downtown-2023.png', year: '2023' },
              ].map((a) => (
                <div key={a.year} style={{ display: 'flex', alignItems: 'center', gap: 16 }}>
                  <picture style={{ flexShrink: 0 }}>
                    <source srcSet={a.src} type="image/webp" />
                    <img src={a.fallback} alt={`Best of Downtown ${a.year} winner`} loading="lazy"
                      style={{ width: 72, height: 72, objectFit: 'contain', display: 'block' }} />
                  </picture>
                  <div>
                    <div style={{
                      fontFamily: FF.display, fontStyle: 'italic', fontWeight: 500,
                      fontSize: 22, color: C.terra, lineHeight: 1.05, letterSpacing: '-0.01em',
                    }}>Best of Downtown</div>
                    <div style={{
                      fontFamily: FF.display, fontSize: 16, color: C.ink, marginTop: 4, fontWeight: 400,
                    }}>{a.year} Winner</div>
                  </div>
                </div>
              ))}
            </div>
            <a
              href="https://www.ladowntownnews.com/business/showalters-salon-is-making-a-name-for-itself/article_ec46c7b4-a189-11ec-a96d-eb31f9d13bdd.html"
              target="_blank" rel="noopener noreferrer"
              style={{
                display: 'inline-flex', alignItems: 'center', gap: 8,
                marginTop: 28, paddingBottom: 4,
                fontFamily: FF.display, fontStyle: 'italic', fontSize: 17,
                color: C.ink, textDecoration: 'none',
                borderBottom: `1px solid ${C.terra}66`,
                transition: 'color .25s, border-color .25s',
              }}
              onMouseEnter={(e) => { e.currentTarget.style.color = C.terra; e.currentTarget.style.borderColor = C.terra; }}
              onMouseLeave={(e) => { e.currentTarget.style.color = C.ink; e.currentTarget.style.borderColor = C.terra + '66'; }}
            >
              As featured in LA Downtown News
              <span style={{ transition: 'transform .25s' }}>→</span>
            </a>
          </div>
        </Reveal>
      </div>
    </section>
  );
}

// ── PORTFOLIO ──
function Portfolio({ C, FF, HS, padY, layout }) {
  return (
    <section id="work" className="m-section" style={{ padding: `0 56px ${padY}px` }}>
      <Reveal as="div" className="m-stack" style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 48 }}>
        <h2 className="m-h2" style={{ fontFamily: FF.display, fontWeight: 300, fontStyle: 'italic', fontSize: 80 * HS, margin: 0, letterSpacing: '-0.03em' }}>
          Recent <span style={{ color: C.terra, fontWeight: 600, fontStyle: 'normal' }}>work</span>
        </h2>
        <span style={{ fontFamily: FF.mono, fontSize: 11, letterSpacing: '0.2em', textTransform: 'uppercase', color: C.rust }}>2024 — 2026</span>
      </Reveal>
      <Reveal delay={120}>
        {layout === 'grid' && <PortfolioGrid C={C} FF={FF} />}
        {layout === 'masonry' && <PortfolioMasonry C={C} FF={FF} />}
        {layout === 'film' && <PortfolioFilm C={C} FF={FF} />}
      </Reveal>
    </section>
  );
}

function PortfolioMasonry({ C, FF }) {
  return (
    <div className="m-grid-2" style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 16 }}>
      {IMG.work.map((src, i) => {
        const tall = i % 3 === 0;
        return (
          <figure key={i} data-c="open" style={{
            margin: 0, gridRow: tall ? 'span 2' : 'span 1',
            aspectRatio: tall ? '3/5' : '4/5',
            overflow: 'hidden', borderRadius: 4, position: 'relative', background: C.sand,
            transition: 'transform .4s',
          }} onMouseEnter={(e) => e.currentTarget.style.transform = 'translateY(-6px)'}
             onMouseLeave={(e) => e.currentTarget.style.transform = 'translateY(0)'}>
            <img src={src} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover', filter: 'sepia(0.08)' }} />
            <div style={{ position: 'absolute', top: 12, left: 12, fontFamily: FF.mono, fontSize: 10, letterSpacing: '0.2em', color: C.cream, background: `${C.ink}66`, backdropFilter: 'blur(4px)', padding: '4px 10px', borderRadius: 999 }}>№ {String(i+1).padStart(2, '0')}</div>
          </figure>
        );
      })}
    </div>
  );
}

function PortfolioGrid({ C, FF }) {
  return (
    <div className="m-grid-2" style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 16 }}>
      {IMG.work.map((src, i) => (
        <figure key={i} data-c="open" style={{ margin: 0, aspectRatio: '4/5', overflow: 'hidden', borderRadius: 4, position: 'relative', background: C.sand, transition: 'transform .4s' }}
          onMouseEnter={(e) => e.currentTarget.style.transform = 'translateY(-6px)'}
          onMouseLeave={(e) => e.currentTarget.style.transform = 'translateY(0)'}>
          <img src={src} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover', filter: 'sepia(0.08)' }} />
          <div style={{ position: 'absolute', top: 12, left: 12, fontFamily: FF.mono, fontSize: 10, letterSpacing: '0.2em', color: C.cream, background: `${C.ink}66`, backdropFilter: 'blur(4px)', padding: '4px 10px', borderRadius: 999 }}>№ {String(i+1).padStart(2, '0')}</div>
        </figure>
      ))}
    </div>
  );
}

function PortfolioFilm({ C, FF }) {
  return (
    <div style={{ display: 'flex', gap: 16, overflowX: 'auto', paddingBottom: 16, scrollSnapType: 'x mandatory' }}>
      {IMG.work.map((src, i) => (
        <figure key={i} data-c="open" style={{ margin: 0, flex: '0 0 auto', width: 320, aspectRatio: '4/5', overflow: 'hidden', borderRadius: 4, position: 'relative', scrollSnapAlign: 'start', background: C.sand }}>
          <img src={src} alt="" style={{ width: '100%', height: '100%', objectFit: 'cover', filter: 'sepia(0.08)' }} />
          <div style={{ position: 'absolute', top: 12, left: 12, fontFamily: FF.mono, fontSize: 10, letterSpacing: '0.2em', color: C.cream, background: `${C.ink}66`, backdropFilter: 'blur(4px)', padding: '4px 10px', borderRadius: 999 }}>№ {String(i+1).padStart(2, '0')}</div>
        </figure>
      ))}
    </div>
  );
}

// ── PRESS / FEATURED WORK ──
function Press({ C, FF, HS, padY }) {
  const partners = [
    'Verizon', 'Olaplex', 'Biolage', 'Big Sexy Hair',
    'Square', 'Vagaro', 'Live Nation', 'E!',
  ];
  return (
    <section id="press" className="m-section m-section-y" style={{ padding: `${padY}px 56px`, background: C.cream, position: 'relative', overflow: 'hidden' }}>
      <div className="m-grid-stack" style={{ display: 'grid', gridTemplateColumns: '1fr 1.5fr', gap: 80, alignItems: 'start' }}>
        <Reveal style={{ position: 'sticky', top: 100 }}>
          <div className="m-eyebrow" style={{ fontFamily: FF.mono, fontSize: 11, letterSpacing: '0.24em', textTransform: 'uppercase', color: C.rust, marginBottom: 24 }}>Featured Work</div>
          <h2 className="m-h2" style={{ fontFamily: FF.display, fontWeight: 300, fontStyle: 'italic', fontSize: 80 * HS, lineHeight: 0.95, margin: 0, letterSpacing: '-0.03em' }}>
            Brand<br/><span style={{ fontWeight: 600, fontStyle: 'normal', color: C.terra }}>partnerships.</span>
          </h2>
        </Reveal>

        <Reveal delay={120}>
          {/* Hero credit */}
          <div style={{
            background: C.sand,
            borderRadius: 24,
            padding: '36px 40px',
            position: 'relative',
            overflow: 'hidden',
          }}>
            <div style={{ fontFamily: FF.display, fontSize: 56 * HS, fontStyle: 'italic', fontWeight: 300, lineHeight: 1, letterSpacing: '-0.03em' }}>
              Verizon
            </div>
            <div style={{ marginTop: 8, fontFamily: FF.display, fontSize: 22, fontStyle: 'italic', color: C.ink + 'cc' }}>
              commercial with <span style={{ color: C.terra, fontWeight: 600, fontStyle: 'normal' }}>J. Balvin</span>
            </div>
            <div style={{ marginTop: 28, paddingTop: 20, borderTop: `1px dashed ${C.terra}66`, display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', gap: 16 }}>
              <span style={{ fontFamily: FF.mono, fontSize: 10, letterSpacing: '0.2em', textTransform: 'uppercase', color: C.rust, flexShrink: 0 }}>Filming location</span>
              <span style={{ fontFamily: FF.display, fontStyle: 'italic', fontSize: 18, color: C.ink, textAlign: 'right' }}>No Name Salon · Downtown Los Angeles</span>
            </div>
          </div>

          {/* Partners grid */}
          <div style={{ marginTop: 24, fontFamily: FF.mono, fontSize: 10, letterSpacing: '0.2em', textTransform: 'uppercase', color: C.rust, marginBottom: 16 }}>
            Brands I&rsquo;ve worked with &amp; collaborated with
          </div>
          <div className="m-partners" style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', borderTop: `1px solid ${C.terra}33`, borderLeft: `1px solid ${C.terra}33` }}>
            {partners.map((p, i) => (
              <div key={p} className="m-partner-cell" style={{
                padding: '32px 16px', textAlign: 'center',
                borderRight: `1px solid ${C.terra}33`, borderBottom: `1px solid ${C.terra}33`,
                fontFamily: FF.display, fontStyle: 'italic', fontSize: 26, fontWeight: 400,
                color: C.ink, transition: 'all .3s', cursor: 'pointer',
              }}
              onMouseEnter={(e) => { e.currentTarget.style.background = C.sand; e.currentTarget.style.color = C.terra; }}
              onMouseLeave={(e) => { e.currentTarget.style.background = 'transparent'; e.currentTarget.style.color = C.ink; }}>
                {p}
              </div>
            ))}
          </div>
          
          {/* Color lines — Brandfetch logos */}
          <div style={{ marginTop: 40, fontFamily: FF.mono, fontSize: 10, letterSpacing: '0.2em', textTransform: 'uppercase', color: C.rust, marginBottom: 20 }}>
            Color lines I use
          </div>
          <div className="m-color-lines" style={{
            display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 0,
            borderTop: `1px solid ${C.terra}33`, borderLeft: `1px solid ${C.terra}33`,
          }}>
            {[
              { name: 'Redken',            brandId: 'idmZoUjBMS', height: 36 },
              { name: 'Brazilian Blowout', brandId: 'idzzbBhirp', height: 30 },
              { name: 'Wella',             brandId: 'idukvmU-qB', height: 40 },
            ].map((b) => (
              <div key={b.brandId} style={{
                padding: '36px 20px', minHeight: 110,
                borderRight: `1px solid ${C.terra}33`, borderBottom: `1px solid ${C.terra}33`,
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                transition: 'background .3s',
              }}
              onMouseEnter={(e) => { e.currentTarget.style.background = C.sand + '88'; }}
              onMouseLeave={(e) => { e.currentTarget.style.background = 'transparent'; }}>
                <img
                  src={`https://cdn.brandfetch.io/${b.brandId}/logo?c=1bxyb5nrjtgfh5y0zigft6sw4h5saiKEWdB`}
                  alt={b.name}
                  loading="lazy"
                  style={{ height: b.height, width: 'auto', maxWidth: '85%', objectFit: 'contain', display: 'block' }}
                />
              </div>
            ))}
          </div>
        </Reveal>
      </div>
    </section>
  );
}

// ── SERVICES ──
function Services({ C, FF, HS, padY }) {
  const [open, setOpen] = uS('Lived-In Color');
  return (
    <section id="services" className="m-section m-section-y" style={{ padding: `${padY}px 56px`, background: C.sand, position: 'relative' }}>
      <div className="m-grid-stack" style={{ display: 'grid', gridTemplateColumns: '1fr 1.5fr', gap: 80, alignItems: 'start' }}>
        <div style={{ position: 'sticky', top: 100 }}>
          <div className="m-eyebrow" style={{ fontFamily: FF.mono, fontSize: 11, letterSpacing: '0.24em', textTransform: 'uppercase', color: C.rust, marginBottom: 16 }}>The Menu</div>
          <h2 className="m-h2" style={{ fontFamily: FF.display, fontWeight: 300, fontStyle: 'italic', fontSize: 80 * HS, lineHeight: 0.95, margin: 0, letterSpacing: '-0.03em' }}>
            Slow<br/>services.
          </h2>
          <p style={{ marginTop: 32, fontFamily: FF.display, fontSize: 17, lineHeight: 1.55, opacity: 0.8 }}>
            Pricing varies with length and density. Every visit includes a full consultation, scalp massage, and tea.
          </p>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8, marginTop: 32 }}>
            {Object.keys(HER_SERVICES).map(cat => (
              <button key={cat} data-c="" onClick={() => setOpen(cat)} style={{
                textAlign: 'left', background: 'none', border: 'none', cursor: 'pointer',
                fontFamily: FF.display, fontSize: 28, fontWeight: open === cat ? 600 : 300,
                fontStyle: open === cat ? 'normal' : 'italic',
                color: open === cat ? C.terra : C.ink, padding: '8px 0',
                transition: 'all .3s', display: 'flex', alignItems: 'center', gap: 16,
              }}>
                <span style={{ width: open === cat ? 32 : 12, height: 1, background: open === cat ? C.terra : C.ink, transition: 'width .3s' }} />
                {cat}
              </button>
            ))}
          </div>
        </div>
        <div>
          {HER_SERVICES[open].map(([name, price], i) => (
            <div key={i} data-c="book" style={{
              display: 'flex', alignItems: 'baseline', justifyContent: 'space-between',
              padding: '24px 0', borderBottom: `1px solid ${C.ink}22`,
              fontFamily: FF.display, fontSize: 24, cursor: 'pointer', transition: 'padding-left .3s, color .3s',
            }} onMouseEnter={(e) => { e.currentTarget.style.paddingLeft = '16px'; e.currentTarget.style.color = C.terra; }}
            onMouseLeave={(e) => { e.currentTarget.style.paddingLeft = '0'; e.currentTarget.style.color = C.ink; }}>
              <span style={{ fontStyle: 'italic' }}>{name}</span>
              <span style={{ fontFamily: FF.mono, fontSize: 16 }}>{price}</span>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

// ── TESTIMONIALS ──
function Testimonials({ C, FF, HS, padY }) {
  return (
    <section id="reviews" className="m-section m-section-y" style={{ padding: `${padY}px 56px` }}>
      <Reveal style={{ textAlign: 'center', marginBottom: 64 }}>
        <div className="m-eyebrow" style={{ fontFamily: FF.mono, fontSize: 11, letterSpacing: '0.24em', textTransform: 'uppercase', color: C.rust, marginBottom: 16 }}>Said by clients</div>
        <h2 className="m-h2" style={{ fontFamily: FF.display, fontWeight: 300, fontStyle: 'italic', fontSize: 80 * HS, margin: 0 }}>
          Kind <span style={{ color: C.terra, fontWeight: 600, fontStyle: 'normal' }}>letters.</span>
        </h2>
      </Reveal>
      <div className="m-grid-stack" style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 32 }}>
        {TESTIMONIALS.map((t, i) => (
          <Reveal key={i} delay={i * 100} style={{
            background: C.cream, padding: 36, borderRadius: '24px 24px 24px 4px',
            border: `1px solid ${C.terra}22`, position: 'relative',
          }}>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', height: 32 }}>
              <div style={{ fontFamily: FF.display, fontSize: 96, lineHeight: 0.4, color: C.terra }}>“</div>
              {t.source === 'yelp' && (
                <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                  <span style={{ fontSize: 13, letterSpacing: '0.05em', color: '#d32323' }}>★★★★★</span>
                  <span style={{ fontFamily: FF.mono, fontSize: 9, letterSpacing: '0.22em', textTransform: 'uppercase', color: C.rust }}>Yelp</span>
                </div>
              )}
            </div>
            <p style={{ fontFamily: FF.display, fontSize: 17, lineHeight: 1.6, margin: 0, fontStyle: 'italic' }}>{t.body}</p>
            <div style={{ marginTop: 24, paddingTop: 16, borderTop: `1px dashed ${C.terra}66`, display: 'flex', alignItems: 'center', gap: 12 }}>
              <div style={{ width: 40, height: 40, borderRadius: '50%', background: C.terra, display: 'flex', alignItems: 'center', justifyContent: 'center', color: C.cream, fontFamily: FF.display, fontWeight: 600, fontSize: 16 }}>
                {t.name[0]}
              </div>
              <div>
                <div style={{ fontFamily: FF.display, fontSize: 16, fontWeight: 500 }}>{t.name}</div>
                <div style={{ fontFamily: FF.mono, fontSize: 10, letterSpacing: '0.16em', textTransform: 'uppercase', color: C.rust, marginTop: 2 }}>{t.service}</div>
              </div>
            </div>
          </Reveal>
        ))}
      </div>
    </section>
  );
}

// ── FAQ ──
function FAQSection({ C, FF, HS, padY }) {
  return (
    <section className="m-section" style={{ padding: `${padY/2}px 56px ${padY}px` }}>
      <Reveal as="h2" className="m-h2" style={{ fontFamily: FF.display, fontWeight: 300, fontStyle: 'italic', fontSize: 64 * HS, margin: '0 0 32px' }}>
        Things people <span style={{ color: C.terra, fontWeight: 600, fontStyle: 'normal' }}>ask.</span>
      </Reveal>
      <div className="m-grid-stack" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>
        {FAQ.map(([q, a], i) => (
          <Reveal key={i} as="details" delay={i * 50} style={{
            background: i % 2 === 0 ? C.sand : C.cream,
            borderRadius: 18, padding: '20px 24px', border: `1px solid ${C.terra}22`,
          }}>
            <summary data-c="" style={{ fontFamily: FF.display, fontSize: 19, cursor: 'pointer', listStyle: 'none', display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 16 }}>
              <span style={{ fontStyle: 'italic' }}>{q}</span>
              <span style={{ width: 28, height: 28, borderRadius: '50%', background: C.terra, color: C.cream, display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 16, flexShrink: 0 }}>+</span>
            </summary>
            <p style={{ fontFamily: FF.display, fontSize: 15, lineHeight: 1.55, marginTop: 16, marginBottom: 0, opacity: 0.85 }}>{a}</p>
          </Reveal>
        ))}
      </div>
    </section>
  );
}

// ── CTA ──
function CTA({ C, FF, HS }) {
  return (
    <section className="m-section" style={{ padding: '120px 56px', textAlign: 'center', background: `linear-gradient(180deg, ${C.cream} 0%, ${C.sun} 100%)`, position: 'relative', overflow: 'hidden' }}>
      <Reveal>
        <div className="m-eyebrow" style={{ fontFamily: FF.mono, fontSize: 11, letterSpacing: '0.24em', textTransform: 'uppercase', color: C.rust, marginBottom: 24 }}>
          ✺ &nbsp; The Studio &nbsp; ✺
        </div>
        <h2 className="m-h1" style={{ fontFamily: FF.display, fontWeight: 300, fontStyle: 'italic', fontSize: 120 * HS, lineHeight: 0.92, margin: 0, letterSpacing: '-0.04em' }}>
          See you<br/>
          <span style={{ fontWeight: 600, fontStyle: 'normal', color: C.terra }}>in the chair.</span>
        </h2>
        <a className="m-btn" href="#book" data-c="reserve" style={{ display: 'inline-block', marginTop: 48, padding: '20px 48px', background: C.ink, color: C.cream, borderRadius: 999, fontSize: 14, letterSpacing: '0.06em', cursor: 'pointer', textDecoration: 'none' }}>Reserve a visit →</a>
      </Reveal>
    </section>
  );
}

// ── FOOTER ──
function Footer({ C, FF }) {
  return (
    <footer className="m-footer" style={{ padding: '48px 56px', background: C.ink, color: C.cream, display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 32 }}>
      <div>
        <div style={{ fontFamily: FF.display, fontStyle: 'italic', fontSize: 28 }}>Harlee Showalter<span style={{ color: C.terra }}>.</span></div>
        <div style={{ fontFamily: FF.mono, fontSize: 10, letterSpacing: '0.22em', textTransform: 'uppercase', color: C.terra, marginTop: 8 }}>at Desert Lounge Salon</div>
        <p style={{ fontFamily: FF.display, fontSize: 14, lineHeight: 1.55, marginTop: 16, opacity: 0.7 }}>
          Lived-in color and slow cuts, in the heart of St. George.
        </p>
      </div>
      {[['Studio', 'Desert Lounge Salon\n75 N 100 E\nSt. George, UT 84770\nWed & Fri · 9–5'], ['Index', 'About\nWork\nServices\nReviews\nFAQ'], ['Elsewhere', 'Instagram\nPinterest\nNewsletter']].map(([t, b]) => (
        <div key={t}>
          <div style={{ fontFamily: FF.mono, fontSize: 11, letterSpacing: '0.2em', textTransform: 'uppercase', color: C.terra, marginBottom: 16 }}>{t}</div>
          <div style={{ fontFamily: 'Inter', fontSize: 13, lineHeight: 1.8, whiteSpace: 'pre-line', opacity: 0.85 }}>{b}</div>
        </div>
      ))}
    </footer>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
