/* ══════════════════════════════════════════════════════════════
   Full-stack additions — forms, portal dashboard, record lists.
   Uses the same tokens as site.css so nothing about the approved
   visual design changes.
══════════════════════════════════════════════════════════════ */

/* ── Honeypot (bots fill it, humans never see it) ── */
.hp-field {
  position: absolute !important;
  left: -9999px !important;
  width: 1px; height: 1px;
  opacity: 0; pointer-events: none;
}

/* ── Inline form errors ── */
.form-error {
  display: none;
  background: rgba(196,30,46,.12);
  border: 1px solid rgba(196,30,46,.4);
  color: #ff8f9c;
  padding: 12px 16px;
  border-radius: 8px;
  margin: 14px 0 4px;
  font-size: .85rem;
  font-weight: 600;
  line-height: 1.5;
}
.form-error.show { display: block; }

/* ── Busy state for any submit button ── */
.btn.is-busy { opacity: .6; pointer-events: none; }

/* ── Toast ── */
.portal-toast.error {
  background: var(--red);
  border-color: var(--red2);
}

/* ══════════════════════════════════
   DASHBOARD TABS
══════════════════════════════════ */
.dash-tabs {
  display: flex; gap: 4px; flex-wrap: wrap;
  border-bottom: 1px solid var(--border);
  margin-bottom: 22px;
}
.dash-tab {
  background: none; border: none; border-bottom: 2px solid transparent;
  color: rgba(255,255,255,.45); font-family: inherit;
  font-size: .86rem; font-weight: 700; padding: 11px 16px;
  cursor: pointer; transition: color .18s, border-color .18s;
  display: flex; align-items: center; gap: 7px; white-space: nowrap;
}
.dash-tab:hover { color: rgba(255,255,255,.8); }
.dash-tab.active { color: var(--white); border-bottom-color: var(--red); }
.tab-count {
  font-size: .66rem; font-weight: 800; min-width: 18px;
  padding: 2px 6px; border-radius: 20px;
  background: rgba(255,255,255,.09); color: rgba(255,255,255,.6);
}
.dash-tab.active .tab-count { background: var(--red-lt); color: #ff8f9c; }
.tab-count.alert { background: var(--red); color: #fff; }
.tab-count:empty { display: none; }

.dash-tab-panel { display: none; }
.dash-tab-panel.active { display: block; }

.panel-pad { padding: 20px 24px; }
.panel-hint { font-size: .82rem; color: rgba(255,255,255,.42); line-height: 1.65; }

.dash-panel-header {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; flex-wrap: wrap;
}
.dash-search {
  background: var(--dark3); border: 1px solid var(--border2); color: var(--white);
  font-family: inherit; font-size: .82rem; padding: 8px 12px;
  border-radius: 7px; min-width: 220px;
}
.dash-search:focus { outline: none; border-color: var(--blue2); }
.dash-search::placeholder { color: rgba(255,255,255,.3); }

.filter-row { display: flex; gap: 6px; flex-wrap: wrap; }
.filter-chip {
  background: rgba(255,255,255,.05); border: 1px solid var(--border2);
  color: rgba(255,255,255,.55); font-family: inherit;
  font-size: .72rem; font-weight: 700; padding: 6px 13px;
  border-radius: 20px; cursor: pointer; transition: all .15s;
}
.filter-chip:hover { color: var(--white); border-color: var(--border2); }
.filter-chip.active { background: var(--red); border-color: var(--red); color: #fff; }

/* ══════════════════════════════════
   RECORD LISTS (bookings / quotes / messages / customers)
══════════════════════════════════ */
.record-list { display: flex; flex-direction: column; }
.list-empty {
  padding: 44px 24px; text-align: center;
  color: rgba(255,255,255,.3); font-size: .88rem;
}

.rec {
  border-bottom: 1px solid var(--border);
  transition: background .15s;
}
.rec:last-child { border-bottom: none; }
.rec-head {
  display: flex; align-items: center; gap: 14px;
  padding: 15px 22px; cursor: pointer;
}
.rec-head:hover { background: rgba(255,255,255,.025); }
.rec-main { flex: 1; min-width: 0; }
.rec-title {
  font-size: .92rem; font-weight: 800; color: var(--white);
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
}
.rec-sub {
  font-size: .78rem; color: rgba(255,255,255,.4);
  margin-top: 3px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rec-right { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.rec-amt { font-size: .95rem; font-weight: 900; color: var(--white); }
.rec-caret {
  color: rgba(255,255,255,.3); font-size: .8rem;
  transition: transform .2s; flex-shrink: 0;
}
.rec.open .rec-caret { transform: rotate(90deg); }
.rec-body { display: none; padding: 4px 22px 20px; }
.rec.open .rec-body { display: block; }
.rec-unread .rec-title::before {
  content: ''; width: 7px; height: 7px; border-radius: 50%;
  background: var(--red); flex-shrink: 0;
}

.detail-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(200px,1fr));
  gap: 2px 20px; background: var(--dark2);
  border: 1px solid var(--border); border-radius: 10px; padding: 16px 18px;
}
.detail-item { padding: 6px 0; min-width: 0; }
.detail-key {
  font-size: .64rem; font-weight: 800; letter-spacing: 1px;
  text-transform: uppercase; color: rgba(255,255,255,.32); margin-bottom: 3px;
}
.detail-val { font-size: .85rem; color: rgba(255,255,255,.82); word-break: break-word; }
.detail-val a { color: var(--blue3); text-decoration: none; }
.detail-val a:hover { text-decoration: underline; }
.detail-full { grid-column: 1 / -1; }

.rec-actions {
  display: flex; gap: 8px; flex-wrap: wrap;
  margin-top: 14px; align-items: center;
}
.rec-actions .mini-btn.danger:hover { border-color: var(--red); color: #ff8f9c; }
.rec-actions .mini-btn.go:hover { border-color: #66bb6a; color: #66bb6a; }

.status-select {
  background: var(--dark3); border: 1px solid var(--border2); color: var(--white);
  font-family: inherit; font-size: .75rem; font-weight: 700;
  padding: 6px 10px; border-radius: 6px; cursor: pointer;
}
.status-select:focus { outline: none; border-color: var(--blue2); }

.dash-pill.confirmed { background: rgba(102,187,106,.15); color: #66bb6a; }
.dash-pill.completed { background: rgba(77,130,170,.2); color: #7db6dd; }
.dash-pill.cancelled { background: rgba(255,255,255,.08); color: rgba(255,255,255,.45); }
.dash-pill.paid { background: rgba(102,187,106,.15); color: #66bb6a; }
.dash-pill.unpaid { background: rgba(255,167,38,.15); color: #ffa726; }
.dash-pill.new { background: var(--red); color: #fff; }

.owner-note {
  width: 100%; background: var(--dark3); border: 1px solid var(--border2);
  color: var(--white); font-family: inherit; font-size: .82rem;
  padding: 10px 12px; border-radius: 7px; min-height: 64px;
  resize: vertical; margin-top: 12px;
}
.owner-note:focus { outline: none; border-color: var(--blue2); }
.owner-note::placeholder { color: rgba(255,255,255,.28); }

/* ══════════════════════════════════
   AVAILABILITY / CALENDAR FEED
══════════════════════════════════ */
.blocked-list { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.blocked-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  background: var(--dark2); border: 1px solid var(--border);
  border-radius: 8px; padding: 11px 14px;
}
.blocked-date { font-size: .85rem; font-weight: 700; color: var(--white); }
.blocked-reason { font-size: .76rem; color: rgba(255,255,255,.38); margin-top: 2px; }

.feed-url-box {
  display: flex; align-items: center; gap: 10px;
  background: var(--dark3); border: 1px solid var(--border2);
  border-radius: 8px; padding: 11px 13px; margin-top: 8px;
}
.feed-url-box code {
  flex: 1; min-width: 0; font-size: .74rem; color: var(--blue3);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  overflow-x: auto; white-space: nowrap;
}
.howto { display: flex; flex-direction: column; gap: 9px; margin-top: 8px; }
.howto p { font-size: .78rem; color: rgba(255,255,255,.45); line-height: 1.6; }
.howto strong { color: rgba(255,255,255,.75); font-weight: 700; }

/* ── Calendar day that the owner has blocked off ── */
.cal-day.blocked {
  color: rgba(255,255,255,.2);
  text-decoration: line-through;
  cursor: not-allowed;
  pointer-events: none;
}

/* ── A start time already taken, by a booking or by the owner's own
      calendar. Kept visible rather than hidden so the customer can see
      the day has some availability, just not that slot. ── */
.time-slot.slot-taken {
  opacity: .32;
  cursor: not-allowed;
  text-decoration: line-through;
  border-color: var(--border) !important;
  background: rgba(255,255,255,.02) !important;
}
.time-slot.slot-taken:hover { transform: none; }

/* ── Estimated job length, shown before the customer picks a time so the
      finish time isn't a surprise on the day. ── */
.duration-note {
  display: none;
  margin-top: 20px;
  padding: 13px 16px;
  background: var(--blue-lt);
  border: 1px solid rgba(77,130,170,.4);
  border-radius: 9px;
  font-size: .85rem;
  line-height: 1.6;
  color: #a9d0ea;
}
.duration-note.show { display: block; }
.duration-note strong { color: var(--white); font-weight: 800; }

.slot-hint {
  font-size: .82rem;
  color: rgba(255,255,255,.4);
  margin: 0 0 12px;
  line-height: 1.55;
}
.time-slot .slot-end {
  font-size: .68rem;
  color: rgba(255,255,255,.35);
  margin-top: 3px;
}
.time-slot.selected .slot-end { color: rgba(255,255,255,.65); }

.slots-empty {
  grid-column: 1 / -1;
  padding: 18px;
  text-align: center;
  font-size: .85rem;
  line-height: 1.6;
  color: rgba(255,255,255,.4);
  background: rgba(255,255,255,.03);
  border: 1px dashed var(--border2);
  border-radius: 10px;
}

/* ── Address verification ──────────────────────────────────── */
.addr-hint {
  font-size: .76rem;
  color: rgba(255,255,255,.32);
  margin-top: 6px;
  line-height: 1.5;
}
.addr-check {
  display: none;
  margin-top: 9px;
  padding: 10px 13px;
  border-radius: 8px;
  font-size: .82rem;
  line-height: 1.55;
}
.addr-check.show { display: block; }
.addr-check.checking {
  background: rgba(255,255,255,.04);
  border: 1px solid var(--border2);
  color: rgba(255,255,255,.5);
}
.addr-check.good {
  background: rgba(102,187,106,.1);
  border: 1px solid rgba(102,187,106,.35);
  color: #8fd894;
}
.addr-check.warn {
  background: rgba(255,167,38,.1);
  border: 1px solid rgba(255,167,38,.35);
  color: #ffc670;
}
.addr-check.bad {
  background: rgba(196,30,46,.12);
  border: 1px solid rgba(196,30,46,.4);
  color: #ff8f9c;
}
.addr-check .addr-resolved {
  display: block;
  margin-top: 4px;
  font-size: .78rem;
  opacity: .8;
}

@media (max-width: 620px) {
  .rec-head { padding: 14px 16px; gap: 10px; }
  .rec-body { padding: 4px 16px 18px; }
  .dash-search { min-width: 0; width: 100%; }
}

/* ── Booking wizard step labels ──────────────────────────────
   At phone widths the five labels are wider than their columns, so
   "VEHICLE" and "SCHEDULE" run together. Tightening the type keeps
   each label inside its own step without touching the desktop design. */
@media (max-width: 560px) {
  .step-label { font-size: .55rem; letter-spacing: .3px; }
}
@media (max-width: 400px) {
  .step-label { font-size: .5rem; letter-spacing: 0; }
}

/* ══════════════════════════════════════════════════════════════
   NO SIDEWAYS SCROLLING ON PHONES

   The design's grids use `repeat(auto-fit, minmax(<fixed>px, 1fr))`.
   A fixed minimum can't shrink, so on a narrow phone the track is wider
   than the screen and the whole page pans left-to-right. It compounds
   because grid and flex children default to `min-width: auto`, so an
   inner grid (the add-on picker, say) pushes its parent card wider than
   the viewport too.

   The fix is `min(<fixed>px, 100%)`: behave exactly as before when
   there's room, collapse to the available width when there isn't.
   Nothing changes above these breakpoints.
══════════════════════════════════════════════════════════════ */
.ba-grid        { grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); }
.services-full  { grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); }
.fee-grid       { grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr)); }
.pro-grid,
.pricing-grid,
.processor-row  { grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr)); }
.why-grid       { grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr)); }
.addon-grid     { grid-template-columns: repeat(auto-fill, minmax(min(210px, 100%), 1fr)); }
.dash-stats     { grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr)); }
.detail-grid    { grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr)); }

