/* =====================================================================
   Service Bar — component re-skin layer (goal_migration UI rework).
   Loaded AFTER styles.css so equal-specificity later rules win the cascade.
   Consumes /styles/tokens.css. Assembled from public/styles/_parts/*.css
   (one part per component category). To regenerate: re-run the reskin
   workflow then re-cat the parts.
   ===================================================================== */

/* =====================================================================
   Service Bar re-skin · Category 01 — Global base, typography, links,
   focus, scrollbars, selection.
   ---------------------------------------------------------------------
   Appended AFTER styles.css; equal-specificity later rules win. Where an
   existing app rule is MORE specific, this file repeats the app's own
   selector (or scopes by id) to match/exceed it rather than using
   !important. Every value consumes /styles/tokens.css (Service Bar).
   Hardcoded literals are flagged inline; none are colors.
   ===================================================================== */

/* ---------------------------------------------------------------------
   1 · BASE — page paper, system grotesque stack, body rhythm.
   Reinforces the app's existing body{} (styles.css:7061) with the full
   recipe: token type scale, optimizeLegibility, calm numerals default.
   --------------------------------------------------------------------- */
html {
  background: var(--surface-page);
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Firefox scrollbar tint — inherited; does not force width (calm). */
  scrollbar-color: var(--scale-ink-300) transparent;
}

body {
  font-family: var(--font);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  letter-spacing: var(--ls-body);
  color: var(--color-text);
  background: var(--surface-page);
  font-variant-numeric: var(--fnum-default);
  text-rendering: optimizeLegibility;
}

/* Two weights only (400 / 600). Bare emphasis maps to semibold, not the
   UA 700, so the hierarchy stays size-and-ink driven (tokens §4). */
strong,
b,
dt {
  font-weight: var(--fw-semibold);
}

/* ---------------------------------------------------------------------
   2 · TYPE SCALE — headings map to the token ramp. Weights drop from the
   UA 700 to 600 (the system's single heavy weight). Letter-spacing wins
   over the app's `* { letter-spacing: 0 }` (styles.css:7057) by virtue of
   element specificity (0,0,1) > universal (0,0,0). Margins are left to
   the app's per-context heading rules — only the type face is set here.
   --------------------------------------------------------------------- */
h1 {
  font-size: var(--fs-h1);
  line-height: var(--lh-h1);
  font-weight: var(--fw-h1);
  letter-spacing: var(--ls-h1);
}

h2,
.employee-hero-copy h2 {
  font-size: var(--fs-h2);
  line-height: var(--lh-h2);
  font-weight: var(--fw-h2);
  letter-spacing: var(--ls-h2);
}

h3 {
  /* 16px: a deliberate step between --fs-h2 (18) and --fs-body (15);
     no dedicated h3 token exists in tokens.css §4 (noted). */
  font-size: 16px;
  line-height: var(--lh-h2);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-h2);
}

h4 {
  font-size: var(--fs-body);
  line-height: var(--lh-h2);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-body);
}

/* DISPLAY step — the schedule period header set "with intent" (tokens
   §4 display graft). #scheduleDetail / #pastScheduleDetail carry the
   week date range, so they take tabular numerals too. Id scope (1,0,1)
   clears the generic h3 rule above. */
#scheduleDetail > h3,
#pastScheduleDetail > h3 {
  font-size: var(--fs-display);
  line-height: var(--lh-display);
  font-weight: var(--fw-display);
  letter-spacing: var(--ls-display);
  font-variant-numeric: var(--fnum-data);
}

/* Per-week landmark inside the grid ("Week 1" / "Week 2") — elevated
   from the UA-small h4 to the h1 step so each week reads as a header. */
.week-section > h4 {
  font-size: var(--fs-h1);
  line-height: var(--lh-h1);
  font-weight: var(--fw-h1);
  letter-spacing: var(--ls-h1);
  font-variant-numeric: var(--fnum-data);
}

/* ---------------------------------------------------------------------
   3 · OVERLINES / CAPTIONS — the one uppercase type style (tokens §4
   caption: 11px / 600 / 0.06em tracked). Voice guide: ALL-CAPS exists
   ONLY as this overline style, never as copy emphasis. Color is left to
   the app's own rule so role/brand meaning is untouched — type only.
   Selectors mirror styles.css:7124 and :35 for equal specificity. */
.card-eyebrow,
.manager-sidebar-group-title,
.dashboard-action-kicker {
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  font-weight: var(--fw-caption);
  letter-spacing: var(--ls-caption);
  text-transform: uppercase;
}

.configuration-feature-group h4 {
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  font-weight: var(--fw-caption);
  letter-spacing: var(--ls-caption);
  text-transform: uppercase;
}

/* ---------------------------------------------------------------------
   4 · LINKS — never default blue or visited-purple (audit #6). Bare
   inline anchors get the underline recipe; class-bearing anchors (nav
   items, .button-link, .marketing-* etc.) are link-shaped components and
   keep their own color/decoration via higher specificity.
   --------------------------------------------------------------------- */
a,
a:visited {
  color: var(--color-link);
}

a:hover {
  color: var(--color-link-hover);
}

a:not([class]) {
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}

a:not([class]):hover {
  text-decoration-thickness: 2px;
}

/* ---------------------------------------------------------------------
   5 · FOCUS — ONE recipe app-wide (audit #12): 2px solid ring, 2px
   offset, replacing the old 0.22-alpha 3px blue ring (styles.css:8803).
   Danger controls swap the ring to --focus-danger. Tabs / horizontally
   scrolling link strips use an inset (-2px) offset so the ring isn't
   clipped by their overflow. Selectors repeat the app's own focus group
   so equal specificity + later source wins (no !important).
   --------------------------------------------------------------------- */
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
a:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible,
[role="button"]:focus-visible,
.settings-tab-btn:focus-visible,
.manager-mobile-tab-btn:focus-visible,
.manager-mobile-more-link:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: var(--focus-ring-offset);
}

/* Inset ring where the +2px offset would clip (tabs, scroll strips). */
.settings-tab-btn:focus-visible,
.manager-mobile-tab-btn:focus-visible,
.manager-mobile-more-link:focus-visible,
.workspace-section-link:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: -2px;
}

/* Destructive controls — red ring (specificity beats the base group). */
button.warn:focus-visible,
.warn button:focus-visible,
.button-link.warn:focus-visible {
  outline-color: var(--focus-danger);
}

/* Ring is a keyboard affordance only — suppress the mouse/touch ring. */
button:focus:not(:focus-visible),
a:focus:not(:focus-visible),
summary:focus:not(:focus-visible),
[tabindex]:focus:not(:focus-visible) {
  outline: none;
}

/* ---------------------------------------------------------------------
   6 · SELECTION — primary green wash (tokens §2: --color-primary-wash is
   the documented selection wash). Text stays full-ink for AA.
   --------------------------------------------------------------------- */
::selection {
  background: var(--color-primary-wash);
  color: var(--color-text);
}
::-moz-selection {
  background: var(--color-primary-wash);
  color: var(--color-text);
}

/* ---------------------------------------------------------------------
   7 · SCROLLBARS — quiet, hairline-toned, pill thumb. Scoped to the
   document scroller and textareas so inner overflow regions keep their
   native overlay behavior (and the nav strips that set
   `::-webkit-scrollbar{display:none}` keep winning at their specificity).
   --------------------------------------------------------------------- */
html::-webkit-scrollbar,
body::-webkit-scrollbar,
textarea::-webkit-scrollbar {
  width: 10px;  /* no scrollbar-size token exists (noted) */
  height: 10px;
}
html::-webkit-scrollbar-track,
body::-webkit-scrollbar-track,
textarea::-webkit-scrollbar-track {
  background: transparent;
}
html::-webkit-scrollbar-thumb,
body::-webkit-scrollbar-thumb,
textarea::-webkit-scrollbar-thumb {
  background: var(--scale-ink-300);
  border-radius: var(--r-pill);
  border: 2px solid transparent;  /* inset the thumb via padding-box */
  background-clip: padding-box;
}
html::-webkit-scrollbar-thumb:hover,
body::-webkit-scrollbar-thumb:hover,
textarea::-webkit-scrollbar-thumb:hover {
  background: var(--scale-ink-400);
}

/* ---------------------------------------------------------------------
   8 · TABULAR NUMERALS — every time / hour / count cell aligns on the
   data figure set (tokens §4: font-variant-numeric: var(--fnum-data)).
   Applied via the app's own classes that hold numbers, plus numeric
   inputs. No money columns exist in this product (noted).
   --------------------------------------------------------------------- */
.chip-time,
.tmpl-chip-time-display,
.tmpl-chip-times,
.tmpl-cell-count,
.restaurant-hours-range,
.schedule-range-short,
.changes-count-badge,
.changes-count-warn,
.help-manual-section-count,
.help-manual-filter-count,
.manager-mobile-day-summary-counts,
.manager-mobile-day-counts,
input[type="time"],
input[type="date"],
input[type="number"] {
  font-variant-numeric: var(--fnum-data);
}

/* =====================================================================
   Service Bar re-skin · Category 02 — Buttons.
   ---------------------------------------------------------------------
   Appended AFTER styles.css; equal-specificity later rules win. Where an
   existing app rule is MORE specific, this file repeats the app's own
   selector (e.g. button:not(.employee-summary-toggle):...:active, or
   .top-nav button.nav-btn) to match/exceed it rather than reaching for
   !important. Every value consumes /styles/tokens.css (Service Bar).

   Scope: the app's REAL button system —
     • base <button> + button.primary  → primary green
     • button.secondary / .button-link.secondary / .nav-btn → secondary
     • button.warn / .warn button / .button-link.warn → destructive red
     • .button-link (link styled as a button)
     • .nav-btn (TOP nav button only; sidebar nav = category 11)
     • dense / row-action buttons: .schedule-row-actions > button,
       .schedule-delete-small, .sched-add-shift-btn, .chip-action-btn,
       .chip-remove-btn

   Recipe (components.html §01): flat surfaces (no skeuomorphic
   --button-surface-shadow gloss), hover = darken (no lift), press =
   translateY(1px) with NO filter/gloss, ONE disabled recipe (well fill /
   disabled ink / hairline / not-allowed), 8px radius (6px on dense
   controls), two type weights (600 on controls), 44px touch floor below
   900px, token-driven motion (reduced-motion safe via tokens.css).

   NOT owned here: the ONE focus-visible ring (2px solid, 2px offset,
   danger→red) is established app-wide in category 01 (01-base-type.css,
   which already covers button + button.warn). This file only ADDS the
   destructive-intent ring for .schedule-delete-small, which 01 cannot
   match (it is not .warn).

   Wiring: add `@import url("/styles/_parts/02-buttons.css?v=sb1");` to
   service-bar.css in category order (same staged pattern as the sibling
   parts, which are not yet imported either).
   ===================================================================== */

/* ---------------------------------------------------------------------
   1 · BASE — flat, dense, token typography. Replaces the resting gloss
   (styles.css:695/707/7157 --button-surface-shadow*) and the UA 760
   weight (styles.css:7156). inline-flex centres label + optional icon
   and is inline-level like the UA button, so document flow is unchanged.
   Card-shaped buttons (.dashboard-action-card, .manager-mobile-*-grid
   button) set their own display:grid at higher specificity and are
   unaffected. Padding is left to the app's existing model so tiny
   buttons (.chip-action-btn, .sched-add-shift-btn) keep their own size.
   --------------------------------------------------------------------- */
button,
.button-link,
.nav-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  border-radius: var(--r);
  font-family: inherit;
  font-size: var(--fs-data);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-data);
  letter-spacing: 0;
  white-space: nowrap;
  box-shadow: none;
  transition:
    background-color var(--dur-2) var(--ease-out),
    border-color var(--dur-2) var(--ease-out),
    color var(--dur-2) var(--ease-out),
    transform var(--dur-1) var(--ease-out);
}

.button-link {
  text-decoration: none;
}

/* ---------------------------------------------------------------------
   2 · PRIMARY — base button + explicit .primary + bare .button-link.
   Green is the next action; flat fill, white label. (Specialty buttons
   that opt out of a fill — .sched-add-shift-btn, .schedule-sort-button —
   keep their own transparent background at higher specificity.)
   --------------------------------------------------------------------- */
button,
button.primary,
.button-link {
  background: var(--color-primary);
  color: var(--color-on-primary);
  border: 1px solid transparent;
}

/* ---------------------------------------------------------------------
   3 · SECONDARY — quiet alternative on panel paper with a crisp control
   hairline (--line-strong, one step firmer than the bridge's --rs-line).
   .nav-btn (top nav) reads as a secondary control until it goes active.
   --------------------------------------------------------------------- */
button.secondary,
.button-link.secondary,
.nav-btn {
  background: var(--surface-panel);
  color: var(--color-text);
  border: 1px solid var(--line-strong);
}

/* ---------------------------------------------------------------------
   4 · DESTRUCTIVE — red, white label. Confirmed-destructive only.
   --------------------------------------------------------------------- */
button.warn,
.warn button,
.button-link.warn {
  background: var(--color-danger);
  color: var(--color-text-inverse);
  border: 1px solid transparent;
}

/* ---------------------------------------------------------------------
   5 · HOVER — darken in place, NO lift, NO gloss. The broad selector
   only NEUTRALISES the app's translateY(-1px) + soft-shadow hover
   (styles.css:7181/7182/7183/8796); it sets no background, so the dozens
   of classed specialty buttons (chips, sort, add-shift, tabs) keep their
   own hover skins. The green/grey/red fill change is then scoped to
   genuinely-primary buttons (classless or .primary) and the explicit
   variant classes — no bleed onto unrelated classed buttons.
   --------------------------------------------------------------------- */
button:hover:not(:disabled),
.button-link:hover,
.nav-btn:hover {
  transform: none;
  box-shadow: none;
}

/* primary = a classless <button> (the app's bare primary action) or an
   explicit .primary / bare .button-link */
button:not([class]):hover:not(:disabled),
button.primary:hover:not(:disabled),
.button-link:not(.secondary):not(.warn):hover {
  background: var(--color-primary-hover);
  color: var(--color-on-primary);
}

button.secondary:hover:not(:disabled),
.button-link.secondary:hover,
.nav-btn:hover {
  background: var(--surface-hover);
  border-color: var(--line-hover);
  color: var(--color-text);
}

button.warn:hover:not(:disabled),
.warn button:hover:not(:disabled),
.button-link.warn:hover {
  background: var(--color-danger-hover);
  color: var(--color-text-inverse);
}

/* ---------------------------------------------------------------------
   6 · ACTIVE / PRESS — single subtle 1px push, no saturate/brightness
   filter, no pressed gloss. Mirrors the app's compound active selector
   (styles.css:6397) and the link/nav active rules (6388/6390) to win.
   --------------------------------------------------------------------- */
button:not(.employee-summary-toggle):not(:disabled):active,
.button-link:active,
.nav-btn:active {
  transform: translateY(1px);
  box-shadow: none;
  filter: none;
}

button:not([class]):not(:disabled):active,
button.primary:not(:disabled):active,
.button-link:not(.secondary):not(.warn):active {
  background: var(--color-primary-active);
  color: var(--color-on-primary);
}

button.secondary:not(.employee-summary-toggle):not(:disabled):active,
.button-link.secondary:active,
.nav-btn:active {
  background: var(--surface-sunken);
  border-color: var(--line-hover);
  color: var(--color-text);
}

button.warn:not(.employee-summary-toggle):not(:disabled):active,
.button-link.warn:active {
  background: var(--color-danger-hover);
  color: var(--color-text-inverse);
}

/* ---------------------------------------------------------------------
   7 · DISABLED — the ONE global button recipe (audit #7). Identical
   across primary / secondary / destructive so "grayed out" means exactly
   one thing: well fill, disabled ink (contrast-exempt), hairline,
   not-allowed cursor, flat. Extends the app's reset (styles.css:6420)
   with the missing surface/ink/border; (0,2,1) clears the variant fills
   (button.secondary / button.warn at 0,1,1) without !important.
   --------------------------------------------------------------------- */
button:not(.employee-summary-toggle):disabled,
.button-link.is-disabled,
.button-link[aria-disabled="true"] {
  background: var(--surface-sunken);
  color: var(--color-text-disabled);
  border: 1px solid var(--line-mid);
  cursor: not-allowed;
  box-shadow: none;
  transform: none;
  filter: none;
}

/* ---------------------------------------------------------------------
   8 · TOP-NAV BUTTON — flatten the legacy gold "active" gloss
   (styles.css:645 inset gold ring, :647 gold ::after dot — amber-adjacent
   hues are reserved for warnings, never identity). Active = primary green
   fill; the green carries the state, so the decorative dot is retired.
   .top-nav button.nav-btn (0,1,2) is repeated to clear the legacy green
   pill fill (styles.css:658).
   --------------------------------------------------------------------- */
.top-nav button.nav-btn {
  background: var(--surface-panel);
  color: var(--color-text);
  border: 1px solid var(--line-strong);
}

.nav-btn.active,
.top-nav button.nav-btn.active {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--color-on-primary);
  box-shadow: none;
}

.nav-btn.active:hover,
.top-nav button.nav-btn.active:hover {
  background: var(--color-primary-hover);
  border-color: var(--color-primary-hover);
}

.nav-btn.active::after {
  display: none;
}

/* ---------------------------------------------------------------------
   9 · DENSE / ROW-ACTION BUTTONS — 6px radius on small controls
   (--r-s), --ctl-h-sm height. The destructive row action keeps the
   secondary skin (set in §3) but carries danger ink + a destructive
   focus ring (the one ring category 01 cannot match, since it is not
   .warn). Touch floor restored under 900px in §11.
   --------------------------------------------------------------------- */
.schedule-row-actions > button {
  min-height: var(--ctl-h-sm);
  border-radius: var(--r-s);
  font-size: var(--fs-data);
}

button.schedule-delete-small {
  color: var(--color-danger);
  border-radius: var(--r-s);
}

button.schedule-delete-small:hover:not(:disabled) {
  background: var(--color-danger-subtle);
  border-color: var(--color-danger);
  color: var(--color-danger-text);
}

button.schedule-delete-small:focus-visible {
  outline-color: var(--focus-danger);
}

/* Dashed "add shift" affordance — neutral ghost, never a status hue. */
.sched-add-shift-btn {
  background: transparent;
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-s);
  color: var(--color-text-secondary);
}

.sched-add-shift-btn:hover {
  background: var(--surface-hover);
  border-color: var(--line-hover);
  color: var(--color-text);
}

/* Tiny chip micro-buttons — flatten the soft gloss (styles.css:3044/3057),
   re-tint to Service Bar neutrals. Pill shape kept (these are chip-scale,
   not text buttons); category 05 owns the chips themselves. */
.chip-action-btn,
.chip-remove-btn {
  border: 1px solid var(--line-strong);
  background: var(--surface-panel);
  color: var(--color-text-secondary);
  box-shadow: none;
}

.chip-action-btn:hover,
.chip-remove-btn:hover {
  background: var(--surface-hover);
  border-color: var(--line-hover);
  color: var(--color-text);
}

/* ---------------------------------------------------------------------
   10 · LINK-STYLE BUTTON — header sort control reads as a green text
   link (links are never default blue, audit #6). The app already tints
   it green; reaffirm with tokens and drop any underline-on-rest.
   --------------------------------------------------------------------- */
.schedule-sort-button:hover,
.schedule-sort-button:focus-visible,
.schedule-sort-button.is-active {
  color: var(--color-link-hover);
}

/* ---------------------------------------------------------------------
   11 · TOUCH FLOOR — every text/row-action button rises to 44px below
   900px (audit #12). The app enforces this for full <button>s via its
   own ui-mobile rules; this covers the dense controls re-sized in §9.
   Chip micro-buttons are exempt (the app bumps them separately).
   --------------------------------------------------------------------- */
@media (max-width: 900px) {
  .schedule-row-actions > button,
  button.schedule-delete-small,
  .sched-add-shift-btn {
    min-height: var(--tap-min);
  }
}

/* =====================================================================
   Service Bar re-skin · Category 03 — Inputs, selects, form groups
   ---------------------------------------------------------------------
   Appended AFTER styles.css (loaded via /styles/service-bar.css), so
   equal-specificity rules here win the cascade. Targets the app's REAL
   selectors (generic input/select/textarea + the few wrappers that
   re-declare borders/backgrounds at higher specificity).

   Recipe: components.html §02 "Inputs & selects" + tokens.css §9.
     · --ctl-h 36px form height        · --line-strong control borders
     · --line-hover on hover           · ONE focus recipe (2px solid
       ring, 2px offset; danger swaps the hue)
     · --color-text-muted placeholders · custom chevron on selects
       (audit #1 — native chrome replaced)
     · ONE disabled recipe (well fill / disabled ink / hairline)
     · error state = --color-danger    · tabular-nums on number/date/time
   Every value is a token; the only literals are inside the chevron
   data-URI (stroke %235b6c64 == --scale-ink-600, can't be tokenised
   inside a url()) — noted in risks.
   ===================================================================== */

/* ---------------------------------------------------------------------
   1 · Base field skin — text-like inputs, textareas, selects.
   Input types are enumerated so file / color / checkbox / radio / range
   controls keep their own skins (they are out of this category).
   Typed selectors are (0,1,1); textarea/select are (0,0,1) but sit
   after styles.css's tag-level rules, so both win at the appended order.
   --------------------------------------------------------------------- */
input[type="text"],
input[type="email"],
input[type="password"],
input[type="tel"],
input[type="search"],
input[type="url"],
input[type="number"],
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"],
input[type="week"],
input:not([type]),
textarea,
select {
  background-color: var(--surface-panel);
  color: var(--color-text);
  font-family: inherit;
  font-size: var(--fs-data);            /* 13px — recipe's 13.5 has no token */
  font-weight: var(--fw-regular);       /* specific heavier rules still win */
  border: 1px solid var(--line-strong);
  border-radius: var(--r);              /* 8px form controls */
  box-shadow: none;                     /* kill the base inset highlight */
  transition: border-color var(--t-fast) var(--ease-out),
              box-shadow var(--t-fast) var(--ease-out);
}

/* horizontal rhythm; selects get extra room for the chevron below */
input[type="text"],
input[type="email"],
input[type="password"],
input[type="tel"],
input[type="search"],
input[type="url"],
input[type="number"],
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"],
input[type="week"],
input:not([type]),
textarea {
  padding: var(--space-2) var(--space-3);   /* 8px / 12px */
}

/* placeholders are hints only — muted ink, never the label (audit #6) */
input::placeholder,
textarea::placeholder {
  color: var(--color-text-muted);
  opacity: 1;                            /* Firefox dims placeholders */
}

/* tabular figures on every number / time / date field (hard rule) */
input[type="number"],
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"],
input[type="week"] {
  font-variant-numeric: var(--fnum-data);
}
/* native date/time picker glyph — quieted to match the muted chevron */
input[type="date"]::-webkit-calendar-picker-indicator,
input[type="time"]::-webkit-calendar-picker-indicator,
input[type="datetime-local"]::-webkit-calendar-picker-indicator {
  opacity: 0.55;
  cursor: pointer;
}

/* hover — control border lifts to --line-hover */
input[type="text"]:hover,
input[type="email"]:hover,
input[type="password"]:hover,
input[type="tel"]:hover,
input[type="search"]:hover,
input[type="url"]:hover,
input[type="number"]:hover,
input[type="date"]:hover,
input[type="time"]:hover,
input[type="datetime-local"]:hover,
input:not([type]):hover,
textarea:hover,
select:hover {
  border-color: var(--line-hover);
}

/* ---------------------------------------------------------------------
   2 · ONE focus recipe — replaces the app's two legacy treatments
   (the 0.14-alpha green glow at input:focus and the 3px 0.22-alpha
   outline at input:focus-visible). 2px solid green ring, 2px offset,
   border tints primary, glow removed. Both :focus and :focus-visible
   are restated so mouse and keyboard land on the same ring and the
   later source order beats the legacy rules at equal specificity.
   --------------------------------------------------------------------- */
input[type="text"]:focus,
input[type="email"]:focus,
input[type="password"]:focus,
input[type="tel"]:focus,
input[type="search"]:focus,
input[type="url"]:focus,
input[type="number"]:focus,
input[type="date"]:focus,
input[type="time"]:focus,
input[type="datetime-local"]:focus,
input[type="month"]:focus,
input[type="week"]:focus,
input:not([type]):focus,
textarea:focus,
select:focus,
input[type="text"]:focus-visible,
input[type="email"]:focus-visible,
input[type="password"]:focus-visible,
input[type="tel"]:focus-visible,
input[type="search"]:focus-visible,
input[type="url"]:focus-visible,
input[type="number"]:focus-visible,
input[type="date"]:focus-visible,
input[type="time"]:focus-visible,
input[type="datetime-local"]:focus-visible,
input:not([type]):focus-visible,
textarea:focus-visible,
select:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: var(--focus-ring-offset);
  border-color: var(--color-primary);
  box-shadow: none;
}

/* ---------------------------------------------------------------------
   3 · Custom select — native chrome replaced with a muted chevron
   (audit #1). appearance:none + background-image longhand so a more
   specific `background:` shorthand on a wrapper can't silently leave a
   select arrowless without us re-asserting the glyph (see §6).
   --------------------------------------------------------------------- */
select {
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  padding: var(--space-2) var(--space-6) var(--space-2) var(--space-3); /* 8 / 32 / 8 / 12 */
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='none' stroke='%235b6c64' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><path d='M4 6l4 4 4-4'/></svg>");
  background-repeat: no-repeat;
  background-position: right var(--space-2) center;
}
/* hide the IE/Edge legacy expand arrow so we don't show two */
select::-ms-expand { display: none; }

/* ---------------------------------------------------------------------
   4 · Form height — --ctl-h on the canonical form contexts. Applied to
   the app's field wrappers (not globally) so the dense in-grid template
   inputs keep their compact heights. min-height (not height) so wrappers
   that already ask for a taller touch target keep theirs.
   --------------------------------------------------------------------- */
.owner-settings-fields > label input:not([type="color"]),
.owner-settings-fields > label select,
.owner-entity-fields label input:not([type="color"]),
.owner-entity-fields label select,
.owner-setting-rule-input input,
.owner-role-department-field select,
.add-shift-form input,
.add-shift-form select,
.schedule-generate-field input,
.schedule-generate-field select,
.template-library-field input,
.template-library-field select,
.user-mgmt-cell input,
.user-mgmt-cell select,
.restaurant-hours-range input,
.manager-prompt-field input,
.onboarding-fields input,
.onboarding-fields select,
.role-preview-select {
  min-height: var(--ctl-h);
}

/* ---------------------------------------------------------------------
   5 · Labeled form groups — label above, help / error below.
   The app's help copy is `.hint` / `.hint-inline`; labels are the field
   wrappers' own <label> text. Re-point both to the type tokens.
   --------------------------------------------------------------------- */
.owner-settings-fields label,
.owner-entity-fields label,
.owner-setting-rule-input,
.add-shift-form label {
  color: var(--color-text-secondary);
}
.owner-settings-fields > label,
.add-shift-form label {
  font-weight: var(--fw-semibold);      /* persistent label, never a hint */
}
.hint,
.hint-inline {
  color: var(--color-text-muted);
}

/* ---------------------------------------------------------------------
   6 · Wrapper selects that re-declare `background:` shorthand — restate
   the chevron (and token border / fill) at matching specificity so they
   never render arrowless. Listed after the generic rule so the longhand
   background-image overrides the shorthand's implicit `none`.
   --------------------------------------------------------------------- */
.add-shift-form input,
.add-shift-form select {
  border: 1px solid var(--line-strong);
  border-radius: var(--r-s);            /* compact modal control — 6px */
  background-color: var(--surface-panel);
  color: var(--color-text);
}
.add-shift-form select {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='none' stroke='%235b6c64' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><path d='M4 6l4 4 4-4'/></svg>");
  background-repeat: no-repeat;
  background-position: right var(--space-2) center;
  padding-right: var(--space-6);
}
.test-mode-banner .role-preview-select {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='none' stroke='%235b6c64' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><path d='M4 6l4 4 4-4'/></svg>");
  background-repeat: no-repeat;
  background-position: right var(--space-2) center;
  padding-right: var(--space-6);
}
.owner-settings-fields input[type="color"],
.owner-entity-fields input[type="color"] {
  border: 1px solid var(--line-strong);
  border-radius: var(--r);
}

/* ---------------------------------------------------------------------
   7 · Error state — red border + red ring (audit #9: red spent only on
   meaning). Hooks for aria-invalid / .is-invalid; the app does not emit
   these today, so the rules are inert until error markup lands.
   --------------------------------------------------------------------- */
