/* ==========================================================================
   KH Haircare — booking flow
   Styles for booking.html only, loaded after layout.css. Nothing in here is
   used by any other page, which is why it is a separate sheet.

   Page heading and step bar · form fields · pill groups · date strip ·
   slot grid · phone field · summary card · deposit · return notice ·
   success panel

   The form primitives (.field and friends) are stated here rather than shared
   with review.css: the two sheets are never loaded together, and each page
   owns the form on it.
   ========================================================================== */


/* ==========================================================================
   PAGE
   No hero here, so the first block clears the fixed header itself — the same
   arrangement as .review-intro and .about-intro.
   ========================================================================== */

.booking{
  padding-block:calc(var(--header-h) + clamp(1.5rem,4vw,2.5rem)) clamp(3rem,7vw,5rem);
}

/* Back on the inline start, the counter on the inline end. Both mirror with
   the writing direction because the row is flex and nothing in it is pinned
   to a physical side. */
.booking__bar{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:1rem;
  min-block-size:2.25rem;
  margin-block-end:.75rem;
}

.booking__back{
  display:inline-flex;
  align-items:center;
  gap:.5rem;
  padding:.4rem .2rem;
  background:none;
  border:0;
  font-size:var(--step--1);
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--kh-muted);
  cursor:pointer;
  transition:color .35s var(--ease);
}

.booking__back:hover{
  color:var(--kh-copper-deep);
}

.booking__back-icon{
  inline-size:var(--icon-sm);
  block-size:var(--icon-sm);
}

/* The arrow points at the inline start, which is the opposite physical
   direction in Arabic. */
[dir="rtl"] .booking__back-icon{
  transform:scaleX(-1);
}

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

/* The counter is the only thing left on the row on step 1, and it belongs at
   the end of it either way. */
.booking__progress{
  margin-inline-start:auto;
}

/* Below the hero's --step-3, matching .review-intro__title: this is a page
   heading, not a headline. */
.booking__title{
  font-size:var(--step-2);
  margin-block-end:clamp(1.5rem,4vw,2.25rem);
}


/* ==========================================================================
   FORM
   One column throughout. The steps are stacked in the document and all but
   one carries the hidden attribute, so nothing the visitor typed is ever
   taken out of the DOM.
   ========================================================================== */

.booking-form{
  display:grid;
  gap:1.5rem;
  max-inline-size:var(--field);
}

.booking-step{
  display:grid;
  gap:1.5rem;
  /* Grid tracks would otherwise take their width from the widest child, and
     the date strip is far wider than the page at 360px. */
  min-inline-size:0;
}

.booking-step__title{
  font-size:var(--step-1);
  color:var(--kh-espresso);
}

/* The heading takes focus on every step change so a screen reader lands on
   the new step rather than staying where the button was. The ring that comes
   with that would read as an error on a piece of static copy. */
.booking-step__title:focus{
  outline:none;
}


/* ==========================================================================
   FIELDS
   ========================================================================== */

.field{
  /* Fieldsets carry an intrinsic minimum width that ignores the grid track,
     which is exactly how a form starts overflowing at 360px. */
  min-inline-size:0;
  border:0;
  padding:0;
}

.field__label{
  display:block;
  margin-block-end:.5rem;
  padding:0;                     /* legend */
  font-size:var(--step--1);
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--kh-muted);
}

.field__control{
  inline-size:100%;
  padding:.8em 1em;
  background:var(--kh-ivory);
  border:1px solid var(--kh-line);
  border-radius:var(--radius-sm);
  color:var(--kh-ink);
  transition:border-color .35s var(--ease);
}

.field__control::placeholder{
  color:var(--kh-muted);
}

.field__control:hover{
  border-color:var(--kh-hairline);
}

.field__control--area{
  resize:vertical;
  min-block-size:6.5rem;
  line-height:1.7;
}

/* Never display:none. These are aria-live regions, and a region that is not
   in the accessibility tree at the moment its text changes is not announced.
   An empty <p> generates no line box, so it costs nothing while it is
   silent — only the margin is held back until there is something to
   separate. */
