/* Booking Board management UI (dashboard + editor)
 * Plan: docs/plans/BOOKING-BOARD-DEFINITIVE-BUILD-PLAN-2026-06-20.md §4 Stage 5
 * Loaded after style.css so these rules win; scoped to .bb-* / .bb-modal. */

/* Overlay container. booking-board-dashboard.js mounts
 * <div class="modal-overlay bb-overlay"> straight onto <body>, but the project
 * has no base `.modal-overlay` rule (other modals are inline in index.html and
 * style their own wrappers), so without this the overlay rendered as an
 * unpositioned, invisible static block at the foot of the page — tapping
 * "Booking board" did nothing. Give it the standard full-viewport scrim +
 * centred dialog. */
.bb-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal, 3000);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(15, 23, 42, 0.55);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  overflow-y: auto;
  overscroll-behavior: contain;
  animation: bbOverlayIn 0.18s ease-out;
}

@keyframes bbOverlayIn { from { opacity: 0; } to { opacity: 1; } }

/* On phones the dialog should use the full width and not get clipped by the
 * viewport — cap its height and let the body scroll inside. */
@media (max-width: 640px) {
  .bb-overlay { padding: 12px; align-items: flex-start; }
  .bb-overlay .bb-modal { max-height: calc(100dvh - 24px); }
}

.bb-modal { max-width: 640px; width: 100%; }

/* Rounded BOTTOM (2026-07-20, user: "the bottom of the booking board is
   currently square"). The panel inherits a full border-radius from the base
   .modal-content, but the pinned .modal-footer action bar at the bottom carries
   its own --surface-secondary background + top border and, as the last flex
   child filling the panel's bottom edge, its square corners showed through
   (the parent's overflow-clip rounds the panel box, but the footer's opaque
   fill reads as a square shelf inside it). Round the footer's bottom corners to
   match the panel so the whole board ends in a clean radius. Belt-and-braces:
   also pin the panel radius explicitly so a future base-token change can't
   re-square it. */
.bb-modal { border-radius: var(--radius-2xl, 20px); overflow: hidden; }
.bb-modal .modal-footer,
.bb-modal .bb-editor-footer,
/* WHATEVER ENDS THE PANEL (2026-08-14, user: "Booking board initially loads
   with a jagged rather than rounded bottom"). The rule rounded only the FOOTER
   - but show() mounts header + body with NO footer, so during "Loading..." the
   last child is .modal-body, an opaque square-cornered surface painting over
   the rounded panel. */
.bb-modal > :last-child {
  border-bottom-left-radius: var(--radius-2xl, 20px);
  border-bottom-right-radius: var(--radius-2xl, 20px);
}

/* The base `.modal-content` rule (style.css) caps the dialog at max-height:90vh
 * with overflow:hidden and lays its children out as a flex column. The booking
 * board now adopts the app-canonical shell — `.modal-header` (pinned) /
 * `.modal-body` (the large scrollable white area: padding, flex:1, overflow-y:
 * auto) / `.modal-footer` (pinned action bar). `.bb-body` keeps its class only as
 * a scoping hook for the booking-board-specific field styles below; it inherits
 * all its scroll/padding/white surface from `.modal-body`. Scoped so every other
 * modal that shares `.modal-content` is untouched. */