input[aria-invalid="true"],
select[aria-invalid="true"],
textarea[aria-invalid="true"],
.is-invalid > input,
.is-invalid > select,
.is-invalid > textarea,
.is-invalid input,
.is-invalid select {
  border-color: var(--color-danger);
}
input[aria-invalid="true"]:focus,
select[aria-invalid="true"]:focus,
textarea[aria-invalid="true"]:focus,
.is-invalid > input:focus,
.is-invalid > select:focus,
.is-invalid > textarea:focus,
.is-invalid input:focus,
.is-invalid select:focus {
  outline-color: var(--focus-danger);
  border-color: var(--color-danger);
}
.ferr,
.field-error,
.is-invalid .hint {
  color: var(--color-danger-text);
  font-weight: var(--fw-semibold);
}

/* ---------------------------------------------------------------------
   8 · ONE disabled recipe — well fill, disabled ink, hairline, no shadow,
   not-allowed cursor. Identical to the global recipe in the component
   sheet so "grayed out" reads as exactly one thing. !important is the
   documented last resort here: wrapper rules (e.g. .add-shift-form)
   re-declare border/background at higher specificity, and disabled must
   beat them all.
   --------------------------------------------------------------------- */
input:disabled,
select:disabled,
textarea:disabled {
  background-color: var(--surface-sunken) !important;
  color: var(--color-text-disabled) !important;
  border-color: var(--line-mid) !important;
  box-shadow: none !important;
  cursor: not-allowed !important;
}
input:disabled::placeholder,
textarea:disabled::placeholder {
  color: var(--color-text-disabled);
}

/* ---------------------------------------------------------------------
   9 · Touch floor — every text field / select rises to --tap-min below
   900px (audit #12). Mirrors the app's existing ui-mobile sizing; the
   two dense in-grid template inputs are restored just under so the
   manager matrix stays compact on tablets.
   --------------------------------------------------------------------- */
@media (max-width: 900px) {
  input[type="text"],
  input[type="email"],
  input[type="password"],
  input[type="tel"],
  input[type="search"],
  input[type="url"],
  input[type="number"],
  input[type="date"],
  input[type="time"],
  input[type="datetime-local"],
  input:not([type]),
  select {
    min-height: var(--tap-min);
  }
  .tmpl-skill-inline input[type="number"],
  .tmpl-chip-row input[type="time"] {
    min-height: 0;
  }
}

/* =====================================================================
   Service Bar re-skin · CATEGORY 04 — Checkboxes, radios & toggles
   ---------------------------------------------------------------------
   Loaded AFTER styles.css; equal-specificity rules here WIN the cascade.
   Consumes /styles/tokens.css for every color / space / radius / shadow /
   type / focus / motion value.

   What this category owns (app's REAL class names, grepped from
   public/app.js + styles.css — NOT the sheet's demo classes):
     · .state-checkbox + .state-checkbox__{input,button,indicator,state,
       text,title,desc} — the "[Label] On/Off" pill control emitted by
       stateCheckboxHtml(). Modifiers: --settings --chip --field --filter
       --feature, plus .configuration-feature-switch.
     · Configuration toggle ROWS: .owner-settings-fields > .state-checkbox
       --settings, .owner-setting-rule-card / .owner-setting-paired-card
       (the warm-paper setting cards that wrap toggles).
     · .configuration-limit-toggle — Warn/Block native-checkbox chips.
     · .restaurant-open-day-toggle / .restaurant-open-day-status —
       Open/Closed switch with a native checkbox under the hood.
     · Standalone native <input type=checkbox|radio> — green-when-on.

   Recipe applied (components.html §03 "Checkboxes & toggles"):
     green = on everywhere (--color-primary); flat hairline surfaces (no
     inset highlights / drop shadows); ONE focus recipe (2px solid ring,
     2px offset — replaces the banned ~invisible rgba(40,93,143,.22)
     rings); ONE disabled recipe; two type weights (400/600, killing the
     800s); 6px dense-control radius; 4px native boxes via accent-color;
     44px tap floor < 900px; token-driven motion (reduced-motion safe via
     the token kill-switch in tokens.css).
   ===================================================================== */

/* ---------------------------------------------------------------------
   1 · state-checkbox — the "[Label] On/Off" pill control
   The JS hides the native <input> and renders a styled pill button; we
   restyle the pill, never the structure.
   --------------------------------------------------------------------- */
.state-checkbox.state-checkbox {
  color: var(--color-text-secondary);
}

/* Off pill — recessed well, hairline border, muted ink (AA on sunken),
   flat (no inset highlight), Service Bar dense-control radius + type. */
.state-checkbox__button {
  border: 1px solid var(--line-strong);
  border-radius: var(--r-s);
  background: var(--surface-sunken);
  color: var(--color-text-muted);
  font-size: var(--fs-time);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-time);
  box-shadow: none;
  transition:
    background var(--dur-3) var(--ease-out),
    border-color var(--dur-2) var(--ease-out),
    color var(--dur-2) var(--ease-out);
}

.state-checkbox__indicator {
  border-radius: var(--r-pill);
}

/* On pill — solid primary green, white ink, flat. */
.state-checkbox__input:checked ~ .state-checkbox__button {
  border-color: var(--color-primary);
  background: var(--color-primary);
  color: var(--color-on-primary);
  box-shadow: none;
}

.state-checkbox__input:checked ~ .state-checkbox__button .state-checkbox__indicator {
  background: currentColor;
  opacity: 1;
}

/* THE one focus recipe — 2px solid ring, 2px offset, lands on the pill. */
.state-checkbox__input:focus-visible ~ .state-checkbox__button {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: var(--focus-ring-offset);
}

/* Hover — off lifts to white panel on a stronger hairline; on deepens. */
.state-checkbox:hover .state-checkbox__button {
  border-color: var(--line-hover);
  background: var(--surface-panel);
}

.state-checkbox:hover .state-checkbox__input:checked ~ .state-checkbox__button {
  border-color: var(--color-primary-hover);
  background: var(--color-primary-hover);
}

/* ONE disabled recipe — dim + not-allowed; meaning (green/neutral) is
   preserved under the dim so a locked "On" still reads On, and the row's
   explanatory copy stays legible. */
.state-checkbox:has(.state-checkbox__input:disabled) {
  cursor: not-allowed;
  opacity: 0.5;
}

/* Label / description typography — two weights only. */
.state-checkbox__title {
  font-weight: var(--fw-semibold);
  color: var(--color-text);
}

.state-checkbox__desc {
  color: var(--color-text-muted);
}

/* Configuration feature switch keeps its existing sizing; inherits the
   pill skin above. */
.configuration-feature-switch .state-checkbox__button {
  min-height: 30px;
}

/* ---------------------------------------------------------------------
   2 · Configuration toggle ROWS — kill the warm-paper gradient cards;
   Service Bar uses three flat surface levels (panel + hairline).
   --------------------------------------------------------------------- */
.owner-settings-fields > .state-checkbox--settings {
  border: 1px solid var(--line-mid);
  border-radius: var(--r);
  background: var(--surface-panel);
  box-shadow: none;
}

.owner-setting-rule-card,
.owner-setting-paired-card {
  border: 1px solid var(--line-mid);
  border-radius: var(--r);
  background: var(--surface-panel);
  box-shadow: none;
}

/* ---------------------------------------------------------------------
   3 · Warn / Block limit toggles — native checkbox + label chip.
   --------------------------------------------------------------------- */
.configuration-limit-toggle {
  border: 1px solid var(--line-strong);
  border-radius: var(--r-s);
  background: var(--surface-panel);
  color: var(--color-text-secondary);
  font-size: var(--fs-time);
  font-weight: var(--fw-semibold);
  transition:
    background var(--dur-2) var(--ease-out),
    border-color var(--dur-2) var(--ease-out),
    color var(--dur-2) var(--ease-out);
}

.configuration-limit-toggle:hover {
  border-color: var(--line-hover);
  background: var(--surface-hover);
}

/* Green when on. */
.configuration-limit-toggle:has(input:checked) {
  border-color: var(--color-primary);
  background: var(--color-primary-subtle);
  color: var(--color-primary-text);
}

.configuration-limit-toggle input {
  accent-color: var(--color-primary);
}

.configuration-limit-toggle input:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: var(--focus-ring-offset);
}

/* ---------------------------------------------------------------------
   4 · Open / Closed day switch — native checkbox under a status pill.
   Open = healthy green, Closed = neutral well. Status hue spent only on
   meaning (on/off), never as a warning.
   --------------------------------------------------------------------- */
.restaurant-open-day-toggle {
  border: 1px solid var(--line-strong);
  border-radius: var(--r);
  background: var(--surface-panel);
  color: var(--color-text-secondary);
}

.restaurant-open-day-toggle:hover,
.restaurant-open-day-toggle:focus-within {
  border-color: var(--line-hover);
  background: var(--surface-hover);
}

.restaurant-open-day-toggle:has(input[type="checkbox"]:checked) {
  border-color: var(--color-primary);
  background: var(--color-primary-wash);
}

.restaurant-open-day-toggle:has(input[type="checkbox"]:not(:checked)) {
  border-color: var(--line-mid);
  background: var(--surface-band);
}

.restaurant-open-day-name {
  font-weight: var(--fw-semibold);
}

/* Open pill (checked). */
.restaurant-open-day-status {
  border: 1px solid var(--color-primary);
  border-radius: var(--r-pill);
  background: var(--color-primary-subtle);
  color: var(--color-primary-text);
  font-size: var(--fs-time);
  font-weight: var(--fw-semibold);
}

/* Closed pill (unchecked) — neutral well. */
.restaurant-open-day-toggle input[type="checkbox"]:not(:checked) + .restaurant-open-day-status {
  border-color: var(--line-strong);
  background: var(--surface-sunken);
  color: var(--color-text-muted);
}

/* THE one focus recipe (replaces the banned rgba(40,93,143,.22) ring). */
.restaurant-open-day-toggle input[type="checkbox"]:focus-visible + .restaurant-open-day-status {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: var(--focus-ring-offset);
}

/* ---------------------------------------------------------------------
   5 · Standalone native checkbox / radio — green when on, everywhere.
   Native boxes don't honor a custom 4px radius cross-browser; accent-color
   is the modern, AA-safe way to deliver "green = on" without a full custom
   control. The visually-hidden inputs behind custom toggles are excluded
   from the focus ring (their styled siblings already carry it).
   --------------------------------------------------------------------- */
input[type="checkbox"],
input[type="radio"] {
  accent-color: var(--color-primary);
}

input[type="checkbox"]:not(.state-checkbox__input):focus-visible,
input[type="radio"]:not(.state-checkbox__input):focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: var(--focus-ring-offset);
}

/* ---------------------------------------------------------------------
   6 · Touch floor — every toggle control rises to 44px below 900px
   (audit #12). Reduced motion is handled by the token kill-switch.
   --------------------------------------------------------------------- */
@media (max-width: 900px) {
  .state-checkbox__button,
  .configuration-feature-switch .state-checkbox__button,
  .configuration-limit-toggle,
  .restaurant-open-day-status {
    min-height: var(--tap-min);
  }
}

/* =====================================================================
   Service Bar re-skin — CATEGORY 05
   Cards, surfaces, dense rows & tables
   ---------------------------------------------------------------------
   Loaded AFTER styles.css (equal-specificity later rules WIN). Every
   value is a /styles/tokens.css var(--…). Recipe source of truth:
   03-system/components.html §04 "Cards, rows & tables" (.card / .lrow /
   .lcols / table.dt) + tokens.css §1–§9.

   Re-skin targets (app's REAL selectors):
     surfaces  .card .item .employee-card .owner-settings-panel
               .modal-card .empty-state-body + nested entity cards
     wells     .owner-settings-fields>label .platform-checkbox
               .schedule-send-scope  → --surface-sunken
     headers   .card-eyebrow (overline) + section h2/h1 display step
     dense row .schedule-table-body-row (list density)
     tables    .schedule-table(-head) · .user-mgmt-table(-head/-row) ·
               real .table  (sticky head, tabular-nums, hover, selected)

   Structure = ONE hairline + whitespace. sh-1 rests, sh-2 floats.
   ===================================================================== */

/* ---------------------------------------------------------------------
   1 · SURFACE LEVELS — panel = white card, hairline + sh-1, radius 8.
   Re-affirmed with direct Service Bar tokens so shape/hairline/elevation
   land exactly (the rs-* bridge already shifts the palette).
   --------------------------------------------------------------------- */
.card,
.item,
.employee-card,
.owner-settings-panel,
.empty-state-body,
.modal-card {
  background: var(--surface-panel);
  border: var(--hairline);              /* 1px solid --line-mid */
  border-radius: var(--r);              /* 8px */
  box-shadow: var(--sh-1);
}

/* nested entity / config cards = same resting panel */
.platform-tenant-card,
.developer-company-card,
.platform-domain-card,
.owner-entity-card,
.owner-setting-rule-card,
.owner-setting-paired-card,
.schedule-generate-config,
.schedule-generate-actions,
.employee-inline-panel,
.message-history-entry,
.role-skill-item,
.availability-painter,
.employee-self-serve-grid,
.timeoff-calendar-block,
.timeoff-calendar-sidecar,
.owner-summary-card {
  background: var(--surface-panel);
  border: var(--hairline);
  border-radius: var(--r);
  box-shadow: var(--sh-1);
}

/* density: the 4/8 system, not the old 12/16 ad-hoc padding */
.card        { padding: var(--space-4); margin-bottom: var(--space-4); }  /* 16 */
.item,
.employee-card { padding: var(--space-3); }                               /* 12 */

/* RAISED overlays float on sh-2, never a border (recipe: card-raised) */
.modal-card {
  border: var(--hairline);
  box-shadow: var(--sh-2);
}

/* SUNKEN wells — recessed trays behind fields / off-states (--surface-sunken) */
.owner-settings-fields > label,
.owner-settings-fields > .state-checkbox--settings,
.platform-checkbox,
.schedule-send-scope {
  background: var(--surface-sunken);
  border: var(--hairline-faint);
  border-radius: var(--r-s);
}

/* ---------------------------------------------------------------------
   2 · PANEL HEADERS — overline caption + display/heading type step.
   Caption is the uppercase 600 / .06em overline (recipe .spec-t/.lcols).
   --------------------------------------------------------------------- */
.card-eyebrow,
.manager-sidebar-group-title,
.dashboard-action-kicker {
  font-size: var(--fs-caption);          /* 11 */
  font-weight: var(--fw-semibold);       /* 600, not weight-sprawl 850 */
  letter-spacing: var(--ls-caption);     /* .06em */
  text-transform: uppercase;
  color: var(--color-primary);
}

/* the display step — set with intent, tabular numerals, tight tracking */
.schedule-page-head h1 {
  font-weight: var(--fw-display);        /* 600 */
  letter-spacing: var(--ls-display);     /* -.015em */
  font-variant-numeric: var(--fnum-data);
}

.schedule-list-head h2 {
  font-size: var(--fs-h1);
  font-weight: var(--fw-h1);
  letter-spacing: var(--ls-h1);
  font-variant-numeric: var(--fnum-data);
}

/* ---------------------------------------------------------------------
   3 · DENSE LIST ROWS — the schedule list reads like recipe .lrow:
   hairline separator, tight padding, hover lift tint, selected = wash +
   2px inset green edge, focus ring sits INSIDE the row.
   --------------------------------------------------------------------- */
.schedule-table {
  border: var(--hairline);
  border-radius: var(--r);
  background: var(--surface-panel);
}

.schedule-table-body-row {
  padding: var(--space-2) var(--space-4);          /* 8 / 16 — denser */
  border-bottom: var(--hairline-faint);            /* row separator */
  font-size: var(--fs-data);
  transition: background-color var(--dur-2) var(--ease-out),
              box-shadow var(--dur-2) var(--ease-out);
}

/* numeric cells (date range, counts, dates) rail on tabular figures */
.schedule-table-body-row [role="cell"],
.schedule-range-short {
  font-variant-numeric: var(--fnum-data);
}

.schedule-table-body-row:hover {
  background: var(--surface-hover);                /* faint lift tint */
}

.schedule-table-body-row:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: calc(-1 * var(--focus-ring-offset));   /* inset, no clip */
}

/* current-week + selected left edge → 2px green identity edge */
.schedule-table-body-row.is-current::before,
.schedule-table-body-row.schedule-card-selected::before {
  width: var(--edge-status);                       /* 2px */
  background: var(--color-primary);
}

/* selected = wash + the inset edge; drop the old gradient + ring */
.schedule-table-body-row.schedule-card-selected {
  border-color: transparent;
  background: var(--wash);
  box-shadow: none;
}

/* ---------------------------------------------------------------------
   4 · USER-MGMT TABLE — grid "table": white sticky head + inset hairline
   caption, hairline rows, table-row hover (faint), self-row = wash + edge.
   --------------------------------------------------------------------- */
.user-mgmt-table {
  border: var(--hairline);
  border-radius: var(--r);
  box-shadow: var(--sh-1);
}

.user-mgmt-table-head {
  position: sticky;                                /* clipped by table's
                                                      overflow:hidden — stays
                                                      put, never floats off */
  top: 0;
  z-index: var(--z-sticky);
  padding: var(--space-2) var(--space-4);
  background: var(--surface-panel);                /* recipe th = white */
  border-bottom: none;
  box-shadow: inset 0 -1px 0 var(--line-2);        /* inset bottom hairline */
  color: var(--color-text-muted);
  font-size: var(--fs-caption);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-caption);
  text-transform: uppercase;
}

.user-mgmt-row {
  padding: var(--space-2) var(--space-4);
  border-bottom: var(--hairline-faint);
  font-size: var(--fs-data);
  transition: background-color var(--dur-2) var(--ease-out);
}

.user-mgmt-cell {
  font-variant-numeric: var(--fnum-data);          /* phone digits rail */
}

.user-mgmt-row:hover {
  background: var(--surface-hover-faint);          /* table-row hover */
}

.user-mgmt-row:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: calc(-1 * var(--focus-ring-offset));
}

/* "you" row — identity wash + inset green edge (meaningful, not status) */
.user-mgmt-row.user-mgmt-row-self {
  background: var(--wash);
  box-shadow: inset var(--edge-status) 0 0 var(--color-primary);
}
.user-mgmt-row.user-mgmt-row-self:hover {
  background: var(--wash);
}

/* ---------------------------------------------------------------------
   5 · SCHEDULE TABLE HEAD (grid) — match the recipe head treatment.
   NOTE: .schedule-table is overflow:visible (its row menus must escape),
   so a sticky head resolves against the page scroller. Opaque panel bg
   keeps rows from bleeding through; see risks.
   --------------------------------------------------------------------- */
.schedule-table-head {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  border-bottom: none;
  background: var(--surface-panel);
  box-shadow: inset 0 -1px 0 var(--line-2);
  color: var(--color-text-muted);
  font-size: var(--fs-caption);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-caption);
}
.schedule-table-head [role="columnheader"] {
  font-variant-numeric: var(--fnum-data);
}

/* ---------------------------------------------------------------------
   6 · REAL <table> .table — sticky caption head + tabular-nums.
   Kept on border-collapse:collapse so calendar/grid cell rules stay
   crisp; only the header is re-skinned to the data-table recipe.
   --------------------------------------------------------------------- */
.table {
  font-size: var(--fs-data);
  font-variant-numeric: var(--fnum-data);
}

.table th {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  padding: var(--space-2) var(--space-3);
  background: var(--surface-panel);
  /* collapse-table borders can drop on sticky scroll — pin a line via shadow */
  box-shadow: inset 0 -1px 0 var(--line-2);
  color: var(--color-text-muted);
  font-size: var(--fs-caption);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-caption);
  text-transform: uppercase;
}

.table td {
  padding: 7px var(--space-3);
  font-variant-numeric: var(--fnum-data);
}

.table tbody tr {
  transition: background-color var(--dur-2) var(--ease-out);
}
.table tbody tr:hover {
  background: var(--surface-hover-faint);          /* table-row hover */
}

/* ---------------------------------------------------------------------
   7 · FOCUSABLE SURFACES — ONE focus recipe (2px solid ring, 2px offset)
   for clickable cards in this category, replacing the near-invisible
   alpha ring on these specific surfaces.
   --------------------------------------------------------------------- */
.employee-card.employee-card-collapsible:focus-visible,
.platform-tenant-card:focus-visible,
.developer-company-card:focus-visible,
.owner-entity-card:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: var(--focus-ring-offset);
}

/* ---------------------------------------------------------------------
   8 · TOUCH FLOOR (<900px) — dense rows breathe to a comfortable tap
   target (recipe media block: .lrow → 13px vertical).
   --------------------------------------------------------------------- */
@media (max-width: 900px) {
  .schedule-table-body-row {
    padding-top: var(--space-3);                   /* 12 */
    padding-bottom: var(--space-3);
  }
  .user-mgmt-row {
    padding-top: var(--space-3);
    padding-bottom: var(--space-3);
  }
}

/* Motion: all transitions above consume --dur-*, which the tokens.css
   reduced-motion kill switch collapses to 0.01ms — no extra guard needed.
   No transform-on-hover is introduced here, so nothing animates on the
   row except the token-governed background. */

/* =====================================================================
   06 · Status pills, role-accent shift chips & shift chips
   ---------------------------------------------------------------------
   Service Bar re-skin part. Appended AFTER styles.css, so equal-
   specificity rules here WIN by source order. Every value consumes a
   tokens.css custom property (loaded app-wide as /styles/tokens.css).

   Recipe source: components.html §05 "Status & shift chips" + tokens.css
   §2 (status language), §9 (focus/touch), §10 (role accents).

   Closed status vocabulary, decodable by meaning (audit #9):
     Draft   = dashed NEUTRAL (never amber)   Final = info blue
     Sent    = healthy green ("published")     Pending = amber (waiting)
     Approved= green   Denied/Conflict = red   Warning/Review = amber
     Off/Open/Canceled = neutral well          Info/Extra = blue

   App reality this part re-skins (its OWN class names, not the sheet's
   .pill/.badge): .status-pill[.status-*|.warn|.neutral],
   .manager-status-pill, .autosave-status-pill, .shift-chip family,
   .tmpl-shift-chip, .chip-role/.chip-time, .chip-extra-badge,
   .chip-lock-badge, .chip-status-row.

   SCOPE LIMIT (documented, see risks): filled grid/template chips carry
   a JS-injected inline `background:linear-gradient(... role hue ...)`
   from scheduleChipInlineStyle(). The role hue lives only in that inline
   style, so the §10 "wash fill + 3px role edge" identity cannot be
   rebuilt in CSS without an app.js change — overriding the background
   would DESTROY role identity (every chip flat-neutral). We therefore
   keep the inline role fill and bring the Service Bar SHAPE, density,
   hairlines, hover/focus, status edges, typography and motion to the
   chip; role identity continues to ride the inline fill + the role-name
   text the chip always carries.
   ===================================================================== */

/* =====================================================================
   STATUS PILLS — .status-pill (+ .status-* / .warn / .neutral)
   Closed vocabulary, one hue per meaning. Overrides the legacy bucket
   at styles.css:7225-7249 (which mis-bucketed pending-manager→green and
   warning/canceled→red). Equal specificity, appended later → wins.
   ===================================================================== */
.status-pill {
  gap: var(--space-1);
  padding: 2px 8px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-pill);
  background: var(--surface-panel);
  color: var(--color-text-secondary);
  font-size: 11px;
  line-height: 1.25;
  font-weight: var(--fw-semibold);
  letter-spacing: 0.01em;
  font-variant-numeric: var(--fnum-data); /* counts/enums rail (audit) */
}

/* green — Approved / Sent / On / Ready / healthy ("published") */
.status-pill.status-approved {
  background: var(--status-published-bg);
  color: var(--status-published-fg);
  border-color: transparent;
}
/* red — Denied / Conflict / High-risk / urgent-destructive */
.status-pill.status-denied {
  background: var(--status-conflict-bg);
  color: var(--status-conflict-fg);
  border-color: transparent;
}
/* amber — Pending (waiting on you) / Review / Warning / Tight / Medium */
.status-pill.status-pending-employee,
.status-pill.status-pending-manager,
.status-pill.status-review,
.status-pill.warn {
  background: var(--status-warning-bg);
  color: var(--status-warning-fg);
  border-color: transparent;
}
/* neutral well — Open / Assigned (no warning hue spent) */
.status-pill.status-open {
  background: var(--surface-sunken);
  color: var(--color-text-secondary);
  border-color: var(--line-2);
}
/* neutral well, muted — Canceled / Scheduled-out (off is a choice) */
.status-pill.status-canceled,
.status-pill.neutral {
  background: var(--surface-sunken);
  color: var(--color-text-muted);
  border-color: var(--line-2);
}

/* =====================================================================
   MANAGER TOP-BAR PILLS — .manager-status-pill (.ok/.warn/.neutral)
   ===================================================================== */
.manager-status-pill {
  border-radius: var(--r-pill);
  border: 1px solid transparent;
  font-weight: var(--fw-semibold);
  font-variant-numeric: var(--fnum-data);
}
.manager-status-pill.ok {
  background: var(--status-published-bg);
  color: var(--status-published-fg);
  border-color: transparent;
}
.manager-status-pill.warn {
  background: var(--status-warning-bg);
  color: var(--status-warning-fg);
  border-color: transparent;
}
.manager-status-pill.neutral {
  background: var(--surface-sunken);
  color: var(--color-text-secondary);
  border-color: var(--line-2);
}

/* =====================================================================
   AUTOSAVE PILL — .autosave-status-pill[data-state]
   Lives on the white save-bar, so it keeps a colored 1px border to
   carry state at distance. saving=amber · saved=green · error=red.
   ===================================================================== */
.autosave-status-pill {
  border: 1px solid var(--line-2);
  border-radius: var(--r-pill);
  background: var(--surface-panel);
  color: var(--color-text-secondary);
  font-weight: var(--fw-semibold);
  font-variant-numeric: var(--fnum-data);
  transition:
    background var(--dur-3) var(--ease-out),
    border-color var(--dur-3) var(--ease-out),
    color var(--dur-3) var(--ease-out),
    opacity var(--dur-4) var(--ease-out),
    transform var(--dur-4) var(--ease-out);
}
.autosave-status-pill[data-state="saving"] {
  border-color: var(--color-warning);
  background: var(--status-warning-bg);
  color: var(--status-warning-fg);
}
.autosave-status-pill[data-state="saved"] {
  border-color: var(--color-primary);
  background: var(--status-published-bg);
  color: var(--status-published-fg);
}
.autosave-status-pill[data-state="error"] {
  border-color: var(--color-danger);
  background: var(--status-conflict-bg);
  color: var(--status-conflict-fg);
}

/* =====================================================================
   SHIFT CHIPS — .shift-chip (live grid) + role accent recipe
   Shape/density/hairlines/states only; inline role fill is preserved.
   ===================================================================== */
.shift-chip {
  border-radius: var(--r-s);              /* dense control: 6px */
  border: 1px solid var(--line);          /* hairline frame */
  box-shadow: none;                       /* override the heavy 0 4px 12px at :8144 */
  transition:
    box-shadow var(--dur-2) var(--ease-out),
    border-color var(--dur-2) var(--ease-out),
    transform var(--dur-2) var(--ease-out);
}
/* hover lift — sh-1 is the resting/hovered-chip elevation in the recipe */
.shift-chip.shift-chip-interactive:hover {
  border-color: var(--line-2);
  box-shadow: var(--sh-1);
  transform: translateY(-1px);
}
/* one focus recipe app-wide: 2px solid ring, 2px offset (audit #12) */
.shift-chip:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: var(--focus-ring-offset);
}
/* picked-up chip — between resting and overlay elevation */
.shift-chip.dragging {
  box-shadow: var(--sh-drag);
}

/* chip typography — role name stays the labeled identity; time tabular */
.shift-chip .chip-role {
  font-weight: var(--fw-semibold);        /* two-weight system: 600 not 700 */
}
.shift-chip .chip-time {
  font-variant-numeric: var(--fnum-data); /* times rail — tabular (audit) */
}
.chip-status-row {
  gap: var(--space-1);
}

/* per-status redundancy edge on FILLED chips (color + the badge word).
   Role hues never wear these — amber/green/red are status only (§10). */
.shift-chip.status-pending-employee,
.shift-chip.status-pending-manager {
  border-color: var(--dot-warning);
}
.shift-chip.status-approved {
  border-color: var(--color-primary);
}
.shift-chip.status-denied {
  border-color: var(--color-danger);
}
.shift-chip.status-review {
  border-color: var(--dot-warning);
}
.shift-chip.status-canceled {
  border-color: var(--line-2);
}
/* training = structural variant, neutral dashed (never a status hue) */
.shift-chip.training {
  border-color: var(--line-2);
}

/* UNFILLED — dashed red "nobody yet" (decode rule: dashed red = unfilled).
   Placed after the status-edge block so it wins over its status-denied
   badge class. No inline fill on unfilled chips, so CSS owns the look. */
