/* ============================================
   IZZY BLENDS — GLOBAL STYLES
   Private Barber Studio · Denver, CO
   Mobile-first. Onyx base, Bone text,
   Cherry Red + Chrome do the talking.
   ============================================ */

/* --- Reset --- */
*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

/* --- Brand tokens (from BRAND_KIT.md) --- */
:root {
  --onyx:      #0B0B0C;
  --asphalt:   #16171A;
  --cherry:    #D62027;
  --oxblood:   #7A0C0C;
  --chrome:    #C9CDD2;
  --chrome-lo: #8A9099;
  --bone:      #EDE7D6;
  --smoke:     #7D828A; /* lightened from #6E7276 — 5.1:1 on Onyx (WCAG AA) */

  --grad-chrome: linear-gradient(180deg, #EDEFF2 0%, #C9CDD2 40%, #8A9099 70%, #C9CDD2 100%);
  --grad-red:    linear-gradient(180deg, #D62027 0%, #7A0C0C 100%);

  /* Type roles — brush script for wordmark, blackletter
     for section headers only */
  --font-wordmark: 'Kaushan Script', cursive;
  --font-header:   'Pirata One', cursive;
  --font-label:    'Oswald', sans-serif;
  --font-body:     'Barlow', sans-serif;
}

/* --- Base --- */
html {
  scroll-behavior: smooth;
}

body {
  background-color: var(--onyx);
  color: var(--bone);
  font-family: var(--font-body);
  font-weight: 400;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img {
  display: block;
  max-width: 100%;
}

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

ul {
  list-style: none;
}

/* ============================================
   HERO — full height, reverent, heavy
   The lockup sits alone in generous negative
   space: wordmark, studio line, one flourish,
   one red action. Nothing else.
   ============================================ */

.hero {
  position: relative;
  /* dvh locks to the real visible viewport as the mobile
     address bar hides/shows; plain vh is the fallback */
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  padding: 4rem 1.5rem;
  background-color: var(--onyx); /* paints first, no flash */
}

/* Rooftop photo layer — a real <img> (see index.html) so
   phones download the small WebP variant */
.hero__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.hero__bg picture {
  display: block;
  width: 100%;
  height: 100%;
}

.hero__bg img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* 45% x keeps Izzy centered in portrait crops;
     36% y holds his head + the skyline in widescreen crops */
  object-position: 45% 36%;
}

/* Onyx overlays: a vignette that buries the edges, and a
   vertical gradient — near-opaque top/bottom, ~68% through
   the middle band — so the photo is atmosphere, not backdrop */
.hero__bg-overlay {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(120% 90% at 50% 42%,
      rgba(11, 11, 12, 0) 42%,
      rgba(11, 11, 12, 0.82) 100%),
    linear-gradient(180deg,
      rgba(11, 11, 12, 0.95) 0%,
      rgba(11, 11, 12, 0.68) 40%,
      rgba(11, 11, 12, 0.72) 64%,
      rgba(11, 11, 12, 0.97) 100%);
}

/* Portrait phones: slide the crop so Izzy stands left of the
   centered type column (his white shirt is the brightest patch —
   keep it out from under the tagline), and run the overlay a
   touch darker for contrast on the narrow slice */
@media (max-width: 600px) {
  .hero__bg img {
    object-position: 32% 36%;
  }

  .hero__bg-overlay {
    background:
      radial-gradient(130% 90% at 50% 42%,
        rgba(11, 11, 12, 0) 38%,
        rgba(11, 11, 12, 0.85) 100%),
      linear-gradient(180deg,
        rgba(11, 11, 12, 0.95) 0%,
        rgba(11, 11, 12, 0.76) 40%,
        rgba(11, 11, 12, 0.8) 64%,
        rgba(11, 11, 12, 0.97) 100%);
  }
}

/* Concrete grain — low-opacity noise over the photo */
.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
  background-repeat: repeat;
  background-size: 180px 180px;
}

/* Ambient smoke — two soft tinted plumes drifting very
   slowly behind the lockup. Transform-only, no filters,
   so it stays cheap on mobile. */
.hero__smoke {
  position: absolute;
  inset: -15%;
  z-index: 1;
  pointer-events: none;
  background:
    radial-gradient(42% 30% at 30% 68%, rgba(201, 205, 210, 0.045), transparent 70%),
    radial-gradient(36% 26% at 72% 28%, rgba(122, 12, 12, 0.07), transparent 70%);
}

.hero__inner {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  max-width: 40rem;
}

/* --- Barber pole — pure CSS, brand palette ----------- */

.hero__pole {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  margin-bottom: 2.25rem;
}

.pole__cap {
  width: 30px;
  height: 8px;
  background: var(--grad-chrome);
  border-radius: 2px;
}

.pole__body {
  position: relative;
  width: 22px;
  height: 84px;
  overflow: hidden;
  border-radius: 3px;
  border: 1px solid rgba(201, 205, 210, 0.2);
  background-color: var(--asphalt);
}

/* Stripes live on an oversized layer translated by exactly
   one diagonal period (36px / sin45 ≈ 50.9px) per loop, so
   the spiral scrolls seamlessly — transform-only, GPU-cheap */
.pole__body::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: -51px;
  bottom: -51px;
  background: repeating-linear-gradient(
    45deg,
    var(--cherry) 0 9px,
    var(--asphalt) 9px 18px,
    var(--bone) 18px 27px,
    var(--asphalt) 27px 36px
  );
}

