/* ==========================================================================
   KH Haircare — base
   Reset, element defaults, utility classes, buttons, RTL and motion prefs.
   All values come from tokens.css.
   ========================================================================== */

/* --- Reset ---------------------------------------------------------------- */

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

html{
  scroll-behavior:smooth;
  -webkit-text-size-adjust:100%;
  /* Hold the scrollbar's column open even when there is nothing to scroll.
     Both body scroll locks (the mobile panel and the intro curtain) take the
     body out of flow, which leaves the document with no scrollbar — without
     this the page widens by the scrollbar's width for as long as the lock is
     held, and snaps back on release. For the curtain that release lands on the
     exact frame the hero is uncovered, so the reveal would open with a jolt.
     On overlay-scrollbar platforms this reserves nothing and costs nothing. */
  scrollbar-gutter:stable;
}

body{
  font-family:var(--font-body);
  font-size:var(--step-0);
  font-weight:400;
  line-height:1.7;
  color:var(--kh-ink);
  background:var(--kh-cream);
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
}

/* --- Elements ------------------------------------------------------------- */

h1,h2,h3,h4{
  font-family:var(--font-display);
  font-weight:400;
  line-height:1.12;
}

h1{font-size:var(--step-3);}
h2{font-size:var(--step-2);}
h3{font-size:var(--step-1);}

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

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

/* The UA rule for [hidden] is display:none, and any author `display` beats it
   — a .btn or a grid container would stay on screen with the attribute set.
   Panels that JS shows and hides rely on this holding. */
[hidden]{
  display:none !important;
}

button,
input,
select,
textarea{
  font:inherit;
  color:inherit;
}

/* --- Utilities ------------------------------------------------------------ */

.accent-italic{
  display:block;
  font-style:italic;
  color:var(--kh-copper);
}

.eyebrow{
  font-size:var(--step--1);
  letter-spacing:.28em;
  text-transform:uppercase;
  color:var(--kh-muted);
}

.wrap{
  max-width:var(--wrap);
  margin-inline:auto;
  padding-inline:var(--gutter);
}

.section{
  padding-block:clamp(3.5rem,8vw,7rem);
}

.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;
}

/* --- Skip link ------------------------------------------------------------
   The first thing Tab reaches on every page. Parked above the viewport until
   it has focus, then drops in over the header — and over the intro curtain,
   which sits at 200. Logical inset, so it opens at the right under RTL. */

.skip-link{
  position:fixed;
  inset-block-start:calc(env(safe-area-inset-top, 0px) + .75rem);
  inset-inline-start:var(--gutter);
  z-index:300;
  padding:.75em 1.4em;
  border-radius:var(--radius-pill);
  background:var(--kh-espresso);
  color:var(--kh-cream);
  font-size:var(--step--1);
  transform:translateY(calc(-100% - 2rem));
  transition:transform .25s var(--ease);
}

.skip-link:focus{
  transform:none;
}

.skip-link:focus-visible{
  outline:2px solid var(--kh-copper-deep);
  outline-offset:3px;
}

/* <main> takes focus from the skip link so the next Tab continues inside it.
   A ring round the whole page body would read as a fault. */
main[tabindex="-1"]:focus{
  outline:none;
}

/* --- Scroll reveal -------------------------------------------------------- */

/* Revealed content is visible by default. main.js adds .is-armed to hide it,
   then .is-visible to play it — so a page whose module never runs, or is
   blocked, still shows everything. Only opacity and transform move, so this
   never touches layout.

   --i is the element's step within its own group, written by main.js and
   capped there so a long gallery cannot crawl. */
.reveal.is-armed{
  opacity:0;
  transform:translateY(20px);
  transition:
    opacity .7s var(--ease),
    transform .7s var(--ease);
  transition-delay:calc(var(--i, 0) * 70ms);
}

.reveal.is-armed.is-visible{
  opacity:1;
  transform:none;
}

/* Images fade in rather than popping. Armed by JS for the same reason, and
   only on images the reveal above is not already fading — two opacity
   transitions on one element read as a stutter. */
img.is-armed{
  opacity:0;
  transition:opacity .5s var(--ease);
}

img.is-armed.is-loaded{
  opacity:1;
}

/* --- Buttons -------------------------------------------------------------- */

.btn{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:.6em;
  padding:1.05em 2.4em;
  border:1px solid transparent;
  border-radius:var(--radius-pill);
  font-size:var(--step--1);
  letter-spacing:.2em;
  text-transform:uppercase;
  cursor:pointer;
}

.btn--primary{
  background:var(--kh-espresso);
  color:var(--kh-cream);
}

.btn--primary:hover{
  background:var(--kh-copper-deep);
}

.btn--ghost{
  background:transparent;
  border-color:var(--kh-line);
  color:var(--kh-espresso);
}