.shift-chip.unfilled {
  background: var(--surface-panel);
  border: 1px dashed var(--color-danger);
  box-shadow: none;
  color: var(--color-danger-text);
}
.shift-chip.unfilled .chip-role {
  color: var(--color-danger);
}
.shift-chip.unfilled .chip-time {
  color: var(--color-danger-text);
}
.shift-chip.unfilled.shift-chip-interactive:hover {
  background: var(--status-conflict-bg);
  border-color: var(--color-danger);
  box-shadow: var(--sh-1);
}

/* ABOVE-TEMPLATE REVIEW — amber warning (needs your decision).
   After the status block so it wins over its status-review badge class. */
.shift-chip.review-shift {
  background: var(--status-warning-bg);
  border: 1px solid var(--scale-amber-500);
  box-shadow: none;
  color: var(--status-warning-fg);
}
.shift-chip.review-shift .chip-role {
  color: var(--status-warning-fg);
}
.shift-chip.review-shift .chip-time {
  color: var(--color-warning-text);
}

/* =====================================================================
   CHIP META BADGES
   ===================================================================== */
/* "Extra" / "Linked N" — neutral FACT, info blue (was amber #c07030,
   which impersonated a warning — §10 ban). Amber stays reserved. */
.chip-extra-badge {
  background: var(--status-info-bg);
  color: var(--status-info-fg);
  border-radius: var(--r-xs);             /* 4px tag */
  letter-spacing: var(--ls-caption);
  font-weight: var(--fw-semibold);
  font-variant-numeric: var(--fnum-data);
}
/* lock recurrence count — neutral (was gold; recurrence isn't a warning) */
.chip-lock-badge {
  border-color: var(--line-2);
  background: var(--surface-panel);
  color: var(--color-text-secondary);
  font-weight: var(--fw-semibold);
  font-variant-numeric: var(--fnum-data);
}

/* =====================================================================
   TEMPLATE-BUILDER CHIPS — .tmpl-shift-chip (also inline role fill)
   ===================================================================== */
.tmpl-shift-chip {
  border-radius: var(--r-s);              /* override :8175 rs-radius (8px) */
  border-color: var(--line-2);            /* hairline (was #d8d2c5) */
  transition:
    box-shadow var(--dur-2) var(--ease-out),
    border-color var(--dur-2) var(--ease-out);
}
.tmpl-shift-chip:hover {
  border-color: var(--line-hover);
  box-shadow: var(--sh-1);
}
/* selected ≠ focused: selection = 2px inset green edge (recipe);
   focus = the one outline ring. Two signals never look alike. */
.tmpl-shift-chip:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: var(--focus-ring-offset);
}
.tmpl-shift-chip.is-selected {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--color-primary);
}
/* inline time-edit affordance — tabular + the one focus ring */
.tmpl-chip-time-display {
  font-variant-numeric: var(--fnum-data);
}
.tmpl-chip-time-display:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: var(--focus-ring-offset);
  border-color: transparent;
}

/* =====================================================================
   TOUCH FLOOR — every interactive chip rises to 44px below 900px
   (audit #12). status pills are non-interactive spans → exempt.
   ===================================================================== */
@media (max-width: 900px) {
  .shift-chip.shift-chip-interactive,
  .tmpl-shift-chip {
    min-height: var(--tap-min);
  }
}

/* =====================================================================
   REDUCED MOTION — freeze the one-shot "settle" dim so state is never
   conveyed by motion alone; the saved pill/bar stays fully legible.
   (--dur-* tokens already collapse to ~0; these keyframes are hardcoded.)
   ===================================================================== */
@media (prefers-reduced-motion: reduce) {
  .autosave-status-pill[data-state="saved"],
  .template-savebar[data-state="saved"],
  .autosave-session-savebar[data-state="saved"] {
    animation: none;
  }
  .shift-chip,
  .shift-chip.shift-chip-interactive:hover {
    transform: none;
  }
}

/* =====================================================================
   Service Bar re-skin · CATEGORY 07 — Tabs, dropdown menus, filter
   popover, pagination.
   ---------------------------------------------------------------------
   Loaded AFTER styles.css (equal-specificity later rules win). Every
   value reads /styles/tokens.css. The app owns these class names; we
   restyle in place — no markup, layout-flow or behavior changes.

   Recipe source: components.html §06 "Tabs, menus & paging" (the
   underline tab, the filter popover, the quiet pager).

   Decode rules honored here:
     · active tab  = ink text + GREEN underline (green reserved for the
       chosen view; never a fill the way a primary button is).
     · popovers/menus = panel surface + --line-2 hairline + --sh-2,
       on the --z-dropdown layer; they appear instant and fade per §8.
     · ONE focus recipe (2px solid --focus; 2px offset, inset -2px where
       a ring would clip inside a tab strip or a tight menu).
     · ONE disabled recipe (well fill / --ink-dis / no shadow|lift).
     · counts are tabular-nums; 44px touch floor below 900px.

   NOTE on PAGINATION: the live app ships no paginated list — there is
   no .pager / .pbtn / page-number markup anywhere in app.js, employee.js
   or the HTML shells (verified). So there is nothing to re-skin and we
   deliberately add NO speculative .pager selectors (the brief says use
   the app's real classes, not invented ones). If a pager is added later
   it should follow §06: 32px quiet wells, --r-s, green reserved for
   actions, current page = --well + --line-2, disabled = the one recipe.
   ===================================================================== */

/* ---------------------------------------------------------------------
   Shared overlay entrance — overlays appear effectively instant (§8:
   in ≈ 0ms) with a hair of fade so a popping menu doesn't feel like a
   layout jump. Reduced-motion zeroes --dur-1 at the token level; the
   guard below removes the animation outright as a belt-and-braces.
   --------------------------------------------------------------------- */
@keyframes sbOverlayIn {
  from { opacity: 0; transform: translateY(-2px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* =====================================================================
   1 · UNDERLINE TABS — in-page view switcher (.settings-tab-bar /
   .settings-tab-btn). The category's hero: ink text + green underline.
   Mobile (body.ui-mobile / .has-manager-mobile-tab-bar) keeps its own
   higher-specificity grid layout untouched; this block governs desktop.
   ===================================================================== */
.settings-tab-bar {
  gap: var(--space-0);
  /* 1px hairline bar; the active button's 2px underline overlaps it via
     margin-bottom:-1px below so the green sits flush on the rule. */
  border-bottom: 1px solid var(--line);
  margin-bottom: var(--space-4);
}

.settings-tab-btn {
  padding: var(--space-2) var(--space-4);
  min-height: var(--ctl-h);
  color: var(--color-text-muted);
  font-size: var(--fs-data);
  font-weight: var(--fw-semibold);
  letter-spacing: 0;
  background: transparent;
  border: 0;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  border-radius: var(--r-s) var(--r-s) 0 0;
  transition: color var(--t-fast) var(--ease-out),
              background var(--t-fast) var(--ease-out),
              border-color var(--t-fast) var(--ease-out);
}

/* hover = ink + quiet well; no lift (overrides the global button
   translateY at styles.css:8796 — match its specificity, land later) */
.settings-tab-btn:hover:not(.active) {
  color: var(--ink);
  background: var(--well);
  transform: none;
}

/* active = ink text + the green underline; deliberately NO fill */
.settings-tab-btn.active {
  color: var(--ink);
  background: transparent;
  border-bottom-color: var(--green);
}

/* the ONE focus recipe — inset so the ring rides inside the tab strip
   rather than clipping on the bar's overflow (tokens §9). Overrides the
   dim 0.22-alpha ring at styles.css:8803. */
.settings-tab-btn:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: -2px;
}

/* =====================================================================
   2 · SEGMENTED TABS — mobile candidate filter strip
   (.manager-mobile-candidate-tabs, role="tablist"). Resting = panel
   chip; chosen = solid green pill with white label. Counts tabular.
   Mirror the app's body.ui-mobile specificity so these land.
   ===================================================================== */
body.ui-mobile .manager-mobile-candidate-tabs {
  gap: var(--space-1);
}
body.ui-mobile .manager-mobile-candidate-tabs button {
  min-height: var(--tap-min);
  border: 1px solid var(--line);
  border-radius: var(--r-s);
  background: var(--surface);
  color: var(--ink);
  transition: background var(--t-fast) var(--ease-out),
              border-color var(--t-fast) var(--ease-out),
              color var(--t-fast) var(--ease-out);
}
body.ui-mobile .manager-mobile-candidate-tabs button:hover {
  background: var(--well);
  transform: none;
}
body.ui-mobile .manager-mobile-candidate-tabs button.active {
  background: var(--green);
  border-color: var(--green);
  color: var(--color-on-primary);
}
body.ui-mobile .manager-mobile-candidate-tabs button:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: var(--focus-ring-offset);
}
body.ui-mobile .manager-mobile-candidate-tabs span {
  font-size: var(--fs-caption);
  font-weight: var(--fw-semibold);
  letter-spacing: 0;
  text-transform: none;
}
body.ui-mobile .manager-mobile-candidate-tabs strong {
  font-size: var(--fs-data);
  font-weight: var(--fw-semibold);
  font-variant-numeric: var(--fnum-data);
}

/* =====================================================================
   3 · FILTER POPOVER — trigger button + panel (schedule + template
   views share .schedule-filter-* ; template adds .template-advanced-
   filters which inherits the same classes).
   ===================================================================== */
.schedule-filter-toolbar {
  gap: var(--space-2);
}

/* active filter = green tint chip on the trigger (green is allowed here:
   it marks an active narrowing the user turned on, not a status hue) */
.schedule-filter-trigger.is-active {
  border-color: var(--green);
  color: var(--green-ink);
  background: var(--green-tint);
}
.schedule-filter-trigger:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: var(--focus-ring-offset);
}

/* the popover itself — panel surface, --line-2 hairline, --r, --sh-2,
   on the dropdown z-layer; fades in per §8 */
.schedule-filter-panel {
  z-index: var(--z-dropdown);
  top: calc(100% + var(--space-1));
  border: 1px solid var(--line-2);
  border-radius: var(--r);
  background: var(--surface);
  box-shadow: var(--sh-2);
  padding: var(--space-3);
  animation: sbOverlayIn var(--dur-1) var(--ease-out);
}
.schedule-filter-panel-head {
  margin-bottom: var(--space-3);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--line-faint);
}
.schedule-filter-panel-head b {
  font-size: var(--fs-data);
  font-weight: var(--fw-semibold);
  color: var(--ink);
}
.schedule-filter-grid {
  gap: var(--space-3);
}
.schedule-filter-group {
  gap: var(--space-1);
}
/* group label = the §06 .fg overline: caption scale, uppercase, quiet */
.schedule-filter-title {
  color: var(--color-text-muted);
  font-size: var(--fs-caption);
  font-weight: var(--fw-caption);
  letter-spacing: var(--ls-caption);
  text-transform: uppercase;
}
/* option rows = full-width hit targets; whole row warms to --well on
   hover. The checkbox box inside is owned by the checkbox category. */
.schedule-filter-option {
  gap: var(--space-2);
  min-height: var(--ctl-h-xs);
  padding: var(--space-1) var(--space-2);
  margin: 0 calc(var(--space-2) * -1);
  color: var(--ink);
  font-size: var(--fs-data);
  border-radius: var(--r-s);
  transition: background var(--t-fast) var(--ease-out);
}
.schedule-filter-option:hover {
  background: var(--well);
}
.schedule-filter-option:focus-within {
  background: var(--well);
}

/* =====================================================================
   4 · HELP-MANUAL FILTER BUTTONS — section filter toggles with counts
   (.help-manual-filter-btn / .help-manual-filter-count). The toggle
   base is a .workspace-section-link (owned by the nav/section category);
   here we own the count's typography + focus.
   ===================================================================== */
.help-manual-filter-count {
  color: var(--color-text-muted);
  font-size: var(--fs-time);
  font-weight: var(--fw-semibold);
  font-variant-numeric: var(--fnum-data);
}
.help-manual-filter-btn.active .help-manual-filter-count {
  color: var(--color-text-inverse);
  opacity: 0.82;
}
.help-manual-filter-btn:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: var(--focus-ring-offset);
}

/* =====================================================================
   5 · DROPDOWN / CONTEXT MENUS — the popover surfaces that open on the
   --z-dropdown layer carrying --sh-2.
   ===================================================================== */

/* 5a · chip context menu (shift chip … actions) */
.chip-context-menu {
  z-index: var(--z-dropdown);
  min-width: 180px;
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: var(--r);
  box-shadow: var(--sh-2);
  padding: var(--space-1);
  animation: sbOverlayIn var(--dur-1) var(--ease-out);
}
.chip-context-item {
  border-radius: var(--r-s);
  background: transparent;
  color: var(--ink);
  padding: var(--space-2) var(--space-3);
  font-size: var(--fs-data);
  transition: background var(--t-fast) var(--ease-out),
              color var(--t-fast) var(--ease-out);
}
.chip-context-item:hover {
  background: var(--well);
  transform: none;          /* cancel the global button lift */
}
.chip-context-item:active {
  background: var(--green-tint);
}
.chip-context-item:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: -2px;
}
/* the ONE disabled recipe — no opacity dimming, no lift */
.chip-context-item:disabled,
.chip-context-item:disabled:hover {
  color: var(--ink-dis);
  background: transparent;
  cursor: not-allowed;
  opacity: 1;
}

/* 5b · schedule-row "more" menu */
.schedule-row-more-menu {
  z-index: var(--z-dropdown);
  top: calc(100% + var(--space-1));
  gap: var(--space-1);
  padding: var(--space-2);
  border: 1px solid var(--line-2);
  border-radius: var(--r);
  background: var(--surface);
  box-shadow: var(--sh-2);
  animation: sbOverlayIn var(--dur-1) var(--ease-out);
}
.schedule-row-more-menu > button {
  min-height: var(--ctl-h-sm);
  border-radius: var(--r-s);
  font-size: var(--fs-data);
}
.schedule-row-more-menu > button:hover:not(:disabled) {
  transform: none;
}
.schedule-row-more-menu > button:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: -2px;
}

/* 5c · lock recurrence popover — surface only (its rich form internals
   belong to the forms category; we just bring the shell to the recipe) */
.lock-popover {
  z-index: var(--z-dropdown);
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: var(--r);
  box-shadow: var(--sh-2);
  animation: sbOverlayIn var(--dur-1) var(--ease-out);
}

/* =====================================================================
   6 · TOUCH FLOOR — every control in this category rises to 44px below
   900px (audit #12 / §06 media block).
   ===================================================================== */
@media (max-width: 900px) {
  .settings-tab-btn { min-height: var(--tap-min); }
  .schedule-filter-option { min-height: var(--tap-min); }
  .chip-context-item { min-height: var(--tap-min); display: flex; align-items: center; }
  .schedule-row-more-menu > button { min-height: var(--tap-min); }
}

/* =====================================================================
   7 · REDUCED MOTION — kill the overlay entrance outright (the token
   kill-switch already zeroes --dur-*; this removes the animation so no
   sub-ms flash remains). State is never conveyed by motion alone here.
   ===================================================================== */
@media (prefers-reduced-motion: reduce) {
  .schedule-filter-panel,
  .chip-context-menu,
  .schedule-row-more-menu,
  .lock-popover {
    animation: none;
  }
}

/* =====================================================================
   CATEGORY 08 — Dialogs / modals  →  Service Bar re-skin
   ---------------------------------------------------------------------
   Appended AFTER styles.css. Targets the app's REAL class names so
   equal-specificity later rules win; a parent class is repeated only
   where the original rule is more specific (no !important unless noted).

   Recipe source: components.html §07 "Dialogs" + tokens.css.
   The app-native manager/employee dialog suite (confirm · text prompt ·
   choice · notice · the schedule-send / template-sync / changes-review /
   add-shift / shift-detail modals) is restyled — NOT rebuilt. Every JS
   hook (class names, data-attrs, ids, click/scroll flow) is preserved;
   only paint changes.

   Shell map (tokens.css):
     scrim  = --scrim  @ --z-scrim          (.modal-backdrop / .modal-overlay)
     dialog = --surface + --r(8px) + --sh-2 @ --z-dialog   (.modal-card …)

   Deliberate recipe refinements (see risks):
     · Title set at --fs-h2 (18px) not the demo's compact 15px — app
       modals carry richer headings than the board's 380px confirm card,
       and the app's <h3> default already reads at this step; 15px would
       break the established hierarchy.
     · Scrim is pure ink @32% (--scrim); the old skin's backdrop blur is
       dropped — the recipe specifies "ink at 32%", nothing more.
     · One focus recipe everywhere (2px solid ring, 2px offset) — the old
       choice-option focus used a soft box-shadow ring (audit #12 ban).
     · Status hues spent only on meaning: changes-review badges/icons map
       to the status language (assign=green · reassign=info · unassign/
       For-Review=danger · over-template=warning · training=role accent).
   ===================================================================== */

/* ===================================================================
   §1 · Scrim / overlay — the one workspace dimming layer
   .modal-backdrop is the common scrim; .modal-overlay is the
   changes-review modal's scrim (was UNSTYLED in styles.css — giving it
   the shell here makes it actually overlay, matching the recipe).
   =================================================================== */
.modal-backdrop,
.modal-overlay {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
  background: var(--scrim);
  z-index: var(--z-scrim);
  /* recipe: overlays appear instantly (in: 0ms) — no entrance animation */
}
/* drop the legacy blur from styles.css:7591 — recipe scrim is ink only */
.modal-backdrop {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

/* ===================================================================
   §2 · Dialog card — the system's only --sh-2 on a workspace surface
   Base .modal-card wins over styles.css:3589 / 7089 / 7596 / 8355
   (all 0,1,0, earlier in source).  .changes-modal-card carries no
   .modal-card class, so it gets the shell explicitly.
   =================================================================== */
.modal-card,
.changes-modal-card {
  position: relative;
  z-index: var(--z-dialog);
  background: var(--surface);
  border: var(--hairline);
  border-radius: var(--r);
  box-shadow: var(--sh-2);
  padding: var(--space-5) var(--space-5) var(--space-4);
  color: var(--color-text);
}
/* size variants keep their widths; only the shell/padding is re-skinned.
   Re-asserted AFTER the base so the roomier intents survive. */
.add-shift-modal-card {
  padding: var(--space-6) var(--space-5) var(--space-5);
}
.changes-modal-card {
  width: min(560px, 96vw);
  max-height: 85vh;
  overflow-y: auto;
}
.template-sync-preview-card { width: min(760px, 100%); }
.unsaved-changes-card { width: min(520px, 100%); }
.manager-confirm-card { width: min(460px, 100%); }

/* Compact padding on narrow viewports without the ui-mobile class
   (body.ui-mobile already handles touch via 0,2,1 rules). Re-asserted
   here so §2's later base cannot reintroduce the wide padding. */
@media (max-width: 720px) {
  .modal-card,
  .changes-modal-card {
    padding: var(--space-4);
  }
}

/* ===================================================================
   §3 · Title — single dialog-heading recipe across the suite
   =================================================================== */
.modal-card h3,
.changes-modal-header h3,
.add-shift-modal-card h3 {
  margin: 0 0 var(--space-1);
  color: var(--color-text);
  font-size: var(--fs-h2);
  line-height: var(--lh-h2);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-h2);
}

/* ===================================================================
   §4 · Body copy / supporting text
   =================================================================== */
.modal-card p,
.manager-confirm-body,
.manager-confirm-body p,
.unsaved-changes-card p,
.template-sync-preview-copy,
.employee-confirm-card p {
  margin: 0;
  color: var(--color-text-secondary);
  font-size: var(--fs-data);
  line-height: var(--lh-body);
}
.manager-confirm-body { display: grid; gap: var(--space-2); }

/* muted meta line ("Jun 15 to Jun 21", channel hints) inside dialogs */
.modal-card .hint,
.changes-baseline-note {
  color: var(--color-text-muted);
  font-size: var(--fs-time);
  line-height: var(--lh-time);
}
.changes-baseline-note { margin: 0 0 var(--space-3); }

/* ===================================================================
   §5 · Footer action rows — buttons inherit category 02; this only
   sets the layout language (right-aligned, --space-2 gap).
   =================================================================== */
.manager-confirm-actions,
.unsaved-changes-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-5);
}
.modal-card .row {
  gap: var(--space-2);
  margin-top: var(--space-4);
}
/* stacked full-width action list (employee + shift-detail dialogs) */
.modal-action-stack,
.manager-mobile-sheet-actions {
  display: grid;
  gap: var(--space-2);
  margin-top: var(--space-4);
}
.modal-meta-stack { gap: var(--space-2); margin-top: var(--space-2); }

/* ===================================================================
   §6 · Choice dialog — verb-first option buttons (.opt-btn recipe)
   App class: .manager-choice-option in a scroll list.
   =================================================================== */
.manager-choice-list {
  display: grid;
  gap: var(--space-2);
  margin-top: var(--space-3);
  max-height: min(46vh, 360px);
  overflow: auto;
  padding-right: var(--space-0);
}
.manager-choice-option {
  width: 100%;
  justify-content: flex-start;
  text-align: left;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--line-2);
  border-radius: var(--r);
  background: var(--surface);
  color: var(--color-text);
  box-shadow: none;
  transition: border-color var(--t-fast) var(--ease-out),
              background var(--t-fast) var(--ease-out);
}
.manager-choice-option:hover,
.manager-choice-option.is-default {
  border-color: var(--green);
  background: var(--wash);
  box-shadow: none;
}
.manager-choice-option:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: var(--focus-ring-offset);
  box-shadow: none;
}

/* ===================================================================
   §7 · Text-prompt field + send-scope choice fieldset
   =================================================================== */
.manager-prompt-field {
  display: grid;
  gap: var(--space-1);
  margin-top: var(--space-3);
  color: var(--color-text);
  font-size: var(--fs-data);
  font-weight: var(--fw-semibold);
}

.schedule-send-scope {
  margin: var(--space-3) 0;
  padding: var(--space-3);
  border: var(--hairline);
  border-radius: var(--r-s);
  background: var(--surface-sunken);
}
.schedule-send-scope legend {
  padding: 0 var(--space-1);
  color: var(--color-text-muted);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-caption);
  text-transform: uppercase;
}
.schedule-send-scope-option {
  gap: var(--space-2);
  margin: var(--space-2) 0;
  color: var(--color-text);
}
.schedule-send-scope-option small { color: var(--color-text-muted); }
/* one disabled recipe: dimmed + not-allowed, never readable copy */
.schedule-send-scope-option.is-disabled {
  opacity: 0.55; /* no opacity token; matches the global is-disabled feel */
  cursor: not-allowed;
}

/* ===================================================================
   §8 · In-dialog notices — tinted papers, status language only
   =================================================================== */
/* unsaved-changes detail = a caution about losing edits → warning amber */
.unsaved-changes-detail {
  margin-top: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--line-warning-soft);
  border-left: var(--edge-status) solid var(--amber-dot);
  border-radius: var(--r-s);
  background: var(--color-warning-subtle);
  color: var(--color-warning-text);
  font-size: var(--fs-data);
  line-height: var(--lh-data);
}
/* template-sync notes: neutral fact vs amber warning */
.template-sync-preview-note {
  margin-top: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--r-s);
  background: var(--surface-sunken);
  color: var(--color-text-secondary);
  font-size: var(--fs-data);
  line-height: var(--lh-data);
}
.template-sync-preview-note.warn {
  border-left: var(--edge-status) solid var(--amber-dot);
  background: var(--color-warning-subtle);
  color: var(--color-warning-text);
}
/* template-sync summary stat tiles */
.template-sync-preview-stat {
  gap: var(--space-1);
  padding: var(--space-3);
  border: var(--hairline);
  border-radius: var(--r-s);
  background: var(--surface-sunken);
}
.template-sync-preview-stat strong {
  font-size: var(--fs-h1);
  font-weight: var(--fw-semibold);
  font-variant-numeric: var(--fnum-data); /* tabular counts */
}
.template-sync-preview-stat span { color: var(--color-text-muted); }
.template-sync-preview-stat.success {
  background: var(--color-primary-subtle);
  border-color: var(--green-bar);
}
.template-sync-preview-stat.success strong { color: var(--green-ink); }
.template-sync-preview-stat.warn {
  background: var(--color-warning-subtle);
  border-color: var(--amber-dot);
}
.template-sync-preview-stat.warn strong { color: var(--color-warning-text); }

/* ===================================================================
   §9 · Changes-review modal — header, section titles, status badges,
   audit log. Status hues spent only on meaning (tokens §10).
   =================================================================== */
.changes-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin-bottom: var(--space-1);
}
.changes-section { margin-bottom: var(--space-5); }
.changes-section-title {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
  padding-bottom: var(--space-1);
  border-bottom: var(--hairline);
  color: var(--color-text-secondary);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-caption);
  text-transform: uppercase;
}
/* count badges carry numbers → tabular */
.changes-count-badge {
  min-width: 20px;
  height: 20px;
  padding: 0 var(--space-1);
  border-radius: var(--r-pill);
  background: var(--surface-sunken);
  color: var(--color-text-secondary);
  font-size: var(--fs-time);
  font-weight: var(--fw-semibold);
  font-variant-numeric: var(--fnum-data);
  line-height: 1;
}
.changes-count-warn {
  background: var(--color-warning-subtle);
  color: var(--color-warning-text);
}
/* For-Review = needs a decision (unfilled-shift mark) → danger;
   Above-template = warning. */
.changes-badge {
  flex-shrink: 0;
  padding: var(--space-0) var(--space-1);
  border-radius: var(--r-xs);
  font-size: var(--fs-caption);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-caption);
  text-transform: uppercase;
  line-height: var(--lh-caption);
}
.changes-badge-tbd  { background: var(--color-danger-subtle);  color: var(--color-danger-text); }
.changes-badge-over { background: var(--color-warning-subtle); color: var(--color-warning-text); }
.changes-tbd-row {
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border: var(--hairline);
  border-radius: var(--r-s);
  background: var(--surface-sunken);
  margin-bottom: var(--space-1);
  font-size: var(--fs-data);
}
.changes-date {
  color: var(--color-text-muted);
  font-size: var(--fs-data);
  font-variant-numeric: var(--fnum-data); /* dates/counts */
}

/* audit log rows + status-coded icon chips */
.audit-entry {
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border: var(--hairline);
  border-radius: var(--r-s);
  background: var(--surface-sunken);
}
.audit-icon {
  background: var(--surface-sunken);
  color: var(--color-text-secondary);
  font-weight: var(--fw-semibold);
}
.audit-icon-assign   { background: var(--color-primary-subtle); color: var(--green-ink); }
.audit-icon-reassign { background: var(--color-info-subtle);    color: var(--blue-ink); }
.audit-icon-unassign { background: var(--color-danger-subtle);  color: var(--color-danger-text); }
.audit-icon-extra    { background: var(--color-warning-subtle); color: var(--color-warning-text); }
.audit-icon-extra-rm { background: var(--color-danger-subtle);  color: var(--color-danger-text); }
.audit-icon-training { background: var(--accent-1-wash);        color: var(--accent-1); }
.audit-msg { color: var(--color-text); font-size: var(--fs-data); line-height: var(--lh-data); }
.audit-meta { color: var(--color-text-muted); font-size: var(--fs-time); }

/* ===================================================================
   §10 · Close ✕ buttons — quiet ghost icon, one focus recipe
   =================================================================== */
.add-shift-modal-close,
.icon-close-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 0;
  border-radius: var(--r-s);
  color: var(--color-text-muted);
  cursor: pointer;
  line-height: 1;
  transition: color var(--t-fast) var(--ease-out),
              background var(--t-fast) var(--ease-out);
}
.add-shift-modal-close:hover,
.icon-close-btn:hover {
  color: var(--color-text);
  background: var(--surface-hover);
}
.add-shift-modal-close:focus-visible,
.icon-close-btn:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: var(--focus-ring-offset);
}

/* ===================================================================
   §11 · Touch floor — every dismiss/choice target ≥44px below 900px
   (tokens §9 --tap-min). The app's ui-mobile path covers most controls;
   this guarantees the floor on plain narrow viewports too.
   =================================================================== */
@media (max-width: 899px) {
  .add-shift-modal-close,
  .icon-close-btn {
    min-width: var(--tap-min);
    min-height: var(--tap-min);
  }
  .manager-choice-option {
    min-height: var(--tap-min);
  }
}