/* Metallic sheen — dark edges, one soft highlight */
.pole__body::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    90deg,
    rgba(11, 11, 12, 0.55),
    rgba(237, 231, 214, 0.16) 30%,
    rgba(237, 231, 214, 0.04) 48%,
    rgba(11, 11, 12, 0.6)
  );
}

.hero__wordmark {
  font-family: var(--font-wordmark);
  font-weight: 400; /* scripts ship one weight */
  font-size: clamp(3rem, 13vw, 5.6rem);
  line-height: 1.15;
  color: var(--bone);
  padding: 0 0.5em 0.12em; /* room for brush tails */
  /* Painted-sign pop: hard offset like a hand-cut shadow,
     then a soft grounding below */
  text-shadow:
    3px 4px 0 rgba(0, 0, 0, 0.85),
    6px 10px 26px rgba(0, 0, 0, 0.55);
}


/* "— PRIVATE BARBER STUDIO —" with thin chrome rules */
.hero__lockup {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-top: 1.5rem;
  font-family: var(--font-label);
  font-weight: 500;
  font-size: clamp(0.72rem, 3vw, 0.85rem);
  letter-spacing: 0.18em;
  text-indent: 0.18em; /* balances the tracking on centered caps */
  text-transform: uppercase;
  color: var(--chrome);
  white-space: nowrap;
}

.hero__lockup::before,
.hero__lockup::after {
  content: '';
  width: clamp(1.5rem, 8vw, 3.5rem);
  height: 1px;
  background: var(--grad-chrome);
  opacity: 0.7;
}

/* Tagline — sharp and modern, the one red statement */
.hero__tagline {
  margin-top: 2.75rem;
  font-family: var(--font-label);
  font-weight: 600;
  /* floor 1.17rem keeps this in WCAG large-text territory —
     cherry on Onyx is 3.8:1, fine for large bold, not for small */
  font-size: clamp(1.17rem, 4.5vw, 1.3rem);
  letter-spacing: 0.24em;
  text-indent: 0.24em;
  text-transform: uppercase;
  line-height: 1.3;
  color: var(--cherry);
}

/* --- Booking CTAs — one refined style, site-wide ------
   Brushed metal on red: cherry-to-oxblood surface, a fine
   bone top highlight, low dark shadow. Hover lifts and a
   chrome sheen sweeps once; press physically depresses. */
