/* ============================================================
   EMPIRE OS — Custom form control widgets (controls.css)
   Used by enhance.js. Linked from index.html AND book.html.
   ============================================================ */

/* ------------------------------------------------------------
   WS-14 · GLOBAL KEYBOARD FOCUS RING (a11y baseline)
   Every interactive element gets the SAME rounded product ring for
   keyboard users — closing the allowlist gap where links, plain
   contenteditables, range inputs and role-based controls fell back to
   the browser's black-box outline (defect #1: login.html links) or to
   nothing at all (defect #2: outline:none with no replacement in
   finances/network/plans/nova).

   • Wrapped in :where() so it has ZERO specificity — ANY component's own
     :focus-visible / :focus rule still wins. Pure safety net.
   • The ring is a box-shadow, which automatically hugs each element's
     OWN border-radius. We never set border-radius here (onboarding
     lesson) — a square control gets a square ring, a pill gets a pill.
   • tabindex="-1" (programmatically-focused containers) is excluded. */
:where(a[href], button, input, select, textarea, summary,
       [contenteditable="true"], [contenteditable="plaintext-only"],
       [tabindex]:not([tabindex="-1"]),
       [role="button"], [role="tab"], [role="switch"], [role="menuitem"],
       [role="option"], [role="checkbox"], [role="radio"], [role="link"]):focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--accent-ring);
}
/* WS-25 · Composite controls: a wrapper marked .ring-host draws the focus ring
   ITSELF (via its own :focus-within style — e.g. the chat composer box). Its
   inner bare field (border:none, radius 0) must not ALSO paint the square
   safety-net ring above — one rounded ring on the box, nothing inside.
   :where() keeps this at zero specificity, like the baseline it tempers. */
:where(.ring-host) :where(input, textarea, select,
       [contenteditable="true"], [contenteditable="plaintext-only"]):focus-visible {
  box-shadow: none;
}
/* FOCUS-SQUARE FIX (Vincent 2026-07-09): a sharp SQUARE ring was appearing
   inside/around text fields everywhere. Root cause: the box-shadow safety-net
   ring above hugs each element's OWN border-radius, and the app's many bare
   composite fields (`.crm-quickadd-input`, `.tk-quickadd-input`, …: border:none,
   background:none, radius 0, sitting inside a wrapper that shows focus via
   `:focus-within`) have radius 0, so the ring rendered as a hard square box
   inside their rounded wrapper. The safety net exists for the ALLOWLIST-GAP
   elements (links, role-buttons, range/checkbox/radio, contenteditables) — plain
   text inputs/textareas are NOT in that gap here: they carry `.input`/`.textarea`
   (own rounded :focus ring) or live in a `:focus-within` wrapper. So suppress the
   safety-net box-shadow on text-entry inputs + textareas only. `:where()` = 0
   specificity, so `.input:focus`'s own ring still wins; a bare field's own
   `outline:none` keeps it silent (wrapper shows focus); and a truly-unstyled
   standalone input falls back to the UA focus outline (radius-following, a11y
   safe) via `outline: revert`. Range/checkbox/radio keep their ring. */
:where(input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="button"]):not([type="submit"]):not([type="reset"]):not([type="image"]):not([type="color"]):not([type="file"]),
       textarea):focus-visible {
  box-shadow: none;
  outline: revert;
}
/* All widget buttons reset native UA chrome so the file is self-sufficient even
   on pages (e.g. book.html) that don't ship the app-shell button reset. */
.eos-select, .eos-date, .eos-opt, .eos-cal-nav, .eos-cal-today, .eos-pop button {
  -webkit-appearance: none; appearance: none; background: none; margin: 0;
  font-family: inherit;
}

/* hide the native element but keep it focusable/submittable & in flow size 0.
   `display:none` last so nothing can override it back into a giant control. */
.eos-native-hidden {
  position: absolute !important; width: 1px !important; height: 1px !important;
  padding: 0 !important; margin: -1px !important; border: 0 !important;
  clip: rect(0 0 0 0) !important; clip-path: inset(50%) !important;
  overflow: hidden !important; white-space: nowrap !important; pointer-events: none !important;
  -webkit-appearance: none !important; appearance: none !important; opacity: 0 !important;
}

/* SAFETY NET — raw native date/time inputs that haven't been enhanced yet
   (before enhance.js runs, or in a missed context) must not render as giant
   browser controls. Size them like a normal .input. Once enhanced the
   .eos-native-hidden rule above (higher specificity + !important) hides them. */