/* ============================================================================
   09 · TOASTS & INLINE NOTICES — Service Bar re-skin
   ----------------------------------------------------------------------------
   Appended AFTER styles.css. Re-skins the app's real markup to the recipe in
   components.html §08 ("Toasts & notices") using tokens.css variables only.

   App markup (do not change — JS depends on it):
     Toasts  : .toast-container > .toast.(success|error|info|warning)
               > .toast-icon  + .toast-msg  + .toast-dismiss
               (.toast.dismissing on exit; emitted by public/shared/toast.js)
     Notices : .auth-inline-message  + [data-tone="error|success|info"]  and the
               shared #resetHint[data-tone] (home/invite/reset-password.js),
               .timeoff-overlap-alert (conflict), .developer-acting-banner (info)

   Recipe shape: white surface, hairline border, a 2px status LEFT EDGE
   (--edge-status) that carries the meaning, --sh-2 on floated toasts, tinted
   --paper-warning / --paper-danger papers on warn/danger notices. Status hues
   are spent only on meaning; links inside notices are green, never blue. ONE
   focus recipe (2px solid ring), 44px dismiss target, reduced-motion safe.
   ============================================================================ */

/* ---------------------------------------------------------------------------
   TOAST STACK — floats above everything on the named z ladder
   --------------------------------------------------------------------------- */
.toast-container {
  z-index: var(--z-toast);                /* was ad-hoc 9999 */
  gap: var(--space-2);
  bottom: calc(var(--space-5) + env(safe-area-inset-bottom, 0px));
  right: var(--space-5);
}

/* ---------------------------------------------------------------------------
   TOAST — white surface + hairline + 2px neutral left edge (status overrides).
   Quiet by default; the edge + the icon carry the status, not a tinted fill.
   --------------------------------------------------------------------------- */
.toast {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--tap-min);             /* dismiss meets the 44px floor */
  padding: var(--space-2) 0 var(--space-2) var(--space-4);
  background: var(--surface);
  color: var(--color-text);
  border: 1px solid var(--line);
  border-left: var(--edge-status) solid var(--line-2);
  border-radius: var(--r);
  box-shadow: var(--sh-2);                /* overlays only — §6 elevation */
  font-size: var(--fs-data);
  line-height: var(--lh-data);
  font-weight: var(--fw-regular);
  max-width: min(380px, calc(100vw - var(--space-7)));
  animation: toast-in var(--dur-3) var(--ease-out);
}

/* status = the left edge colour + the icon colour (decodable, audit #9) */
.toast.success { background: var(--surface); color: var(--color-text); border-left-color: var(--color-primary-accent); }
.toast.error   { background: var(--surface); color: var(--color-text); border-left-color: var(--color-danger); }
.toast.info    { background: var(--surface); color: var(--color-text); border-left-color: var(--dot-changed); }
.toast.warning { background: var(--surface); color: var(--color-text); border-left-color: var(--dot-warning); }

.toast.success .toast-icon { color: var(--color-primary); }
.toast.error   .toast-icon { color: var(--color-danger); }
.toast.info    .toast-icon { color: var(--color-info); }
.toast.warning .toast-icon { color: var(--color-warning); }

.toast-icon {
  flex-shrink: 0;
  margin-top: 0;
  font-size: 16px;          /* recipe "16px glyph" — no 16px size token exists */
  line-height: 1;
}

.toast-msg {
  flex: 1;
  color: var(--color-text);
  font-weight: var(--fw-regular);
  font-variant-numeric: var(--fnum-data);  /* "Texted 6…", "36.0h" align */
}

/* dismiss — a true 44×44 ghost target around the glyph (recipe .tx) */
.toast-dismiss {
  width: var(--tap-min);
  height: var(--tap-min);
  flex-shrink: 0;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink-3);
  opacity: 1;                              /* recipe uses bg hover, not fade */
  font-size: 18px;          /* the × glyph — between body/h2, no exact token */
  line-height: 1;
  border-radius: var(--r-s);
  cursor: pointer;
  transition: background var(--dur-2) var(--ease-out),
              color var(--dur-2) var(--ease-out);
}
.toast-dismiss:hover {
  opacity: 1;
  background: var(--well);
  color: var(--color-text);
}
.toast-dismiss:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: -4px;                    /* inset — ring sits at toast edge */
}

/* motion — token-driven so the reduced-motion kill switch in tokens.css
   (collapses --dur-* to 0.01ms) freezes the slide without breaking the
   animationend dismiss handler in toast.js (it has a 400ms fallback too). */
.toast.dismissing {
  animation: toast-out var(--dur-2) var(--ease-in-out) forwards;
}

/* ---------------------------------------------------------------------------
   INLINE NOTICES
   Live with the content: hairline box, 2px status left edge, tinted paper on
   warn/danger. No icon in this markup, so the status hue also tints the copy
   so meaning survives without a glyph.
   --------------------------------------------------------------------------- */

/* base / info tone (.auth-inline-message default; home.js passes "info") —
   recipe info notice keeps a white surface, blue edge carries the meaning */
.auth-inline-message {
  margin: var(--space-2) 0;
  padding: var(--space-3) var(--space-4);
  background: var(--surface);
  color: var(--color-text);
  border: 1px solid var(--line);
  border-left: var(--edge-status) solid var(--dot-changed);
  border-radius: var(--r);
  font-size: var(--fs-data);
  line-height: var(--lh-body);
  font-weight: var(--fw-semibold);
  font-variant-numeric: var(--fnum-data);
}

/* danger tone — tinted danger paper, red edge, red copy (shared #resetHint) */
.auth-inline-message[data-tone="error"],
#resetHint[data-tone="error"] {
  padding: var(--space-3) var(--space-4);
  background: var(--paper-danger);
  border: 1px solid var(--line);
  border-left: var(--edge-status) solid var(--color-danger);
  border-radius: var(--r);
  color: var(--color-danger-text);
  font-size: var(--fs-data);
  line-height: var(--lh-body);
  font-weight: var(--fw-semibold);
}

/* success tone — green wash, green edge, green ink (positive, never amber) */
.auth-inline-message[data-tone="success"],
#resetHint[data-tone="success"] {
  padding: var(--space-3) var(--space-4);
  background: var(--color-primary-wash);
  border: 1px solid var(--line);
  border-left: var(--edge-status) solid var(--color-primary-accent);
  border-radius: var(--r);
  color: var(--color-primary-text);
  font-size: var(--fs-data);
  line-height: var(--lh-body);
  font-weight: var(--fw-semibold);
}

/* warning tone — defensive: not currently emitted, but keeps amber as the one
   warning/setup hue if a "warning" tone is ever passed (never red) */
.auth-inline-message[data-tone="warning"],
#resetHint[data-tone="warning"] {
  padding: var(--space-3) var(--space-4);
  background: var(--paper-warning);
  border: 1px solid var(--line-warning-soft);
  border-left: var(--edge-status) solid var(--dot-warning);
  border-radius: var(--r);
  color: var(--color-warning-text);
  font-size: var(--fs-data);
  line-height: var(--lh-body);
  font-weight: var(--fw-semibold);
}

/* conflict / overlap alert — danger notice (was a heavy 1px solid #8b1e1e box) */
.timeoff-overlap-alert {
  margin-top: var(--space-2);
  padding: var(--space-3);
  background: var(--paper-danger);
  color: var(--color-text);
  border: 1px solid var(--line);
  border-left: var(--edge-status) solid var(--color-danger);
  border-radius: var(--r);
  font-size: var(--fs-data);
  line-height: var(--lh-body);
  font-variant-numeric: var(--fnum-data);
}
.timeoff-overlap-alert strong,
.timeoff-overlap-alert b {
  color: var(--color-danger-text);
  font-weight: var(--fw-semibold);
}

/* "acting as" banner — info notice: flat blue wash + blue edge (was a rounded
   blue gradient). Layout (flex/justify/gap) left untouched. */
.developer-acting-banner {
  padding: var(--space-3) var(--space-4);
  background: var(--scale-blue-50);
  border: 1px solid var(--line);
  border-left: var(--edge-status) solid var(--dot-changed);
  border-radius: var(--r);
}
.developer-acting-banner-copy strong {
  color: var(--color-info-text);
  font-weight: var(--fw-semibold);
}
.developer-acting-banner-copy span {
  color: var(--color-text-muted);
  font-size: var(--fs-data);
  line-height: var(--lh-data);
}

/* links inside any notice are green, never default blue (audit #6) */
.auth-inline-message a,
.timeoff-overlap-alert a,
.developer-acting-banner a {
  color: var(--color-link);
  text-underline-offset: 2px;
}
.auth-inline-message a:hover,
.timeoff-overlap-alert a:hover,
.developer-acting-banner a:hover {
  color: var(--color-link-hover);
}

/* =====================================================================
   CATEGORY 10 — Autosave indicator / savebar  →  Service Bar re-skin
   ---------------------------------------------------------------------
   Appended AFTER styles.css. Targets the app's REAL class names so
   equal-specificity later rules win; parent classes are repeated only
   where the original rule is more specific.

   Recipe source: components.html §09 "Autosave indicator" + tokens.css.
   The audit grades this the A-component — this evolves the SKIN, not the
   behavior. The three reserved states are frozen: Saving… / Saved /
   Save failed + Retry.

   Deliberate recipe refinement (noted in risks): the old skin tinted the
   "Saving…" state AMBER. Amber is reserved for warnings/setup (tokens
   §10 "status hues spent only on meaning"). The Service Bar savebar
   reads Saving as a NEUTRAL in-progress state — muted ink + a spinner —
   so a routine autosave can never impersonate a warning. Saved = green,
   Save failed = red. Hues are now spent only on meaning.
   ===================================================================== */

/* ---------- spinner keyframe (saving state) ----------
   The app pill renders text only; the spinner is a CSS-only ::before so
   it survives the JS textContent updates and never touches the DOM the
   handlers depend on. Literal duration is frozen under reduced-motion
   below (the token kill-switch only zeroes --dur-*, not literal ms). */
@keyframes autosave-spin {
  to { transform: rotate(360deg); }
}

/* ===================================================================
   Toolbar shell (inline savebar band + history host)
   =================================================================== */
.autosave-toolbar {
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface-sunken);
}
.autosave-toolbar strong {
  color: var(--ink);
  font-weight: var(--fw-semibold);
}
.autosave-toolbar .hint {
  margin-top: var(--space-0);
  color: var(--color-text-muted);
}
.autosave-toolbar-compact {
  padding: 0;
  border: 0;
  background: transparent;
}
.autosave-toolbar-actions {
  gap: var(--space-2);
}

/* ===================================================================
   Status pill — the three frozen states
   Pill shape is kept (proven structure); colors are mapped to the
   Service Bar status language. font-feature: status copy carries no
   numerals, so no tabular-nums here.
   =================================================================== */
.autosave-status-pill {
  min-height: var(--ctl-h-xs);
  padding: var(--space-1) var(--space-2);
  gap: var(--space-1);
  border: 1px solid var(--line-2);
  border-radius: var(--r-pill);
  background: var(--surface-panel);
  color: var(--color-text-secondary);
  font-size: var(--fs-time);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-time);
  letter-spacing: 0;
  transition:
    background var(--dur-3) var(--ease-out),
    border-color var(--dur-3) var(--ease-out),
    color var(--dur-3) var(--ease-out),
    opacity var(--dur-4) var(--ease-out),
    transform var(--dur-4) var(--ease-out);
}

/* SAVING — neutral, never amber. Spinner carries the progress signal. */
.autosave-status-pill[data-state="saving"] {
  border-color: var(--line-2);
  background: var(--well);
  color: var(--color-text-secondary);
}
.autosave-status-pill[data-state="saving"]::before {
  content: "";
  width: 11px;
  height: 11px;
  flex: none;
  border-radius: 50%;
  border: 1.5px solid currentColor;
  border-top-color: transparent;
  opacity: 0.9;
  animation: autosave-spin 0.8s linear infinite;
}

/* SAVED — healthy green. */
.autosave-status-pill[data-state="saved"] {
  border-color: var(--green-bar);
  background: var(--status-published-bg);
  color: var(--status-published-fg);
  animation: autosave-saved-pill-settle 2200ms var(--ease-in-out) 1400ms forwards;
}

/* SAVE FAILED — danger red, persistent until resolved. */
.autosave-status-pill[data-state="error"] {
  border-color: var(--red);
  background: var(--status-conflict-bg);
  color: var(--status-conflict-fg);
}

/* ===================================================================
   Retry — a real focusable control (.secondary base). Restyled to a
   danger-outline control: red ink + danger focus ring. Beats the
   button.secondary base (0,1,1) with a 2-class selector.
   =================================================================== */
.autosave-retry-btn.secondary {
  min-height: var(--ctl-h-sm);
  padding: var(--space-1) var(--space-2);
  border: 1px solid var(--red);
  border-radius: var(--r-s);
  background: var(--surface-panel);
  color: var(--color-danger-text);
  font-weight: var(--fw-semibold);
}
.autosave-retry-btn.secondary:hover:not(:disabled) {
  background: var(--red-tint);
  border-color: var(--red-deep);
  color: var(--color-danger-text);
}
.autosave-retry-btn.secondary:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus-danger);
  outline-offset: var(--focus-ring-offset);
}

/* ===================================================================
   History disclosure + change rows
   =================================================================== */
.autosave-history-panel {
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface-panel);
}
.autosave-history-panel summary {
  padding: var(--space-2) var(--space-3);
  color: var(--ink-2);
  font-size: var(--fs-data);
  font-weight: var(--fw-semibold);
}
.autosave-history-panel summary:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: calc(var(--focus-ring-offset) * -1);
  border-radius: var(--r-s);
}
.autosave-change-list {
  border-top: 1px solid var(--line-faint);
}
.autosave-change-list > .hint {
  padding: var(--space-2) var(--space-3);
  color: var(--color-text-muted);
}
.autosave-change-row {
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-top: 1px solid var(--line-faint);
}
.autosave-change-row strong {
  color: var(--ink);
  font-weight: var(--fw-semibold);
}
.autosave-change-values {
  gap: var(--space-1);
  margin-top: var(--space-1);
  color: var(--ink-2);
  font-size: var(--fs-time);
  /* value chips frequently hold times / hours / counts → tabular */
  font-variant-numeric: var(--fnum-data);
}
.autosave-change-values span:first-child,
.autosave-change-values span:last-child {
  padding: var(--space-0) var(--space-1);
  border-radius: var(--r-xs);
  background: var(--well);
}
.autosave-change-row.is-reverted {
  opacity: 0.68; /* de-emphasis; no opacity token exists */
}
.autosave-change-row.is-conflicted {
  /* conflict = red in the status language (was amber, which reads as a
     warning). 2px status edge per tokens §5 --edge-status. */
  border-left: var(--edge-status) solid var(--red);
}

/* ===================================================================
   Floating sticky savebar (template + autosave session)
   It floats above content → sits on the named --z-savebar layer and
   wears the overlay elevation (--sh-2). Bar CHROME stays neutral across
   states; the pill carries the color (the recipe's quiet-chrome model).
   Error is the exception — failure is never silent, so the bar itself
   gains a danger edge + wash.
   =================================================================== */
.template-savebar,
.autosave-session-savebar {
  z-index: var(--z-savebar);
  gap: var(--space-2);
  margin-top: var(--space-3);
  padding: var(--space-2);
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface); /* fallback for no color-mix support */
  background: color-mix(in srgb, var(--surface) 94%, transparent);
  box-shadow: var(--sh-2);
  backdrop-filter: blur(10px); /* frosted dock; no blur token */
  transition:
    background var(--dur-3) var(--ease-out),
    border-color var(--dur-3) var(--ease-out),
    box-shadow var(--dur-4) var(--ease-out),
    opacity var(--dur-4) var(--ease-out),
    transform var(--dur-4) var(--ease-out);
}

/* SAVING — neutral chrome; the pill spinner is the signal. */
.template-savebar[data-state="saving"],
.autosave-session-savebar[data-state="saving"] {
  border-color: var(--line);
  box-shadow: var(--sh-2);
}

/* SAVED — chrome calms to a lighter resting elevation, then settles. */
.template-savebar[data-state="saved"],
.autosave-session-savebar[data-state="saved"] {
  border-color: var(--line);
  box-shadow: var(--sh-1);
  animation: autosave-saved-bar-settle 2200ms var(--ease-in-out) 1400ms forwards;
}

/* SAVE FAILED — bar wears a danger edge + faint danger wash. */
.template-savebar[data-state="error"],
.autosave-session-savebar[data-state="error"] {
  border-color: var(--color-danger);
  background: var(--paper-danger);
  background: color-mix(in srgb, var(--paper-danger) 96%, transparent);
  box-shadow: var(--sh-2);
}

/* Saved bar stays fully present on hover / focus-within (don't fade away
   while the operator is reaching for Undo). Match the 4-selector
   specificity of the original. */
.template-savebar[data-state="saved"]:hover,
.template-savebar[data-state="saved"]:focus-within,
.autosave-session-savebar[data-state="saved"]:hover,
.autosave-session-savebar[data-state="saved"]:focus-within {
  opacity: 1;
  transform: none;
  border-color: var(--line);
  box-shadow: var(--sh-1);
}
.template-savebar[data-state="saved"]:hover .autosave-status-pill[data-state="saved"],
.template-savebar[data-state="saved"]:focus-within .autosave-status-pill[data-state="saved"],
.autosave-session-savebar[data-state="saved"]:hover .autosave-status-pill[data-state="saved"],
.autosave-session-savebar[data-state="saved"]:focus-within .autosave-status-pill[data-state="saved"] {
  opacity: 1;
  transform: none;
}

.template-savebar-status,
.autosave-session-savebar-status {
  gap: var(--space-2);
}
.template-savebar-actions,
.autosave-session-savebar-actions {
  gap: var(--space-2);
}
.template-savebar-actions > button,
.autosave-session-savebar-actions > button {
  min-height: var(--ctl-h-sm);
  padding: var(--space-1) var(--space-2);
}

/* Revert is destructive → danger ink (keep original (0,2,0) specificity). */
.template-session-revert-btn:not(:disabled),
.autosave-session-revert-btn:not(:disabled) {
  color: var(--color-danger-text);
}

/* Sticky wrapper rides the same named layer as the bar. */
.configuration-page-savebar {
  z-index: var(--z-savebar);
}

/* ===================================================================
   Settle keyframes — opacity/transform only (token-safe; no animated
   colors). Defined here so they win over the originals in styles.css.
   The resting saved colors come from the [data-state="saved"] rules.
   =================================================================== */
@keyframes autosave-saved-bar-settle {
  0%, 58% {
    opacity: 1;
    transform: none;
    box-shadow: var(--sh-1);
  }
  100% {
    opacity: 0.68;
    transform: translateY(2px) scale(0.985);
    box-shadow: var(--sh-1);
  }
}
@keyframes autosave-saved-pill-settle {
  0%, 58% {
    opacity: 1;
    transform: none;
  }
  100% {
    opacity: 0.64;
    transform: scale(0.94);
  }
}

/* ===================================================================
   Touch floor — interactive Retry rises to 44px below 900px (audit #12).
   The pill is status (non-interactive) and is exempt.
   =================================================================== */
@media (max-width: 899.98px) {
  .autosave-retry-btn.secondary {
    min-height: var(--tap-min);
  }
}

/* ===================================================================
   Reduced motion — freeze the literal-duration animations (spinner +
   settles). State is always carried by text/color too, never motion
   alone. Placed last so animation:none wins at equal specificity.
   =================================================================== */
@media (prefers-reduced-motion: reduce) {
  .autosave-status-pill[data-state="saving"]::before {
    animation: none;
  }
  .autosave-status-pill[data-state="saved"],
  .template-savebar[data-state="saved"],
  .autosave-session-savebar[data-state="saved"] {
    animation: none;
  }
}

/* =====================================================================
   SERVICE BAR · Category 11 — Nav shell
   ---------------------------------------------------------------------
   Sidebar / dim nav · top + workspace header · mobile bottom tab bar
   + "More" sheet. Appended AFTER styles.css (and after the rs-* bridge
   block at styles.css:7018+), so equal-specificity rules here WIN.
   Selectors mirror the app's real markup (renderManagerHamburgerNav,
   renderManagerWorkspaceHeader, renderManagerMobileNavigation).

   Recipe: dim, calm, operational. Sidebar recedes into the ink
   (--chrome-bg); the active item is a --chrome-accent green bar +
   brighter ink. The workspace header is a flat hairline band, not a
   shadowed card. Status hues spent only on meaning. ONE focus recipe.

   NOTE ON CHROME WASHES: the dim sidebar's hover/active/divider washes
   are translucent whites (rgba(255,255,255,.0X)) — verbatim from the
   Service Bar concept board (concept-b/board.html .nitem). No token
   exists for "light-on-dark chrome wash"; these alphas ARE the recipe.
   ===================================================================== */

/* =====================================================================
   1 · SIDEBAR SHELL (the manager <header> as dim chrome rail)
   ===================================================================== */
body.manager-workspace > header {
  background: var(--chrome-bg);
  border-right: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow: none;
  padding: var(--space-4) var(--space-3);
}

/* brand plate — the logo is an <img> (could be dark-inked or a tenant
   upload), so it rides a soft green-wash plate to stay legible on ink */
body.manager-workspace > header .brand-block {
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  padding: 0 var(--space-1) var(--space-3);
}
body.manager-workspace > header .brand-logo {
  padding: var(--space-2);
  border-radius: var(--r-s);
  background: var(--color-primary-wash);
}

/* nav scroll column — thin, dim scrollbar */
body.manager-workspace .top-nav {
  gap: var(--space-1);
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.16) transparent;
}
body.manager-workspace .top-nav::-webkit-scrollbar {
  width: 8px;
}
body.manager-workspace .top-nav::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.14);
  border-radius: var(--r-pill);
}

/* =====================================================================
   2 · SIDEBAR GROUPS + OVERLINE TITLES
   ===================================================================== */
body.manager-workspace .manager-sidebar-group {
  background: transparent;
  border: 0;
  border-radius: 0;
  padding: 0;
  gap: var(--space-1);
}
body.manager-workspace .manager-sidebar-group.active {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
}
body.manager-workspace .manager-sidebar-group-title {
  margin: var(--space-4) var(--space-2) var(--space-1);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  font-weight: var(--fw-caption);
  letter-spacing: var(--ls-caption);
  text-transform: uppercase;
  color: var(--chrome-text-mut);
}

/* =====================================================================
   3 · SIDEBAR ITEMS — rest · hover · active(+bar) · focus
   ===================================================================== */
body.manager-workspace .manager-sidebar-link {
  position: relative;
  border: 0;
  border-radius: var(--r-s);
  background: transparent;
  color: var(--chrome-text);
  box-shadow: none;
  padding: var(--space-2) var(--space-3);
  font-size: var(--fs-data);
  line-height: 1.25;
  font-weight: var(--fw-regular);
  letter-spacing: 0;
  transition: background-color var(--dur-2) var(--ease-out),
              color var(--dur-2) var(--ease-out);
}

body.manager-workspace .manager-sidebar-link:hover {
  background: rgba(255, 255, 255, 0.06);
  color: var(--color-text-inverse);
  border-color: transparent;
  transform: none;
}

/* active: subtle white wash + brighter ink + semibold + green edge bar */
body.manager-workspace .manager-sidebar-link.active {
  background: rgba(255, 255, 255, 0.09);
  border-color: transparent;
  color: var(--color-text-inverse);
  font-weight: var(--fw-semibold);
  box-shadow: none;
}
body.manager-workspace .manager-sidebar-link.active::before {
  content: "";
  position: absolute;
  left: 0;
  top: var(--space-1);
  bottom: var(--space-1);
  width: var(--edge-role);
  border-radius: 0 var(--r-xs) var(--r-xs) 0;
  background: var(--chrome-accent);
}

/* ONE focus recipe — inset on the dim rail (the nav scrolls / clips an
   outset ring); bright green-accent ring reads on near-black ink */
body.manager-workspace .manager-sidebar-link:focus-visible {
  outline: var(--focus-ring-w) solid var(--chrome-accent);
  outline-offset: calc(-1 * var(--focus-ring-offset));
}

/* count badge inside a sidebar item — red = "needs attention" (meaning) */
body.manager-workspace .menu-badge {
  background: var(--color-danger);
  color: var(--color-text-inverse);
  font-size: var(--fs-caption);
  font-weight: var(--fw-semibold);
  font-variant-numeric: var(--fnum-data);
}

/* =====================================================================
   4 · SIDEBAR LOGOUT — quiet action in the dim rail
   ===================================================================== */
body.manager-workspace .manager-sidebar-logout {
  margin-top: var(--space-2);
  border-radius: var(--r-s);
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.14);
  color: var(--chrome-text);
  box-shadow: none;
  font-size: var(--fs-data);
  font-weight: var(--fw-semibold);
  transition: background-color var(--dur-2) var(--ease-out),
              color var(--dur-2) var(--ease-out);
}
body.manager-workspace .manager-sidebar-logout:hover {
  background: rgba(255, 255, 255, 0.10);
  color: var(--color-text-inverse);
  border-color: rgba(255, 255, 255, 0.22);
  transform: none;
  box-shadow: none;
}
body.manager-workspace .manager-sidebar-logout:focus-visible {
  outline: var(--focus-ring-w) solid var(--chrome-accent);
  outline-offset: calc(-1 * var(--focus-ring-offset));
}

/* =====================================================================
   5 · WORKSPACE HEADER — flat hairline band (structure felt, not seen)
   ===================================================================== */
.manager-workspace-header {
  gap: var(--space-4);
  margin-bottom: var(--space-1);
  padding: var(--space-1) var(--space-1) var(--space-4);
  border: 0;
  border-bottom: var(--hairline);
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

.manager-workspace-heading {
  gap: var(--space-1);
}
.manager-workspace-heading h1 {
  font-size: var(--fs-display);
  line-height: var(--lh-display);
  font-weight: var(--fw-display);
  letter-spacing: var(--ls-display);
  color: var(--color-text);
}

/* eyebrow overline — calm muted caption, not a bright green kicker */
.manager-workspace-header .card-eyebrow {
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  font-weight: var(--fw-caption);
  letter-spacing: var(--ls-caption);
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.manager-workspace-description {
  font-size: var(--fs-data);
  line-height: var(--lh-body);
  color: var(--color-text-muted);
}

.manager-session-label {
  font-size: var(--fs-data);
  font-weight: var(--fw-semibold);
  color: var(--color-text-muted);
  font-variant-numeric: var(--fnum-data);
}

/* =====================================================================
   6 · STATUS PILLS — decodable; hues spent only on meaning
   ok = healthy green · warn = amber · neutral = quiet grey (never amber)
   ===================================================================== */
.manager-status-pill {
  padding: var(--space-1) var(--space-2);
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  font-size: var(--fs-caption);
  font-weight: var(--fw-semibold);
  letter-spacing: 0;
  font-variant-numeric: var(--fnum-data);
}
.manager-status-pill.ok {
  background: var(--status-published-bg);
  border-color: transparent;
  color: var(--status-published-fg);
}
.manager-status-pill.warn {
  background: var(--status-warning-bg);
  border-color: transparent;
  color: var(--status-warning-fg);
}
.manager-status-pill.neutral {
  background: var(--surface-sunken);
  border-color: transparent;
  color: var(--color-text-secondary);
}

/* =====================================================================
   7 · DEVELOPER "ACTING" BANNER — info notice (blue, 2px status edge)
   ===================================================================== */
.developer-acting-banner {
  padding: var(--space-3);
  border: var(--hairline);
  border-left: var(--edge-status) solid var(--color-info);
  border-radius: var(--r);
  background: var(--color-info-subtle);
}
.developer-acting-banner-copy strong {
  color: var(--color-info-text);
  font-weight: var(--fw-semibold);
}
.developer-acting-banner-copy span {
  color: var(--color-text-secondary);
  font-size: var(--fs-data);
}

/* =====================================================================
   8 · IN-PAGE SECTION NAV — add the missing focus ring (recipe-true)
   ===================================================================== */
.workspace-section-link:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: var(--focus-ring-offset);
}

/* =====================================================================
   9 · MOBILE BOTTOM TAB BAR (<900px) — light surface, 44px+ targets
   ===================================================================== */
.manager-mobile-bottom-tab-bar {
  z-index: var(--z-nav);
  background: var(--surface-panel);
  border-top: var(--hairline);
  /* upward elevation — tokens' --sh-* are downward-only; mirror --sh-2 alphas */
  box-shadow: 0 -1px 3px rgba(13, 31, 26, 0.06),
              0 -8px 24px rgba(13, 31, 26, 0.08);
}

.manager-mobile-tab-btn {
  color: var(--color-text-muted);
  font-size: var(--fs-caption);
  font-weight: var(--fw-semibold);
  letter-spacing: 0;
  transition: color var(--dur-2) var(--ease-out),
              background-color var(--dur-2) var(--ease-out);
}
/* tabs don't lift — a fixed bar shouldn't jump on (mouse) hover */
.manager-mobile-tab-btn:hover {
  color: var(--color-text);
  background: var(--surface-hover);
  transform: none;
}
.manager-mobile-tab-btn.active {
  color: var(--color-primary-text);
  background: var(--color-primary-wash);
}
.manager-mobile-tab-btn.active::before {
  background: var(--color-primary);
}
.manager-mobile-tab-btn:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: calc(-1 * var(--focus-ring-offset));
}
.manager-mobile-tab-badge {
  background: var(--color-danger);
  color: var(--color-text-inverse);
  border: 2px solid var(--surface-panel);
  font-weight: var(--fw-semibold);
  font-variant-numeric: var(--fnum-data);
}