.btn-book {
  position: relative;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px; /* tap target */
  margin-top: 3.25rem;
  padding: 1.1rem 3rem;
  font-family: var(--font-label);
  font-weight: 600;
  font-size: 0.9rem;
  letter-spacing: 0.14em;
  text-indent: 0.14em;
  text-transform: uppercase;
  /* Ghost treatment: near-transparent cherry tint so the dark
     site and skyline read through; bone label for legibility
     over busy photo backgrounds */
  color: var(--bone);
  background: rgba(214, 32, 39, 0.12);
  border: 1px solid rgba(214, 32, 39, 0.65);
  border-radius: 2px;
  transition:
    transform 0.22s cubic-bezier(0.22, 1, 0.36, 1),
    box-shadow 0.22s cubic-bezier(0.22, 1, 0.36, 1),
    background-color 0.22s cubic-bezier(0.22, 1, 0.36, 1),
    border-color 0.22s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Chrome sheen — parked off-canvas, sweeps once on hover-in;
   no transition when idle so it resets invisibly */
.btn-book::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 55%;
  background: linear-gradient(
    105deg,
    transparent 0%,
    rgba(237, 231, 214, 0.16) 50%,
    transparent 100%
  );
  transform: translateX(-160%) skewX(-24deg);
  pointer-events: none;
}

.btn-book:hover {
  transform: translateY(-2px);
  background-color: rgba(214, 32, 39, 0.22);
  border-color: rgba(214, 32, 39, 0.9);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
}

.btn-book:hover::after {
  transform: translateX(300%) skewX(-24deg);
  transition: transform 0.65s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Press: drops back down, tint deepens — physical on tap */
.btn-book:active {
  transform: translateY(1px);
  background-color: rgba(214, 32, 39, 0.3);
  box-shadow: none;
}

/* Reduced motion: no lift, no sweep — tint feedback only */
@media (prefers-reduced-motion: reduce) {
  .btn-book:hover,
  .btn-book:active {
    transform: none;
  }

  .btn-book::after {
    display: none;
  }
}

.hero__meta {
  margin-top: 2.5rem;
  font-family: var(--font-label);
  font-weight: 500;
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-indent: 0.12em;
  text-transform: uppercase;
  color: var(--smoke);
}

/* ── MOTION (all opt-in via prefers-reduced-motion) ──
   Slow, heavy, reverent: fades and small rises only.
   The pole spins, the smoke drifts, sections breathe in
   on scroll. Nothing bounces. */

@media (prefers-reduced-motion: no-preference) {

  /* Hero entrance — staggered fade-and-rise, ~650ms each */
  .hero__pole,
  .hero__wordmark,
  .hero__lockup,
  .hero__tagline,
  .hero .btn-book,
  .hero__meta {
    animation: hero-rise 0.65s cubic-bezier(0.22, 1, 0.36, 1) both;
  }

  .hero__wordmark { animation-delay: 0.1s; }
  .hero__lockup   { animation-delay: 0.22s; }
  .hero__tagline  { animation-delay: 0.34s; }
  .hero .btn-book { animation-delay: 0.46s; }
  .hero__meta     { animation-delay: 0.58s; }

  /* Barber pole rotation */
  .pole__body::before {
    animation: pole-spin 3.8s linear infinite;
  }

  /* Ambient smoke drift */
  .hero__smoke {
    animation: smoke-drift 24s ease-in-out infinite alternate;
  }

  /* Scroll reveals — hidden state only when JS is running */
  .js .reveal {
    opacity: 0;
    transform: translateY(18px);
    transition: opacity 0.7s cubic-bezier(0.22, 1, 0.36, 1),
                transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
  }

  .js .reveal.is-in {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes hero-rise {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes pole-spin {
  to { transform: translateY(50.9px); }
}

@keyframes smoke-drift {
  to { transform: translate3d(3%, -2.5%, 0); }
}

/* Larger screens: keep the same composition, more air */
@media (min-width: 700px) {
  .hero {
    padding: 6rem 2rem;
  }
}

/* ============================================
   SHARED — section titles + chrome dividers
   ============================================ */

.section-title {
  font-family: var(--font-header);
  font-weight: 400;
  font-size: clamp(2.4rem, 9vw, 3.4rem);
  line-height: 1.1;
  letter-spacing: 0.04em;
  text-align: center;
  color: var(--bone);
}

/* Thin chrome rule with a center diamond — the price-sheet divider */
.divider {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  width: 100%;
  max-width: 20rem;
  margin: 1.75rem auto 0;
}

.divider::before,
.divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--grad-chrome);
  opacity: 0.55;
}

.divider__diamond {
  font-size: 0.55rem;
  line-height: 1;
  color: var(--chrome);
}

/* ============================================
   PRICING — the price sheet
   Single column, poster-style rows, easy to
   read one-handed at phone width.
   ============================================ */

.pricing {
  padding: 5.5rem 1.5rem;
}

.pricing__inner {
  max-width: 34rem;
  margin: 0 auto;
}

.price-list {
  margin-top: 2.75rem;
}

.price-row {
  display: flex;
  align-items: baseline;
  gap: 0.9rem;
  padding: 1.15rem 0;
}

.price-row + .price-row {
  border-top: 1px solid rgba(201, 205, 210, 0.12);
}

.price-row__name {
  font-family: var(--font-label);
  font-weight: 500;
  font-size: clamp(0.85rem, 3.6vw, 1rem);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--bone);
}

/* Dotted leader between service and price */
.price-row__leader {
  flex: 1;
  border-bottom: 1px dotted rgba(201, 205, 210, 0.3);
  transform: translateY(-0.28em);
}

.price-row__amount {
  font-family: var(--font-label);
  font-weight: 600;
  font-size: clamp(0.95rem, 4vw, 1.1rem);
  letter-spacing: 0.06em;
  color: var(--chrome);
}

.price-list + .divider {
  margin-top: 2.75rem;
}

@media (min-width: 700px) {
  .pricing {
    padding: 7rem 2rem;
  }
}

/* ============================================
   GALLERY — the work speaks
   1 col on small phones, 2 on larger phones,
   3 from tablet up. Portrait 4:5 crops.
   ============================================ */

.gallery {
  padding: 5.5rem 1.5rem;
}

.gallery__inner {
  max-width: 64rem;
  margin: 0 auto;
}

.gallery__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.9rem;
  margin-top: 2.75rem;
}

