/* ============================================================
   DJ WIZ HOFFA — BOOK page layout
   css/pages/book.css?v=4 — loads after tokens.css + site.css.
   Page-owned classes are prefixed bk- / f- (form). No shell
   overrides, no token changes. Contrast law respected: crimson
   is surface/accent only, never copy.

   TOC:
   01 Hero                    05 Form controls
   02 What-you-get grid       06 Wizard chrome (progress/nav)
   03 Event-type rows         07 Review + confirmation
   04 Form shell + steps      08 Process / payment / closing
   ============================================================ */

/* Safety: hidden always wins over any display rule below */
[hidden] { display: none !important; }

/* ---------- 01 Hero ---------- */
.bk-hero {
  position: relative;
  padding-top: calc(var(--header-h) + clamp(3rem, 8vw, 5.5rem));
  padding-bottom: clamp(3rem, 7vw, 5rem);
}

.bk-hero-grid {
  display: grid;
  gap: var(--sp-7);
  align-items: center;
}

@media (min-width: 980px) {
  .bk-hero-grid {
    grid-template-columns: 1.15fr 0.85fr;
    gap: clamp(3rem, 6vw, 5.5rem);
  }
}

/* The hero is hand-built and skips .sect-head, so the house eyebrow→title
   rhythm (.sect-head gives the eyebrow a sp-4 bottom margin) is lost under the
   global `* { margin:0 }` reset. Restore it here so the conversion page's very
   first block breathes like every section below it. */
.bk-hero-copy .eyebrow { margin-bottom: var(--sp-4); }

.bk-hero-title {
  font-size: clamp(2.9rem, 9.5vw, 7.25rem);
  max-width: 12ch;
}

.bk-kicker {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  margin-top: var(--sp-5);
  font-family: var(--font-label);
  font-weight: 600;
  font-size: clamp(1rem, 1.6vw, 1.25rem);
  text-transform: uppercase;
  letter-spacing: var(--ls-eyebrow);
  color: var(--ivory-80);
}

.bk-kicker::before {
  content: "";
  width: 34px;
  height: 2px;
  background: var(--crimson);
  flex: none;
}

.bk-hero-lead { margin-top: var(--sp-5); }

.bk-hero-cta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-4);
  margin-top: var(--sp-6);
}

.bk-hero-note {
  margin-top: var(--sp-5);
  font-size: var(--fs-small);
  color: var(--smoke);
}

/* Portrait — framed.
   The offset crimson hairline that used to live here (a ::after inset
   top/right +16, left/bottom -16) has been removed. It could not read as
   an intentional offset frame:
     · its box was the FIGURE, so it enclosed the figcaption and its bottom
       rule landed below the caption rather than behind the photograph;
     · its top and right edges hid behind the photo while the left edge
       terminated in mid-air, so the only reliable ink was a naked vertical
       crimson line 16px off the photo's left edge;
     · motion.js drives the img at data-parallax="0.15", which renders it at
       scale(1.06) — at 460px that grows the photo ~13.8px per side and eats
       the 16px offset by a scroll-dependent amount, so the sliver's width
       changed as the page moved.
   Binding it correctly needs a wrapper element around the img alone, which
   is a markup restructure and out of scope for a polish pass. The photo
   already carries a --line-strong border, radius and --shadow-2, and the
   hero's crimson accent is carried by .bk-kicker::before. */
.bk-hero-figure {
  position: relative;
  max-width: 460px;
  margin-inline: auto;
  width: 100%;
}

.bk-hero-figure img {
  width: 100%;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-2);
}

.bk-hero-caption {
  margin-top: var(--sp-4);
  font-family: var(--font-label);
  font-weight: 500;
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: var(--ls-eyebrow);
  color: var(--smoke);
}

/* Proof strip */
.bk-proof {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3) var(--sp-6);
  margin-top: clamp(3rem, 6vw, 4.5rem);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--line);
}

.bk-proof li {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  font-family: var(--font-label);
  font-weight: 500;
  font-size: var(--fs-small);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--smoke);
}

.bk-proof li::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--crimson);
  flex: none;
}

/* ---------- 02 What-you-get grid ---------- */
.bk-get { gap: var(--sp-6) var(--sp-7); }