.field__error,
.booking-form__status,
.slots__note{
  font-size:var(--step--1);
}

.field__error,
.booking-form__status{
  color:var(--kh-copper-deep);
}

.field__error:not(:empty){
  margin-block-start:.5rem;
}

.booking-form__status:not(:empty){
  padding:.8em 1em;
  background:var(--kh-sand);
  border-radius:var(--radius-sm);
}

.field.has-error .field__control{
  border-color:var(--kh-copper-deep);
}

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


/* ==========================================================================
   PILLS
   Single-select groups drawn over real radios. Nothing here depends on a
   click handler: the inputs carry the state, the CSS reads it, and arrow-key
   navigation is the browser's own.
   ========================================================================== */

.pills{
  display:flex;
  flex-wrap:wrap;
  gap:.5rem;
}

.pills__pill{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  padding:.55em 1.4em;
  background:var(--kh-ivory);
  border:1px solid var(--kh-line);
  border-radius:var(--radius-pill);
  font-size:var(--step--1);
  color:var(--kh-espresso);
  cursor:pointer;
  /* Colour, border and press transitions all come from the shared press rule
     in base.css. Restating them here would only override it and drop the
     transform and the shadow back out. */
}

@media (hover:hover){
  .pills__pill:hover{
    border-color:var(--kh-copper);
  }
}

.pills__input:checked + .pills__pill{
  background:var(--kh-copper);
  border-color:var(--kh-copper);
  color:var(--kh-ivory);
}

/* The radio is .sr-only and still the focusable control, so the ring it would
   have drawn is moved onto the pill the visitor can actually see. */
.pills__input:focus-visible + .pills__pill{
  outline:2px solid var(--kh-copper-deep);
  outline-offset:2px;
}


/* ==========================================================================
   DATE STRIP
   Fourteen days on one scrolling, snapping row. As flex items in the document
   flow the cards lay out along the writing direction, so in Arabic the strip
   starts from the right and scrolls the other way with no rules of its own.
   ========================================================================== */

.dates{
  display:flex;
  gap:.5rem;
  /* The strip is the one thing on the page wider than the page. It scrolls
     inside itself; the padding keeps the focus ring and the snap edge off
     the gutter. */
  overflow-x:auto;
  scroll-snap-type:x mandatory;
  padding-block-end:.6rem;
  -webkit-overflow-scrolling:touch;
  scrollbar-width:thin;
}

.dates__day{
  display:flex;
  flex:0 0 var(--date-card);
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap:.1rem;
  block-size:var(--date-card-h);
  padding:.5rem .25rem;
  background:var(--kh-ivory);
  border:1px solid var(--kh-line);
  border-radius:var(--radius-sm);
  scroll-snap-align:start;
  cursor:pointer;
  /* Transitions come from the shared press rule in base.css — see .pills__pill
     above. The card's own labels keep their colour transitions below. */
}

@media (hover:hover){
  .dates__day:hover{
    border-color:var(--kh-copper);
  }
}

.dates__weekday,
.dates__month{
  font-size:var(--step--1);
  line-height:1.2;
  color:var(--kh-muted);
  transition:color .35s var(--ease);
}

.dates__number{
  font-size:var(--step-1);
  line-height:1.2;
  color:var(--kh-ink);
  font-variant-numeric:tabular-nums;
  transition:color .35s var(--ease);
}

.dates__input:checked + .dates__day{
  background:var(--kh-copper);
  border-color:var(--kh-copper);
}

.dates__input:checked + .dates__day .dates__weekday,
.dates__input:checked + .dates__day .dates__month,
.dates__input:checked + .dates__day .dates__number{
  color:var(--kh-ivory);
}

.dates__input:focus-visible + .dates__day{
  outline:2px solid var(--kh-copper-deep);
  outline-offset:2px;
}


/* ==========================================================================
   SLOTS
   Three columns on a desktop, two on a phone. Only free times are returned,
   so every button drawn here is bookable.
   ========================================================================== */

.slots{
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
  gap:.5rem;
}

/* Empty on the loading, error and no-times states — the note below carries
   the message, and an empty grid should take up no room. */