@media (min-width: 420px) {
  .gallery__grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 760px) {
  .gallery__grid {
    grid-template-columns: repeat(3, 1fr);
    gap: 1.1rem;
  }
}

.gallery__item,
.gallery__ph {
  aspect-ratio: 4 / 5;
  background-color: var(--asphalt);
  border: 1px solid rgba(201, 205, 210, 0.12);
  border-radius: 2px;
  overflow: hidden;
}

.gallery__item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Placeholder tiles — quiet asphalt panels, one chrome diamond */
.gallery__ph {
  display: flex;
  align-items: center;
  justify-content: center;
}

.gallery__ph span {
  font-size: 0.6rem;
  color: var(--chrome-lo);
  opacity: 0.6;
}

.gallery__note {
  margin-top: 2rem;
  text-align: center;
  font-family: var(--font-label);
  font-weight: 500;
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-indent: 0.12em;
  text-transform: uppercase;
  color: var(--smoke);
}

.gallery__note-link {
  display: inline-block;
  padding: 0.9rem 0.3rem; /* 44px tap target on a small line */
  margin: -0.9rem 0;
  color: var(--chrome);
  transition: color 0.2s ease;
}

.gallery__note-link:hover {
  color: var(--bone);
}

@media (min-width: 700px) {
  .gallery {
    padding: 7rem 2rem;
  }
}

/* ============================================
   BOOKING — one chair, one action
   The embed slot is a placeholder panel until
   the Calendly inline widget replaces it.
   ============================================ */

.booking {
  padding: 5.5rem 1.5rem;
}

.booking__inner {
  max-width: 44rem;
  margin: 0 auto;
}

.booking__lead {
  margin-top: 2.5rem;
  text-align: center;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 1.05rem;
  color: var(--bone);
}

/* Placeholder for the Calendly inline widget */
.booking__embed-slot {
  margin-top: 2.25rem;
  min-height: 24rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  text-align: center;
  padding: 2rem 1.5rem;
  background-color: var(--asphalt);
  border: 1px dashed rgba(201, 205, 210, 0.25);
  border-radius: 2px;
}

.booking__embed-diamond {
  font-size: 0.7rem;
  color: var(--chrome-lo);
}

.booking__embed-label {
  font-family: var(--font-label);
  font-weight: 600;
  font-size: 0.95rem;
  letter-spacing: 0.12em;
  text-indent: 0.12em;
  text-transform: uppercase;
  color: var(--chrome);
}