/* Let grid and flex children shrink instead of forcing their track wider
   than the screen. */
.booking-layout > *,
.quote-layout > *,
.contact-grid > *,
.dash-grid-2 > *,
.split > *,
.fg-row > *,
.ba-grid > *,
.services-full > * { min-width: 0; }

/* Long unbroken text — an email address, a pasted address — must wrap
   rather than widen the page. */
.info-val, .detail-val, .rec-sub, .bs-val { overflow-wrap: anywhere; }

/* ══════════════════════════════════════════════════════════════
   VERTICAL SCROLLING ONLY

   The layout above already fits every phone width, but this makes it
   structural rather than something a future change could quietly undo.
   Three independent guards, because each covers a different failure:

     max-width      nothing can be wider than the screen to begin with
     overflow-x     anything that still is gets clipped, not scrolled
     overscroll     no horizontal rubber-band at the edges on iOS

   `hidden` is declared first as a fallback and `clip` second, so Safari
   16+ and modern Chrome take `clip` — which does not create a scroll
   container and so leaves the sticky nav working — while older iOS,
   which ignores `clip`, still gets `hidden`.
══════════════════════════════════════════════════════════════ */
html, body {
  max-width: 100%;
  overflow-x: hidden;
  overflow-x: clip;
  overscroll-behavior-x: none;
}