@media (min-width: 768px) { .bk-get { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 980px) { .bk-get { grid-template-columns: repeat(3, 1fr); } }

.bk-get-item {
  border-top: 1px solid var(--line);
  padding-top: var(--sp-5);
}

.bk-get-num {
  display: block;
  font-family: var(--font-logo);
  font-size: 1.5rem;
  line-height: 1;
  color: var(--crimson);          /* decorative numeral, aria-hidden */
  margin-bottom: var(--sp-4);
}

.bk-get-item h3 {
  font-family: var(--font-label);
  font-weight: 600;
  /* Matched to .bk-proc-item h3 (1.1rem) so the two numbered card grids on
     this page share one title size — Event-Types' large Anton names stay the
     deliberate editorial outlier. */
  font-size: 1.1rem;
  letter-spacing: 0.06em;
}

.bk-get-item p {
  margin-top: var(--sp-3);
  font-size: var(--fs-small);
  color: var(--ivory-60);
  max-width: 34ch;
}

/* ---------- 03 Event-type rows ---------- */
.bk-types { border-bottom: 1px solid var(--line); }

.bk-type-row {
  display: grid;
  grid-template-columns: 3rem 1fr;
  gap: var(--sp-2) var(--sp-5);
  align-items: baseline;
  border-top: 1px solid var(--line);
  /* Cindy §23, mobile only: at 360 the description drops under the name and
     the intra-row gap (~23px) was within 12px of the inter-row gap (~35px),
     so each description read as floating between two rows instead of
     belonging to the name above it, across all 7 event types. Opening the
     row padding puts the outside gap at ~2x the inside gap (48 vs 23 at
     360). The 1440 value is unchanged at 1.8rem — desktop is untouched. */
  padding-block: clamp(1.5rem, 4.5vw, 1.8rem);
  transition: background var(--dur-1) var(--ease);
}

/* 2% ivory on near-black was perceptually invisible — the hover read as dead.
   4% actually registers while staying restrained. */
.bk-type-row:hover { background: color-mix(in srgb, var(--ivory) 4%, transparent); }

@media (min-width: 768px) {
  .bk-type-row {
    grid-template-columns: 3.5rem minmax(0, 1.05fr) minmax(0, 1fr);
    align-items: baseline;
  }
}

.bk-type-num {
  font-family: var(--font-logo);
  font-size: 1.15rem;
  color: var(--smoke);
}

.bk-type-name {
  font-size: clamp(1.5rem, 3.6vw, 2.7rem);
  letter-spacing: 0.015em;
}

.bk-type-desc {
  grid-column: 2;
  color: var(--ivory-60);
  font-size: var(--fs-small);
  max-width: 44ch;
}

@media (min-width: 768px) {
  .bk-type-desc { grid-column: 3; justify-self: end; text-align: right; }
}

/* ---------- 04 Form shell + steps ---------- */
/* Cindy §20 gradient rhythm: 7,518px of scroll at effectively one value.
   --bg vs --bg-2 is 1.03:1, so .sect--band reads only via its hairlines,
   and sections 3 and 4 were back-to-back untinted slabs totalling 2,929px
   — section 4 being the FORM, the money moment, with zero lift. Uses the
   already-in-markup but styleless .bk-form-sect hook (book.html:208), so
   this is additive and zero-ripple. Net effect: the form becomes the
   brightest point of the scroll. */
.bk-form-sect {
  background:
    radial-gradient(90% 55% at 50% 0%,
      color-mix(in srgb, var(--ivory) 5%, transparent), transparent 70%),
    var(--bg);
}

.bk-shell {
  background: linear-gradient(to bottom, var(--panel-2), var(--panel) 45%);
  border: 1px solid var(--line);
  border-top: 3px solid var(--crimson);
  border-radius: var(--r-md);
  padding: clamp(1.25rem, 4vw, 3rem);
  /* A pure-black drop shadow is invisible on the near-black ground; the inset
     hairline highlight lights the top edge so the black-glass card separates
     from the surface. */
  box-shadow: var(--shadow-2), inset 0 1px 0 color-mix(in srgb, var(--ivory) 6%, transparent);
}

/* No-JS document flow: steps stack with rules between them */
.bk-step + .bk-step {
  margin-top: var(--sp-8);
  border-top: 1px solid var(--line);
  padding-top: var(--sp-7);
}

/* Wizard mode (JS adds .is-wizard): one step on screen at a time, so the
   between-steps rule and gap must go — an adjacent sibling that is
   display:none still triggers `+`, which otherwise leaves a stray hairline
   and ~7rem of dead space above every step after the first. */
.bk-shell.is-wizard .bk-step + .bk-step {
  margin-top: 0;
  border-top: 0;
  padding-top: 0;
}

fieldset.bk-step,
.f-group {
  border: 0;
  padding: 0;
  margin: 0;
  min-width: 0;
}

.bk-legend,
.bk-review-title {
  display: flex;
  align-items: baseline;
  gap: var(--sp-4);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.5rem, 3vw, 2.1rem);
  text-transform: uppercase;
  letter-spacing: 0.01em;
  line-height: var(--lh-tight);
  color: var(--ivory);
  padding: 0;
  margin-bottom: var(--sp-6);
  width: 100%;
}