/* =====================================================================
   10 · MOBILE "MORE" SHEET — scrim + bottom sheet (dialog layer)
   ===================================================================== */
.manager-mobile-more-scrim {
  z-index: var(--z-scrim);
  background: var(--scrim);
}
.manager-mobile-more-sheet {
  z-index: var(--z-dialog);
  background: var(--surface-panel);
  border: var(--hairline);
  border-bottom: none;
  box-shadow: var(--sh-2);
}
.manager-mobile-more-head h2 {
  color: var(--color-text);
}
.manager-mobile-more-group h3 {
  color: var(--color-text-muted);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  font-weight: var(--fw-caption);
  letter-spacing: var(--ls-caption);
  text-transform: uppercase;
}

.manager-mobile-more-link {
  min-height: var(--tap-min);
  border-radius: var(--r);
  border: var(--hairline-strong);
  background: var(--surface-panel);
  color: var(--color-text);
  box-shadow: var(--sh-1);
  font-weight: var(--fw-semibold);
  transition: background-color var(--dur-2) var(--ease-out),
              border-color var(--dur-2) var(--ease-out);
}
.manager-mobile-more-link:hover {
  background: var(--surface-hover);
  transform: none;
}
.manager-mobile-more-link.active {
  border-color: var(--color-primary);
  background: var(--color-primary-subtle);
  color: var(--color-primary-text);
}
.manager-mobile-more-link:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: var(--focus-ring-offset);
}

/* Close + Logout are quiet (neutral), never a green "primary" by default.
   Both keep the 44px touch floor already set in styles.css. */
.manager-mobile-more-close,
.manager-mobile-more-logout {
  background: var(--surface-sunken);
  border: var(--hairline-strong);
  border-radius: var(--r-s);
  color: var(--color-text-secondary);
  box-shadow: none;
  font-weight: var(--fw-semibold);
}
.manager-mobile-more-close:hover,
.manager-mobile-more-logout:hover {
  background: var(--surface-hover);
  color: var(--color-text);
  transform: none;
}
.manager-mobile-more-close:focus-visible,
.manager-mobile-more-logout:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: var(--focus-ring-offset);
}

/* =====================================================================
   Service Bar re-skin · CATEGORY 12 — Loading skeletons
   ---------------------------------------------------------------------
   Loaded AFTER styles.css (equal-specificity later rules win). Consumes
   /styles/tokens.css. Sources of truth:
     · components.html §10 "Skeletons"  (the .sk / .sk-grid / .sk-lrow /
       .sk-tile shapes + the `shim` 1.4s sweep)
     · motion-spec.md §2 (ambient `shim 1400ms ease-in-out infinite`),
       §4.7 (skeleton→content cross-fade, zero CLS), §5 (reduced-motion
       degradation: shimmer hidden, static well blocks remain).

   What the app ships today: no real skeleton markup — just text
   "Loading…" placeholders (renderManagerPageLocalLoading()), the invite
   #inviteLoadingCard, and a dormant #empLoadOverlay hook in employee.js.
   This part (a) ports the Service Bar skeleton primitive system the
   migration's skeleton-first paint (motion-spec §4.1) will emit, fully
   tokenized, and (b) re-skins the existing loading surfaces. The app has
   NO prior `.sk*` rules, so these introduce the recipe with no
   specificity battle.

   Hard rules honored: shimmer is the only ambient timing here and FREEZES
   under prefers-reduced-motion (the token kill-switch only collapses
   --dur-*; this 1400ms loop is hardcoded ambient, so it is stopped
   explicitly below). Base surface = --surface-sunken. Motion is
   compositor-only (transform/opacity). No status/role hues are spent —
   skeletons carry no meaning, only shape.
   ===================================================================== */

/* ---------------------------------------------------------------------
   1 · Skeleton primitive — the content-shaped block + shared sweep
   --------------------------------------------------------------------- */
.sk {
  position: relative;
  overflow: hidden;
  /* --well aliases --surface-sunken; the recipe's recessed base. */
  background: var(--surface-sunken);
  border-radius: var(--r-xs);          /* 4px dense placeholder corner */
}

/* The one shared shimmer. A glint sweeps L→R via transform only
   (compositor-safe). 1400ms ease-in-out is the sanctioned ambient
   timing (motion-spec §2) — NOT a --dur token, so reduced-motion must
   stop it explicitly (see §5 block at the bottom of this file). */
.sk::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  /* Translucent glint. Fallback rgba for engines without color-mix;
     color-mix derives the same from --surface-panel (#fff) so no raw
     hex carries the value. No token exists for a translucent sweep. */
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.6), transparent);
  background: linear-gradient(
    90deg,
    transparent,
    color-mix(in srgb, var(--surface-panel) 62%, transparent),
    transparent
  );
  animation: shim 1400ms var(--ease-in-out) infinite;
}

@keyframes shim {
  to { transform: translateX(100%); }
}

/* Shape modifiers (token-clean alternatives to the recipe's inline
   `border-radius:999px` pill blocks; heights/widths still come inline
   from the JS that sizes each block to its real content). */
.sk-pill { border-radius: var(--r-pill); }   /* avatar / status pill block */
.sk-block { border-radius: var(--r-s); }      /* chip-height day-cell block */

/* ---------------------------------------------------------------------
   2 · Schedule-grid skeleton — name column is a two-line block, day
   cells are chip-height blocks with honest gaps (predicts real density).
   Generic .hrow/.srow/.nm2 are scoped under .sk-grid so they never bleed.
   Column geometry is kept verbatim from the recipe: the skeleton's last
   frame must share box geometry with the real grid's first frame (§4.7).
   --------------------------------------------------------------------- */
.sk-grid {
  border: var(--hairline);             /* 1px solid --line */
  border-radius: var(--r);             /* 8px panel corner */
  overflow: hidden;
  background: var(--surface-panel);
  min-width: 620px;
}
.sk-grid .hrow {
  display: grid;
  grid-template-columns: 140px repeat(6, 1fr);
  gap: var(--space-2);                 /* 8px */
  padding: var(--space-2) var(--space-3);
  border-bottom: var(--hairline-strong); /* 1px solid --line-2 */
}
.sk-grid .srow {
  display: grid;
  grid-template-columns: 140px repeat(6, 1fr);
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-top: var(--hairline-faint);   /* 1px solid --line-faint */
  align-items: center;
}
.sk-grid .nm2 {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);                 /* 4px between name + hours lines */
}

/* ---------------------------------------------------------------------
   3 · List-row skeleton — pill (avatar/status) · title · meta · action.
   --------------------------------------------------------------------- */
.sk-lrow {
  display: grid;
  grid-template-columns: 64px 170px 1fr 130px;
  gap: var(--space-3);                 /* 12px */
  align-items: center;
  padding: var(--space-3) var(--space-4);
  border-top: var(--hairline-faint);
}

/* ---------------------------------------------------------------------
   4 · Stat-tile skeleton — pill-shaped where the label goes,
   number-sized where the figure goes.
   --------------------------------------------------------------------- */
.sk-tiles {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-3);
}
.sk-tile {
  border: var(--hairline);
  border-radius: var(--r);
  background: var(--surface-panel);
  padding: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

/* ---------------------------------------------------------------------
   5 · Skeleton → content cross-fade (motion-spec §4.7). Opacity ONLY —
   no translate on data swaps. Geometry pinning (the skeleton reserving
   the container height) is what guarantees CLS ≤ 0.1; this fade just
   softens the swap. Wrapper carries .content-enter for one frame.
   --------------------------------------------------------------------- */
.content-enter {
  animation: sk-fade-in var(--dur-2) var(--ease-out);
}
@keyframes sk-fade-in {
  from { opacity: 0; }
}

/* ---------------------------------------------------------------------
   6 · App loading surfaces that exist today, re-skinned to the recipe.
   --------------------------------------------------------------------- */

/* Invite "Checking Invite" card (invite.html #inviteLoadingCard). Same
   auth-card chrome it already inherits; this just settles the type onto
   Service Bar tokens so the loading state reads calm, not alarming.
   Equal id-specificity, declared later, so it wins over styles.css. */
#inviteLoadingCard h2 {
  color: var(--color-text);
  letter-spacing: var(--ls-h1);
}
#inviteLoadingCard .hint {
  color: var(--color-text-muted);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
}

/* Employee bootstrap skeleton overlay (employee.js show/hideEmpSkeleton →
   #empLoadOverlay). Currently dormant (the hook only removes it), but the
   id is the app's own loading selector — styled defensively so a revived
   overlay reads as a Service Bar loading veil hosting .sk blocks, never a
   white flash. Additive; no layout the JS depends on is altered. */
#empLoadOverlay {
  position: absolute;
  inset: 0;
  z-index: var(--z-raised);
  display: grid;
  gap: var(--space-3);
  align-content: start;
  padding: var(--space-5);
  /* translucent paper veil over the screen being refreshed */
  background: color-mix(in srgb, var(--surface-page) 88%, transparent);
}
#empLoadOverlay .sk { width: 100%; }

/* ---------------------------------------------------------------------
   7 · prefers-reduced-motion — FREEZE the shimmer. tokens.css collapses
   --dur-* to 0.01ms, but the ambient `shim`/`sk-fade-in` loops carry
   hardcoded timing, so they must be stopped here. Per motion-spec §5 the
   glint is hidden and the static --surface-sunken well blocks remain;
   content still swaps in one frame (geometry pinning unchanged).
   --------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .sk::after {
    display: none;
    animation: none;
  }
  .content-enter {
    animation: none;
  }
}


/* ===== Schedule detail — Service Bar structural deltas ===== */
/* The schedule-detail surface is rebuilt to the Service Bar mockup
   (design/ui-rethink-2026-06/04-mockups/schedule-detail/after.html): a
   self-contained detail header, a Filled/Unfilled/Warnings stat strip, a
   warnings worklist with jump links, per-day on-counts, rostered-only rows
   with "Show all", an inline Unfilled row, time-first chips and a per-cell
   add ghost. Markup/wiring live in app.js renderScheduleDetailInto /
   renderWeekTable / renderChip / renderManagerMobileScheduleDetail. All
   color/spacing consume design tokens. */

.sd-tnum, .sd-day-on, .sd-nh, .sd-meta-counts, .sd-tile-value, .sd-sec-count {
  font-variant-numeric: tabular-nums;
}

/* ---- Detail header (delta #6) ---- */
.sd-detail-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 18px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}
.sd-detail-titlewrap { min-width: 240px; flex: 1; }
.sd-eyebrow {
  font-size: 10.5px;
  font-weight: var(--fw-semibold);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.sd-detail-title {
  margin: 2px 0 0;
  font-size: 22px;
  font-weight: var(--fw-semibold);
  letter-spacing: -.01em;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.sd-detail-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 7px;
  flex-wrap: wrap;
  font-size: 12.5px;
  color: var(--ink-3);
}
.sd-meta-counts { color: var(--ink-2); }
.sd-detail-actions {
  display: flex;
  flex-direction: column;
  gap: 9px;
  align-items: flex-end;
}
.sd-savebar {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 12.5px;
  color: var(--ink-3);
  padding: 5px 11px;
  background: var(--surface-panel);
  border: var(--hairline);
  border-radius: var(--r);
  box-shadow: var(--sh-1);
}
.sd-autosave-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--green-bar);
  flex: none;
}
.sd-action-cluster {
  display: flex;
  align-items: center;
  gap: 8px;
}
.sd-whysend { font-size: 11.5px; color: var(--ink-3); }
.sd-detail-hint { margin: 6px 0 12px; }

/* ---- Stat strip (delta #1) ---- */
.sd-strip {
  display: grid;
  grid-template-columns: repeat(3, minmax(120px, 200px));
  gap: 12px;
  margin: 6px 0 14px;
}
.sd-tile {
  border: var(--hairline);
  border-radius: var(--r);
  padding: 10px 14px 12px;
  background: var(--surface-panel);
}
.sd-tile-label {
  font-size: 10.5px;
  font-weight: var(--fw-semibold);
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.sd-tile-value {
  font-size: 24px;
  font-weight: var(--fw-semibold);
  line-height: 1.2;
  margin-top: 2px;
}
.sd-tile-sub { font-size: 11.5px; color: var(--ink-3); }
.sd-tile-ok .sd-tile-value { color: var(--green-ink); }
.sd-tile-bad .sd-tile-value { color: var(--red-ink); }
.sd-tile-bad { border-left: 3px solid var(--red); }
.sd-tile-warn .sd-tile-value { color: var(--amber-ink); }
.sd-tile-warn { border-left: 3px solid var(--amber-dot); }

/* ---- Warnings worklist (delta #3) ---- */
.sd-warnrows {
  border: var(--hairline);
  border-radius: var(--r);
  overflow: hidden;
  margin: 0 0 14px;
  background: var(--surface-panel);
}
.sd-wrow {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  font-size: 12.5px;
  border-top: var(--hairline-faint);
}
.sd-wrow:first-child { border-top: 0; }
.sd-wdot { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.sd-wrow-red .sd-wdot { background: var(--dot-urgent); }
.sd-wrow-amber .sd-wdot { background: var(--dot-warning); }
.sd-wrow-clear .sd-wdot { background: var(--green-bar); }
.sd-wrow-clear { color: var(--ink-3); }
.sd-wtext { flex: 1; color: var(--ink-2); min-width: 0; }
.sd-wjump {
  flex: none;
  border: 0;
  background: none;
  color: var(--green);
  font-weight: var(--fw-semibold);
  font-size: 12px;
  cursor: pointer;
  padding: 4px 8px;
  border-radius: var(--r-s);
  white-space: nowrap;
}
.sd-wjump:hover { background: var(--wash); color: var(--green-deep); }
.sd-wjump:focus-visible { outline: var(--focus-ring-w) solid var(--focus); outline-offset: 1px; }

/* ---- Sticky grid header + per-day on-counts (delta #4) ---- */
.schedule-grid thead th {
  position: sticky;
  top: 0;
  z-index: 5;
  background: #f1f6f2;
}
.schedule-grid th:first-child,
.schedule-grid td:first-child {
  position: sticky;
  left: 0;
  z-index: 3;
  background: var(--surface-panel);
}
.schedule-grid thead th:first-child { z-index: 6; }
.sd-day-name { display: block; font-weight: var(--fw-semibold); color: var(--ink); white-space: nowrap; }
.sd-day-on { display: block; margin-top: 2px; font-size: 11px; color: var(--ink-3); }
.sd-daybadge {
  display: inline-block;
  margin-top: 3px;
  border: 0;
  cursor: pointer;
  height: 16px;
  padding: 0 6px;
  border-radius: var(--r-pill);
  font-size: 10px;
  font-weight: var(--fw-semibold);
  line-height: 16px;
}
.sd-daybadge-red { background: var(--red-tint); color: var(--red-ink); }
.sd-daybadge-amber { background: var(--amber-tint); color: var(--amber-ink); }
.sd-daybadge:hover { box-shadow: var(--sh-1); }

/* ---- Section rows: rostered count + Show all (deltas #2, #6 of schedules.md) ---- */
.group-row.sd-secrow td {
  background: var(--surface-band);
  padding: 6px 8px;
}
.sd-secrow .sd-sec-dot {
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--ink-3);
  margin-right: 7px;
  vertical-align: middle;
}
.sd-sec-count { font-weight: var(--fw-regular); color: var(--ink-3); font-size: 11.5px; margin-left: 8px; }
.sd-showall {
  border: 0;
  background: none;
  color: var(--green);
  font-size: 11.5px;
  font-weight: var(--fw-semibold);
  cursor: pointer;
  padding: 3px 8px;
  margin-left: 10px;
  border-radius: var(--r-s);
}
.sd-showall:hover { background: var(--wash); color: var(--green-deep); }

/* ---- Person rows: weekly hours sub-label (delta #7) + Show-all band ---- */
.sd-name-cell { vertical-align: top; }
.sd-name-cell b { display: block; font-size: 12.5px; }
.sd-nh { display: block; font-size: 11px; color: var(--ink-3); white-space: nowrap; }
.sd-nh-near { color: var(--amber-ink); font-weight: var(--fw-semibold); }
.sd-nh-over { color: var(--red-ink); font-weight: var(--fw-semibold); }
.sd-person-row.sd-xtra td { background: var(--surface-band); }
.sd-person-row.sd-xtra .sd-name-cell b { font-weight: var(--fw-regular); color: var(--ink-2); }

/* ---- Inline Unfilled row (delta #5) ---- */
.sd-unfilled-row .sd-unfilled-name { color: var(--red-ink); }

/* ---- Time-first chips + single status dot (delta #8) ---- */
.schedule-grid .shift-chip {
  align-items: flex-start;
  text-align: left;
  padding: 5px 9px 6px 10px;
}
.schedule-grid .shift-chip.has-lock { padding-left: 26px; }
.schedule-grid .shift-chip .chip-time {
  font-size: 12.5px;
  font-weight: var(--fw-semibold);
  color: var(--ink);
  line-height: 1.25;
}
.schedule-grid .shift-chip .chip-meta {
  font-size: 10.5px;
  color: var(--ink-3);
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
.schedule-grid .shift-chip .chip-meta .chip-risk { color: var(--amber-ink); font-weight: var(--fw-semibold); }
.schedule-grid .shift-chip .chip-sub { font-size: 10px; color: var(--ink-3); line-height: 1.3; }
.schedule-grid .shift-chip.unfilled .chip-assign {
  font-size: 11px;
  font-weight: var(--fw-semibold);
  color: var(--red);
  margin-top: 1px;
}
.sd-chip-dot {
  position: absolute;
  top: 5px;
  right: 6px;
  width: 7px; height: 7px;
  border-radius: 50%;
  box-shadow: 0 0 0 2px var(--surface-panel);
}
.sd-chip-dot-amber { background: var(--dot-warning); }
.sd-chip-dot-blue { background: var(--dot-changed); }
.sd-chip-dot-green { background: var(--green-bar); }
.sd-chip-dot-red { background: var(--dot-urgent); }

/* ---- Per-cell add ghost (delta #9) ---- */
.sd-addghost {
  display: block;
  width: 100%;
  min-height: 38px;
  margin: 4px auto 0;
  border: 1px dashed var(--line-2);
  border-radius: var(--r-s);
  background: none;
  color: var(--ink-3);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--dur-2, 120ms) ease, border-color var(--dur-2, 120ms) ease, background var(--dur-2, 120ms) ease;
}
.sched-cell:hover .sd-addghost,
.sd-addghost:focus-visible { opacity: 1; }
.sd-addghost:hover { border-color: var(--line-hover); color: var(--ink-2); background: var(--surface-hover); }
.sd-addghost:focus-visible { outline: var(--focus-ring-w) solid var(--focus); outline-offset: 1px; }

/* ---- Jump pulse (delta #3 / #12) ---- */
@keyframes sd-row-pulse {
  0%, 35% { background-color: var(--blue-tint); }
  100% { background-color: transparent; }
}
.sd-row-pulse { animation: sd-row-pulse 1200ms ease-out 1; }
.sd-row-pulse.sd-warnrows { border-color: var(--blue-ink); }

/* ---- Mobile parity (delta #10) ---- */
.sd-mtile strong { color: var(--ink); }
.sd-mtile-ok strong { color: var(--green-ink); }
.sd-mtile-bad strong { color: var(--red-ink); }
.sd-mtile-bad { border-left: 3px solid var(--red); }
.sd-mtile-warn strong { color: var(--amber-ink); }
.sd-mtile-warn { border-left: 3px solid var(--amber-dot); }
.sd-mtile em { display: block; font-style: normal; font-size: 10.5px; color: var(--ink-3); }
.sd-mobile-warnrows {
  border: var(--hairline);
  border-radius: var(--r);
  overflow: hidden;
  margin: 10px 0;
  background: var(--surface-panel);
}
.sd-mobile-daychips {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  padding: 4px 0 8px;
  -webkit-overflow-scrolling: touch;
}
.sd-dchip {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  min-width: 54px;
  padding: 7px 10px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-s);
  background: var(--surface-panel);
  font-size: 11px;
  cursor: pointer;
}
.sd-dchip b { font-size: 12px; }
.sd-dchip span { color: var(--ink-3); font-variant-numeric: tabular-nums; }
.sd-dchip-urgent { border-color: var(--red); }
.sd-dchip-cur { background: var(--wash); border-color: var(--green); box-shadow: inset 0 -2px 0 var(--green); }

@media (max-width: 760px) {
  .sd-strip { grid-template-columns: repeat(3, 1fr); gap: 8px; }
  .sd-detail-actions { align-items: stretch; width: 100%; }
  .sd-action-cluster { flex-wrap: wrap; }
}
/* ===== end Schedule detail structural deltas ===== */


/* =====================================================================
   Service Bar re-skin · CATEGORY 22 — Login / access (front door)
   ---------------------------------------------------------------------
   Loaded AFTER styles.css (via /styles/service-bar.css), so equal- and
   higher-specificity rules here win the cascade. Consumes /styles/tokens.css
   for every color / space / shape / type / motion value.

   Screen: public/index.html — the centered brand lockup + the three auth
   cards (#universalLoginSection sign-in + reset view, #firstLoginSection,
   #ownerSignupSection). Mockup source of truth:
     design/ui-rethink-2026-06/04-mockups/login/after.html + after-*.png

   Recipe: a centered brand mark on system green over a single 400px white
   card; single-column .ffield rows with persistent .flabel labels; one
   full-width primary submit with a quiet inline "Forgot password?" link;
   in-card danger/info notices; a pending spinner; a content-shaped session
   skeleton. Buttons reuse the app's primary <button> system (category 02);
   inputs reuse the app's field system (category 03). This part only adds
   the auth LAYOUT, the brand lockup, the field-label primitives, the
   notice/spinner/skeleton-line primitives, and the overrides that retire
   the old header band + full-width login card (styles.css:7643-7689).

   Local layout literals (no token exists): --auth-card-w 400px (container
   width) and the brand-mark/brand-name sizes — flagged inline.
   ===================================================================== */

/* ---------------------------------------------------------------------
   1 · PAGE LAYOUT — the centered auth column. The app's existing
   `main:has(#universalLoginSection)` rule already grid-centers this
   block and sets the top offset; .auth-wrap just constrains the width so
   the brand lockup and the card share one 400px column.
   --------------------------------------------------------------------- */
.auth-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: min(100%, 400px);            /* --auth-card-w; no width token exists */
}

/* Hidden always wins inside the auth area. Several primitives below set an
   explicit `display` (.auth-body, .notice, .spin), which would otherwise
   out-rank the UA `[hidden]` and the app's `.hidden` utility at equal
   specificity + later source order — leaking the skeleton / error / spinner. */
.auth-wrap [hidden],
.auth-wrap .hidden {
  display: none !important;
}

/* ---------------------------------------------------------------------
   2 · BRAND LOCKUP — one mark, one name. The calendar mark is recut onto
   system greens (white strokes) inline in the markup; this only sizes and
   spaces it. Replaces the full-width header wordmark (audit #18).
   --------------------------------------------------------------------- */
.brand-lockup {
  display: flex;
  align-items: center;
  gap: var(--space-2);                /* 8px between mark and name */
  margin-bottom: var(--space-5);      /* 24px down to the card */
}
.brand-mark {
  display: block;
  width: 28px;                        /* mark box — no icon-size token */
  height: 28px;
  flex: none;
}
.brand-name {
  font-size: 17px;                    /* between --fs-h2 (18) and body (15) */
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-h1);
  color: var(--color-text);
}

/* ---------------------------------------------------------------------
   3 · AUTH CARD — retire the green top-accent band + 720px width the app
   gives login cards (styles.css:7662). Plain white panel: one uniform
   hairline + the resting card shadow, 24px padding, full column width.
   Id+class (1,1,0) clears the app's id-only login rules (1,0,0).
   --------------------------------------------------------------------- */
#ownerSignupSection.auth-card,
#universalLoginSection.auth-card,
#firstLoginSection.auth-card {
  width: 100%;
  max-width: 100%;
  margin: 0;
  padding: var(--space-5);            /* 24px */
  border: var(--hairline);            /* uniform 1px hairline; kills the top accent */
  border-radius: var(--r);
  box-shadow: var(--sh-1);
}

/* Card heading — the mockup's 22px h1 step (the app inflates login h2 to
   clamp(28px,3vw,38px); reset it to the token h1). */
#ownerSignupSection.auth-card h2,
#universalLoginSection.auth-card h2,
#firstLoginSection.auth-card h2 {
  margin: 0;
  font-size: var(--fs-h1);
  line-height: var(--lh-h1);
  font-weight: var(--fw-h1);
  letter-spacing: var(--ls-h1);
  color: var(--color-text);
}

/* ---------------------------------------------------------------------
   4 · AUTH BODY — each view is a flex column with even rhythm. The skeleton,
   sign-in form, reset form and first-login form all share this geometry so
   swaps never shift layout.
   --------------------------------------------------------------------- */
.auth-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);                /* 16px between rows */
}

/* Sub-heading hint under the title (first-login / owner-signup) — quiet,
   no rule. The credential RECIPE never appears here (audit #17). */
.auth-intro {
  margin: 0;
  margin-top: calc(-1 * var(--space-2));  /* tuck up under the heading */
  font-size: 13px;
  line-height: 1.5;
  color: var(--color-text-muted);
}

/* ---------------------------------------------------------------------
   5 · FIELD PRIMITIVES — single-column rows with persistent visible
   labels (so the card stays labeled through a password-manager autofill).
   --------------------------------------------------------------------- */
.ffield {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);                /* 4px label→input */
  min-width: 0;
}
.flabel {
  font-size: 12px;                    /* label step — no 12px type token */
  font-weight: var(--fw-semibold);
  line-height: 18px;
  color: var(--color-text-secondary);
}
.flabel-optional {
  font-weight: var(--fw-regular);
  color: var(--color-text-muted);
}

/* Password label row: label left, quiet "Forgot password?" link right. */
.flabel-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  min-height: 18px;
}

/* The auth card's inputs sit at the canonical 36px form height (the app's
   field skin already supplies border / focus / hover / 44px touch floor). */
.auth-card .input {
  width: 100%;
  min-height: var(--ctl-h);
}

/* Quiet inline link — the demoted "Forgot password?" / "Back to sign in".
   An invisible extended hit area keeps it tappable without layout cost. */
.quiet-link {
  font-size: 12px;
  font-weight: var(--fw-semibold);
  line-height: 18px;
  position: relative;
  white-space: nowrap;
}
.quiet-link::after {
  content: "";
  position: absolute;
  inset: -10px -8px;
}

/* ---------------------------------------------------------------------
   6 · SUBMIT — one full-width primary action. The green fill / hover /
   active / disabled come from the app's <button class="primary"> system
   (category 02); this only owns the auth layout (full width, tall touch
   target, centered label + optional spinner).
   --------------------------------------------------------------------- */
.auth-submit {
  width: 100%;
  min-height: var(--tap-min);         /* btn-lg — 44px */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 0 var(--space-4);
}
.auth-submit.is-loading {
  pointer-events: none;               /* guard re-submit without the grey disabled skin */
}

/* Spinner — 14px ring, the label carries the state in words alongside it. */
.spin {
  display: inline-block;
  width: 14px;
  height: 14px;
  flex: none;
  border-radius: var(--r-pill);
  border: 2px solid currentColor;
  border-top-color: transparent;
  opacity: 0.9;
  animation: auth-spin 0.8s linear infinite;
}
@keyframes auth-spin { to { transform: rotate(360deg); } }

/* ---------------------------------------------------------------------
   7 · HELPER + LINK FOOTERS — a hairline-ruled quiet line under the card
   body. The reset view's "Back to sign in" reuses it without the rule.
   --------------------------------------------------------------------- */
.auth-help {
  margin: 0;
  border-top: 1px solid var(--line-faint);
  padding-top: var(--space-3);
  font-size: 12.5px;                  /* quiet helper step */
  line-height: 18px;
  color: var(--color-text-muted);
}
.auth-help-link {
  border-top: none;
  padding-top: 0;
}
/* Skeleton helper holds two text lines without margin-collapse. */
#authSkeleton .auth-help {
  display: flex;
  flex-direction: column;
}

