/* ════════════════════════════════════════════════════════════════════
   Phase L0 — single-scroll frame + layout tokens
   See PAGE_LAYOUT_STANDARD.md sections 4 and 7. The whole admin dashboard
   scrolls inside ONE container (.app-scroll) instead of the document, so
   content no longer slides under the fixed top pills. Scoped to
   body.app-framed so the other admin pages that share admin.css / the
   .admin-body class keep normal document scroll.
   ════════════════════════════════════════════════════════════════════ */
:root {
  --page-max: 1320px;
  --page-max-wide: 1600px;
  --page-gutter: clamp(16px, 4vw, 40px);
  --page-col-gap: 24px;
  --rail-w: 200px;
  --rail-pad: 7px;
  --rail-row-gap: 5px;
  --rail-group-gap: 16px;
  --rail-item-radius: 999px; /* style 13: rows are capsules, like the pill */
  --rail-min-h: 40px;
  --rail-indent: 16px;
  --rail-guide: var(--sw-border, #E5DED3);
  --rail-anim: 180ms;
  --rail-ink: var(--sw-ink, #373B4D);
  --rail-ink-strong: var(--sw-ink-deep, #373B4D);
  --rail-muted: var(--sw-muted, #7B8190);
  --rail-active-fill: rgba(255,243,233,0.74);
  --rail-active-bar: rgba(243,138,63,0.90);
  --rail-badge-fill: var(--sw-card-lift, #FFFDF9);

  --chrome-top: 54px;     /* The top-center command search is back (2026-06-11),
                             centered over the content column, so the page reserves
                             just enough top room to clear it. The search and the
                             location pill share top:12 and a 36px height, bottoming
                             at 48px; +6px room sits the content close beneath them.
                             This now equals --sticky-top, so the content and the rail
                             start at the same Y. */
  --chrome-bottom: 112px; /* reserves room for the bottom dock (now sitting 6px off the edge);
                             trimmed from 124 to hand the reclaimed space back to content */
  --sticky-top: 54px;     /* The rail (left column) sticks 54px down so it always
                             clears the location pill (top 12 + 36 tall = 48; +6px
                             room). Matches --chrome-top now that the search is back. */
}

/* The document itself never scrolls; .app-scroll owns the only scrollbar. */
html:has(body.app-framed) { height: 100%; overflow: hidden; }
body.app-framed { height: 100%; overflow: hidden; }

.app-scroll {
  position: fixed;
  inset: 0;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  padding-top: var(--chrome-top);
  padding-bottom: var(--chrome-bottom);
  scroll-padding-top: var(--chrome-top);
}

/* Centered max-width container for later phases. .admin-shell currently
   plays this role; scoped under .app-scroll so it never touches the
   class="page" used by other embedded views (e.g. admin-kpi.ejs). */
.app-scroll .page { max-width: var(--page-max); margin-inline: auto; padding-inline: var(--page-gutter); }
.app-scroll .page--wide { max-width: var(--page-max-wide); }
.app-scroll .page--full { max-width: none; }

/* Shell becomes the inner container inside .app-scroll. The chrome
   clearance that used to live here (padding 94/136) moved to .app-scroll
   above so the two never double up. */
.admin-body .admin-shell {
  display: block;
  max-width: none;
  margin: 0 auto;
  padding: 0 clamp(16px, 2.5vw, 36px);
  min-height: calc(100vh - var(--chrome-top) - var(--chrome-bottom));
}

.admin-body .admin-content {
  padding: 0 !important;
  min-width: 0;
}

/* The HCP status banner is a full-width child ABOVE the sections. It already
   starts at --chrome-top, which clears the top pills, so this extra push now
   resolves to zero (--chrome-top == --sticky-top) but stays as a calc so it
   self-corrects if those tokens ever diverge again. */
.admin-body .admin-content > .alert {
  margin-top: calc(var(--sticky-top, 16px) - var(--chrome-top, 0px));
}

/* Section entrance: animate the CONTENT, never the section box itself, so the
   sticky rail inside .horizon-hub-layout stays perfectly still when you click
   between menu items of the same workspace (the rail is byte-identical across
   those pages). Children above the layout (scope banner, page head) fade and
   slide in from the right (sectionIn); inside the layout only the MAIN column
   does. */
.admin-body .section-page {
  animation: none;
}
.admin-body .section-page > * {
  animation: sectionIn 0.26s cubic-bezier(0.22, 1, 0.36, 1);
}
.admin-body .section-page > .horizon-hub-layout {
  animation: none;
}
.admin-body .section-page .horizon-hub-layout > .horizon-hub-main {
  animation: sectionIn 0.26s cubic-bezier(0.22, 1, 0.36, 1);
}

/* (The View Transitions crossfade that lived here was removed 2026-06-09:
   its old-page snapshot replayed stale pill positions on tab switches, and
   deferring activate() let the pill controllers read the wrong active tab.
   The sectionIn content fade above is the whole transition now.) */
@media (prefers-reduced-motion: reduce) {
  .admin-body .section-page > *,
  .admin-body .section-page .horizon-hub-layout > .horizon-hub-main { animation: none; }
}

.horizon-cornerbar,
.horizon-dock {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

/* The location pill caps the rail column: same fluid gutter as the shell,
   same 236px width as the rail card beneath it, and 36px tall so its round
   end caps share the rail's exact 18px corner curvature. Its shadow is a
   close ambient glow — the old 55px throw read as a dead band across the
   whole top of the page. */
.horizon-cornerbar {
  position: fixed;
  top: 12px;
  left: clamp(16px, 2.5vw, 36px);
  z-index: 90;
  display: flex;
  align-items: center;
  gap: 8px;
  width: 236px;
  height: 36px;
  padding: 0 6px 0 10px;
  border: 1px solid rgba(229, 222, 211, 0.85);
  border-radius: 999px;
  background: linear-gradient(180deg, rgba(255,254,250,0.68), rgba(252,249,243,0.46));
  box-shadow: 0 10px 26px rgba(55,59,77,0.12), 0 2px 8px rgba(55,59,77,0.05), inset 0 1px 0 rgba(255,255,255,0.72);
  backdrop-filter: blur(34px) saturate(190%);
  -webkit-backdrop-filter: blur(34px) saturate(190%);
}

/* The switcher fills the pill so the caret parks at the right edge; long
   location names ellipsize instead of stretching the pill. */
.horizon-cornerbar .horizon-workspace { flex: 1; min-width: 0; }
.horizon-cornerbar .horizon-workspace-trigger {
  width: 100%;
  min-width: 0;
  height: 28px;
  justify-content: space-between;
  padding: 0 8px;
}
.horizon-cornerbar .horizon-workspace-trigger > span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.horizon-brand {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 0;
  flex: none;
  background: transparent;
  box-shadow: none;
}

.horizon-brand-mark {
  width: 26px;
  height: 26px;
  object-fit: contain;
  filter: none;
}

.horizon-workspace {
  position: relative;
}

.horizon-workspace-trigger {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 34px;
  padding: 0 8px;
  list-style: none;
  cursor: pointer;
  border-radius: 12px;
  color: var(--sw-ink, #373B4D);
  font-weight: 780;
  letter-spacing: 0;
}

.horizon-workspace-trigger::-webkit-details-marker,
.horizon-profile-trigger::-webkit-details-marker {
  display: none;
}

.horizon-workspace-trigger:hover {
  background: rgba(255,255,255,0.48);
}

.horizon-workspace[open] .horizon-workspace-trigger svg {
  transform: rotate(180deg);
}

.horizon-workspace-menu,
.horizon-profile-menu {
  position: absolute;
  border: 1px solid rgba(219,211,198,0.88);
  border-radius: 18px;
  background: linear-gradient(180deg, rgba(255,254,250,0.96), rgba(252,250,246,0.91));
  box-shadow: 0 24px 54px rgba(55,59,77,0.19), 0 6px 18px rgba(55,59,77,0.08), inset 0 1px 0 rgba(255,255,255,0.78);
  backdrop-filter: blur(24px) saturate(155%);
  -webkit-backdrop-filter: blur(24px) saturate(155%);
  padding: 9px;
  min-width: 276px;
}

.horizon-workspace-menu {
  top: calc(100% + 7px);
  left: 0;
  transform: none;
}

.horizon-workspace-menu::before {
  content: "";
  position: absolute;
  top: -7px;
  left: 20px;
  width: 12px;
  height: 12px;
  transform: rotate(45deg);
  border-top: 1px solid var(--sw-border, #E5DED3);
  border-left: 1px solid var(--sw-border, #E5DED3);
  background: var(--sw-card-lift, #FFFDF9);
}

.horizon-menu-label {
  padding: 8px 12px 6px;
  color: var(--sw-muted, #7B8190);
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.horizon-workspace-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 10px 12px;
  border: 0;
  border-radius: 12px;
  background: transparent;
  color: var(--sw-ink, #373B4D);
  text-decoration: none;
  cursor: pointer;
  text-align: left;
  font: inherit;
}

.horizon-workspace-row:hover,
.horizon-workspace-row.is-current {
  background: rgba(243,239,231,0.9);
}

.horizon-workspace-row.is-current {
  background: var(--sw-orange-soft, #FFF3E9);
}

.horizon-workspace-avatar {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 10px;
  flex: none;
  background: var(--sw-card-lift, #FFFDF9);
  color: var(--sw-ink-deep, #373B4D);
  font-weight: 800;
  font-size: 12px;
}

.horizon-workspace-row--org .horizon-workspace-avatar {
  background: linear-gradient(150deg, var(--sw-light-blue, #BFE0F3), #373B4D);
  color: #fff;
}

.horizon-workspace-avatar--add {
  background: var(--sw-orange, #F38A3F);
  color: #fff;
  font-size: 18px;
}

.horizon-workspace-copy {
  display: flex;
  flex: 1;
  min-width: 0;
  flex-direction: column;
  gap: 2px;
}

.horizon-workspace-copy strong {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 13.5px;
  font-weight: 750;
  color: var(--sw-ink, #373B4D);
}

.horizon-workspace-copy small {
  color: var(--sw-muted, #7B8190);
  font-size: 11px;
  font-weight: 600;
}

.horizon-current-pill {
  flex: none;
  padding: 3px 8px;
  border-radius: 999px;
  background: rgba(243,138,63,0.14);
  color: #D9742B;
  font-size: 10px;
  font-weight: 800;
}

.horizon-menu-divider {
  height: 1px;
  margin: 7px 6px;
  background: var(--sw-border, #E5DED3);
}

/* The Cmd K / Esc chip: shown inside the top-center search pill (restored
   2026-06-11) and reused as the palette's Esc hint. */
.horizon-command-kbd {
  border: 1px solid rgba(229, 222, 211, 0.85);
  border-radius: 7px;
  background: rgba(255,255,255,0.52);
  color: #A29D8B;
  padding: 3px 9px;
  font-size: 10.5px;
  font-weight: 800;
}

.horizon-dock {
  /* FALLBACK width for the ACTIVE tab's label reveal. sizeDockLabels() in
     admin-dashboard.js measures each tab's real label and overrides this
     per-tab (inline --dock-label-w) so every active pill hugs its OWN word with
     the same small trailing gap — short labels ("Inbox") no longer inherit the
     longest label's slack. This 90px only applies if that JS hasn't run. */
  --dock-label-w: 90px;
  position: fixed;
  left: 50%;
  bottom: 6px;      /* tucked low to the screen edge to give content more room (was 12px, 24px) */
  z-index: 90;
  display: flex;
  align-items: center;
  gap: 12px;
  width: max-content;
  /* Wide enough that all seven tabs + the two wings fit on a normal screen
     (the bar hugs its content and stays centered); on phones it caps at the
     viewport and the tab strip scrolls inside instead of spilling over. */
  max-width: min(1040px, calc(100vw - 32px));
  padding: 10px 15px;          /* a bit taller + roomier so the bar reads bigger */
  border: 1px solid rgba(229, 222, 211, 0.85);
  border-radius: 34px;
  /* Base cream glass. NOTE: the visible dock background is set by the dock-redesign
     rule in 07-dock-schedule.css (.admin-body .horizon-dock) which loads after this
     and wins — change the transparency THERE, not here. */
  background: linear-gradient(180deg, rgba(255,254,250,0.54), rgba(252,249,243,0.34));
  box-shadow: 0 26px 64px rgba(55,59,77,0.20), 0 6px 18px rgba(55,59,77,0.07), inset 0 1px 0 rgba(255,255,255,0.76);
  backdrop-filter: blur(38px) saturate(200%);
  -webkit-backdrop-filter: blur(38px) saturate(200%);
  transform: translateX(-50%);
}

.horizon-dock-wing {
  display: flex;
  align-items: center;
  flex: none;
}

.horizon-dock-center {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 10px;
  /* Take the space between the two fixed wings and, when the seven tabs are
     wider than that (phones, narrow windows), scroll them horizontally INSIDE
     the bar instead of letting the last tabs + profile spill past the rounded
     edge. min-width:0 lets the flex item shrink below its content width so the
     scroll can engage; the bar still grows to fit all tabs on wide screens. */
  flex: 1 1 auto;
  min-width: 0;
  overflow-x: auto;
  overflow-y: hidden;
  /* Vertical headroom INSIDE the scroll clip so the unread-count badge (and its
     white ring) riding a tab's top corner isn't shaved off by overflow-y:hidden;
     the negative margins hand the space back so the dock bar stays the same
     height. Padding, not overflow-y:visible — a scroll container clips both axes. */
  padding: 8px 0;
  margin: -8px 0;
  scrollbar-width: none;            /* Firefox: hide the scrollbar, keep scroll */
  -ms-overflow-style: none;
  scroll-behavior: smooth;
}
.horizon-dock-center::-webkit-scrollbar { display: none; }  /* Safari/Chrome */

.horizon-add {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 50%;
  background: var(--sw-orange, #F38A3F);
  color: #fff;
  box-shadow: 0 2px 8px rgba(243,138,63,0.20);
  cursor: pointer;
}

.horizon-add span {
  display: block;
  margin-top: -2px;
  font-size: 25px;
  font-weight: 400;
  line-height: 1;
}

.horizon-add:hover {
  background: #D9742B;
  transform: translateY(-1px);
}

/* Top-center command search (restored 2026-06-11). It floats centered at the
   same top:12 as the location pill in the corner, and borrows that pill's exact
   height, transparency, blur, and soft shadow so the two read as a matched set
   of floating glass widgets bracketing the top. */
.horizon-searchbar {
  position: fixed;
  top: 12px;
  left: 50%;
  z-index: 88;
  /* 480px keeps the centered pill clear of the left location pill down to
     ~860px, below which it drops to a full-width second row (see ≤860). */
  width: min(480px, calc(100vw - 32px));
  transform: translateX(-50%);
}

.horizon-command-pill {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  height: 36px;                       /* matches .horizon-cornerbar */
  padding: 0 8px 0 14px;
  border: 1px solid rgba(229, 222, 211, 0.85);
  border-radius: 999px;
  /* identical glass recipe to .horizon-cornerbar */
  background: linear-gradient(180deg, rgba(255,254,250,0.68), rgba(252,249,243,0.46));
  box-shadow: 0 10px 26px rgba(55,59,77,0.12), 0 2px 8px rgba(55,59,77,0.05), inset 0 1px 0 rgba(255,255,255,0.72);
  backdrop-filter: blur(34px) saturate(190%);
  -webkit-backdrop-filter: blur(34px) saturate(190%);
  color: var(--sw-muted, #7B8190);
  cursor: pointer;
  font: inherit;
  text-align: left;
  transition: box-shadow 0.18s cubic-bezier(0.22,1,0.36,1), transform 0.18s cubic-bezier(0.22,1,0.36,1);
}

.horizon-command-pill:hover {
  transform: translateY(-1px);
  box-shadow: 0 16px 34px rgba(55,59,77,0.16), 0 3px 10px rgba(55,59,77,0.06), inset 0 1px 0 rgba(255,255,255,0.82);
}

.horizon-command-pill:focus-visible {
  outline: 2px solid var(--sw-orange, #F38A3F);
  outline-offset: 2px;
}

.horizon-command-glyph {
  flex: none;
  color: var(--sw-muted, #7B8190);
}

.horizon-command-placeholder {
  flex: 1;
  color: var(--sw-muted, #7B8190);
  font-size: 13.5px;
  font-weight: 650;
}

.horizon-tab,
.admin-body .horizon-tab {
  position: relative;
  display: inline-grid;
  grid-auto-flow: column;
  grid-template-columns: auto 0px;   /* col 1 = icon, col 2 = label (collapsed to 0) */
  align-items: center;
  min-height: 46px;
  padding: 11px 15px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--sw-muted, #7B8190);
  text-decoration: none;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0;
  white-space: nowrap;
  /* The label column animates 0px -> --dock-label-w, a px value set PER-TAB by
     sizeDockLabels() (admin-dashboard.js) to that tab's measured label width, so
     each active pill hugs its own word + a small trailing gap. It stays a px (NOT
     max-content) so the reveal still interpolates smoothly (px<->px). Because the
     revealed width now differs per tab, the content-sized bar re-centers with a
     gentle eased nudge on a switch — accepted in trade for not padding short
     labels out to the longest one's width. */
  transition: grid-template-columns .44s cubic-bezier(.22, 1, .36, 1),
              background .32s cubic-bezier(.22, 1, .36, 1),
              color .24s ease,
              box-shadow .32s ease;
}
.horizon-tab-ico { width: 24px; height: 24px; flex: none; display: block; }
/* Label lives in the flexible column. min-width:0 + overflow:hidden let it
   collapse fully to 0 at 0fr; border-box keeps its 7px lead-in INSIDE the
   animated track so no sliver shows while it's collapsed. */
.horizon-tab-label {
  box-sizing: border-box;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding-left: 7px;
  opacity: 0;
  transition: opacity .3s ease;
}
.horizon-tab.is-active .horizon-tab-label,
.admin-body .horizon-tab.is-active .horizon-tab-label {
  opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
  .horizon-tab, .horizon-tab-label { transition: none; }
}

/* Disabled "Coming Soon" dock item — greyed out, no hover, does not navigate. */
.horizon-tab--soon,
.admin-body .horizon-tab--soon {
  color: var(--sw-muted, #7B8190);
  opacity: 0.45;
  cursor: default;
  pointer-events: none;
  font-weight: 700;
}
.horizon-tab--soon:hover,
.admin-body .horizon-tab--soon:hover {
  background: transparent;
  color: var(--sw-muted, #7B8190);
}

.horizon-tab:hover,
.admin-body .horizon-tab:hover {
  background: rgba(255,255,255,0.52);
  color: var(--sw-ink, #373B4D);
}

/* Active = a solid orange pill carrying the icon + the revealed label (dark ink
   reads on the orange). It is self-contained, so the expand is pure CSS and the
   glide pill no longer has to chase a resizing target. */
.horizon-tab.is-active,
.admin-body .horizon-tab.is-active {
  grid-template-columns: auto var(--dock-label-w, 90px);   /* reveal label to its measured width (set per-tab in JS); 90px is the no-JS fallback */
  background: var(--sw-orange, #F38A3F);
  color: #373B4D;
  box-shadow: 0 4px 12px rgba(243,138,63,0.26);
}
/* Hovering the active tab keeps it orange (don't flip to the glass hover wash). */
.horizon-tab.is-active:hover,
.admin-body .horizon-tab.is-active:hover {
  background: var(--sw-orange, #F38A3F);
  color: #373B4D;
}

/* Unresolved-count pill on a dock tab (e.g. Feedback in Super Admin). Orange on
   white text reads on both the light location dock and the dark Super Admin dock.
   [hidden] must win over the inline-flex display when the count is zero. */
.horizon-tab-badge,
.admin-body .horizon-tab-badge {
  /* Corner badge pinned to the icon so the unread count shows whether the tab is
     collapsed (icon-only) or the active expanded pill. */
  position: absolute;
  top: 1px;
  right: 1px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--sw-orange, #F38A3F);
  color: #FFFFFF;
  font-size: 10.5px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: 0;
  box-shadow: 0 0 0 2px var(--sw-card-lift, #FFFDF9);
}
.horizon-tab-badge[hidden],
.admin-body .horizon-tab-badge[hidden] { display: none !important; }

.horizon-profile {
  position: relative;
}

.horizon-profile-trigger {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  list-style: none;
  cursor: pointer;
  background: var(--sw-ink, #373B4D);
  color: #fff;
  box-shadow: 0 2px 6px rgba(55,59,77,0.12);
  font-size: 14px;
  font-weight: 800;
}

.horizon-profile-trigger:hover {
  transform: translateY(-1px);
}
.horizon-profile-trigger.is-active {
  background: var(--sw-orange, #F38A3F);
  color: var(--sw-card-lift, #FFFDF9);
}

/* The dock's children never shrink (flex: none keeps the tab labels whole),
   so when the window narrows past the content width the end buttons spill
   over the bar's rounded edge. Squeeze the tabs and gaps first, then drop
   the disabled "Coming Soon" placeholder, so the bar always wraps its
   content. */
@media (max-width: 920px) {
  .horizon-dock { gap: 8px; padding: 8px 10px; }
  .horizon-dock-center { gap: 4px; }
  .horizon-dock-wing { gap: 6px; }
  .horizon-tab,
  .admin-body .horizon-tab { padding: 9px 12px; font-size: 14.5px; }
}

@media (max-width: 780px) {
  .horizon-tab--soon,
  .admin-body .horizon-tab--soon { display: none; }
  .horizon-tab,
  .admin-body .horizon-tab { padding: 8px 10px; font-size: 13.5px; }
}

.horizon-profile-menu {
  right: 0;
  bottom: calc(100% + 14px);
  min-width: 242px;
}

.horizon-profile-head {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 11px 12px 13px;
}

.horizon-profile-head strong,
.horizon-profile-head small {
  display: block;
}

.horizon-profile-head strong {
  color: var(--sw-ink, #373B4D);
  font-size: 13.5px;
  font-weight: 750;
}

.horizon-profile-head small {
  color: var(--sw-muted, #8A836F);
  font-size: 11px;
  font-weight: 650;
  text-transform: capitalize;
}

.horizon-profile-avatar {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  flex: none;
  background: var(--sw-ink, #373B4D);
  color: #fff;
  font-weight: 800;
}

.horizon-profile-item {
  display: block;
  width: 100%;
  padding: 10px 12px;
  border: 0;
  border-radius: 12px;
  background: transparent;
  color: var(--sw-ink, #373B4D);
  text-align: left;
  text-decoration: none;
  font: inherit;
  font-size: 13.5px;
  font-weight: 650;
  cursor: pointer;
}

.horizon-profile-item:hover {
  background: var(--sw-card-lift, #FFFDF9);
}

.horizon-profile-item--danger {
  color: #D65F4F;
}

.horizon-command-scrim {
  position: fixed;
  inset: 0;
  z-index: 120;
  background: rgba(55,59,77,0.22);
  backdrop-filter: blur(3px);
}

.horizon-command-scrim[hidden],
.horizon-command-palette[hidden] {
  display: none;
}

.horizon-command-palette {
  position: fixed;
  top: 9vh;
  left: 50%;
  z-index: 130;
  width: min(640px, 92vw);
  overflow: hidden;
  border: 1px solid var(--sw-border, #E5DED3);
  border-radius: 22px;
  background: rgba(252,250,246,0.78);
  box-shadow: 0 30px 80px rgba(55,59,77,0.24);
  backdrop-filter: blur(30px) saturate(190%);
  -webkit-backdrop-filter: blur(30px) saturate(190%);
  transform: translateX(-50%);
}

.horizon-command-input-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 18px 22px;
  border-bottom: 1px solid var(--sw-border, #E5DED3);
}

.horizon-command-input-row input {
  flex: 1;
  min-width: 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--sw-ink, #373B4D);
  font: inherit;
  font-size: 16px;
  font-weight: 650;
}

.horizon-command-input-row input::placeholder {
  color: #A29D8B;
}

.horizon-command-list {
  max-height: 72vh;
  overflow: auto;
  padding: 8px;
}

.horizon-command-group {
  padding: 10px 14px 5px;
  color: #A29D8B;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.horizon-command-item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 11px 14px;
  border: 0;
  border-radius: 12px;
  background: transparent;
  color: var(--sw-ink, #373B4D);
  text-align: left;
  font: inherit;
  cursor: pointer;
}

.horizon-command-item:hover,
.horizon-command-item.is-selected {
  background: var(--sw-card-lift, #FFFDF9);
}

.horizon-command-item.is-selected .horizon-command-dot {
  background: var(--sw-orange, #F38A3F);
}

.horizon-command-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--sw-light-blue, #BFE0F3);
  flex: none;
}

.horizon-command-copy {
  display: grid;
  gap: 2px;
  flex: 1;
  min-width: 0;
}

.horizon-command-title {
  min-width: 0;
  overflow: hidden;
  color: var(--sw-ink, #373B4D);
  font-size: 13.5px;
  font-weight: 650;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.horizon-command-subtitle {
  min-width: 0;
  overflow: hidden;
  color: var(--sw-muted, #8A836F);
  font-size: 11px;
  font-weight: 600;
  line-height: 1.25;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.horizon-command-kind {
  color: #A29D8B;
  font-size: 11px;
  font-weight: 650;
  white-space: nowrap;
}

.horizon-command-empty {
  padding: 26px 18px;
  color: var(--sw-muted, #8A836F);
  text-align: center;
  font-weight: 650;
}

.horizon-command-status {
  margin: 6px 10px 8px;
  padding: 10px 12px;
  border: 1px solid rgba(229, 222, 211, 0.8);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.46);
  color: var(--sw-muted, #8A836F);
  font-size: 11.5px;
  font-weight: 650;
}

.horizon-command-status--warn {
  color: #B96536;
}

.horizon-embed-section {
  max-width: min(1480px, 100%);
  margin: 0 auto;
}

/* Booking scheduler: CENTER the embedded wizard in the visible band between the
   command search (top) and the floating dock (bottom). min-height (not height)
   only adds slack when the wizard is shorter than the band; taller steps flow
   from the top and scroll normally, so nothing ever clips. The small
   padding-bottom biases the card a hair above true center so it reads clear of
   the floating dock. Never a negative margin-top here — it tucks the stepper
   under the command search. Desktop only; the phone app-shell owns its own
   booking layout (08-mobile-appshell.css). */
@media (min-width: 601px) {
  .horizon-embed-section[data-section="booking-portal"] .horizon-hub-main {
    min-height: calc(100vh - var(--chrome-top, 54px) - var(--chrome-bottom, 112px) - 24px);
    padding-bottom: 24px;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
}

/* Booking tab entrance: a pure fade, replacing the shell's default sectionIn
   (which slides in from the right — on this tab the lateral snap read as the
   card jerking into place). Re-runs on every visit because the section page
   toggles display:none, which restarts CSS animations. */
.admin-body .section-page[data-section="booking-portal"] .horizon-hub-layout > .horizon-hub-main {
  animation: bookingSectionFade 0.16s cubic-bezier(0.22, 1, 0.36, 1);
}
@keyframes bookingSectionFade {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* The wizard iframe re-sizes itself to its content (embed:height messages) on
   load and every step change. Untransitioned, each report snapped the frame —
   and with the band centering above, the whole card visibly jumped to its new
   resting spot. Easing the height turns those snaps into one soft settle (the
   inner FLIP card-morph runs concurrently, so the two read as one motion).
   The 480px floor matches the shell JS clamp in setupEmbedAutosize(). */
.horizon-embed-section[data-section="booking-portal"] .horizon-embed-frame--autosize {
  min-height: 480px;
  transition: height 0.16s cubic-bezier(0.22, 1, 0.36, 1);
}

@media (prefers-reduced-motion: reduce) {
  .admin-body .section-page[data-section="booking-portal"] .horizon-hub-layout > .horizon-hub-main { animation: none; }
  .horizon-embed-section[data-section="booking-portal"] .horizon-embed-frame--autosize { transition: none; }
}

/* The schedule is a dispatch board, not a reading page: give it more of the
   viewport than the standard 1480px column. Wider = more visible hours on the
   Day timeline and roomier Week matrix cells; the cap keeps ultrawide
   monitors from stretching cells absurdly. The booking scheduler (the Step 2
   tech-by-slot grid) shares the wide cap so it reads as the same board. */
.horizon-embed-section[data-section="schedule-agenda"],
.horizon-embed-section[data-section="booking-portal"] {
  max-width: min(1880px, 100%);
}

/* The hub landing-page components (.horizon-hub-hero, -primary, -secondary,
   -grid, -card) were removed 2026-06-09 with the dead booking-hub and
   settings-hub sections. The eyebrow survives: empty/connect panels use it. */
.horizon-hub-eyebrow {
  margin: 0 0 7px;
  color: #D9742B;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* One fixed rail width everywhere (was three different minmax ranges): the
   rail column is exactly as wide as the fixed location pill above it, so the
   two share both edges and read as one column at every viewport width. */
.horizon-hub-layout {
  display: grid;
  grid-template-columns: 236px minmax(0, 1fr);
  gap: 18px;
  align-items: start;
  transition: grid-template-columns var(--rail-anim, 180ms) cubic-bezier(0.22, 1, 0.36, 1),
              column-gap var(--rail-anim, 180ms) cubic-bezier(0.22, 1, 0.36, 1);
}

.horizon-context-layout--wide {
  grid-template-columns: 236px minmax(0, 1fr);
}

/* The KPI rail used to be a narrow 150px strip; it now matches the standard
   rail width so every tab's menu reads as the same component. */
.horizon-context-layout--kpi {
  grid-template-columns: 236px minmax(0, 1fr);
  gap: 18px;
}

.horizon-hub-main {
  min-width: 0;
}

/* ── Recent-bookings dock (Admin scheduler left column) ───────────────
   On the Admin scheduler the booking menu and a narrow "Recent bookings"
   panel share grid column 1 as one sticky unit, so the dock floats
   directly beneath the menu and stays pinned while the scheduler scrolls.
   The rail's own sticky is neutralized here because the wrapper now owns
   the pinning. Scoped to .scheduler-rail-col (which only the
   booking-portal section renders), so every other tab's rail is
   untouched. */
.scheduler-rail-col {
  position: sticky;
  top: var(--sticky-top, 16px);
  align-self: start;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
  max-height: calc(100vh - var(--sticky-top, 16px) - 14px);
}
.scheduler-rail-col .horizon-hub-rail {
  position: static;
  margin-top: 0;
  flex: 0 0 auto;
}
.scheduler-recent-dock {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  border: 1px solid rgba(229, 222, 211, 0.85);
  border-radius: 18px;
  background: linear-gradient(180deg, rgba(255, 254, 250, 0.88), rgba(252, 250, 246, 0.78));
  box-shadow: 0 14px 36px rgba(55, 59, 77, 0.08), inset 0 1px 0 rgba(255, 255, 255, 0.8);
  backdrop-filter: blur(22px) saturate(160%);
  -webkit-backdrop-filter: blur(22px) saturate(160%);
  overflow: hidden;
}
.scheduler-recent-dock[hidden] { display: none; }
.scheduler-recent-dock-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 11px 10px 8px 14px;
  flex: 0 0 auto;
}
.scheduler-recent-dock-title {
  font-size: 0.64rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--sw-muted, #7B8190);
}
.scheduler-recent-dock-refresh {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--sw-muted, #7B8190);
  cursor: pointer;
  transition: background 0.14s ease, color 0.14s ease;
}
.scheduler-recent-dock-refresh:hover { background: rgba(243, 138, 63, 0.10); color: #373B4D; }
.scheduler-recent-dock-refresh.is-spinning svg { animation: schedDockSpin 0.7s ease; }
@keyframes schedDockSpin { to { transform: rotate(360deg); } }
.scheduler-recent-dock-list {
  margin: 0;
  padding: 0 8px 10px;
  list-style: none;
  overflow-y: auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
  overscroll-behavior: contain;
}
.scheduler-recent-dock-row {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px;
  border-radius: 12px;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  transition: background 0.14s ease;
}
.scheduler-recent-dock-row:hover { background: rgba(255, 255, 255, 0.6); text-decoration: none; }
div.scheduler-recent-dock-row { cursor: default; }
.scheduler-recent-dock-avatar {
  flex: 0 0 28px;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  color: #fff;
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.02em;
}
.scheduler-recent-dock-stack {
  min-width: 0;
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.scheduler-recent-dock-name {
  font-size: 0.82rem;
  font-weight: 700;
  color: #373B4D;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.scheduler-recent-dock-sub {
  font-size: 0.7rem;
  color: var(--sw-muted, #7B8190);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.scheduler-recent-dock-sub b { color: #5C6370; font-weight: 700; }
.scheduler-recent-dock-pill {
  flex: 0 0 auto;
  font-size: 0.58rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #8A8475;
  background: rgba(229, 222, 211, 0.5);
  border-radius: 999px;
  padding: 3px 7px;
}
.scheduler-recent-dock-empty {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 14px;
}
.scheduler-recent-dock-empty strong { font-size: 0.8rem; color: #373B4D; }
.scheduler-recent-dock-empty span { font-size: 0.72rem; color: var(--sw-muted, #7B8190); }
/* Collapsed rail or narrow viewport → single column; drop the dock so it
   doesn't strand a panel above the scheduler. */
body.rail-collapsed .scheduler-rail-col { position: static; max-height: none; }
body.rail-collapsed .scheduler-recent-dock { display: none; }
@media (max-width: 960px) {
  .scheduler-rail-col { position: static; max-height: none; }
  .scheduler-recent-dock { display: none; }
}

/* ── Mini page head ──────────────────────────────────────────────────
   Page identity lives INSIDE the main column as one quiet row: a compact
   title plus a scope chip (which location, or global). Sections no longer
   render banners/titles/subs above .horizon-hub-layout, so every rail
   starts at the same Y on every tab and never jumps as you click through
   the menu; this row costs ~36px instead of the old banner + title + sub
   block. */
.hub-mini-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 12px;
  min-height: 32px;
  margin: 0 0 14px;
}

.hub-mini-title {
  margin: 0;
  color: var(--sw-ink-deep, #373B4D);
  font-size: 18px;
  font-weight: 850;
  letter-spacing: -0.01em;
  line-height: 1.2;
}

.hub-mini-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
  padding: 4px 11px;
  border: 1px solid rgba(229, 222, 211, 0.85);
  border-radius: 999px;
  background: rgba(255,255,255,0.55);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.80);
  color: var(--sw-muted, #7B8190);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.hub-mini-chip .dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--sw-orange, #F38A3F);
}

.hub-mini-chip--global .dot {
  background: var(--sw-green, #4BAA78);
}

/* A status badge can take the chip slot (e.g. Overview's health badge). */
.hub-mini-head > .badge2 {
  margin-left: auto;
}

/* ── Collapsible rail: pull-tab handle ─────────────────────────────
   One persisted body flag collapses every section rail so the work
   area gets full width. A slim vertical "pull tab" rides the seam
   between the rail and the work area; when the rail is hidden the tab
   slides to the work area's left edge and flips its chevron. Injected
   once by admin-dashboard.js (setupRailCollapse). The grid-template-
   columns transition above animates the slide; the tab's `left`
   transition is timed to match it. */
body.rail-collapsed .horizon-hub-layout {
  grid-template-columns: 0px minmax(0, 1fr);
  column-gap: 0;
}
body.rail-collapsed .horizon-hub-rail {
  min-width: 0;
  overflow: hidden;
  opacity: 0;
  transform: translateX(-10px);
  pointer-events: none;
}
/* Column 1 also carries the scheduler's recent-bookings dock; clip it as the
   column closes so nothing spills while it animates shut. */
body.rail-collapsed .scheduler-rail-col { overflow: hidden; }

/* Position (top + left) is owned by RailPullTab (public/js/rail-pull-tab.js):
   it measures the visible rail so the tab centers on the MENU's own height and
   tucks into the left margin when collapsed. The values here are only the
   pre-JS fallback plus the shared look and motion. */
#rail-toggle {
  position: fixed;
  top: 50%;
  left: 272px;
  transform: translateY(-50%);
  z-index: 85;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 56px;
  padding: 0;
  border: 1px solid rgba(229, 222, 211, 0.85);
  border-radius: 999px;
  /* Clear, glassy frost: mostly see-through so the content reads through it,
     leaning on a strong blur rather than an opaque fill. */
  background: linear-gradient(180deg, rgba(255,254,250,0.5), rgba(252,249,243,0.32));
  color: var(--sw-ink, #373B4D);
  cursor: pointer;
  box-shadow: 0 10px 26px rgba(55,59,77,0.12), inset 0 1px 0 rgba(255,255,255,0.6);
  backdrop-filter: blur(34px) saturate(200%);
  -webkit-backdrop-filter: blur(34px) saturate(200%);
  transition: left var(--rail-anim, 180ms) cubic-bezier(0.22, 1, 0.36, 1),
              transform 140ms ease, box-shadow 140ms ease, background 140ms ease;
}
#rail-toggle:hover {
  background: linear-gradient(180deg, rgba(255,255,253,0.62), rgba(255,253,249,0.44));
  box-shadow: 0 14px 32px rgba(55,59,77,0.16), inset 0 1px 0 rgba(255,255,255,0.72);
}
/* Tactile press; keep the centering transform so it squishes in place. */
#rail-toggle:active { transform: translateY(-50%) scale(0.94); }
/* The KPI job modal lives inside #app-scroll's own stacking context, so a
   root-level fixed toggle would otherwise float above it — hide it while the
   modal is open. */
body.kpi-desk-drawer-open #rail-toggle { display: none; }
#rail-toggle:focus-visible {
  outline: 2px solid var(--rail-active-bar, rgba(243,138,63,0.90));
  outline-offset: 2px;
}
#rail-toggle svg { width: 14px; height: 14px; flex: none; display: block; }
/* One chevron per state; it points the way the rail will move. */
#rail-toggle .rail-toggle-close,
#rail-toggle .rail-toggle-open { align-items: center; }
#rail-toggle .rail-toggle-close { display: inline-flex; }
#rail-toggle .rail-toggle-open { display: none; }
body.rail-collapsed #rail-toggle .rail-toggle-open { display: inline-flex; }
body.rail-collapsed #rail-toggle .rail-toggle-close { display: none; }

/* Hide the rail handle while modal/full-screen work surfaces own the viewport.
   Otherwise the fixed pull-tab can sit stranded over overlays whose rail is hidden. */
body.comm-editor-open #rail-toggle,
body:has([role="dialog"][aria-modal="true"]:not([hidden])) #rail-toggle,
body:has(.sched-fly-scrim.is-open) #rail-toggle,
body:has(.cust-drawer-scrim.is-open) #rail-toggle,
body:has(.pb-drawer-scrim.is-open) #rail-toggle,
body:has(.pw-scrim.is-open) #rail-toggle,
body:has(.pbpick-scrim.is-open) #rail-toggle,
body:has(.swcp-scrim.is-open) #rail-toggle,
body:has(.pcalc-scrim.is-open) #rail-toggle {
  display: none !important;
}

@media (max-width: 860px) {
  /* The menu is a compact horizontal strip here; hide the pull tab and undo the
     collapse animation so the strip stays fully shown + interactive (otherwise
     the opacity/transform from the collapsed state would leave it invisible). */
  #rail-toggle { display: none; }
  body.rail-collapsed .horizon-hub-layout {
    grid-template-columns: 1fr;
    column-gap: 0;
  }
  body.rail-collapsed .horizon-hub-rail {
    opacity: 1;
    transform: none;
    pointer-events: auto;
    overflow-x: auto;
    overflow-y: visible;
  }
}

/* One rail component for every tab (the booking rail's polish, promoted to
   the standard): soft glass panel, roomy tactile rows, and an independent
   scroll area. When the menu is taller than the viewport it scrolls
   internally; overscroll-behavior:contain keeps the wheel on the menu, not
   the page. */
.horizon-hub-rail {
  position: sticky;
  top: var(--sticky-top, 16px);
  /* --chrome-top now equals --sticky-top (the search is back, so content
     clears the top pills too), making this calc resolve to 0. It stays a calc
     so the rail self-corrects if the two tokens ever diverge again. The rail's
     sticky top keeps it pinned 54px down, clear of the location pill. */
  margin-top: calc(var(--sticky-top, 16px) - var(--chrome-top, 0px));
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 9px;
  border: 1px solid rgba(229, 222, 211, 0.85);
  border-radius: 18px;
  background: linear-gradient(180deg, rgba(255,254,250,0.68), rgba(252,249,243,0.46));
  box-shadow: 0 18px 42px rgba(55,59,77,0.11), inset 0 1px 0 rgba(255,255,255,0.78);
  backdrop-filter: blur(28px) saturate(185%);
  -webkit-backdrop-filter: blur(28px) saturate(185%);
  /* Fade + slide when the rail collapses/expands (the column width animates on
     .horizon-hub-layout above). */
  transition: opacity 170ms ease, transform 220ms cubic-bezier(0.22, 1, 0.36, 1);
  max-height: calc(100dvh - var(--sticky-top, 16px) - 22px);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--sw-border, #E5DED3) transparent;
}
.horizon-hub-rail::-webkit-scrollbar { width: 10px; }
.horizon-hub-rail::-webkit-scrollbar-thumb {
  background: var(--sw-border, #E5DED3);
  border-radius: 10px;
  border: 3px solid transparent;
  background-clip: padding-box;
}
.horizon-hub-rail::-webkit-scrollbar-thumb:hover { background: var(--sw-muted, #7B8190); background-clip: padding-box; }
.horizon-hub-rail::-webkit-scrollbar-track { background: transparent; }

.horizon-hub-rail-title {
  display: block;
  padding: 7px 9px 5px;
  margin: 0;
  color: var(--sw-muted, #7B8190);
  font-size: 10px;
  font-weight: 850;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.horizon-hub-rail-link {
  display: flex;
  min-height: 40px;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  gap: 10px;
  padding: 7px 11px;
  border: 1px solid transparent;
  border-radius: var(--rail-item-radius, 999px);
  color: var(--sw-ink, #373B4D);
  text-decoration: none;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.12s ease;
}

/* A rail link can be a <button> (the Site map action opens a modal instead of
   navigating). Reset native button chrome so it matches the <a> rows. */
button.horizon-hub-rail-link {
  width: 100%;
  font: inherit;
  text-align: left;
  background: none;
  -webkit-appearance: none;
  appearance: none;
  cursor: pointer;
}

/* Tactile press: the row gives slightly under the pointer. */
.horizon-hub-rail-link:active,
.rail-group-trigger:active {
  transform: scale(0.985);
}

/* Hover previews the selection in the same warm family, one register quieter
   than the orange pill: a pale orange-soft wash, no border or shadow chrome,
   label stays ink. The site-wide a:hover underline (style.css) is silenced
   for every anchor inside a rail. */
.horizon-hub-rail a:hover { text-decoration: none; }

.horizon-hub-rail-link:hover {
  border-color: transparent;
  background: var(--sw-orange-soft, #FFEEDC);
  box-shadow: none;
  text-decoration: none;
}

.horizon-hub-rail-link.is-active {
  /* Non-glide fallback (no sliding pill): same flat orange capsule. */
  border-color: transparent;
  background: var(--sw-orange, #F38A3F);
  box-shadow: none;
}

/* Resting labels speak in calm ink; only the selected row (and a closed group
   hiding it) steps up to deep ink at full weight, so the rail reads as one
   quiet list with a single confident selection. */
.horizon-hub-rail-link strong {
  color: var(--sw-ink, #373B4D);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0;
  line-height: 1.15;
}

.horizon-hub-rail-link small {
  display: none;
  color: var(--sw-muted, #7B8190);
  font-size: 11.5px;
  font-weight: 640;
  line-height: 1.25;
}

/* Two-line rows (label + sub-label) stack their text in one column so the
   icon tile stays anchored at the left. */
.rail-text {
  display: flex;
  min-width: 0;
  flex-direction: column;
}

/* ═══════════════ GLIDE RAILS — one sliding active indicator ═══════════════
   Every section rail carries .rail-glide: rows stay calm and transparent, and
   ONE pill (.rail-glide-ind) glides to the active item. KPI rails are
   positioned by public/js/kpi-rail.js (route-aware, incl. KPI Desk views);
   every other rail by setupRailGlide() in admin-dashboard.js. Because a
   workspace's rail is byte-identical on each of its pages, the pill reads as
   a single indicator sliding between items even when navigation swaps the
   underlying section. Design philosophy: warm fill + sunwave-orange accent
   for the current selection; calm elsewhere. */
.rail-glide .horizon-hub-rail-link,
.rail-glide .rail-group-trigger { position: relative; z-index: 1; }

/* Rows stay transparent; the sliding pill behind them shows the selection. */
.rail-glide .horizon-hub-rail-link {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
}
.rail-glide .horizon-hub-rail-link:hover {
  background: var(--sw-orange-soft, #FFEEDC);
  border-color: transparent;
  box-shadow: none;
}
.rail-glide .horizon-hub-rail-link.is-active {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
}
/* Active-row lettering stays DARK INK (the original language): it reads on
   the orange pill (~6:1) and on the bare cream panel, so text never blinks
   out while the pill is mid-glide. Secondary bits get ink-toned tweaks so
   they hold up on the orange. */
.rail-glide .horizon-hub-rail-link.is-active .rail-label,
.rail-glide .horizon-hub-rail-link.is-active strong {
  color: var(--sw-ink-deep, #373B4D);
  font-weight: 800;
}
.rail-glide .horizon-hub-rail-link.is-active .sched-rail-sub { color: rgba(55,59,77,0.72); }
.rail-glide .horizon-hub-rail-link.is-active .rail-count {
  background: rgba(255,255,255,0.55);
  color: var(--sw-ink-deep, #373B4D);
}
.rail-glide .horizon-hub-rail-link--danger.is-active .rail-label { color: var(--sw-ink-deep, #373B4D); }

/* Danger rows (Log out, Delete location) keep their coral wash on hover. */
.rail-glide .horizon-hub-rail-link--danger:hover { background: var(--sw-coral-wash, #FCEBE7); }

/* The sliding pill. Size/position set inline by JS; hidden until placed.
   Same glossy solid-orange treatment as the dock's .is-active-target pill,
   so "selected" reads identically in every menu. No backdrop-filter here:
   blurring a constantly-moving element janks the glide, and the pill is
   near-opaque anyway — the white highlights supply the gloss/fog. */
.rail-glide-ind {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 0;
  width: 0;
  height: 0;
  /* Style 13 (2026-06-10): full capsule, flat fully opaque brand orange —
     no gradient, no gloss highlights, no glow. The selected row's glyph
     rides it bare (no icon coin); see the .is-active .rail-icon rule. */
  border-radius: var(--sw-radius-pill, 999px);
  background: var(--sw-orange, #F38A3F);
  box-shadow: none;
  opacity: 0;
  pointer-events: none;
  will-change: transform, width, height;
  transition: transform 0.30s cubic-bezier(0.22, 1, 0.36, 1),
              width 0.30s cubic-bezier(0.22, 1, 0.36, 1),
              height 0.30s cubic-bezier(0.22, 1, 0.36, 1),
              opacity 0.18s ease;
}
@media (prefers-reduced-motion: reduce) {
  .rail-glide-ind { transition: opacity 0.18s ease; }
}

/* Keep the menu perfectly still on navigation. The section-level 6px entrance
   used to translate the sticky rail (the "jerk"); run it on the KPI content
   only so the rail never moves. */
.admin-body .section-page.horizon-kpi-section,
.section-page.horizon-kpi-section { animation: none; }
.section-page.horizon-kpi-section .horizon-hub-main { animation: sectionIn 0.26s cubic-bezier(0.22, 1, 0.36, 1); }

.page-rail {
  width: 100%;
}

.rail-list {
  display: grid;
  gap: var(--rail-row-gap, 5px);
  margin: 0;
  padding: 0;
  list-style: none;
}

.rail-section-label + .rail-list,
.rail-list + .rail-group,
.rail-group + .rail-list,
.rail-group + .rail-group {
  margin-top: var(--rail-group-gap, 16px);
}

/* Booking rail: uniform spacing between all sections (label, list, groups). */
.booking-page-rail {
  gap: var(--rail-group-gap, 16px);
}
.booking-page-rail > .rail-section-label + .rail-list,
.booking-page-rail > .rail-list + .rail-group,
.booking-page-rail > .rail-group + .rail-list,
.booking-page-rail > .rail-group + .rail-group {
  margin-top: 0;
}

.page-rail-link {
  width: 100%;
  min-height: var(--rail-min-h, 40px);
}

button.page-rail-link {
  appearance: none;
  border: 1px solid transparent;
  background: transparent;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.rail-label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.page-rail-link .rail-label {
  color: var(--sw-ink, #373B4D);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0;
  line-height: 1.15;
}

.rail-count {
  margin-left: auto;
  padding: 2px 7px;
  border-radius: 999px;
  background: var(--rail-badge-fill, #FFFDF9);
  color: var(--rail-muted, #7B8190);
  font-size: 11px;
  font-weight: 850;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
}

/* An empty count is hidden so the rail stays quiet (no column of zeros). */
.rail-count:empty {
  display: none;
}

/* Status dot: a small at-a-glance signal at the left of a row. Prefer a dot
   over a colored pill so the rail stays calm (PAGE_LAYOUT_STANDARD.md 6.9). */
.rail-dot {
  flex: 0 0 auto;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--sw-muted, #7B8190);
}
.rail-dot[hidden] { display: none; }
.rail-dot--review { background: var(--sw-gold, #D39A2E); }
.rail-dot--unpaid { background: var(--sw-coral, #D65F4F); }
.rail-dot--ok { background: var(--sw-green, #4BAA78); }
.rail-dot--info { background: var(--sw-blue, #BFE0F3); }

.rail-group {
  display: grid;
  /* No gap while collapsed: the panel is still a grid row (just 0fr tall),
     so a base gap here would reserve phantom space below the trigger and
     make a closed group taller than the row above it. The 4px breathing
     room belongs between the trigger and the panel only when open. */
  gap: 0;
}
.rail-group.is-open {
  gap: 4px;
}

.rail-group-trigger {
  appearance: none;
  display: flex;
  width: 100%;
  min-height: var(--rail-min-h, 40px);
  align-items: center;
  gap: 10px;
  padding: 7px 9px;
  border: 1px solid transparent;
  border-radius: var(--rail-item-radius, 10px);
  background: transparent;
  color: var(--rail-ink, #373B4D);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.12s ease;
}

.rail-group-trigger:hover,
.rail-group-trigger:focus-visible {
  border-color: transparent;
  background: var(--sw-orange-soft, #FFEEDC);
  box-shadow: none;
}

.rail-group-trigger .rail-label {
  color: var(--sw-ink, #373B4D);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0;
  line-height: 1.15;
}

/* A closed group hiding the active row: a soft peach fill says "you are in
   here" (the old inset left bar drew a square edge inside the capsule). */
.rail-group--has-active:not(.is-open) .rail-group-trigger {
  background: var(--sw-orange-soft, #FFEEDC);
}

.rail-chevron {
  width: 14px;
  height: 14px;
  margin-left: auto;
  color: var(--rail-muted, #7B8190);
  transition: transform var(--rail-anim, 180ms) ease;
}

.rail-group.is-open > .rail-group-trigger .rail-chevron {
  transform: rotate(90deg);
}

.rail-group-panel {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition: grid-template-rows var(--rail-anim, 180ms) ease, opacity var(--rail-anim, 180ms) ease;
}

/* Child combinator on purpose: groups can nest (the KPI rail's desk views sit
   inside the Technician Performance group). A descendant selector here would
   let an open OUTER group force a closed INNER panel to full height, leaving
   a tall blank gap where its hidden links sit. */
.rail-group.is-open > .rail-group-panel {
  grid-template-rows: 1fr;
  opacity: 1;
}

.rail-group-panel .rail-list {
  min-height: 0;
  margin-left: var(--rail-indent, 16px);
  padding-left: 8px;
  overflow: hidden;
  border-left: 1px solid var(--rail-guide, #E5DED3);
}

.rail-group:not(.is-open) .rail-group-panel a,
.rail-group:not(.is-open) .rail-group-panel button {
  visibility: hidden;
  pointer-events: none;
}

.rail-list--nested .page-rail-link {
  min-height: 32px;
  padding: 6px 10px;
  border-radius: var(--rail-item-radius, 999px);
}

.rail-list--nested .page-rail-link strong,
.rail-list--nested .page-rail-link .rail-label {
  font-size: 12px;
  font-weight: 700;
}

/* Static fallback for panel links outside a glide rail (none today): match
   the flat orange capsule selected language. */
.rail-panel-link.is-active {
  background: var(--sw-orange, #F38A3F);
  border-radius: var(--sw-radius-pill, 999px);
  box-shadow: none;
}
.rail-panel-link.is-active .rail-label { color: var(--sw-ink-deep, #373B4D); }

/* Second, deeper level: the active settings item reveals its in-page sub-panels
   nested beneath it (e.g. Schedule settings -> Calendar, Arrival windows, ...).
   The indent and guide line come from the .rail-group-panel .rail-list rule
   above; this only adds vertical breathing room. */
.rail-list--panel {
  margin-top: 4px;
  margin-bottom: 6px;
}

.page-rail-link:focus-visible,
.rail-group-trigger:focus-visible {
  outline: 2px solid var(--sw-orange, #F38A3F);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .rail-chevron,
  .rail-group-panel {
    transition: none;
  }
}

/* The booking rail's polish (icon tiles, tactile rows, independent scroll)
   was promoted to the base .horizon-hub-rail component above, so every tab's
   menu shares it; no booking-specific overrides remain. */

/* Icon coin on every rail row (same drawing language as the main nav:
   20x20 viewBox, 1.6 stroke, round caps). A perfect circle styled like a
   small frosted-glass token resting on the tray: warm lift fill, a hairline
   edge where the light catches, and a whisper of ambient shadow. Shared by
   every tab's menu — Booking, Schedule, KPI, Settings, Profile, Overview,
   Locations — so the rails read as one component across the whole admin. */
.horizon-hub-rail .rail-icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: var(--sw-radius-pill, 999px);
  background: var(--sw-card-lift, #FFFDF9);
  color: var(--sw-muted, #7B8190);
  box-shadow: inset 0 0 0 1px var(--sw-border, #E5DED3),
              inset 0 1px 0 rgba(255, 255, 255, 0.9),
              0 1px 3px var(--sw-shadow, rgba(55, 59, 77, 0.08));
  transition: background 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
}
.horizon-hub-rail .rail-icon svg { width: 16px; height: 16px; }

/* Hover warms the tile one step past the row wash so the whole row reads as a
   preview of selection: idle gray tile, hover warm tile on a pale peach row,
   active frosted-white tile riding the glossy orange pill. */
.horizon-hub-rail .horizon-hub-rail-link:hover .rail-icon,
.horizon-hub-rail .rail-group-trigger:hover .rail-icon {
  background: rgba(243, 138, 63, 0.18);
  color: var(--sw-orange-dark, #C8651C);
  box-shadow: inset 0 0 0 1px rgba(243, 138, 63, 0.32),
              inset 0 1px 0 rgba(255, 255, 255, 0.55);
}

/* Danger rows (Log out, Delete location) stay coral on hover; they never
   preview the orange selection. */
.horizon-hub-rail .horizon-hub-rail-link--danger:hover .rail-icon {
  background: var(--sw-coral-wash, #FCEBE7);
  color: var(--sw-coral, #D65F4F);
  box-shadow: inset 0 0 0 1px rgba(214, 95, 79, 0.30),
              inset 0 1px 0 rgba(255, 255, 255, 0.6);
}
/* Active rows ride the flat orange capsule with a BARE glyph: the coin
   dissolves entirely (style 13) and the icon draws in the same ink as the
   label, so icon + label read as one unit on the orange. */
.horizon-hub-rail .horizon-hub-rail-link.is-active .rail-icon,
.horizon-hub-rail .rail-panel-link.is-active .rail-icon,
.horizon-hub-rail .rail-group-trigger.is-active .rail-icon {
  background: transparent;
  color: var(--sw-ink-deep, #373B4D);
  box-shadow: none;
}

/* A closed group hiding the active row sits on cream (no pill), so its
   trigger keeps the warm orange tint. */
.horizon-hub-rail .rail-group--has-active:not(.is-open) .rail-group-trigger .rail-icon {
  background: rgba(243, 138, 63, 0.18);
  color: var(--sw-orange-dark, #C8651C);
  box-shadow: inset 0 0 0 1px rgba(243, 138, 63, 0.32),
              inset 0 1px 0 rgba(255, 255, 255, 0.55);
}

/* A group trigger that is itself the active destination (e.g. KPI admin with
   no sub-queue chosen yet) rides the pill too; same dark-ink label. A closed
   group hiding the active row also keeps its label at selection strength. */
.rail-glide .rail-group-trigger.is-active .rail-label,
.rail-group--has-active:not(.is-open) .rail-group-trigger .rail-label {
  color: var(--sw-ink-deep, #373B4D);
  font-weight: 800;
}

/* Danger rows (Log out, Delete location) tint their coin coral. */
.horizon-hub-rail .horizon-hub-rail-link--danger .rail-icon {
  background: var(--sw-coral-wash, #FCEBE7);
  color: var(--sw-coral, #D65F4F);
  box-shadow: inset 0 0 0 1px rgba(214, 95, 79, 0.22),
              inset 0 1px 0 rgba(255, 255, 255, 0.6);
}

/* Nested (grouped) rows: slightly smaller tile, tighter indent. */
.horizon-hub-rail .rail-group-panel .rail-list { margin-left: 11px; padding-left: 10px; }
.horizon-hub-rail .rail-list--nested .page-rail-link { min-height: 34px; padding: 5px 8px; gap: 9px; }
.horizon-hub-rail .rail-list--nested .rail-icon { width: 24px; height: 24px; border-radius: var(--sw-radius-pill, 999px); }
.horizon-hub-rail .rail-list--nested .rail-icon svg { width: 15px; height: 15px; }

.horizon-embed-frame {
  display: block;
  width: 100%;
  height: min(980px, calc(100vh - 226px));
  min-height: 680px;
  border: 0;
  background: #fff;
}

.horizon-embed-frame--flush {
  height: calc(100vh - 232px);
  min-height: 720px;
  border-radius: 14px;
  background: transparent;
}

/* Auto-sized embed: the iframe grows to its content height (set inline by JS via
   the embed:height postMessage), so it has no inner scrollbar and flows with the
   page. The values here are only the pre-JS fallback. See PAGE_LAYOUT_STANDARD.md
   section 5. */
.horizon-embed-frame--autosize {
  height: auto;
  min-height: 600px;
}

/* Customer booking-link share bar above the embedded public booker.
   Bento-Box Soft Minimalism: warm card, generous whitespace, pill controls,
   one ambient low-opacity shadow. The copy is width-capped so it never crowds
   the actions cluster (Rule of Proximity). */
.online-booking-share {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 10px 18px;
  margin: 0 auto 14px;
  padding: 12px 16px;
  width: fit-content;
  max-width: 100%;
  border: 1px solid var(--sw-border, #E5DED3);
  border-radius: 16px;
  background: linear-gradient(180deg, var(--sw-card-hi, #FFFDF9), var(--sw-card, #FCFAF6));
  box-shadow: 0 10px 26px rgba(55,59,77,0.05);
}
.online-booking-share-copy {
  display: grid;
  flex: 0 0 auto;
}
.online-booking-share-copy strong {
  color: var(--sw-ink-deep, #373B4D);
  font-size: 15px;
  font-weight: 820;
  letter-spacing: -0.01em;
}
.online-booking-share-copy span {
  color: var(--sw-muted, #7B8190);
  font-size: 13px;
  font-weight: 600;
  line-height: 1.45;
}
.online-booking-share-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.online-booking-share-url {
  padding: 9px 20px;
  border: 1px solid var(--sw-border, #E5DED3);
  border-radius: 999px;
  background: var(--sw-card-lift, #FFFDF9);
  color: var(--sw-ink, #373B4D);
  font-family: 'Inter', system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: -0.01em;
  white-space: nowrap;
  max-width: 440px;
  overflow: hidden;
  text-overflow: ellipsis;
}

.horizon-embed-frame--kpi {
  height: calc(100vh - 174px);
  min-height: 760px;
  border-radius: 12px;
}

.horizon-empty-panel {
  min-height: 420px;
  padding: clamp(28px, 5vw, 64px);
  border: 1px solid rgba(229, 222, 211, 0.85);
  border-radius: 14px;
  background: linear-gradient(180deg, rgba(255,254,250,0.68), rgba(252,249,243,0.46));
  box-shadow: 0 18px 42px rgba(55,59,77,0.10), inset 0 1px 0 rgba(255,255,255,0.76);
  backdrop-filter: blur(24px) saturate(175%);
  -webkit-backdrop-filter: blur(24px) saturate(175%);
}

.horizon-empty-panel h1 {
  margin: 0 0 10px;
  color: var(--sw-ink-deep, #373B4D);
  font-size: clamp(30px, 4vw, 52px);
  font-weight: 840;
  letter-spacing: 0;
}

.horizon-empty-panel p:last-child {
  max-width: 620px;
  margin: 0;
  color: var(--sw-muted, #7B8190);
  font-size: 15px;
  font-weight: 620;
  line-height: 1.55;
}

.admin-body .admin-nav-source {
  position: fixed;
  top: 78px;
  left: 20px;
  z-index: 82;
  width: min(330px, calc(100vw - 40px));
  height: auto;
  max-height: none;
  overflow: visible;
  padding: 0;
  border: 0;
  background: transparent;
  box-shadow: none;
  pointer-events: none;
}

.admin-body .admin-nav-source .admin-nav-group {
  display: none !important;
}

/* The copy-from panel floats on its own now (it used to be the one visible
   group left inside the hidden sidebar, which meant it could never paint on
   phone, where .admin-nav is display:none). Same spot on screen: a glass
   card hanging under the workspace pill. */
.admin-body .loc-add-float {
  position: fixed;
  top: 78px;
  left: 20px;
  z-index: 84;
  width: min(330px, calc(100vw - 40px));
}

.admin-body .loc-add-float .admin-nav-loc-add-panel {
  margin: 0;
  padding: 12px 10px 10px;
  border: 1px solid rgba(229, 222, 211, 0.85);
  border-radius: 18px;
  background: linear-gradient(180deg, rgba(255,254,250,0.78), rgba(252,250,246,0.62));
  box-shadow: 0 22px 50px rgba(55,59,77,0.18), 0 6px 18px rgba(55,59,77,0.08);
  backdrop-filter: blur(30px) saturate(190%);
  -webkit-backdrop-filter: blur(30px) saturate(190%);
}

.admin-body .loc-add-float .admin-nav-loc-add-panel[hidden] {
  display: none !important;
}

/* ── Location name (asked FIRST — seeds the URL slug + Square location) ── */
.admin-body .loc-add-name {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 2px 0 8px;
  padding: 9px 8px 8px;
  border: 1px solid var(--sw-border, #E5DED3);
  border-radius: 14px;
  background: var(--sw-card-lift, #FFFDF9);
}

.admin-body .loc-add-name-label {
  margin: 0;
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--sw-muted, #7B8190);
}

.admin-body .loc-add-name-input {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  min-height: 34px;
  padding: 7px 11px;
  border: 1px solid var(--sw-border, #E5DED3);
  border-radius: var(--sw-radius-input, 14px);
  background: var(--sw-card, #FCFAF6);
  color: var(--sw-ink, #373B4D);
  font-family: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  line-height: 1.2;
  transition: border-color 0.14s ease, box-shadow 0.14s ease;
}

.admin-body .loc-add-name-input::placeholder {
  color: var(--sw-muted, #7B8190);
  font-weight: 500;
}

.admin-body .loc-add-name-input:focus {
  outline: none;
  border-color: transparent;
  box-shadow: var(--sw-focus-shadow, 0 0 0 1px #F38A3F, 0 6px 13px rgba(243, 138, 63, 0.30));
}

/* Nudge state: a source was clicked with no name typed yet. */
.admin-body .loc-add-name-input.is-missing {
  border-color: var(--sw-coral, #D65F4F);
  box-shadow: 0 0 0 1px var(--sw-coral, #D65F4F), 0 6px 13px rgba(214, 95, 79, 0.22);
}

.admin-body .loc-add-name-note {
  margin: 0;
  font-size: 0.72rem;
  line-height: 1.35;
  color: var(--sw-muted, #7B8190);
}

/* ── Job provider choice (Housecall Pro vs Sunwave only) ──────────────
   Two pills, one orange active at a time. Inactive is the quiet lift +
   hairline so it still reads as a control, never a bare grey box. */
.admin-body .loc-add-provider {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 2px 0 8px;
  padding: 9px 8px 8px;
  border: 1px solid var(--sw-border, #E5DED3);
  border-radius: 14px;
  background: var(--sw-card-lift, #FFFDF9);
}

.admin-body .loc-add-provider-label {
  margin: 0;
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--sw-muted, #7B8190);
}

.admin-body .loc-add-provider-choices {
  display: flex;
  gap: 6px;
}

.admin-body .loc-add-provider-pill {
  -webkit-appearance: none;
  appearance: none;
  flex: 1 1 0;
  min-height: 32px;
  padding: 7px 10px;
  border: 1px solid var(--sw-border, #E5DED3);
  border-radius: var(--sw-radius-pill, 999px);
  background: var(--sw-card, #FCFAF6);
  color: var(--sw-ink, #373B4D);
  font-family: inherit;
  font-size: 0.78rem;
  font-weight: 700;
  line-height: 1.1;
  cursor: pointer;
  transition: background 0.14s ease, border-color 0.14s ease, color 0.14s ease, transform 0.14s ease;
}

.admin-body .loc-add-provider-pill:hover {
  border-color: rgba(243, 138, 63, 0.45);
  transform: translateY(-1px);
}

.admin-body .loc-add-provider-pill:focus-visible {
  outline: 2px solid var(--sw-orange, #F38A3F);
  outline-offset: 2px;
}

.admin-body .loc-add-provider-pill.is-on {
  background: var(--sw-orange-soft, #FFEEDC);
  border-color: var(--sw-orange, #F38A3F);
  color: var(--sw-orange-dark, #C66518);
}

.admin-body .loc-add-provider-note {
  margin: 0;
  font-size: 0.72rem;
  line-height: 1.35;
  color: var(--sw-muted, #7B8190);
}

@media (prefers-reduced-motion: reduce) {
  .admin-body .loc-add-provider-pill { transition: none; }
  .admin-body .loc-add-provider-pill:hover { transform: none; }
}

/* Phone: the sidebar is gone entirely, so the panel hangs off the same
   floating pill with the app-shell's own top clearance. */
@media (max-width: 600px) {
  .admin-body .loc-add-float {
    top: calc(var(--chrome-top, 64px) + 6px);
    left: 12px;
    right: 12px;
    width: auto;
  }
}

.admin-body .admin-page-footer {
  padding-bottom: 18px;
}

.admin-body .save-bar,
.admin-body .bento-save-bar {
  bottom: 92px;
}

@media (max-width: 1040px) {
  .horizon-dock {
    gap: 5px;
    padding: 7px 8px;
  }
  .horizon-tab,
  .admin-body .horizon-tab {
    padding: 8px 11px;
    font-size: 13px;
  }
  /* Pill and rail shrink together so they keep sharing both edges. */
  .horizon-cornerbar {
    width: 170px;
  }
  .horizon-hub-layout {
    grid-template-columns: 170px minmax(0, 1fr);
  }
}

@media (max-width: 860px) {
  /* The centered search can no longer clear the left location pill at this
     width, so it drops to a full-width second row just below the pill, and
     the page reserves enough top room for both (pill row + search row). */
  :root { --chrome-top: 104px; }
  .horizon-searchbar {
    top: 58px;
    width: calc(100vw - 28px);
  }
  .admin-body .admin-shell {
    /* .admin-shell is INSIDE .app-scroll, which pads the top by
       var(--chrome-top) (bumped above to clear the two stacked top rows).
       Bottom is 0 because .app-scroll supplies --chrome-bottom. */
    padding: 0 16px 0;
  }
  .horizon-dock {
    bottom: 8px;
    width: calc(100vw - 20px);
    gap: 5px;
    border-radius: 24px;
  }
  .horizon-dock-center {
    justify-content: flex-start;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .horizon-dock-center::-webkit-scrollbar {
    display: none;
  }
  .horizon-tab,
  .admin-body .horizon-tab {
    padding: 8px 12px;
  }
  .horizon-command-kbd {
    display: none;
  }
  .horizon-hub-layout {
    grid-template-columns: 1fr;
  }
  /* On mobile every rail is a horizontal strip, so undo the desktop
     sticky / independent-scroll treatment and let it scroll sideways. */
  .horizon-hub-rail {
    position: relative;
    top: auto;
    flex-direction: row;
    max-height: none;
    overflow-x: auto;
    overflow-y: visible;
    overscroll-behavior: auto;
    padding: 7px;
    scrollbar-width: none;
  }
  .horizon-hub-rail::-webkit-scrollbar {
    display: none;
  }
  .horizon-hub-rail-link {
    min-width: 188px;
  }
  .page-rail .rail-list,
  .page-rail .rail-group {
    min-width: 188px;
  }
  .page-rail .rail-section-label {
    display: none;
  }
  .page-rail .rail-group-panel {
    grid-template-rows: 1fr;
    opacity: 1;
  }
  .page-rail .rail-group-panel .rail-list {
    margin-left: 0;
    margin-top: 6px;
    padding-left: 0;
    border-left: 0;
  }
  /* The strip forces every group panel open (above), so make those rows
     visible and clickable too, and drop the now-meaningless chevron. */
  .page-rail .rail-group:not(.is-open) .rail-group-panel a,
  .page-rail .rail-group:not(.is-open) .rail-group-panel button {
    visibility: visible;
    pointer-events: auto;
  }
  .page-rail .rail-chevron {
    display: none;
  }
  /* Booking portal: the whole Settings group (Booking settings, Availability,
     Available techs, Service area, Service categories, Booking survey) is
     desktop-only — drop it from the mobile booking strip. Tools + the two
     primary links (Admin scheduler, Online booking page) stay. */
  .booking-page-rail .rail-group--booking-settings {
    display: none;
  }
  .horizon-embed-frame {
    height: calc(100vh - 238px);
    min-height: 560px;
  }
}

@media (max-width: 560px) {
  /* Phone: hug the location name and center the pill on the row instead of
     spanning edge-to-edge, and sit it a touch higher. fit-content + max-width
     keeps a short name compact while a long one ellipsizes (the label cap
     below) before the pill can reach the screen edges. */
  .horizon-cornerbar {
    /* max() clears the clock / Dynamic Island in the installed app (safe-area
       inset > 0) and keeps the original 8px in a browser tab (inset = 0). The
       schedule/inbox embeds' top clearance assumes this exact formula. */
    top: max(8px, env(safe-area-inset-top, 0px));
    left: 50%;
    right: auto;
    transform: translateX(-50%);
    width: fit-content;
    max-width: calc(100vw - 28px);
  }
  .horizon-workspace {
    min-width: 0;
  }
  .horizon-workspace-trigger span {
    overflow: hidden;
    max-width: calc(100vw - 104px);
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  /* The pill is now centered + content-width, so its dropdown can't anchor to
     the (off-center, brand-shifted) workspace or it shoots off the right edge.
     Pin it to the viewport instead: 14px from each edge, just under the pill. */
  .horizon-workspace-menu {
    position: fixed;
    top: calc(max(8px, env(safe-area-inset-top, 0px)) + 43px); /* pill top + height(36) + 7px gap */
    left: 14px;
    right: 14px;
    width: auto;
    transform: none;
    z-index: 140;         /* above the pill/dock chrome (z 90) */
  }
  /* Point the little notch up at the centered pill, not the far-left corner
     (keep the 45° rotation that forms the diamond). */
  .horizon-workspace-menu::before {
    left: 50%;
    transform: translateX(-50%) rotate(45deg);
  }
}

/* ════════ Super Admin (org) — dark-grey workspace ════════
   The cross-location workspace turns dark grey so it's instantly obvious
   you're org-wide, not inside one location. The original dark treatment
   lived on `.site-header`, but the horizon rewrite hides that element
   (`.admin-legacy-header { display:none }` in 05-hubs-keys-users.css), so
   it never showed — the styling was painting an invisible bar. These rules
   re-apply it to the LIVE floating chrome (corner pill, command search,
   dock) plus the page canvas, and flip the chrome text/icons to light.
   The `is-super-admin` body class is server-rendered, so there's no flash,
   and content cards keep their own light backgrounds, so they still read. */

/* Page canvas → dark grey, with the brand tints dimmed so light cards pop. */
.admin-body.is-super-admin {
  background:
    radial-gradient(980px 640px at 92% -12%, rgba(191,224,243,0.10), transparent 60%),
    radial-gradient(860px 620px at -12% 112%, rgba(243,138,63,0.06), transparent 58%),
    #23252C;
}

/* The three floating glass bars → dark-grey frosted glass. */
.admin-body.is-super-admin .horizon-cornerbar,
.admin-body.is-super-admin .horizon-command-pill,
.admin-body.is-super-admin .horizon-dock {
  background: linear-gradient(180deg, rgba(46,48,57,0.86), rgba(36,38,46,0.78));
  border-color: rgba(255,255,255,0.12);
  box-shadow: 0 18px 44px rgba(0,0,0,0.42), 0 4px 14px rgba(0,0,0,0.24), inset 0 1px 0 rgba(255,255,255,0.08);
}
/* …but the dock itself reads as far more transparent dark glass (the "more
   transparent tabs" request). The cornerbar + command pill keep the solid dark
   treatment above; this later same-specificity rule overrides only the dock. */
.admin-body.is-super-admin .horizon-dock {
  background: linear-gradient(180deg, rgba(46,48,57,0.34), rgba(36,38,46,0.22));
  box-shadow: 0 18px 44px rgba(0,0,0,0.30), 0 4px 14px rgba(0,0,0,0.18), inset 0 1px 0 rgba(255,255,255,0.10);
}

/* Workspace switcher (corner pill) — text + caret to light. */
.admin-body.is-super-admin .horizon-workspace-trigger { color: #EAF0FB; }
.admin-body.is-super-admin .horizon-workspace-trigger:hover { background: rgba(255,255,255,0.10); }

/* Command search — light glyph + placeholder + key hint. */
.admin-body.is-super-admin .horizon-command-pill,
.admin-body.is-super-admin .horizon-command-glyph,
.admin-body.is-super-admin .horizon-command-placeholder { color: rgba(234,240,251,0.74); }
.admin-body.is-super-admin .horizon-command-kbd {
  background: rgba(255,255,255,0.10);
  border-color: rgba(255,255,255,0.16);
  color: rgba(234,240,251,0.82);
}

/* Dock tabs — light when idle, white on hover; the active orange pill
   already reads fine on dark, so it's left untouched. Hover feedback is the
   icon brightening ONLY — no background wash (the faint white pill read as a
   stray bubble hanging off the icon on the dark glass dock). */
.admin-body.is-super-admin .horizon-tab { color: rgba(234,240,251,0.72); }
.admin-body.is-super-admin .horizon-tab:hover {
  background: transparent;
  color: #FFFFFF;
}
/* Keep the active orange pill (dark ink) on the dark dock too — these win over
   the lighter super-admin tab color + hover wash above (incl. when hovered). */
.admin-body.is-super-admin .horizon-tab.is-active,
.admin-body.is-super-admin .horizon-tab.is-active:hover {
  background: var(--sw-orange, #F38A3F);
  color: #373B4D;
}

/* Profile avatar — a faint light ring so the dark-ink circle stays
   distinct against the dark dock. */
.admin-body.is-super-admin .horizon-profile-trigger {
  box-shadow: 0 0 0 1px rgba(255,255,255,0.20), 0 2px 6px rgba(0,0,0,0.30);
}