.bk-legend:focus-visible,
.bk-review-title:focus-visible {
  outline: 2px solid var(--ivory);
  outline-offset: 4px;
}

.bk-legend-num {
  font-family: var(--font-logo);
  font-size: 0.8em;
  color: var(--crimson);          /* decorative numeral, aria-hidden */
}

.bk-fields {
  display: grid;
  gap: var(--sp-6);
}

.f-duo { display: grid; gap: var(--sp-6); }

@media (min-width: 768px) {
  .f-duo { grid-template-columns: 1fr 1fr; gap: var(--sp-5); }
}

/* ---------- 05 Form controls ---------- */
.f-field { display: grid; gap: var(--sp-3); }

.f-label {
  display: block;
  font-family: var(--font-label);
  font-weight: 600;
  font-size: 0.95rem;
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--ivory-80);
}

.f-label .req { color: var(--ivory-60); }

.f-hint-inline {
  font-weight: 400;
  color: var(--smoke);
  letter-spacing: 0.08em;
  text-transform: none;
  font-size: 0.9rem;
}

/* Cindy §22: --smoke is reserved for tertiary text 14px+. This carries real
   budget guidance ("Your quote comes after review — this just helps shape
   the conversation"), which is not tertiary. 15px lifts it to 6.2:1. */
.f-hint {
  font-size: var(--fs-small);
  color: var(--smoke);
}

.f-input,
.f-select,
.f-area {
  width: 100%;
  min-height: 48px;
  padding: 0.8rem 1rem;
  background: #101013;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  color: var(--ivory);
  transition: border-color var(--dur-1) var(--ease), background var(--dur-1) var(--ease);
}

.f-area { resize: vertical; min-height: 0; }

.f-input:hover, .f-select:hover, .f-area:hover { border-color: rgba(242, 239, 228, 0.4); }

.f-input:focus, .f-select:focus, .f-area:focus {
  border-color: var(--ivory);
  outline: none;
}

.f-input:focus-visible, .f-select:focus-visible, .f-area:focus-visible {
  outline: 2px solid var(--ivory);
  outline-offset: 2px;
}

/* Cindy §19 contrast: at 0.35 ivory the placeholder measured 2.93:1 on the
   field fill — failing WCAG 1.4.3 — and ten fields on this form carry their
   ONLY guidance in the placeholder ("e.g. 2 hours before doors", "Loading
   dock, street, stairs…", "Anything to keep off the decks"). 50% measures
   4.78:1: passes AA with headroom, still clearly subordinate to typed ivory. */
.f-input::placeholder, .f-area::placeholder {
  color: color-mix(in srgb, var(--ivory) 50%, transparent);
}

.f-select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 2.6rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23F2EFE4' stroke-width='1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  cursor: pointer;
}

.f-select option { background: #101013; color: var(--ivory); }

/* Error state — text + border, never color alone */
.f-field.is-invalid .f-input,
.f-field.is-invalid .f-select,
.f-field.is-invalid .f-area {
  border-color: var(--crimson-hot);
}

.f-err {
  font-size: var(--fs-small);
  color: #F2A9B4;                 /* light error tint — passes AA on panel */
}

/* Radio / checkbox chips */
.f-group > .chip-row { margin-top: var(--sp-3); }

.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
}