/* ---------------------------------------------------------------------
   8 · NOTICES — in-card danger (failed sign-in) + info (reset sent).
   Scoped to .auth-card so the primitive can't leak onto app surfaces.
   --------------------------------------------------------------------- */
.auth-card .notice {
  display: flex;
  gap: var(--space-2);
  align-items: flex-start;
  padding: var(--space-3) var(--space-3) var(--space-3) var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--surface-panel);
  font-size: 13px;
  line-height: 1.5;
  color: var(--color-text);
}
.auth-card .notice .nic {
  flex: none;
  margin-top: 1px;
  line-height: 0;
}
.auth-card .notice-danger {
  border-left: var(--edge-status) solid var(--color-danger);
  background: var(--paper-danger);
}
.auth-card .notice-danger .nic { color: var(--color-danger); }
.auth-card .notice-info {
  border-left: var(--edge-status) solid var(--dot-changed);
  background: var(--surface-panel);
}
.auth-card .notice-info .nic { color: var(--color-info); }

/* ---------------------------------------------------------------------
   9 · SESSION SKELETON — line dimensions for the auth-shaped skeleton.
   The shimmer base + sweep + reduced-motion freeze come from the shared
   `.sk` primitive (category 12). These add only the auth row heights so
   the skeleton's last frame matches the form's first frame (zero CLS).
   --------------------------------------------------------------------- */
.sk-h1 {
  height: 26px;
  display: flex;
  align-items: center;
}
.sk-input {
  height: var(--ctl-h);
  border-radius: var(--r);
}
.sk-btn {
  height: var(--tap-min);
  border-radius: var(--r);
}
.sk-line {
  display: block;
  height: 11px;
  margin: 3.5px 0;
}

/* ---------------------------------------------------------------------
   10 · FADE — skeleton→form, view swaps and the error notice enter on
   opacity only (motion-spec §4.1). Token-driven, so reduced motion
   collapses the duration via the tokens.css kill-switch.
   --------------------------------------------------------------------- */
.auth-card .fade-in,
.auth-wrap .fade-in {
  animation: auth-fade-in var(--dur-2) var(--ease-out);
}
@keyframes auth-fade-in { from { opacity: 0; } }

/* ---------------------------------------------------------------------
   11 · TOUCH FLOOR — auth inputs rise to 44px under 900px (the app's
   field rules already lift typed inputs; this covers the height we pinned
   to --ctl-h in §5). Reduced-motion freezes the spinner.
   --------------------------------------------------------------------- */
@media (max-width: 900px) {
  .auth-card .input {
    min-height: var(--tap-min);
  }
}
@media (prefers-reduced-motion: reduce) {
  .spin { animation: none; }
}

/* =====================================================================
   SERVICE BAR · Category 20 — Employees screen (manager roster)
   ---------------------------------------------------------------------
   List-first, columned roster (Employee | Roles | Phone | This week | ›)
   with a master-detail side editor panel. Loaded AFTER service-bar.css
   from employees.html so equal-specificity rules here win the cascade.
   Consumes /styles/tokens.css; no hardcoded colors.

   Mirrors the Service Bar mockup (04-mockups/employees/after.html):
   demoted Add/Import to header actions, role chips, formatted phone +
   amber "No phone", per-row weekly load, a Filter popover with per-option
   counts, and a 520px right-side editor (full-screen sheet on phones).
   ===================================================================== */

/* ---------------------------------------------------------------------
   1 · WORKSPACE — roster (flex:1) beside a sticky editor panel
   --------------------------------------------------------------------- */
.emp-workspace {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
}
.emp-roster-card {
  flex: 1;
  min-width: 0;
  margin: 0;
  padding: var(--space-4);
}

/* ---------------------------------------------------------------------
   2 · ROSTER HEADER — title + demoted Add / Import actions
   --------------------------------------------------------------------- */
.emp-roster-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.emp-roster-heading h2 {
  margin: 0;
}
.emp-roster-heading .hint {
  margin-top: 2px;
}
.emp-head-actions {
  display: flex;
  gap: var(--space-2);
  flex: none;
}

/* ---------------------------------------------------------------------
   3 · TOOLBAR — search · Filter button + popover · count line
   --------------------------------------------------------------------- */
.emp-toolbar {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
  flex-wrap: wrap;
}
.emp-search {
  flex: 1;
  min-width: 180px;
  max-width: 420px;
}
.emp-search input {
  width: 100%;
}
.emp-filter-wrap {
  position: relative;
  flex: none;
}
.emp-filter-btn.emp-filter-btn-active {
  border-color: var(--color-primary);
  color: var(--color-primary-text);
  background: var(--color-primary-wash);
}
.emp-countline {
  margin-left: auto;
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--color-text-muted);
  white-space: nowrap;
  font-variant-numeric: var(--fnum-data);
}
.emp-count-num {
  font-variant-numeric: var(--fnum-data);
}
.emp-count-clear,
.emp-fclear {
  border: 0;
  background: none;
  padding: 0;
  margin: 0;
  font-size: var(--fs-caption);
  font-weight: var(--fw-semibold);
  color: var(--color-link);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.emp-count-clear:hover,
.emp-fclear:hover {
  color: var(--color-link-hover);
}

/* filter popover --------------------------------------------------- */
.emp-filter-popover {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: var(--z-dropdown);
  width: 256px;
  max-height: 360px;
  overflow: auto;
  padding: 6px 0;
  background: var(--surface-panel);
  border: var(--hairline-strong);
  border-radius: var(--r);
  box-shadow: var(--sh-2);
}
.emp-filter-popover[hidden] {
  display: none;
}
.emp-fgroup-title {
  padding: 8px 14px 4px;
  font-size: var(--fs-caption);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-caption);
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.emp-fopt {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 7px 14px;
  border: 0;
  background: none;
  font-size: var(--fs-data);
  text-align: left;
  color: var(--color-text);
  cursor: pointer;
  transition: background-color var(--dur-2) var(--ease-out);
}
.emp-fopt:hover {
  background: var(--surface-hover);
}
.emp-fopt:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: calc(-1 * var(--focus-ring-offset));
}
.emp-fbox {
  width: 15px;
  height: 15px;
  flex: none;
  display: grid;
  place-items: center;
  border: 1px solid var(--line-strong);
  border-radius: 4px;
  background: var(--surface-panel);
  color: var(--color-on-primary);
}
.emp-fopt.on .emp-fbox {
  background: var(--color-primary);
  border-color: var(--color-primary);
}
.emp-fopt-label {
  flex: 1;
  min-width: 0;
}
.emp-fcount {
  flex: none;
  font-size: var(--fs-caption);
  color: var(--color-text-muted);
  font-variant-numeric: var(--fnum-data);
}
.emp-fapply {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 14px 4px;
  margin-top: 6px;
  border-top: var(--hairline-faint);
}
.emp-fapply .hint {
  font-size: var(--fs-caption);
}

/* ---------------------------------------------------------------------
   4 · COLUMN HEADER + ROWS — the columned roster grid
   --------------------------------------------------------------------- */
.emp-colhead,
.emp-rows .employee-card.erow {
  display: grid;
  grid-template-columns:
    minmax(150px, 1.6fr) minmax(118px, 1fr) minmax(104px, 150px) 92px 22px;
  gap: 10px;
  align-items: center;
}
.emp-colhead {
  padding: 4px 8px 8px;
  font-size: var(--fs-caption);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-caption);
  text-transform: uppercase;
  color: var(--color-text-muted);
  border-bottom: var(--hairline-strong);
}
.emp-colhead .r {
  text-align: right;
}

.emp-rows {
  display: block;
  margin-top: 0;
}
/* rows are list lines, not stacked cards — strip the card chrome */
.emp-rows .employee-card.erow {
  width: 100%;
  text-align: left;
  padding: 10px 8px;
  min-height: 56px;
  background: var(--surface-panel);
  border: 0;
  border-top: var(--hairline);
  border-radius: 0;
  box-shadow: none;
  cursor: pointer;
  transition: background-color var(--dur-2) var(--ease-out);
}
.emp-rows .employee-card.erow:first-child {
  border-top: 0;
}
.emp-rows .employee-card.erow:hover {
  background: var(--surface-hover);
}
.emp-rows .employee-card.erow:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: calc(-1 * var(--focus-ring-offset));
}
.emp-rows .employee-card.erow.sel {
  background: var(--color-primary-wash);
  box-shadow: inset 2px 0 0 var(--color-primary);
}
.emp-rows .employee-card.erow.erow-history {
  cursor: default;
  grid-template-columns:
    minmax(150px, 1.6fr) minmax(118px, 1fr) minmax(104px, 150px) 92px auto;
}
.emp-rows .employee-card.erow.erow-history:hover {
  background: var(--surface-panel);
}
.emp-rows-empty {
  border-top: 0;
}

/* name cell -------------------------------------------------------- */
.erow-cell {
  min-width: 0;
}
.erow-name {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.erow-nm {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  font-size: var(--fs-data);
  font-weight: var(--fw-semibold);
  color: var(--color-text);
}
.erow-nm-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.erow-sub {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  font-size: var(--fs-caption);
  color: var(--color-text-muted);
}
.erow-sub > :first-child {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.emp-row-nocontact {
  color: var(--status-warning-fg);
  font-weight: var(--fw-semibold);
}
.emp-rowflags {
  display: inline-flex;
  gap: 6px;
  flex: none;
}
.emp-rowflag {
  padding: 1px 7px;
  border-radius: var(--r-pill);
  font-size: 10px;
  font-weight: var(--fw-semibold);
  color: var(--color-text-secondary);
  background: var(--surface-sunken);
  white-space: nowrap;
}
.emp-rowflag-warn {
  color: var(--status-warning-fg);
  background: var(--status-warning-bg);
}

/* roles cell ------------------------------------------------------- */
.erow-roles {
  display: flex;
  gap: 6px;
  min-width: 0;
  overflow: hidden;
}

/* phone cell ------------------------------------------------------- */
.emp-phone {
  font-size: var(--fs-data);
  color: var(--color-text-secondary);
  font-variant-numeric: var(--fnum-data);
  white-space: nowrap;
}
.emp-phone-none {
  font-size: var(--fs-caption);
  font-weight: var(--fw-semibold);
  color: var(--status-warning-fg);
}

/* this-week cell --------------------------------------------------- */
.erow-week {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0;
}
.emp-week-h {
  font-size: var(--fs-data);
  font-weight: var(--fw-semibold);
  color: var(--color-text);
  font-variant-numeric: var(--fnum-data);
}
.emp-week-s {
  font-size: var(--fs-caption);
  color: var(--color-text-muted);
  font-variant-numeric: var(--fnum-data);
}
.emp-week-h.is-light {
  color: var(--color-text-muted);
}
.emp-week-empty {
  color: var(--color-text-disabled);
}

/* chevron + history actions --------------------------------------- */
.erow-chev {
  display: flex;
  justify-content: flex-end;
  color: var(--color-text-disabled);
}
.erow-actions {
  display: flex;
  gap: 6px;
  justify-content: flex-end;
}

/* ---------------------------------------------------------------------
   5 · ROLE CHIPS — fixed role palette (color carried inline as --erc*)
   --------------------------------------------------------------------- */
.emp-rolechip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 22px;
  max-width: 100%;
  padding: 0 10px;
  border-radius: var(--r-pill);
  font-size: 11.5px;
  font-weight: var(--fw-semibold);
  white-space: nowrap;
  background: var(--erc-wash, var(--surface-sunken));
  color: var(--erc-ink, var(--color-text-secondary));
}
.emp-rolechip > span,
.emp-rolechip {
  overflow: hidden;
  text-overflow: ellipsis;
}
.emp-rolechip > i {
  width: 6px;
  height: 6px;
  flex: none;
  border-radius: 50%;
  background: var(--erc, currentColor);
}
.emp-rolechip-more {
  background: var(--surface-sunken);
  color: var(--color-text-secondary);
  border: 1px solid var(--line);
}
.emp-rolechip-none {
  background: var(--status-warning-bg);
  color: var(--status-warning-fg);
}

/* current/upcoming out status — amber pill (row + panel header) */
.emp-outpill {
  display: inline-flex;
  align-items: center;
  flex: none;
  height: 18px;
  padding: 0 8px;
  border-radius: var(--r-pill);
  font-size: 10.5px;
  font-weight: var(--fw-semibold);
  letter-spacing: 0.01em;
  white-space: nowrap;
  color: var(--status-warning-fg);
  background: var(--status-warning-bg);
  font-variant-numeric: var(--fnum-data);
}

/* ---------------------------------------------------------------------
   6 · EDITOR PANEL — sticky 520px master-detail surface
   --------------------------------------------------------------------- */
.emp-editor-panel {
  flex: 0 0 520px;
  align-self: flex-start;
  position: sticky;
  top: var(--space-3);
  max-height: calc(100vh - var(--space-6));
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--surface-panel);
  border: var(--hairline);
  border-radius: var(--r);
  box-shadow: var(--sh-2);
}
.emp-editor-panel[hidden] {
  display: none;
}
.emp-panel-head {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4);
  border-bottom: var(--hairline);
}
.emp-panel-id {
  flex: 1;
  min-width: 0;
}
.emp-panel-name {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin: 0;
  font-size: var(--fs-h1);
  font-weight: var(--fw-display);
  letter-spacing: var(--ls-display);
  color: var(--color-text);
}
.emp-panel-name-text {
  overflow: hidden;
  text-overflow: ellipsis;
}
.emp-panel-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 6px;
  flex-wrap: wrap;
}
.emp-panel-chips {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.emp-panel-hours {
  font-size: var(--fs-caption);
  color: var(--color-text-muted);
  font-variant-numeric: var(--fnum-data);
}
.emp-panel-close {
  width: 32px;
  height: 32px;
  flex: none;
  display: grid;
  place-items: center;
  border: 0;
  background: none;
  border-radius: var(--r-s);
  color: var(--color-text-muted);
  cursor: pointer;
  transition: background-color var(--dur-2) var(--ease-out),
              color var(--dur-2) var(--ease-out);
}
.emp-panel-close:hover {
  background: var(--surface-hover);
  color: var(--color-text);
}
.emp-panel-close:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: var(--focus-ring-offset);
}
.emp-panel-body {
  flex: 1;
  min-height: 0;
  overflow: auto;
  padding: var(--space-3) var(--space-4) var(--space-4);
}
/* the relocated editor reads as one column inside the 520px panel */
.emp-panel-body .employee-editor {
  display: block;
}
.emp-panel-body .employee-edit-split {
  display: block;
}
.emp-panel-body .employee-role-col,
.emp-panel-body .employee-avail-col {
  width: 100%;
}

/* quiet-danger archive (solid red only lives in the confirm dialog) */
.emp-panel-body button.employee-editor-archive,
.emp-panel-body button.warn.employee-editor-archive {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
  color: var(--color-danger-text);
}
.emp-panel-body button.employee-editor-archive:hover,
.emp-panel-body button.warn.employee-editor-archive:hover {
  background: var(--color-danger-subtle);
  color: var(--color-danger);
}
/* the autosave savebar narrates saves — the login-save button only
   appears when there are actual username/password changes to commit */
.emp-panel-body [data-emp-login-save]:disabled {
  display: none;
}

/* dialog hosts are layout-invisible wrappers around fixed modals */
.emp-dialog-host {
  display: contents;
}

/* ---------------------------------------------------------------------
   7 · MOBILE (<=900px) — stacked rows, full-screen editor sheet
   --------------------------------------------------------------------- */
@media (max-width: 900px) {
  .emp-workspace {
    display: block;
  }
  .emp-roster-head {
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-2);
  }
  .emp-head-actions {
    width: 100%;
  }
  .emp-head-actions > button {
    flex: 1;
  }
  .emp-search {
    flex-basis: 100%;
    max-width: none;
  }
  .emp-countline {
    margin-left: 0;
  }
  .emp-colhead {
    display: none;
  }
  .emp-rows .employee-card.erow {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-rows: auto auto;
    row-gap: 4px;
    min-height: 64px;
    padding: 11px 8px;
  }
  .erow-name {
    grid-column: 1;
    grid-row: 1;
  }
  .erow-week {
    grid-column: 2;
    grid-row: 1;
  }
  .erow-roles {
    grid-column: 1;
    grid-row: 2;
  }
  .erow-phone-cell {
    grid-column: 2;
    grid-row: 2;
    justify-self: end;
  }
  .erow-chev {
    display: none;
  }
  .emp-rows .employee-card.erow.erow-history {
    grid-template-columns: minmax(0, 1fr) auto;
  }
  .emp-rows .employee-card.erow.erow-history .erow-actions {
    grid-column: 1 / -1;
    grid-row: 3;
    justify-content: flex-start;
  }
  .emp-filter-popover {
    width: min(280px, calc(100vw - 32px));
  }
  .emp-editor-panel:not([hidden]) {
    position: fixed;
    inset: 0;
    z-index: var(--z-dialog);
    max-height: none;
    border: 0;
    border-radius: 0;
    box-shadow: none;
  }
  body.emp-panel-open {
    overflow: hidden;
  }
}

/* =====================================================================
   Service Bar re-skin · Category 21 — EMPLOYEE PORTAL HOME + tab shell.
   ---------------------------------------------------------------------
   Screen CSS for the redesigned employee portal (public/employee.html +
   renderDashboardHome() in public/employee.js). Loaded AFTER
   service-bar.css via its own <link>, so equal-specificity later rules
   win the cascade. Every value consumes /styles/tokens.css. No literals
   except the role-chip dot geometry and the hatch angle.

   Mockup: design/ui-rethink-2026-06/04-mockups/employee-home/after.html
   Structure: a sparse single-question Home (next-shift hero → this-week
   7-tile strip → one amber "Needs your answer" notice) sitting on four
   REAL tab views (Home / Schedule / Requests / Profile), phone-first
   with a centered column on desktop.
   ===================================================================== */

/* ---------------------------------------------------------------------
   0 · Tabular numerals helper + real tab-view visibility.
   --------------------------------------------------------------------- */
.employee-view { display: grid; gap: var(--space-4); }
.employee-view[hidden] { display: none; }

/* ---------------------------------------------------------------------
   1 · APP BAR — slim sticky bar: venue/brand left, today's date right.
   Overrides the tall gradient header for the employee portal only.
   --------------------------------------------------------------------- */
.emp-appbar {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  padding: 0 var(--space-4);
  min-height: 52px;
  background: var(--surface-page);
  border-bottom: var(--hairline);
}
.emp-appbar-row {
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  min-height: 52px;
  flex-wrap: nowrap;
}
.emp-appbar .brand-block {
  min-height: 0;
  align-items: center;
  gap: var(--space-2);
}
.emp-appbar .brand-logo {
  max-height: 30px;
  height: 30px;
}
.emp-venue-name {
  font-size: 16px;
  font-weight: var(--fw-semibold);
  letter-spacing: -0.01em;
  color: var(--color-text);
}
.emp-venue-name[hidden] { display: none; }
/* When the tenant carries a venue name, show it as text and drop the logo. */
body.emp-has-venue .emp-appbar .brand-logo { display: none; }
.emp-today {
  font-size: 12.5px;
  color: var(--color-text-muted);
  font-variant-numeric: var(--fnum-data);
  white-space: nowrap;
}

/* ---------------------------------------------------------------------
   2 · PORTAL COLUMN — phone-first, centered column on desktop, clear of
   the fixed bottom tab bar.
   --------------------------------------------------------------------- */
.employee-portal {
  max-width: 520px;
  margin: 0 auto;
  gap: var(--space-4);
}
body.emp-portal-active main {
  padding-bottom: calc(62px + var(--space-5) + env(safe-area-inset-bottom, 0px));
}

/* Tabs are the portal's primary nav in BOTH phone and desktop layouts. */
body.emp-portal-active .mobile-bottom-tab-bar { display: block; }
body.emp-portal-active .mobile-bottom-tab-bar-inner {
  max-width: 520px;
  margin: 0 auto;
}

/* ---------------------------------------------------------------------
   3 · HOME — section eyebrows.
   --------------------------------------------------------------------- */
.emp-home { display: block; }
.emp-eyebrow {
  margin: var(--space-5) 0 var(--space-2);
  font-size: var(--fs-caption);
  font-weight: var(--fw-caption);
  letter-spacing: var(--ls-caption);
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.emp-home > .emp-eyebrow:first-child { margin-top: var(--space-1); }

/* ---------------------------------------------------------------------
   4 · HERO — relative day, display time range, role chip + service, crew.
   --------------------------------------------------------------------- */
.emp-hero {
  padding: var(--space-4);
  min-height: 168px;
}
.emp-hero.emp-hero--empty {
  min-height: 120px;
  display: grid;
  align-content: center;
  gap: var(--space-1);
}
.emp-hero-empty-title { font-size: var(--fs-h2); font-weight: var(--fw-h2); }
.emp-hero-empty-body { font-size: 13px; color: var(--color-text-muted); }
.emp-hero-when {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  flex-wrap: wrap;
}
.emp-hero-rel {
  font-size: 13px;
  font-weight: var(--fw-semibold);
  color: var(--color-primary-text);
}
.emp-hero-date {
  font-size: 13px;
  color: var(--color-text-muted);
  font-variant-numeric: var(--fnum-data);
}
.emp-hero-time {
  margin-top: 2px;
  font-size: var(--fs-display);
  font-weight: var(--fw-display);
  letter-spacing: var(--ls-display);
  line-height: var(--lh-display);
  font-variant-numeric: var(--fnum-data);
  color: var(--color-text);
}
.emp-hero-meta {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: 7px;
  flex-wrap: wrap;
}
.emp-hero-service { font-size: 13px; color: var(--color-text-secondary); }

/* role chip — identity hue from tokens.css §10, never the sole signal. */
.emp-rolechip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 22px;
  padding: 0 10px;
  border-radius: var(--r-pill);
  font-size: 11.5px;
  font-weight: var(--fw-semibold);
  background: var(--rcw, var(--surface-sunken));
  color: var(--rc, var(--color-text-secondary));
  white-space: nowrap;
}
.emp-rolechip i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--rc, currentColor);
}

/* crew — "On with you": first three bold, "+N more" expander. */
.emp-crew {
  border-top: 1px solid var(--line-soft);
  margin-top: var(--space-3);
  padding-top: var(--space-3);
}
.emp-crew-label {
  margin-bottom: 5px;
  font-size: 11px;
  font-weight: var(--fw-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.emp-crew-names {
  font-size: 13px;
  line-height: 1.55;
  color: var(--color-text-secondary);
}
.emp-crew-names b { font-weight: var(--fw-semibold); color: var(--color-text); }
.emp-crew-solo { color: var(--color-text-muted); }
.emp-crew-more {
  border: 0;
  background: none;
  color: var(--color-link);
  font-size: 13px;
  font-weight: var(--fw-semibold);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
  padding: 4px 2px;
  border-radius: 3px;
  min-height: 0;
  box-shadow: none;
}
.emp-crew-more:hover { color: var(--color-link-hover); background: none; }

/* ---------------------------------------------------------------------
   5 · THIS WEEK — dense 7-column Mon–Sun strip.
   --------------------------------------------------------------------- */
.emp-weekstrip {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
}
.emp-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  min-height: 64px;
  padding: 6px 2px;
  background: var(--surface-panel);
  border: var(--hairline);
  border-radius: var(--r-s);
  cursor: pointer;
  font: inherit;
  box-shadow: none;
  transition: border-color var(--dur-2) var(--ease-out);
}
.emp-tile-day {
  font-size: 10.5px;
  font-weight: var(--fw-semibold);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.emp-tile-val {
  font-size: 11.5px;
  font-weight: var(--fw-semibold);
  font-variant-numeric: var(--fnum-data);
  color: var(--color-text);
}
.emp-tile:hover { border-color: var(--line-hover); }
.emp-tile--on { background: var(--color-primary-wash); border-color: var(--color-primary-accent); }
.emp-tile--on .emp-tile-val { color: var(--color-primary-text); }
.emp-tile--off .emp-tile-val { color: var(--color-text-disabled); font-weight: var(--fw-regular); }
.emp-tile--past .emp-tile-val { color: var(--color-text-disabled); font-weight: var(--fw-regular); }
.emp-tile--closed {
  cursor: default;
  background: var(--surface-sunken);
  background-image: repeating-linear-gradient(45deg, transparent 0 5px, var(--line-mid) 5px 6px);
}
.emp-tile--closed:hover { border-color: var(--line-mid); }
.emp-tile--closed .emp-tile-val { color: var(--color-text-disabled); font-weight: var(--fw-regular); }
.emp-tile--today { box-shadow: inset 0 2px 0 var(--color-primary-accent); }
.emp-tile--today .emp-tile-day { color: var(--color-primary); }

.emp-weeksum {
  margin-top: var(--space-2);
  font-size: 12.5px;
  color: var(--color-text-muted);
  font-variant-numeric: var(--fnum-data);
}

/* ---------------------------------------------------------------------
   6 · NEEDS YOUR ANSWER — amber left-bordered notice + all-clear.
   --------------------------------------------------------------------- */
.emp-notice {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 12px 14px;
  border: var(--hairline);
  border-radius: var(--r);
  background: var(--surface-panel);
  box-shadow: var(--sh-1);
  font-size: 13px;
  line-height: 1.5;
}
.emp-notice + .emp-notice { margin-top: var(--space-2); }
.emp-notice--warn {
  border-left: var(--edge-status) solid var(--dot-warning);
  background: var(--paper-warning);
}
.emp-notice-icon { flex: none; margin-top: 1px; color: var(--dot-warning); }
.emp-notice-body { flex: 1; min-width: 0; }
.emp-notice-body b { font-weight: var(--fw-semibold); }
.emp-notice-act { margin-top: 9px; }
.emp-respond-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: var(--ctl-h-sm);
  padding: 0 12px;
  font-size: 12.5px;
  font-weight: var(--fw-semibold);
  color: var(--color-text);
  background: var(--surface-panel);
  border: 1px solid var(--line-strong);
  border-radius: var(--r);
  cursor: pointer;
  box-shadow: none;
}
.emp-respond-btn:hover { background: var(--surface-hover); border-color: var(--line-hover); }
.emp-allclear {
  padding: var(--space-4);
  text-align: center;
  font-size: 13px;
  color: var(--color-text-muted);
}

/* ---------------------------------------------------------------------
   7 · PROFILE — demoted Log out (quiet ghost at the end of the view).
   --------------------------------------------------------------------- */
.emp-logout-wrap {
  margin-top: var(--space-3);
  display: flex;
  justify-content: center;
}
.emp-logout-btn {
  background: transparent;
  border: 1px solid var(--line-mid);
  color: var(--color-text-secondary);
  box-shadow: none;
}
.emp-logout-btn:hover {
  background: var(--surface-sunken);
  color: var(--color-text);
}

/* ---------------------------------------------------------------------
   8 · Touch floor on phones — tiles and crew expander stay tappable.
   --------------------------------------------------------------------- */
@media (max-width: 900px) {
  .emp-tile { min-height: 66px; }
}

/* ===== Configuration — Service Bar structural deltas ===== */
/* Implements the headline structural moves from the Service Bar mockup
   (design/ui-rethink-2026-06/04-mockups/configuration/after.html):
     #1 off-feature value pane · #2 collapsible+counted rail groups ·
     #3 full-width rail toggle block · #4 actionable amber chip ·
     #5 unitized Schedule Limits cards · #6 neutral off pill ·
     #7 mobile section-index sheet · #8 sticky mobile savebar.
   All selectors consume var(--…) tokens and load after styles.css so the
   equal-specificity overrides win on the cascade. */

/* --- #4 · Actionable top-bar chip (deep-links to Messaging) --------- */
.manager-status-pill--action {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  cursor: pointer;
  font: inherit;
  font-size: var(--fs-caption);
  font-weight: var(--fw-semibold);
  transition:
    border-color var(--dur-2) var(--ease-out),
    background var(--dur-2) var(--ease-out),
    transform var(--dur-2) var(--ease-out);
}
.manager-status-pill--action::before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.75;
}
.manager-status-pill--action:hover {
  border-color: var(--status-warning-fg);
}
.manager-status-pill--action:active {
  transform: translateY(1px);
}
.manager-status-pill--action:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: var(--focus-ring-offset);
}

/* --- #2 · Rail: collapsible, counted group headers ------------------ */
.configuration-feature-list {
  padding: 0;
  overflow: hidden;
}
.configuration-feature-group + .configuration-feature-group {
  margin-top: 0;
  border-top: 1px solid var(--line);
}
.configuration-group-toggle {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  padding: 10px 14px;
  border: 0;
  background: var(--surface-band);
  text-align: left;
  cursor: pointer;
  transition: background var(--dur-2) var(--ease-out);
}
.configuration-group-toggle:hover {
  background: var(--well);
}
.configuration-group-toggle:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: -2px;
}
.configuration-group-name {
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  font-weight: var(--fw-caption);
  letter-spacing: var(--ls-caption);
  text-transform: uppercase;
  color: var(--color-text-secondary);
}
.configuration-group-meta {
  margin-left: auto;
  font-size: 11px;
  color: var(--color-text-muted);
  font-variant-numeric: var(--fnum-data);
}
.configuration-group-chevron {
  display: inline-flex;
  color: var(--color-text-muted);
  transition: transform var(--dur-2) var(--ease-out);
}
.configuration-feature-group.is-collapsed .configuration-group-chevron {
  transform: rotate(-90deg);
}
.configuration-feature-group.is-collapsed .configuration-feature-group-body {
  display: none;
}