input[type="date"]:not([data-eos-enhanced]),
input[type="time"]:not([data-eos-enhanced]),
input[type="datetime-local"]:not([data-eos-enhanced]) {
  box-sizing: border-box; height: 40px; max-width: 100%; padding: 0 12px;
  font-size: var(--fs-sm); font-family: inherit; border-radius: var(--r-sm);
  border: 1px solid var(--border); background: var(--surface-1); color: var(--text-100);
  -webkit-appearance: none; appearance: none;
}
/* tame the oversized native spin / inner UI on those raw inputs */
input[type="date"]:not([data-eos-enhanced])::-webkit-calendar-picker-indicator,
input[type="time"]:not([data-eos-enhanced])::-webkit-calendar-picker-indicator,
input[type="datetime-local"]:not([data-eos-enhanced])::-webkit-calendar-picker-indicator {
  opacity: .55; cursor: pointer;
}
input[type="date"]:not([data-eos-enhanced])::-webkit-inner-spin-button,
input[type="time"]:not([data-eos-enhanced])::-webkit-inner-spin-button,
input[type="datetime-local"]:not([data-eos-enhanced])::-webkit-inner-spin-button { display: none; }

/* shared trigger surface — mirrors the page's .input / .select exactly so the
   enhanced control is never taller/wider than a normal field (38px, fs-sm). */
.eos-select, .eos-date {
  display: inline-flex; align-items: center; gap: 9px; width: 100%; max-width: 100%;
  height: 40px; padding: 0 12px; border-radius: var(--r-sm); box-sizing: border-box;
  background: var(--surface-1); border: 1px solid var(--border);
  color: var(--text-100); font-size: var(--fs-sm); font-family: inherit; font-weight: 500;
  text-align: left; cursor: pointer;
  transition: border-color var(--t-fast) var(--ease-out), background var(--t-fast) var(--ease-out), box-shadow var(--t-fast) var(--ease-out);
}
.eos-select:hover, .eos-date:hover { border-color: var(--text-400); background: var(--surface-0); }
.eos-select.is-open, .eos-date.is-open,
.eos-select:focus-visible, .eos-date:focus-visible,
.eos-date.eos-date-field:focus-within {
  outline: none; border-color: var(--accent); background: var(--surface-0); box-shadow: 0 0 0 3px var(--accent-ring);
}
.eos-select.is-disabled, .eos-date.is-disabled { opacity: .55; cursor: not-allowed; }
.eos-select-label, .eos-date-label { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; line-height: 1.2; }

/* ---- typeable date field (div wrapper = text input + calendar icon button) ---- */
.eos-date.eos-date-field { cursor: text; padding: 0 4px 0 12px; gap: 4px; }
.eos-date.eos-date-field.is-disabled { cursor: not-allowed; }
.eos-date-input {
  flex: 1; min-width: 0; height: 100%; border: 0; background: transparent;
  color: var(--text-100); font-family: inherit; font-size: var(--fs-sm); font-weight: 500;
  padding: 0; margin: 0; outline: none; box-shadow: none; -webkit-appearance: none; appearance: none;
}
.eos-date-input::placeholder { color: var(--text-500); font-weight: 400; }
.eos-date-input:disabled { cursor: not-allowed; }
.eos-date-btn {
  display: grid; place-items: center; flex-shrink: 0; width: 30px; height: 30px;
  border-radius: var(--r-xs); border: 0; background: transparent; color: var(--text-400);
  cursor: pointer; padding: 0; transition: background var(--t-fast), color var(--t-fast);
}
.eos-date-btn:hover { background: var(--surface-2); color: var(--text-100); }
.eos-date.eos-date-field.is-disabled .eos-date-btn { pointer-events: none; opacity: .5; }
.eos-date-btn svg { width: 15px; height: 15px; }
.eos-select.is-placeholder .eos-select-label,
.eos-date.is-placeholder .eos-date-label { color: var(--text-500); }
.eos-select-chev { display: flex; color: var(--text-400); flex-shrink: 0; transition: transform var(--t-fast) var(--ease-out); }
.eos-select.is-open .eos-select-chev { transform: rotate(180deg); }
.eos-date-ic { display: flex; color: var(--text-400); flex-shrink: 0; }
.eos-select-chev svg, .eos-date-ic svg { width: 16px; height: 16px; }

/* small variant to coexist with .select-sm */
.select-sm + .eos-select { height: 32px; font-size: var(--fs-xs); }

/* ---- popover (desktop) ---- */
.eos-pop {
  /* A popup must outrank the surface that opened it. --z-modal (100) put it
     UNDER anything declaring more (the ideation lightbox is 120), where it
     still rendered but ate every click. enhance.js raises this further at open
     time when the anchor sits inside a higher surface; this is the floor. */
  z-index: var(--z-popover); background: var(--surface-0);
  border: 1px solid var(--border-strong); border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg, var(--shadow-xl)); padding: 6px; opacity: 0; transform: translateY(-4px);
  transition: opacity var(--t-fast) var(--ease-out), transform var(--t-fast) var(--ease-out);
}
.eos-pop.in { opacity: 1; transform: none; }
/* overscroll-behavior:contain — long lists (the ~420-zone timezone picker) must
   scroll INSIDE the popover; without it the wheel chains to the page underneath
   at either end and the whole form lurches ("picker is weird when you scroll"). */
