/*
 * Booking wizard, and the appointment detail page that manages what it books.
 *
 * The wizard's own rules were transcribed from wireframes/appointment-booking.html until the v3
 * pass (2026-09-12) rebuilt the page on the site kit: its shell, stepper, calendar, time chips,
 * hold strip and review now live in the "v3 — booking" block at the foot of this file, and the
 * pre-v3 `.booking-*` rules they replaced are gone. Nothing outside page-booking.php and
 * assets/js/booking.js ever rendered them.
 *
 * The appointment-detail week/reschedule picker (`.appointment-week__*`, built at runtime by
 * assets/js/appointments.js) used to be styled here too — this file predates account.css's own
 * "Wave 3 — appointments" pass, which mirrored the same classes onto the kit look. That pass
 * folded the WHOLE component into account.css (day, dayhead, times, slot and its states, none, tz,
 * confirm, locks — every selector this file used to carry) but could not remove the original copy
 * here, since booking.css was not its file to touch. `account-appointment-detail` always loads
 * account.css after this one, so for months the two definitions have not disagreed by accident —
 * account.css's rule has simply always won, including its 44px slot floor over this file's 34px
 * one. Confirmed live (2026-09-26): the rendered `.appointment-week__slot` box matches account.css
 * byte for byte and never this file's numbers. Removed rather than left, because a dead second
 * definition of a live component is exactly the fork this project's had drift from before, and it
 * only takes an enqueue-order change to make the worse, sub-44px copy live again silently.
 */

/* ---------------------------------------------------------------------
 * v3 — booking. Ported from Claude outputs/design-system-v3/css/public-v3.css,
 * which is one file for every public surface; the theme serves them on different
 * routes, so it is split the way the site is actually loaded.
 * --------------------------------------------------------------------- */
.iz-cal { padding: var(--pad-row); border: 1px solid var(--iz-line-soft); border-radius: 20px; background: #fff; }
.iz-cal__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-2); }
/* The calendar head names a month, not a headline, so it is off Pinar and onto the h4 rung's own
   size — the largest thing in this small card without borrowing the display face. */
.iz-cal__head b { color: var(--iz-ink); font-family: var(--font-body); font-size: var(--text-h4-size); line-height: var(--text-h4-lh); font-weight: 600; }
.iz-cal__grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: var(--space-0); }
.iz-cal__dow { padding: var(--space-0) 0; color: var(--iz-ink-soft); font: var(--text-micro); text-align: center; }
/* min-height is the floor a narrow phone actually hits: at 320–390px the seven-column grid's own
 * fr tracks compute to 33–41px, below it, and this is what brings a tapped day up to 44px there.
 * From roughly 400px up the track itself already clears 44px and the rule does nothing — measured
 * at 320/375/800/1280, no width where it forces a size past its own 7-column row (docs/decisions.md
 * 2026-09-26). */
.iz-cal__day { position: relative; display: grid; place-items: center; aspect-ratio: 1; min-height: 44px; border: 0; border-radius: 12px; background: none; color: var(--iz-ink); font-family: var(--font-body); font-size: var(--text-body-s-size); line-height: 1; font-weight: 700; font-variant-numeric: tabular-nums; cursor: pointer; transition: background-color .16s var(--iz-ease), color .16s var(--iz-ease), transform .16s var(--iz-ease-out); }
.iz-cal__day.is-free::after { content: ""; position: absolute; bottom: 6px; width: 5px; height: 5px; border-radius: 50%; background: var(--secondary-500); }
/* A disabled day's number is the only way to orient inside the month, and most of a month is
 * disabled — everything before today. #c3cfd1 on white is about 1.5:1, which is not readable;
 * --iz-ink-soft is the site's floor for text on a light ground and is what these use now. The
 * three disabled reasons stay distinguishable by what is drawn, not by three greys: a full day is
 * struck through, an unavailable one is plain, a past one is plain and behind the month's start. */
.iz-cal__day:disabled { color: var(--iz-ink-soft); cursor: default; }
/* After :disabled, not before it. Both selectors are (0,2,0) and every full day is also disabled,
 * so the later rule wins — declared first, this colour never applied at all. */