.booking__embed-sub {
  font-family: var(--font-body);
  font-size: 0.9rem;
  color: var(--smoke);
}

.booking__meta {
  margin-top: 2rem;
  text-align: center;
  font-family: var(--font-label);
  font-weight: 500;
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-indent: 0.12em;
  text-transform: uppercase;
  color: var(--smoke);
}

@media (min-width: 700px) {
  .booking {
    padding: 7rem 2rem;
  }
}

/* Anchor lands with a little air above the title */
#book,
#pricing,
#gallery {
  scroll-margin-top: 1rem;
}

/* ============================================
   FOOTER — quiet sign-off
   ============================================ */

.footer {
  border-top: 1px solid rgba(201, 205, 210, 0.12);
  padding: 3rem 1.5rem calc(3rem + env(safe-area-inset-bottom, 0px));
}

.footer__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.9rem;
  text-align: center;
}

.footer__ig {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;  /* tap target */
  min-height: 44px;
  color: var(--chrome);
  transition: color 0.2s ease;
}

.footer__ig:hover {
  color: var(--bone);
}

.footer__note {
  font-family: var(--font-label);
  font-weight: 500;
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-indent: 0.12em;
  text-transform: uppercase;
  color: var(--smoke);
}

.footer__name {
  font-family: var(--font-wordmark);
  font-weight: 400;
  font-size: 1.5rem;
  color: var(--bone);
}

/* ============================================
   STICKY BOOKING BAR
   Slides up once the hero scrolls away, steps
   aside when the booking section is on screen.
   ============================================ */

.book-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 100;
  padding: 0.6rem 1rem calc(0.6rem + env(safe-area-inset-bottom, 0px));
  background: rgba(11, 11, 12, 0.94);
  border-top: 1px solid rgba(201, 205, 210, 0.14);
  transform: translateY(110%);
  transition: transform 0.3s ease;
}

.book-bar.is-visible {
  transform: translateY(0);
}

.book-bar__btn {
  display: flex;
  width: 100%;
  max-width: 28rem;
  margin: 0 auto;          /* cancel .btn-book's top margin */
  padding: 0.75rem 1.5rem; /* same style, compact proportions */
}

/* ============================================
   BRANDED LOADER — pole-first handoff
   The hero pole itself plays the loader: JS
   transforms it to screen center over an Onyx
   veil, then glides it home while the veil
   fades and the hero assembles around it. The
   stripe spin never stops or restarts.
   States: .is-loading (veil solid, pole centered,
   hero held) → .is-handing (glide + fade + hero
   rises) → .pole-handed (done; pole keeps no
   entrance animation so it never re-appears).
   ============================================ */

.is-loading body {
  overflow: hidden;
}

.is-loading body::before,
.is-handing body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 90;
  background: var(--onyx);
  pointer-events: none;
}

.is-handing body::before {
  opacity: 0;
  transition: opacity 0.55s cubic-bezier(0.22, 1, 0.36, 1);
}

/* The pole rides above the veil, in both states */
.is-loading .hero__pole,
.is-handing .hero__pole {
  position: relative;
  z-index: 95;
}

/* Pole shows instantly (no entrance rise) and, once handed
   off, never replays its entrance */
.is-loading .hero__pole,
.is-handing .hero__pole,
.pole-handed .hero__pole {
  animation: none;
  opacity: 1;
}

/* Hold the rest of the hero at 0% until the glide begins;
   their staggered entrance then plays during the handoff */
.is-loading .hero__wordmark,
.is-loading .hero__lockup,
.is-loading .hero__tagline,
.is-loading .hero .btn-book,
.is-loading .hero__meta {
  animation-play-state: paused;
}

/* ============================================
   ACCESSIBILITY
   ============================================ */

/* Keyboard focus — one clean chrome ring everywhere */
:focus-visible {
  outline: 2px solid var(--chrome);
  outline-offset: 3px;
}

/* Reduced motion — kill every animation and transition,
   and let anchors jump instead of glide */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }

  .book-bar {
    transition: none;
  }
}