.bb-modal { display: flex; flex-direction: column; }
.bb-modal .modal-header { flex-shrink: 0; }
.bb-loading, .bb-error { padding: 24px 4px; color: var(--text-secondary, #64748b); }
.bb-error { color: var(--danger-fg, #b91c1c); }
/* ⭐2026-08-20 (owner: "New booking board area still has a lot of scrollable
   space"). The editor's inline form-error box ships as
   `<div class="bb-error hidden" id="bb-formerr">` — but `.hidden` is NOT
   defined in this stylesheet, so the "hidden" box rendered as an empty
   BLOCK. Measured live in the created-board editor: 548px tall — more than
   every real field in the form combined (the whole body scrolled 1451px for
   ~900px of content). It also keeps its 24px padding while empty. Hide it
   properly, and collapse ANY empty .bb-error so a cleared error leaves no
   ghost gap behind. */
.bb-error.hidden,
.bb-error[hidden] { display: none; }
.bb-error:empty { display: none; padding: 0; }

/* Empty / upsell state */
.bb-empty { padding: 8px 4px 4px; }
.bb-empty p { color: var(--text-secondary, #64748b); margin: 0 0 16px; line-height: 1.55; }

/* Board row */
.bb-row {
  display: flex; gap: 12px; align-items: flex-start; justify-content: space-between;
  padding: 14px 0; border-bottom: 1px solid var(--border-color, #e2e8f0); flex-wrap: wrap;
}
.bb-row:last-of-type { border-bottom: 0; }
.bb-row-main { min-width: 0; flex: 1 1 260px; }
.bb-row-title { font-weight: 600; display: flex; align-items: center; gap: 8px; }
.bb-row-url { font-size: .85rem; margin: 3px 0; word-break: break-all; }
.bb-row-url a { color: var(--primary-700, #0f766e); }
.bb-row-meta { font-size: .82rem; color: var(--text-secondary, #64748b); }
.bb-row-actions { display: flex; flex-wrap: wrap; gap: 6px; align-items: flex-start; }

.bb-chip { font-size: .68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  padding: 2px 7px; border-radius: 999px; }
.bb-chip--live { background: rgba(20, 184, 166, 0.14); color: var(--primary-700, #0f766e); }
.bb-chip--disabled { background: rgba(148, 163, 184, 0.18); color: var(--text-secondary, #64748b); }
.bb-chip--expired { background: var(--danger-bg, #fef2f2); color: var(--danger-fg, #b91c1c); }
.bb-chip--incomplete { background: #fef3c7; color: #92400e; }

/* Empty-board (no declared availability) guidance banner */
.bb-setup-banner {
  background: #fffbeb; border: 1px solid #fde68a; color: #92400e;
  border-radius: 8px; padding: 10px 12px; margin-bottom: 14px; font-size: .9rem; line-height: 1.5;
}
/* Per-row: the page is live but a visitor would see no times (2026-09-26). */
.bb-row-warn {
  background: #fffbeb; border: 1px solid #fde68a; color: #92400e;
  border-radius: 6px; padding: 6px 10px; margin-top: 6px; font-size: .85rem; line-height: 1.45;
}
.bb-link-btn {
  background: none; border: 0; padding: 0; font: inherit; font-weight: 600;
  color: #92400e; text-decoration: underline; cursor: pointer;
}
/* The booking count in a row's meta line opens "Your bookings" (2026-09-23).
   Same link shape as .bb-link-btn, in the brand teal rather than the
   warning banner's amber. */
.bb-row-meta .bb-bookings-link { color: var(--primary-700, #0f766e); }
.bb-row-meta .bb-bookings-link:focus-visible { outline: 2px solid var(--primary-600, #0d9488); outline-offset: 2px; border-radius: 2px; }
.bb-hours-source { font-size: .88rem; color: var(--text-secondary, #64748b); }

/* ⭐ 2026-09-17 (owner: "the button seems too small"). MEASURED before
   changing anything: 34x34 on a fine pointer, and 44 high on touch only
   because the global (pointer: coarse) rule lifts it. Raised to a 36px floor,
   which stays under the 44px touch minimum the coarse rule already enforces.
   2026-09-23: the LOOK now comes from the app's own buttons (btn btn-sm +
   btn-primary / btn-secondary / btn-ghost) — this page had a third, private
   button family. .bb-btn keeps only the owner's floor (btn-sm is 32px);
   .bb-btn--primary stays as the marker for the row's ONE primary action.
   2026-09-30 (launch fix F16): the floor is 44px on EVERY pointer, the
   owner's touch-target norm; 36 measured 36 tall at 412 on a phone. */
.bb-btn {
  min-height: 44px;
}
.bb-btn--danger { color: var(--danger-fg, #b91c1c); }
.bb-btn--danger:hover { background: var(--danger-bg, #fef2f2); }

/* Dashboard empty-state footer (holds the single "Create booking board" button).
 * The editor uses the app-canonical .modal-footer (pinned action bar) instead. */
.bb-footer { display: flex; gap: 10px; align-items: center; margin-top: 18px; }

/* Editor */
.bb-editor { display: block; }
.bb-field { display: block; margin-bottom: 16px; }
.bb-field-label { display: block; font-size: .85rem; font-weight: 600;
  color: var(--text-secondary, #64748b); margin-bottom: 6px; }
.bb-field input[type=text],
.bb-field select,
.bb-field textarea {
  width: 100%; font: inherit; padding: 9px 11px; border-radius: var(--input-radius, 12px);
  border: 1px solid var(--border-color, #e2e8f0);
  background: var(--surface-primary, #fff); color: var(--text-primary, #1e293b);
}
.bb-field textarea { resize: vertical; min-height: 64px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .85rem; }

.bb-slugrow { display: flex; align-items: stretch; border: 1px solid var(--border-color, #e2e8f0);
  border-radius: var(--input-radius, 12px); overflow: hidden; }
.bb-slugpre { display: flex; align-items: center; padding: 0 8px; font-size: .82rem;
  color: var(--text-secondary, #64748b); background: var(--surface-secondary, #f8fafc); white-space: nowrap; }
.bb-slugrow input { border: 0 !important; border-radius: 0 !important; flex: 1; }
.bb-slughint { font-size: .8rem; margin-top: 5px; min-height: 1em; }
.bb-slughint.bb-ok { color: var(--primary-700, #0f766e); }
.bb-slughint.bb-warn { color: #b45309; }

/* Toggle groups ("Stays live for", "Visitors can") use the app-canonical
 * .option-pill capsules (visual styling lives in css/board-modals.css). This
 * only lays them out in a wrapping row, mirroring .create-board-options. The
 * pills are not flex:1 here — they should size to their label, not stretch. */
.bb-pillgroup { display: flex; flex-wrap: wrap; gap: 8px; }
.bb-pillgroup .option-pill { flex: 0 0 auto; }

.bb-embedhint { font-size: .8rem; margin-top: 6px; color: var(--text-secondary, #64748b); }
.bb-embedhint--warn { color: #b45309; }

/* Theme editor — accent colour row */
.bb-accent-row { display: inline-flex; gap: 8px; align-items: center; }
.bb-accent-row input[type=color] { width: 44px; height: 36px; padding: 2px; border: 1px solid var(--border-color, #e2e8f0); border-radius: var(--input-radius, 12px); background: none; cursor: pointer; }
.bb-accent-hex { width: 110px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.bb-accent-hex.bb-invalid { border-color: var(--danger-fg, #b91c1c); }

/* Embed preview */
.bb-preview { margin-top: 4px; }
.bb-preview-frame { width: 100%; max-width: 560px; height: 420px; border: 1px solid var(--border-color, #e2e8f0); border-radius: 10px; background: #fff; }

/* Booking rules disclosure (collapsible secondary controls in the editor) */
.bb-rules { margin-bottom: 16px; border: 1px solid var(--border-color, #e2e8f0); border-radius: 10px; overflow: hidden; }
.bb-rules-summary {
  display: flex; align-items: baseline; gap: 8px; cursor: pointer; list-style: none;
  padding: 11px 13px; font-size: .9rem; font-weight: 600; color: var(--text-primary, #1e293b);
  background: var(--surface-secondary, #f8fafc);
}
.bb-rules-summary::-webkit-details-marker { display: none; }
.bb-rules-summary i { color: var(--primary-700, #0f766e); }
.bb-rules-title { flex: 0 0 auto; }
.bb-rules-sub { flex: 1 1 auto; min-width: 0; font-weight: 400; font-size: .82rem;
  color: var(--text-secondary, #64748b); text-align: right; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bb-rules[open] .bb-rules-sub { display: none; } /* the inputs below say it once open */
.bb-rules-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 14px;
  padding: 14px 13px 4px;
}
.bb-rule { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.bb-rule-label { font-size: .8rem; font-weight: 600; color: var(--text-secondary, #64748b); }
.bb-rule-num {
  width: 100%; font: inherit; padding: 8px 10px; border-radius: var(--input-radius, 12px);
  border: 1px solid var(--border-color, #e2e8f0);
  background: var(--surface-primary, #fff); color: var(--text-primary, #1e293b);
}
.bb-rule-tiers { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; padding: 6px 13px 4px; font-size: .85rem; }
.bb-rule-tiers-label { font-weight: 600; color: var(--text-secondary, #64748b); }
.bb-rule-tiers label { display: inline-flex; align-items: center; gap: 5px; cursor: pointer; }
.bb-rules-help { padding: 4px 13px 13px; margin: 0; font-size: .78rem; line-height: 1.5; color: var(--text-secondary, #64748b); }

/* Pointer to the OTHER booking tool (2026-09-23): this page books you; a
   group's "Booking links" share bookings across members. */
.bb-pointer { margin: 16px 0 0; padding-top: 12px; border-top: 1px solid var(--border-color, #e2e8f0);
  font-size: .85rem; line-height: 1.5; color: var(--text-secondary, #64748b); }
.bb-pointer i { color: var(--primary-600, #0d9488); margin-right: 4px; }

/* DARK MODE (2026-09-23). This sheet had none: surfaces flipped via the base
   modal, but every literal hex (chips, the amber setup banner, danger red,
   the slug hints) stayed light-on-light. Same toggle as team-booking-admin.css
   (body.dark-mode, never the OS query) and the same danger/amber values, so
   the two booking screens read as one family. */
body.dark-mode .bb-row-url a,
body.dark-mode .bb-rules-summary i,
body.dark-mode .bb-slughint.bb-ok { color: var(--primary-400, #2dd4bf); }
body.dark-mode .bb-chip--live { background: rgba(45, 212, 191, 0.16); color: var(--primary-400, #2dd4bf); }
body.dark-mode .bb-chip--expired { background: rgba(153, 27, 27, 0.25); color: #fecaca; }
body.dark-mode .bb-chip--incomplete { background: rgba(180, 83, 9, 0.22); color: #fcd34d; }
body.dark-mode .bb-error,
body.dark-mode .bb-btn--danger { color: #fca5a5; }
body.dark-mode .bb-btn--danger:hover { background: rgba(153, 27, 27, 0.25); color: #fca5a5; }
body.dark-mode .bb-row-warn { background: rgba(180, 83, 9, 0.16); border-color: rgba(251, 191, 36, 0.35); color: #fcd34d; }
body.dark-mode .bb-setup-banner { background: rgba(180, 83, 9, 0.16); border-color: rgba(251, 191, 36, 0.35); color: #fcd34d; }
body.dark-mode .bb-link-btn { color: #fcd34d; }
body.dark-mode .bb-row-meta .bb-bookings-link { color: var(--primary-300, #5eead4); }
body.dark-mode .bb-slughint.bb-warn,
body.dark-mode .bb-embedhint--warn { color: #fbbf24; }

@media (max-width: 540px) {
  .bb-row-actions { width: 100%; }
  .bb-rules-grid { grid-template-columns: 1fr; }
  .bb-rules-sub { display: none; } /* avoid summary line wrapping on narrow screens */
}

/* Where you'll meet (2026-09-23): video link on its own line, then type +
   phone/address side by side; stacks on phones. Inputs inherit .bb-field. */
.bb-where-row { display: grid; grid-template-columns: minmax(150px, 1fr) 2fr; gap: 8px; margin-top: 8px; }
@media (max-width: 540px) { .bb-where-row { grid-template-columns: 1fr; } }

/* ── "When can people book you?" weekly hours (2026-09-26) ─────────────
   Same cells as the temporary-group hour grid: grey not open, light teal
   Possible, clear teal Preferred (one teal family, owner 2026-10-02/03). One
   weekday at a time, 6 × 4 cells, so each cell is tappable on a phone. The
   cells print only their hour: the level is the colour, and its word is in
   the legend and each cell's label. */
.bb-hours { border: 1px solid var(--slate-200, #e2e8f0); border-radius: 10px; padding: 10px 12px; margin: 14px 0; }
.bb-hours > summary { cursor: pointer; font-weight: 600; list-style: none; }
.bb-hours > summary::-webkit-details-marker { display: none; }
.bb-hours-intro, .bb-hours-alt { font-size: .86rem; color: var(--text-secondary, #64748b); margin: 8px 0; }
/* The how-to sentence sits behind an (i) beside the title, closed by default
   (2026-10-02, owner: it took a lot of room); grid, days and key stay shown.
   Inside the <details>, so it only shows while the section is open. */
.bb-hours { position: relative; }
.bb-hours > summary { padding-right: 48px; }
.bb-hours-help-btn { position: absolute; top: 10px; right: 6px; width: 44px; height: 44px; display: inline-flex;
  align-items: center; justify-content: center; border: 0; border-radius: 50%; background: transparent;
  color: var(--text-secondary, #64748b); font-size: 1rem; cursor: pointer; }
.bb-hours-help-btn:hover, .bb-hours-help-btn[aria-expanded="true"] { color: var(--primary-700, #0f766e); background: var(--surface-2, #eef1f5); }
.bb-hours-intro[hidden] { display: none; }
body.dark-mode .bb-hours-help-btn:hover, body.dark-mode .bb-hours-help-btn[aria-expanded="true"] { background: #1e293b; color: #5eead4; }
/* The day row is the setup editor's (.day-selector / .day-pill, style.css +
   css/days-off.css; 2026-09-29): same pills, same day-off / Guarded marks.
   Here it only aligns left and marks a day that holds bookable hours. */
.whg-days.day-selector { justify-content: flex-start; margin: 8px 0; }
/* Seven days on one line at 360px (2026-10-02): the pills share the width
   and keep their 44px height; the coarse-pointer min-width is released. */
.whg-days.day-selector { flex-wrap: nowrap; gap: 4px; }
.whg-days.day-selector > .whg-day { flex: 1 1 0; min-width: 0; max-width: 48px; min-height: 44px; }
.whg-day.day-pill.has-hours:not(.active)::after { content: ''; position: absolute; top: -2px; right: -2px; width: 6px; height: 6px;
  border-radius: 50%; background: var(--status-available, #22c55e); display: block; }
.whg-daynote { font-size: .8rem; color: var(--text-secondary, #64748b); margin: 0 0 8px; }/* One continuous bar per row, grey until marked; a marked stretch is one
   rounded run (run-s / run-e set in the grid's cellClass). Same look as the
   temporary-group hour grid (2026-09-26, owner: "Why ugly square blocks"). */
/* AM and PM rows (2026-10-02, owner: "I'd rather an AM and PM line"): a
   label column, then twelve hours a row. The coarse-pointer floor
   (style.css: [role="button"] { min-width: 44px }) held each cell at 44px
   (528px in a 300px box), so it is released inside the grid: cells are
   ~22-26px wide on a phone and stay 44px tall. */
.whg-cells { display: grid; grid-template-columns: auto repeat(12, minmax(0, 1fr)); row-gap: 6px; column-gap: 0;
  align-items: stretch; touch-action: none; user-select: none; }
.whg-cells > .whg-hour { min-width: 0; }
.whg-rowlabel { display: flex; align-items: center; padding-right: 6px; font-size: .72rem; font-weight: 700;
  letter-spacing: .02em; color: var(--text-secondary, #64748b); }
.whg-cells.is-idle { opacity: .5; }
.whg-dayhint { font-size: .8rem; color: var(--text-secondary, #64748b); margin: 8px 0 0; }
.whg-hour { min-height: 40px; display: flex; align-items: center; justify-content: center; border-radius: 0;
  position: relative; background: var(--surface-2, #eef1f5); box-shadow: inset -1px 0 0 rgba(15, 23, 42, 0.07);
  color: var(--slate-900, #0f172a); font-size: 11px; font-weight: 600; cursor: pointer;
  font-variant-numeric: tabular-nums; overflow: hidden; }
.whg-hour.row-e, .whg-hour.is-open:not(.run-e), .whg-hour.is-best:not(.run-e) { box-shadow: none; }
.whg-hour.row-s { border-top-left-radius: 10px; border-bottom-left-radius: 10px; }
.whg-hour.row-e { border-top-right-radius: 10px; border-bottom-right-radius: 10px; }
/* The colour is a layer over the grey track, so run corners sit on grey. */
.whg-hour.is-open::before, .whg-hour.is-best::before { content: ''; position: absolute; inset: 0; z-index: 0; }
.whg-hour.is-open { color: var(--level-possible-ink, #0f172a); }
.whg-hour.is-best { color: var(--level-preferred-ink, #0f172a); }
.whg-hour.is-open::before { background: var(--level-possible, #99f6e4); }
.whg-hour.is-best::before { background: var(--level-preferred, #0d9488); }
.whg-hour.run-s::before { border-top-left-radius: 8px; border-bottom-left-radius: 8px; }
.whg-hour.run-e::before { border-top-right-radius: 8px; border-bottom-right-radius: 8px; }
.whg-hour.row-s::before { border-top-left-radius: 10px; border-bottom-left-radius: 10px; }
.whg-hour.row-e::before { border-top-right-radius: 10px; border-bottom-right-radius: 10px; }
.whg-hour > * { position: relative; z-index: 1; }
/* A part-open hour (an edge on the quarter hour) draws its quarters. */
.whg-hour > .whg-q { position: absolute; inset: 0; z-index: 0; border-radius: inherit; }
/* The picked days disagree here. */
.whg-hour.is-differs { background-image: repeating-linear-gradient(135deg, rgba(100, 116, 139, 0.28) 0 4px, transparent 4px 8px); }
.whg-sw.is-differs { background-image: repeating-linear-gradient(135deg, rgba(100, 116, 139, 0.55) 0 2px, transparent 2px 4px); }
.whg-legend { display: flex; flex-wrap: wrap; gap: 6px 12px; font-size: .8rem; color: var(--text-secondary, #64748b); margin: 8px 0; }
.whg-legend span { display: inline-flex; align-items: center; gap: 4px; }
.whg-sw { display: inline-block; width: 10px; height: 10px; border-radius: 2px; background: var(--surface-2, #eef1f5); box-shadow: inset 0 0 0 1px rgba(15, 23, 42, 0.12); }
.whg-sw.is-open { background: var(--level-possible, #99f6e4); }
.whg-sw.is-best { background: var(--level-preferred, #0d9488); }
.whg-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.whg-actions [data-whg="save"] { margin-left: auto; }
.whg-note { font-size: .8rem; color: var(--text-secondary, #64748b); margin: 8px 0 0; }
.whg-status { font-size: .85rem; margin: 6px 0 0; min-height: 1em; }
.whg-status--ok { color: var(--primary-700, #0f766e); }
.whg-status--warn, .whg-status--error { color: #b45309; }
/* Exact times (2026-10-03): each open stretch is a tappable time under the
   hours; tapping one opens the 15-minute editor. Cell taps are unchanged. */
.whg-runs { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 8px 0 0; }
.whg-runs:empty { display: none; }
.whg-runs-label { flex-basis: 100%; font-size: .8rem; color: var(--text-secondary, #64748b); }
.whg-run { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 12px; border-radius: 999px;
  border: 1px solid var(--border-color, #cbd5e1); background: var(--surface-1, #fff); color: inherit; font: inherit; font-size: .85rem;
  font-variant-numeric: tabular-nums; cursor: pointer; }
/* The level colour on BOTH ends of the pill (2026-10-05, owner: "colour on
   both edges not just one side"). */
.whg-run.is-open { box-shadow: inset 4px 0 0 var(--level-possible, #99f6e4), inset -4px 0 0 var(--level-possible, #99f6e4); }
.whg-run.is-best { box-shadow: inset 4px 0 0 var(--level-preferred, #0d9488), inset -4px 0 0 var(--level-preferred, #0d9488); }
.whg-run.is-editing { border-color: var(--primary-600, #0d9488); }
.whg-run i { font-size: .75rem; opacity: .7; }
.whg-editor { margin: 8px 0 0; padding: 10px 12px; border: 1px solid var(--border-color, #cbd5e1); border-radius: 12px; background: var(--surface-1, #fff); }
.whg-ed-range { margin: 0 0 6px; font-weight: 700; font-size: 1rem; font-variant-numeric: tabular-nums; }
.whg-ed-row { display: flex; align-items: center; gap: 8px; margin: 4px 0; }
.whg-ed-name { min-width: 3.5em; font-size: .85rem; color: var(--text-secondary, #64748b); }
.whg-ed-step { width: 44px; height: 44px; border-radius: 10px; border: 1px solid var(--border-color, #cbd5e1);
  background: var(--surface-2, #eef1f5); color: inherit; font-size: 1.1rem; cursor: pointer; }
.whg-ed-step:disabled { opacity: .4; cursor: default; }
.whg-ed-val { min-width: 5.5em; text-align: center; font-variant-numeric: tabular-nums; }
.whg-ed-levels { display: flex; gap: 6px; margin: 8px 0 4px; }
.whg-ed-lv { min-height: 44px; padding: 0 14px; border-radius: 10px; border: 1px solid var(--border-color, #cbd5e1);
  background: var(--surface-1, #fff); color: inherit; font: inherit; font-size: .85rem; cursor: pointer; }
.whg-ed-lv.is-on { border-color: var(--primary-600, #0d9488); box-shadow: inset 0 0 0 1px var(--primary-600, #0d9488); font-weight: 600; }
.whg-ed-days { margin: 4px 0; font-size: .8rem; color: var(--text-secondary, #64748b); }
.whg-ed-actions { display: flex; gap: 6px; justify-content: flex-end; }
.whg-ed-actions .btn { min-height: 44px; }
.whg-diffhint { font-size: .8rem; color: var(--text-secondary, #64748b); margin: -4px 0 8px; }
.whg-connect { font-size: .85rem; margin: 6px 0 0; }
.whg-actions [data-whg="fillcal"].is-locked i { font-size: .75em; margin-right: 2px; }
/* The bulk actions rest NEUTRAL (2026-10-05, owner: they "appear as always
   selected (teal)"): btn-secondary's teal tint is the same look as a
   selected day chip. Teal means ON here: a fill that is applied shows
   pressed, and pressing it again takes it out. */
.whg-actions .btn-secondary:not(.is-on), .whg-actions .btn-ghost {
  background: var(--surface-primary, #fff); border: 1px solid var(--border-color, #e2e8f0);
  color: var(--text-primary, #1e293b); box-shadow: none; }
.whg-actions .btn-secondary:not(.is-on):hover, .whg-actions .btn-ghost:hover {
  background: var(--surface-secondary, #f8fafc); border-color: var(--slate-300, #cbd5e1); }
body.dark-mode .whg-actions .btn-secondary:not(.is-on), body.dark-mode .whg-actions .btn-ghost {
  background: #0f172a; border-color: #334155; color: #e2e8f0; }
.whg-actions .btn.is-on { background: var(--primary-50, #f0fdfa); border-color: var(--primary-500, #14b8a6); color: var(--primary-700, #0f766e); box-shadow: inset 0 0 0 1px var(--primary-500, #14b8a6); }
body.dark-mode .whg-run, body.dark-mode .whg-editor, body.dark-mode .whg-ed-lv { background: #0f172a; border-color: #334155; }
body.dark-mode .whg-ed-step { background: #1e293b; border-color: #334155; }
.bb-groups { margin-top: 14px; }
.bb-group-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 6px 0;
  border-top: 1px solid var(--slate-100, #f1f5f9); }
.bb-group-name { font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
body.dark-mode .bb-hours { border-color: var(--slate-700, #334155); }
body.dark-mode .whg-hour { background: #1e293b; color: #f1f5f9; box-shadow: inset -1px 0 0 rgba(255, 255, 255, 0.06); }
body.dark-mode .whg-hour.is-open { color: var(--level-possible-ink, #f0fdf4); }
body.dark-mode .whg-hour.is-best { color: var(--level-preferred-ink, #0f172a); }
body.dark-mode .whg-sw { background: #1e293b; }
body.dark-mode .whg-sw.is-open { background: var(--level-possible, #0f766e); }
body.dark-mode .whg-sw.is-best { background: var(--level-preferred, #2dd4bf); }
body.dark-mode .bb-group-row { border-top-color: var(--slate-700, #334155); }

/* "Also offer" meeting lengths (2026-09-29): a wrap of plain checkboxes. */
.bb-also, .tba-also { display: flex; flex-wrap: wrap; gap: 6px 14px; }
.bb-also-opt, .tba-also-opt { display: inline-flex; align-items: center; gap: 6px; min-height: 32px; font-size: .9rem; cursor: pointer; }

/* ── 44px TOUCH TARGETS (launch fix F16, 2026-09-30) ─────────────────────
   Measured at 412 in the launch audit: "3 bookings" 70x20, "Set your
   availability" 129x20, day chips 45x34, hour cells 44x40, length checkboxes
   32 tall, pills 38, number fields 39, the hours <summary> 21. Every control
   on this screen now clears 44px tall, on any pointer. The link-styled
   buttons keep their look and grow an invisible 44px box. */
.bb-overlay .bb-link-btn,
.bb-row-meta .bb-bookings-link { display: inline-flex; align-items: center; min-height: 44px; }
.bb-row-url a { display: inline-flex; align-items: center; min-height: 44px; max-width: 100%; overflow-wrap: anywhere; }
.bb-hours > summary { display: flex; align-items: center; gap: 6px; min-height: 44px; }
.whg-day { min-height: 44px; }
.whg-hour { min-height: 44px; }
.bb-also-opt, .tba-also-opt { min-height: 44px; }
.bb-also-opt input, .tba-also-opt input,
.bb-rule-tiers input, .bb-rule-shape input, .bb-rule-approve input { width: var(--checkbox-size, 18px); height: var(--checkbox-size, 18px); margin: 0; flex: 0 0 auto; }
.bb-rule-tiers label, .bb-rule-shape label, .bb-rule-approve label { min-height: 44px; display: inline-flex; align-items: center; gap: 8px; }
.bb-rule-shape, .bb-rule-approve { padding: 0 13px; }
.bb-pillgroup .option-pill { min-height: 44px; }
.bb-editor input[type=text], .bb-editor input[type=number], .bb-editor input[type=date],
.bb-editor select, .bb-rule-num { min-height: 44px; box-sizing: border-box; }
.bb-accent-row input[type=color] { height: 44px; }
.bb-durrow { display: flex; gap: 8px; align-items: center; }
.bb-durrow select { flex: 1 1 auto; min-width: 0; }
.bb-durrow input { width: 96px; flex: 0 0 auto; }
#bb-expires { display: block; margin-bottom: 8px; }
/* Unsaved hours (F26): stops the close and asks, in the panel's footer. */
.bb-unsaved { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 8px 0;
  padding: 8px 10px; border-radius: 8px; background: #fffbeb; border: 1px solid #fde68a; color: #92400e; font-size: .88rem; }
.bb-unsaved span { flex: 1 1 100%; }
.bb-unsaved .btn { min-height: 44px; }
body.dark-mode .bb-unsaved { background: rgba(180, 83, 9, 0.18); border-color: #92400e; color: #fcd34d; }
/* Pinned as the panel's footer (2026-10-07): always on screen when the X asks. */
.bb-modal > .bb-unsaved { flex-shrink: 0; margin: 0; padding: 12px 16px; border-width: 1px 0 0;
  border-radius: 0 0 var(--radius-2xl, 20px) var(--radius-2xl, 20px); }
/* Measured on the built app at 412 (launch fixes, 2026-10-01): the global
   coarse-pointer floor ([role=button] min-width 44px, style.css) made each
   of the 12 hour cells 44 wide, so a row was 528px in a 330px box and hours
   8-12 were cut off. The cells share the row (27px wide, 44 tall); the grid
   actions and the "Open preview" link get the 44px height. */
.whg-cells .whg-hour { min-width: 0; }
.whg-actions .btn, .bb-unsaved .btn { min-height: 44px; }
.bb-preview a.bb-btn { display: inline-flex; align-items: center; min-height: 44px; }

/* THE NARROWEST PHONES (owner 2026-10-02, "Yes all", then "an AM and PM
   line"): below 360px the twelve hours of each half wrap into two rows of six
   (~45px cells) under their AM / PM label, instead of 17px cells. The JS row
   ends sit at 0/11 and 12/23, so the 6-hour ends (5|6, 17|18) are rounded
   here, on the grey track and the colour layer. */
@media (max-width: 359px) {
  .whg-cells { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .whg-cells .whg-rowlabel { grid-column: 1 / -1; padding: 2px 0 0; }
  .whg-cells .whg-hour[data-hour="5"], .whg-cells .whg-hour[data-hour="5"]::before,
  .whg-cells .whg-hour[data-hour="17"], .whg-cells .whg-hour[data-hour="17"]::before { border-top-right-radius: 10px; border-bottom-right-radius: 10px; }
  .whg-cells .whg-hour[data-hour="6"], .whg-cells .whg-hour[data-hour="6"]::before,
  .whg-cells .whg-hour[data-hour="18"], .whg-cells .whg-hour[data-hour="18"]::before { border-top-left-radius: 10px; border-bottom-left-radius: 10px; }
  .whg-cells .whg-hour[data-hour="5"], .whg-cells .whg-hour[data-hour="17"] { box-shadow: none; }
}

/* Two labelled sections (2026-10-05): My booking page / Group booking links. */
.bb-section-head { margin: 4px 0 10px; }
.bb-section-title { display: flex; align-items: center; gap: 8px; margin: 0; font-size: 1rem; font-weight: 700; color: var(--text-primary, #1e293b); }
.bb-section-title i { color: var(--primary-600, #0d9488); font-size: .9em; }
.bb-section-sub { margin: 2px 0 0; font-size: .85rem; color: var(--text-secondary, #64748b); }
.bb-groups { margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--border-color, #e2e8f0); }
.bb-group-name i { color: var(--text-secondary, #64748b); margin-right: 4px; }
.bb-field textarea.bb-message { font-family: inherit; font-size: .9rem; }

/* "Set your availability" on the hours header (2026-10-05). */
.bb-hours > summary { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; min-height: 44px; }
.bb-hours-title { flex: 1 1 auto; }
.bb-hours-cta { display: inline-flex; align-items: center; gap: 6px; min-height: 36px; padding: 0 12px; border-radius: 999px;
  border: 1px solid var(--primary-300, #5eead4); background: var(--primary-50, #f0fdfa); color: var(--primary-700, #0f766e);
  font-size: .85rem; font-weight: 600; }
.bb-hours-cta i { font-size: .75em; transition: transform .15s ease; }
.bb-hours[open] .bb-hours-cta { background: var(--surface-primary, #fff); border-color: var(--border-color, #e2e8f0); color: var(--text-secondary, #64748b); }
.bb-hours[open] .bb-hours-cta i { transform: rotate(180deg); }
.bb-hours .bb-hours-cta-close, .bb-hours[open] .bb-hours-cta-open { display: none; }
.bb-hours[open] .bb-hours-cta-close { display: inline; }
body.dark-mode .bb-hours-cta { background: #0f172a; border-color: var(--primary-700, #0f766e); color: var(--primary-300, #5eead4); }

/* "Your calendar" (2026-10-05): which calendars close times. */
.bb-cal-sources { display: flex; flex-wrap: wrap; gap: 6px 16px; margin-top: 8px; }
.bb-cal-sources[hidden] { display: none; }
.bb-cal-source { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; font-size: .9rem; }

/* A ✕ on each time pill (2026-10-05): the pill and its ✕ read as one chip. */
.whg-run-wrap { display: inline-flex; align-items: stretch; border-radius: 999px; }
.whg-run-wrap > .whg-run { border-top-right-radius: 0; border-bottom-right-radius: 0; border-right: 0; padding-right: 8px; }
.whg-run-x { display: inline-flex; align-items: center; justify-content: center; min-width: 44px; min-height: 44px; padding: 0 12px 0 8px;
  border: 1px solid var(--border-color, #e2e8f0); border-left: 0; border-radius: 0 999px 999px 0; background: var(--surface-primary, #fff);
  color: var(--text-secondary, #64748b); cursor: pointer; font: inherit; }
.whg-run-wrap.is-open > .whg-run-x { box-shadow: inset -4px 0 0 var(--level-possible, #99f6e4); }
.whg-run-wrap.is-best > .whg-run-x { box-shadow: inset -4px 0 0 var(--level-preferred, #0d9488); }
.whg-run-wrap > .whg-run.is-open { box-shadow: inset 4px 0 0 var(--level-possible, #99f6e4); }
.whg-run-wrap > .whg-run.is-best { box-shadow: inset 4px 0 0 var(--level-preferred, #0d9488); }
.whg-run-x:hover, .whg-run-x:focus-visible { color: var(--danger-fg, #b91c1c); background: var(--danger-bg, #fef2f2); outline: none; }
body.dark-mode .whg-run-x { background: #0f172a; border-color: #334155; color: #94a3b8; }