.eos-pop-list { max-height: 290px; overflow-y: auto; overscroll-behavior: contain; display: flex; flex-direction: column; gap: 1px; }
.eos-pop-group { padding: 9px 10px 4px; font-size: var(--fs-2xs); font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--text-500); }
.eos-pop-empty { padding: 16px 12px; text-align: center; color: var(--text-400); font-size: var(--fs-sm); }
.eos-pop-title { padding: 6px 8px 8px; font-size: var(--fs-sm); font-weight: 600; color: var(--text-100); }

.eos-opt {
  display: flex; align-items: center; gap: 10px; width: 100%; padding: 9px 11px;
  border: 1px solid transparent; border-radius: var(--r-sm); font-size: 14px; color: var(--text-200);
  cursor: pointer; transition: background var(--t-fast), color var(--t-fast); text-align: left;
}
.eos-opt:hover, .eos-opt.hi { background: var(--surface-2); color: var(--text-100); }
/* selected option: soft accent tint + check, readable in light & dark */
.eos-opt.is-sel { background: var(--accent-soft); color: var(--text-100); font-weight: 600; }
.eos-opt.is-sel:hover, .eos-opt.is-sel.hi { background: var(--accent-soft); }
.eos-opt.is-disabled { opacity: .45; cursor: not-allowed; }
.eos-opt-label { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.eos-opt-check { display: none; color: var(--text-100); flex-shrink: 0; }
.eos-opt.is-sel .eos-opt-check { display: flex; }

/* search box inside the popover */
.eos-pop-search { position: relative; display: flex; align-items: center; padding: 4px 4px 6px; }
.eos-pop-search-ic { position: absolute; left: 14px; color: var(--text-400); display: flex; pointer-events: none; }
.eos-pop-search-in {
  width: 100%; height: 34px; padding: 0 10px 0 32px; border-radius: var(--r-xs);
  background: var(--surface-1); border: 1px solid var(--border); color: var(--text-100);
  font-size: var(--fs-sm); font-family: inherit;
}
.eos-pop-search-in:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }

/* ---- calendar popover ---- */
.eos-date-pop { width: 268px; padding: 12px; }
.eos-cal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.eos-cal-title { font-size: var(--fs-sm); font-weight: 600; color: var(--text-100); }
.eos-cal-nav {
  width: 30px; height: 30px; border-radius: var(--r-sm); display: grid; place-items: center;
  border: 1px solid var(--border); background: var(--surface-1); color: var(--text-300);
  cursor: pointer; transition: border-color var(--t-fast) var(--ease-smooth), color var(--t-fast) var(--ease-smooth), background var(--t-fast) var(--ease-smooth), transform var(--t-fast) var(--ease-smooth);
}
.eos-cal-nav:hover { border-color: var(--border-strong); color: var(--text-100); }
.eos-cal-nav:active { transform: scale(0.94); }
.eos-cal-nav svg { width: 15px; height: 15px; }
.eos-cal-dow { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); margin-bottom: 4px; }
.eos-cal-dow span { text-align: center; font-size: var(--fs-2xs); font-weight: 600; color: var(--text-400); }
/* minmax(0,1fr) — NOT plain 1fr (= minmax(auto,1fr)) — so all 7 columns stay
   truly equal; otherwise a cell's min-content blows one column wide and the
   day numbers misalign under the weekday header. */
.eos-cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); grid-auto-rows: 32px; gap: 2px; }
.eos-cell {
  height: 32px; min-height: 0; min-width: 0; width: 100%; display: grid; place-items: center; border-radius: var(--r-sm);
  font-size: var(--fs-sm); color: var(--text-200); border: 1px solid transparent;
  cursor: pointer; transition: background var(--t-fast), border-color var(--t-fast), color var(--t-fast);
}
.eos-cell.empty { visibility: hidden; cursor: default; }
.eos-cell:hover { background: var(--surface-2); color: var(--text-100); }
.eos-cell:active { transform: scale(0.9); }
.eos-cell.today { box-shadow: inset 0 0 0 1.5px var(--border-strong); }
.eos-cell.sel, .eos-cell.sel:hover { background: var(--accent); color: var(--accent-fg); font-weight: 600; box-shadow: none; }
.eos-cal-foot { display: flex; justify-content: flex-end; margin-top: 10px; }
.eos-cal-today {
  font-size: var(--fs-xs); font-weight: 560; color: var(--text-300); padding: 5px 10px;
  border-radius: var(--r-xs); border: 1px solid var(--border); background: var(--surface-1); cursor: pointer; transition: border-color var(--t-fast) var(--ease-smooth), color var(--t-fast) var(--ease-smooth), background var(--t-fast) var(--ease-smooth), transform var(--t-fast) var(--ease-smooth);
}
.eos-cal-today:hover { border-color: var(--border-strong); color: var(--text-100); }
.eos-cal-today:active { transform: scale(0.97); }
.eos-cal-time { display: flex; align-items: center; gap: 8px; margin-top: 10px; color: var(--text-400); }
.eos-cal-time-in {
  flex: 1; height: 32px; padding: 0 10px; border-radius: var(--r-xs);
  background: var(--surface-1); border: 1px solid var(--border); color: var(--text-100); font-size: var(--fs-sm); font-family: inherit;
}
.eos-cal-time-in:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }
.eos-time-list { max-height: 260px; }