/* --- #3 · Rail row stacks; the On/Off toggle becomes a full-width block
       below title + description (kills the ~90px description squeeze) --- */
.configuration-feature-row {
  display: block;
  grid-template-columns: none;
  border: 0;
  border-top: 1px solid var(--line-faint);
  border-radius: 0;
  padding: 9px 14px 10px;
}
.configuration-feature-row.is-active {
  border-color: transparent;
  border-top-color: var(--line-faint);
  background: var(--wash);
  box-shadow: inset 2px 0 0 var(--color-primary);
}
.configuration-feature-link {
  display: block;
  width: 100%;
  padding: 0;
  border-radius: var(--r-xs);
}
.configuration-feature-row.is-active .configuration-feature-title {
  color: var(--color-primary-text, var(--color-primary));
}
.configuration-feature-desc {
  display: block;
  margin-top: 1px;
}
.configuration-feature-switch.state-checkbox {
  display: flex;
  justify-self: stretch;
  width: 100%;
  margin-top: 8px;
}
.configuration-feature-switch .state-checkbox__button {
  width: 100%;
  min-width: 0;
  min-height: 32px;
  justify-content: flex-start;
}
.configuration-feature-badge {
  margin-top: 8px;
}

/* --- #1 · Off-feature value pane (replaces the blank pane) ---------- */
.configuration-off-pane {
  background: var(--well);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 18px 20px;
}
.configuration-off-pane-title {
  margin: 0 0 4px;
  font-size: 14.5px;
  font-weight: var(--fw-semibold);
  color: var(--color-text);
}
.configuration-off-pane-lead {
  margin: 0;
  max-width: 560px;
  font-size: 13.5px;
  color: var(--color-text-secondary);
}
.configuration-off-pane-list {
  list-style: none;
  margin: 12px 0 16px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.configuration-off-pane-list li {
  position: relative;
  padding-left: 16px;
  max-width: 560px;
  font-size: 13px;
  color: var(--color-text-secondary);
}
.configuration-off-pane-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 8px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--color-primary);
}
.configuration-off-pane-actions {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}
.configuration-off-pane-turn-on {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 36px;
  padding: 0 16px;
  border: 1px solid transparent;
  border-radius: var(--r);
  background: var(--color-primary);
  color: var(--color-on-primary);
  font: inherit;
  font-size: 13px;
  font-weight: var(--fw-semibold);
  cursor: pointer;
  transition: background var(--dur-2) var(--ease-out), transform var(--dur-2) var(--ease-out);
}
.configuration-off-pane-turn-on:hover {
  background: var(--color-primary-hover);
}
.configuration-off-pane-turn-on:active {
  transform: translateY(1px);
}
.configuration-off-pane-turn-on:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: var(--focus-ring-offset);
}
.configuration-off-pane-help {
  font-size: 12.5px;
  color: var(--color-link);
  cursor: pointer;
}

/* --- #5 · Schedule Limits cards: title once, unitized input, meta line --- */
.configuration-limit-title {
  display: block;
  margin-bottom: 9px;
  font-size: 13px;
  font-weight: var(--fw-semibold);
  color: var(--color-text);
}
.configuration-limit-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.configuration-limit-input.igroup {
  position: relative;
  display: flex;
  align-items: stretch;
  width: 128px;
  flex: none;
}
.configuration-limit-input input {
  flex: 1;
  min-width: 0;
  height: var(--ctl-h, 34px);
  padding: 0 11px;
  font: inherit;
  font-size: 13.5px;
  font-variant-numeric: var(--fnum-data);
  color: var(--color-text);
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: var(--r);
}
.configuration-limit-input input:hover {
  border-color: var(--line-hover);
}
.configuration-limit-input input:focus {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: 1px;
  border-color: var(--color-primary);
}
.configuration-limit-input.unitized input {
  border-radius: var(--r) 0 0 var(--r);
}
.configuration-limit-unit {
  display: flex;
  align-items: center;
  padding: 0 11px;
  font-size: 13px;
  color: var(--color-text-muted);
  background: var(--well);
  border: 1px solid var(--line-2);
  border-left: 0;
  border-radius: 0 var(--r) var(--r) 0;
}
.configuration-limit-meta {
  margin-top: 8px;
  font-size: 11.5px;
  color: var(--color-text-muted);
}

/* --- #7 · Mobile section-index trigger (hidden on desktop) ---------- */
.configuration-section-index {
  display: none;
  width: 100%;
  align-items: center;
  gap: 10px;
  min-height: 48px;
  padding: 9px 14px;
  text-align: left;
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: var(--r);
  box-shadow: var(--sh-1);
  cursor: pointer;
  transition: background var(--dur-2) var(--ease-out), border-color var(--dur-2) var(--ease-out);
}
.configuration-section-index:active {
  background: var(--well);
}
.configuration-section-index-icon {
  display: inline-flex;
  color: var(--color-text-muted);
  flex: none;
}
.configuration-section-index-stack {
  flex: 1;
  min-width: 0;
}
.configuration-section-index-eyebrow {
  display: block;
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  font-weight: var(--fw-caption);
  letter-spacing: var(--ls-caption);
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.configuration-section-index-current {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 1px;
  font-size: 14px;
  font-weight: var(--fw-semibold);
  color: var(--color-text);
}
.configuration-section-index-word {
  flex: none;
}
.configuration-section-index-chevron {
  display: inline-flex;
  color: var(--color-text-muted);
  flex: none;
}

/* --- #7 · Mobile section-index bottom sheet ------------------------- */
.configuration-sheet-scrim {
  position: fixed;
  inset: 0;
  background: var(--scrim);
  z-index: var(--z-scrim);
}
.configuration-sheet {
  position: fixed;
  left: 8px;
  right: 8px;
  bottom: 8px;
  max-height: 72vh;
  overflow: auto;
  z-index: var(--z-dialog);
  background: var(--surface-raised);
  border-radius: var(--r);
  box-shadow: var(--sh-2);
  padding: 6px 0 10px;
}
.configuration-sheet-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 16px 6px;
}
.configuration-sheet-title {
  font-size: 13px;
  font-weight: var(--fw-semibold);
  color: var(--color-text);
}
.configuration-sheet-close {
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border: 0;
  background: none;
  color: var(--color-text-muted);
  cursor: pointer;
  border-radius: var(--r-s);
}
.configuration-sheet-close:hover {
  background: var(--well);
  color: var(--color-text);
}
.configuration-sheet-group {
  padding: 12px 16px 4px;
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  font-weight: var(--fw-caption);
  letter-spacing: var(--ls-caption);
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.configuration-sheet-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 44px;
  padding: 8px 16px;
  border: 0;
  background: none;
  font: inherit;
  font-size: 14px;
  text-align: left;
  color: var(--color-text);
  cursor: pointer;
  transition: background var(--dur-2) var(--ease-out);
}
.configuration-sheet-row:hover {
  background: var(--well);
}
.configuration-sheet-row.is-active {
  background: var(--wash);
  box-shadow: inset 2px 0 0 var(--color-primary);
  font-weight: var(--fw-semibold);
  color: var(--color-primary-text, var(--color-primary));
}
.configuration-sheet-row-label {
  flex: 1;
  min-width: 0;
}
.configuration-sheet-word {
  margin-left: auto;
  font-size: 12px;
  font-weight: var(--fw-semibold);
  color: var(--color-text-muted);
}
.configuration-sheet-word.is-on {
  color: var(--color-primary-text, var(--color-primary));
}

/* --- Responsive: pane-first phone order (#7) + sticky savebar (#8) --- */
@media (max-width: 900px) {
  .configuration-hub-layout {
    grid-template-columns: minmax(0, 1fr);
  }
  .configuration-feature-list {
    display: none;
  }
  .configuration-section-index {
    display: flex;
  }
  .configuration-limit-row {
    flex-wrap: wrap;
  }
  .configuration-limit-input.igroup {
    width: 140px;
  }
  .configuration-limit-input input {
    height: var(--tap-min);
  }
  .configuration-off-pane-turn-on {
    height: var(--tap-min);
  }
  .configuration-sheet-row {
    min-height: var(--tap-min);
  }
}

/* #8 · Keep the configuration savebar sticky on phones (was position:static,
   which parked Saved/Saving/Undo at the bottom of a long page). */
body.manager-workspace.ui-mobile .configuration-page-savebar,
body.manager-workspace.has-manager-mobile-tab-bar .configuration-page-savebar {
  position: sticky;
  bottom: calc(84px + env(safe-area-inset-bottom, 0px));
  z-index: var(--z-savebar);
}

/* =====================================================================
   Approvals — Service Bar structural deltas
   ---------------------------------------------------------------------
   Reorganizes the Request Inbox around ONE "Waiting on you" decision
   queue (mixed time-off + trade KIND-eyebrow cards, amber count) plus an
   on-screen "Recently decided" trail. One primary action per card,
   coverage cost as a conditional one-line amber notice, real tabs in
   place of the blue hyperlink sub-nav, and an "Assign time off" header
   dialog. Consumes tokens.css names only. (Mockup:
   04-mockups/approvals/after-desktop.png / after-mobile.png / after.html)
   ===================================================================== */

/* --- header affordances row (autosave + Assign time off) --- */
.approvals-head {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.autosave-indicator {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: 12.5px;
  color: var(--color-text-muted);
  white-space: nowrap;
}
.autosave-indicator-icon {
  display: inline-flex;
  color: var(--color-primary);
  font-weight: 700;
}

/* --- real tabs (replace blue hyperlink sub-nav) --- */
.sb-tabs {
  display: flex;
  gap: 2px;
  margin-bottom: var(--space-4);
  border-bottom: 1px solid var(--line);
  overflow-x: auto;
}
.sb-tab {
  position: relative;
  display: inline-flex;
  align-items: center;
  height: 36px;
  padding: 0 13px;
  border: 0;
  background: none;
  box-shadow: none;
  font-size: 13px;
  font-weight: var(--fw-semibold);
  color: var(--ink-3);
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
  border-radius: var(--r-s) var(--r-s) 0 0;
}
.sb-tab:hover {
  color: var(--ink);
  background: var(--well);
  text-decoration: none;
  transform: none;
  box-shadow: none;
}
.sb-tab[aria-selected="true"] {
  color: var(--ink);
}
.sb-tab[aria-selected="true"]::after {
  content: "";
  position: absolute;
  left: 8px;
  right: 8px;
  bottom: 0;
  height: 2px;
  border-radius: 2px;
  background: var(--green);
}
.sb-tab:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: -2px;
}

/* --- sections + amber count --- */
.approvals-section + .approvals-section {
  margin-top: var(--space-5);
}
.approvals-sechead {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  margin: 0 0 var(--space-2);
}
.approvals-sechead h2 {
  margin: 0;
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  letter-spacing: var(--ls-caption);
  text-transform: uppercase;
  font-weight: var(--fw-caption);
  color: var(--ink-3);
}
.approvals-count {
  display: inline-flex;
  align-items: center;
  height: 16px;
  padding: 0 6px;
  border-radius: var(--r-pill);
  background: var(--amber-tint);
  color: var(--amber-ink);
  font-size: 10.5px;
  font-weight: var(--fw-semibold);
  font-variant-numeric: var(--fnum-data);
}
.approvals-count.is-zero {
  display: none;
}
.approvals-count--muted {
  background: var(--well);
  color: var(--color-text-muted);
}

/* --- request card (KIND eyebrow · name·date · reason+submitted) --- */
.reqcard {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "head acts"
    "who  acts"
    "meta acts"
    "extra extra";
  gap: 2px var(--space-4);
  align-items: start;
  background: var(--surface);
  border: var(--hairline);
  border-radius: var(--r);
  box-shadow: var(--sh-1);
  padding: 14px 16px;
  margin-bottom: var(--space-3);
}
.reqcard:last-child {
  margin-bottom: 0;
}
.rc-head {
  grid-area: head;
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.rc-kind {
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  letter-spacing: var(--ls-caption);
  text-transform: uppercase;
  font-weight: var(--fw-caption);
  color: var(--ink-3);
}
.rc-who {
  grid-area: who;
  margin-top: 2px;
  font-size: 15px;
  font-weight: var(--fw-semibold);
  color: var(--ink);
}
.rc-who .rc-range {
  font-weight: var(--fw-semibold);
  font-variant-numeric: var(--fnum-data);
}
.rc-sep {
  padding: 0 5px;
  color: var(--ink-dis);
  font-weight: var(--fw-regular);
}
.rc-meta {
  grid-area: meta;
  margin-top: 1px;
  font-size: 12.5px;
  color: var(--ink-3);
}
.rc-acts {
  grid-area: acts;
  display: flex;
  gap: var(--space-2);
  align-self: center;
}
.rc-extra {
  grid-area: extra;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: 10px;
}
.rc-extra:empty {
  display: none;
}
.rc-secondary-acts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* --- one primary per card: Approve (solid) + quiet-destructive Deny --- */
.reqcard .rc-acts .sb-approve,
.reqcard .rc-acts .sb-deny {
  min-height: var(--ctl-h-sm);
  padding: 0 16px;
  font-size: 13px;
}
.sb-approve {
  background: var(--color-primary);
  color: var(--color-on-primary);
}
.sb-approve:hover:not(:disabled) {
  background: var(--color-primary-hover);
}
button.sb-deny {
  color: var(--color-danger-text);
}
button.sb-deny:hover:not(:disabled) {
  background: var(--color-danger-subtle);
  border-color: var(--color-danger);
  color: var(--color-danger-text);
}
button.sb-deny:focus-visible {
  outline-color: var(--focus-danger);
}

/* --- conditional coverage notice (amber one-line + View [Day] jump) --- */
.reqcard-notice {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 9px 12px;
  border: 1px solid var(--line);
  border-left: var(--edge-status) solid var(--amber-dot);
  border-radius: var(--r);
  background: var(--paper-warning);
  font-size: 13px;
  line-height: 1.5;
}
.reqcard-notice-icon {
  flex: none;
  margin-top: 1px;
  color: var(--amber-dot);
  font-weight: 700;
}
.reqcard-notice-text {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--color-text);
}
.reqcard-notice-text b {
  font-weight: var(--fw-semibold);
}
.reqcard-notice-act {
  flex: none;
  margin-left: auto;
}
button.sb-notice-jump {
  padding: 0 2px;
  background: transparent;
  border: 0;
  box-shadow: none;
  color: var(--color-link);
  font-size: 13px;
  font-weight: var(--fw-semibold);
  white-space: nowrap;
  text-decoration: none;
}
button.sb-notice-jump:hover {
  color: var(--color-link-hover);
  text-decoration: underline;
  transform: none;
  box-shadow: none;
}

/* --- queue states: all-clear, swipe hint, empty --- */
.approvals-allclear {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 13px 16px;
  background: var(--surface);
  border: var(--hairline);
  border-radius: var(--r);
  box-shadow: var(--sh-1);
  font-size: 13.5px;
  color: var(--color-text-secondary);
}
.approvals-allclear-icon {
  color: var(--color-primary);
  font-weight: 700;
}
.approvals-swipe-hint {
  display: none;
  margin: 0;
  padding: var(--space-2) 2px 0;
  font-size: 11px;
  color: var(--ink-3);
}
.approvals-empty {
  padding: 26px 20px;
  text-align: center;
  background: var(--surface);
  border: var(--hairline);
  border-radius: var(--r);
  box-shadow: var(--sh-1);
}
.approvals-empty h3 {
  margin: 0 0 var(--space-1);
  font-size: 15px;
  font-weight: var(--fw-semibold);
  color: var(--color-text);
}
.approvals-empty p {
  max-width: 380px;
  margin: 0 auto var(--space-3);
  font-size: 13px;
  color: var(--ink-3);
}

/* --- recently decided trail (compact history rows) --- */
.approvals-history {
  border: var(--hairline);
  border-radius: var(--r);
  background: var(--surface);
  box-shadow: var(--sh-1);
  overflow: hidden;
}
.approvals-hrow {
  display: grid;
  grid-template-columns: 96px minmax(0, 1.4fr) minmax(0, 1.2fr) 150px 90px;
  gap: var(--space-3);
  align-items: center;
  padding: 10px 16px;
  border-top: var(--hairline-faint);
  font-size: 13px;
}
.approvals-hrow:first-child {
  border-top: 0;
}
.approvals-hrow > span {
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.approvals-hrow-kind {
  font-size: 12px;
  color: var(--ink-3);
}
.approvals-hrow-who {
  font-weight: var(--fw-semibold);
}
.approvals-hrow-when {
  color: var(--ink-2);
}
.approvals-hrow-sub {
  font-size: 12.5px;
  color: var(--ink-3);
}
.approvals-hrow-pill {
  justify-self: end;
}

/* --- pending pill maps to amber (was neutral status-open) --- */
.status-pill.status-pending {
  background: var(--status-warning-bg);
  color: var(--status-warning-fg);
  border-color: transparent;
}

/* --- assign time off dialog --- */
.assign-timeoff-card {
  width: min(440px, 100%);
}

/* --- phone: stacked full-width actions (Approve heavier) + swipe hint --- */
@media (max-width: 900px) {
  .approvals-head {
    flex-wrap: wrap;
  }
  .reqcard {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "head"
      "who"
      "meta"
      "extra"
      "acts";
    padding: 14px;
  }
  .rc-acts {
    align-self: stretch;
    margin-top: var(--space-3);
  }
  .rc-acts .sb-deny,
  .rc-acts .sb-approve {
    flex: 1;
    min-height: var(--tap-min);
  }
  .rc-acts .sb-approve {
    flex: 1.5;
  }
  .approvals-swipe-hint {
    display: block;
  }
  .approvals-hrow {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "who pill"
      "when pill"
      "sub pill";
    gap: 1px var(--space-3);
    padding: 12px 14px;
  }
  .approvals-hrow-kind {
    display: none;
  }
  .approvals-hrow-who { grid-area: who; }
  .approvals-hrow-when { grid-area: when; }
  .approvals-hrow-sub { grid-area: sub; }
  .approvals-hrow-pill {
    grid-area: pill;
    align-self: center;
  }
}

/* ===== Template — Service Bar structural deltas ===== */
/* Layout/markup moves the token re-skin alone could not deliver: a sticky top toolbar with
   docked autosave, scannable per-day / per-role / week totals, one quiet empty row per role,
   a single quiet Closed column, chip remove affordance + click-to-open action menu, an
   edit-times dialog, and a Mon–Sun day switcher for phones. Consumes tokens only. */

/* 1 · STICKY TOP TOOLBAR (filter · fill · ghost clear · spacer · docked savebar) */
.template-toolbar {
  position: sticky;
  top: 0;
  z-index: var(--z-savebar);
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-3);
  padding: 9px 0;
  background: var(--paper);
  border-bottom: var(--hairline);
}
.template-toolbar-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  min-width: 0;
}
.template-toolbar-spacer { flex: 1 1 auto; }
.template-toolbar .template-advanced-filters,
.template-toolbar .schedule-filter-toolbar { margin: 0; }
/* Clear template demoted to a ghost button. */
.tmpl-clear-btn.secondary {
  background: transparent;
  border-color: transparent;
  color: var(--ink-3);
  box-shadow: none;
}
.tmpl-clear-btn.secondary:hover {
  background: var(--well);
  border-color: transparent;
  color: var(--ink);
}
/* Autosave docks inline at the toolbar's right edge — it never scrolls away (was sticky-bottom). */
.template-toolbar .template-savebar {
  position: static;
  bottom: auto;
  margin-top: 0;
  flex: 0 0 auto;
  min-width: 0;
}

/* 2/3/4 · MATRIX — totals, role column, footer */
.template-matrix-wrap { margin-top: var(--space-3); }
.template-matrix { font-size: 12px; }
.template-matrix thead th {
  border: 0;
  border-bottom: 1px solid var(--line-2);
  border-left: 1px solid var(--col-faint);
  padding: 8px 10px 7px;
  text-align: left;
  vertical-align: top;
  background: var(--surface);
  text-transform: none;
  font-weight: var(--fw-semibold);
}
.template-matrix thead th:first-child { border-left: 0; }
.tmpl-day-name,
.tmpl-th-role {
  display: block;
  font-size: var(--fs-caption);
  font-weight: var(--fw-caption);
  letter-spacing: var(--ls-caption);
  text-transform: uppercase;
  color: var(--ink-2);
}
.tmpl-day-total,
.tmpl-th-sub {
  display: block;
  margin-top: 1px;
  font-size: 11px;
  font-weight: var(--fw-regular);
  text-transform: none;
  letter-spacing: 0;
  color: var(--ink-3);
}
.template-matrix thead th.tmpl-day-closed { background: var(--well); }
.template-matrix thead th.tmpl-day-closed .tmpl-day-name { color: var(--ink-dis); }
.tmpl-closed-badge {
  display: inline-flex;
  align-items: center;
  height: 16px;
  padding: 0 6px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-pill);
  background: var(--well);
  color: var(--ink-3);
  font-size: 10.5px;
  font-weight: var(--fw-semibold);
  text-transform: none;
  letter-spacing: 0;
}
.template-matrix .tmpl-role {
  border: 0;
  border-top: 1px solid var(--line-faint);
  padding: 9px 10px;
  vertical-align: top;
  background: var(--surface);
}
.tmpl-role-name {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 13px;
  font-weight: var(--fw-semibold);
  text-transform: none;
  color: var(--ink);
}
.tmpl-role-swatch {
  width: 8px;
  height: 8px;
  flex: none;
  border-radius: 2px;
  background: var(--rc, var(--line-2));
}
.tmpl-role-total {
  display: block;
  margin-top: 2px;
  padding-left: 15px;
  font-size: 11px;
  font-weight: var(--fw-regular);
  color: var(--ink-3);
}
.tmpl-role-service {
  display: block;
  margin-top: 2px;
  padding-left: 15px;
  font-size: 10.5px;
  color: var(--ink-3);
}
.template-matrix .tmpl-cell {
  border: 0;
  border-top: 1px solid var(--line-faint);
  border-left: 1px solid var(--col-faint);
  padding: 6px;
  min-height: 56px;
  vertical-align: top;
  background: var(--surface);
}
.template-matrix .tmpl-cell:first-child { border-left: 0; }
/* 10 · Closed day = one quiet dimmed column (no per-cell pill or repeated sentence). */
.template-matrix .tmpl-cell.is-closed {
  background: var(--well);
  border-left-color: transparent;
}
/* 5 · One quiet empty row per role. */
.template-matrix .tmpl-empty-row {
  padding: 10px 14px;
  color: var(--ink-3);
}
.tmpl-empty-msg {
  font-size: 12.5px;
  color: var(--ink-3);
  margin-right: 10px;
}
.template-matrix tfoot .tmpl-foot-cell {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
  border: 0;
  border-top: 1px solid var(--line);
  padding: 8px 14px;
  background: var(--surface-band);
}
.tmpl-foot-total {
  font-size: 12px;
  font-weight: var(--fw-semibold);
  color: var(--ink-2);
}
.tmpl-foot-note {
  font-size: 12px;
  color: var(--ink-3);
}

/* quiet add control — hover/focus revealed; doubles as Paste while clipboard is armed */
.tmpl-addshift {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  height: 24px;
  padding: 0 8px;
  border: 1px dashed transparent;
  border-radius: var(--r-s);
  background: none;
  color: transparent;
  font-size: 11px;
  font-weight: var(--fw-semibold);
  cursor: pointer;
  transition:
    color var(--dur-2) var(--ease-out),
    border-color var(--dur-2) var(--ease-out),
    background-color var(--dur-2) var(--ease-out);
}
.tmpl-addshift .tmpl-ic {
  opacity: 0;
  transition: opacity var(--dur-2) var(--ease-out);
}
.tmpl-cell:hover .tmpl-addshift,
.tmpl-addshift:focus-visible { color: var(--ink-3); border-color: var(--line-2); }
.tmpl-cell:hover .tmpl-addshift .tmpl-ic,
.tmpl-addshift:focus-visible .tmpl-ic { opacity: 1; }
.tmpl-addshift:hover { color: var(--green-ink); border-color: var(--green-bar); background: var(--wash); }
.tmpl-addshift:focus-visible { outline: var(--focus-ring-w) solid var(--focus); outline-offset: 1px; }
.tmpl-addshift.is-paste { color: var(--green-ink); border-color: var(--green-bar); }
.tmpl-addshift.is-paste .tmpl-ic { opacity: 1; }
.tmpl-empty-row .tmpl-addshift { color: var(--ink-3); border-color: var(--line-2); }
.tmpl-empty-row .tmpl-addshift .tmpl-ic { opacity: 1; }

/* 6/11 · CHIP — sibling remove "x", 4px role edge, time-first then Service · Role */
.tmpl-chipwrap { position: relative; margin: 0 0 5px; }
.tmpl-chipwrap:last-child { margin-bottom: 0; }
.template-matrix .tmpl-shift-chip,
.tmpl-mchips .tmpl-shift-chip {
  position: relative;
  margin: 0;
  padding: 5px 9px 6px 11px;
  overflow: hidden;
}
.tmpl-shift-chip::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 4px;
  border-radius: 5px 0 0 5px;
  background: var(--rc, transparent);
}
.tmpl-chip-meta-line {
  display: block;
  margin-top: 1px;
  font-size: 10.5px;
  color: var(--ink-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tmpl-chip-x {
  position: absolute;
  top: 3px;
  right: 3px;
  width: 20px;
  height: 20px;
  display: grid;
  place-items: center;
  padding: 0;
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: var(--r-xs);
  color: var(--ink-3);
  cursor: pointer;
  opacity: 0;
  transition:
    opacity var(--dur-2) var(--ease-out),
    color var(--dur-2) var(--ease-out),
    border-color var(--dur-2) var(--ease-out),
    background-color var(--dur-2) var(--ease-out);
}
.tmpl-chipwrap:hover .tmpl-chip-x,
.tmpl-chipwrap:focus-within .tmpl-chip-x { opacity: 1; }
.tmpl-chip-x:hover { color: var(--red); border-color: var(--red); background: var(--red-tint); }
.tmpl-chip-x:focus-visible {
  opacity: 1;
  outline: var(--focus-ring-w) solid var(--focus-danger);
  outline-offset: 1px;
}
@media (hover: none) { .tmpl-chip-x { display: none; } } /* touch removes via the action sheet */

/* 7 · action menu danger verb */
.chip-context-item.is-danger { color: var(--red-ink); }
.chip-context-item.is-danger:hover { background: var(--red-tint); }

/* 8 · edit-times dialog */
.tmpl-time-fields {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-top: 12px;
}
.tmpl-time-field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.tmpl-time-field span { font-size: 12px; font-weight: var(--fw-semibold); color: var(--ink-2); }
.tmpl-time-field input {
  height: var(--ctl-h);
  width: 100%;
  padding: 0 11px;
  font-family: inherit;
  font-size: 13.5px;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line-2);
  border-radius: var(--r);
}
.tmpl-time-field input:focus {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: 1px;
  border-color: var(--green);
}
.tmpl-time-error { margin-top: 10px; font-size: 12px; color: var(--red-ink); }
.tmpl-time-error[hidden] { display: none; }

/* 9 · MOBILE day-at-a-time — hidden on desktop */
.template-mobile { display: none; }
.tmpl-dayseg {
  position: sticky;
  top: 0;
  z-index: var(--z-savebar);
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
  padding: 3px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--sh-1);
}
.tmpl-dseg {
  min-height: 46px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: var(--r-s);
  background: none;
  color: var(--ink-2);
  font-size: 12px;
  font-weight: var(--fw-semibold);
  cursor: pointer;
}
.tmpl-dseg-count { font-size: 10.5px; font-weight: var(--fw-semibold); color: var(--ink-3); }
.tmpl-dseg.is-selected { background: var(--wash); color: var(--green-ink); box-shadow: inset 0 -2px 0 var(--green); }
.tmpl-dseg.is-selected .tmpl-dseg-count { color: var(--green-ink); }
.tmpl-dseg.is-closed,
.tmpl-dseg.is-closed .tmpl-dseg-count { color: var(--ink-dis); }
.tmpl-dseg:focus-visible { outline: var(--focus-ring-w) solid var(--focus); outline-offset: -2px; }
.tmpl-msum {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 12px 2px 0;
  font-size: 12.5px;
  color: var(--ink-3);
}
.tmpl-msum b { font-size: 13px; font-weight: var(--fw-semibold); color: var(--ink); }
.tmpl-mlist { display: flex; flex-direction: column; gap: 10px; padding-top: 12px; }
.tmpl-mrole {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--sh-1);
  padding: 10px 12px 12px;
}
.tmpl-mrh { display: flex; align-items: center; gap: 8px; padding-bottom: 8px; }
.tmpl-mrh b { font-size: 14px; font-weight: var(--fw-semibold); }
.tmpl-mrh-total { margin-left: auto; font-size: 12px; color: var(--ink-3); }
.tmpl-mchips { display: flex; flex-direction: column; gap: 8px; }
.tmpl-mchips .tmpl-chipwrap { margin: 0; }
.tmpl-mempty { font-size: 12.5px; color: var(--ink-3); padding: 2px 0; }
.tmpl-addshift-block {
  display: flex;
  width: 100%;
  height: var(--tap-min);
  margin-top: 8px;
  border: 1px dashed var(--line-2);
  border-radius: var(--r-s);
  color: var(--ink-2);
  font-size: 13px;
}
.tmpl-addshift-block .tmpl-ic { opacity: 1; }
.tmpl-mclosed {
  background: var(--well);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 22px 16px;
  text-align: center;
  margin-top: 12px;
}
.tmpl-mclosed b { display: block; font-size: 14px; font-weight: var(--fw-semibold); color: var(--ink-2); }
.tmpl-mclosed span { font-size: 12.5px; color: var(--ink-3); }