/* inline-flex (not the label default `inline`) so the absolutely positioned
   input resolves `inset:0` against a real box on every engine */
.chip { position: relative; display: inline-flex; }

.chip input {
  position: absolute;
  inset: 0;
  opacity: 0;
  margin: 0;
  cursor: pointer;
}

.chip span {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0.55rem 1.15rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  background: #101013;
  font-family: var(--font-label);
  font-weight: 500;
  font-size: 0.98rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ivory-80);
  cursor: pointer;
  transition: background var(--dur-1) var(--ease),
              border-color var(--dur-1) var(--ease),
              color var(--dur-1) var(--ease);
}

.chip:hover span { border-color: rgba(242, 239, 228, 0.45); color: var(--ivory); }

.chip input:checked + span {
  background: var(--crimson);
  border-color: var(--crimson);
  color: var(--ivory);
}

.chip input:focus-visible + span {
  outline: 2px solid var(--ivory);
  outline-offset: 3px;
}

/* "Other" genre input: visible by default (no-JS floor);
   collapses via :has() where supported until Other is checked */
@supports selector(:has(*)) {
  .f-genres-wrap:not(:has(#g-other:checked)) .g-other { display: none; }
}

.f-genres-wrap .g-other { margin-top: var(--sp-4); }

/* Consent checkboxes — real boxes for clarity */
.bk-consents {
  display: grid;
  gap: var(--sp-3);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: var(--sp-5);
}

.f-consent {
  display: flex;
  align-items: flex-start;
  gap: 0.8rem;
  cursor: pointer;
  padding-block: 0.35rem;
}

.f-consent input {
  width: 22px;
  height: 22px;
  margin-top: 1px;
  flex: none;
  accent-color: var(--crimson);
  cursor: pointer;
}

.f-consent span {
  font-size: var(--fs-small);
  color: var(--ivory-80);
}

/* ---------- 06 Wizard chrome ---------- */
.bk-progress { margin-bottom: var(--sp-7); }

.bk-dots {
  display: flex;
  gap: var(--sp-2);
}

.bk-dots li {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  padding-top: 0.7rem;
  border-top: 2px solid var(--line);
  min-width: 0;
}

.bk-dots li.is-done { border-top-color: var(--crimson-deep); }
.bk-dots li.is-active { border-top-color: var(--crimson); }

.bk-dot-num {
  font-family: var(--font-logo);
  font-size: 1.05rem;
  line-height: 1;
  color: var(--smoke);
}

.bk-dots li.is-active .bk-dot-num { color: var(--ivory); }

.bk-dot-label {
  font-family: var(--font-label);
  font-weight: 500;
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--smoke);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.bk-dots li.is-active .bk-dot-label { color: var(--ivory); }

/* Cindy §21 fit + type integrity at 360: five flex:1 columns in a 278px
   shell interior gave each li 49px, so "Logistics" (58px) and "Contact"
   (50px) were chopped by text-overflow:ellipsis — and since every INACTIVE
   label is hidden below 560, the one label chopped was always the ACTIVE
   one, i.e. exactly the label that orients the user, rendered "LOGISTI…".
   Let the active step claim the room the hidden labels vacate: inactive
   columns only need a 2-digit Bebas numeral (~20px), which leaves the
   active column ~134px against the 58px worst case. */
@media (max-width: 559.98px) {
  .bk-dots li:not(.is-active) .bk-dot-label { display: none; }

  .bk-dots li { flex: 0 1 1.75rem; }
  .bk-dots li.is-active { flex: 1 1 auto; }
}

.bk-nav {
  display: flex;
  justify-content: space-between;
  gap: var(--sp-4);
  margin-top: var(--sp-7);
  padding-top: var(--sp-6);
  border-top: 1px solid var(--line);
}

.bk-nav #bk-next,
.bk-nav #bk-send { margin-left: auto; }

/* Cindy §22 follow-through: the submit-line honesty copy is the
   expectation-setting line at the decision point (shared by the wizard and
   no-JS instances). --smoke left it the faintest text on the money path; ivory-60
   gives it presence while staying subordinate to the button. */
.bk-honest {
  margin-top: var(--sp-5);
  font-size: var(--fs-small);
  color: var(--ivory-60);
}

/* Native (no-JS) submit block */
.bk-native {
  margin-top: var(--sp-8);
  padding-top: var(--sp-6);
  border-top: 1px solid var(--line);
  display: grid;
  gap: var(--sp-5);
  justify-items: start;
}

.bk-native .bk-honest { margin-top: 0; }

/* ---------- 07 Review + confirmation ---------- */
.bk-review-lead {
  color: var(--ivory-60);
  margin-bottom: var(--sp-6);
}

.bk-rev-group {
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: var(--sp-5);
}

.bk-rev-group + .bk-rev-group { margin-top: var(--sp-5); }

.bk-rev-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
}

.bk-rev-head h4 { letter-spacing: 0.08em; }

.bk-rev-edit {
  min-height: 44px;
  padding: 0.5rem 1rem;
  background: transparent;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  color: var(--ivory);
  font-family: var(--font-label);
  font-weight: 600;
  font-size: 0.9rem;
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  cursor: pointer;
  transition: border-color var(--dur-1) var(--ease), background var(--dur-1) var(--ease);
}

.bk-rev-edit:hover { border-color: var(--ivory); background: rgba(242, 239, 228, 0.06); }

.bk-rev-list {
  margin-top: var(--sp-4);
  display: grid;
  gap: var(--sp-2) var(--sp-5);
}

@media (min-width: 768px) {
  .bk-rev-list { grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.6fr); }
}