/* Touch drags scroll the page up and down and nothing else. pinch-zoom is
   named explicitly so it keeps working — locking zoom out would make the
   site unreadable for anyone who needs to enlarge it. */
body { touch-action: pan-y pinch-zoom; }

/* Except where something is genuinely meant to scroll sideways inside
   itself — the calendar feed URL, and any wide block added later. Without
   this they would become unreachable on a touch screen. */
.feed-url-box code,
.dash-table,
[data-scroll-x] {
  touch-action: auto;
  overscroll-behavior-x: contain;
}

/* iOS Safari inflates text in some layouts, which can widen a container
   past the viewport. Opt out — the design is already responsive. */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

/* Reclaim horizontal room on small phones, where 24px each side plus the
   wizard's own 36px leaves very little for the content itself. */
@media (max-width: 480px) {
  .section, .section-sm { padding-left: 16px; padding-right: 16px; }
  .wizard-step { padding-left: 18px; padding-right: 18px; }
  .wizard-progress { padding-left: 14px; padding-right: 14px; }
  .quote-card, .contact-msg-card { padding-left: 20px; padding-right: 20px; }
}

/* ── Owner's schedule editor on a booking ──────────────────────
   How long a detail takes depends on the vehicle in front of him, so the
   estimate is only a starting point and this is where the real number
   gets set. */
.sched-editor {
  margin-top: 14px;
  padding: 14px 16px;
  background: var(--dark2);
  border: 1px solid var(--border2);
  border-radius: 10px;
}
.sched-title {
  font-size: .68rem; font-weight: 800; letter-spacing: 1px;
  text-transform: uppercase; color: rgba(255,255,255,.4); margin-bottom: 11px;
}
.sched-row { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; }
.sched-row label {
  display: flex; flex-direction: column; gap: 5px;
  font-size: .72rem; font-weight: 700; color: rgba(255,255,255,.5);
}
.sched-row select {
  background: var(--dark3); border: 1px solid var(--border2); color: var(--white);
  font-family: inherit; font-size: .82rem; font-weight: 600;
  padding: 8px 11px; border-radius: 7px; cursor: pointer; min-width: 130px;
}
.sched-row select:focus { outline: none; border-color: var(--blue2); }
.sched-hint {
  font-size: .74rem; color: rgba(255,255,255,.35);
  margin-top: 10px; line-height: 1.55;
}

@media (max-width: 620px) {
  .sched-row { flex-direction: column; align-items: stretch; }
  .sched-row select { width: 100%; }
}