.iz-cal__day.is-full { color: var(--iz-ink-soft); text-decoration: line-through; cursor: not-allowed; }
.iz-cal__day.is-today { box-shadow: 0 0 0 1.5px var(--primary-200) inset; }
.iz-cal__day[aria-pressed="true"] { background: var(--secondary-500); color: #fff; }
.iz-cal__day[aria-pressed="true"]::after { background: #fff; }
.iz-cal__day:active:not(:disabled) { transform: scale(var(--iz-press)); }
.iz-cal__day:focus-visible { outline: none; box-shadow: var(--iz-focus); }
@media (hover: hover) and (pointer: fine) {
	.iz-cal__day.is-free:not([aria-pressed="true"]):hover { background: var(--secondary-50); }
}
.iz-hold { display: flex; align-items: center; gap: var(--gap-inline); padding: var(--space-2) var(--pad-row); border-radius: 14px; background: var(--secondary-50); color: var(--secondary-700); font: var(--text-body-s); }
/* The countdown figure inside the strip is a number, weight 700. */
.iz-hold b { font-weight: 700; }

/* ------------------------------------------------------------- the wizard's shell
 * One centred column. The pre-v3 page was a .75fr/1.25fr split whose left rail spelled the four
 * steps out in prose beside a progress bar that already named them, and its own 1240px container
 * meant the site header had to be widened to match; both are gone, so the page lines up with
 * --chrome-width like every other page and the wizard is centred inside it. */
.booking-shell { display: grid; width: var(--chrome-width); margin-inline: auto; gap: var(--space-head); padding-block-end: var(--space-band); }
.booking-shell > * { min-width: 0; }
.booking-flow { display: grid; gap: var(--space-block); width: 100%; max-width: 880px; margin-inline: auto; }
/* The vine over the stepper — the pattern book's own proportions. */
.booking-vine { width: min(420px, 78%); height: 76px; justify-self: center; }

.booking-step { display: none; }
.booking-step.is-active { display: grid; gap: var(--gap-form); }
.booking-step > * { min-width: 0; }
/* H2-09: booking.js gives each step `tabindex="-1"` and focuses it after Next/Back/«تغییر» so
 * keyboard and screen-reader focus lands on the step that just appeared instead of a button that
 * just became `display: none`. It is a landing target, not a control, so no ring — the same
 * courtesy-focus pattern `data-status` and the hold strip already use without one. */
.booking-step:focus { outline: none; }
@media (prefers-reduced-motion: no-preference) {
	.booking-step.is-active { animation: booking-in .32s var(--iz-ease-out); }
	@keyframes booking-in { from { opacity: 0; translate: 0 8px; } to { opacity: 1; translate: none; } }
}

.booking-two { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--gap-form) var(--gap-grid); }
.booking-actions { display: flex; align-items: center; justify-content: space-between; gap: var(--gap-inline); }
.booking-inline-actions { display: flex; align-items: center; gap: var(--gap-inline); flex-wrap: wrap; }

/* booking.js writes the message straight into this element, so it stays a plain box rather than
   the kit notice's icon/body/action grid. */
.booking-error { padding: var(--pad-row); border-radius: 14px; background: var(--tone-attention-bg); color: var(--tone-attention-fg); font: var(--text-body-s); }

/* ------------------------------------------------------------- step 2: date and time */
.booking-when { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--gap-grid); align-items: start; }
.booking-availability { display: grid; gap: var(--space-stack); align-content: start; }
/* The month grid's legend. v3 marks a free day with a dot and strikes a full one through, so each
   sample here is that idiom itself — at --iz-ink-soft, because these are labels to read and not
   disabled controls. A day that is simply not offered carries no mark, which is what it looks
   like. */
.booking-cal__key { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-0) var(--space-3); margin: var(--space-stack) 0 0; color: var(--iz-ink-soft); font: var(--text-micro); }
.booking-cal__key span { display: inline-flex; align-items: center; gap: var(--space-0); }
.booking-cal__key .is-free::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: var(--secondary-500); }
.booking-cal__key .is-full { text-decoration: line-through; }
/* Both placeholders are `.iz-skel` in the markup; these give them their size. */
.booking-cal__loading { grid-column: 1 / -1; height: 132px; border-radius: 14px; }
.booking-skeleton { height: 44px; border-radius: 12px; }

/* The time chips. These six rules are the v3 reference's own and are byte-identical to the copy in
 * account.css: the reference file carried them under the account pages, the split followed it, and
 * /booking/ never loads account.css. They are a shared component and belong in kit.css beside the
 * calendar's neighbours — flagged in the wave 5 report rather than moved, because kit.css is off
 * limits to this pass. */