.slots:empty{
  display:none;
}

.slots__slot{
  display:flex;
  align-items:center;
  justify-content:center;
  padding:.7em .5em;
  background:var(--kh-ivory);
  border:1px solid var(--kh-line);
  border-radius:var(--radius-sm);
  font-size:var(--step--1);
  color:var(--kh-espresso);
  font-variant-numeric:tabular-nums;
  cursor:pointer;
  transition:
    background-color .35s var(--ease),
    border-color .35s var(--ease),
    color .35s var(--ease);
}

@media (hover:hover){
  .slots__slot:hover{
    border-color:var(--kh-copper);
  }
}

.slots__input:checked + .slots__slot{
  background:var(--kh-copper);
  border-color:var(--kh-copper);
  color:var(--kh-ivory);
}

.slots__input:focus-visible + .slots__slot{
  outline:2px solid var(--kh-copper-deep);
  outline-offset:2px;
}

/* Loading, "no times available", and the failure line all land here. Quiet by
   default; the failure state colours it and adds the retry button. */
.slots__note{
  color:var(--kh-muted);
}

.slots__note:not(:empty){
  margin-block-start:.25rem;
}

.slots__note.is-error{
  color:var(--kh-copper-deep);
}

.slots__retry{
  margin-block-start:.75rem;
  padding:.6em 1.6em;
}


/* ==========================================================================
   PHONE
   Country selector then the number. Flex, so the pair swaps sides in Arabic
   along with everything else.
   ========================================================================== */

.phone{
  display:flex;
  gap:.5rem;
}

.phone__country{
  flex:0 1 var(--country);
  min-inline-size:0;
  /* The list is long and the names can be, so let the option text be clipped
     rather than let the control set the row's width. */
  text-overflow:ellipsis;
}

.phone__number{
  flex:1 1 auto;
  min-inline-size:0;
}


/* ==========================================================================
   SUMMARY
   The request, when it is, who it is for and where. No price and no
   duration — the final price is agreed over WhatsApp, and only the deposit
   below is paid on this page.
   ========================================================================== */

.summary{
  display:grid;
  gap:.9rem;
  padding:clamp(1.25rem,3vw,1.75rem);
  background:var(--kh-cream);
  border:1px solid var(--kh-hairline);
  border-radius:var(--radius);
}

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

.summary__value{
  margin-block-start:.15rem;
  color:var(--kh-ink);
  /* A pasted address or an unbroken word would otherwise push the card wider
     than its column and take the page into horizontal scroll. */
  overflow-wrap:anywhere;
  white-space:pre-line;
}

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


/* ==========================================================================
   CONSENT
   The reminder checkbox under the summary. An ordinary label at body size in
   ink — it reads as part of the form, not as fine print. The focus ring comes
   from the FOCUS block below, like every other control here. Logical
   properties throughout, so the box sits on the right under RTL.
   ========================================================================== */

.consent{
  margin-block-start:1.5rem;
}

.consent__row{
  display:flex;
  align-items:flex-start;
  gap:.75rem;
}

/* Native box, tinted to the palette. The small top margin sits it on the
   first line of the label rather than the middle of a wrapped one. */
.consent__input{
  flex:none;
  inline-size:var(--checkbox);
  block-size:var(--checkbox);
  margin:.2em 0 0;
  accent-color:var(--kh-copper-deep);
  cursor:pointer;
}

.consent__label{
  font-size:var(--step-0);
  color:var(--kh-ink);
  cursor:pointer;
}

/* Indented to start under the label text, not under the box. */
.consent__hint{
  margin-block-start:.35rem;
  padding-inline-start:calc(var(--checkbox) + .75rem);
  font-size:var(--step--1);
  color:var(--kh-muted);
}

.consent__link{
  margin-inline-start:.5rem;
  color:var(--kh-copper-deep);
  text-decoration:underline;
  text-underline-offset:.2em;
}


/* ==========================================================================
   DEPOSIT
   Under the reminder, set off by a hairline: the last thing read before the
   pay button. The Stripe line is fine print, the amount is not.
   ========================================================================== */