.btn--ghost:hover{
  background:var(--kh-sand);
}

/* --- Press feedback --------------------------------------------------------
   Every pressable face on the site presses the same way: a hard, blurless edge
   underneath at rest, deepened as the pointer approaches, collapsed while it
   is down. Flat rather than a raised bevel — the whole travel is four pixels,
   and what sells it is the face moving with the edge rather than any lighting.

   One rule for all five surfaces rather than a copy per component: the buttons,
   the header nav pills, the booking step pills, the booking date cards and the
   stars on the review form. A new pressable joins the selector lists. The three
   steps come from tokens, so a surface with no face of its own can shadow them
   locally instead of leaving the rule — see the nav pill at the end.

   Written here rather than in booking.css or review.css because base.css is
   the one stylesheet every page loads; the selectors that match nothing on a
   given page cost nothing.

   The transition is named rather than `all`: `all` also transitions inherited
   properties, so a button inside the mobile menu panel animates the panel's
   visibility flip and is briefly unfocusable while that runs.
   -------------------------------------------------------------------------- */

.btn,
.site-nav__link,
.pills__pill,
.dates__day,
.rating__star{
  box-shadow:var(--press-rest);
  transition:
    background-color .35s var(--ease),
    color .35s var(--ease),
    border-color .35s var(--ease),
    box-shadow .35s var(--ease),
    transform .35s var(--ease);
}

/* Hover-capable pointers only: on touch there is nothing to lift out of, and
   the lifted state would stick after the tap. The active nav pill is excluded
   because the pill it would lift off is the sliding indicator, which stays
   put — the label would come away from its own background. */
@media (hover:hover){
  .btn:hover,
  .site-nav__link:not([aria-current]):hover,
  .pills__pill:hover,
  .dates__day:hover,
  .rating__star:hover{
    transform:translateY(-2px);
    box-shadow:var(--press-lift);
  }
}

/* The press itself. :active is pointer-down on every device, so this is also
   what a tap gets. .12s rather than .35s: a press that takes a third of a
   second to land reads as the page hesitating, not as the control answering.
   Last of the press rules on purpose — it ties with the hover block on
   specificity and has to win while the pointer is down. */
.btn:active,
.site-nav__link:active,
.pills__pill:active,
.dates__day:active,
.rating__star:active{
  transform:translateY(1px);
  box-shadow:var(--press-down);
  transition-duration:.12s;
}

/* Two of the five have no face of their own — the nav pill is transparent at
   rest and only translucent on hover, and the rating star is a bare glyph in a
   padding box. An edge under either draws a card that is not there: five ghost
   tiles under the stars, and on the nav a shadow falling outside the bar's
   .35rem padding. They keep the travel, which is the half of this that says
   "pressed", and drop the edge until there is something to cast it. */
.site-nav__link,
.rating__star{
  --press-rest:none;
  --press-lift:none;
  --press-down:none;
}

/* --- RTL ------------------------------------------------------------------ */

[dir="rtl"] body{
  font-family:var(--font-ar);
}

/* Playfair has no Arabic glyphs — headings must not fall back to a random
   system face. Almarai carries the display sizes too. */
[dir="rtl"] h1,
[dir="rtl"] h2,
[dir="rtl"] h3,
[dir="rtl"] h4{
  font-family:var(--font-ar);
}

/* Almarai has no true italic, and synthesised oblique Arabic reads as a
   rendering fault. The accent keeps its colour, drops the slant. */
[dir="rtl"] .accent-italic{
  font-style:normal;
}

[dir="rtl"] .eyebrow{
  letter-spacing:0;
}

/* --- Motion preferences --------------------------------------------------- */

@media (prefers-reduced-motion:reduce){
  html{
    scroll-behavior:auto;
  }

  *,
  *::before,
  *::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    scroll-behavior:auto !important;
  }

  /* main.js does not arm anything under reduced motion, so these should never
     match. They are here so a preference that changes mid-session cannot strand
     content at opacity 0 or leave it displaced. */
  .reveal.is-armed,
  .reveal.is-armed.is-visible{
    opacity:1;
    transform:none;
    transition:none;
  }

  img.is-armed{
    opacity:1;
    transition:none;
  }

  /* Press feedback keeps its colours and loses its movement. The shadow step
     goes with it: a face that deepens its edge without rising is reporting a
     lift that never happens. */
  .btn:hover,
  .site-nav__link:hover,
  .pills__pill:hover,
  .dates__day:hover,
  .rating__star:hover,
  .btn:active,
  .site-nav__link:active,
  .pills__pill:active,
  .dates__day:active,
  .rating__star:active{
    transform:none;
    box-shadow:var(--press-rest);
  }
}
