/* Tag-to-booking button on estimate chips (admin rail). Quiet inset
   pill at rest; flips to the orange-soft active treatment when this
   estimate is tagged to the booking. Multiple estimates can be
   tagged, so several chips may show the active treatment at once —
   they all mark the same one selection (what this booking is filed
   against). */
.acc-tl-doc-tag-btn {
  /* Lives on the chip itself (below the summary), so it shows without
     expanding. Compact, inset pill, left-aligned — short "Tag" when collapsed,
     "Tag this job" when expanded. */
  display: block;
  width: fit-content;
  margin: 8px 13px 12px;
  padding: 6px 14px;
  border: 1px solid var(--sw-border, #E5DED3);
  border-radius: var(--sw-radius-pill, 999px);
  background: var(--sw-card-lift, #FFFDF9);
  color: var(--sw-ink, #373B4D);
  font-family: inherit;
  font-size: 0.78rem;
  font-weight: 700;
  cursor: pointer;
  transition: background 140ms ease, color 140ms ease, border-color 140ms ease, transform 140ms ease;
}
.acc-tl-doc-tag-btn:hover { background: var(--sw-card-lift, #FFFDF9); }
.acc-tl-doc-tag-btn:active { transform: scale(0.97); }
.acc-tl-doc-tag-btn.is-tagged {
  background: var(--sw-orange-soft, #FFEEDC);
  border-color: var(--sw-orange, #F38A3F);
  color: var(--sw-orange-dark, #C66518);
}
.acc-tl-doc.acc-tl-doc--tagged { border-left: 3px solid var(--sw-orange, #F38A3F); }
@media (prefers-reduced-motion: reduce) {
  .acc-tl-doc-tag-btn { transition: none; }
}
/* End of timeline rules. */

.acc-visit-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto 26px;
  grid-template-areas:
    "date amount blank"
    "tech status blank";
  gap: 2px 10px;
  padding: 0 16px 8px;
  color: #7B8190;
  font-size: 0.56rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.acc-visit-head span:nth-child(1) { grid-area: date; }
.acc-visit-head span:nth-child(2) { grid-area: tech; }
.acc-visit-head span:nth-child(3) {
  grid-area: amount;
  text-align: right;
}
.acc-visit-head span:nth-child(4) {
  grid-area: status;
  text-align: right;
}
.acc-visit-head span:nth-child(5) { grid-area: blank; }
.acc-list.acc-visit-list {
  display: grid;
  gap: 10px;
  border: 0;
  border-radius: 0;
  background: transparent;
  overflow: visible;
}
.acc-visit-list > li.acc-visit {
  display: block;
  padding: 0;
  border: 1px solid #E5DED3;
  border-radius: 18px;
  background: #FFFDF9;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.86),
    0 8px 22px rgba(55, 59, 77, 0.045);
  overflow: hidden;
}
.acc-visit-list > li.acc-visit + li.acc-visit { border-top: 1px solid #E5DED3; }
.acc-visit-summary {
  width: 100%;
  border: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto 26px;
  grid-template-areas:
    "date money caret"
    "tech status caret";
  gap: 7px 10px;
  align-items: center;
  padding: 15px 16px;
  text-align: left;
  font: inherit;
  transition: background 0.16s ease;
}
.acc-visit-summary:hover {
  background: linear-gradient(180deg, #FFFDF9, #FCFAF6);
}
.acc-visit-summary[aria-expanded="true"] {
  background: linear-gradient(180deg, #FFF8EF, #FFFDF9);
}
.acc-visit-date,
.acc-visit-tech,
.acc-visit-money {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.acc-visit-date {
  grid-area: date;
  font-weight: 800;
  color: #373B4D;
  font-size: 0.98rem;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.acc-visit-tech {
  grid-area: tech;
  color: #7B8190;
  font-size: 0.78rem;
  font-weight: 750;
}
.acc-visit-money {
  grid-area: money;
  color: #373B4D;
  font-weight: 800;
  font-size: 1.02rem;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.acc-visit--open .acc-visit-money { color: #D65F4F; }
.acc-visit-status {
  grid-area: status;
  justify-self: start;
  font-size: 0.58rem;
  text-transform: uppercase;
  letter-spacing: 0.10em;
  padding: 3px 9px;
  border-radius: 999px;
  background: #FFFDF9;
  color: #7B8190;
  font-weight: 800;
  white-space: nowrap;
  justify-self: end;
}
.acc-visit--paid .acc-visit-status {
  background: rgba(75, 170, 120, 0.16);
  color: #2E7D4F;
}
.acc-visit--open .acc-visit-status {
  background: rgba(211, 154, 46, 0.18);
  color: #C66518;
}
.acc-visit--unknown .acc-visit-status {
  background: rgba(191, 224, 243, 0.55);
  color: #1F5A86;
}
.acc-visit-caret {
  grid-area: caret;
  align-self: center;
  justify-self: end;
  width: 24px;
  height: 24px;
  border-radius: 999px;
  background: #FFFDF9;
  color: #7B8190;
  font-size: 0.95rem;
  font-weight: 800;
  line-height: 24px;
  text-align: center;
  transition: transform 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.acc-visit-summary[aria-expanded="true"] .acc-visit-caret {
  transform: rotate(180deg);
  background: #FFEEDC;
  color: #C66518;
}
.acc-visit-detail {
  margin: 0 12px 12px;
  padding: 12px;
  display: grid;
  gap: 10px;
  border: 1px solid #E5DED3;
  border-radius: 14px;
  background: #F8F5EF;
}
.acc-visit-detail[hidden] {
  display: none;
}
.acc-visit-detail-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}
.acc-visit-detail-grid > div {
  min-width: 0;
  padding: 10px 11px;
  border-radius: 12px;
  background: #FFFDF9;
  border: 1px solid #E5DED3;
  display: grid;
  gap: 2px;
}
.acc-visit-detail-label {
  font-size: 0.56rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #7B8190;
}
.acc-visit-invoice,
.acc-visit-amount,
.acc-visit-detail-tech {
  min-width: 0;
  color: #373B4D;
  font-size: 0.76rem;
  font-weight: 800;
  overflow-wrap: anywhere;
}
.acc-visit-desc {
  margin: 0;
  color: #373B4D;
  font-size: 0.82rem;
  line-height: 1.45;
  white-space: pre-wrap;
  padding: 10px 11px;
  border-radius: 12px;
  background: #FFFDF9;
  border: 1px solid #E5DED3;
}
.acc-visit-link {
  width: fit-content;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 7px 12px;
  border-radius: 999px;
  background: #FFEEDC;
  color: #C66518;
  border: 1px solid rgba(243, 138, 63, 0.28);
}
.acc-job-date {
  font-weight: 700;
  min-width: 96px;
  color: #373B4D;
  font-variant-numeric: tabular-nums;
}
/* Status badges use the philosophy's pill pattern: fully rounded
   ends, soft wash background, same-hue strong text. */
.acc-job-status {
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.10em;
  padding: 3px 10px;
  border-radius: 999px;
  background: #FFFDF9;
  color: #7B8190;
  font-weight: 800;
}
.acc-job-status--completed {
  background: rgba(75, 170, 120, 0.16);
  color: #2E7D4F;
}
.acc-job-status--in_progress {
  background: rgba(211, 154, 46, 0.18);
  color: #C66518;
}
.acc-job-status--scheduled {
  background: rgba(191, 224, 243, 0.55);
  color: #1F5A86;
}
.acc-job-status--canceled,
.acc-job-status--cancelled {
  background: #FFFDF9;
  color: #7B8190;
}
.acc-job-tech { font-size: 0.85rem; color: #373B4D; font-weight: 600; }
.acc-job-invoice {
  font-size: 0.78rem;
  color: #1F5A86;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.acc-job-desc { flex-basis: 100%; color: #7B8190; font-size: 0.82rem; }
.acc-source {
  display: inline-flex;
  align-items: center;
  width: fit-content;
  max-width: 100%;
  padding: 2px 8px;
  border-radius: 999px;
  background: rgba(191, 224, 243, 0.36);
  color: #1F5A86;
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.acc-open-link {
  color: #B86012;
  font-size: 0.76rem;
  font-weight: 800;
  text-decoration: none;
}
.acc-open-link:hover {
  text-decoration: underline;
}
.acc-list > li.acc-invoice {
  display: block;
  padding: 0;
}
.acc-invoice-summary {
  width: 100%;
  border: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  padding: 12px 14px;
  text-align: left;
  font: inherit;
}
.acc-invoice-summary:hover {
  background: rgba(243, 138, 63, 0.05);
}
.acc-invoice-summary[aria-expanded="true"] {
  background: #FFF8EF;
}
.acc-invoice-num {
  font-weight: 700;
  min-width: 110px;
  color: #373B4D;
  font-variant-numeric: tabular-nums;
}
.acc-invoice-amt {
  font-variant-numeric: tabular-nums;
  min-width: 80px;
  font-weight: 600;
}
.acc-invoice-balance {
  font-size: 0.72rem;
  color: #B86012;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}
/* Status pill on each invoice row. Default is the philosophy's inset
   wash with muted graphite text — quiet, archival reading for
   ambiguous statuses (canceled, voided, draft, anything we don't
   recognize). Modifier classes paint the meaningful states:
     --paid     → green wash + emerald text  (money in)
     --open     → gold wash + warm-brown text (money still owed) */
.acc-invoice-status {
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.10em;
  padding: 3px 10px;
  border-radius: 999px;
  background: #FFFDF9;
  color: #7B8190;
  font-weight: 800;
}
.acc-invoice--paid .acc-invoice-status {
  background: rgba(75, 170, 120, 0.16);
  color: #2E7D4F;
}
.acc-invoice--open { background: rgba(243, 138, 63, 0.05); }
.acc-invoice--open .acc-invoice-status {
  background: rgba(211, 154, 46, 0.18);
  color: #C66518;
}
/* Synthetic invoice rows — synthesized server-side from job records
   when HCP's invoices endpoint didn't return amount data for this
   customer. Renders with the deep-navy "informational" hue (same
   family as the .acc-stat--info color) so the row reads as "data
   exists in HCP, just not in this API response" rather than as a
   warning. Amount column shows "—" instead of $0. */
.acc-invoice--synthetic { background: rgba(191, 224, 243, 0.20); }
.acc-invoice--synthetic .acc-invoice-status {
  background: rgba(191, 224, 243, 0.55);
  color: #1F5A86;
}
.acc-invoice--synthetic .acc-invoice-amt {
  color: #7B8190;
  font-weight: 600;
}
.acc-invoice-detail {
  padding: 0 14px 14px;
  display: grid;
  gap: 10px;
}
.acc-invoice-detail[hidden] {
  display: none;
}
.acc-invoice-desc {
  margin: 0;
  color: #373B4D;
  font-size: 0.82rem;
  line-height: 1.45;
  white-space: pre-wrap;
}
.acc-invoice-lines {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 6px;
}
.acc-invoice-line {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 3px 10px;
  padding: 8px 10px;
  background: #FCFAF6;
  border: 1px solid #E5DED3;
  border-radius: 10px;
}
.acc-invoice-line-name {
  color: #373B4D;
  font-size: 0.78rem;
  font-weight: 800;
  min-width: 0;
}
.acc-invoice-line-amount {
  color: #373B4D;
  font-size: 0.78rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}
/* Quantity badge — small inline marker sitting on its own row so
   the multi-paragraph description below isn't visually prefixed by
   "Qty X · " (which ran the two together when the description
   spans multiple paragraphs). */
.acc-invoice-line-qty {
  grid-column: 1 / -1;
  color: #7B8190;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  margin-top: 2px;
}
.acc-invoice-line-qty[hidden] { display: none; }
.acc-invoice-line-desc {
  grid-column: 1 / -1;
  color: #7B8190;
  font-size: 0.72rem;
  line-height: 1.35;
  /* Same multiline-preservation rule as .acc-tl-doc-desc above.
     Line-item descriptions from HCP (the rich "Scope of Work /
     Detailed Scope of Work" content the user pasted as a screenshot)
     ship with \n separators between paragraphs. */
  white-space: pre-line;
  margin-top: 4px;
}
.acc-invoice-line-desc[hidden] { display: none; }
.acc-invoice-profile {
  margin: 0;
}
.acc-invoice-link {
  width: fit-content;
}
@media (max-width: 560px) {
  .acc-visit-head {
    display: none;
  }
  .acc-visit-summary {
    grid-template-columns: minmax(0, 1fr) auto 26px;
    gap: 7px 8px;
  }
  .acc-visit-date {
    grid-area: date;
  }
  .acc-visit-money {
    grid-area: money;
    text-align: right;
  }
  .acc-visit-caret {
    grid-area: caret;
  }
  .acc-visit-tech {
    grid-area: tech;
  }
  .acc-visit-status {
    grid-area: status;
    justify-self: end;
  }
  .acc-visit-detail-grid {
    grid-template-columns: 1fr;
  }
  .acc-tech-main {
    align-items: flex-start;
    flex-wrap: wrap;
  }
  .acc-tech-meta {
    flex: 1 1 100%;
    max-width: none;
    text-align: left;
    margin-left: 38px;
  }
  .acc-tech-appointments {
    margin-left: 0;
  }
  .acc-tech-appointment {
    grid-template-columns: 1fr;
  }
  .acc-tech-appt-desc {
    white-space: normal;
  }
  .acc-invoice-summary {
    gap: 7px;
  }
  .acc-invoice-num,
  .acc-invoice-amt {
    min-width: 0;
  }
}
.acc-cap-note {
  margin: 10px 0 0;
  font-size: 0.82rem;
  color: var(--text-muted);
  font-style: italic;
}
/* Small footnote under a list when the data is known-partial (e.g.
   invoices were capped at the HCP page size). Quieter than .acc-cap-note
   because it's a clarification, not a missing-capability warning. */
.acc-section-note {
  margin: 6px 4px 0;
  font-size: 0.75rem;
  color: var(--text-muted);
  line-height: 1.4;
}

/* Cross-location result row. Softer surface + a badge that names the
   sister franchise the customer actually belongs to. Picking one of
   these prompts a switch/keep confirmation before the form fills. */
.admin-customer-search-result--other-loc {
  background: rgba(243, 138, 63, 0.04);
}
.admin-customer-search-result--other-loc:hover,
.admin-customer-search-result--other-loc:focus {
  background: rgba(243, 138, 63, 0.10);
}
.admin-customer-search-result-loc-badge {
  display: inline-block;
  padding: 1px 7px;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  color: var(--orange, #E07A2A);
  background: rgba(243, 138, 63, 0.14);
  border-radius: 10px;
  margin-left: 2px;
}

/* ───── Admin override toggles ─────
   Collapsible <details> panel inside the admin booking banner.
   Hosts the bypass switches for business hours + trip charge.
   Lead-time bypass is automatic (no toggle, just a status line).
   Defaults closed so the surface stays calm — admins only open it
   when they actually need to force-book something unusual. */
.admin-overrides {
  border-top: 1px dashed rgba(39, 41, 54, 0.10);
  padding-top: 10px;
}
.admin-overrides-summary {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px 4px 6px;
  margin-left: -6px;
  border-radius: 8px;
  font-size: 0.85rem;
  color: var(--text-muted);
  cursor: pointer;
  list-style: none;
  user-select: none;
  transition: background 0.15s, color 0.15s;
  &::-webkit-details-marker { display: none; }
  &:hover { background: rgba(39, 41, 54, 0.04); color: var(--text); }
  & svg { transition: transform 0.2s ease; }
}
.admin-overrides[open] > .admin-overrides-summary {
  color: var(--text);
  font-weight: 600;
  & svg { transform: rotate(180deg); }
}
.admin-overrides-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  background: var(--orange, #E07A2A);
  color: #fff;
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 700;
  line-height: 1;
}
.admin-overrides-body {
  margin-top: 10px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px 14px;
  background: rgba(255, 255, 255, 0.55);
  border: 1px solid rgba(39, 41, 54, 0.08);
  border-radius: 10px;
}
.admin-overrides-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  font-size: 0.82rem;
  color: var(--text-muted);
}
.admin-overrides-status svg { flex-shrink: 0; }
.admin-overrides-toggle {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 8px 10px;
  border-radius: 8px;
  cursor: pointer;
  transition: background 0.12s;
  &:hover { background: rgba(39, 41, 54, 0.04); }
  & input[type="checkbox"] {
    margin-top: 2px;
    accent-color: var(--orange, #E07A2A);
    cursor: pointer;
  }
  &:has(input:checked) {
    background: rgba(224, 122, 42, 0.08);
  }
}
.admin-overrides-toggle-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 0.88rem;
  color: var(--text);
}
.admin-overrides-toggle-text strong { font-weight: 600; }

/* ═══════════ Admin single-page flow ═══════════
   When the booking form has data-admin-flow="1" (set in EJS only when
   the page was rendered via /admin/book/:slug), every step panel is
   visible at once and they're reordered into:
     1. Describe the issue (step 3)
     2. Customer information incl. address (step 4 — booking.js
        hoists the address autocomplete into here at init so the
        autocomplete + structured fields read as one section)
     3. Pick tech (tech-easter-egg dropdown, inside step 2)
     4. Schedule (calendar, inside step 2)
     5. Submit (admin-flow-submit-row, lives outside step panels)

   Implemented entirely with CSS reordering — the public flow shares
   the same markup and behaves unchanged. */
/* Single-page only: the wizard (data-admin-wizard) keeps the stepper —
   it's the 1·2·3 progress affordance — so exclude it here. The handful
   of rules below tagged :not([data-admin-wizard="1"]) are the layout
   rules that turn the form into one long page; everything else in this
   section is shared admin element styling and applies to both. */
form[data-admin-flow="1"]:not([data-admin-wizard="1"]) .stepper { display: none; }
/* Step-card padding + flex layout — scope DOUBLE-COVERED. The
   original `form[data-admin-flow="1"]` selector silently failed on
   at least one render path (sub-cards visibly flush against the
   step-card border in admin booking screenshots), so the same
   rules are also scoped under .booking-page--admin which we know
   is being applied (it's what activates the 2-column grid with
   the customer rail on the left). Belt-and-suspenders: whichever
   selector matches, the padding + flex layout still fires.
   The two selectors share one rule body — equal specificity, no
   conflict. */
form[data-admin-flow="1"]:not([data-admin-wizard="1"]) .step-card,
.booking-page--admin form[data-admin-flow="1"]:not([data-admin-wizard="1"]) .step-card {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  gap: 0;
  height: auto;
  transition: none;
  max-width: none;
  width: 100%;
  overflow: visible;
  /* Padding — bumped to 32/40 so every inner sub-card (suggestions
     strip, calendar, textarea card, customer-info grid) has a clear
     inset from the step-card's edge. Earlier passes ran 26/30; the
     visible gap kept reading as "sub-cards touching the sides"
     because (a) 30px wasn't large enough at 1200px+ widths and
     (b) the step-card's old #FCFAF6 background was effectively the
     same color as the canvas (#FAF9F6), so the outer step-card
     border was invisible and the inner cards looked like they were
     floating directly on the page. We bump padding here AND give
     the step-card a visibly distinct surface below. */
  padding: 32px 40px;
  /* Step-card sits visibly above the warm canvas. Was #FFFCF4 (read
     as yellow). #FCFAF6 is the palette's standard warm-card cream —
     less yellow, still clearly brighter than the new #F3EDDF canvas
     (cream-on-cream contrast with ~10 hex points of headroom). Inner
     sub-cards use #FFFDF9 / lighter highlights so they still nest. */
  background: #FCFAF6;
  border-color: #DED5C8;
}
@media (max-width: 1100px) {
  form[data-admin-flow="1"]:not([data-admin-wizard="1"]) .step-card,
  .booking-page--admin form[data-admin-flow="1"]:not([data-admin-wizard="1"]) .step-card { padding: 26px 28px; }
}
@media (max-width: 760px) {
  form[data-admin-flow="1"]:not([data-admin-wizard="1"]) .step-card,
  .booking-page--admin form[data-admin-flow="1"]:not([data-admin-wizard="1"]) .step-card { padding: 20px 18px; }
}
/* Reordering — admin booking starts with the verified service address
   and schedule, then the job description, then editable customer and
   address details. */
form[data-admin-flow="1"]:not([data-admin-wizard="1"]) .step-panel[data-step="2"] { order: 1; }
form[data-admin-flow="1"]:not([data-admin-wizard="1"]) .step-panel[data-step="3"] { order: 2; }
form[data-admin-flow="1"]:not([data-admin-wizard="1"]) .step-panel[data-step="4"] { order: 3; }
form[data-admin-flow="1"]:not([data-admin-wizard="1"]) .admin-flow-submit-row { order: 4; }
form[data-admin-flow="1"]:not([data-admin-wizard="1"]) .step-panel[data-step="2"] > .actions { display: none !important; }
/* Drawer-internal Back/Continue buttons (rendered by calendar.js inside
   the .cal-drawer-tray when a date is picked) are step-nav buttons
   that don't belong on a single-page admin layout — the bottom
   "Schedule booking" CTA is the only submit. */
form[data-admin-flow="1"] .cal-drawer-actions { display: none !important; }
/* Keep the verified address control expanded in admin mode. The public
   flow collapses this into #step2-summary after verification, but the
   admin scheduler should show one address control at the top and never
   a second summary chip. */
form[data-admin-flow="1"] #step2-prelude,
form[data-admin-flow="1"] #step2-prelude.is-collapsed {
  display: block !important;
  max-height: none !important;
  opacity: 1 !important;
  visibility: visible !important;
  overflow: visible !important;
  pointer-events: auto !important;
  margin-bottom: 0 !important;
}
form[data-admin-flow="1"] #step2-summary { display: none !important; }

/* Section headings — only injected where the shared public-flow markup
   does not already provide a useful admin heading. Step 3 has its own
   <h2>; step 4 + the loaded calendar get admin labels so the single-
   page card scans as clear sections. The tech picker used to get one
   too, but its inline icon + "Technician filter" label now serve as
   the section header inline. */
/* Section headings — bolded label per block (Schedule / What is going
   on? / Customer information). No underline, no divider above. The
   labels alone carry the visual hierarchy and the page reads as a
   continuous form instead of stacked tiles. */
/* The "Schedule" label above the calendar was removed (2026-06-14):
   the 1·2·3 stepper already names this step, so repeating it inside the
   card just pushed the calendar down. */
form[data-admin-flow="1"] .step-panel[data-step="3"] h2 {
  font-size: 1.05rem;
  font-weight: 800;
  letter-spacing: -0.015em;
  color: #373B4D;
  margin: 0 0 16px;
}
form[data-admin-flow="1"] .step-panel[data-step="4"]::before {
  content: 'Customer information';
  display: block;
  font-size: 1.05rem;
  font-weight: 800;
  letter-spacing: -0.015em;
  color: #373B4D;
  margin: 0 0 10px;
}
/* Tech picker — strip the easter-egg pill chrome in admin mode so it
   reads as a regular section. The cream box + icon + "Specific tech"
   label make sense as a hidden customer-facing surprise; in admin
   mode where the picker is the primary surface for tech routing,
   we want a plain dropdown under the "Pick a tech" heading. */
form[data-admin-flow="1"] .tech-easter-egg {
  background: transparent;
  border: 0;
  padding: 0;
  margin: 0;
  max-height: none;
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  flex-direction: column;
  align-items: stretch;
  gap: 0;
  transition: none;
}
form[data-admin-flow="1"] .step-panel[data-step="2"] {
  display: grid;
  /* Was 22px between the address card, tech picker, suggestions, and
     calendar. The mockup ran at ~14px and read tighter without
     blurring the sub-card boundaries. */
  gap: 14px;
}
/* Tech filter row — icon + label + select sit inline as a single
   bento control row, left-anchored. The select sizes to its content
   (tech names) and the icon/label/select are dimensioned to feel
   proportional to a single-word value, not stretched to fill space.
   Extra bottom margin so the row reads as a distinct control above
   the calendar card rather than touching its top edge. */
form[data-admin-flow="1"] .tech-easter-egg {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 9px;
  flex-direction: row;
  margin-bottom: 6px;
}
form[data-admin-flow="1"] .tech-easter-egg-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  flex: 0 0 24px;
  background: #FFFDF9;
  border-radius: 999px;
  color: #7B8190;
}
form[data-admin-flow="1"] .tech-easter-egg-icon svg { width: 12px; height: 12px; }
form[data-admin-flow="1"] .tech-easter-egg-label {
  display: inline-block;
  font-size: 0.82rem;
  font-weight: 700;
  color: #373B4D;
  letter-spacing: -0.005em;
  flex: 0 0 auto;
  white-space: nowrap;
}
/* Custom-styled select — strips the native browser chrome and
   replaces the dropdown arrow with an inline-SVG background image
   (warm muted chevron, swaps to orange on hover/focus). Pill shape +
   warm card-highlight bg + soft border match the rest of the page's
   form controls per the philosophy doc. */
form[data-admin-flow="1"] .tech-easter-egg-select {
  /* Pill sized for a single tech name. Earlier passes ran 40px tall
     × 320px max-width, which felt huge for "Lincoln Ashcom" or
     "All". Tightened to 32px × 240px so the control reads as a
     compact filter chip, not a hero input. */
  flex: 0 1 auto;
  width: auto;
  max-width: 240px;
  min-height: 32px;
  padding: 6px 30px 6px 12px;
  background-color: #FFFDF9;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%237B8190' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M1 1.5l5 5 5-5'/></svg>");
  background-repeat: no-repeat;
  background-position: right 11px center;
  background-size: 10px 6px;
  border: 1px solid #E5DED3;
  border-radius: 999px;
  color: #373B4D;
  font-size: 0.86rem;
  font-weight: 600;
  font-family: inherit;
  letter-spacing: -0.005em;
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  cursor: pointer;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.85) inset;
  transition: border-color 0.12s ease, background-color 0.12s ease,
              box-shadow 0.12s ease, color 0.12s ease;
}
form[data-admin-flow="1"] .tech-easter-egg-select:hover {
  border-color: rgba(243, 138, 63, 0.4);
  background-color: #FFFAF1;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%23F38A3F' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M1 1.5l5 5 5-5'/></svg>");
}
form[data-admin-flow="1"] .tech-easter-egg-select:focus {
  outline: none;
  border-color: transparent;
  background-color: #FFFDF9;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%23F38A3F' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M1 1.5l5 5 5-5'/></svg>");
  box-shadow: var(--sw-focus-shadow, 0 0 0 1px #F38A3F, 0 6px 13px rgba(243, 138, 63, 0.30)),
              0 1px 0 rgba(255, 255, 255, 0.85) inset;
}
form[data-admin-flow="1"] .tech-easter-egg-icon:hover,
form[data-admin-flow="1"] .tech-easter-egg:focus-within .tech-easter-egg-icon {
  color: #F38A3F;
  background: rgba(243, 138, 63, 0.14);
}
form[data-admin-flow="1"] #zone-message {
  margin: 0;
}

/* Property type — admin booking is overwhelmingly residential. Keep
   the radio inputs in the DOM (so the form ships property_type=
   'residential' by default) but hide the visual control. If the
   admin needs to file a commercial booking they can do it directly
   in HCP via the link at the bottom. */
form[data-admin-flow="1"] .property-type-field { display: none; }
form[data-admin-flow="1"] .commercial-notice { display: none; }

/* Admin-only "confirmed this is a residence" gate. Replaces the
   property-type pills (hidden above) with a single confirmation
   checkbox the admin must tick before submitting. The point isn't
   the data — every booking is residential anyway — it's the
   prompt: forcing an empty checkbox encourages the admin to
   actually ask the customer "is this a home?" instead of auto-
   assuming. Default-unchecked is the design.

   Visual treatment: warm-inset card with a custom-styled check box
   (philosophy avoids the OS default look) + label + small hint.
   Validation state (.is-invalid) fires on submit attempt if still
   unchecked, with a coral border + inline error message. */
.admin-residential-confirm {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  margin: 10px 0 4px;
  background: #FCFAF6;
  border: 1px solid #E5DED3;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.14s ease, border-color 0.14s ease;
  position: relative;
}
.admin-residential-confirm:hover { background: #FFFAF1; }
/* Hide the native input — the custom .admin-residential-confirm-box
   is the visible check surface. The native input still tracks state
   + receives the click (the label proxies it). */
.admin-residential-confirm input[type="checkbox"] {
  position: absolute;
  opacity: 0;
  pointer-events: none;
  width: 0; height: 0;
}
.admin-residential-confirm-box {
  flex: 0 0 15px;
  width: 15px;
  height: 15px;
  border: 1.5px solid #C9C2B0;
  border-radius: 4px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: #FFFFFF;
  color: #FFFFFF;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.admin-residential-confirm-box svg { opacity: 0; transition: opacity 0.12s ease; }
.admin-residential-confirm input[type="checkbox"]:checked ~ .admin-residential-confirm-box {
  background: #4BAA78;
  border-color: #4BAA78;
}
.admin-residential-confirm input[type="checkbox"]:checked ~ .admin-residential-confirm-box svg { opacity: 1; }
.admin-residential-confirm input[type="checkbox"]:focus-visible ~ .admin-residential-confirm-box {
  box-shadow: 0 0 0 3px rgba(243, 138, 63, 0.22);
}
.admin-residential-confirm-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.admin-residential-confirm-text strong {
  font-size: 0.78rem;
  font-weight: 600;
  color: #373B4D;
  letter-spacing: -0.005em;
  line-height: 1.2;
}
.admin-residential-confirm-hint {
  font-size: 0.72rem;
  color: #7B8190;
  font-weight: 500;
  line-height: 1.35;
}
/* Invalid state — admin tried to submit without ticking. Coral
   border + soft wash mirrors the unpaid-coral semantic from the
   philosophy palette (clear, serious, not screaming). Auto-clears
   on the next change event in JS. */
.admin-residential-confirm.is-invalid {
  background: #FCEBE7;
  border-color: rgba(214, 95, 79, 0.55);
}
.admin-residential-confirm.is-invalid .admin-residential-confirm-box {
  border-color: #D65F4F;
}
.admin-residential-confirm-error {
  display: none;
  font-size: 0.74rem;
  color: #B14535;
  font-weight: 600;
  margin: 4px 14px 0;
}
.admin-residential-confirm.is-invalid + .admin-residential-confirm-error {
  display: block;
}

/* Compact-but-airy spacing — the admin user already knows what every
   field is for, so the public flow's hero breathing is wasted, but
   the previous 14px row-gap left labels and inputs cramped against
   each other. 18px row-gap pairs with the 8px label-to-input gap
   in .field for a comfortable read.

   max-width: none + margin: 0 overrides the public flow's 760px
   centered grid so the form fills the card's content area on
   admin. Was leaving ~80-160px of empty padding on either side of
   the grid even when the card itself was full-width. */
form[data-admin-flow="1"] .your-info-grid {
  /* Tightened (2026-06-14) from 18px to read more compact per the
     density pass — the admin form was airier than it needed to be. */
  row-gap: 12px;
  column-gap: 18px;
  grid-template-columns: repeat(2, minmax(220px, 1fr));
  max-width: none;
  margin: 0;
  align-items: start;
}
@media (max-width: 720px) {
  form[data-admin-flow="1"] .your-info-grid {
    grid-template-columns: 1fr;
  }
  form[data-admin-flow="1"] .your-info-grid .span-2 {
    grid-column: auto;
  }
}
form[data-admin-flow="1"] .ledger-field { margin: 0; }

/* The verified service address lives at the top of admin step 2, above
   the tech picker and calendar. Strip the public flow's narrow centering
   so the input lines up with the rest of the admin card. */
form[data-admin-flow="1"] .admin-address-field {
  max-width: none;
  margin: 0;
  width: 100%;
}
form[data-admin-flow="1"] .admin-address-field .address-input-wrap,
form[data-admin-flow="1"] .admin-address-field input {
  width: 100%;
}

/* Step 4's address-summary block duplicates the verified address field
   at the top of the admin scheduler. Hide only that display summary;
   the structured inputs (.address-edit-field rows of street/city/state)
   stay editable and submit normally. */
form[data-admin-flow="1"] .step-panel[data-step="4"] .address-summary { display: none; }

/* Strip the customer-flow validation chrome in admin mode so the form
   reads as plain, consistent input pills (matches the mockup). The
   public flow uses these affordances heavily — green check circles
   confirm each field validated, autofilled address rows lock to a
   muted "confirmed" state with a pencil to unlock for edit. Admins
   don't need any of that: they're filling phone-in bookings and the
   green-check / locked / pencil chrome is visual noise. The inputs
   themselves still validate (form submit still gates on required),
   just no visible decoration. */
form[data-admin-flow="1"] .field-check,
form[data-admin-flow="1"] .field-edit-btn {
  display: none !important;
}
/* Reset the locked-state styling so prefilled fields look identical
   to blank ones. Without this, an autofilled street/city/state read
   as grey/muted inset boxes while a blank first/last name reads as
   the warm-card pill. */
form[data-admin-flow="1"] .field.is-locked input,
form[data-admin-flow="1"] .field.is-locked input:hover,
form[data-admin-flow="1"] .field.is-locked input:focus {
  background: #FFFDF9 !important;
  border-color: #E5DED3 !important;
  color: var(--text);
  cursor: text;
  font-weight: 400;
  padding-right: 14px !important;
  -webkit-text-fill-color: var(--text);
}
/* Remove the right-side padding reservation the check icon needed,
   since the icon is hidden in admin mode. */
form[data-admin-flow="1"] .your-info-grid .field.has-check input {
  padding-right: 14px;
}
/* Strip the emerald border-tint on .is-valid — the green check was
   the primary confirmation signal, the border was secondary. With
   the check hidden, leaving the border in green would just confuse. */
form[data-admin-flow="1"] .field.is-valid input {
  border-color: #E5DED3;
}

/* Trip-charge agreement IS shown in admin mode — it acts as a
   memory prompt so the admin remembers to ask the customer on the
   phone and only ticks the box once they've confirmed verbally.
   The hidden trip_charge_amount input nested inside still ships
   with the form. Re-style the wrapper to fit the admin bento
   aesthetic: warm card-highlight fill against the step-card's warm
   card surface, soft warm border, no big padding — reads as a
   compact confirmation row, not a callout. */
form[data-admin-flow="1"] .trip-charge-agree {
  background: #FFFDF9;
  border: 1px solid #E5DED3;
  border-radius: 14px;
  padding: 12px 16px;
  margin: 18px 0 4px;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.85) inset;
}
form[data-admin-flow="1"] .trip-charge-agree-row {
  display: flex;
  align-items: center;
  gap: 12px;
  cursor: pointer;
}
form[data-admin-flow="1"] .trip-charge-agree-text {
  font-size: 0.92rem;
  color: var(--text);
  line-height: 1.45;
}
form[data-admin-flow="1"] .trip-charge-agree-text strong {
  color: #373B4D;
  font-weight: 700;
}

/* Hide every per-step Back/Continue group. The one button we DO want
   visible (the bottom "Schedule booking" submit) lives outside the
   step panels in .admin-flow-submit-row. !important here because some
   per-step rules later in the file (e.g. step 3's max-width centering
   on `.step-panel[data-step="3"] > .actions`) match with equal
   specificity and were declared after, so the cascade would otherwise
   make .actions visible. */
form[data-admin-flow="1"]:not([data-admin-wizard="1"]) .step-panel .actions,
.booking-page--admin form[data-admin-flow="1"]:not([data-admin-wizard="1"]) .step-panel .actions { display: none !important; }

/* ═══════════ Admin wizard (?wizard=1) ═══════════
   Stepped variant of the admin scheduler. It keeps data-admin-flow set
   (so all the admin ELEMENT styling above still applies) but skips the
   single-page LAYOUT rules (excluded via :not([data-admin-wizard]))
   so the default stepped .step-card behaviour returns: one panel at a
   time and the FLIP height morph. The per-step max-width from
   .step-card[data-active-step] (Customer 920 → Schedule 1200 → Work
   1040) is OVERRIDDEN to one shared width below so the steps align as
   you advance. Only the deltas live here. */
/* Hidden panels MUST stay hidden. The shared single-page rules set
   display on some panels (e.g. step 2 → display:grid) at a higher
   specificity than the UA [hidden] rule, which would otherwise force a
   "hidden" wizard step back into view. This !important override keeps
   showStep's one-panel-at-a-time contract intact. */
form[data-admin-wizard="1"] .step-panel[hidden] { display: none !important; }
/* Re-add the card inset the excluded single-page rule used to supply. */
form[data-admin-wizard="1"] .step-card { padding: 32px 40px; }
@media (max-width: 1100px) { form[data-admin-wizard="1"] .step-card { padding: 26px 28px; } }
@media (max-width: 760px)  { form[data-admin-wizard="1"] .step-card { padding: 20px 18px; } }
/* One consistent card width across the three wizard steps so Customer →
   Schedule → Work LINE UP as you advance. The shared per-step widths in
   .step-card[data-active-step] (Customer 920 → Schedule 1200 → Work 1040)
   were tuned for the PUBLIC flow; in the centered admin wizard they made
   each step re-center at a different width, so the steps didn't align and
   the narrower ones (esp. Work, coming straight after the widest Schedule)
   read as shoved off to one side. Pinning all three to a single width
   means the card box — and the centered 1·2·3 stepper above it — stay put
   step to step. Scoped to wizard mode, so the public flow and the
   single-page admin keep their per-step morph. Inner content keeps its own
   caps (e.g. Work fields at 880) and stays centered within this frame.
   Beats the (0,1,1) base rules via the extra form-attr + step-attr. */
form[data-admin-wizard="1"] .step-card[data-active-step="4"],
form[data-admin-wizard="1"] .step-card[data-active-step="2"],
form[data-admin-wizard="1"] .step-card[data-active-step="3"] {
  max-width: 1120px;
}
/* The Google address lookup is relocated into the Customer step's
   two-column grid (admin-wizard.js); span it full width and give it a
   little breathing room above the structured street/city/state rows. */
form[data-admin-wizard="1"] .your-info-grid .address-field { grid-column: 1 / -1; margin-bottom: 0; gap: 6px; }
/* The address lookup left #step2-prelude (it only held the now-hidden
   property-type pills besides the address). Drop the empty container so
   the Schedule step opens straight onto the calendar. Both selectors so
   it beats the shared force-expand rule whether or not .is-collapsed is
   present. */
form[data-admin-wizard="1"] #step2-prelude,
form[data-admin-wizard="1"] #step2-prelude.is-collapsed { display: none !important; }
/* Residential-confirm + trip-charge are relocated into Customer/Work
   respectively; keep their normal block flow (no single-page resets). */
form[data-admin-wizard="1"] #admin-residential-confirm { margin-top: 4px; }
form[data-admin-wizard="1"] .admin-flow-submit-row { margin-top: 20px; }
/* Every stepper pill is a live jump target in the admin wizard (the
   admin can move between steps in any order), so they all read as
   clickable, not just the visited/done ones. */
form[data-admin-wizard="1"] .stepper .step { cursor: pointer; }

/* Per-step section margins — strip the cosmetic chrome so each
   panel reads as a section, not a separate "page." The flex gap on
   the step-card supplies all the visual separation. The min-height
   reset is critical: the public flow gives every panel a 540px
   min-height so the FLIP morph has something to interpolate between.
   In admin mode all panels are visible at once, so that floor turns
   into hundreds of pixels of empty scroll-space below short sections
   like "Describe the issue."

   Dual-scoped (same reason as the step-card padding above) so it
   can't silently fail if data-admin-flow isn't set. Without the
   step-panel padding reset, the public flow's 48/52 step-panel
   padding would compound with the new 40/56 step-card padding. */
form[data-admin-flow="1"] .step-panel,
.booking-page--admin form[data-admin-flow="1"] .step-panel {
  padding: 0;
  background: transparent;
  border: 0;
  box-shadow: none;
  margin: 0;
  min-height: 0;
}
/* Step 2 in admin contains the address verifier, tech picker, and
   calendar; strip its own internal padding so it lines up with the rest. */
form[data-admin-flow="1"] .step-panel[data-step="2"],
.booking-page--admin form[data-admin-flow="1"] .step-panel[data-step="2"] { padding: 0; min-height: 0; }
form[data-admin-flow="1"] .step-panel[data-step="2"] > *,
.booking-page--admin form[data-admin-flow="1"] .step-panel[data-step="2"] > * {
  margin-left: 0 !important;
  margin-right: 0 !important;
}
form[data-admin-flow="1"] .step-panel[data-step="2"] > #availability,
.booking-page--admin form[data-admin-flow="1"] .step-panel[data-step="2"] > #availability {
  margin-top: 0;
}
/* Steps 1 + 3 + 4 also each carry their own padding/min-height
   overrides (step 1's service grid, step 3's tight text panel, step
   4's centered grid). None of those apply in admin mode — every
   section sits flat inside the step-card and shares its rhythm. */
form[data-admin-flow="1"] .step-panel[data-step="1"],
form[data-admin-flow="1"] .step-panel[data-step="3"],
form[data-admin-flow="1"] .step-panel[data-step="4"],
.booking-page--admin form[data-admin-flow="1"] .step-panel[data-step="1"],
.booking-page--admin form[data-admin-flow="1"] .step-panel[data-step="3"],
.booking-page--admin form[data-admin-flow="1"] .step-panel[data-step="4"] {
  padding: 0;
  min-height: 0;
}
form[data-admin-flow="1"]:not([data-admin-wizard="1"]) .step-panel[data-step="3"],
form[data-admin-flow="1"]:not([data-admin-wizard="1"]) .step-panel[data-step="4"] {
  /* Section rhythm — whitespace only, no visible divider rule.
     Single-page only: in the wizard each step stands alone in the card,
     so this inter-section top padding would just be dead space.
     The earlier hairline border-top kept slicing the page into
     three labeled tiles when the natural reading flow was a
     single continuous form. With the section labels still bolded
     above each block, the visual hierarchy holds without a line.
     Bumped the gap to 28px to give each section a confident
     breathing room now that there's no rule to anchor on. */
  padding-top: 28px;
  margin-top: 8px;
  border-top: 0;
}
/* Step 3's contents (heading + textarea + actions) center inside an
   880px window in the public flow so the textarea has presence
   without sprawling. In admin mode every section needs to share the
   step-card's content width — otherwise the "Describe the issue"
   textarea sits in a narrow column while the customer-info grid
   below it spans the full width. */
form[data-admin-flow="1"] .step-panel[data-step="3"] > .heading-serif,
form[data-admin-flow="1"] .step-panel[data-step="3"] > .ledger-field,
form[data-admin-flow="1"] .step-panel[data-step="3"] > .field,
form[data-admin-flow="1"] .step-panel[data-step="3"] > .actions {
  max-width: none;
  margin-left: 0;
  margin-right: 0;
}

/* Work-summary textarea — convert the ledger ("writing on lined
   paper") style to a proper bento field in admin mode. The public
   flow uses the bare underline because the customer is filling in a
   single thought; in admin the textarea reads as "floating text on
   canvas" without a visible field card around it. Bento treatment:
   warm card-highlight fill, warm hairline border, 14px squircle, soft
   inset highlight, internal padding so the text + placeholder don't
   hug the edges. */
form[data-admin-flow="1"] .ledger-field { gap: 8px; }
form[data-admin-flow="1"] .textarea-ledger {
  border: 1px solid #E5DED3;
  border-radius: 14px;
  background: #FFFDF9;
  padding: 14px 16px;
  /* Override the textarea's rows="5" default (which renders ~150px
     tall) and let admins drag-resize vertically when they need
     more room. Cap so it can't blow out the page. */
  height: 96px;
  min-height: 96px;
  max-height: 280px;
  resize: vertical;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.85) inset;
  font-size: 1rem;
  line-height: 1.5;
  color: #373B4D;
  transition: border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}
form[data-admin-flow="1"] .textarea-ledger::placeholder {
  color: #7B8190;
  font-style: normal;
  opacity: 1;
}
form[data-admin-flow="1"] .textarea-ledger:hover:not(:focus) {
  border-color: rgba(243, 138, 63, 0.35);
  background: #FFFAF1;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.85) inset;
}
form[data-admin-flow="1"] .textarea-ledger:focus {
  outline: none;
  background: #FFFDF9;
  border-color: transparent;
  box-shadow:
    var(--sw-focus-shadow, 0 0 0 1px #F38A3F, 0 6px 13px rgba(243, 138, 63, 0.30)),
    0 1px 0 rgba(255, 255, 255, 0.85) inset;
}
/* Char count + Required label sit beneath the textarea, not against
   its underline (no underline anymore). Tight upper margin since the
   textarea now has its own border-bottom. */
form[data-admin-flow="1"] .ledger-meta {
  padding: 0 4px;
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  color: #7B8190;
}
form[data-admin-flow="1"] .ledger-required {
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  color: #7B8190;
}
/* Tech picker → calendar gap. The tech picker is its own section
   with its own ::before heading, so leave a clean gap before the
   calendar heading kicks in. The step-card's 32px flex gap handles
   the major section-to-section rhythm; this nudges the tech-picker
   section closer to its calendar so the pair reads as related (both
   pick "when to send a tech"). */
form[data-admin-flow="1"] .tech-easter-egg { margin-bottom: 0; }

form[data-admin-flow="1"] .admin-calendar-placeholder {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 22px 24px;
  /* Bento-style empty state: warm dashed border, warm inset fill,
     larger squircle radius matching the rest of the form's sub-cards.
     Reads as "this section is waiting" without feeling like an alert. */
  border: 1px dashed rgba(243, 138, 63, 0.35);
  border-radius: 16px;
  background: #FFFDF9;
  color: #7B8190;
}
form[data-admin-flow="1"] .admin-calendar-placeholder[hidden] { display: none !important; }
form[data-admin-flow="1"] .admin-calendar-placeholder strong {
  color: #373B4D;
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: -0.01em;
}
form[data-admin-flow="1"] .admin-calendar-placeholder span {
  font-size: 0.88rem;
  line-height: 1.5;
}
form[data-admin-flow="1"] #availability:not([hidden]) {
  display: block;
  min-width: 0;
}
form[data-admin-flow="1"] .admin-cal {
  border-radius: 18px;
  padding: 20px;
}
/* ── Wizard Schedule step (2): drop the "card within a card" ──
   On the Schedule step the calendar (.admin-cal) is the only content,
   so its own card chrome sat INSIDE the step-card — two concentric,
   same-fill cards reading as a card-within-a-card, with the
   Back/Continue row stranded in the outer frame beneath it. Strip the
   inner calendar card's chrome (only in the wizard, only on step 2) so
   the step-card is the single surface: the grid expands to its full
   width, the Back button reads as inside that one card, and the
   calendar drops a touch lower. The step-2 .actions row already carries
   margin-top:32px, so Back/Continue keep clear separation below. */
form[data-admin-wizard="1"] .step-panel[data-step="2"] #availability .admin-cal {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
  padding: 0;
  margin-top: 12px;
}
form[data-admin-flow="1"] .admin-cal-header {
  gap: 12px;
  margin-bottom: 14px;
}
form[data-admin-flow="1"] .admin-cal-meter {
  /* Keep the hero-scale gap/padding from the base rule rather than
     tightening them — the admin scheduler is the canonical use of
     this meter and deserves the editorial-KPI presence per the
     design philosophy doc. */
  gap: 22px 36px;
  margin-bottom: 16px;
}
form[data-admin-flow="1"] .admin-cal-grid-wrap {
  max-width: 100%;
}
form[data-admin-flow="1"] .admin-cal-grid {
  /* Flipped axes: tech-label column (left, fits "Firstname Lastname")
     + N time-slot columns. Slots are the small fixed axis (3-4 per
     day at the 3-hour cadence), so each column gets equal share of
     the remaining width. */
  grid-template-columns: 180px repeat(var(--num-slots, 1), minmax(140px, 1fr));
}
@media (max-width: 720px) {
  form[data-admin-flow="1"] .admin-cal {
    padding: 16px;
    border-radius: 16px;
  }
  /* Phone: keep the clustered nav (prev | date | next) center-aligned;
     the cluster fits comfortably even on narrow viewports because the
     nav buttons are now circular 36px icons and the date trigger
     auto-shrinks via padding. No longer need the old wrap-and-stack
     layout that was tuned for the bigger pill-shaped Prev/Next buttons. */
  form[data-admin-flow="1"] .admin-cal-top-row {
    /* Phone: drop the centering spacer so the date pill flows left
       and Today stays right. Tight enough that they share one line. */
    gap: 8px;
  }
  form[data-admin-flow="1"] .admin-cal-top-spacer { display: none; }
  form[data-admin-flow="1"] .admin-cal-strip-cell {
    padding: 4px 3px 8px;
  }
  form[data-admin-flow="1"] .admin-cal-strip-date {
    font-size: 0.96rem;
  }
  form[data-admin-flow="1"] .admin-cal-grid {
    /* Phone: tighter tech-label column, slots still fill remaining
       width. Same flipped axis logic as the desktop rule above. */
    grid-template-columns: 140px repeat(var(--num-slots, 1), minmax(96px, 1fr));
  }
}

/* Submit row — sits inside the step-card, after the last step panel.
   The step-card's flex gap handles the major rhythm; no border-top
   needed (the Review sub-card below already provides a strong visual
   boundary, and the prior hairline read as an orphaned divider with
   no card chrome to anchor it). */
.admin-flow-submit-row {
  padding-top: 24px;
  display: flex;
  flex-direction: column;
  gap: 18px;
  align-items: center;
}

/* Review block — recap of the form contents, sits above the submit
   button. Each row hides itself when the corresponding value is
   empty; the empty-state line shows when no values are populated yet.
   Booking.js (updateAdminReview) drives the populate/hide.

   Bento sub-card: warm card-highlight fill lifts off the step-card's
   own warm card surface, warm soft border + 16px squircle, generous
   padding, soft ambient shadow with warm undertone. */
.admin-flow-review {
  align-self: stretch;
  background: #FFFDF9;
  border: 1px solid #E5DED3;
  border-radius: 16px;
  padding: 20px 22px;
  box-shadow:
    0 6px 18px rgba(55, 59, 77, 0.04),
    0 1px 0 rgba(255, 255, 255, 0.85) inset;
}
.admin-flow-review-heading {
  /* Hero-ish recap title: heavy deep navy ink. Was a serif italic
     header; the bento system uses one geometric sans-serif family
     with weight contrast doing the hierarchy work. */
  font-size: 0.78rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #7B8190;
  margin: 0 0 14px;
  padding-bottom: 10px;
  border-bottom: 1px solid #E5DED3;
}
/* Plan block — "When you submit" preview that lists what will
   happen to HCP (file under existing vs create new, plus per-field
   updates). Sits between the Review heading and the existing key/
   value review rows. Warm inset wash so it reads as a deliberate
   summary, not just another row in the list. */
.admin-flow-plan {
  margin: 0 0 14px;
  padding: 12px 14px;
  background: #FFFDF9;
  border: 1px solid #E5DED3;
  border-radius: 12px;
}
.admin-flow-plan[hidden] { display: none; }
.admin-flow-plan-eyebrow {
  display: block;
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #7B8190;
  margin-bottom: 8px;
}
.admin-flow-plan-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.admin-flow-plan-item {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  font-size: 0.88rem;
  line-height: 1.4;
  color: var(--text);
}
.admin-flow-plan-bullet {
  flex: 0 0 7px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  margin-top: 7px;
  background: #7B8190;
}
/* Header bullet (the "file under existing X" / "create new X" row)
   is the lede; deep navy so it reads as the primary action. */
.admin-flow-plan-item--header .admin-flow-plan-bullet {
  background: #373B4D;
}
.admin-flow-plan-item--header .admin-flow-plan-text {
  font-weight: 700;
  color: #373B4D;
}
/* Update bullets — orange dot mirrors the per-field .is-modified
   indicator on the form fields above so the admin can connect
   "this field has a dot" with "this bullet describes the change." */
.admin-flow-plan-item--update .admin-flow-plan-bullet {
  background: #F38A3F;
}
/* Warn bullets — used for slot overrides (double-book, force-book past
   slot, force-book closed day). Red dot + bolder text + tinted
   background so the admin can't miss it. This is the second-of-two
   warnings the admin sees for a forced slot pick: the calendar popup
   confirms intent, this bullet re-states what's about to happen at
   submit time. */
.admin-flow-plan-item--warn {
  background: rgba(196, 53, 53, 0.07);
  border: 1px solid rgba(196, 53, 53, 0.22);
  border-radius: 10px;
  padding: 8px 10px;
  align-items: center;
}
.admin-flow-plan-item--warn .admin-flow-plan-bullet {
  margin-top: 0;
  background: #C43535;
  box-shadow: 0 0 0 3px rgba(196, 53, 53, 0.15);
}
.admin-flow-plan-item--warn .admin-flow-plan-text {
  color: #8B1F1F;
  font-weight: 600;
}
.admin-flow-plan-text {
  flex: 1 1 auto;
  min-width: 0;
}
.admin-flow-review-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.admin-flow-review-row {
  display: grid;
  grid-template-columns: 104px 1fr;
  gap: 16px;
  align-items: baseline;
  font-size: 0.92rem;
  line-height: 1.4;
}
.admin-flow-review-row[hidden] { display: none; }
.admin-flow-review-label {
  /* Label = uppercase eyebrow. Strong letter-spacing, muted graphite,
     800 weight so it reads as a label not a sentence. */
  color: #7B8190;
  text-transform: uppercase;
  letter-spacing: 0.10em;
  font-size: 0.66rem;
  font-weight: 800;
}
.admin-flow-review-value {
  /* Value = deep navy hero ink, slightly heavier weight so the
     filled rows visually anchor against the labels. */
  color: #373B4D;
  font-weight: 600;
  word-break: break-word;
  font-variant-numeric: tabular-nums;
}
.admin-flow-review-empty {
  margin: 0;
  font-size: 0.85rem;
  color: #7B8190;
  font-style: italic;
}
.admin-flow-review-empty[hidden] { display: none; }
@media (max-width: 600px) {
  .admin-flow-review { padding: 16px 16px 14px; border-radius: 14px; }
  .admin-flow-review-row {
    grid-template-columns: 1fr;
    gap: 2px;
  }
}
/* Hero CTA — this is THE action on the admin booking page. Bigger
   pad, slightly heavier weight, and a soft orange ring under the
   pill so it carries the visual weight of "primary action" per
   philosophy doc: "solid blocks of the accent color... text inside
   is bold and centered." */
.admin-flow-submit-row .btn-primary {
  align-self: center;
  justify-content: center;
  min-width: 260px;
  padding: 16px 40px;
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: 0.005em;
  box-shadow:
    0 8px 22px rgba(243, 138, 63, 0.28),
    0 1px 0 rgba(255, 255, 255, 0.20) inset;
  transition: background 0.18s ease, box-shadow 0.18s ease, transform 0.08s ease;
}
.admin-flow-submit-row .btn-primary:hover:not(:disabled) {
  box-shadow:
    0 12px 28px rgba(243, 138, 63, 0.36),
    0 1px 0 rgba(255, 255, 255, 0.22) inset;
}
.admin-flow-submit-row .btn-primary:active:not(:disabled) {
  box-shadow:
    0 4px 14px rgba(243, 138, 63, 0.30),
    0 1px 0 rgba(255, 255, 255, 0.18) inset;
}
.admin-flow-submit-row .alert {
  margin: 0;
  align-self: stretch;
}
/* Housecall Pro escape-hatch link — quiet so it doesn't compete with
   the primary submit, but always visible at the bottom for the admin
   to jump to HCP for anything the booking page can't do (reschedules,
   line-item edits, attaching photos, refunds, etc.). */
.admin-flow-hcp-link {
  align-self: center;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  margin-top: 4px;
  border: 1px solid rgba(39, 41, 54, 0.10);
  border-radius: 999px;
  background: rgba(39, 41, 54, 0.02);
  font-size: 0.85rem;
  color: var(--text-muted);
  text-decoration: none;
  transition: background 0.15s, color 0.15s, border-color 0.15s, transform 0.05s;
}
.admin-flow-hcp-link:hover {
  background: rgba(39, 41, 54, 0.06);
  color: var(--text);
  border-color: rgba(39, 41, 54, 0.16);
}
.admin-flow-hcp-link:active {
  transform: translateY(1px);
}
.admin-flow-hcp-link svg {
  flex-shrink: 0;
  opacity: 0.7;
}