.deposit{
  display:grid;
  gap:.6rem;
  padding-block-start:1.5rem;
  border-block-start:1px solid var(--kh-hairline);
}

.deposit__title{
  font-size:var(--step-0);
  font-weight:500;
  color:var(--kh-espresso);
}

.deposit__text{
  font-size:var(--step-0);
  color:var(--kh-ink);
}

.deposit__text.is-error{
  color:var(--kh-copper-deep);
}

.deposit__retry{
  justify-self:start;
  padding:.6em 1.6em;
}

.deposit__note{
  font-size:var(--step--1);
  color:var(--kh-muted);
}

.deposit__link{
  margin-inline-start:.35rem;
  color:var(--kh-copper-deep);
  text-decoration:underline;
  text-underline-offset:.2em;
}


/* ==========================================================================
   RETURN
   Back from Stripe. The notice sits over the form when a booking is put back
   unpaid; the panel stands in for the form while a payment is confirmed, and
   stays when the answer is not a booking. Both quiet: nothing here is the
   visitor's mistake.
   ========================================================================== */

/* Never display:none — it is a live region, like .booking-form__status. */
.booking-notice{
  max-inline-size:var(--field);
  font-size:var(--step--1);
  color:var(--kh-espresso);
}

.booking-notice:not(:empty){
  margin-block-end:1.5rem;
  padding:.8em 1em;
  background:var(--kh-blush);
  border:1px solid var(--kh-hairline);
  border-radius:var(--radius-sm);
}

.booking-return{
  display:grid;
  gap:1.5rem;
  max-inline-size:var(--field);
  padding-block:clamp(.5rem,2vw,1rem);
}

.booking-return__text{
  color:var(--kh-muted);
}

.booking-return__whatsapp{
  justify-self:start;
}


/* ==========================================================================
   SUBMIT
   ========================================================================== */

.booking-form__next{
  justify-self:start;
}

.booking-form__next[disabled]{
  opacity:.6;
  cursor:progress;
}

/* Disabled but not busy: waiting on the deposit amount, not on a request. */
.booking-form__next[disabled][aria-busy="false"]{
  cursor:not-allowed;
}

.booking-form__next[disabled]:hover{
  background:var(--kh-espresso);
  transform:none;
}


/* ==========================================================================
   SUCCESS
   Replaces the form in place — no reload, and nothing about approval: the
   slot is taken the moment the POST comes back.
   ========================================================================== */

.booking-success{
  max-inline-size:var(--field);
  padding-block:clamp(1rem,3vw,2rem);
}

.booking-success__title{
  font-size:var(--step-2);
}

.booking-success__title:focus{
  outline:none;
}

.booking-success__body{
  margin-block-start:.75rem;
  color:var(--kh-muted);
}

.booking-success__when{
  margin-block-start:1.25rem;
  font-size:var(--step-1);
  font-family:var(--font-display);
  color:var(--kh-ink);
}

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

.booking-success__countdown{
  margin-block-start:1rem;
  color:var(--kh-muted);
}

/* The primary button and the Stay text button share a row while they fit,
   and Stay drops under it on a phone. Flex follows the writing direction, so
   the button leads at the right in Arabic with nothing mirrored by hand. */
.booking-success__actions{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  gap:1rem 1.5rem;
  margin-block-start:2rem;
}

.booking-success__stay{
  padding:.4rem .2rem;
  background:none;
  border:0;
  font-size:var(--step--1);
  color:var(--kh-muted);
  text-decoration:underline;
  text-underline-offset:.25em;
  cursor:pointer;
  transition:color .35s var(--ease);
}

.booking-success__stay:hover{
  color:var(--kh-copper-deep);
}


/* ==========================================================================
   FOCUS
   base.css leaves the UA ring in place; the form is where it has to be
   deliberate, so it is stated once here for everything on this page.
   ========================================================================== */

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

.field__control:focus-visible{
  outline-offset:0;
  border-color:var(--kh-copper);
}


/* ==========================================================================
   WIDER THAN A PHONE
   ========================================================================== */

@media (min-width:600px){
  .slots{
    grid-template-columns:repeat(3,minmax(0,1fr));
  }
}