/* Cindy §22: every field label on the Review step — the last screen before
   send — was 13px --smoke uppercase at 0.14em tracking, the hardest-to-read
   text on the conversion path. 15px + ivory-60 = 6.2:1 on panel. The dd
   stays --ivory at 17px, so the label/value hierarchy is intact. */
.bk-rev-list dt {
  font-family: var(--font-label);
  font-weight: 500;
  font-size: var(--fs-small);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--ivory-60);
  padding-top: 0.2rem;
}

.bk-rev-list dd {
  margin: 0 0 var(--sp-3);
  color: var(--ivory);
  overflow-wrap: anywhere;
}

@media (min-width: 768px) {
  .bk-rev-list dd { margin-bottom: 0; }
}

.bk-rev-empty {
  margin-top: var(--sp-3);
  font-size: var(--fs-small);
  color: var(--smoke);
}

/* Confirmation panel */
.bk-confirm { text-align: left; }

.bk-confirm:focus-visible { outline: 2px solid var(--ivory); outline-offset: 6px; }

.bk-confirm h3 { margin-top: var(--sp-4); }

.bk-confirm-copy {
  margin-top: var(--sp-4);
  color: var(--ivory-80);
  max-width: 58ch;
}

.bk-confirm-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-4);
  margin-top: var(--sp-6);
}

.bk-confirm-call {
  margin-top: var(--sp-7);
  font-size: var(--fs-small);
  color: var(--smoke);
}

.bk-confirm-phone {
  display: inline-block;
  margin-top: var(--sp-2);
  font-family: var(--font-logo);
  font-size: clamp(2rem, 6vw, 3.2rem);
  line-height: 1.1;
  color: var(--ivory);
  text-decoration: none;
}

.bk-confirm-phone:hover { text-decoration: underline; text-decoration-color: var(--crimson-hot); }

.bk-return {
  display: block;
  margin-top: var(--sp-6);
  min-height: 44px;
  padding: 0.6rem 0;
  background: transparent;
  border: 0;
  color: var(--smoke);
  font-family: var(--font-label);
  font-weight: 500;
  font-size: var(--fs-small);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  cursor: pointer;
}

.bk-return:hover { color: var(--ivory); }

/* ---------- 08 Process / payment / closing ---------- */
/* Match .bk-get's row/column rhythm (sp-6 row / sp-7 column) so the two
   numbered grids on this page breathe identically instead of inverting. */
.bk-process { gap: var(--sp-6) var(--sp-7); }