/* ------------------------------------------------------------- step 3 and 4 */
.booking-auth { display: grid; gap: var(--gap-form); }
.booking-auth__state { display: none; }
.booking-auth__state.is-active { display: grid; gap: var(--space-3); }
/* H2 slice A: .booking-two is reused as the inline sign-in's name-fields wrapper
 * (data-auth-names), shown only once otp/request answers will_register — same trap forum.css's
 * .forum-auth__two[hidden] documents: the [hidden] attribute's own `display: none` is user-agent
 * origin, and this rule's own `display: grid` is author origin, so without this line the fields
 * would render even while `hidden` is set. */
.booking-two[hidden] { display: none; }
/* The inline sign-in's two hidden hand-off links (two_factor_password_required,
 * verify_phone_to_hold) are plain `.iz-link`s, which the kit sets to `display: inline-flex` — the
 * same author-origin-beats-[hidden] trap as above, scoped to this block rather than fixed on the
 * shared kit class (out of this slice's file list). */
.booking-auth .iz-link[hidden] { display: none; }
.booking-hold b { font-variant-numeric: tabular-nums; }
/* The «not guaranteed» line belongs to the strip above it, not to the review below. */
.booking-hold-note { margin-block-start: calc(-1 * var(--space-3)); } /* the step's gap less this is --gap-field */
.booking-policy-link { margin: 0; }

/* The agreement block (H2 slice A): new relative to the pre-adoption page, which only linked out
 * to the standalone policy page — wireframes/appointment-booking.html's own step 4 always asked
 * for an inline checkbox. The six titled sections sit inside a native <details>, collapsed by
 * default, rather than always open: the review step's job is to confirm four or five already-made
 * choices, and dropping six full policy sections into it unconditionally would bury that under
 * text most visitors have already read once (the minimal-design direction, decisions.md
 * 2026-09-27). <details> needs no JavaScript and no custom open/close motion — the toggle is
 * occasional (once per booking) and the native disclosure already reads correctly in RTL. */
.booking-agreement { display: grid; gap: var(--space-1); }
.booking-policy-sections summary { color: var(--secondary-700); font: var(--text-body-s); cursor: pointer; }
.booking-policy-sections summary:focus-visible { outline: none; box-shadow: var(--iz-focus); border-radius: 6px; }
.booking-policy-sections[open] summary { margin-block-end: var(--space-1); }
/* Flow content (policy text), so margins. 600: IRANSans 700 is for numerals. */
.booking-policy-sections h4 { margin: var(--space-3) 0 var(--gap-title); color: var(--iz-ink); font: var(--text-body-s); font-weight: 600; }
.booking-policy-sections p { margin: 0 0 var(--space-2); color: var(--iz-text); font: var(--text-body-s); }
/* The checkbox: a native input plus its own label text, the same reasoning auth.css's
 * .auth__remember gives itself — a single yes/no next to a sentence, not the choice-chip
 * component this site uses for picking one of several options. */
.booking-agree { display: flex; align-items: center; gap: var(--gap-inline); min-height: 44px; color: var(--iz-ink); font: var(--text-body-s); cursor: pointer; }
.booking-agree input { flex: none; width: 20px; height: 20px; accent-color: var(--primary-600); }
.booking-agree input:focus-visible { outline: none; box-shadow: var(--iz-focus); }

@media (max-width: 860px) {
	.booking-when { grid-template-columns: minmax(0, 1fr); }
}

/* ------------------------------------------------------------- step 1, two fields to a row
 * Owner, 2026-09-29: "consider having 2 inputs in a row and notes in the last row". From 761px the
 * step's fields sit two to a row; the notes textarea, the step's buttons and the no-availability
 * notice each take a full row. `align-items: start` because the help lines under two neighbours
 * are different lengths and a stretched field would part its label from its control. One column
 * below that, which is the rule above unchanged. Scoped to step 1: the other steps hold a calendar,
 * a sign-in and a review, not a form of fields. */
@media (min-width: 761px) {
	.booking-step[data-step="1"].is-active { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--gap-grid); align-items: start; }
	.booking-step[data-step="1"] > :not(.iz-field), .booking-step[data-step="1"] > .iz-field:has(textarea) { grid-column: 1 / -1; }
}

@media (max-width: 520px) {
	.booking-two { grid-template-columns: minmax(0, 1fr); }
	.booking-vine { height: 62px; }
}