/* phone (ui-mode width/coarse driven — NOT has-manager-mobile-tab-bar, which is also present on
   desktop): swap the matrix for the day switcher; dock autosave above the tab bar */
body.ui-mobile .template-matrix-wrap { display: none; }
body.ui-mobile .template-mobile { display: block; padding-bottom: 150px; }
body.ui-mobile .template-toolbar {
  position: static;
  flex-wrap: wrap;
  border-bottom: 0;
  padding: 0 0 4px;
}
body.manager-workspace.ui-mobile .template-toolbar .template-savebar {
  position: fixed;
  left: 10px;
  right: 10px;
  bottom: calc(86px + env(safe-area-inset-bottom, 0px));
  z-index: var(--z-savebar);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin: 0;
  padding: 7px 8px 7px 12px;
  box-shadow: var(--sh-2);
}
body.manager-workspace.ui-mobile .template-toolbar .template-savebar-actions {
  display: flex;
  grid-template-columns: none;
  gap: 4px;
  margin-left: auto;
}
body.manager-workspace.ui-mobile .template-toolbar .template-savebar-actions > button {
  width: auto;
  min-height: 38px;
}

/* ===== Manager phone — Service Bar structural deltas =====
   Phone-only (<=900px / body.ui-mobile) command surface for schedules.html.
   The desktop Schedules workspace is untouched: #managerMobileCommandCenter is
   display:none unless body.ui-mobile (base rule in styles.css). Tokens only. */

/* ---- page layout: lead with the command surface; demote generate/list/AI (deltas #1, #9) ---- */
body.ui-mobile.manager-schedules-page .schedule-page-head { display: none; }
body.ui-mobile.manager-schedules-page #managerAiAssistantPanel { display: none; }
body.ui-mobile.manager-schedules-page .schedule-list-head,
body.ui-mobile.manager-schedules-page #scheduleAdvancedFilters,
body.ui-mobile.manager-schedules-page #schedulesList { display: none; }
body.ui-mobile.manager-schedules-page.manager-mobile-has-schedule #scheduleGenerateCard,
body.ui-mobile.manager-schedules-page.manager-mobile-has-schedule .schedule-list-card { display: none; }

/* Schedule tab focused: reveal the schedule workspace + generate card, hide the home surface (delta #8) */
body.ui-mobile.manager-schedules-page.manager-mobile-schedule-focused #managerMobileCommandCenter { display: none !important; }
body.ui-mobile.manager-schedules-page.manager-mobile-schedule-focused.manager-mobile-has-schedule .schedule-list-card { display: block; }
body.ui-mobile.manager-schedules-page.manager-mobile-schedule-focused.manager-mobile-has-schedule #scheduleGenerateCard { display: block; }

/* ---- command surface container (overrides the desktop-only display:none guard in styles.css) ---- */
body.ui-mobile.manager-schedules-page #managerMobileCommandCenter {
  display: flex !important;
  flex-direction: column;
  gap: 12px;
  padding: 0;
}
body.ui-mobile #managerMobileCommandCenter {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 0;
}
body.ui-mobile.manager-schedules-page.manager-mobile-has-schedule:not(.manager-mobile-schedule-focused) #managerMobileCommandCenter {
  /* fill the viewport so the savedock docks just above the tab bar (delta #7) */
  min-height: calc(100vh - 122px - env(safe-area-inset-bottom, 0px));
}
body.ui-mobile #managerMobileCommandCenter .tnum { font-variant-numeric: var(--fnum-data); }
body.ui-mobile #managerMobileCommandCenter .mpc-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--sh-1);
}

/* ---- appbar / week-status header (delta #2) ---- */
body.ui-mobile #managerMobileCommandCenter .mpc-appbar { padding: 4px 2px 0; }
body.ui-mobile #managerMobileCommandCenter .mpc-over {
  font-size: var(--fs-caption);
  font-weight: var(--fw-caption);
  letter-spacing: var(--ls-caption);
  text-transform: uppercase;
  color: var(--ink-3);
}
body.ui-mobile #managerMobileCommandCenter .mpc-toprow {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-top: 2px;
}
body.ui-mobile #managerMobileCommandCenter .mpc-toprow h1 {
  margin: 0;
  font-size: 27px;
  line-height: 1.12;
  font-weight: 700;
  color: var(--ink);
  font-variant-numeric: var(--fnum-data);
}
body.ui-mobile #managerMobileCommandCenter .mpc-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 7px;
  margin-top: 5px;
  font-size: 12.5px;
  color: var(--ink-3);
  font-variant-numeric: var(--fnum-data);
}
body.ui-mobile #managerMobileCommandCenter .mpc-meta .uf { color: var(--red-ink); font-weight: var(--fw-semibold); }

/* ---- status pill ---- */
body.ui-mobile #managerMobileCommandCenter .mpc-pill {
  display: inline-flex;
  align-items: center;
  height: 21px;
  padding: 0 10px;
  border-radius: var(--r-pill);
  font-size: 11px;
  font-weight: var(--fw-semibold);
  letter-spacing: 0.02em;
  white-space: nowrap;
}
body.ui-mobile #managerMobileCommandCenter .mpc-pill-draft {
  color: var(--status-draft-fg);
  background: var(--status-draft-bg);
  border: 1px dashed var(--status-draft-border);
}
body.ui-mobile #managerMobileCommandCenter .mpc-pill-sent {
  color: var(--status-sent-fg);
  background: var(--status-sent-bg);
}
body.ui-mobile #managerMobileCommandCenter .mpc-pill-pending {
  color: var(--status-warning-fg);
  background: var(--status-warning-bg);
  height: 18px;
  padding: 0 8px;
  font-size: 10.5px;
  vertical-align: 1px;
}

/* ---- section overlines ---- */
body.ui-mobile #managerMobileCommandCenter .mpc-section { display: flex; flex-direction: column; gap: 7px; }
body.ui-mobile #managerMobileCommandCenter .mpc-sect-row,
body.ui-mobile #managerMobileCommandCenter .mpc-sect {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: var(--fs-caption);
  font-weight: var(--fw-caption);
  letter-spacing: var(--ls-caption);
  text-transform: uppercase;
  color: var(--ink-3);
}
body.ui-mobile #managerMobileCommandCenter .mpc-sect-row { padding: 0 2px; }
body.ui-mobile #managerMobileCommandCenter .mpc-sect-row .cnt { color: var(--ink-2); font-variant-numeric: var(--fnum-data); }

/* ---- today / On now strip (delta #3) ---- */
body.ui-mobile #managerMobileCommandCenter .mpc-today { padding: 12px 14px 0; }
body.ui-mobile #managerMobileCommandCenter .mpc-today-hd {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: 20px;
}
body.ui-mobile #managerMobileCommandCenter .mpc-today-hd .mpc-win { font-size: 11.5px; color: var(--ink-3); }
body.ui-mobile #managerMobileCommandCenter .mpc-prow {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  border-bottom: 1px solid var(--line-faint);
}
body.ui-mobile #managerMobileCommandCenter .mpc-prow-empty { color: var(--ink-3); }
body.ui-mobile #managerMobileCommandCenter .mpc-redge {
  width: 4px;
  height: 26px;
  border-radius: 2px;
  background: var(--rc, var(--line-2));
  flex: none;
}
body.ui-mobile #managerMobileCommandCenter .mpc-who { flex: 1; min-width: 0; line-height: 1.25; }
body.ui-mobile #managerMobileCommandCenter .mpc-who .n {
  display: block;
  font-size: 13.5px;
  font-weight: var(--fw-semibold);
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
body.ui-mobile #managerMobileCommandCenter .mpc-who .r { display: block; font-size: 11px; color: var(--ink-3); }
body.ui-mobile #managerMobileCommandCenter .mpc-til { font-size: 12px; color: var(--ink-2); white-space: nowrap; }
body.ui-mobile #managerMobileCommandCenter .mpc-fdot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--dot-changed);
  flex: none;
}
body.ui-mobile #managerMobileCommandCenter .mpc-upnext {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  min-height: 46px;
  margin: 0 -14px;
  padding: 0 14px;
  border-top: 1px solid var(--line);
  background: var(--surface-band);
  border-radius: 0 0 var(--r) var(--r);
}
body.ui-mobile #managerMobileCommandCenter .mpc-up-l { flex: 1; min-width: 0; }
body.ui-mobile #managerMobileCommandCenter .mpc-up-l .l1 {
  display: block;
  font-size: 12.5px;
  font-weight: var(--fw-semibold);
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
body.ui-mobile #managerMobileCommandCenter .mpc-up-l .l2 {
  display: block;
  font-size: 11px;
  color: var(--ink-3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
body.ui-mobile #managerMobileCommandCenter .mpc-linkbtn {
  border: 0;
  background: none;
  color: var(--green);
  font-size: 12.5px;
  font-weight: var(--fw-semibold);
  cursor: pointer;
  padding: 0 4px;
  min-height: 32px;
  border-radius: var(--r-s);
  white-space: nowrap;
}
body.ui-mobile #managerMobileCommandCenter .mpc-linkbtn:hover { background: var(--wash); color: var(--green-deep); }

/* ---- needs-attention worklist (delta #4) ---- */
body.ui-mobile #managerMobileCommandCenter .mpc-attn { overflow: hidden; }
body.ui-mobile #managerMobileCommandCenter .mpc-uitem {
  position: relative;
  padding: 11px 14px 12px 16px;
  border-bottom: 1px solid var(--line-faint);
}
body.ui-mobile #managerMobileCommandCenter .mpc-uitem:last-child { border-bottom: 0; }
body.ui-mobile #managerMobileCommandCenter .mpc-uitem::before {
  content: "";
  position: absolute;
  left: 0;
  top: 9px;
  bottom: 9px;
  width: 3px;
  border-radius: 2px;
}
body.ui-mobile #managerMobileCommandCenter .mpc-lvl-red::before { background: var(--dot-urgent); }
body.ui-mobile #managerMobileCommandCenter .mpc-lvl-amber::before { background: var(--dot-warning); }
body.ui-mobile #managerMobileCommandCenter .mpc-lvl-ok::before { background: var(--green-bar); }
body.ui-mobile #managerMobileCommandCenter .mpc-lvl-ok { background: var(--color-primary-wash); }
body.ui-mobile #managerMobileCommandCenter .mpc-uitem .tt {
  font-size: 13.5px;
  font-weight: var(--fw-semibold);
  line-height: 1.35;
  color: var(--ink);
  font-variant-numeric: var(--fnum-data);
}
body.ui-mobile #managerMobileCommandCenter .mpc-uitem .tt .kw-red { color: var(--red-ink); }
body.ui-mobile #managerMobileCommandCenter .mpc-uitem .tt .kw-amber { color: var(--amber-ink); }
body.ui-mobile #managerMobileCommandCenter .mpc-uitem .body { display: flex; gap: 10px; margin-top: 3px; }
body.ui-mobile #managerMobileCommandCenter .mpc-uitem .mlines { flex: 1; min-width: 0; }
body.ui-mobile #managerMobileCommandCenter .mpc-uitem .ml {
  font-size: 12px;
  color: var(--ink-3);
  line-height: 1.45;
  font-variant-numeric: var(--fnum-data);
}
body.ui-mobile #managerMobileCommandCenter .mpc-uitem .aside { flex: none; display: flex; align-items: center; }
body.ui-mobile #managerMobileCommandCenter .mpc-uitem .okline { font-size: 12px; color: var(--green-ink); margin-top: 3px; }
body.ui-mobile #managerMobileCommandCenter .mpc-actsrow { display: flex; gap: 8px; margin-top: 9px; }
body.ui-mobile #managerMobileCommandCenter .mpc-actsrow .mpc-btn { flex: 1; }
body.ui-mobile #managerMobileCommandCenter .mpc-attn-empty {
  padding: 16px 14px;
  font-size: 13px;
  color: var(--ink-3);
}

/* ---- next 3 days cards (delta #5) ---- */
body.ui-mobile #managerMobileCommandCenter .mpc-days {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}
body.ui-mobile #managerMobileCommandCenter .mpc-dayc {
  min-height: 116px;
  text-align: left;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--sh-1);
  padding: 10px 11px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
}
body.ui-mobile #managerMobileCommandCenter .mpc-dayc:hover { background: var(--surface-hover); border-color: var(--line-hover); }
body.ui-mobile #managerMobileCommandCenter .mpc-dayc .dl {
  font-size: 10px;
  font-weight: var(--fw-caption);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--ink-3);
  white-space: nowrap;
}
body.ui-mobile #managerMobileCommandCenter .mpc-dayc .dn {
  font-size: 19px;
  font-weight: var(--fw-semibold);
  color: var(--ink);
  line-height: 1.2;
  margin-top: 2px;
}
body.ui-mobile #managerMobileCommandCenter .mpc-dayc .dn .dns { font-size: 11px; font-weight: 400; color: var(--ink-3); }
body.ui-mobile #managerMobileCommandCenter .mpc-dayc .ds {
  display: block;
  font-size: 11px;
  color: var(--ink-3);
  margin-top: 2px;
  line-height: 1.25;
  white-space: nowrap;
}
body.ui-mobile #managerMobileCommandCenter .mpc-dayc .bdg { margin-top: auto; display: flex; min-height: 16px; padding-top: 6px; }
body.ui-mobile #managerMobileCommandCenter .mpc-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 17px;
  padding: 0 6px;
  border-radius: var(--r-pill);
  font-size: 10.5px;
  font-weight: var(--fw-semibold);
}
body.ui-mobile #managerMobileCommandCenter .mpc-badge i { width: 5px; height: 5px; border-radius: 50%; display: inline-block; }
body.ui-mobile #managerMobileCommandCenter .mpc-badge-red { background: var(--red-tint); color: var(--red-ink); }
body.ui-mobile #managerMobileCommandCenter .mpc-badge-red i { background: var(--red); }
body.ui-mobile #managerMobileCommandCenter .mpc-badge-amber { background: var(--amber-tint); color: var(--amber-ink); }
body.ui-mobile #managerMobileCommandCenter .mpc-badge-amber i { background: var(--amber-dot); }
body.ui-mobile #managerMobileCommandCenter .mpc-badge-blue { background: var(--blue-tint); color: var(--blue-ink); }
body.ui-mobile #managerMobileCommandCenter .mpc-badge-blue i { background: var(--blue-dot); }

/* ---- quick actions: Send primary + Add secondary (delta #6) ---- */
body.ui-mobile #managerMobileCommandCenter .mpc-quick {
  display: grid;
  grid-template-columns: 1.5fr 1fr;
  gap: 8px;
}
body.ui-mobile #managerMobileCommandCenter .mpc-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: var(--tap-min);
  padding: 0 14px;
  font-size: 13.5px;
  font-weight: var(--fw-semibold);
  border-radius: var(--r);
  border: 1px solid transparent;
  cursor: pointer;
  white-space: nowrap;
}
body.ui-mobile #managerMobileCommandCenter .mpc-btn-sm { min-height: 38px; font-size: 12.5px; padding: 0 12px; }
body.ui-mobile #managerMobileCommandCenter .mpc-btn-pri { background: var(--green); color: var(--color-on-primary); }
body.ui-mobile #managerMobileCommandCenter .mpc-btn-pri:hover { background: var(--green-deep); }
body.ui-mobile #managerMobileCommandCenter .mpc-btn-sec { background: var(--surface); color: var(--ink); border-color: var(--line-2); }
body.ui-mobile #managerMobileCommandCenter .mpc-btn-sec:hover { background: var(--surface-hover); border-color: var(--line-hover); }
body.ui-mobile #managerMobileCommandCenter .mpc-btn-ghost { background: transparent; color: var(--ink-2); }
body.ui-mobile #managerMobileCommandCenter .mpc-btn-ghost:hover { background: var(--well); color: var(--ink); }

/* ---- docked autosave savebar (delta #7) ---- */
body.ui-mobile #managerMobileCommandCenter .mpc-savedock { margin-top: auto; padding-top: 2px; }
body.ui-mobile #managerMobileCommandCenter .mpc-savebar {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 40px;
  padding: 0 8px 0 12px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--sh-1);
}
body.ui-mobile #managerMobileCommandCenter .mpc-autosave {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  color: var(--ink-3);
}
body.ui-mobile #managerMobileCommandCenter .mpc-autosave.saved .mpc-check { color: var(--green); font-weight: var(--fw-semibold); }
body.ui-mobile #managerMobileCommandCenter .mpc-autosave.error { color: var(--red); font-weight: var(--fw-semibold); }
body.ui-mobile #managerMobileCommandCenter .mpc-retry {
  margin-left: auto;
  min-height: 28px;
  padding: 0 8px;
  border: 0;
  background: none;
  font-size: 12.5px;
  font-weight: var(--fw-semibold);
  color: var(--red);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
  border-radius: var(--r-s);
}
body.ui-mobile #managerMobileCommandCenter .mpc-spin {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  border: 1.5px solid currentColor;
  border-top-color: transparent;
  opacity: 0.9;
  animation: mpc-spin 0.8s linear infinite;
}
@keyframes mpc-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { body.ui-mobile #managerMobileCommandCenter .mpc-spin { animation-duration: 0.01ms; } }

body.ui-mobile #managerMobileCommandCenter .mpc-empty { padding: 16px; font-size: 13px; color: var(--ink-3); }

/* ---- tab-bar amber badge variant (delta #10) ---- */
.manager-mobile-tab-badge.is-amber { background: var(--amber-dot); color: var(--scale-ink-900, #17201c); }

/* ---- More sheet: quiet 44px dismiss (delta #11) ---- */
.manager-mobile-more-close {
  width: var(--tap-min);
  height: var(--tap-min);
  min-height: var(--tap-min);
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: none;
  color: var(--ink-3);
  font-size: 18px;
  line-height: 1;
  border-radius: var(--r-s);
  cursor: pointer;
}
.manager-mobile-more-close:hover { background: var(--well); color: var(--ink); }

/* =====================================================================
   Service Bar re-skin · Category 31 — Employee home "this week" strip:
   full week, past days shown quieter.
   ---------------------------------------------------------------------
   Appended AFTER 21-employee-home.css so equal-specificity later rules
   win the cascade. The strip now renders EVERY day Mon–Sun including
   elapsed ones (server `currentWeekShifts`), so a day already worked keeps
   its real shift start and merely reads a touch dimmer instead of "—".
   Every value consumes /styles/tokens.css (Service Bar).
   ===================================================================== */

/* Elapsed days this week stay legible but recede behind today + upcoming.
   `emp-tile--was` is added by the client to any past, non-today tile. */
.emp-tile--was { opacity: 0.6; }

/* A past day you worked keeps the "on" wash so it still reads as a shift —
   the real start time stays visible, just calmed by the opacity above. The
   border drops to a neutral line so it never competes with today's accent. */
.emp-tile--was.emp-tile--on { border-color: var(--line-mid); }
.emp-tile--was.emp-tile--on .emp-tile-val {
  color: var(--color-text);
  font-weight: var(--fw-semibold);
}

/* A past day off reads like a normal off day, just dimmer via the opacity. */
.emp-tile--was.emp-tile--off .emp-tile-val { color: var(--color-text-disabled); }

/* Hovering an elapsed (still tappable) day lifts it back to full strength so
   it clearly signals it routes to the full schedule view. */
.emp-tile--was:hover { opacity: 1; }

/* =====================================================================
   Service Bar re-skin · Category 30 — Deferred LOW/MED polish.
   ---------------------------------------------------------------------
   Appended LAST to service-bar.css (after styles.css), so equal-specificity
   later rules win the cascade. Every value consumes /styles/tokens.css.
   Covers four polish items (markup/wiring live in public/app.js):
     1. Schedule detail — legend re-author (#11) + optimistic row pulse /
        autosave Saving…→Saved (#12).
     2. Employees — availability painter swatch legend + grayscale-safe
        "available" glyph (employees delta #11).
     3. Configuration — "Open Onboarding" moved to the page-header action
        row (configuration delta #9).
     4. Manager phone — Fill/quick-assign bottom sheet (#8) + resolved-item
        green receipt rows (#4). Phone-only (≤900px / body.ui-mobile).
   ===================================================================== */

/* =====================================================================
   1 · SCHEDULE DETAIL — legend re-authored as real chip specimens (#11)
   The legend reuses the live grid's .shift-chip / .sd-chip-dot markup so
   the legend and grid can never drift. Collapsible; state persists in JS.
   ===================================================================== */
.sd-legend-wrap { margin: 6px 0 12px; }
.sd-legend-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 0;
  background: none;
  padding: 4px 6px;
  font: inherit;
  font-size: 12.5px;
  font-weight: var(--fw-semibold);
  color: var(--ink-2);
  cursor: pointer;
  border-radius: var(--r-s);
}
.sd-legend-toggle:hover { background: var(--well); color: var(--ink); }
.sd-legend-toggle:focus-visible {
  outline: var(--focus-ring-w) solid var(--focus);
  outline-offset: var(--focus-ring-offset);
}
.sd-legend-caret {
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid currentColor;
  transition: transform var(--dur-2) var(--ease-out);
}
.sd-legend-toggle[aria-expanded="false"] .sd-legend-caret { transform: rotate(-90deg); }

.sd-legend-row {
  display: none;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 18px;
  padding: 9px 6px 2px;
  font-size: 11.5px;
  color: var(--ink-3);
}
.sd-legend-row.is-open { display: flex; }
.sd-legend-item { display: inline-flex; align-items: center; gap: 7px; }

/* Compact, non-interactive specimen of the live .shift-chip. */
.sd-legend-chip.shift-chip {
  width: auto;
  min-width: 0;
  max-width: none;
  margin: 0;
  padding: 3px 8px;
  flex-direction: row;
  align-items: center;
  gap: 5px;
  cursor: default;
  pointer-events: none;
}
.sd-legend-chip.shift-chip .chip-time { font-size: 11px; line-height: 1.2; }
.sd-legend-chip.shift-chip .chip-assign {
  font-size: 10px;
  font-weight: var(--fw-semibold);
  color: var(--color-danger);
}
.sd-legend-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex: none;
}
.sd-legend-closed {
  display: inline-block;
  width: 16px;
  height: 16px;
  border-radius: var(--r-xs);
  background: var(--surface-sunken);
  border: 1px solid var(--line);
  flex: none;
}

/* ---- Optimistic save: autosave indicator runs Saving…→Saved (#12) ----
   The touched-row blue pulse reuses the existing .sd-row-pulse keyframe. */
.sd-savebar.is-saving { color: var(--ink-2); }
.sd-savebar.is-saving .sd-autosave-dot {
  background: var(--amber-dot);
  animation: sd-savebar-pulse 900ms var(--ease-in-out) infinite;
}
@keyframes sd-savebar-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}
@media (prefers-reduced-motion: reduce) {
  /* Never convey state by motion alone: freeze the dot; the text still flips. */
  .sd-savebar.is-saving .sd-autosave-dot { animation: none; }
}

/* =====================================================================
   2 · EMPLOYEES — availability painter swatch legend + grayscale safety
   (employees delta #11). The available cell carries a check glyph + green
   border so the grid decodes without color; off cells go quiet (sunken).
   ===================================================================== */
.availability-painter-legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 16px;
  margin: 8px 0 4px;
  font-size: 12px;
  color: var(--ink-3);
}
.availability-painter-legend-item { display: inline-flex; align-items: center; gap: 6px; }
.availability-painter-swatch {
  position: relative;
  display: inline-block;
  width: 18px;
  height: 18px;
  flex: none;
  border-radius: 5px;
  border: 1px solid var(--line-2);
  background: var(--surface-panel);
}
.availability-painter-swatch.is-regular { background: var(--green-tint); border-color: var(--green); }
.availability-painter-swatch.is-oncall {
  background: repeating-linear-gradient(135deg, var(--blue-tint) 0 5px, var(--surface-panel) 5px 10px);
  border-color: var(--blue-dot);
}
.availability-painter-swatch.is-clear { background: var(--surface-panel); border-style: dashed; }

/* Grayscale-safe "available" mark on both the legend swatch and live cells. */
.availability-painter-swatch.is-regular::after,
.availability-painter-cell.is-regular::after {
  content: "\2713"; /* ✓ */
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--green-ink);
  font-weight: var(--fw-semibold);
  pointer-events: none;
}
.availability-painter-swatch.is-regular::after { font-size: 12px; }
.availability-painter-cell.is-regular {
  position: relative;
  border-color: var(--green);
}
.availability-painter-cell.is-regular::after { font-size: 17px; }
/* Off cells: quiet/grayscale well instead of bright white. */
.availability-painter-cell.is-clear {
  background: var(--surface-sunken);
  border-style: dashed;
  border-color: var(--line-2);
}

/* =====================================================================
   3 · CONFIGURATION — "Open Onboarding" in the page-header action row (#9)
   ===================================================================== */
.manager-header-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}
.manager-header-action-btn {
  white-space: nowrap;
  height: var(--ctl-h-sm);
  padding: 0 14px;
  font-size: 13px;
}
body.manager-workspace.ui-mobile .manager-header-actions { width: 100%; }
body.manager-workspace.ui-mobile .manager-header-action-btn { width: 100%; height: var(--tap-min); }

/* =====================================================================
   4 · MANAGER PHONE — resolved-item receipts (#4) + Fill/assign sheet (#8)
   Phone-only. The receipt pills + green row reuse the command center's
   existing .mpc-lvl-ok / .okline recipe.
   ===================================================================== */
body.ui-mobile #managerMobileCommandCenter .mpc-pill-approved {
  background: var(--green-tint);
  color: var(--green-ink);
}
body.ui-mobile #managerMobileCommandCenter .mpc-pill-denied {
  background: var(--red-tint);
  color: var(--red-ink);
}
body.ui-mobile #managerMobileCommandCenter .mpc-receipt .tt { color: var(--ink-2); }

/* ---- Fill shift / quick assign as a bottom sheet (#8) ----
   The assign dialog already does the work in place (reusing the existing
   assign handler + /api/schedules/fill-options); on phone it reads as a
   bottom sheet (scrim + sheet at --z-dialog) instead of a centered card.
   Desktop never gets body.ui-mobile, so the desktop fill sheet is unchanged. */
body.ui-mobile #scheduleMobileAssignModalHost .modal-backdrop {
  align-items: flex-end;
  justify-content: center;
  padding: 0;
}
body.ui-mobile #scheduleMobileAssignModalHost .modal-card.manager-mobile-assign-card {
  width: 100%;
  max-width: 100%;
  margin: 0;
  max-height: 88vh;
  overflow-y: auto;
  border-radius: var(--r) var(--r) 0 0;
  padding: 8px 16px calc(16px + env(safe-area-inset-bottom));
  box-shadow: var(--sh-2);
  animation: mpc-sheet-up var(--dur-4) var(--ease-out);
}
/* grab handle */
body.ui-mobile #scheduleMobileAssignModalHost .modal-card.manager-mobile-assign-card::before {
  content: "";
  display: block;
  width: 38px;
  height: 4px;
  margin: 4px auto 10px;
  border-radius: var(--r-pill);
  background: var(--line-2);
}
@keyframes mpc-sheet-up {
  from { transform: translateY(24px); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  body.ui-mobile #scheduleMobileAssignModalHost .modal-card.manager-mobile-assign-card { animation: none; }
}