@media (min-width: 768px) { .bk-process { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 980px) { .bk-process { grid-template-columns: repeat(4, 1fr); } }

.bk-proc-item { position: relative; }

.bk-proc-item::before {
  content: "";
  display: block;
  width: 26px;
  height: 2px;
  background: var(--crimson);
  margin-bottom: var(--sp-4);
}

.bk-proc-num {
  display: block;
  font-family: var(--font-logo);
  font-size: var(--fs-stat);
  line-height: 1;
  color: var(--ivory);
  margin-bottom: var(--sp-3);
}

.bk-proc-item h3 {
  font-family: var(--font-label);
  font-weight: 600;
  font-size: 1.1rem;
  letter-spacing: 0.06em;
}

.bk-proc-item p {
  margin-top: var(--sp-2);
  font-size: var(--fs-small);
  color: var(--ivory-60);
  max-width: 30ch;
}

/* Payment note band */
.bk-pay {
  /* Same panel-2→panel depth as .bk-shell so the two crimson-edged cards share
     one card-depth language instead of this band reading flat. */
  background: linear-gradient(to bottom, var(--panel-2), var(--panel) 60%);
  border: 1px solid var(--line);
  border-left: 3px solid var(--crimson);
  border-radius: var(--r-md);
  padding: clamp(1.5rem, 4vw, 2.75rem);
}

.bk-pay-title {
  font-size: clamp(1.6rem, 3.4vw, 2.4rem);
  margin-top: var(--sp-4);
}

.bk-pay p:not(.eyebrow) {
  margin-top: var(--sp-4);
  color: var(--ivory-80);
  max-width: 62ch;
}

/* Closing CTA */
/* Cindy §20: the only tonal event on the whole page was this 12% crimson
   radial — the closing got crimson but never light. Ivory lift stacked
   above the crimson so the accent still reads, raw rgba dropped. */
.bk-close {
  border-top: 1px solid var(--line);
  background:
    radial-gradient(70% 50% at 50% 100%,
      color-mix(in srgb, var(--ivory) 4%, transparent), transparent 70%),
    radial-gradient(55% 45% at 50% 100%,
      color-mix(in srgb, var(--crimson) 14%, transparent), transparent 70%),
    var(--bg);
}

.bk-close-title {
  font-size: clamp(2.2rem, 6.5vw, 5rem);
  max-width: 18ch;
  margin-inline: auto;
  margin-top: var(--sp-5);
}

.bk-close-phone {
  display: inline-block;
  margin-top: var(--sp-6);
  font-family: var(--font-logo);
  font-size: clamp(2.6rem, 8vw, 5.5rem);
  line-height: 1;
  color: var(--ivory);
  text-decoration: none;
  letter-spacing: 0.03em;
}

.bk-close-phone:hover {
  text-decoration: underline;
  text-decoration-color: var(--crimson-hot);
  text-decoration-thickness: 3px;
  text-underline-offset: 0.15em;
}

.bk-close-cta {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-4);
  margin-top: var(--sp-7);
}

/* ============ EVENT WIZARD BAND — the deeper planning layer ============
   Tokens only. This block previously reached for --bg2/--ink2/--ink3/--cond,
   none of which exist in tokens.css, so it fell through to off-palette warm
   browns imported from another project's vocabulary. The house band idiom is
   a flat --bg-2 ground with a fixed-length ivory lift off the top edge —
   fixed px, not a percentage, so it reads the same on any band height. */
.bk-vve {
  background-color: var(--bg-2);
  background-image: linear-gradient(to bottom,
    color-mix(in srgb, var(--ivory) 4%, transparent) 0, transparent 200px);
  border-block: 1px solid var(--line);
}
/* The band skips .sect-head and stacks bare eyebrow + title + lead as direct
   children, so under the global reset they glue together with no rhythm.
   Restore the standard eyebrow→title→lead gaps. */
.bk-vve .eyebrow { margin-bottom: var(--sp-4); }
.bk-vve .sect-title { margin-bottom: var(--sp-5); font-size: var(--fs-title); }

.bk-vve-lead {
  max-width: 62ch;
  /* Aligned to the shared lead scale (.sect-lead): --fs-lead at --ivory-60,
     so this lead matches every other section lead on the page. */
  color: var(--ivory-60);
  font-size: var(--fs-lead);
  margin-bottom: clamp(1.75rem, 4vw, 2.5rem);
}
.bk-vve-cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: clamp(0.9rem, 2.5vw, 1.5rem);
}
/* --smoke sits ~390px into the band, well past the 200px lift, so it reads
   on flat --bg-2 at 4.96:1 — AA clear. */
.bk-vve-note {
  font-family: var(--font-label);
  font-size: 0.85rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--smoke);
}