/* ---- mobile bottom sheet (≤640px) ---- */
.eos-sheet-backdrop {
  position: fixed; inset: 0; background: rgba(0,0,0,.45); z-index: var(--z-modal);
  opacity: 0; transition: opacity var(--t-med, 200ms) var(--ease-out);
}
.eos-sheet-backdrop.in { opacity: 1; }
.eos-pop.eos-sheet {
  position: fixed; left: 0; right: 0; bottom: 0; top: auto; width: 100%;
  max-height: 72vh; border-radius: var(--r-lg) var(--r-lg) 0 0; padding: 8px 12px 22px;
  transform: translateY(100%); z-index: calc(var(--z-modal) + 1);
}
.eos-pop.eos-sheet.in { transform: none; }
.eos-pop.eos-sheet .eos-pop-list { max-height: 56vh; }
.eos-pop.eos-sheet.eos-date-pop { width: 100%; }
.eos-sheet-grab { width: 38px; height: 4px; border-radius: var(--r-xs); background: var(--border-strong); margin: 6px auto 12px; }

/* ============================================================
   INTERNATIONAL PHONE INPUT (phone.js)
   Country selector (flag + dial code) joined to the tel input as one
   field. Mirrors the page's .inp surface so it sits cleanly in the form.
   Heights/radii fall back to the booking page's tokens.
   ============================================================ */
.eos-phone {
  display: flex; align-items: stretch; width: 100%;
  background: var(--surface-2); border: 1px solid var(--border-strong);
  border-radius: var(--r-md, 11px); overflow: hidden;
  transition: border-color var(--t-fast) var(--ease-smooth), box-shadow var(--t-fast) var(--ease-smooth), background var(--t-fast) var(--ease-smooth);
}
.eos-phone:focus-within {
  border-color: var(--accent); background: var(--surface-0);
  box-shadow: 0 0 0 3px var(--accent-ring);
}
/* country trigger — flag + dial code, divider on the right edge */
.eos-phone-cc {
  display: inline-flex; align-items: center; gap: 7px; flex-shrink: 0;
  padding: 0 11px 0 13px; border: 0; border-right: 1px solid var(--border-strong);
  background: transparent; color: var(--text-100); font-family: inherit;
  font-size: 14px; font-weight: 500; cursor: pointer;
  transition: background var(--t-fast) var(--ease-smooth), color var(--t-fast) var(--ease-smooth);
}
.eos-phone-cc:hover { background: var(--surface-3); }
.eos-phone-cc:focus-visible { outline: none; background: var(--surface-3); }
.eos-phone.is-open .eos-phone-cc, .eos-phone-cc.is-open { background: var(--surface-3); }
.eos-phone-flag { font-size: 17px; line-height: 1; }
.eos-phone-dial { font-variant-numeric: tabular-nums; color: var(--text-200); }
.eos-phone-chev { display: inline-flex; color: var(--text-400); transition: transform var(--t-fast, 120ms) var(--ease-out); margin-left: -1px; }
.eos-phone-cc.is-open .eos-phone-chev { transform: rotate(180deg); }
/* the tel input itself — borderless inside the wrapper, fills remaining space */
.eos-phone-input.inp, .eos-phone-input {
  flex: 1; min-width: 0; border: 0 !important; background: transparent !important;
  border-radius: 0 !important; box-shadow: none !important;
  padding: 12px 13px; font-variant-numeric: tabular-nums;
}
.eos-phone-input:focus { box-shadow: none !important; outline: none; }

/* country popover rows: flag · name · dial code · check */
.eos-phone-opt { gap: 11px; }
.eos-phone-opt-flag { font-size: 17px; line-height: 1; flex-shrink: 0; }
.eos-phone-opt-dial {
  flex-shrink: 0; color: var(--text-400); font-size: 13px;
  font-variant-numeric: tabular-nums; margin-left: auto;
}
.eos-phone-opt.is-sel .eos-phone-opt-dial { color: var(--text-300); }
.eos-phone-opt .eos-opt-check { margin-left: 4px; }
.eos-phone-pop .eos-pop-list { max-height: 280px; }
