/* ============================================
   Quota & Assignment Modal — aligned to canonical
   app primitives (.modal-header / .tab-btn /
   .proposer-chip / .boards-dropdown / .modal-footer).
   See style.css for source-of-truth tokens.
   ============================================ */

/* Modal sizing — wide modal, but uses the canonical
   --radius-2xl, --surface-primary, and shadow stack
   from .modal-content (style.css:12536). */
.quota-assignment-modal .modal-content,
.quota-assignment-modal-content {
  max-width: 1400px;
  width: 98%;
  height: 94vh;
  max-height: 94vh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  border-radius: var(--radius-2xl, 24px);
  background: var(--surface-primary, #ffffff);
  box-shadow:
    0 24px 48px rgba(0, 0, 0, 0.2),
    0 0 0 1px rgba(255, 255, 255, 0.1),
    var(--shadow-glow-lg);
}

body.dark-mode .quota-assignment-modal .modal-content,
body.dark-mode .quota-assignment-modal-content {
  background: var(--surface-secondary);
  box-shadow:
    0 24px 48px rgba(0, 0, 0, 0.4),
    0 0 0 1px rgba(255, 255, 255, 0.05),
    0 0 60px rgba(20, 184, 166, 0.15);
}

/* Header — inherits .modal-header from style.css:13333.
   Local rules only override what the wide layout needs. */
.qa-header {
  flex-shrink: 0;
  gap: 16px;
}

.qa-header-left {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: 1;
  min-width: 0;
  flex-wrap: wrap;
}

.qa-header h2 {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 0 0 auto;
}

.qa-header h2 i {
  color: var(--primary-500, #14b8a6);
  font-size: 0.875em;
}

/* Tier badge — chip geometry mirrors .proposer-chip
   (style.css:22826) but tinted with the brand gradient
   to read as "tier indicator" rather than "filter". */
.qa-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 26px;
  padding: 0 10px;
  border-radius: var(--radius-full);
  background: linear-gradient(135deg, var(--primary-500) 0%, var(--accent-500) 100%);
  color: #fff;
  font-size: 0.6875rem;
  font-weight: 700;
  /* NO uppercase (2026-09-01): the 2026-08-14 fix renamed the badge to
     "Business plan" so it names the REQUIREMENT, but text-transform was
     shouting it back to "BUSINESS PLAN" — which reads as a status claim
     ("you are on Business") right beside a plan-locked banner. Sentence
     case keeps it a label, not a verdict. */
  letter-spacing: 0.05em;
  box-shadow: 0 1px 3px rgba(20, 184, 166, 0.25);
  flex: 0 0 auto;
}

/* Board selector pill — mirrors .proposer-chip neutral
   resting state (style.css:22826) so it sits beside the
   ENTERPRISE badge as a coherent chip row. */
.qa-board-selector {
  position: relative;
  flex: 0 0 auto;
}

.qa-board-selector-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 36px;
  padding: 0 12px;
  border-radius: var(--radius-full);
  border: 1px solid var(--slate-200, #e2e8f0);
  background: var(--white, #fff);
  color: var(--slate-700, #334155);
  font-family: inherit;
  font-size: 0.8125rem;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
  white-space: nowrap;
}

.qa-board-selector-btn:hover {
  border-color: var(--primary-300);
  background: var(--primary-50);
  color: var(--primary-700);
}

.qa-board-selector-btn > i:first-child {
  color: var(--primary-500);
  font-size: 0.8125rem;
}

.qa-board-chevron {
  font-size: 0.625rem;
  color: var(--slate-400);
  transition: transform 0.15s ease;
}

.qa-board-selector.open .qa-board-chevron {
  transform: rotate(180deg);
}

body.dark-mode .qa-board-selector-btn {
  background: var(--surface-secondary);
  border-color: var(--slate-700);
  color: var(--slate-200);
}

body.dark-mode .qa-board-selector-btn:hover {
  background: rgba(20, 184, 166, 0.12);
  border-color: rgba(20, 184, 166, 0.4);
  color: var(--primary-300);
}

/* Board dropdown — mirrors .boards-dropdown chrome
   (style.css:1044). Same width, radius, shadow, items. */
.qa-board-dropdown {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  width: min(340px, 90vw);
  background: var(--surface-primary);
  border: 1px solid var(--slate-200);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xl);
  z-index: var(--z-dropdown, 1040);
  display: none;
  flex-direction: column;
  overflow: hidden;
  padding: var(--space-2, 8px) 0;
}

.qa-board-dropdown.active {
  display: flex;
}

.qa-board-option {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border: none;
  background: none;
  width: 100%;
  text-align: left;
  font-family: inherit;
  font-size: 0.875rem;
  color: var(--slate-700);
  cursor: pointer;
  transition: background 0.15s ease;
}

.qa-board-option:hover {
  background: var(--slate-50);
}

.qa-board-option.active {
  background: var(--primary-50);
  color: var(--primary-700);
  font-weight: 600;
}

.qa-board-option > i {
  color: var(--primary-500);
  width: 16px;
  text-align: center;
  flex-shrink: 0;
}

.qa-board-count {
  margin-left: auto;
  min-width: 22px;
  height: 20px;
  padding: 0 7px;
  border-radius: var(--radius-full);
  background: var(--slate-100);
  color: var(--slate-600);
  font-size: 0.6875rem;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.qa-board-option.active .qa-board-count {
  background: var(--primary-100, #ccfbf1);
  color: var(--primary-700);
}

.qa-board-divider {
  height: 1px;
  margin: 6px 0;
  background: var(--slate-200);
}

.qa-board-create {
  color: var(--primary-600);
  font-weight: 600;
}

.qa-board-create > i {
  color: var(--primary-500);
}

body.dark-mode .qa-board-dropdown {
  background: var(--surface-secondary);
  border-color: var(--slate-700);
}

body.dark-mode .qa-board-option {
  color: var(--slate-200);
}

body.dark-mode .qa-board-option:hover {
  background: rgba(255, 255, 255, 0.04);
}

body.dark-mode .qa-board-option.active {
  background: rgba(20, 184, 166, 0.12);
  color: var(--primary-300);
}

body.dark-mode .qa-board-divider {
  background: var(--slate-700);
}

body.dark-mode .qa-board-count {
  background: rgba(255, 255, 255, 0.06);
  color: var(--slate-300);
}

/* Tabs — mirrors .tab-btn from style.css:21527.
   Same underline animation, same active pill bg,
   same dark-mode pair. */
.qa-tabs {
  display: flex;
  gap: 4px;
  padding: 0 24px;
  border-bottom: 1px solid var(--slate-200, #e2e8f0);
  flex-shrink: 0;
  overflow-x: auto;
  /* A SCROLLING TAB STRIP MUST LOOK SCROLLABLE (2026-08-14, user: "this blank
     version with no options was discovered on mobile").
     Measured at 412px: 609px of tabs inside a 404px strip, so Distribute and
     History sat off-screen with NO visual cue — indistinguishable from "those
     tabs do not exist", which is exactly how it was reported. Snap-scrolling
     plus a fade on the overflowing edge makes the strip legible as something
     you can move, and momentum scrolling makes it feel like one. */
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;                 /* the fade is the affordance */
  position: relative;
}
.qa-tabs::-webkit-scrollbar { display: none; }
.qa-tab { scroll-snap-align: start; }

/* The fade cue itself. It is a STICKY flex item rather than a ::after on the
   strip, because a pseudo-element positioned inside a scrolling container
   scrolls away with the content — it would vanish at exactly the moment it is
   meant to say "there is more this way". Sticky keeps it pinned to the visible
   right edge while the tabs move underneath.
   `position: sticky; right: 0` + a negative margin so it overlays the last tab
   instead of consuming width (which would push yet another tab out of view). */
.qa-tabs::after {
  content: '';
  position: sticky;
  right: 0;
  flex: 0 0 28px;
  margin-left: -28px;
  align-self: stretch;
  pointer-events: none;
  background: linear-gradient(to right, transparent, var(--white, #fff) 78%);
}
body.dark-mode .qa-tabs::after {
  background: linear-gradient(to right, transparent, var(--slate-900, #0f172a) 78%);
}
/* From 360px up all five tabs fit (2026-09-24: steps on the tabs, History
   icon-only on a phone), so the fade would be a lie there — it was greying
   out the History icon. It stays for the narrowest phones, which scroll. */
@media (min-width: 360px) {
  .qa-tabs::after { display: none; }
}

.qa-tab {
  flex: 0 0 auto;
  min-width: fit-content;
  padding: 10px 14px;
  border: none;
  background: transparent;
  color: var(--slate-500, #746d8f);
  font-family: inherit;
  font-size: 0.8125rem;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  position: relative;
  white-space: nowrap;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  display: flex;
  align-items: center;
  gap: 8px;
}

.qa-tab::before {
  content: '';
  position: absolute;
  bottom: -1px;
  left: 50%;
  transform: translateX(-50%) scaleX(0);
  width: 80%;
  height: 2px;
  background: var(--primary-500, #14b8a6);
  transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

.qa-tab:hover {
  color: var(--primary-500, #14b8a6);
  background: rgba(20, 184, 166, 0.08);
}

.qa-tab:hover::before {
  transform: translateX(-50%) scaleX(1);
}

.qa-tab.active {
  color: var(--primary-500, #14b8a6);
  background: rgba(20, 184, 166, 0.12);
  font-weight: 700;
}

.qa-tab.active::before {
  transform: translateX(-50%) scaleX(1);
}

.qa-tab i {
  font-size: 0.875em;
  color: currentColor;
  opacity: 0.85;
}

body.dark-mode .qa-tab {
  color: var(--slate-400, #a0a0b0);
}

body.dark-mode .qa-tab:hover {
  color: var(--primary-400);
  background: rgba(20, 184, 166, 0.12);
}

body.dark-mode .qa-tab.active {
  color: var(--primary-400);
  background: rgba(20, 184, 166, 0.2);
}

body.dark-mode .qa-tabs {
  border-bottom-color: var(--slate-700);
}

/* Tab content — fills remaining space; scrolls if needed.
   Inherits 24px padding rhythm from .modal-body
   (style.css:13412). */
.qa-tab-content {
  padding: 24px;
  overflow-y: auto;
  flex: 1 1 0;
  min-height: 0;
  -webkit-overflow-scrolling: touch;
}

/* Persistent modal footer — mirrors .modal-footer
   (style.css:13423). Reserved for the future
   modal-level sticky action surface; per-tab Save
   buttons keep using the in-tab .qa-action-bar
   block defined further down. */
.qa-modal-action-bar {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 12px;
  padding: 16px 24px calc(16px + var(--safe-area-bottom, 0px));
  border-top: 1px solid var(--slate-200, #e2e8f0);
  background: var(--surface-primary, #fff);
  border-radius: 0 0 var(--radius-2xl, 24px) var(--radius-2xl, 24px);
  flex-shrink: 0;
}

.qa-modal-action-bar-status {
  margin-right: auto;
  font-size: 0.8125rem;
  color: var(--slate-500);
}

body.dark-mode .qa-modal-action-bar {
  border-top-color: var(--slate-700);
  background: var(--surface-secondary);
}

body.dark-mode .qa-modal-action-bar-status {
  color: var(--slate-400);
}

/* ============================================
   UTILITIES — small helpers used across tabs.
   Replace inline style="display:none / width:60px /
   text-transform:uppercase / flex:N" usages so the
   markup stays clean and themeable.
   ============================================ */

.qa-tab-content .is-hidden,
.shift-type-editor .is-hidden {
  display: none !important;
}

.qa-input-narrow {
  width: 60px;
}

.qa-input-uppercase {
  text-transform: uppercase;
}

.qa-form-group-1 {
  flex: 1;
}

.qa-form-group-2 {
  flex: 2;
}

.qa-mt-sm { margin-top: 10px; }
.qa-mt-md { margin-top: 16px; }
.qa-mb-sm { margin-bottom: 10px; }
.qa-mb-md { margin-bottom: 16px; }

/* Stat-card variants — inline border + value colors
   were previously hardcoded; route through classes so
   dark-mode + theme tokens stay coherent. */
.qa-stat-card.qa-stat-warning {
  border-color: rgba(245, 158, 11, 0.4);
}

.qa-stat-card.qa-stat-warning .qa-stat-value {
  color: var(--status-flex, #fbbf24);
}

body.dark-mode .qa-stat-card.qa-stat-warning {
  border-color: rgba(245, 158, 11, 0.5);
  background: rgba(245, 158, 11, 0.08);
}

/* Empty-state success/error variants — replace inline
   color="..." on the wrapper. */
.qa-empty-state.qa-success > i {
  color: var(--primary-500, #14b8a6);
  background: linear-gradient(135deg, rgba(20, 184, 166, 0.18), rgba(6, 182, 212, 0.10));
}

.qa-empty-state.qa-error > i {
  color: var(--error, #ef4444);
  background: linear-gradient(135deg, rgba(239, 68, 68, 0.15), rgba(220, 38, 38, 0.08));
}

.qa-empty-state.qa-error .qa-empty-state-title {
  color: var(--error, #ef4444);
}

/* ============================================
   SHIFT TYPES TAB
   ============================================ */

/* Tab toolbar — section title on the left, primary
   action on the right. Used at the top of each tab so
   action affordances live in one consistent place. */
.qa-tab-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 16px;
}

/* Groups a toolbar's buttons so a third action (e.g. Coverage's "One per
   region") sits next to the primary action instead of between title and
   button — space-between on 3 flex children centers the middle one instead
   of pinning actions to the right (owner screenshot, 2026-10-05: "Add Type"
   floated dead-center of the Coverage header). */
.qa-tab-toolbar-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.qa-tab-title {
  margin: 0;
  font-size: 0.9375rem;
  font-weight: 700;
  color: var(--slate-800, #1e293b);
  letter-spacing: -0.01em;
}

body.dark-mode .qa-tab-title {
  color: var(--slate-100, #f1f5f9);
}

/* Coverage type cards — card chrome aligned to canonical
   .member-selection-item (style.css:37794). The leading
   color swatch + icon read --qa-type-color from the row
   so no inline style="color:..." is needed. */
.qa-shift-types-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 20px;
}

.qa-shift-type-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border-radius: var(--radius-md, 12px);
  background: var(--slate-50, #f8fafc);
  border: 1px solid var(--slate-200, #e2e8f0);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.qa-shift-type-item:hover {
  border-color: var(--primary-300, #5eead4);
  box-shadow: 0 1px 3px rgba(20, 184, 166, 0.08);
}

.qa-shift-type-color {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--qa-type-color, var(--primary-500, #14b8a6));
  box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.04);
}

.qa-shift-type-icon {
  width: 28px;
  height: 28px;
  border-radius: var(--radius-sm, 8px);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.875rem;
  color: var(--qa-type-color, var(--primary-500, #14b8a6));
  background: rgba(20, 184, 166, 0.12);
  background: color-mix(in srgb, var(--qa-type-color, #14b8a6) 12%, transparent);
  flex-shrink: 0;
}

.qa-shift-type-info {
  flex: 1;
  min-width: 0;
}

.qa-shift-type-name {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--slate-800, #1f2937);
  display: flex;
  align-items: baseline;
  gap: 6px;
}

.qa-shift-type-short {
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--slate-400, #94a3b8);
}

.qa-shift-type-meta {
  font-size: 0.75rem;
  color: var(--slate-500, #6b7280);
  margin-top: 2px;
}

.qa-shift-type-actions {
  display: flex;
  gap: 4px;
  flex-shrink: 0;
}

.qa-shift-type-actions button {
  width: 30px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.75rem;
  border: none;
  background: transparent;
  cursor: pointer;
  color: var(--slate-500, #6b7280);
  border-radius: var(--radius-sm, 8px);
  transition: background-color 0.15s ease, color 0.15s ease;
}

.qa-shift-type-actions button:hover {
  background: var(--slate-100, #f1f5f9);
  color: var(--slate-700, #334155);
}

.qa-shift-type-actions .qa-btn-delete:hover {
  color: var(--error, #ef4444);
  background: rgba(239, 68, 68, 0.08);
}

body.dark-mode .qa-shift-type-item {
  background: rgba(15, 23, 42, 0.4);
  border-color: var(--slate-700);
}

body.dark-mode .qa-shift-type-item:hover {
  border-color: rgba(20, 184, 166, 0.4);
}

body.dark-mode .qa-shift-type-name {
  color: var(--slate-100);
}

body.dark-mode .qa-shift-type-short {
  color: var(--slate-500);
}

body.dark-mode .qa-shift-type-meta {
  color: var(--slate-400);
}

body.dark-mode .qa-shift-type-actions button {
  color: var(--slate-400);
}

body.dark-mode .qa-shift-type-actions button:hover {
  background: rgba(255, 255, 255, 0.06);
  color: var(--slate-100);
}

/* Shift Type Editor Form */
.qa-editor-form {
  padding: 20px;
  border-radius: var(--radius-md, 12px);
  background: var(--surface-secondary, #f9fafb);
  border: 1px solid var(--primary-color, #14b8a6);
  margin-bottom: 20px;
}

.qa-editor-form .qa-form-row {
  display: flex;
  gap: 14px;
  margin-bottom: 12px;
  align-items: center;
  flex-wrap: wrap;
}

.qa-editor-form label {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--text-secondary, #6b7280);
  min-width: 90px;
}

.qa-editor-form input[type="text"],
.qa-editor-form input[type="number"],
.qa-editor-form select {
  padding: 10px 14px;
  border: 1.5px solid var(--border-default, #d1d5db);
  border-radius: var(--radius-lg, 14px);
  font-size: 0.9375rem;
  background: var(--surface-primary, #fff);
  color: var(--text-primary, #111827);
  flex: 1;
  min-width: 80px;
  transition: all var(--transition-fast, 0.15s);
}

.qa-editor-form input[type="text"]:focus,
.qa-editor-form input[type="number"]:focus,
.qa-editor-form select:focus {
  border-color: var(--primary-400, #14b8a6);
  outline: none;
  box-shadow: var(--focus-ring-shadow);
}

.qa-editor-form .qa-form-actions {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  margin-top: 16px;
}

/* Empty state — mirrors .empty-state composition
   from style.css:35750 (centered illustration +
   title + hint). Icon sits inside a soft brand-tinted
   circle. */
.qa-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 48px 24px;
  color: var(--slate-500, #6b7280);
  font-size: 0.9375rem;
  gap: 12px;
}

.qa-empty-state > i {
  width: 80px;
  height: 80px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 2rem;
  color: var(--primary-500, #14b8a6);
  background: linear-gradient(135deg, rgba(20, 184, 166, 0.12), rgba(6, 182, 212, 0.08));
  margin-bottom: 6px;
}

.qa-empty-state-title {
  margin: 0;
  font-size: 1rem;
  font-weight: 700;
  color: var(--slate-800, #1e293b);
  letter-spacing: -0.01em;
}

.qa-empty-state-hint {
  margin: 0;
  font-size: 0.8125rem;
  color: var(--slate-500, #6b7280);
  max-width: 320px;
  line-height: 1.45;
}

body.dark-mode .qa-empty-state-title {
  color: var(--slate-100);
}

body.dark-mode .qa-empty-state-hint {
  color: var(--slate-400);
}

/* Info banner — same gradient shape as .collab-cta-banner
   (style.css:13489) but slimmer; reused across tabs as
   the canonical "tip / status" callout. */
.qa-blank-slate-hint {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  margin: 0 0 16px;
  border-radius: var(--radius-md, 12px);
  background: linear-gradient(135deg, rgba(13, 148, 136, 0.08), rgba(20, 184, 166, 0.05));
  border: 1px solid rgba(13, 148, 136, 0.25);
  color: var(--slate-700, #334155);
  font-size: 0.8125rem;
  line-height: 1.45;
}

.qa-blank-slate-hint i {
  color: var(--primary-500, #14b8a6);
  font-size: 1rem;
  flex: 0 0 auto;
}

.qa-blank-slate-hint strong {
  font-weight: 600;
  color: var(--slate-800, #1f2937);
}

body.dark-mode .qa-blank-slate-hint {
  background: linear-gradient(135deg, rgba(20, 184, 166, 0.12), rgba(20, 184, 166, 0.06));
  border-color: rgba(20, 184, 166, 0.35);
  color: var(--slate-200);
}

body.dark-mode .qa-blank-slate-hint strong {
  color: var(--slate-100);
}

.qa-quota-progress-row.qa-row-placeholder .qa-quota-progress-fill {
  opacity: 0.35;
}
.qa-quota-progress-row.qa-row-placeholder .qa-hour-input {
  color: var(--text-secondary, #6b7280);
  font-style: italic;
}
.qa-quota-progress-row.qa-row-placeholder .qa-quota-used em {
  font-style: italic;
  opacity: 0.7;
}

/* ============================================
   QUOTAS TAB
   ============================================ */

.qa-quota-table-wrapper {
  overflow-x: auto;
  margin-bottom: 20px;
}

.qa-quota-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
}

.qa-quota-table th {
  padding: 10px 14px;
  font-weight: 600;
  color: var(--text-secondary, #6b7280);
  text-align: center;
  border-bottom: 2px solid var(--border-subtle, #e5e7eb);
  font-size: 0.8125rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.qa-quota-table th:first-child {
  text-align: left;
}

.qa-quota-table td {
  padding: 10px 14px;
  border-bottom: 1px solid var(--border-subtle, #e5e7eb);
  text-align: center;
  vertical-align: middle;
}

.qa-quota-table td:first-child {
  text-align: left;
  font-weight: 500;
  color: var(--text-primary, #111827);
}

.qa-quota-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
}

.qa-quota-cell input[type="number"] {
  width: 64px;
  text-align: center;
  padding: 6px 8px;
  border: 1px solid var(--border-default, #d1d5db);
  border-radius: var(--radius-sm, 4px);
  font-size: 0.875rem;
  background: var(--surface-primary, #fff);
  color: var(--text-primary, #111827);
}

.qa-quota-cell input[type="number"]:focus {
  border-color: var(--primary-color, #14b8a6);
  outline: none;
  box-shadow: var(--focus-ring-shadow);
}

.qa-quota-used {
  font-size: 0.75rem;
  color: var(--text-tertiary, #9ca3af);
}

.qa-quota-used.over-quota {
  color: var(--status-busy, #64748b);
  font-weight: 600;
}

.qa-quota-period-selector {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 16px;
  font-size: 0.875rem;
}

.qa-quota-period-selector label {
  color: var(--text-secondary, #6b7280);
  font-weight: 500;
}

.qa-quota-period-selector select {
  padding: 6px 10px;
  border: 1px solid var(--border-default, #d1d5db);
  border-radius: var(--radius-sm, 4px);
  font-size: 0.875rem;
  background: var(--surface-primary, #fff);
}

/* ============================================
   AUTO-ASSIGN TAB
   ============================================ */

.qa-assign-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  margin-bottom: 24px;
  padding-bottom: 20px;
  border-bottom: 1px solid var(--border-subtle, #e5e7eb);
}

.qa-control-group {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.qa-control-group label {
  font-size: 0.8125rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--text-secondary, #6b7280);
}

.qa-control-group input[type="date"] {
  padding: 10px 14px;
  border: 1.5px solid var(--border-default, #d1d5db);
  border-radius: var(--radius-lg, 14px);
  font-size: 0.9375rem;
  background: var(--surface-primary, #fff);
  color: var(--text-primary, #111827);
  transition: all var(--transition-fast, 0.15s);
}

.qa-control-group input[type="date"]:focus {
  border-color: var(--primary-400, #14b8a6);
  outline: none;
  box-shadow: var(--focus-ring-shadow);
}

.qa-checkbox-group {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.qa-checkbox-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.875rem;
  color: var(--text-primary, #111827);
  cursor: pointer;
}

.qa-checkbox-label input[type="checkbox"] {
  accent-color: var(--primary-color, #14b8a6);
}

/* In-tab action bar — a CTA row appended at the
   bottom of a tab's body. Visually distinct from
   the (future) modal-level sticky .qa-modal-action-bar:
   no border-top, no surface bg, just spacing. */
.qa-action-bar {
  display: flex;
  gap: 12px;
  justify-content: flex-end;
  align-items: center;
  padding: 16px 0 4px;
  margin-top: 8px;
}

.qa-action-centered {
  justify-content: center;
}

/* Buttons - matches platform .propose-btn pattern */
.qa-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 18px;
  border: none;
  border-radius: var(--radius-full, 9999px);
  font-size: 0.875rem;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.15s ease;
}

.qa-btn i {
  font-size: 0.8125rem;
}

/* THE APP'S PRIMARY, NOT A DARKER COUSIN (2026-09-24, owner: "The buttons
   seem a wrong green"). This faded teal into --primary-600, a deep green,
   while every .btn-primary in the app fades teal into cyan (--accent-500).
   Measured side by side: #14b8a6->#0d9488 here vs #14b8a6->#06b6d4 there. */
.qa-btn-primary {
  background: linear-gradient(135deg, var(--primary-500, #14b8a6) 0%, var(--accent-500, #06b6d4) 100%);
  color: #fff;
}

.qa-btn-primary:hover {
  background: linear-gradient(135deg, var(--primary-600, #0d9488) 0%, var(--accent-600, #0891b2) 100%);
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(20, 184, 166, 0.3);
}

.qa-btn-secondary {
  background: none;
  color: var(--text-secondary, #4b5563);
  border: 1px solid var(--border-default, #d1d5db);
}

.qa-btn-secondary:hover {
  background: var(--surface-tertiary, #f3f4f6);
  color: var(--text-primary, #111827);
}

.qa-btn-danger {
  background: none;
  color: var(--status-busy, #64748b);
  border: 1px solid rgba(100, 116, 139, 0.3);
  border: 1px solid color-mix(in srgb, var(--status-busy, #64748b) 30%, transparent);
}

.qa-btn-danger:hover {
  background: rgba(239, 68, 68, 0.08);
}

.qa-btn-sm {
  padding: 6px 12px;
  font-size: 0.8125rem;
}

/* Preview table */
.qa-preview-section {
  margin-top: 20px;
}

.qa-preview-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.qa-preview-header h3 {
  font-size: 1rem;
  font-weight: 600;
  color: var(--text-primary, #111827);
  margin: 0;
}

.qa-preview-stats {
  display: flex;
  gap: 16px;
  margin-bottom: 18px;
  flex-wrap: wrap;
}

.qa-stat-card {
  padding: 14px 18px;
  border-radius: var(--radius-md, 12px);
  background: var(--surface-secondary, #f9fafb);
  border: 1px solid var(--border-subtle, #e5e7eb);
  text-align: center;
  min-width: 100px;
}

.qa-stat-value {
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--primary-color, #14b8a6);
}

.qa-stat-label {
  font-size: 0.75rem;
  color: var(--text-secondary, #6b7280);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  margin-top: 3px;
}

.qa-preview-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
}

.qa-preview-table th {
  padding: 10px 14px;
  font-weight: 600;
  color: var(--text-secondary, #6b7280);
  text-align: left;
  border-bottom: 2px solid var(--border-subtle, #e5e7eb);
  font-size: 0.8125rem;
  text-transform: uppercase;
}

.qa-preview-table td {
  padding: 10px 14px;
  border-bottom: 1px solid var(--border-subtle, #e5e7eb);
  color: var(--text-primary, #111827);
}

.qa-preview-table tr:hover {
  background: var(--surface-secondary, #f9fafb);
}

/* Fairness indicator dots */
.qa-fairness-dot {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  vertical-align: middle;
  margin-right: 5px;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.9);
}

/* Fairness band swatch colours pull from the canonical 9-step ramp in
   css/fairness-view.css (--fv-l1..l9), so the modal speaks the same colour
   vocabulary as the fairness panel + per-row burden shading. Memory
   `traffic_light_palette.md` is the contract. */
.qa-fairness-excellent { background: var(--fv-l2, #15803d); }
.qa-fairness-good { background: var(--fv-l3, #16a34a); }
.qa-fairness-fair { background: var(--fv-l5, #fbbf24); }
.qa-fairness-attention { background: var(--fv-l6, #f59e0b); }
.qa-fairness-critical { background: var(--fv-l8, #dc2626); }
/* Audit-2026-05-30-03-23: degenerate-input / no-coverage case. Neutral
   grey so a 0-shift preview doesn't paint a green "Excellent" pill. */
.qa-fairness-no-data { background: var(--text-muted, #94a3b8); }

/* Fairness label badges in preview stats */
.qa-stat-value .qa-fairness-dot {
  width: 10px;
  height: 10px;
}

.qa-stat-card:has(.qa-fairness-dot) .qa-stat-value {
  font-size: 0.9375rem;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: 14px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

/* Pill text + tint derive from the same --fv-l* ramp the swatch reads.
   color-mix keeps the text legible against light/dark backgrounds without
   hand-tuning per-band hex values. */
.qa-stat-card:has(.qa-fairness-excellent) .qa-stat-value {
  background: rgba(21, 128, 61, 0.15);
  background: color-mix(in srgb, var(--fv-l2, #15803d) 15%, transparent);
  color: #16773c;
  color: color-mix(in srgb, var(--fv-l2, #15803d) 90%, var(--text-primary, #1f2937));
}

.qa-stat-card:has(.qa-fairness-good) .qa-stat-value {
  background: rgba(22, 163, 74, 0.15);
  background: color-mix(in srgb, var(--fv-l3, #16a34a) 15%, transparent);
  color: #179748;
  color: color-mix(in srgb, var(--fv-l3, #16a34a) 90%, var(--text-primary, #1f2937));
}

.qa-stat-card:has(.qa-fairness-fair) .qa-stat-value {
  background: rgba(251, 191, 36, 0.18);
  background: color-mix(in srgb, var(--fv-l5, #fbbf24) 18%, transparent);
  color: #cfa128;
  color: color-mix(in srgb, var(--fv-l5, #fbbf24) 80%, var(--text-primary, #1f2937));
}

.qa-stat-card:has(.qa-fairness-attention) .qa-stat-value {
  background: rgba(245, 158, 11, 0.18);
  background: color-mix(in srgb, var(--fv-l6, #f59e0b) 18%, transparent);
  color: #d58c12;
  color: color-mix(in srgb, var(--fv-l6, #f59e0b) 85%, var(--text-primary, #1f2937));
}

.qa-stat-card:has(.qa-fairness-critical) .qa-stat-value {
  background: rgba(220, 38, 38, 0.15);
  background: color-mix(in srgb, var(--fv-l8, #dc2626) 15%, transparent);
  color: var(--fv-l8, #dc2626);
}

.qa-stat-card:has(.qa-fairness-no-data) .qa-stat-value {
  background: rgba(148, 163, 184, 0.15);
  background: color-mix(in srgb, var(--text-muted, #94a3b8) 15%, transparent);
  color: var(--text-secondary, #475569);
}

/* Warnings — canonical flex-amber (memory `traffic_light_palette.md`). */
/* B1: persistent "Local only — not synced" banner at the top of the modal.
   Amber (flex token) = caution, not error-red — committing locally isn't a
   failure, but the admin must know it didn't reach the team. */
.qa-sync-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 12px;
  padding: 10px 14px;
  border-radius: var(--radius-md, 8px);
  font-size: 0.8125rem;
  line-height: 1.4;
  color: var(--text-primary, #1e293b);
  background: rgba(251, 191, 36, 0.14);
  background: color-mix(in srgb, var(--status-flex, #fbbf24) 14%, transparent);
  border: 1px solid rgba(251, 191, 36, 0.35);
  border: 1px solid color-mix(in srgb, var(--status-flex, #fbbf24) 35%, transparent);
}
.qa-sync-banner i {
  color: var(--status-flex, #d97706);
  flex: 0 0 auto;
}
.dark-mode .qa-sync-banner {
  color: var(--text-primary, #e2e8f0);
  background: rgba(251, 191, 36, 0.18);
  background: color-mix(in srgb, var(--status-flex, #fbbf24) 18%, transparent);
}

/* READ-ONLY EXPLANATION (2026-08-14, user: "this blank version with no options
   was discovered on mobile enterprise tier. no way to do anything by ui").
   Hiding the three write tabs left an empty state whose CTA jumped to a tab
   that was no longer rendered. This note says WHICH of the three reasons
   applies. Neutral slate rather than the amber sync banner: not knowing your
   plan yet, or not being an admin, is a state of affairs, not a warning. */
.qa-readonly-note {
  display: flex;
  align-items: flex-start;
  gap: 10px 12px;
  margin: 0 0 12px;
  padding: 12px 14px;
  border-radius: var(--radius-md, 8px);
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--text-primary, #1e293b);
  background: rgba(226, 232, 240, 0.55);
  background: color-mix(in srgb, var(--status-empty, #e2e8f0) 55%, transparent);
  border: 1px solid rgba(148, 163, 184, 0.4);
  border: 1px solid color-mix(in srgb, var(--slate-400, #94a3b8) 40%, transparent);
}
.qa-readonly-note i {
  flex: 0 0 auto;
  margin-top: 2px;
  color: var(--slate-500, #64748b);
}
.qa-readonly-note .qa-readonly-retry,
.qa-readonly-note .qa-readonly-upgrade {
  flex: 0 0 auto;
  margin-left: auto;
  padding: 5px 12px;
  min-height: 32px;
  border-radius: var(--radius-md, 8px);
  border: 1px solid var(--slate-300, #cbd5e1);
  background: var(--white, #fff);
  color: var(--text-primary, #1e293b);
  font-size: 0.8125rem;
  font-weight: 600;
  cursor: pointer;
}
.qa-readonly-note .qa-readonly-retry:hover {
  background: var(--slate-50, #f8fafc);
  border-color: var(--slate-400, #94a3b8);
}
/* THE UPGRADE BUTTON HAD NO RULES AT ALL (2026-09-09). It is emitted as
   `.qa-readonly-upgrade` while every rule here named `.qa-readonly-retry`,
   so the one way forward on this screen rendered as a bare UA-default button:
   square corners, grey, no touch height, and none of the phone or dark-mode
   treatment its sibling gets. It is the only action on a read-only screen, so
   it is painted as the primary action rather than another muted control. */
.qa-readonly-note .qa-readonly-upgrade {
  border-color: transparent;
  background: var(--primary-600, #0d9488);
  color: var(--white, #fff);
}
.qa-readonly-note .qa-readonly-upgrade:hover {
  background: var(--primary-700, #0f766e);
  border-color: transparent;
}
.qa-readonly-note .qa-readonly-upgrade:focus-visible {
  outline: 2px solid var(--primary-600, #0d9488);
  outline-offset: 2px;
}

/* The message is the note's body, so it takes the free width and the lock
   icon keeps its first line instead of claiming a line of its own. A basis of
   `auto` measures the sentence at its natural width, which cannot fit beside
   the icon inside the dismiss-button padding, so `flex-wrap: wrap` pushed it
   to the next line and spent a whole phone line on one 14px glyph. A zero
   basis lets it shrink onto the icon's line and take the width that is left. */
.qa-readonly-note > span {
  flex: 1 1 0;
  min-width: 0;
}

/* On a phone the note + button will not sit on one line without cramping. */
@media (max-width: 640px) {
  .qa-readonly-note { flex-wrap: wrap; }
  /* The sentence takes the rest of its own row, so the button below cannot
     shrink up beside it. Without this the span's `flex: 1 1 0` lets both fit
     on one line and the button's 100% basis never forces the wrap. */
  .qa-readonly-note > span { flex: 1 1 calc(100% - 24px); }
  /* NOT FULL-BLEED, BUT STILL ITS OWN ROW (2026-09-09). `width:100%` made
     a 316px slab the loudest element in a note whose job is to explain a
     state. Sizing it to its label alone was worse: it then fitted BESIDE the
     sentence and squeezed the message into a narrow four-line column. So
     force the wrap with a full-width flex line, then let the button size to
     its label inside it — the message keeps the width, the button follows it
     on its own row and reads as the note's follow-up, not a page action. */
  .qa-readonly-note .qa-readonly-retry,
  .qa-readonly-note .qa-readonly-upgrade {
    flex: 0 0 100%;
    align-self: flex-start;
    margin-left: 34px; /* clears the lock icon, aligns under the sentence */
    width: auto;
    max-width: max-content;
    min-height: 44px; /* touch target */
    padding-inline: 18px;
  }
}
.dark-mode .qa-readonly-note {
  color: var(--text-primary, #e2e8f0);
  background: rgba(51, 65, 85, 0.55);
  background: color-mix(in srgb, var(--slate-700, #334155) 55%, transparent);
  border-color: rgba(100, 116, 139, 0.45);
  border-color: color-mix(in srgb, var(--slate-500, #64748b) 45%, transparent);
}
.dark-mode .qa-readonly-note .qa-readonly-retry {
  background: var(--slate-800, #1e293b);
  border-color: var(--slate-600, #475569);
  color: var(--slate-100, #f1f5f9);
}
/* Dark mode keeps the upgrade button teal (the lighter ramp), not slate —
   it is still the only action on the screen. */
.dark-mode .qa-readonly-note .qa-readonly-upgrade {
  background: var(--primary-600, #14b8a6);
  border-color: transparent;
  color: var(--slate-900, #0f172a);
}
.dark-mode .qa-readonly-note .qa-readonly-upgrade:hover {
  background: var(--primary-500, #2dd4bf);
}

.qa-warnings {
  margin-top: 16px;
  padding: 12px 16px;
  border-radius: var(--radius-md, 8px);
  background: rgba(251, 191, 36, 0.1);
  background: color-mix(in srgb, var(--status-flex, #fbbf24) 10%, transparent);
  border: 1px solid rgba(251, 191, 36, 0.25);
  border: 1px solid color-mix(in srgb, var(--status-flex, #fbbf24) 25%, transparent);
}

.qa-warnings-title {
  font-size: 0.875rem;
  font-weight: 600;
  color: #cfa128;
  color: color-mix(in srgb, var(--status-flex, #fbbf24) 80%, var(--text-primary, #1f2937));
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.qa-warnings-list {
  list-style: none;
  padding: 0;
  margin: 0;
  font-size: 0.8125rem;
  color: #b9922a;
  color: color-mix(in srgb, var(--status-flex, #fbbf24) 70%, var(--text-primary, #1f2937));
  max-height: 120px;
  overflow-y: auto;
}

.qa-warnings-list li {
  padding: 2px 0;
}

/* High-severity warning block (P1.2 — sleep-hour gate). Uses the canonical
   --status-sleep token (indigo) because the warning code is SLEEP_HOUR; red
   is reserved for confirmed conflicts (--status-busy) per
   traffic_light_palette.md. Falls back to literal indigo if the token isn't
   loaded (e.g. tests). */
.qa-warnings-high {
  background: rgba(124, 58, 237, 0.1);
  background: color-mix(in srgb, var(--status-sleep, #7c3aed) 10%, transparent);
  border-color: rgba(124, 58, 237, 0.3);
  border-color: color-mix(in srgb, var(--status-sleep, #7c3aed) 30%, transparent);
}
.qa-warnings-high .qa-warnings-title {
  color: var(--status-sleep, #7c3aed);
}
.qa-warnings-high .qa-warnings-list {
  color: #6e37d2;
  color: color-mix(in srgb, var(--status-sleep, #7c3aed) 85%, var(--text-primary, #1f2937));
}
.qa-ack-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  font-size: 0.8125rem;
  color: var(--text-primary, #1f2937);
  cursor: pointer;
}
.qa-ack-row input[type="checkbox"] {
  cursor: pointer;
}

/* ============================================
   HISTORY TAB
   ============================================ */

.qa-history-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.qa-history-item {
  padding: 16px 20px;
  border-radius: var(--radius-md, 12px);
  background: var(--surface-secondary, #f9fafb);
  border: 1px solid var(--border-subtle, #e5e7eb);
  transition: background 0.15s;
}

.qa-history-item:hover {
  background: var(--surface-tertiary, #f3f4f6);
}

.qa-history-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

.qa-history-date {
  font-weight: 600;
  font-size: 0.9375rem;
  color: var(--text-primary, #111827);
}

.qa-history-status {
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  padding: 3px 10px;
  border-radius: 10px;
}

.qa-history-status.committed {
  background: rgba(22, 163, 74, 0.12);
  background: color-mix(in srgb, var(--status-working, #16a34a) 12%, transparent);
  color: var(--status-working, #16a34a);
}

.qa-history-status.rolled-back {
  background: rgba(100, 116, 139, 0.12);
  background: color-mix(in srgb, var(--status-busy, #64748b) 12%, transparent);
  color: var(--status-busy, #64748b);
}

.qa-history-status.preview {
  background: rgba(251, 191, 36, 0.12);
  background: color-mix(in srgb, var(--status-flex, #fbbf24) 12%, transparent);
  color: #c49a29;
  color: color-mix(in srgb, var(--status-flex, #fbbf24) 75%, var(--text-primary, #1f2937));
}

.qa-run-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin-bottom: 12px;
}

.qa-run-stat {
  font-size: 0.8125rem;
  color: var(--text-secondary, #6b7280);
}

.qa-run-stat strong {
  color: var(--text-primary, #111827);
}

.qa-history-actions {
  display: flex;
  gap: 8px;
  margin-top: 8px;
}

.qa-history-detail {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border-subtle, #e5e7eb);
}

/* P4.D — Audit trail disclosure on each run in the History tab. Plain
   monospace list reads as a log; matches the chronological-events feel
   of CLI output rather than competing with the rich stat cards above. */
.qa-history-audit {
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px dashed var(--border-subtle, #e5e7eb);
  font-size: 0.8125rem;
  color: var(--text-secondary, #6b7280);
}
.qa-history-audit summary {
  cursor: pointer;
  user-select: none;
  padding: 4px 0;
  display: flex;
  align-items: center;
  gap: 6px;
}
.qa-history-audit summary i {
  font-size: 0.75rem;
  opacity: 0.7;
}
.qa-history-audit-list {
  list-style: none;
  padding: 8px 0 0 0;
  margin: 0;
  max-height: 240px;
  overflow-y: auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.75rem;
  line-height: 1.4;
}
.qa-history-audit-list li {
  padding: 2px 0;
  color: var(--text-primary, #1f2937);
}
.qa-audit-when {
  color: var(--text-tertiary, #9ca3af);
  margin-right: 6px;
}
.qa-audit-actor {
  font-weight: 600;
  margin-right: 4px;
}
.qa-audit-action {
  color: var(--text-secondary, #6b7280);
}
.qa-audit-reason {
  color: var(--text-tertiary, #9ca3af);
  font-style: italic;
}
.qa-audit-more {
  padding-top: 6px;
  font-style: italic;
  color: var(--text-tertiary, #9ca3af);
}

.qa-history-toggle {
  font-size: 0.8125rem;
  color: var(--primary-color, #14b8a6);
  cursor: pointer;
  background: none;
  border: none;
  padding: 0;
  font-weight: 500;
}

.qa-history-toggle:hover {
  text-decoration: underline;
}

/* ============================================
   REDESIGNED UI — SHARED
   ============================================ */

/* Section label (uppercase mini-header) */
.qa-section-label {
  font-size: 0.875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--text-secondary, #6b7280);
  margin-bottom: 10px;
  margin-top: 18px;
}

.qa-section-label:first-child { margin-top: 0; }

/* Colored dot for shift types — reads --qa-type-color
   from the nearest ancestor that sets it; no inline
   style="background:..." needed. */
.qa-shift-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--qa-type-color, var(--slate-300, #cbd5e1));
}

/* Input suffix text ("h/week", "hours") */
.qa-input-suffix {
  font-size: 0.875rem;
  color: var(--text-secondary, #6b7280);
  white-space: nowrap;
}

/* Hours number input */
.qa-hours-input {
  width: 68px;
  text-align: center;
  padding: 8px 10px;
  border: 1.5px solid var(--border-default, #d1d5db);
  border-radius: var(--radius-lg, 14px);
  font-size: 0.9375rem;
  background: var(--surface-primary, #fff);
  color: var(--text-primary, #111827);
  transition: all var(--transition-fast, 0.15s);
}

.qa-hours-input:focus {
  border-color: var(--primary-400, #14b8a6);
  outline: none;
  box-shadow: var(--focus-ring-shadow);
}

/* Large button */
.qa-btn-lg {
  padding: 10px 22px;
  font-size: 0.9375rem;
}

/* Centered action bar */
.qa-action-centered {
  justify-content: center;
}

/* ============================================
   TAB 1 REDESIGN: PRESET & DURATION CHIPS
   ============================================ */

/* Preset chip container */
.qa-preset-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 6px;
}

/* Duration chip container */
.qa-duration-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 6px;
}

/* Custom duration input row */
.qa-custom-duration-input {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 6px;
  margin-bottom: 6px;
  position: relative;
}

.qa-custom-duration-input input[type="number"] {
  width: 110px;
  padding: 10px 32px 10px 14px;
  border: 1.5px solid var(--border-default, #d1d5db);
  border-radius: var(--radius-lg, 14px);
  font-size: 0.9375rem;
  background: var(--surface-primary, #fff);
  color: var(--text-primary, #111827);
  transition: all var(--transition-fast, 0.15s);
  -moz-appearance: textfield;
}

.qa-custom-duration-input input[type="number"]::-webkit-outer-spin-button,
.qa-custom-duration-input input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/* Custom stepper buttons */
.qa-duration-stepper {
  position: absolute;
  right: 4px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.qa-duration-stepper button {
  width: 22px;
  height: 16px;
  border: 1px solid var(--border-default, #d1d5db);
  background: var(--surface-secondary, #f9fafb);
  color: var(--text-primary, #374151);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  transition: all 0.1s;
  padding: 0;
}

.qa-duration-stepper button:first-child {
  border-radius: 4px 4px 0 0;
}

.qa-duration-stepper button:last-child {
  border-radius: 0 0 4px 4px;
}

.qa-duration-stepper button:hover {
  background: var(--primary-100, #ccfbf1);
  color: var(--primary-600, #0d9488);
}

.qa-custom-duration-input input:focus {
  border-color: var(--primary-400, #14b8a6);
  outline: none;
  box-shadow: var(--focus-ring-shadow);
}

/* Inline fields row (name + short + color) */
.qa-inline-fields {
  display: flex;
  gap: 12px;
  align-items: flex-end;
  margin-top: 14px;
  margin-bottom: 10px;
  flex-wrap: wrap;
}

.qa-field {
  flex: 1;
  min-width: 120px;
}

.qa-field input[type="text"] {
  width: 100%;
  padding: 10px 14px;
  border: 1.5px solid var(--border-default, #d1d5db);
  border-radius: var(--radius-lg, 14px);
  font-size: 0.9375rem;
  background: var(--surface-primary, #fff);
  color: var(--text-primary, #111827);
  transition: all var(--transition-fast, 0.15s);
}

.qa-field input:focus {
  border-color: var(--primary-400, #14b8a6);
  outline: none;
  box-shadow: var(--focus-ring-shadow);
}

.qa-field-narrow {
  flex: 0 0 70px;
  min-width: 70px;
}

.qa-field-color {
  flex: 0 0 50px;
  min-width: 50px;
}

.qa-field-color input[type="color"] {
  width: 40px;
  height: 40px;
  padding: 2px;
  border: 1.5px solid var(--border-default, #d1d5db);
  border-radius: var(--radius-md, 12px);
  cursor: pointer;
  background: none;
  transition: all var(--transition-fast, 0.15s);
}

.qa-field-color input[type="color"]:hover {
  border-color: var(--primary-500, #14b8a6);
  transform: scale(1.05);
}

/* ============================================
   TAB 2 REDESIGN: MEMBER CARDS & QUOTAS
   ============================================ */

/* Period selector */
.qa-period-selector {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}

.qa-period-chips {
  display: flex;
  gap: 8px;
}

/* Member cards container */
.qa-member-cards {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 20px;
}

/* Single member card — mirrors .member-selection-item
   chrome (style.css:37794) so the team-hours row matches
   the rest of the app's "avatar + name + meta" cards. */
.qa-member-card {
  border-radius: var(--radius-md, 12px);
  background: var(--slate-50, #f8fafc);
  border: 1px solid var(--slate-200, #e2e8f0);
  overflow: hidden;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.qa-member-card:hover {
  border-color: var(--primary-300, #5eead4);
  box-shadow: 0 1px 3px rgba(20, 184, 166, 0.08);
}

.qa-member-card-header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--slate-200, #e2e8f0);
}

/* The inner <label> wrapping checkbox + avatar + info
   should fill available space; the total badge sits at
   the trailing edge. */
.qa-member-card-header .member-selection-item {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0;
  padding: 0;
  background: transparent;
  border: none;
  flex: 1;
  min-width: 0;
  cursor: pointer;
}

.qa-member-card-header .qa-member-toggle {
  width: var(--checkbox-size, 18px);
  height: var(--checkbox-size, 18px);
  accent-color: var(--primary-500, #14b8a6);
  flex-shrink: 0;
  cursor: pointer;
}

.qa-member-card-header .member-avatar {
  width: 40px;
  height: 40px;
  border-radius: var(--radius-md, 12px);
  background: linear-gradient(135deg, var(--primary-500, #14b8a6), var(--accent-500, #06b6d4));
  color: #fff;
  font-size: 0.9375rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.qa-member-card-header .member-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}

.qa-member-card-header .member-name {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--slate-800, #1f2937);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.qa-member-card-header .member-tz {
  font-size: 0.75rem;
  color: var(--slate-500, #6b7280);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

body.dark-mode .qa-member-card {
  background: rgba(15, 23, 42, 0.4);
  border-color: var(--slate-700);
}

body.dark-mode .qa-member-card:hover {
  border-color: rgba(20, 184, 166, 0.4);
  box-shadow: 0 1px 3px rgba(20, 184, 166, 0.12);
}

body.dark-mode .qa-member-card-header {
  border-bottom-color: var(--slate-700);
}

body.dark-mode .qa-member-card-header .member-name {
  color: var(--slate-100);
}

body.dark-mode .qa-member-card-header .member-tz {
  color: var(--slate-400);
}

/* Quota rows inside member card */
.qa-member-quotas {
  padding: 10px 18px;
}

/* ── Per-member date exclusions (Hours-tab card footer) ────────── */
.qa-member-exclusions {
  padding: 8px 18px 10px;
  border-top: 1px solid var(--border-subtle, rgba(229, 231, 235, 0.5));
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.qa-exclusions-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.qa-exclusions-label {
  font-size: 0.75rem;
  color: var(--slate-500, #6b7280);
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.qa-exclusions-label i {
  font-size: 0.75rem;
  opacity: 0.75;
}

.qa-exclusion-add-btn {
  width: 24px;
  height: 24px;
  border-radius: var(--radius-sm, 6px);
  border: 1px dashed var(--slate-300, #cbd5e1);
  background: transparent;
  color: var(--slate-500, #6b7280);
  font-size: 0.75rem;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}

.qa-exclusion-add-btn:hover {
  border-color: var(--primary-400, #2dd4bf);
  color: var(--primary-600, #0d9488);
  background: rgba(20, 184, 166, 0.06);
}

.qa-exclusion-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.qa-exclusion-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 8px;
  border-radius: 999px;
  /* Neutral slate — an exclusion is not an error, it's a planned skip.
     Deliberately not the busy-red status token. */
  background: var(--slate-100, #f1f5f9);
  border: 1px solid var(--slate-200, #e2e8f0);
  font-size: 0.75rem;
  color: var(--slate-700, #334155);
  line-height: 1.4;
}

.qa-exclusion-chip i {
  font-size: 0.6875rem;
  color: var(--slate-400, #94a3b8);
}

.qa-exclusion-chip-remove {
  border: none;
  background: transparent;
  color: var(--slate-400, #94a3b8);
  font-size: 0.875rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 0 0 2px;
  transition: color 0.15s ease;
}

.qa-exclusion-chip-remove:hover {
  color: var(--status-busy, #64748b);
}

.qa-exclusion-add {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.qa-exclusion-add[hidden] {
  display: none;
}

.qa-exclusion-date,
.qa-exclusion-reason {
  padding: 5px 8px;
  border-radius: var(--radius-sm, 6px);
  border: 1px solid var(--slate-300, #cbd5e1);
  background: var(--surface, #fff);
  font-size: 0.8125rem;
  color: var(--slate-800, #1f2937);
}

.qa-exclusion-reason {
  flex: 1;
  min-width: 120px;
}

.qa-exclusion-date:focus,
.qa-exclusion-reason:focus {
  outline: none;
  border-color: var(--primary-400, #2dd4bf);
  box-shadow: 0 0 0 2px rgba(20, 184, 166, 0.15);
}

/* Dark mode */
body.dark-mode .qa-member-exclusions {
  border-top-color: var(--slate-700);
}

body.dark-mode .qa-exclusions-label {
  color: var(--slate-400);
}

body.dark-mode .qa-exclusion-add-btn {
  border-color: var(--slate-600);
  color: var(--slate-400);
}

body.dark-mode .qa-exclusion-add-btn:hover {
  border-color: rgba(20, 184, 166, 0.5);
  color: var(--primary-300, #5eead4);
  background: rgba(20, 184, 166, 0.1);
}

body.dark-mode .qa-exclusion-chip {
  background: rgba(30, 41, 59, 0.6);
  border-color: var(--slate-700);
  color: var(--slate-200);
}

body.dark-mode .qa-exclusion-date,
body.dark-mode .qa-exclusion-reason {
  background: rgba(15, 23, 42, 0.6);
  border-color: var(--slate-600);
  color: var(--slate-100);
}

.qa-quota-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 0;
  gap: 12px;
}

.qa-quota-row + .qa-quota-row {
  border-top: 1px solid var(--border-subtle, rgba(229, 231, 235, 0.5));
}

.qa-quota-row-left {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 0.9375rem;
  color: var(--text-primary, #111827);
  min-width: 100px;
  flex: 0 0 auto;
  max-width: 140px;
  overflow: hidden;
}

.qa-quota-row-left > span:last-child {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.qa-quota-row-right {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: nowrap;
  justify-content: flex-end;
  flex: 1;
  min-width: 0;
}

/* Usage badge */
.qa-quota-used-badge {
  font-size: 0.75rem;
  color: var(--text-tertiary, #9ca3af);
  white-space: nowrap;
  flex-shrink: 0;
  min-width: 70px;
  text-align: right;
}

.qa-quota-used-badge.over-quota {
  color: var(--status-busy, #64748b);
  font-weight: 600;
}

/* ============================================
   VISUAL PROGRESS BARS (Quota visualization)
   ============================================ */

.qa-quota-progress-container {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
}

/* Quota progress row — borderless inside the member
   card chrome; the per-row --qa-type-color custom
   property feeds the dot + bar fill so no inline styles
   leak into the markup. */
.qa-quota-progress-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 14px;
  background: transparent;
  border-radius: 0;
  border: none;
}

.qa-quota-progress-row + .qa-quota-progress-row {
  border-top: 1px solid var(--slate-200, #e2e8f0);
}

body.dark-mode .qa-quota-progress-row + .qa-quota-progress-row {
  border-top-color: var(--slate-700, #374151);
}

.qa-quota-type-label {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 110px;
  max-width: 140px;
  flex-shrink: 0;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--slate-700, #334155);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

body.dark-mode .qa-quota-type-label {
  color: var(--slate-200, #e2e8f0);
}

.qa-quota-type-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--qa-type-color, var(--primary-500, #14b8a6));
  box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.04);
}

.qa-quota-progress-bar-wrapper {
  flex: 1;
  min-width: 120px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.qa-quota-progress-bar {
  height: 6px;
  background: var(--slate-200, #e2e8f0);
  border-radius: var(--radius-full, 9999px);
  overflow: hidden;
  position: relative;
}

body.dark-mode .qa-quota-progress-bar {
  background: rgba(255, 255, 255, 0.08);
}

.qa-quota-progress-fill {
  height: 100%;
  width: var(--qa-fill-pct, 0%);
  border-radius: var(--radius-full, 9999px);
  background: var(--qa-type-color, var(--primary-500, #14b8a6));
  transition: width 0.3s ease, background-color 0.15s ease;
  min-width: 2px;
}

.qa-quota-progress-row.over-quota .qa-quota-progress-fill {
  background: linear-gradient(90deg, #ef4444 0%, #dc2626 100%);
}

.qa-quota-progress-stats {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 0.75rem;
  color: var(--text-secondary, #6b7280);
}

.qa-quota-progress-value {
  font-weight: 600;
  color: var(--text-primary, #111827);
  min-width: 70px;
  text-align: right;
  flex-shrink: 0;
}

/* Status colors mirror STATUS_PRESENTATION canonical
   greens (#16a34a "working") and the canonical danger
   --error / #ef4444 from the design tokens. */
.qa-quota-progress-value.complete {
  color: var(--status-working, #16a34a);
}

.qa-quota-progress-value.over-quota {
  color: var(--error, #ef4444);
}

.qa-quota-status-icon {
  margin-left: 6px;
  font-size: 0.875rem;
}

.qa-quota-status-icon.complete {
  color: var(--status-working, #16a34a);
}

.qa-quota-status-icon.over-quota {
  color: var(--error, #ef4444);
}

/* Hour chips row below progress bar */
.qa-quota-chips-row {
  display: flex;
  align-items: center;
  gap: 6px;
  padding-left: 98px; /* Align with progress bar */
}

.qa-quota-chips-row .qa-hour-chips {
  flex-shrink: 0;
}

.qa-quota-chips-row .qa-hours-readout {
  margin-left: auto;
}

/* Member summary line */
.qa-member-summary {
  padding: 8px 14px;
  font-size: 0.8125rem;
  color: var(--text-secondary, #6b7280);
  border-top: 1px solid var(--border-subtle, #e5e7eb);
  background: var(--surface-tertiary, rgba(243, 244, 246, 0.5));
}

.qa-member-summary strong {
  color: var(--text-primary, #111827);
}

/* Quick-apply bar */
.qa-quick-assign-bar {
  padding: 14px 16px;
  border-radius: var(--radius-md, 12px);
  background: var(--surface-secondary, #f9fafb);
  border: 1px solid var(--border-subtle, #e5e7eb);
  margin-bottom: 16px;
}

.qa-quick-assign-bar .qa-section-label {
  margin-top: 0;
  margin-bottom: 10px;
}

.qa-quick-assign-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
}

.qa-quick-field {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.8125rem;
  color: var(--text-primary, #111827);
}

.qa-quick-field .qa-hours-readout,
.qa-quick-field .qa-quick-readout {
  width: 50px;
}

/* ============================================
   TAB 3 REDESIGN: DISTRIBUTE
   ============================================ */

/* Setup wrapper */
.qa-distribute-setup {
  margin-bottom: 16px;
}

/* Date range row */
.qa-date-range-row {
  display: flex;
  gap: 16px;
  margin-bottom: 8px;
  flex-wrap: wrap;
}

.qa-date-range-row .qa-control-group {
  /* Size each From/To field to its content rather than letting them grow.
     With flex:1 the two date groups absorbed all free space and shoved the
     trailing Refresh button hard against the right edge, reading as a
     right-aligned row. flex:0 0 auto keeps From / To / Refresh as a tidy
     left-packed cluster. The @media(max-width:640px) block still stacks
     them vertically. */
  flex: 0 0 auto;
  min-width: 140px;
}

/* Range quick-select chips */
.qa-range-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 14px;
}

/* Shift type toggle chips — same chip family as
   .qa-period-chip / .qa-bulk-preset, but the active
   state borrows the per-row --qa-type-color so the
   user can see which type they're toggling. */
.qa-shift-type-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 14px;
}

/* ⚠️.qa-workbench-types IS THE SAME WIDGET (2026-08-23, user: "ShiftSupportShift").
   The Schedule/workbench tab renders identical chip markup into
   .qa-workbench-types (quota-assignment-modal.js ~1585) while the Distribute
   tab uses .qa-shift-type-chips (~5064). Every chip rule in this file was
   scoped to the latter, so the workbench chips matched only a leftover
   checkbox-era `.qa-type-toggle` rule further down — no pill shape, no
   background, no separation — and consecutive labels read as one run-on string
   ("Shift" + "Support" + "Shift"). Both containers are listed on every chip
   rule from here down; keep them paired when adding rules. */
.qa-shift-type-chips .qa-type-toggle,
.qa-workbench-types .qa-type-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 32px;
  padding: 0 12px;
  border: 1px solid var(--slate-200, #e2e8f0);
  border-radius: var(--radius-full, 9999px);
  background: var(--white, #fff);
  color: var(--slate-600, #475569);
  font-family: inherit;
  font-size: 0.75rem;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  line-height: 1;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.15s ease;
}

.qa-shift-type-chips .qa-type-toggle:hover,
.qa-workbench-types .qa-type-toggle:hover {
  border-color: var(--primary-300, #5eead4);
  background: var(--primary-50, #f0fdfa);
  color: var(--primary-700, #0f766e);
  transform: translateY(-1px);
}

.qa-shift-type-chips .qa-type-toggle.active,
.qa-workbench-types .qa-type-toggle.active {
  border-color: var(--qa-type-color, var(--primary-500, #14b8a6));
  background: rgba(20, 184, 166, 0.15);
  background: color-mix(in srgb, var(--qa-type-color, var(--primary-500, #14b8a6)) 15%, transparent);
  /* Darkened toward black rather than the raw hue (2026-08-23). The hue is
     admin-choosable, and on a 15% tint of itself the lighter presets measured
     ~2-3:1 — amber #f59e0b was 1.96:1. 60% is the worst-case-safe value across
     every hue in play (4 CSS presets + 3 JS seeds + JS _PRESETS + arbitrary
     custom): worst case 4.93:1. Re-measure before raising it. */
  color: #094742;
  color: color-mix(in srgb, var(--qa-type-color, var(--primary-700, #0f766e)) 60%, #000);
  font-weight: 600;
}

.qa-shift-type-chips .qa-type-toggle i,
.qa-workbench-types .qa-type-toggle i {
  font-size: 0.6875rem;
}

body.dark-mode .qa-shift-type-chips .qa-type-toggle,
body.dark-mode .qa-workbench-types .qa-type-toggle {
  background: rgba(15, 23, 42, 0.4);
  border-color: var(--slate-700, #374151);
  color: var(--slate-300, #cbd5e1);
}

body.dark-mode .qa-shift-type-chips .qa-type-toggle:hover,
body.dark-mode .qa-workbench-types .qa-type-toggle:hover {
  border-color: rgba(20, 184, 166, 0.5);
  background: rgba(20, 184, 166, 0.12);
  color: var(--primary-300, #5eead4);
}

body.dark-mode .qa-shift-type-chips .qa-type-toggle.active,
body.dark-mode .qa-workbench-types .qa-type-toggle.active {
  background: rgba(20, 184, 166, 0.25);
  background: color-mix(in srgb, var(--qa-type-color, var(--primary-500)) 25%, transparent);
  color: #fff;
}

/* Member filter (details/summary) */
.qa-member-filter {
  margin-bottom: 14px;
  border-radius: var(--radius-md, 12px);
  background: var(--surface-secondary, #f9fafb);
  border: 1px solid var(--border-subtle, #e5e7eb);
  padding: 10px 14px;
}

.qa-member-filter summary {
  cursor: pointer;
  font-size: 0.875rem;
  color: var(--text-primary, #111827);
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 8px;
  list-style: none;
}

.qa-member-filter summary::-webkit-details-marker { display: none; }

.qa-member-filter summary::before {
  content: '\f054';
  font-family: 'Font Awesome 6 Free';
  font-weight: 900;
  font-size: 0.6875rem;
  transition: transform 0.15s;
  color: var(--text-tertiary, #9ca3af);
}

.qa-member-filter[open] summary::before {
  transform: rotate(90deg);
}

/* Preview — grouped by member */
.qa-preview-members {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 16px;
}

.qa-preview-member-card {
  border-radius: var(--radius-md, 12px);
  background: var(--surface-secondary, #f9fafb);
  border: 1px solid var(--border-subtle, #e5e7eb);
  overflow: hidden;
}

.qa-preview-member-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border-subtle, #e5e7eb);
}

.qa-preview-member-header .member-avatar {
  flex-shrink: 0;
}

.qa-preview-member-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.qa-preview-member-name {
  font-weight: 600;
  font-size: 0.875rem;
  color: var(--text-primary, #111827);
}

.qa-preview-member-summary {
  font-size: 0.75rem;
  color: var(--text-secondary, #6b7280);
}

/* Shift rows inside preview card */
.qa-preview-member-shifts {
  padding: 4px 14px 8px;
}

.qa-preview-shift-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 5px 0;
  font-size: 0.875rem;
}

.qa-preview-shift-row + .qa-preview-shift-row {
  border-top: 1px solid var(--border-subtle, rgba(229, 231, 235, 0.5));
}

.qa-preview-date {
  min-width: 110px;
  color: var(--text-primary, #111827);
  font-weight: 500;
}

.qa-preview-time {
  min-width: 110px;
  color: var(--text-secondary, #6b7280);
}

.qa-preview-type {
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--text-secondary, #6b7280);
  margin-left: auto;
}

/* Collapsible warnings */
.qa-warnings-collapsible {
  margin: 12px 0;
  border-radius: var(--radius-md, 12px);
  background: rgba(245, 158, 11, 0.08);
  border: 1px solid rgba(245, 158, 11, 0.2);
  padding: 10px 14px;
}

.qa-warnings-collapsible summary {
  cursor: pointer;
  font-size: 0.8125rem;
  font-weight: 600;
  color: #b45309;
  display: flex;
  align-items: center;
  gap: 6px;
  list-style: none;
}

.qa-warnings-collapsible summary::-webkit-details-marker { display: none; }

/* ============================================
   COLOR SWATCHES (Tab 1)
   ============================================ */

.qa-swatch-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 6px;
  margin-bottom: 10px;
}

.qa-color-swatch {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  border: 2px solid transparent;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.15s;
  padding: 0;
  background: none;
}

.qa-color-swatch:hover {
  transform: scale(1.1);
  border-color: var(--primary-500, #14b8a6);
  box-shadow: 0 2px 8px rgba(20, 184, 166, 0.3);
}

.qa-color-swatch.active {
  border-color: var(--primary-500, #14b8a6);
  box-shadow: 0 0 0 3px rgba(20, 184, 166, 0.2);
  transform: scale(1.05);
}

.qa-color-swatch .fa-check {
  color: #fff;
  font-size: 0.6875rem;
  opacity: 0;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}

.qa-color-swatch.active .fa-check {
  opacity: 1;
}

.qa-color-picker {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.qa-swatch-primary {
  display: flex;
  align-items: center;
}

.qa-color-expand {
  width: 28px;
  height: 28px;
  border-radius: 6px;
  border: 1.5px dashed var(--border-default, #d1d5db);
  background: var(--surface-secondary, #f9fafb);
  color: var(--text-tertiary, #9ca3af);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.75rem;
  transition: all 0.15s;
}

.qa-color-expand:hover {
  border-color: var(--primary-400, #14b8a6);
  color: var(--primary-500, #14b8a6);
  background: var(--surface-primary, #fff);
}

.qa-swatch-extended {
  padding-top: 4px;
  border-top: 1px solid var(--border-subtle, #e5e7eb);
  margin-top: 2px;
}

/* ============================================
   CONTRACT CHIPS (Tab 2)
   ============================================ */

.qa-contract-section {
  margin-bottom: 16px;
}

.qa-contract-section .qa-section-label {
  margin-bottom: 8px;
}

.qa-contract-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
}

/* ============================================
   HOUR CHIPS (Tab 2 quota rows)
   ============================================ */

.qa-hour-chips {
  display: flex;
  gap: 3px;
}

.qa-hour-chip {
  min-width: 32px;
  height: 26px;
  border-radius: var(--radius-full, 9999px);
  border: 1.5px solid var(--border-default, #e2e8f0);
  background: var(--surface-primary, #fff);
  color: var(--text-secondary, #475569);
  font-size: 0.75rem;
  font-weight: 600;
  cursor: pointer;
  padding: 0 6px;
  transition: all 0.15s;
  display: flex;
  align-items: center;
  justify-content: center;
}

.qa-hour-chip:hover {
  border-color: var(--primary-500, #14b8a6);
  color: var(--primary-600, #0d9488);
  transform: translateY(-1px);
}

.qa-hour-chip.active {
  color: #fff;
  border-color: transparent;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}

.qa-hours-readout {
  width: 56px;
  min-width: 56px;
  text-align: center;
  padding: 4px 8px;
  border: 1.5px solid var(--border-default, #d1d5db);
  border-radius: var(--radius-lg, 14px);
  font-size: 0.875rem;
  font-weight: 700;
  color: var(--text-primary, #111827);
  background: var(--surface-primary, #fff);
  transition: all var(--transition-fast, 0.15s);
  flex-shrink: 0;
}

.qa-hours-readout:focus {
  border-color: var(--primary-400, #14b8a6);
  outline: none;
  box-shadow: var(--focus-ring-shadow);
}

/* ============================================
   HOUR STEPPER COMPONENT
   ============================================ */

.qa-stepper-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 6px;
}

.qa-quota-used {
  font-size: 0.75rem;
  color: var(--text-secondary, #6b7280);
  min-width: 50px;
}

/* Numeric stepper — matches the radius + focus-ring
   token pattern of canonical .form-group input
   (style.css:15960). */
.qa-hour-stepper {
  display: inline-flex;
  align-items: center;
  border: 1.5px solid var(--slate-200, #e2e8f0);
  border-radius: var(--radius-md, 12px);
  overflow: hidden;
  background: var(--white, #fff);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.qa-hour-stepper:focus-within {
  border-color: var(--primary-400, #2dd4bf);
  box-shadow: var(--focus-ring-shadow);
}

.qa-step-btn {
  width: 30px;
  height: 30px;
  border: none;
  background: transparent;
  font-size: 1rem;
  font-weight: 600;
  color: var(--slate-600, #475569);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.qa-step-btn:hover {
  background: var(--primary-50, #f0fdfa);
  color: var(--primary-600, #0d9488);
}

.qa-step-btn:active {
  background: var(--primary-100, #ccfbf1);
}

.qa-hour-input {
  width: 44px;
  height: 30px;
  border: none;
  border-left: 1px solid var(--slate-200, #e2e8f0);
  border-right: 1px solid var(--slate-200, #e2e8f0);
  text-align: center;
  font-family: inherit;
  font-weight: 700;
  font-size: 0.8125rem;
  color: var(--slate-800, #1f2937);
  background: var(--white, #fff);
  -moz-appearance: textfield;
}

.qa-hour-input::-webkit-outer-spin-button,
.qa-hour-input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.qa-hour-input:focus {
  outline: none;
}

/* Compact stepper for quick apply bar */
.qa-hour-stepper-compact {
  border-radius: var(--radius-md, 8px);
}

.qa-hour-stepper-compact .qa-step-btn {
  width: 26px;
  height: 26px;
  font-size: 0.875rem;
}

.qa-hour-stepper-compact .qa-hour-input,
.qa-hour-stepper-compact .qa-quick-input {
  width: 40px;
  height: 26px;
  font-size: 0.875rem;
}

/* Member total badge — small chip-shaped count token. */
.qa-member-total-badge {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 10px;
  border-radius: var(--radius-full, 9999px);
  background: var(--slate-100, #f1f5f9);
  color: var(--slate-700, #334155);
  font-size: 0.75rem;
  font-weight: 700;
  flex-shrink: 0;
}

.qa-period-suffix-inline {
  font-size: 0.625rem;
  font-weight: 500;
  color: var(--slate-500, #94a3b8);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* A blank-slate total is a SUGGESTION, not a saved figure - the per-type
   rows below it already say "suggested", and without this the badge printed
   "40.5 hrs/wk" in full saved weight directly beneath a hint reading "No
   hours set yet". Lighter, outlined, so it reads as a proposal. */
.qa-member-total-badge.qa-total-suggested {
  background: transparent;
  border: 1px dashed var(--slate-300, #cbd5e1);
  color: var(--slate-500, #64748b);
  font-weight: 600;
}
body.dark-mode .qa-member-total-badge.qa-total-suggested {
  background: transparent;
  border-color: rgba(148, 163, 184, 0.35);
  color: var(--slate-400, #94a3b8);
}

/* Dark mode stepper */
body.dark-mode .qa-hour-stepper {
  background: rgba(15, 23, 42, 0.4);
  border-color: var(--slate-700, #374151);
}

body.dark-mode .qa-hour-stepper:focus-within {
  border-color: rgba(20, 184, 166, 0.6);
  box-shadow: var(--focus-ring-shadow);
}

body.dark-mode .qa-step-btn {
  color: var(--slate-300, #cbd5e1);
}

body.dark-mode .qa-step-btn:hover {
  background: rgba(20, 184, 166, 0.15);
  color: var(--primary-300, #5eead4);
}

body.dark-mode .qa-hour-input {
  background: transparent;
  color: var(--slate-100, #f1f5f9);
  border-left-color: var(--slate-700, #374151);
  border-right-color: var(--slate-700, #374151);
}

body.dark-mode .qa-member-total-badge {
  background: rgba(255, 255, 255, 0.06);
  color: var(--slate-200, #e2e8f0);
}

/* ============================================
   SCHEDULE TAB (Tab 4) — RETIRED
   ---------------------------------------------
   The standalone Schedule tab and its read-only Member Cards / Coverage
   Heatmap views were merged into the Workbench. The .qa-schedule-* rules
   below (member cards, type breakdown, progress, shift list, shift-type
   swatches) are now DEAD — no JS emits these classes. Left in place
   (harmless, unrendered) to avoid a risky multi-range delete during the
   launch pass; safe to remove wholesale in a dedicated cleanup.
   ============================================ */

.qa-schedule-controls {
  margin-bottom: 20px;
}

.qa-schedule-members {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* Schedule member cards — same chrome as Team Hours
   member cards (.qa-member-card). Avatar, name, meta
   layout matches the canonical .member-selection-item
   pattern (style.css:37794). */
.qa-schedule-member-card {
  background: var(--slate-50, #f8fafc);
  border: 1px solid var(--slate-200, #e2e8f0);
  border-radius: var(--radius-md, 12px);
  padding: 14px;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.qa-schedule-member-card:hover {
  border-color: var(--primary-300, #5eead4);
  box-shadow: 0 1px 3px rgba(20, 184, 166, 0.08);
}

body.dark-mode .qa-schedule-member-card {
  background: rgba(15, 23, 42, 0.4);
  border-color: var(--slate-700);
}

body.dark-mode .qa-schedule-member-card:hover {
  border-color: rgba(20, 184, 166, 0.4);
}

.qa-schedule-member-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
}

.qa-schedule-member-header .member-avatar {
  width: 36px;
  height: 36px;
  border-radius: var(--radius-md, 10px);
  background: linear-gradient(135deg, var(--primary-500, #14b8a6), var(--accent-500, #06b6d4));
  color: #fff;
  font-size: 0.8125rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.qa-schedule-member-info {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.qa-schedule-member-name {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--slate-800, #1e293b);
}

.qa-schedule-member-meta {
  font-size: 0.75rem;
  color: var(--slate-500, #6b7280);
}

body.dark-mode .qa-schedule-member-name {
  color: var(--slate-100);
}

body.dark-mode .qa-schedule-member-meta {
  color: var(--slate-400);
}

.qa-schedule-type-breakdown {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 10px;
}

.qa-schedule-type-row {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 0.8125rem;
}

.qa-schedule-type-name {
  min-width: 40px;
  color: var(--slate-600, #4b5563);
  font-weight: 500;
}

body.dark-mode .qa-schedule-type-name {
  color: var(--slate-300);
}

.qa-schedule-progress {
  flex: 1;
  height: 6px;
  background: var(--slate-200, #e2e8f0);
  border-radius: var(--radius-full, 9999px);
  overflow: hidden;
  min-width: 60px;
}

body.dark-mode .qa-schedule-progress {
  background: rgba(255, 255, 255, 0.08);
}

.qa-schedule-progress-bar {
  height: 100%;
  width: var(--qa-fill-pct, 0%);
  border-radius: var(--radius-full, 9999px);
  transition: width 0.3s ease;
  background: var(--qa-type-color, var(--primary-500, #14b8a6));
}

.qa-schedule-progress-bar.over {
  background: linear-gradient(90deg, #f59e0b 0%, #d97706 100%);
}

.qa-schedule-type-hours {
  font-size: 0.75rem;
  color: var(--slate-500, #94a3b8);
  min-width: 55px;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.qa-schedule-total {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-top: 12px;
  border-top: 1px solid var(--slate-200, #e2e8f0);
  font-size: 0.8125rem;
  color: var(--slate-600, #475569);
}

body.dark-mode .qa-schedule-total {
  border-top-color: var(--slate-700);
  color: var(--slate-300);
}

.qa-schedule-progress-total {
  max-width: 100px;
}

.qa-schedule-pct {
  font-weight: 700;
  color: var(--primary-600, #0d9488);
  min-width: 40px;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.qa-schedule-pct.over {
  color: #d97706;
}

.qa-schedule-assignments {
  margin-top: 10px;
}

.qa-schedule-assignments summary {
  font-size: 0.8125rem;
  color: var(--text-tertiary, #6b7280);
  cursor: pointer;
  padding: 8px 0;
  display: flex;
  align-items: center;
  gap: 8px;
}

.qa-schedule-assignments summary:hover {
  color: var(--primary-500, #14b8a6);
}

.qa-schedule-shift-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 8px;
  padding-left: 4px;
}

.qa-schedule-shift-row {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 0.8125rem;
  color: var(--text-secondary, #4b5563);
  padding: 5px 0;
}

.qa-schedule-shift-date {
  min-width: 90px;
}

.qa-schedule-shift-time {
  min-width: 90px;
  color: var(--text-tertiary, #6b7280);
}

.qa-schedule-shift-type {
  font-weight: 600;
}

/* ============================================
   DARK MODE
   ============================================ */

.dark-mode .quota-assignment-modal-content {
  background: var(--surface-primary, #1f2937);
}

.dark-mode .qa-header {
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-header h2 {
  color: var(--text-primary, #f9fafb);
}

.dark-mode .qa-tabs {
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-tab {
  color: var(--text-secondary, #9ca3af);
}

.dark-mode .qa-tab:hover {
  color: var(--text-primary, #f9fafb);
}

.dark-mode .qa-shift-type-item {
  background: var(--surface-secondary, #111827);
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-shift-type-item:hover {
  background: var(--surface-tertiary, #1f2937);
}

.dark-mode .qa-shift-type-name {
  color: var(--text-primary, #f9fafb);
}

.dark-mode .qa-editor-form {
  background: var(--surface-secondary, #111827);
}

.dark-mode .qa-editor-form input,
.dark-mode .qa-editor-form select {
  background: var(--surface-tertiary, #1f2937);
  color: var(--text-primary, #f9fafb);
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-quota-table th {
  color: var(--text-secondary, #9ca3af);
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-quota-table td {
  border-color: var(--border-subtle, #374151);
  color: var(--text-primary, #f9fafb);
}

.dark-mode .qa-quota-cell input {
  background: var(--surface-tertiary, #1f2937);
  color: var(--text-primary, #f9fafb);
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-control-group input,
.dark-mode .qa-control-group select {
  background: var(--surface-tertiary, #1f2937);
  color: var(--text-primary, #f9fafb);
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-stat-card {
  background: var(--surface-secondary, #111827);
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-preview-table th {
  color: var(--text-secondary, #9ca3af);
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-preview-table td {
  color: var(--text-primary, #f9fafb);
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-preview-table tr:hover {
  background: var(--surface-secondary, #111827);
}

.dark-mode .qa-history-item {
  background: var(--surface-secondary, #111827);
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-history-item:hover {
  background: var(--surface-tertiary, #1f2937);
}

.dark-mode .qa-history-date {
  color: var(--text-primary, #f9fafb);
}

.dark-mode .qa-btn-secondary {
  background: var(--surface-secondary, #111827);
  color: var(--text-primary, #f9fafb);
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-btn-secondary:hover {
  background: var(--surface-tertiary, #1f2937);
}

/* Dark mode — redesigned UI */
.dark-mode .qa-section-label {
  color: var(--text-secondary, #9ca3af);
}

.dark-mode .qa-input-suffix {
  color: var(--text-secondary, #9ca3af);
}

.dark-mode .qa-hours-input {
  background: var(--surface-tertiary, #1f2937);
  color: var(--text-primary, #f9fafb);
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-field input[type="text"] {
  background: var(--surface-tertiary, #1f2937);
  color: var(--text-primary, #f9fafb);
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-field-color input[type="color"] {
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-custom-duration-input input {
  background: var(--surface-tertiary, #1f2937);
  color: var(--text-primary, #f9fafb);
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-member-card {
  background: var(--surface-secondary, #111827);
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-member-card-header {
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-quota-row-left {
  color: var(--text-primary, #f9fafb);
}

.dark-mode .qa-quota-row + .qa-quota-row {
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-quota-used-badge {
  color: var(--text-tertiary, #6b7280);
}

/* Dark mode — progress bars */
.dark-mode .qa-quota-progress-row {
  background: var(--surface-secondary, #1f2937);
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-quota-progress-row:hover {
  background: var(--surface-tertiary, #374151);
}

.dark-mode .qa-quota-type-label {
  color: var(--text-primary, #f9fafb);
}

.dark-mode .qa-quota-progress-bar {
  background: var(--surface-tertiary, #374151);
}

.dark-mode .qa-quota-progress-value {
  color: var(--text-primary, #f9fafb);
}

.dark-mode .qa-quota-progress-stats {
  color: var(--text-secondary, #9ca3af);
}

.dark-mode .qa-member-summary {
  color: var(--text-secondary, #9ca3af);
  border-color: var(--border-subtle, #374151);
  background: rgba(31, 41, 55, 0.5);
}

.dark-mode .qa-member-summary strong {
  color: var(--text-primary, #f9fafb);
}

.dark-mode .qa-quick-assign-bar {
  background: var(--surface-secondary, #111827);
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-quick-field {
  color: var(--text-primary, #f9fafb);
}

.dark-mode .qa-member-filter {
  background: var(--surface-secondary, #111827);
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-member-filter summary {
  color: var(--text-primary, #f9fafb);
}

.dark-mode .qa-preview-member-card {
  background: var(--surface-secondary, #111827);
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-preview-member-header {
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-preview-member-name {
  color: var(--text-primary, #f9fafb);
}

.dark-mode .qa-preview-member-summary {
  color: var(--text-secondary, #9ca3af);
}

.dark-mode .qa-preview-date {
  color: var(--text-primary, #f9fafb);
}

.dark-mode .qa-preview-time {
  color: var(--text-secondary, #9ca3af);
}

.dark-mode .qa-preview-type {
  color: var(--text-secondary, #9ca3af);
}

.dark-mode .qa-preview-shift-row + .qa-preview-shift-row {
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-warnings-collapsible {
  background: rgba(245, 158, 11, 0.05);
  border-color: rgba(245, 158, 11, 0.15);
}

.dark-mode .qa-warnings-collapsible summary {
  color: #fbbf24;
}

/* Dark mode — color swatches */
.dark-mode .qa-color-swatch {
  border-color: transparent;
}

.dark-mode .qa-color-swatch.active {
  border-color: var(--primary-400, #2dd4bf);
  box-shadow: 0 0 0 3px rgba(45, 212, 191, 0.25);
}

.dark-mode .qa-color-expand {
  background: var(--surface-tertiary, #374151);
  border-color: var(--border-subtle, #4b5563);
  color: var(--text-tertiary, #6b7280);
}

.dark-mode .qa-color-expand:hover {
  border-color: var(--primary-400, #2dd4bf);
  color: var(--primary-400, #2dd4bf);
}

.dark-mode .qa-swatch-extended {
  border-color: var(--border-subtle, #374151);
}

/* Dark mode — hour chips */
.dark-mode .qa-hour-chip {
  background: var(--surface-secondary, #1f2937);
  border-color: var(--border-subtle, #374151);
  color: var(--text-secondary, #9ca3af);
}

.dark-mode .qa-hour-chip:hover {
  border-color: var(--primary-400, #2dd4bf);
  color: var(--primary-400, #2dd4bf);
}

.dark-mode .qa-hour-chip.active {
  border-color: transparent;
}

.dark-mode .qa-hours-readout {
  background: var(--surface-tertiary, #1f2937);
  color: var(--text-primary, #f9fafb);
  border-color: var(--border-subtle, #374151);
}

/* Dark mode — schedule tab */
.dark-mode .qa-schedule-member-card {
  background: var(--surface-secondary, #1f2937);
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-schedule-member-name {
  color: var(--text-primary, #f9fafb);
}

.dark-mode .qa-schedule-member-meta {
  color: var(--text-tertiary, #6b7280);
}

.dark-mode .qa-schedule-type-name {
  color: var(--text-secondary, #9ca3af);
}

.dark-mode .qa-schedule-progress {
  background: var(--surface-tertiary, #374151);
}

.dark-mode .qa-schedule-type-hours {
  color: var(--text-tertiary, #6b7280);
}

.dark-mode .qa-schedule-total {
  color: var(--text-secondary, #9ca3af);
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-schedule-pct {
  color: var(--primary-400, #2dd4bf);
}

.dark-mode .qa-schedule-assignments summary {
  color: var(--text-tertiary, #6b7280);
}

.dark-mode .qa-schedule-shift-row {
  color: var(--text-secondary, #9ca3af);
}

.dark-mode .qa-schedule-shift-time {
  color: var(--text-tertiary, #6b7280);
}

/* ============================================
   RESPONSIVE
   ============================================ */

@media (max-width: 640px) {
  .quota-assignment-modal-content {
    max-width: 100%;
    width: 100%;
    height: 100vh;
    max-height: 100vh;
    border-radius: 0;
  }

  /* ⭐2026-08-20 (owner, mobile screenshot: "This banner and other labels ie
     beta, buisness plan etc means the viewable scheduling area seems too
     little especially considering the large mobile ui").
     Measured before: header 143px + tabs 44px + a three-line lock banner ate
     ~800px of an 844px viewport, so the schedule itself started below the
     fold. The chrome all still SAYS the same things — it just stops taking a
     line each. Title and badges share one line (the title no longer wraps
     beside the pill), the plan/BETA pills shrink to true micro-chips, and the
     lock banner tightens to two lines. */
  .qa-header {
    padding: 10px 14px 8px;
    gap: 8px;
    align-items: center;
  }

  .qa-header h2 {
    font-size: 1rem;
    line-height: 1.2;
    /* One line beside the badges instead of wrapping under them. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
  }

  .qa-header-left {
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    min-width: 0;
  }

  /* Plan / BETA pills: same words, micro-chip weight. */
  .qa-header .qa-badge,
  .qa-header .beta-badge,
  .qa-header [class*="plan-badge"] {
    font-size: 0.625rem;
    padding: 2px 7px;
    letter-spacing: 0.02em;
    line-height: 1.4;
    flex: 0 0 auto;
  }

  .qa-tabs {
    padding: 0 16px;
  }

  .qa-tab {
    padding: 10px 12px;
    font-size: 0.8125rem;
  }

  .qa-tab-content {
    padding: 16px;
  }

  .qa-assign-controls {
    flex-direction: column;
    gap: 12px;
  }

  .qa-preview-stats {
    gap: 8px;
  }

  .qa-stat-card {
    min-width: 70px;
    padding: 8px 10px;
  }

  .qa-run-stats {
    grid-template-columns: 1fr 1fr;
  }

  .qa-quota-table {
    font-size: 0.75rem;
  }

  .qa-quota-cell input[type="number"] {
    width: 46px;
  }

  .qa-inline-fields {
    flex-direction: column;
    gap: 8px;
  }

  .qa-field-narrow,
  .qa-field-color {
    flex: 1;
    min-width: 0;
  }

  .qa-date-range-row {
    flex-direction: column;
    /* Cross-axis is now horizontal (column layout). The base rule sets
       align-items:flex-end, which on mobile right-shoves the From / To
       fields and the Refresh button. Reset to flex-start so the stacked
       cluster reads left-aligned. */
    align-items: flex-start;
    gap: 10px;
  }

  .qa-quota-row {
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
  }

  .qa-quota-row-right {
    width: 100%;
    justify-content: flex-start;
    flex-wrap: wrap;
  }

  .qa-quick-assign-row {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }

  .qa-preview-shift-row {
    flex-wrap: wrap;
    gap: 6px;
  }

  .qa-preview-date {
    min-width: 90px;
  }

  .qa-preview-time {
    min-width: 90px;
  }

  .qa-hours-readout {
    width: 52px;
    min-width: 52px;
  }

  /* Progress bars mobile */
  .qa-quota-progress-row {
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
    padding: 12px;
  }

  .qa-quota-type-label {
    min-width: auto;
  }

  .qa-quota-chips-row {
    padding-left: 0;
    flex-wrap: wrap;
  }

  /* ── Workbench (the "Schedule" tab) — the primary surface ──
     The week grid is the one editable schedule view now. Make it usable
     one-handed: horizontal-scroll the grid, pin the member column + date
     header so context survives the scroll, and keep cells tappable. */
  .qa-workbench-toolbar {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
  }

  .qa-workbench-period,
  .qa-workbench-types,
  .qa-workbench-configure {
    flex-wrap: wrap;
  }

  .qa-workbench-window {
    justify-content: space-between;
  }

  /* Grid scrolls horizontally within its own wrap; the page must not. */
  .qa-week-grid,
  .qa-workbench-grid-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  /* Sticky member column — stays put while days scroll sideways. */
  .qa-week-grid th:first-child,
  .qa-week-grid td:first-child {
    position: sticky;
    left: 0;
    z-index: 2;
    min-width: 96px;
    background: var(--surface-primary, #fff);
  }

  /* Sticky cells need an opaque bg so scrolled content can't show through. */
  body.dark-mode .qa-week-grid th:first-child,
  body.dark-mode .qa-week-grid td:first-child,
  body.dark-mode .qa-week-grid thead th {
    background: var(--surface-primary, #0f172a);
  }

  /* Sticky date header — stays put while members scroll down. */
  .qa-week-grid thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--surface-primary, #fff);
  }

  /* Top-left corner cell sits above both sticky axes. */
  .qa-week-grid thead th:first-child {
    z-index: 3;
  }

  /* Keep shift + empty cells a comfortable tap target on touch. */
  .qa-grid-cell,
  .qa-grid-cell-empty {
    min-width: 40px;
    min-height: 40px;
    height: auto;
  }

  /* Hover-scale reads badly on touch (sticky transform jitter) — drop it. */
  .qa-grid-cell:hover {
    transform: none;
  }

  /* Recurring-schedule rows: let actions wrap instead of overflowing. */
  .qa-recurring-actions {
    flex-wrap: wrap;
  }

  /* Distribute + History toolbars stack rather than clip. */
  .qa-tab-toolbar {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }

  /* Any inline action bar (commit / discard / generate) goes full-width. */
  .qa-action-bar {
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
  }

  .qa-workbench-action-buttons {
    display: flex;
    gap: 8px;
  }

  .qa-workbench-action-buttons .qa-btn {
    flex: 1;
  }

  /* 44px minimum touch target on the modal's interactive chrome. */
  .qa-btn,
  .qa-tab,
  .qa-period-chip,
  .proposer-chip,
  .qa-type-toggle {
    min-height: 44px;
  }
}

/* Extra-small phones — tighten the grid without losing tap targets. */
@media (max-width: 480px) {
  .qa-week-grid table {
    font-size: 0.75rem;
  }

  .qa-week-grid th,
  .qa-week-grid td {
    padding: 4px;
  }

  .qa-grid-cell,
  .qa-grid-cell-empty {
    min-width: 36px;
    font-size: 0.6875rem;
  }

  .qa-week-grid th:first-child,
  .qa-week-grid td:first-child {
    min-width: 84px;
  }
}

/* ============================================
   NEW: Shift Window Time Inputs
   ============================================ */

.qa-time-window-row {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}

.qa-field-time {
  flex: 1;
  min-width: 100px;
}

.qa-field-time label {
  display: block;
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--text-secondary, #6b7280);
  margin-bottom: 4px;
}

.qa-field-time label small {
  font-weight: 400;
  opacity: 0.7;
}

.qa-field-time input[type="time"] {
  width: 100%;
  padding: 10px 14px;
  border: 1.5px solid var(--border-default, #d1d5db);
  border-radius: var(--radius-lg, 14px);
  font-size: 0.875rem;
  background: var(--surface-primary, #fff);
  color: var(--text-primary, #111827);
  transition: all var(--transition-fast, 0.15s);
}

.qa-field-time input[type="time"]:focus {
  border-color: var(--primary-400, #14b8a6);
  outline: none;
  box-shadow: var(--focus-ring-shadow);
}

.dark-mode .qa-field-time input[type="time"] {
  background: var(--surface-tertiary, #1f2937);
  border-color: var(--border-subtle, #374151);
  color: var(--text-primary, #f9fafb);
}

/* ============================================
   NEW: Why Button for Assignment Explanations
   ============================================ */

.qa-why-btn {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: none;
  background: var(--surface-tertiary, #f3f4f6);
  color: var(--text-tertiary, #9ca3af);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.75rem;
  transition: all 0.15s;
  flex-shrink: 0;
  margin-left: auto;
}

.qa-why-btn:hover {
  background: var(--primary-100, #ccfbf1);
  color: var(--primary-600, #0d9488);
}

.dark-mode .qa-why-btn {
  background: var(--surface-secondary, #374151);
  color: var(--text-tertiary, #9ca3af);
}

.dark-mode .qa-why-btn:hover {
  background: var(--primary-900, #134e4a);
  color: var(--primary-300, #5eead4);
}

/* ============================================
   Time Quality Indicator
   Shows local time quality for shift assignments
   ============================================ */

.qa-time-quality {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  font-size: 10px;
  margin-left: auto;
}

.qa-tq-excellent {
  background: rgba(16, 185, 129, 0.15);
  color: #059669;
}

.qa-tq-good {
  background: rgba(34, 197, 94, 0.15);
  color: #16a34a;
}

.qa-tq-fair {
  background: rgba(245, 158, 11, 0.15);
  color: #d97706;
}

.qa-tq-poor {
  background: rgba(239, 68, 68, 0.15);
  color: #dc2626;
}

.dark-mode .qa-tq-excellent {
  background: rgba(16, 185, 129, 0.2);
  color: #34d399;
}

.dark-mode .qa-tq-good {
  background: rgba(34, 197, 94, 0.2);
  color: #4ade80;
}

.dark-mode .qa-tq-fair {
  background: rgba(245, 158, 11, 0.2);
  color: #fbbf24;
}

.dark-mode .qa-tq-poor {
  background: rgba(239, 68, 68, 0.2);
  color: #f87171;
}

/* ============================================
   NEW: Fairness Smoothing Control
   ============================================ */

.qa-smoothing-control {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 12px 0;
  border-top: 1px solid var(--border-subtle, #e5e7eb);
  margin-top: 12px;
}

.qa-checkbox-label {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--text-primary, #111827);
}

.qa-checkbox-label input[type="checkbox"] {
  width: var(--checkbox-size, 18px);
  height: var(--checkbox-size, 18px);
  accent-color: var(--primary-color, #14b8a6);
  cursor: pointer;
}

.qa-help-text {
  font-size: 0.75rem;
  color: var(--text-tertiary, #9ca3af);
  margin-left: 24px;
}

/* ============================================
   NEW: Consecutive Days Input
   ============================================ */

.qa-consec-input {
  width: 60px;
  text-align: center;
  padding: 6px 8px;
  border: 1.5px solid var(--border-default, #d1d5db);
  border-radius: var(--radius-md, 10px);
  font-size: 0.875rem;
  background: var(--surface-primary, #fff);
  color: var(--text-primary, #111827);
}

.qa-consec-input:focus {
  border-color: var(--primary-400, #14b8a6);
  outline: none;
  box-shadow: var(--focus-ring-shadow);
}

.dark-mode .qa-consec-input {
  background: var(--surface-tertiary, #1f2937);
  border-color: var(--border-subtle, #374151);
  color: var(--text-primary, #f9fafb);
}

/* ============================================
   NEW: Preview Shift Row with Why Button
   ============================================ */

.qa-preview-shift-row {
  position: relative;
}

.qa-preview-shift-row[title]:hover {
  background: var(--surface-secondary, #f9fafb);
}

/* ============================================
   NEW: Members Under Minimum Warning Badge
   ============================================ */

.qa-under-minimum-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: var(--radius-full, 9999px);
  background: rgba(245, 158, 11, 0.15);
  color: #d97706;
  font-size: 0.75rem;
  font-weight: 600;
}

.dark-mode .qa-under-minimum-badge {
  background: rgba(245, 158, 11, 0.2);
  color: #fbbf24;
}

/* ============================================
   HIGH CONTRAST SHIFT TYPE COLOR CODING
   ============================================ */

/* Shift Type Color Variables */
:root {
  --shift-color: #3b82f6;           /* Blue - professional work */
  --shift-bg: rgba(59, 130, 246, 0.12);
  --on-call-color: #f59e0b;         /* Amber - warning/alert */
  --on-call-bg: rgba(245, 158, 11, 0.12);
  --support-color: #8b5cf6;         /* Purple - service/help */
  --support-bg: rgba(139, 92, 246, 0.12);
  --standby-color: #06b6d4;         /* Cyan - ready state */
  --standby-bg: rgba(6, 182, 212, 0.12);
  --custom-color: #6b7280;          /* Gray - neutral */
  --custom-bg: rgba(107, 114, 128, 0.12);
}

/* Shift type list items with left border accent */
.qa-shift-type-item {
  border-left: 4px solid transparent;
}

.qa-shift-type-item[data-preset="shift"] {
  border-left-color: var(--shift-color);
}

.qa-shift-type-item[data-preset="on-call"] {
  border-left-color: var(--on-call-color);
}

.qa-shift-type-item[data-preset="support"] {
  border-left-color: var(--support-color);
}

.qa-shift-type-item[data-preset="standby"] {
  border-left-color: var(--standby-color);
}

/* Preview shift type pills with high contrast backgrounds */
.qa-preview-type {
  padding: 2px 8px;
  border-radius: var(--radius-full, 9999px);
  font-weight: 600;
}

.qa-preview-type[data-type="shift"],
.qa-preview-type.shift-type-shift {
  background: var(--shift-bg);
  color: #2563eb;
}

.qa-preview-type[data-type="on-call"],
.qa-preview-type.shift-type-on-call {
  background: var(--on-call-bg);
  color: #d97706;
}

.qa-preview-type[data-type="support"],
.qa-preview-type.shift-type-support {
  background: var(--support-bg);
  color: #7c3aed;
}

.qa-preview-type[data-type="standby"],
.qa-preview-type.shift-type-standby {
  background: var(--standby-bg);
  color: #0891b2;
}

/* Schedule shift type badges */
.qa-schedule-shift-type {
  padding: 2px 6px;
  border-radius: var(--radius-sm, 4px);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.qa-schedule-shift-type[data-type="shift"],
.qa-schedule-shift-type.shift-type-shift {
  background: var(--shift-bg);
  color: #2563eb;
}

.qa-schedule-shift-type[data-type="on-call"],
.qa-schedule-shift-type.shift-type-on-call {
  background: var(--on-call-bg);
  color: #d97706;
}

.qa-schedule-shift-type[data-type="support"],
.qa-schedule-shift-type.shift-type-support {
  background: var(--support-bg);
  color: #7c3aed;
}

.qa-schedule-shift-type[data-type="standby"],
.qa-schedule-shift-type.shift-type-standby {
  background: var(--standby-bg);
  color: #0891b2;
}

/* Distribute tab type toggle chips with colored borders when active.
   ⚠️THESE MADE THE LABEL INVISIBLE (fixed 2026-08-23, user: "the contrast
   seems wrong"). Each rule set `background: <solid hue>` but NO `color`, so the
   text kept `color: var(--qa-type-color)` from the .active rule above — THE
   SAME HUE. Active chips were coloured text on an identical fill: exactly
   1.00:1, the label simply disappeared.
   `color: #fff` is not the fix either; measured on these hues white gives 3.68
   (shift), 2.15 (on-call), 4.23 (support), 2.43 (standby) — all under the 4.5:1
   AA floor for 12px text.
   So each keeps a 12% TINT of its hue as the fill with the hue darkened for the
   text, at the minimum darkening that clears 4.5:1 for that specific colour.
   The border stays full-strength so the chip still reads as its type. */
.qa-shift-type-chips .qa-type-toggle[data-preset="shift"].active,
.qa-shift-type-chips .qa-type-toggle.shift-type-shift.active,
.qa-workbench-types .qa-type-toggle[data-preset="shift"].active,
.qa-workbench-types .qa-type-toggle.shift-type-shift.active {
  background: #e7f0fe;
  background: color-mix(in srgb, var(--shift-color) 12%, #fff);
  border-color: var(--shift-color);
  color: #2f68c5;
  color: color-mix(in srgb, var(--shift-color) 80%, #000);   /* 4.68:1 */
}

.qa-shift-type-chips .qa-type-toggle[data-preset="on-call"].active,
.qa-shift-type-chips .qa-type-toggle.shift-type-on-call.active,
.qa-workbench-types .qa-type-toggle[data-preset="on-call"].active,
.qa-workbench-types .qa-type-toggle.shift-type-on-call.active {
  background: #fef3e2;
  background: color-mix(in srgb, var(--on-call-color) 12%, #fff);
  border-color: var(--on-call-color);
  color: #935f07;
  color: color-mix(in srgb, var(--on-call-color) 60%, #000); /* 4.93:1 */
}

.qa-shift-type-chips .qa-type-toggle[data-preset="support"].active,
.qa-shift-type-chips .qa-type-toggle.shift-type-support.active,
.qa-workbench-types .qa-type-toggle[data-preset="support"].active,
.qa-workbench-types .qa-type-toggle.shift-type-support.active {
  background: #f1ebfe;
  background: color-mix(in srgb, var(--support-color) 12%, #fff);
  border-color: var(--support-color);
  color: #764ed1;
  color: color-mix(in srgb, var(--support-color) 85%, #000); /* 4.78:1 */
}

.qa-shift-type-chips .qa-type-toggle[data-preset="standby"].active,
.qa-shift-type-chips .qa-type-toggle.shift-type-standby.active,
.qa-workbench-types .qa-type-toggle[data-preset="standby"].active,
.qa-workbench-types .qa-type-toggle.shift-type-standby.active {
  background: #e1f6fa;
  background: color-mix(in srgb, var(--standby-color) 12%, #fff);
  border-color: var(--standby-color);
  color: #04768a;
  color: color-mix(in srgb, var(--standby-color) 65%, #000); /* 4.73:1 */
}

/* Dark mode adjustments for shift type colors */
.dark-mode .qa-preview-type[data-type="shift"],
.dark-mode .qa-preview-type.shift-type-shift {
  background: rgba(59, 130, 246, 0.2);
  color: #60a5fa;
}

.dark-mode .qa-preview-type[data-type="on-call"],
.dark-mode .qa-preview-type.shift-type-on-call {
  background: rgba(245, 158, 11, 0.2);
  color: #fbbf24;
}

.dark-mode .qa-preview-type[data-type="support"],
.dark-mode .qa-preview-type.shift-type-support {
  background: rgba(139, 92, 246, 0.2);
  color: #a78bfa;
}

.dark-mode .qa-preview-type[data-type="standby"],
.dark-mode .qa-preview-type.shift-type-standby {
  background: rgba(6, 182, 212, 0.2);
  color: #22d3ee;
}

.dark-mode .qa-schedule-shift-type[data-type="shift"],
.dark-mode .qa-schedule-shift-type.shift-type-shift {
  background: rgba(59, 130, 246, 0.25);
  color: #60a5fa;
}

.dark-mode .qa-schedule-shift-type[data-type="on-call"],
.dark-mode .qa-schedule-shift-type.shift-type-on-call {
  background: rgba(245, 158, 11, 0.25);
  color: #fbbf24;
}

.dark-mode .qa-schedule-shift-type[data-type="support"],
.dark-mode .qa-schedule-shift-type.shift-type-support {
  background: rgba(139, 92, 246, 0.25);
  color: #a78bfa;
}

.dark-mode .qa-schedule-shift-type[data-type="standby"],
.dark-mode .qa-schedule-shift-type.shift-type-standby {
  background: rgba(6, 182, 212, 0.25);
  color: #22d3ee;
}

/* Dark mode stepper buttons */
.dark-mode .qa-duration-stepper button {
  background: var(--surface-secondary, #374151);
  color: var(--text-tertiary, #9ca3af);
}

.dark-mode .qa-duration-stepper button:hover {
  background: var(--primary-900, #134e4a);
  color: var(--primary-300, #5eead4);
}

/* ============================================
   MEMBER CONTRACT DROPDOWN (Team Hours Tab)
   ============================================ */

.qa-contract-dropdown {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  margin-bottom: 8px;
  background: var(--surface-tertiary, rgba(243, 244, 246, 0.7));
  border-radius: var(--radius-md, 8px);
  font-size: 0.875rem;
}

.qa-contract-dropdown label {
  color: var(--text-secondary, #6b7280);
  font-weight: 500;
}

.qa-contract-dropdown select {
  padding: 4px 24px 4px 8px;
  border: 1px solid var(--border-default, #d1d5db);
  border-radius: var(--radius-sm, 6px);
  background: var(--surface-primary, #fff);
  color: var(--text-primary, #111827);
  font-size: 0.875rem;
  font-weight: 500;
  cursor: pointer;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3E%3Cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 4px center;
  background-size: 16px;
}

.qa-contract-dropdown select:focus {
  outline: none;
  border-color: var(--primary-400, #14b8a6);
  box-shadow: var(--focus-ring-shadow);
}

.qa-contract-badge {
  padding: 2px 6px;
  border-radius: var(--radius-full, 9999px);
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.qa-contract-badge.full-time {
  background: #dbeafe;
  color: #1e40af;
  border: 1px solid #3b82f6;
}

.qa-contract-badge.part-time {
  background: #ede9fe;
  color: #5b21b6;
  border: 1px solid #a855f7;
}

.qa-contract-badge.contractor {
  background: #fef3c7;
  color: #92400e;
  border: 1px solid #f59e0b;
}

.qa-contract-badge.custom {
  background: #f3f4f6;
  color: #1f2937;
  border: 1px solid #9ca3af;
}

.dark-mode .qa-contract-dropdown {
  background: rgba(31, 41, 55, 0.7);
}

.dark-mode .qa-contract-dropdown label {
  color: var(--text-secondary, #9ca3af);
}

.dark-mode .qa-contract-dropdown select {
  background-color: var(--surface-secondary, #1f2937);
  border-color: var(--border-subtle, #374151);
  color: var(--text-primary, #f9fafb);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3E%3Cpath stroke='%239ca3af' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3E%3C/svg%3E");
}

.dark-mode .qa-contract-badge.full-time {
  background: rgba(59, 130, 246, 0.25);
  color: #93c5fd;
  border-color: #3b82f6;
}

.dark-mode .qa-contract-badge.part-time {
  background: rgba(139, 92, 246, 0.25);
  color: #c4b5fd;
  border-color: #a855f7;
}

.dark-mode .qa-contract-badge.contractor {
  background: rgba(245, 158, 11, 0.25);
  color: #fcd34d;
  border-color: #f59e0b;
}

.dark-mode .qa-contract-badge.custom {
  background: rgba(107, 114, 128, 0.25);
  color: #d1d5db;
  border-color: #6b7280;
}

/* ============================================
   TIMEZONE REGION FILTER (Distribute Tab)
   ============================================ */

.qa-timezone-filter {
  margin-bottom: 14px;
  padding: 12px 14px;
  background: var(--surface-secondary, #f9fafb);
  border: 1px solid var(--border-subtle, #e5e7eb);
  border-radius: var(--radius-md, 12px);
}

.qa-tz-region-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 10px;
}

/* Timezone-region chips — chip family. */
.qa-tz-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 32px;
  padding: 0 12px;
  border: 1px solid var(--slate-200, #e2e8f0);
  border-radius: var(--radius-full, 9999px);
  background: var(--white, #fff);
  color: var(--slate-600, #475569);
  font-family: inherit;
  font-size: 0.75rem;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  line-height: 1;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.15s ease;
}

.qa-tz-chip i {
  font-size: 0.6875rem;
}

.qa-tz-chip:hover {
  border-color: var(--primary-300, #5eead4);
  background: var(--primary-50, #f0fdfa);
  color: var(--primary-700, #0f766e);
  transform: translateY(-1px);
}

.qa-tz-chip.active {
  border-color: var(--primary-500, #14b8a6);
  background: rgba(20, 184, 166, 0.15);
  color: var(--primary-700, #0f766e);
  font-weight: 600;
  box-shadow: 0 1px 3px rgba(20, 184, 166, 0.15);
}

.qa-tz-chip .tz-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 16px;
  padding: 0 5px;
  border-radius: var(--radius-full, 9999px);
  background: var(--slate-100, #f1f5f9);
  color: var(--slate-600, #475569);
  font-size: 0.6875rem;
  font-weight: 600;
  margin-left: 2px;
}

.qa-tz-chip.active .tz-count {
  background: rgba(20, 184, 166, 0.22);
  color: var(--primary-700, #0f766e);
}

/* ⚠️ALIGNMENT (2026-08-23, user: "Fair distribution / Require 24h coverage —
   Alignment wrong"). Three radio labels in a flex row with NO flex-wrap, while
   the sibling chip row directly above (.qa-tz-region-chips) does wrap — so on a
   narrow modal the chips wrapped and this row overflowed, and two adjacent rows
   in the same container visibly disagreed.
   The mechanism for one option sitting off-baseline from another: each label is
   itself display:flex + align-items:center, so when the longest option
   ("Require 24h coverage") was squeezed its text wrapped to two lines INSIDE
   the label, and centring a two-line label against one-line neighbours put them
   on different baselines.
   Fix: let the ROW wrap; stop the LABELS wrapping. */
.qa-coverage-options {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 16px;
  padding-top: 8px;
  border-top: 1px solid var(--border-subtle, #e5e7eb);
}

.qa-coverage-options label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.875rem;
  color: var(--text-primary, #111827);
  cursor: pointer;
  white-space: nowrap;
}

.qa-coverage-options input[type="radio"] {
  accent-color: var(--primary-color, #14b8a6);
  /* Don't let the control shrink when the row is tight — a squashed radio is
     the other way these options drift out of line with each other. */
  flex: none;
  margin: 0;
}

.dark-mode .qa-timezone-filter {
  background: var(--surface-secondary, #111827);
  border-color: var(--border-subtle, #374151);
}

body.dark-mode .qa-tz-chip {
  background: rgba(15, 23, 42, 0.4);
  border-color: var(--slate-700, #374151);
  color: var(--slate-300, #cbd5e1);
}

body.dark-mode .qa-tz-chip:hover {
  border-color: rgba(20, 184, 166, 0.5);
  background: rgba(20, 184, 166, 0.12);
  color: var(--primary-300, #5eead4);
}

body.dark-mode .qa-tz-chip.active {
  border-color: rgba(20, 184, 166, 0.6);
  background: rgba(20, 184, 166, 0.2);
  color: var(--primary-300, #5eead4);
}

body.dark-mode .qa-tz-chip .tz-count {
  background: rgba(255, 255, 255, 0.08);
  color: var(--slate-300);
}

body.dark-mode .qa-tz-chip.active .tz-count {
  background: rgba(20, 184, 166, 0.3);
  color: var(--primary-200);
}

.dark-mode .qa-coverage-options {
  border-top-color: var(--border-subtle, #374151);
}

.dark-mode .qa-coverage-options label {
  color: var(--text-primary, #f9fafb);
}

/* ============================================
   MEMBER REQUIREMENTS MATRIX (Distribute Tab)
   ============================================ */

.qa-requirements-matrix {
  margin-bottom: 14px;
}

.qa-matrix-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

.qa-matrix-actions {
  display: flex;
  gap: 6px;
}

.qa-matrix-actions button {
  padding: 4px 10px;
  border: 1px solid var(--border-default, #d1d5db);
  border-radius: var(--radius-sm, 6px);
  background: var(--surface-primary, #fff);
  color: var(--text-secondary, #6b7280);
  font-size: 0.75rem;
  cursor: pointer;
  transition: all 0.15s;
}

.qa-matrix-actions button:hover {
  background: var(--surface-secondary, #f3f4f6);
  color: var(--text-primary, #111827);
}

.qa-member-req-card {
  padding: 12px 14px;
  margin-bottom: 8px;
  background: var(--surface-secondary, #f9fafb);
  border: 1px solid var(--border-subtle, #e5e7eb);
  border-radius: var(--radius-md, 10px);
  transition: all 0.15s;
}

.qa-member-req-card.excluded {
  opacity: 0.5;
  background: var(--surface-tertiary, #f3f4f6);
}

.qa-member-req-card:hover:not(.excluded) {
  border-color: var(--primary-300, #5eead4);
}

.qa-member-req-header {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
}

.qa-member-req-header .member-selection-item {
  flex: 1;
  margin: 0;
  padding: 0;
}

.qa-req-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  font-size: 0.8125rem;
  color: var(--text-secondary, #6b7280);
  margin-bottom: 8px;
  padding-bottom: 8px;
  border-bottom: 1px dashed var(--border-subtle, #e5e7eb);
}

.qa-req-meta-item {
  display: flex;
  align-items: center;
  gap: 4px;
}

.qa-req-meta-item i {
  font-size: 0.75rem;
  color: var(--text-tertiary, #9ca3af);
}

.qa-req-targets {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 8px;
}

.qa-req-target {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.875rem;
}

.qa-req-target label {
  color: var(--text-secondary, #6b7280);
  font-weight: 500;
}

.qa-req-target select {
  padding: 3px 20px 3px 6px;
  border: 1px solid var(--border-default, #d1d5db);
  border-radius: var(--radius-sm, 4px);
  background: var(--surface-primary, #fff);
  font-size: 0.8125rem;
  cursor: pointer;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3E%3Cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 2px center;
  background-size: 14px;
}

.qa-req-priority {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
}

.qa-req-priority label {
  font-size: 0.75rem;
  color: var(--text-tertiary, #9ca3af);
}

.qa-req-priority select {
  padding: 2px 18px 2px 6px;
  border: 1px solid var(--border-subtle, #e5e7eb);
  border-radius: var(--radius-sm, 4px);
  background: var(--surface-primary, #fff);
  font-size: 0.75rem;
  cursor: pointer;
}

.qa-req-note {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 0.75rem;
  color: var(--text-tertiary, #9ca3af);
  font-style: italic;
}

.qa-req-note i {
  color: var(--on-call-color, #f59e0b);
}

.qa-matrix-summary {
  padding: 10px 14px;
  background: var(--primary-50, #f0fdfa);
  border: 1px solid var(--primary-200, #99f6e4);
  border-radius: var(--radius-md, 8px);
  font-size: 0.8125rem;
  color: var(--primary-800, #115e59);
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
}

.dark-mode .qa-member-req-card {
  background: var(--surface-secondary, #111827);
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-member-req-card.excluded {
  background: var(--surface-tertiary, #1f2937);
}

.dark-mode .qa-req-meta {
  border-bottom-color: var(--border-subtle, #374151);
}

.dark-mode .qa-req-target select,
.dark-mode .qa-req-priority select {
  background-color: var(--surface-tertiary, #1f2937);
  border-color: var(--border-subtle, #374151);
  color: var(--text-primary, #f9fafb);
}

.dark-mode .qa-matrix-summary {
  background: rgba(20, 184, 166, 0.1);
  border-color: rgba(20, 184, 166, 0.3);
  color: var(--primary-300, #5eead4);
}

/* ============================================
   SCHEDULE TAB - WEEK GRID VIEW
   ============================================ */

/* P5.C — Recurring schedules section in the Schedule tab. Collapsible
   so admins who don't use the cron see no clutter, but discoverable for
   those who do. Tokens-only — fairness vocabulary stays consistent. */
.qa-recurring-schedules {
  margin-bottom: 16px;
  padding: 10px 14px;
  border: 1px solid var(--border-subtle, #e5e7eb);
  border-radius: var(--radius-md, 8px);
  background: var(--surface-secondary, #f9fafb);
}
.qa-recurring-schedules summary {
  cursor: pointer;
  user-select: none;
  padding: 4px 0;
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  color: var(--text-primary, #1f2937);
}
.qa-recurring-schedules summary i {
  color: var(--text-secondary, #64748b);
}
.qa-section-count {
  margin-left: auto;
  font-size: 0.75rem;
  padding: 2px 8px;
  border-radius: 10px;
  background: var(--surface-primary, #fff);
  color: var(--text-secondary, #64748b);
  font-weight: 600;
}
.qa-recurring-list {
  list-style: none;
  margin: 12px 0 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.qa-recurring-item {
  padding: 10px 12px;
  background: var(--surface-primary, #fff);
  border: 1px solid var(--border-subtle, #e5e7eb);
  border-radius: var(--radius-sm, 6px);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.qa-recurring-inactive {
  opacity: 0.6;
}
.qa-recurring-head {
  display: flex;
  align-items: center;
  gap: 10px;
}
.qa-recurring-name {
  font-weight: 600;
  color: var(--text-primary, #1f2937);
}
.qa-recurring-pattern {
  font-size: 0.75rem;
  padding: 2px 8px;
  border-radius: 10px;
  background: rgba(22, 163, 74, 0.12);
  background: color-mix(in srgb, var(--status-working, #16a34a) 12%, transparent);
  color: #188b46;
  color: color-mix(in srgb, var(--status-working, #16a34a) 80%, var(--text-primary, #1f2937));
}
.qa-recurring-badge-inactive {
  font-size: 0.75rem;
  padding: 2px 8px;
  border-radius: 10px;
  background: rgba(251, 191, 36, 0.15);
  background: color-mix(in srgb, var(--status-flex, #fbbf24) 15%, transparent);
  color: #c49a29;
  color: color-mix(in srgb, var(--status-flex, #fbbf24) 75%, var(--text-primary, #1f2937));
  margin-left: auto;
}
.qa-recurring-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  font-size: 0.8125rem;
  color: var(--text-secondary, #64748b);
}
.qa-recurring-days {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.75rem;
}
.qa-recurring-actions {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
body.dark-mode .qa-recurring-schedules {
  background: var(--surface-secondary, #1e293b);
  border-color: var(--border-default, #334155);
}
body.dark-mode .qa-recurring-item {
  background: var(--surface-primary, #0f172a);
  border-color: var(--border-default, #334155);
}

/* ── Recurring schedule inline edit form (P5.C) ────────────────── */
.qa-recurring-edit-form {
  margin-top: 12px;
  padding: 14px;
  border-radius: var(--radius-md, 12px);
  background: var(--slate-50, #f8fafc);
  border: 1px solid var(--slate-200, #e2e8f0);
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.qa-re-field {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.qa-re-label {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--slate-600, #475569);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.qa-re-name,
.qa-re-draftlead,
.qa-re-commitlead {
  padding: 7px 10px;
  border-radius: var(--radius-sm, 6px);
  border: 1px solid var(--slate-300, #cbd5e1);
  background: var(--surface, #fff);
  font-size: 0.875rem;
  color: var(--slate-800, #1f2937);
}

.qa-re-name:focus,
.qa-re-draftlead:focus,
.qa-re-commitlead:focus {
  outline: none;
  border-color: var(--primary-400, #2dd4bf);
  box-shadow: 0 0 0 2px rgba(20, 184, 166, 0.15);
}

.qa-re-pattern-chips,
.qa-re-day-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

/* Day-of-week toggles. Since 2026-09-29 they are the setup weekday row in
   picker form (.day-selector--pick .day-pill, css/days-off.css), which draws
   them; the square-chip look below is for the fallback buttons only. */
.qa-re-day-chip {
  font-weight: 600;
  cursor: pointer;
}
.qa-re-day-chip:not(.day-pill) {
  min-width: 42px;
  padding: 6px 10px;
  border-radius: var(--radius-sm, 6px);
  border: 1px solid var(--slate-300, #cbd5e1);
  background: var(--surface, #fff);
  color: var(--slate-600, #475569);
  font-size: 0.75rem;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.qa-re-day-chip:not(.day-pill):hover {
  border-color: var(--primary-400, #2dd4bf);
}

.qa-re-day-chip:not(.day-pill).active {
  background: var(--primary-500, #14b8a6);
  border-color: var(--primary-500, #14b8a6);
  color: #fff;
}

.qa-re-check-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 8px;
}

.qa-re-check {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border-radius: var(--radius-sm, 6px);
  border: 1px solid var(--slate-200, #e2e8f0);
  background: var(--surface, #fff);
  font-size: 0.8125rem;
  color: var(--slate-700, #334155);
  cursor: pointer;
}

.qa-re-check input {
  accent-color: var(--primary-500, #14b8a6);
  flex-shrink: 0;
}

.qa-re-check-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--qa-type-color, #14b8a6);
  flex-shrink: 0;
}

.qa-re-empty {
  font-size: 0.8125rem;
  color: var(--slate-500, #6b7280);
  font-style: italic;
}

.qa-re-lead-row {
  flex-direction: row;
  gap: 14px;
  flex-wrap: wrap;
}

.qa-re-lead {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1;
  min-width: 140px;
}

.qa-re-lead input {
  max-width: 100px;
}

.qa-re-actions {
  display: flex;
  gap: 8px;
  padding-top: 4px;
}

/* Dark mode */
body.dark-mode .qa-recurring-edit-form {
  background: rgba(15, 23, 42, 0.4);
  border-color: var(--slate-700);
}

body.dark-mode .qa-re-label {
  color: var(--slate-400);
}

body.dark-mode .qa-re-name,
body.dark-mode .qa-re-draftlead,
body.dark-mode .qa-re-commitlead,
body.dark-mode .qa-re-day-chip:not(.day-pill),
body.dark-mode .qa-re-check {
  background: rgba(15, 23, 42, 0.6);
  border-color: var(--slate-600);
  color: var(--slate-100);
}

body.dark-mode .qa-re-day-chip:not(.day-pill).active {
  background: var(--primary-500, #14b8a6);
  border-color: var(--primary-500, #14b8a6);
  color: #fff;
}

/* Schedule view-toggle (Week Grid / Member Cards / Coverage Heatmap) retired:
   the three read-only views were merged into the single editable Workbench
   grid, so .qa-schedule-view-toggle / .qa-view-btn no longer render. */

.qa-week-grid {
  overflow-x: auto;
  margin-bottom: 16px;
}

.qa-week-grid table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8125rem;
}

.qa-week-grid th {
  padding: 8px 6px;
  font-weight: 600;
  text-align: center;
  color: var(--text-secondary, #6b7280);
  border-bottom: 2px solid var(--border-subtle, #e5e7eb);
  font-size: 0.75rem;
  text-transform: uppercase;
}

.qa-week-grid th:first-child {
  text-align: left;
  min-width: 120px;
}

.qa-week-grid td {
  padding: 6px;
  text-align: center;
  border-bottom: 1px solid var(--border-subtle, #e5e7eb);
  vertical-align: middle;
}

.qa-week-grid td:first-child {
  text-align: left;
  font-weight: 500;
  color: var(--text-primary, #111827);
}

.qa-week-grid tr:hover td {
  background: var(--surface-secondary, #f9fafb);
}

.qa-week-grid .coverage-row td {
  font-weight: 700;
  color: var(--text-secondary, #6b7280);
  background: var(--surface-secondary, #f9fafb);
  border-top: 2px solid var(--border-subtle, #e5e7eb);
}

.qa-grid-cell {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 32px;
  height: 26px;
  padding: 0 6px;
  border-radius: var(--radius-sm, 4px);
  font-weight: 700;
  font-size: 0.75rem;
  cursor: pointer;
  transition: all 0.15s;
}

.qa-grid-cell:hover {
  transform: scale(1.1);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
}

.qa-grid-cell.shift {
  background: var(--shift-bg);
  color: var(--shift-color);
}

.qa-grid-cell.on-call {
  background: var(--on-call-bg);
  color: var(--on-call-color);
}

.qa-grid-cell.support {
  background: var(--support-bg);
  color: var(--support-color);
}

.qa-grid-cell.standby {
  background: var(--standby-bg);
  color: var(--standby-color);
}

.qa-grid-cell.empty {
  color: var(--text-tertiary, #9ca3af);
  background: none;
}

.qa-grid-cell.gap {
  background: rgba(239, 68, 68, 0.1);
  color: #ef4444;
}

.qa-coverage-count {
  font-weight: 700;
}

.qa-coverage-count.good {
  color: var(--success-color, #10b981);
}

.qa-coverage-count.low {
  color: var(--on-call-color, #f59e0b);
}

.qa-coverage-count.gap {
  color: #ef4444;
}

/* Grid legend — small inline key shown above the
   week grid. Swatch reads --qa-type-color from the
   parent .qa-legend-item; "empty" + "no shift" use
   neutral slate tokens. */
.qa-grid-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  padding: 10px 14px;
  background: var(--slate-50, #f8fafc);
  border: 1px solid var(--slate-200, #e2e8f0);
  border-radius: var(--radius-md, 12px);
  margin-bottom: 14px;
  font-size: 0.75rem;
  color: var(--slate-700, #334155);
}

body.dark-mode .qa-grid-legend {
  background: rgba(15, 23, 42, 0.4);
  border-color: var(--slate-700);
  color: var(--slate-300);
}

.qa-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.qa-legend-swatch {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  height: 16px;
  padding: 0 4px;
  border-radius: var(--radius-xs, 4px);
  font-size: 0.625rem;
  font-weight: 700;
  /* ⚠️WAS `color: #fff` over the raw hue — measured 2.15:1 on the amber
     on-call default and 2.37:1 on cyan standby, at 10px where AA needs the full
     4.5:1 (the large-text 3:1 allowance does not apply). The hue is admin-
     chosen, so no fixed foreground is safe for all of them. Tint the fill and
     darken the glyph, both derived from the hue so it holds for any colour:
     worst case across every preset/seed/custom hue is 4.73:1. (2026-08-23) */
  background: #d5f2ef;
  background: color-mix(in srgb, var(--qa-type-color, var(--primary-500, #14b8a6)) 18%, #fff);
  color: #094742;
  color: color-mix(in srgb, var(--qa-type-color, var(--primary-700, #0f766e)) 60%, #000);
  box-shadow: inset 0 0 0 1px var(--qa-type-color, var(--primary-500, #14b8a6));
  letter-spacing: 0.02em;
}

.qa-legend-swatch.empty {
  background: var(--slate-100, #f1f5f9);
  color: var(--slate-400, #94a3b8);
}

body.dark-mode .qa-legend-swatch.empty {
  background: rgba(255, 255, 255, 0.06);
  color: var(--slate-500);
}

.dark-mode .qa-week-grid th {
  border-bottom-color: var(--border-subtle, #374151);
}

.dark-mode .qa-week-grid td {
  border-bottom-color: var(--border-subtle, #374151);
}

.dark-mode .qa-week-grid td:first-child {
  color: var(--text-primary, #f9fafb);
}

.dark-mode .qa-week-grid tr:hover td {
  background: var(--surface-secondary, #1f2937);
}

.dark-mode .qa-week-grid .coverage-row td {
  background: var(--surface-secondary, #111827);
  border-top-color: var(--border-subtle, #374151);
}

.dark-mode .qa-grid-legend {
  background: var(--surface-secondary, #111827);
}

/* Coverage Heatmap view retired (merged into the Workbench). */

/* ============================================
   SETTINGS TAB - Accordion Sections
   ============================================ */

.qa-settings-section {
  margin-bottom: 8px;
  border: 1px solid var(--border-subtle, #e5e7eb);
  border-radius: var(--radius-md, 8px);
  overflow: hidden;
}

.qa-accordion-header {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 12px 16px;
  background: var(--surface-secondary, #f9fafb);
  border: none;
  cursor: pointer;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text-primary, #111827);
  text-align: left;
  transition: background 0.15s;
}

.qa-accordion-header:hover {
  background: var(--surface-tertiary, #f3f4f6);
}

.qa-accordion-icon {
  font-size: 0.75rem;
  color: var(--text-secondary, #6b7280);
  transition: transform 0.2s;
}

.qa-section-badge {
  margin-left: auto;
  font-size: 0.75rem;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 10px;
  background: var(--primary-100, #ccfbf1);
  color: var(--primary-700, #0f766e);
}

.qa-accordion-content {
  padding: 16px;
  border-top: 1px solid var(--border-subtle, #e5e7eb);
}

.qa-accordion-content.collapsed {
  display: none;
}

.qa-empty-hint {
  font-size: 0.875rem;
  color: var(--text-secondary, #6b7280);
  font-style: italic;
  padding: 12px 0;
}

/* Work Schedules List */
.qa-work-schedules-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.qa-work-schedule-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 14px;
  background: var(--surface-primary, #fff);
  border: 1px solid var(--border-subtle, #e5e7eb);
  border-radius: var(--radius-sm, 6px);
}

.qa-ws-name {
  font-weight: 500;
  color: var(--text-primary, #111827);
}

.qa-ws-hours {
  font-size: 0.875rem;
  color: var(--text-secondary, #6b7280);
}

/* History List */
.qa-history-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.qa-history-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  background: var(--surface-primary, #fff);
  border: 1px solid var(--border-subtle, #e5e7eb);
  border-radius: var(--radius-sm, 6px);
}

.qa-history-info {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.qa-history-date {
  font-weight: 500;
  color: var(--text-primary, #111827);
}

.qa-history-stats {
  font-size: 0.8125rem;
  color: var(--text-secondary, #6b7280);
}

.qa-history-status {
  font-size: 0.75rem;
  font-weight: 600;
  padding: 3px 8px;
  border-radius: 10px;
}

.qa-history-status.committed {
  background: var(--success-100, #dcfce7);
  color: var(--success-700, #15803d);
}

.qa-history-status.rolled-back {
  background: var(--error-100, #fee2e2);
  color: var(--error-700, #b91c1c);
}

.qa-history-status.preview {
  background: var(--warning-100, #fef3c7);
  color: var(--warning-700, #a16207);
}

.qa-rollback-btn {
  font-size: 0.75rem;
  padding: 4px 10px;
}

/* ============================================
   SCHEDULE TAB - View Toggle
   ============================================ */

/* (Duplicate .qa-schedule-view-toggle / .qa-view-btn segmented-control block
   removed — the three-view switcher was retired with the Schedule tab.) */

/* Section Groups */
.qa-section-group {
  margin-bottom: 20px;
}

.qa-type-toggles {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.qa-type-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  background: var(--surface-secondary, #f9fafb);
  border: 1px solid var(--border-subtle, #e5e7eb);
  border-radius: var(--radius-md, 8px);
  cursor: pointer;
  font-size: 0.875rem;
  transition: all 0.15s;
}

.qa-type-toggle:has(input:checked) {
  background: var(--primary-50, #f0fdfa);
  border-color: var(--primary-300, #5eead4);
}

.qa-type-toggle input {
  width: 16px;
  height: 16px;
}

.qa-type-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
}

.qa-options-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.qa-option-toggle {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 0.875rem;
  color: var(--text-primary, #111827);
  cursor: pointer;
}

.qa-option-toggle input {
  width: 18px;
  height: 18px;
}

/* Dark mode for settings */
.dark-mode .qa-settings-section {
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-accordion-header {
  background: var(--surface-secondary, #1f2937);
  color: var(--text-primary, #f9fafb);
}

.dark-mode .qa-accordion-header:hover {
  background: var(--surface-tertiary, #374151);
}

.dark-mode .qa-accordion-content {
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-section-badge {
  background: var(--primary-900, #134e4a);
  color: var(--primary-300, #5eead4);
}

.dark-mode .qa-work-schedule-item,
.dark-mode .qa-history-item {
  background: var(--surface-secondary, #1f2937);
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-ws-name,
.dark-mode .qa-history-date {
  color: var(--text-primary, #f9fafb);
}

.dark-mode .qa-type-toggle {
  background: var(--surface-secondary, #1f2937);
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-type-toggle:has(input:checked) {
  background: var(--primary-900, #134e4a);
  border-color: var(--primary-700, #0f766e);
}

.dark-mode .qa-option-toggle {
  color: var(--text-primary, #f9fafb);
}

/* ============================================
   BULK PRESET BUTTONS (Capacity Tab)
   ============================================ */

.qa-bulk-actions {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px 16px;
  margin-top: 16px;
  background: var(--slate-50, #f8fafc);
  border: 1px solid var(--slate-200, #e2e8f0);
  border-radius: var(--radius-md, 12px);
}

.qa-bulk-actions .qa-section-label {
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--slate-500, #6b7280);
  margin: 0;
}

.qa-bulk-preset-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

/* Mirrors .qa-period-chip / .proposer-chip family. */
.qa-bulk-preset {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 32px;
  padding: 0 12px;
  border: 1px solid var(--slate-200, #e2e8f0);
  border-radius: var(--radius-full, 9999px);
  background: var(--white, #fff);
  color: var(--slate-600, #475569);
  font-family: inherit;
  font-size: 0.75rem;
  font-weight: 500;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.15s ease;
  white-space: nowrap;
  line-height: 1;
}

.qa-bulk-preset:hover {
  border-color: var(--primary-300, #5eead4);
  background: var(--primary-50, #f0fdfa);
  color: var(--primary-700, #0f766e);
  transform: translateY(-1px);
}

.qa-bulk-preset:active {
  transform: translateY(0);
}

.qa-bulk-preset.qa-bulk-custom {
  border-style: dashed;
  color: var(--slate-500, #6b7280);
}

.qa-bulk-preset.qa-bulk-custom:hover {
  border-style: solid;
  border-color: var(--primary-300, #5eead4);
  color: var(--primary-700, #0f766e);
}

/* Dark mode bulk presets */
.dark-mode .qa-bulk-actions {
  background: rgba(15, 23, 42, 0.4);
  border-color: var(--slate-700, #374151);
}

.dark-mode .qa-bulk-actions .qa-section-label {
  color: var(--slate-400, #9ca3af);
}

.dark-mode .qa-bulk-preset {
  background: rgba(15, 23, 42, 0.4);
  border-color: var(--slate-700, #374151);
  color: var(--slate-200, #f9fafb);
}

.dark-mode .qa-bulk-preset:hover {
  background: rgba(20, 184, 166, 0.12);
  border-color: rgba(20, 184, 166, 0.5);
  color: var(--primary-300, #5eead4);
}

.dark-mode .qa-bulk-preset.qa-bulk-custom {
  color: var(--slate-400, #9ca3af);
}

.dark-mode .qa-bulk-preset.qa-bulk-custom:hover {
  color: var(--primary-300, #5eead4);
}

/* Mobile responsive bulk presets */
@media (max-width: 640px) {
  .qa-bulk-preset-row {
    gap: 6px;
  }

  .qa-bulk-preset {
    padding: 5px 12px;
    font-size: 0.75rem;
    flex: 1;
    min-width: 40px;
  }
}

/* ============================================
   PERIOD SELECTOR (Fill Tab)
   ============================================ */

.qa-period-selector {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* Period chips — mirrors .proposer-chip geometry
   (style.css:22826) so every filter chip in the modal
   reads the same. Active = teal-tinted, not solid fill. */
.qa-period-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.qa-period-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  /* Audit-2026-05-30-03-31: was height:32px which puts the chip below the
     44px touch-target floor on mobile. Use min-height so dense desktop
     layouts can still draw a compact chip, and a media query below tops
     it back to 44px on touch screens. */
  min-height: 36px;
  padding: 0 12px;
  border: 1px solid var(--slate-200, #e2e8f0);
  border-radius: var(--radius-full, 9999px);
  background: var(--white, #fff);
  color: var(--slate-600, #475569);
  font-family: inherit;
  font-size: 0.75rem;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  line-height: 1;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.15s ease;
}

@media (max-width: 640px), (pointer: coarse) {
  .qa-period-chip { min-height: 44px; padding: 0 14px; }
}

.qa-period-chip i {
  font-size: 0.6875rem;
}

.qa-period-chip:hover {
  border-color: var(--primary-300, #5eead4);
  background: var(--primary-50, #f0fdfa);
  color: var(--primary-700, #0f766e);
  transform: translateY(-1px);
}

.qa-period-chip.active {
  border-color: var(--primary-500, #14b8a6);
  background: rgba(20, 184, 166, 0.15);
  color: var(--primary-700, #0f766e);
  font-weight: 600;
  box-shadow: 0 1px 3px rgba(20, 184, 166, 0.15);
}

.qa-period-chip.active:hover {
  background: rgba(20, 184, 166, 0.22);
}

.qa-period-preview {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.875rem;
  color: var(--text-primary, #111827);
  font-weight: 500;
}

.qa-period-preview i {
  color: var(--primary-500, #14b8a6);
}

.qa-custom-dates {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px;
  background: var(--surface-secondary, #f9fafb);
  border-radius: var(--radius-md, 10px);
}

.qa-custom-dates .qa-input {
  flex: 1;
  max-width: 150px;
}

.qa-date-sep {
  color: var(--text-tertiary, #9ca3af);
  font-weight: 500;
}

/* Dark mode period selector */
.dark-mode .qa-period-chip {
  background: rgba(15, 23, 42, 0.4);
  border-color: var(--slate-700, #374151);
  color: var(--slate-300, #cbd5e1);
}

.dark-mode .qa-period-chip:hover {
  border-color: rgba(20, 184, 166, 0.5);
  background: rgba(20, 184, 166, 0.12);
  color: var(--primary-300, #5eead4);
}

.dark-mode .qa-period-chip.active {
  border-color: rgba(20, 184, 166, 0.6);
  background: rgba(20, 184, 166, 0.2);
  color: var(--primary-300, #5eead4);
}

.dark-mode .qa-period-preview {
  color: var(--text-primary, #f9fafb);
}

.dark-mode .qa-custom-dates {
  background: var(--surface-secondary, #111827);
}

/* Mobile responsive period selector */
@media (max-width: 640px) {
  .qa-period-chips {
    gap: 4px;
  }

  /* THE PHONE RULE WAS DOING THE OPPOSITE OF WHAT IT PROMISED (2026-09-23).
     The base .qa-period-chip comment says a media query "tops it back to 44px
     on touch screens"; this block instead cut it to 24px — barely half the
     touch floor, on the surface where touch is the ONLY input. Chips stay
     visually compact via padding/font-size; only the tappable box grows. */
  .qa-period-chip {
    padding: 5px 10px;
    font-size: 0.75rem;
    min-height: 44px;
  }

  .qa-custom-dates {
    flex-direction: column;
    gap: 8px;
  }

  .qa-custom-dates .qa-input {
    max-width: 100%;
    width: 100%;
  }
}

/* ============================================
   ADVANCED OPTIONS (Shift Type Editor)
   ============================================ */

.qa-advanced-options {
  margin-top: 16px;
  border: 1px solid var(--border-subtle, #e5e7eb);
  border-radius: var(--radius-md, 10px);
  overflow: hidden;
}

.qa-advanced-toggle {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 12px 14px;
  background: var(--surface-secondary, #f9fafb);
  cursor: pointer;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--text-secondary, #6b7280);
  transition: all 0.15s;
  list-style: none;
}

.qa-advanced-toggle::-webkit-details-marker {
  display: none;
}

.qa-advanced-toggle:hover {
  background: var(--surface-tertiary, #f3f4f6);
  color: var(--text-primary, #111827);
}

.qa-advanced-toggle .qa-toggle-icon {
  margin-left: auto;
  font-size: 0.75rem;
  transition: transform 0.2s;
}

.qa-advanced-options[open] .qa-toggle-icon {
  transform: rotate(90deg);
}

.qa-advanced-content {
  padding: 14px;
  border-top: 1px solid var(--border-subtle, #e5e7eb);
}

.qa-advanced-hint {
  margin: 10px 0 0;
  font-size: 0.8125rem;
  color: var(--text-tertiary, #9ca3af);
  font-style: italic;
}

/* Dark mode advanced options */
.dark-mode .qa-advanced-options {
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-advanced-toggle {
  background: var(--surface-secondary, #1f2937);
  color: var(--text-secondary, #9ca3af);
}

.dark-mode .qa-advanced-toggle:hover {
  background: var(--surface-tertiary, #374151);
  color: var(--text-primary, #f9fafb);
}

.dark-mode .qa-advanced-content {
  border-top-color: var(--border-subtle, #374151);
}

/* ============================================
   TAB COMPLETION INDICATORS
   ============================================ */

.qa-tab-status {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  margin-left: 6px;
  font-size: 0.625rem;
  transition: all 0.2s;
}

/* Pending state - empty circle */
.qa-tab-status[data-status="pending"] {
  border: 2px solid var(--text-tertiary, #9ca3af);
  background: transparent;
}

.qa-tab-status[data-status="pending"]::before {
  content: "";
}

/* Complete state - checkmark */
.qa-tab-status[data-status="complete"] {
  background: var(--success-color, #10b981);
  border: none;
  color: #fff;
}

.qa-tab-status[data-status="complete"]::before {
  content: "✓";
  font-weight: 700;
}

/* In progress state - partial fill */
.qa-tab-status[data-status="in-progress"] {
  border: 2px solid var(--primary-400, #2dd4bf);
  background: linear-gradient(to right, var(--primary-400, #2dd4bf) 50%, transparent 50%);
}

/* Optional state - small dot */
.qa-tab-status[data-status="optional"] {
  width: 8px;
  height: 8px;
  background: var(--text-tertiary, #9ca3af);
  opacity: 0.5;
}

/* Hide indicators when tab is active (less clutter) */
.qa-tab.active .qa-tab-status {
  opacity: 0.6;
}

/* Dark mode */
.dark-mode .qa-tab-status[data-status="pending"] {
  border-color: var(--text-tertiary, #6b7280);
}

.dark-mode .qa-tab-status[data-status="complete"] {
  background: var(--success-color, #10b981);
}

.dark-mode .qa-tab-status[data-status="optional"] {
  background: var(--text-tertiary, #6b7280);
}

/* ============================================
   EDIT MODALS (Team Defaults, Member Leave)
   ============================================ */

.qa-modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(15, 23, 42, 0.5);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  /* Was --z-toast (5000): the same layer as the toast container, so a
     publish-time toast and this modal's own bottom chrome (sync banner,
     action bar) fought for the same stacking context and rendered as an
     illegible overlapping stack (owner screenshot, 2026-10-05). Every other
     modal in the app uses --z-modal (3000); toasts (5000) now always render
     above it, same as they do above every other dialog. */
  z-index: var(--z-modal);
  display: flex;
  align-items: center;
  justify-content: center;
  animation: qaModalFadeIn 0.15s ease-out;
}

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

.qa-modal-dialog {
  background: var(--surface-primary, #ffffff);
  border-radius: 16px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.25);
  max-width: 500px;
  width: 90%;
  max-height: 85vh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  animation: qaModalSlideIn 0.2s ease-out;
}

@keyframes qaModalSlideIn {
  from {
    opacity: 0;
    transform: translateY(20px) scale(0.95);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

.qa-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid var(--border-color, #e2e8f0);
  background: var(--surface-secondary, #f8fafc);
}

.qa-modal-header h3 {
  margin: 0;
  font-size: 1rem;
  font-weight: 600;
  color: var(--text-primary, #111827);
  display: flex;
  align-items: center;
  gap: 10px;
}

.qa-modal-header h3 i {
  color: var(--primary-500, #14b8a6);
}

.qa-modal-header h3 .qa-member-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.75rem;
  font-weight: 700;
  color: #fff;
}

.qa-modal-close {
  width: 32px;
  height: 32px;
  border: none;
  background: transparent;
  border-radius: var(--radius-full, 9999px);
  color: var(--text-tertiary, #9ca3af);
  cursor: pointer;
  transition: all 0.15s;
  display: flex;
  align-items: center;
  justify-content: center;
}

.qa-modal-close:hover {
  background: var(--surface-tertiary, #e2e8f0);
  color: var(--text-primary, #111827);
}

.qa-modal-body {
  padding: 20px;
  overflow-y: auto;
  flex: 1;
}

.qa-modal-hint {
  margin: 0 0 16px;
  font-size: 0.875rem;
  color: var(--text-secondary, #64748b);
}

.qa-modal-footer {
  display: flex;
  gap: 10px;
  padding: 16px 20px;
  border-top: 1px solid var(--border-color, #e2e8f0);
  background: var(--surface-secondary, #f8fafc);
  justify-content: flex-end;
}

/* Edit Defaults Cards */
.qa-defaults-edit-card {
  padding: 16px;
  border: 1px solid var(--border-color, #e2e8f0);
  border-radius: 12px;
  margin-bottom: 12px;
  background: var(--surface-primary, #ffffff);
}

.qa-defaults-edit-card:last-child {
  margin-bottom: 0;
}

.qa-defaults-edit-header h4 {
  margin: 0 0 12px;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text-primary, #111827);
}

.qa-defaults-edit-fields {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.qa-field-group {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.qa-field-group label {
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--text-secondary, #64748b);
  display: flex;
  align-items: center;
  gap: 6px;
}

.qa-field-group label i {
  font-size: 0.75rem;
}

.qa-field-group .qa-input {
  padding: 8px 12px;
  border: 1px solid var(--border-color, #e2e8f0);
  border-radius: 8px;
  font-size: 0.875rem;
  background: var(--surface-primary, #ffffff);
  color: var(--text-primary, #111827);
}

.qa-field-group .qa-input:focus {
  outline: none;
  border-color: var(--primary-500, #14b8a6);
  box-shadow: var(--focus-ring-shadow);
}

.qa-field-group .qa-input:disabled {
  background: var(--surface-secondary, #f8fafc);
  color: var(--text-tertiary, #9ca3af);
}

.qa-sick-input-row {
  display: flex;
  gap: 10px;
  align-items: center;
}

.qa-sick-input-row .qa-input {
  flex: 1;
}

.qa-unlimited-toggle {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.8125rem;
  color: var(--text-secondary, #64748b);
  cursor: pointer;
  white-space: nowrap;
}

.qa-unlimited-toggle input[type="checkbox"] {
  accent-color: var(--primary-500, #14b8a6);
}

/* Leave Edit Grid */
.qa-leave-edit-grid {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.qa-leave-edit-row {
  padding: 14px;
  border: 1px solid var(--border-color, #e2e8f0);
  border-radius: 12px;
  background: var(--surface-secondary, #f8fafc);
}

.qa-leave-edit-label {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
  font-weight: 600;
  font-size: 0.875rem;
  color: var(--text-primary, #111827);
}

.qa-leave-edit-label i {
  font-size: 1rem;
}

.qa-leave-edit-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
  gap: 12px;
}

.qa-unlimited-notice {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: rgba(249, 115, 22, 0.1);
  border-radius: 8px;
  font-size: 0.875rem;
  color: #c2410c;
  grid-column: span 2;
}

.qa-unlimited-notice i {
  font-size: 0.875rem;
}

/* Dark Mode for Edit Modals */
.dark-mode .qa-modal-overlay {
  background: rgba(0, 0, 0, 0.7);
}

.dark-mode .qa-modal-dialog {
  background: var(--surface-primary, #1e293b);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}

.dark-mode .qa-modal-header {
  background: var(--surface-secondary, #0f172a);
  border-bottom-color: var(--border-color, #334155);
}

.dark-mode .qa-modal-header h3 {
  color: var(--text-primary, #f1f5f9);
}

.dark-mode .qa-modal-close:hover {
  background: var(--surface-tertiary, #334155);
  color: var(--text-primary, #f1f5f9);
}

.dark-mode .qa-modal-hint {
  color: var(--text-secondary, #94a3b8);
}

.dark-mode .qa-modal-footer {
  background: var(--surface-secondary, #0f172a);
  border-top-color: var(--border-color, #334155);
}

.dark-mode .qa-defaults-edit-card {
  background: var(--surface-secondary, #0f172a);
  border-color: var(--border-color, #334155);
}

.dark-mode .qa-defaults-edit-header h4 {
  color: var(--text-primary, #f1f5f9);
}

.dark-mode .qa-field-group label {
  color: var(--text-secondary, #94a3b8);
}

.dark-mode .qa-field-group .qa-input {
  background: var(--surface-primary, #1e293b);
  border-color: var(--border-color, #334155);
  color: var(--text-primary, #f1f5f9);
}

.dark-mode .qa-field-group .qa-input:disabled {
  background: var(--surface-tertiary, #334155);
  color: var(--text-tertiary, #64748b);
}

.dark-mode .qa-leave-edit-row {
  background: var(--surface-secondary, #0f172a);
  border-color: var(--border-color, #334155);
}

.dark-mode .qa-leave-edit-label {
  color: var(--text-primary, #f1f5f9);
}

.dark-mode .qa-unlimited-notice {
  background: rgba(249, 115, 22, 0.15);
  color: #fb923c;
}

/* Responsive */
@media (max-width: 480px) {
  .qa-modal-dialog {
    width: 95%;
    max-height: 90vh;
  }

  .qa-modal-header {
    padding: 14px 16px;
  }

  .qa-modal-body {
    padding: 16px;
  }

  .qa-modal-footer {
    padding: 14px 16px;
  }

  .qa-leave-edit-fields {
    grid-template-columns: 1fr 1fr;
  }

  .qa-sick-input-row {
    flex-direction: column;
    align-items: stretch;
  }
}

/* ============================================
   CALENDAR PICKER (Schedule Period)
   ============================================ */

.qa-calendar-picker-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: 1px solid var(--border-color, #e2e8f0);
  border-radius: 8px;
  background: var(--surface-primary, #ffffff);
  color: var(--text-secondary, #64748b);
  cursor: pointer;
  transition: all 0.15s;
  flex-shrink: 0;
}

.qa-calendar-picker-btn:hover {
  border-color: var(--primary-500, #14b8a6);
  background: var(--primary-50, rgba(20, 184, 166, 0.05));
  color: var(--primary-600, #0d9488);
}

.qa-calendar-picker-btn i {
  font-size: 0.875rem;
}

.qa-date-range-row {
  display: flex;
  /* Left-pack the From / To fields + Refresh button. This is a DUPLICATE
     base rule (the first is at ~line 2019); because it appears later in
     source order with equal specificity it wins the cascade everywhere,
     including the mobile @media block that resets to flex-start. It used
     to set align-items:flex-end, which clobbered the mobile left-align fix
     and right-shoved the date entrance. flex-start reads cleanly on both:
     the From/To labels sit ABOVE their inputs, so there is no baseline to
     align by — top-alignment is correct on desktop and mobile alike. */
  align-items: flex-start;
  justify-content: flex-start;
  gap: 12px;
  flex-wrap: wrap;
}

/* Calendar Picker Dialog */
.qa-calendar-picker-dialog {
  max-width: 340px;
  width: 90%;
  background: var(--surface-primary, #ffffff);
  border-radius: 16px;
  overflow: hidden;
  user-select: none;
}

.qa-calendar-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px;
  background: var(--surface-secondary, #f8fafc);
  border-bottom: 1px solid var(--border-color, #e2e8f0);
}

.qa-cal-month-label {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--text-primary, #111827);
}

.qa-cal-nav {
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: var(--surface-primary, #ffffff);
  border-radius: 8px;
  color: var(--text-secondary, #64748b);
  cursor: pointer;
  transition: all 0.15s;
}

.qa-cal-nav:hover {
  background: var(--primary-500, #14b8a6);
  color: #fff;
}

.qa-calendar-weekdays {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  padding: 10px 12px 6px;
  text-align: center;
  font-size: 10px;
  font-weight: 600;
  color: var(--text-tertiary, #9ca3af);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.qa-calendar-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
  padding: 4px 12px 12px;
}

.qa-cal-day {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 8px;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--text-primary, #111827);
  cursor: pointer;
  transition: all 0.1s;
}

.qa-cal-day.empty {
  cursor: default;
}

.qa-cal-day.today {
  background: var(--surface-tertiary, #e2e8f0);
  font-weight: 700;
}

.qa-cal-day:not(.empty):hover {
  background: var(--primary-50, rgba(20, 184, 166, 0.1));
}

/* Selected range */
.qa-cal-day.selected {
  background: var(--primary-100, rgba(20, 184, 166, 0.15));
  color: var(--primary-700, #0f766e);
  border-radius: 0;
}

.qa-cal-day.selected.range-start {
  background: var(--primary-500, #14b8a6);
  color: #fff;
  border-radius: 8px 0 0 8px;
}

.qa-cal-day.selected.range-end {
  background: var(--primary-500, #14b8a6);
  color: #fff;
  border-radius: 0 8px 8px 0;
}

.qa-cal-day.selected.range-start.range-end {
  border-radius: 8px;
}

/* Selection info */
.qa-calendar-selection {
  padding: 12px 16px;
  background: var(--primary-50, rgba(20, 184, 166, 0.08));
  border-top: 1px solid var(--border-color, #e2e8f0);
  text-align: center;
}

.qa-cal-selection-info {
  font-size: 0.875rem;
  color: var(--text-secondary, #64748b);
}

.qa-cal-hint {
  font-size: 0.875rem;
  color: var(--text-tertiary, #9ca3af);
}

.qa-cal-total {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 6px;
  margin-bottom: 4px;
}

.qa-cal-total-number {
  font-size: 2rem;
  font-weight: 800;
  color: var(--primary-600, #0d9488);
  line-height: 1;
}

.qa-cal-total-label {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text-secondary, #64748b);
}

.qa-cal-date-range {
  display: block;
  font-size: 0.75rem;
  color: var(--text-tertiary, #9ca3af);
}

/* Day sequence badges */
.day-seq-badge {
  position: absolute;
  top: 2px;
  right: 2px;
  min-width: 14px;
  height: 14px;
  padding: 0 3px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--primary-500, #14b8a6);
  color: #fff;
  font-size: 9px;
  font-weight: 700;
  border-radius: 7px;
  line-height: 1;
}

.qa-cal-day.range-start .day-seq-badge,
.qa-cal-day.range-end .day-seq-badge {
  background: #fff;
  color: var(--primary-600, #0d9488);
}

/* Dark mode calendar */
.dark-mode .qa-calendar-picker-btn {
  background: var(--surface-tertiary, #1f2937);
  border-color: var(--border-color, #374151);
  color: var(--text-secondary, #94a3b8);
}

.dark-mode .qa-calendar-picker-btn:hover {
  border-color: var(--primary-500, #14b8a6);
  background: rgba(20, 184, 166, 0.15);
  color: var(--primary-400, #2dd4bf);
}

.dark-mode .qa-calendar-picker-dialog {
  background: var(--surface-primary, #1e293b);
}

.dark-mode .qa-calendar-header {
  background: var(--surface-secondary, #0f172a);
  border-bottom-color: var(--border-color, #334155);
}

.dark-mode .qa-cal-month-label {
  color: var(--text-primary, #f1f5f9);
}

.dark-mode .qa-cal-nav {
  background: var(--surface-primary, #1e293b);
  color: var(--text-secondary, #94a3b8);
}

.dark-mode .qa-cal-day {
  color: var(--text-primary, #f1f5f9);
}

.dark-mode .qa-cal-day.today {
  background: var(--surface-tertiary, #334155);
}

.dark-mode .qa-calendar-selection {
  background: rgba(20, 184, 166, 0.1);
  border-top-color: var(--border-color, #334155);
}

.dark-mode .qa-cal-total-number {
  color: var(--primary-400, #2dd4bf);
}

@media (max-width: 480px) {
  .qa-calendar-picker-dialog {
    width: 95%;
  }

  .qa-cal-day {
    width: 34px;
    height: 34px;
    font-size: 0.875rem;
  }
}

/* ============================================
   BOARD SELECTOR
   ============================================ */

.qa-board-selector {
  position: relative;
  margin-left: 12px;
}

.qa-board-selector-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  border: 1px solid var(--border-subtle, #e5e7eb);
  border-radius: var(--radius-md, 8px);
  background: var(--surface-secondary, #f9fafb);
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--text-primary, #111827);
  cursor: pointer;
  transition: all 0.15s ease;
}

.qa-board-selector-btn:hover {
  background: var(--surface-tertiary, #f3f4f6);
  border-color: var(--primary-color, #14b8a6);
}

.qa-board-selector-btn i:first-child {
  color: var(--primary-color, #14b8a6);
}

.qa-board-chevron {
  font-size: 0.7em;
  color: var(--text-secondary, #6b7280);
  transition: transform 0.2s ease;
}

.qa-board-dropdown.active + .qa-board-selector-btn .qa-board-chevron,
.qa-board-selector-btn:focus + .qa-board-dropdown .qa-board-chevron {
  transform: rotate(180deg);
}

.qa-board-dropdown {
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 200px;
  background: var(--surface-primary, #ffffff);
  border: 1px solid var(--border-subtle, #e5e7eb);
  border-radius: var(--radius-md, 8px);
  box-shadow: var(--shadow-lg, 0 10px 25px rgba(0,0,0,0.15));
  z-index: 100;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px);
  transition: all 0.2s ease;
  margin-top: 4px;
}

.qa-board-dropdown.active {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

.qa-board-option {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 10px 14px;
  border: none;
  background: none;
  font-size: 0.875rem;
  color: var(--text-primary, #111827);
  cursor: pointer;
  text-align: left;
  transition: background 0.15s ease;
}

.qa-board-option:hover {
  background: var(--surface-secondary, #f9fafb);
}

.qa-board-option.active {
  background: var(--primary-50, #f0fdfa);
  color: var(--primary-color, #14b8a6);
}

.qa-board-option i {
  width: 16px;
  text-align: center;
  color: var(--text-secondary, #6b7280);
}

.qa-board-option.active i {
  color: var(--primary-color, #14b8a6);
}

.qa-board-count {
  margin-left: auto;
  font-size: 0.75rem;
  background: var(--surface-tertiary, #f3f4f6);
  padding: 2px 6px;
  border-radius: var(--radius-sm, 4px);
  color: var(--text-secondary, #6b7280);
}

.qa-board-divider {
  height: 1px;
  background: var(--border-subtle, #e5e7eb);
  margin: 4px 0;
}

/* (.qa-board-create / .qa-board-create i color rules
   moved into the canonical .qa-board-option block at
   the top of this file. Kept empty as a marker.) */

/* ============================================
   EDITABLE PREVIEW GRID
   ============================================ */

.qa-preview-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
  flex-wrap: wrap;
  gap: 12px;
}

.qa-preview-toolbar {
  display: flex;
  gap: 8px;
}

.qa-btn-ghost {
  background: transparent;
  border: 1px solid var(--border-subtle, #e5e7eb);
  color: var(--text-secondary, #6b7280);
}

.qa-btn-ghost:hover:not(:disabled) {
  background: var(--surface-secondary, #f9fafb);
  color: var(--text-primary, #111827);
}

.qa-btn-ghost:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.qa-preview-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 12px;
  margin-bottom: 16px;
}

.qa-preview-day {
  background: var(--surface-secondary, #f9fafb);
  border-radius: var(--radius-md, 8px);
  padding: 12px;
  border: 1px solid var(--border-subtle, #e5e7eb);
}

.qa-preview-day-header {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text-primary, #111827);
  margin-bottom: 10px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--border-subtle, #e5e7eb);
}

.qa-preview-day-slots {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 60px;
  padding: 4px;
  border-radius: var(--radius-sm, 4px);
  transition: background 0.2s ease;
}

.qa-preview-day-slots.drag-over {
  background: rgba(20, 184, 166, 0.1);
  border: 1px dashed var(--primary-color, #14b8a6);
}

.qa-preview-slot {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  background: var(--surface-primary, #ffffff);
  border-radius: var(--radius-sm, 6px);
  border: 1px solid var(--border-subtle, #e5e7eb);
  cursor: grab;
  transition: all 0.15s ease;
}

.qa-preview-slot:hover {
  border-color: var(--primary-color, #14b8a6);
  box-shadow: 0 2px 8px rgba(0,0,0,0.08);
}

.qa-preview-slot.dragging {
  opacity: 0.5;
  cursor: grabbing;
}

.qa-slot-color {
  width: 4px;
  height: 32px;
  border-radius: 2px;
  flex-shrink: 0;
}

.qa-slot-content {
  flex: 1;
  min-width: 0;
}

.qa-slot-member-select {
  width: 100%;
  padding: 4px 6px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm, 4px);
  background: transparent;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--text-primary, #111827);
  cursor: pointer;
  transition: all 0.15s ease;
}

.qa-slot-member-select:hover,
.qa-slot-member-select:focus {
  border-color: var(--border-subtle, #e5e7eb);
  background: var(--surface-secondary, #f9fafb);
}

.qa-slot-time {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 0.75rem;
  color: var(--text-secondary, #6b7280);
}

.qa-slot-time-input {
  width: 70px;
  padding: 2px 4px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm, 4px);
  background: transparent;
  font-size: 0.75rem;
  color: var(--text-secondary, #6b7280);
}

.qa-slot-time-input:hover,
.qa-slot-time-input:focus {
  border-color: var(--border-subtle, #e5e7eb);
  background: var(--surface-primary, #ffffff);
}

.qa-slot-remove {
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: transparent;
  color: var(--text-tertiary, #9ca3af);
  border-radius: var(--radius-sm, 4px);
  cursor: pointer;
  transition: all 0.15s ease;
  flex-shrink: 0;
}

.qa-slot-remove:hover {
  background: rgba(239, 68, 68, 0.1);
  color: #ef4444;
}

.qa-slot-add {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px;
  border: 1px dashed var(--border-subtle, #e5e7eb);
  border-radius: var(--radius-sm, 6px);
  background: transparent;
  font-size: 0.75rem;
  color: var(--text-secondary, #6b7280);
  cursor: pointer;
  transition: all 0.15s ease;
}

.qa-slot-add:hover {
  border-color: var(--primary-color, #14b8a6);
  color: var(--primary-color, #14b8a6);
  background: rgba(20, 184, 166, 0.05);
}

.qa-fairness-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 36px;
  height: 28px;
  padding: 0 8px;
  border-radius: var(--radius-md, 8px);
  font-size: 0.875rem;
  font-weight: 700;
}

.qa-fairness-badge.excellent {
  background: rgba(76, 29, 149, 0.15);
  color: #4c1d95;
}

.qa-fairness-badge.good {
  background: rgba(91, 33, 182, 0.15);
  color: #5b21b6;
}

.qa-fairness-badge.fair {
  background: rgba(109, 40, 217, 0.15);
  color: #6d28d9;
}

.qa-fairness-badge.attention {
  background: rgba(124, 58, 237, 0.15);
  color: #7c3aed;
}

/* (.qa-empty-state.qa-success / .qa-error color is
   defined in the empty-state block at the top of
   the file via per-element selectors. !important
   was a workaround for cascading; no longer needed.) */

/* ============================================
   SICK DAYS WIDGET
   ============================================ */

.qa-sick-days-widget {
  padding: 12px 14px;
  background: var(--surface-secondary, #f9fafb);
  border-radius: var(--radius-md, 8px);
  border: 1px solid var(--border-subtle, #e5e7eb);
}

.qa-sick-days-widget.warning {
  border-color: var(--warning-color, #f59e0b);
  background: rgba(245, 158, 11, 0.05);
}

.qa-sick-days-widget.critical {
  border-color: var(--danger-color, #ef4444);
  background: rgba(239, 68, 68, 0.05);
}

.qa-sick-header {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text-primary, #111827);
  margin-bottom: 8px;
}

.qa-sick-header i {
  color: var(--text-secondary, #6b7280);
}

.qa-sick-days-widget.warning .qa-sick-header i {
  color: var(--warning-color, #f59e0b);
}

.qa-sick-days-widget.critical .qa-sick-header i {
  color: var(--danger-color, #ef4444);
}

.qa-sick-bar {
  height: 6px;
  background: var(--surface-tertiary, #e5e7eb);
  border-radius: 3px;
  overflow: hidden;
  margin-bottom: 8px;
}

.qa-sick-fill {
  height: 100%;
  width: var(--qa-fill-pct, 0%);
  background: var(--primary-500, #14b8a6);
  border-radius: var(--radius-full, 9999px);
  transition: width 0.3s ease, background-color 0.15s ease;
}

.qa-sick-days-widget.warning .qa-sick-fill {
  background: #f59e0b;
}

.qa-sick-days-widget.critical .qa-sick-fill {
  background: var(--error, #ef4444);
}

.qa-sick-stats {
  display: flex;
  justify-content: space-between;
  font-size: 0.75rem;
  color: var(--text-secondary, #6b7280);
}

.qa-sick-month {
  font-weight: 500;
}

/* ============================================
   HISTORY VIEW
   ============================================ */

.qa-history-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 40px 20px;
  text-align: center;
  color: var(--text-secondary, #6b7280);
}

.qa-history-empty i {
  font-size: 2rem;
  opacity: 0.4;
}

/* History runs — stacked card list. Each card has
   a header (date + status pill), a stats row, and a
   footer (timestamp + action button). Mirrors the
   .qa-member-card chrome and chip family. */
.qa-history-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.qa-history-item {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px;
  background: var(--slate-50, #f8fafc);
  border-radius: var(--radius-md, 12px);
  border: 1px solid var(--slate-200, #e2e8f0);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.qa-history-item:hover {
  border-color: var(--primary-300, #5eead4);
  box-shadow: 0 1px 3px rgba(20, 184, 166, 0.08);
}

.qa-history-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

/* Audit-2026-05-30-03-25: actor attribution line in History tab. The
   cron variant gets a robot icon + slightly muted tint to distinguish
   server-driven runs from admin-driven ones. */
.qa-history-actor {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.8125rem;
  color: var(--text-secondary, #475569);
}
.qa-history-actor i { font-size: 0.75rem; opacity: 0.8; }
.qa-history-actor-cron { color: var(--text-muted, #64748b); font-style: italic; }

.qa-history-date {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--slate-800, #1e293b);
}

.qa-history-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border-radius: var(--radius-full, 9999px);
  font-size: 0.6875rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border: 1px solid transparent;
}

.qa-history-status.committed {
  background: rgba(22, 163, 74, 0.12);
  color: #15803d;
  border-color: rgba(22, 163, 74, 0.3);
}

.qa-history-status.rolled-back {
  background: rgba(239, 68, 68, 0.10);
  color: var(--error, #ef4444);
  border-color: rgba(239, 68, 68, 0.3);
}

.qa-history-status.preview {
  background: rgba(245, 158, 11, 0.12);
  color: #b45309;
  border-color: rgba(245, 158, 11, 0.3);
}

.qa-run-stats {
  display: flex;
  gap: 18px;
  flex-wrap: wrap;
}

.qa-run-stat {
  font-size: 0.75rem;
  color: var(--slate-500, #6b7280);
}

.qa-run-stat strong {
  display: block;
  font-size: 1rem;
  font-weight: 700;
  color: var(--slate-800, #1e293b);
  font-variant-numeric: tabular-nums;
}

.qa-history-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--slate-200, #e2e8f0);
}

.qa-history-timestamp {
  font-size: 0.6875rem;
  color: var(--slate-500, #94a3b8);
  font-variant-numeric: tabular-nums;
}

body.dark-mode .qa-history-item {
  background: rgba(15, 23, 42, 0.4);
  border-color: var(--slate-700, #334155);
}

body.dark-mode .qa-history-item:hover {
  border-color: rgba(20, 184, 166, 0.4);
}

body.dark-mode .qa-history-date {
  color: var(--slate-100);
}

body.dark-mode .qa-run-stat {
  color: var(--slate-400);
}

body.dark-mode .qa-run-stat strong {
  color: var(--slate-100);
}

body.dark-mode .qa-history-footer {
  border-top-color: var(--slate-700);
}

body.dark-mode .qa-history-timestamp {
  color: var(--slate-500);
}

body.dark-mode .qa-history-status.committed {
  background: rgba(22, 163, 74, 0.2);
  color: #4ade80;
  border-color: rgba(22, 163, 74, 0.4);
}

body.dark-mode .qa-history-status.rolled-back {
  background: rgba(239, 68, 68, 0.18);
  color: #f87171;
  border-color: rgba(239, 68, 68, 0.4);
}

body.dark-mode .qa-history-status.preview {
  background: rgba(245, 158, 11, 0.18);
  color: #fbbf24;
  border-color: rgba(245, 158, 11, 0.4);
}

/* ============================================
   DARK MODE SUPPORT FOR NEW COMPONENTS
   ============================================ */

/* (Legacy .dark-mode .qa-board-selector-btn / dropdown
   / option rules removed during the visual redesign —
   see body.dark-mode rules in the shell block above
   that mirror canonical .boards-dropdown chrome.) */

.dark-mode .qa-preview-day {
  background: var(--surface-secondary, #1e293b);
  border-color: var(--border-color, #334155);
}

.dark-mode .qa-preview-day-header {
  color: var(--text-primary, #f1f5f9);
  border-bottom-color: var(--border-color, #334155);
}

.dark-mode .qa-preview-slot {
  background: var(--surface-primary, #0f172a);
  border-color: var(--border-color, #334155);
}

.dark-mode .qa-slot-member-select {
  color: var(--text-primary, #f1f5f9);
}

.dark-mode .qa-slot-time-input {
  color: var(--text-secondary, #94a3b8);
}

.dark-mode .qa-sick-days-widget {
  background: var(--surface-secondary, #1e293b);
  border-color: var(--border-color, #334155);
}

.dark-mode .qa-sick-header {
  color: var(--text-primary, #f1f5f9);
}

/* (Legacy .dark-mode .qa-history-item / date rules
   removed — see body.dark-mode rules in the history
   block above.) */

/* ============================================
   Validation & Feedback States
   ============================================ */

/* Input Error State — specificity raised via the
   form-input compound selector so we can drop !important. */
.qa-input-error,
input.qa-input-error,
.shift-type-editor .form-input.qa-input-error {
  border-color: var(--error, #ef4444);
  box-shadow: 0 0 0 2px rgba(239, 68, 68, 0.15);
}

.qa-input-error:focus {
  border-color: var(--danger-color, #ef4444);
  box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.2);
}

/* Success State for Empty States */
.qa-empty-state.qa-success {
  color: var(--success-color, #22c55e);
}

.qa-empty-state.qa-success i {
  color: var(--success-color, #22c55e);
}

/* Warning State for Empty States */
.qa-empty-state.qa-warning {
  color: var(--warning-color, #f59e0b);
}

.qa-empty-state.qa-warning i {
  color: var(--warning-color, #f59e0b);
}

/* Error State for Empty States */
.qa-empty-state.qa-error {
  color: var(--danger-color, #ef4444);
}

.qa-empty-state.qa-error i {
  color: var(--danger-color, #ef4444);
}

/* Dark mode support */
body.dark-mode .qa-input-error,
body.dark-mode input.qa-input-error,
body.dark-mode .shift-type-editor .form-input.qa-input-error {
  border-color: #f87171;
  box-shadow: 0 0 0 2px rgba(248, 113, 113, 0.2);
}

.dark-mode .qa-empty-state.qa-success {
  color: var(--success-color, #4ade80);
}

.dark-mode .qa-empty-state.qa-warning {
  color: var(--warning-color, #fbbf24);
}

.dark-mode .qa-empty-state.qa-error {
  color: var(--danger-color, #f87171);
}

/* ============================================
   Shift Type Editor (Redesigned)
   ============================================ */

.shift-type-editor {
  background: var(--surface-secondary, #f9fafb);
  border: 1px solid var(--border-subtle, #e5e7eb);
  border-radius: var(--radius-lg, 12px);
  padding: 20px;
  margin-bottom: 16px;
}

.shift-type-editor .editor-header {
  margin-bottom: 16px;
}

.shift-type-editor .editor-header h4 {
  margin: 0;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--text-primary, #111827);
  display: flex;
  align-items: center;
  gap: 8px;
}

.shift-type-editor .editor-header h4 i {
  color: var(--primary-color, #3b82f6);
}

/* Form row for inline fields */
.shift-type-editor .form-row {
  display: flex;
  gap: 12px;
  margin-bottom: 0;
}

.shift-type-editor .form-group {
  margin-bottom: 14px;
}

.shift-type-editor .form-group label {
  display: block;
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--text-secondary, #6b7280);
  margin-bottom: 4px;
}

/* Compact chips for shift type editor */
.shift-type-editor .event-type-chips {
  gap: 6px;
}

.shift-type-editor .event-type-chip {
  padding: 6px 12px;
  font-size: 0.75rem;
  min-height: auto;
  border-radius: 9999px;
}

.shift-type-editor .event-type-chip i {
  font-size: 0.75rem;
}

.shift-type-editor .duration-chips {
  gap: 6px;
}

.shift-type-editor .duration-chip {
  padding: 6px 12px;
  font-size: 0.75rem;
  min-height: auto;
  border-radius: 9999px;
}

.shift-type-editor .form-input {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid var(--border-default, #d1d5db);
  border-radius: var(--radius-md, 8px);
  font-size: 0.875rem;
  background: var(--white, #ffffff);
  color: var(--text-primary, #111827);
  transition: border-color 0.15s, box-shadow 0.15s;
}

.shift-type-editor .form-input:focus {
  outline: none;
  border-color: var(--primary-color, #3b82f6);
  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}

.shift-type-editor .form-input.input-error {
  border-color: var(--danger-color, #ef4444);
  box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.1);
}

/* Custom duration row */
.shift-type-editor .custom-duration-row {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 10px;
  padding: 10px 12px;
  background: var(--surface-tertiary, #f3f4f6);
  border-radius: var(--radius-md, 8px);
  position: relative;
  z-index: 1;
}

/* Specificity raised so we can drop !important —
   the chained selectors win over generic .form-input. */
.shift-type-editor .custom-duration-row input.form-input,
.shift-type-editor .custom-duration-row input.qa-input-narrow {
  width: 60px;
  padding: 6px 8px;
  text-align: center;
  font-size: 0.875rem;
}

.shift-type-editor .input-suffix {
  font-size: 0.75rem;
  color: var(--text-secondary, #6b7280);
  font-weight: 500;
}

/* Color swatches */
.shift-type-editor .color-swatches {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 6px;
}

.shift-type-editor .color-swatches.extended {
  margin-top: 8px;
}

.shift-type-editor .color-swatch {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 2px solid transparent;
  background: var(--qa-swatch-color, var(--primary-500, #14b8a6));
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.15s, border-color 0.15s, box-shadow 0.15s;
  padding: 0;
}

.shift-type-editor .color-swatch:hover {
  transform: scale(1.1);
}

.shift-type-editor .color-swatch.active {
  border-color: var(--text-primary, #111827);
  box-shadow: 0 0 0 2px var(--white, #ffffff);
}

.shift-type-editor .color-swatch i {
  color: var(--white, #ffffff);
  font-size: 0.75rem;
  opacity: 0;
  text-shadow: 0 1px 2px rgba(0,0,0,0.3);
}

.shift-type-editor .color-swatch.active i {
  opacity: 1;
}

.shift-type-editor .color-swatch.color-expand {
  background: var(--surface-tertiary, #f3f4f6);
  border: 1px dashed var(--border-default, #d1d5db);
}

.shift-type-editor .color-swatch.color-expand i {
  color: var(--text-secondary, #6b7280);
  opacity: 1;
}

/* Advanced section */
.shift-type-editor .advanced-section {
  margin-top: 16px;
  border-top: 1px solid var(--border-subtle, #e5e7eb);
  padding-top: 12px;
}

.shift-type-editor .advanced-section summary {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--text-secondary, #6b7280);
  cursor: pointer;
  user-select: none;
  padding: 4px 0;
}

.shift-type-editor .advanced-section summary:hover {
  color: var(--text-primary, #111827);
}

.shift-type-editor .advanced-section summary i {
  font-size: 0.75rem;
}

.shift-type-editor .advanced-section[open] summary {
  margin-bottom: 12px;
}

.shift-type-editor .advanced-content {
  padding-left: 4px;
}

.shift-type-editor .advanced-content .form-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}

/* Form actions */
.shift-type-editor .form-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--border-subtle, #e5e7eb);
}

.shift-type-editor .btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  border-radius: var(--radius-md, 8px);
  font-size: 0.8125rem;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.15s;
  border: none;
}

.shift-type-editor .btn-primary {
  background: var(--primary-color, #3b82f6);
  color: var(--white, #ffffff);
}

.shift-type-editor .btn-primary:hover {
  background: var(--primary-600, #2563eb);
}

.shift-type-editor .btn-secondary {
  background: var(--white, #ffffff);
  color: var(--text-secondary, #6b7280);
  border: 1px solid var(--border-default, #d1d5db);
}

.shift-type-editor .btn-secondary:hover {
  background: var(--surface-tertiary, #f3f4f6);
  color: var(--text-primary, #111827);
}

/* Dark mode */
.dark-mode .shift-type-editor {
  background: var(--surface-secondary, #1f2937);
  border-color: var(--border-subtle, #374151);
}

.dark-mode .shift-type-editor .form-input {
  background: var(--surface-primary, #111827);
  border-color: var(--border-default, #4b5563);
  color: var(--text-primary, #f9fafb);
}

.dark-mode .shift-type-editor .color-swatch.color-expand {
  background: var(--surface-tertiary, #374151);
  border-color: var(--border-default, #4b5563);
}

.dark-mode .shift-type-editor .btn-secondary {
  background: var(--surface-primary, #111827);
  border-color: var(--border-default, #4b5563);
  color: var(--text-secondary, #9ca3af);
}

.dark-mode .shift-type-editor .advanced-section {
  border-color: var(--border-subtle, #374151);
}

.dark-mode .shift-type-editor .form-actions {
  border-color: var(--border-subtle, #374151);
}

.dark-mode .shift-type-editor .custom-duration-row {
  background: var(--surface-tertiary, #374151);
}

/* ============================================
   TEAM HOURS - MEMBERS HEADER (Attendees style)
   ============================================ */

/* Section header — small uppercase label on the left,
   muted count on the right. Mirrors the section-label
   typography used elsewhere in the modal. */
.qa-members-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--slate-200, #e2e8f0);
}

.qa-members-header-left {
  display: flex;
  align-items: center;
  gap: 14px;
}

.qa-members-label {
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--slate-500, #6b7280);
}

.qa-select-all-wrap {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  font-size: 0.75rem;
  color: var(--slate-600, #475569);
  font-weight: 500;
}

.qa-select-all-wrap input[type="checkbox"] {
  width: var(--checkbox-size, 18px);
  height: var(--checkbox-size, 18px);
  accent-color: var(--primary-500, #14b8a6);
  cursor: pointer;
}

.qa-select-all-label {
  font-weight: 500;
}

.qa-members-count {
  font-size: 0.75rem;
  color: var(--slate-500, #94a3b8);
  font-weight: 500;
}

/* Member list — stacked cards with breathing room.
   Each card keeps its own chrome (border + bg) so the
   row reads as a discrete unit. Mirrors the .member-
   selection-item card pattern (style.css:37794). */
.qa-member-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-height: 500px;
  overflow-y: auto;
  padding: 2px;
  margin: -2px;
}

/* A SCROLLER'S CHILDREN MUST NOT SHRINK (2026-09-24, owner: "the cards get
   off some text on mobile"). The card is overflow:hidden, which makes its
   flex min-height 0, so four cards were squeezed into the 500px cap (116px
   each, 520px of content) and the stepper row was cut off at the bottom
   instead of the list scrolling. */
.qa-member-list > * {
  flex-shrink: 0;
}

/* ============================================
   TOTAL HOURS DISTRIBUTE
   ============================================ */

.qa-total-distribute {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 16px;
  margin-top: 12px;
  background: var(--slate-50, #f8fafc);
  border: 1px solid var(--slate-200, #e2e8f0);
  border-radius: var(--radius-md, 12px);
}

.qa-total-input-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.qa-total-input-row .qa-hour-input {
  width: 100px;
}

/* ============================================
   BUTTON STATE VARIANTS
   Specificity raised via .qa-btn.qa-btn-success
   so we can drop !important. STATUS_PRESENTATION
   greens (#22c55e available, #16a34a working).
   ============================================ */

.qa-btn.qa-btn-success {
  background: #22c55e;
  border-color: #22c55e;
  color: #fff;
}

.qa-btn.qa-btn-success:hover {
  background: #16a34a;
}

.qa-btn.qa-btn-warning {
  background: #f59e0b;
  border-color: #f59e0b;
  color: #fff;
}

.qa-btn.qa-btn-warning:hover {
  background: #d97706;
}

/* ============================================
   LEAVE-TYPE COLOR SYSTEM
   One central place for the three leave-type
   tokens (vacation / sick / personal) so the
   leave bars + edit-modal icons + edit-row
   strips all read from the same source.
   ============================================ */

.qa-leave-vacation { --qa-leave-color: #22c55e; }
.qa-leave-sick     { --qa-leave-color: #f97316; }
.qa-leave-personal { --qa-leave-color: #a855f7; }

.qa-leave-edit-row .qa-leave-edit-label > i,
.qa-leave-bar-row .qa-leave-label,
.qa-leave-bar-used {
  color: var(--qa-leave-color, var(--primary-500, #14b8a6));
}

.qa-leave-bar-used {
  background: var(--qa-leave-color, var(--primary-500, #14b8a6));
  width: var(--qa-used-pct, 0%);
}

.qa-leave-bar-pending {
  width: var(--qa-pending-pct, 0%);
  left: var(--qa-pending-left, 0%);
}

/* Member avatar — reads --qa-member-color when an
   inline custom prop is set, otherwise falls back to
   the canonical brand gradient used in
   .member-selection-item (style.css:37794). */
.qa-member-avatar {
  background: var(--qa-member-color, linear-gradient(135deg, var(--primary-500, #14b8a6), var(--accent-500, #06b6d4)));
}

/* (.qa-period-suffix-inline defined alongside member
   total badge above — duplicate removed during the
   visual-consistency redesign.) */

/* ============================================
   DARK MODE: NEW ELEMENTS
   ============================================ */

.dark-mode .qa-members-header {
  border-bottom-color: var(--border-subtle, #374151);
}

.dark-mode .qa-members-label {
  color: var(--text-secondary, #9ca3af);
}

.dark-mode .qa-members-count {
  color: var(--text-tertiary, #6b7280);
}

.dark-mode .qa-member-list {
  border-color: var(--border-subtle, #374151);
  background: var(--surface-secondary, #111827);
}

.dark-mode .qa-member-list .qa-member-card {
  border-bottom-color: var(--border-subtle, #374151);
}

.dark-mode .qa-total-distribute {
  background: var(--surface-secondary, #111827);
  border-color: var(--border-subtle, #374151);
}

.dark-mode .qa-period-suffix-inline {
  color: var(--text-tertiary, #6b7280);
}

/* ============================================
   READ-ONLY MODE (quotas.view, no quotas.assign)
   ============================================ */
.quota-assignment-modal.qa-readonly .qa-action-bar,
.quota-assignment-modal.qa-readonly .qa-btn-primary,
.quota-assignment-modal.qa-readonly .qa-btn-danger,
.quota-assignment-modal.qa-readonly .qa-rollback-run,
.quota-assignment-modal.qa-readonly .qa-rollback-btn,
.quota-assignment-modal.qa-readonly .qa-edit-type,
.quota-assignment-modal.qa-readonly .qa-delete-type,
.quota-assignment-modal.qa-readonly .qa-edit-shift-type,
.quota-assignment-modal.qa-readonly .qa-delete-shift-type,
.quota-assignment-modal.qa-readonly #qa-add-shift-type,
.quota-assignment-modal.qa-readonly #qa-distribute-btn,
.quota-assignment-modal.qa-readonly .qa-bulk-preset,
.quota-assignment-modal.qa-readonly .qa-step-btn,
.quota-assignment-modal.qa-readonly .qa-hour-input,
.quota-assignment-modal.qa-readonly input[type="number"],
.quota-assignment-modal.qa-readonly input[type="time"],
.quota-assignment-modal.qa-readonly input[type="date"][readonly] {
    pointer-events: none;
}
.quota-assignment-modal.qa-readonly .qa-action-bar,
.quota-assignment-modal.qa-readonly .qa-btn-primary,
.quota-assignment-modal.qa-readonly .qa-btn-danger,
.quota-assignment-modal.qa-readonly .qa-edit-type,
.quota-assignment-modal.qa-readonly .qa-delete-type,
.quota-assignment-modal.qa-readonly .qa-edit-shift-type,
.quota-assignment-modal.qa-readonly .qa-delete-shift-type,
/* 2026-09-01 browser verification: with only pointer-events:none the hour
   steppers and bulk presets still LOOKED live while their Save button was
   hidden — edits changed on screen and silently went nowhere. A read-only
   viewer sees the numbers, not the editors. */
.quota-assignment-modal.qa-readonly .qa-step-btn,
.quota-assignment-modal.qa-readonly .qa-bulk-preset,
.quota-assignment-modal.qa-readonly .qa-total-distribute {
    display: none !important;
}
/* 2026-09-28: a primary action that is the VIEWER's own (their shifts feed,
   "Add to my calendar") stays for read-only members; the rules above hide
   every .qa-btn-primary because most of them change the team's schedule. */
.quota-assignment-modal.qa-readonly .qa-btn-primary.qa-readonly-keep {
    display: inline-flex !important;
    pointer-events: auto;
}


/* ============================================
   PHASE 3.1 — CELL ACTION POPOVER
   ============================================ */
.qa-grid-cell-action {
    cursor: pointer;
    border: 1px solid transparent;
    background: inherit;
    color: inherit;
    transition: transform .08s ease, box-shadow .08s ease;
}
.qa-grid-cell-action:hover,
.qa-grid-cell-action:focus-visible {
    transform: translateY(-1px);
    box-shadow: 0 1px 4px rgba(0,0,0,0.18);
    outline: none;
}
.quota-assignment-modal.qa-readonly .qa-grid-cell-action {
    cursor: default;
}

/* Cell popover — mirrors .meet-now-popup chrome
   (style.css:42241): white surface, soft shadow,
   shared border + radius. */
.qa-cell-popover {
    width: 320px;
    max-width: calc(100vw - 16px);
    background: var(--surface-primary, #ffffff);
    border: 1px solid var(--slate-200, #e2e8f0);
    border-radius: var(--radius-lg, 16px);
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.05);
    padding: 0;
    font-size: 0.8125rem;
    color: var(--slate-800, #1f2937);
    overflow: hidden;
}

.qa-cell-popover-header {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 12px 14px;
    background: var(--slate-50, #f8fafc);
    border-bottom: 1px solid var(--slate-200, #e2e8f0);
}

.qa-cell-popover-meta {
    color: var(--slate-500, #6b7280);
    font-size: 0.6875rem;
}

.qa-cell-popover-body {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 12px 14px;
}

.qa-cell-popover-row {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.qa-cell-popover-row label {
    font-size: 0.6875rem;
    font-weight: 600;
    color: var(--slate-500, #6b7280);
    width: 100%;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.qa-cell-popover-select {
    flex: 1 1 auto;
    min-width: 0;
    padding: 8px 10px;
    border: 1.5px solid var(--slate-200, #e2e8f0);
    border-radius: var(--radius-sm, 8px);
    background: var(--white, #fff);
    color: var(--slate-800, #1e293b);
    font-family: inherit;
    font-size: 0.8125rem;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.qa-cell-popover-select:focus {
    outline: none;
    border-color: var(--primary-400, #2dd4bf);
    box-shadow: var(--focus-ring-shadow);
}

body.dark-mode .qa-cell-popover {
    background: var(--surface-secondary, #1e293b);
    border-color: var(--slate-700, #334155);
    color: var(--slate-100, #f1f5f9);
}

body.dark-mode .qa-cell-popover-header {
    background: rgba(15, 23, 42, 0.6);
    border-bottom-color: var(--slate-700);
}

body.dark-mode .qa-cell-popover-meta {
    color: var(--slate-400);
}

body.dark-mode .qa-cell-popover-row label {
    color: var(--slate-400);
}

body.dark-mode .qa-cell-popover-select {
    background: rgba(15, 23, 42, 0.4);
    border-color: var(--slate-700);
    color: var(--slate-100);
}

/* ============================================
   PHASE 3.4 — NEEDS-COVER INDICATORS
   ============================================ */
.qa-stat-card.qa-stat-needs-cover {
    border-color: rgba(245, 158, 11, 0.4);
    background: rgba(245, 158, 11, 0.06);
}

.qa-stat-card.qa-stat-needs-cover .qa-stat-value {
    color: #d97706;
}

body.dark-mode .qa-stat-card.qa-stat-needs-cover {
    border-color: rgba(245, 158, 11, 0.5);
    background: rgba(245, 158, 11, 0.1);
}
.qa-needs-cover-banner {
    margin: 0 0 16px 0;
    padding: 12px 14px;
    border-radius: 8px;
    border: 1px solid rgba(245, 158, 11, 0.35);
    background: rgba(245, 158, 11, 0.08);
}
.qa-needs-cover-banner-header {
    display: flex;
    align-items: center;
    gap: 8px;
    font-weight: 600;
    color: #b45309;
    margin-bottom: 8px;
    font-size: 13px;
}
.qa-needs-cover-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.qa-needs-cover-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 8px;
    background: var(--surface, #fff);
    border-radius: 6px;
    font-size: 12px;
}
.qa-needs-cover-meta { flex: 1 1 auto; }
.qa-needs-cover-requestor {
    color: var(--text-tertiary, #6b7280);
    font-size: 11px;
}
body.dark-mode .qa-needs-cover-banner {
    background: rgba(245, 158, 11, 0.15);
    border-color: rgba(245, 158, 11, 0.45);
}
body.dark-mode .qa-needs-cover-banner-header { color: #fbbf24; }
body.dark-mode .qa-needs-cover-item {
    background: var(--surface-secondary, #1f2937);
}

/* ============================================================
   WORKBENCH — Phase 1
   One canvas: toolbar / grid / action bar.
   Reuses existing .qa-week-grid / .qa-grid-cell / .qa-action-bar
   styles. Only adds the workbench shell + draft chrome.
   ============================================================ */
.qa-workbench {
    display: flex;
    flex-direction: column;
    gap: 16px;
    padding: 12px 4px 80px; /* bottom padding leaves room for sticky action bar */
}

.qa-workbench-toolbar {
    display: flex;
    flex-wrap: wrap;
    gap: 12px 18px;
    align-items: center;
    padding: 10px 12px;
    border: 1px solid var(--border-subtle, #e5e7eb);
    border-radius: 10px;
    background: var(--surface-secondary, #f9fafb);
}
body.dark-mode .qa-workbench-toolbar {
    border-color: rgba(255, 255, 255, 0.08);
    background: var(--surface-secondary, #1f2937);
}

.qa-workbench-period,
.qa-workbench-types,
.qa-workbench-configure {
    display: flex;
    gap: 6px;
    align-items: center;
    flex-wrap: wrap;
}
.qa-workbench-configure { margin-left: auto; }

.qa-workbench-window {
    display: flex;
    gap: 6px;
    align-items: center;
    padding: 2px 6px;
    border: 1px solid var(--border-subtle, #e5e7eb);
    border-radius: 8px;
    background: var(--surface-primary, #ffffff);
}
body.dark-mode .qa-workbench-window {
    background: var(--surface-primary, #0f172a);
    border-color: rgba(255, 255, 255, 0.08);
}
.qa-window-label {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-primary, #111827);
    padding: 0 6px;
    min-width: 140px;
    text-align: center;
}
body.dark-mode .qa-window-label { color: var(--text-primary, #f3f4f6); }

.qa-icon-btn {
    appearance: none;
    background: transparent;
    border: none;
    color: var(--text-secondary, #6b7280);
    width: 26px;
    height: 26px;
    border-radius: 6px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s, color 0.15s;
}
.qa-icon-btn:hover {
    background: var(--surface-tertiary, #f3f4f6);
    color: var(--text-primary, #111827);
}
body.dark-mode .qa-icon-btn:hover {
    background: rgba(255, 255, 255, 0.06);
    color: var(--text-primary, #f3f4f6);
}

/* Banner above the grid (needs-cover etc.) */
.qa-workbench-banner {
    margin: 0;
}

/* Empty state CTA — admins land here on first open, no data yet. */
.qa-workbench-cta {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: 48px 24px;
    gap: 12px;
    border: 1px dashed var(--border-subtle, #d1d5db);
    border-radius: 12px;
    background: var(--surface-secondary, #f9fafb);
}
.qa-workbench-cta > i {
    font-size: 32px;
    color: var(--accent-primary, #3b82f6);
}
.qa-workbench-cta-title {
    font-size: 16px;
    font-weight: 600;
    margin: 0;
    color: var(--text-primary, #111827);
}
.qa-workbench-cta-hint {
    font-size: 13px;
    color: var(--text-secondary, #6b7280);
    margin: 0;
    max-width: 380px;
}
body.dark-mode .qa-workbench-cta {
    background: var(--surface-secondary, #1f2937);
    border-color: rgba(255, 255, 255, 0.12);
}
body.dark-mode .qa-workbench-cta-title { color: var(--text-primary, #f3f4f6); }

/* Grid wrapper just gives the table some breathing room */
.qa-workbench-grid-wrap {
    border: 1px solid var(--border-subtle, #e5e7eb);
    border-radius: 10px;
    overflow: hidden;
    background: var(--surface-primary, #ffffff);
}
body.dark-mode .qa-workbench-grid-wrap {
    background: var(--surface-primary, #0f172a);
    border-color: rgba(255, 255, 255, 0.08);
}

/* Today highlight on the grid header */
.qa-grid-today {
    color: var(--accent-primary, #3b82f6) !important;
    position: relative;
}
.qa-grid-today::after {
    content: '';
    position: absolute;
    left: 12px;
    right: 12px;
    bottom: 4px;
    height: 2px;
    background: var(--accent-primary, #3b82f6);
    border-radius: 1px;
}

/* Preview / draft cells — striped overlay so the eye sees them as
   provisional. Same color from --qa-type-color, just less assertive. */
.qa-grid-cell-preview {
    position: relative;
    opacity: 0.85;
    background-image: repeating-linear-gradient(
        45deg,
        transparent,
        transparent 4px,
        rgba(255, 255, 255, 0.18) 4px,
        rgba(255, 255, 255, 0.18) 8px
    );
}
.qa-grid-cell-preview::after {
    content: '';
    position: absolute;
    top: 1px;
    right: 1px;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--accent-primary, #3b82f6);
    box-shadow: 0 0 0 1.5px var(--surface-primary, #fff);
}
body.dark-mode .qa-grid-cell-preview::after {
    box-shadow: 0 0 0 1.5px var(--surface-primary, #0f172a);
}

.qa-preview-swatch {
    background-image: repeating-linear-gradient(
        45deg,
        var(--surface-tertiary, #e5e7eb),
        var(--surface-tertiary, #e5e7eb) 3px,
        var(--surface-secondary, #f3f4f6) 3px,
        var(--surface-secondary, #f3f4f6) 6px
    );
}

/* Workbench action bar — sticky to bottom of the modal body so
   Commit/Discard is always reachable during long scrolls. */
.qa-workbench-action-bar {
    position: sticky;
    bottom: 0;
    margin: 0 -4px -12px;
    padding: 12px 16px;
    background: var(--surface-primary, #ffffff);
    border-top: 1px solid var(--border-subtle, #e5e7eb);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    z-index: 5;
    box-shadow: 0 -4px 12px -8px rgba(0, 0, 0, 0.12);
}
.qa-workbench-action-bar-light {
    justify-content: flex-end;
    background: transparent;
    border-top: none;
    box-shadow: none;
    padding: 4px 16px;
}
body.dark-mode .qa-workbench-action-bar {
    background: var(--surface-primary, #0f172a);
    border-color: rgba(255, 255, 255, 0.08);
}
.qa-workbench-draft-label {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    color: var(--text-secondary, #6b7280);
}
.qa-workbench-draft-label i {
    color: var(--accent-primary, #3b82f6);
    font-size: 10px;
}
.qa-workbench-action-buttons {
    display: flex;
    gap: 8px;
}

/* Read-only mode hides the workbench action bar (write actions only) */
.quota-assignment-modal.qa-readonly .qa-workbench-action-bar {
    display: none;
}

/* ============================================================
   WORKBENCH INTERVENTIONS BANNER — Phase 3
   Stacked rows above the grid. Each row has a colored shift-type
   dot, a 2-line meta block, and 1-3 verb buttons.
   ============================================================ */
.qa-interventions-banner {
    background: rgba(245, 158, 11, 0.06);
    border: 1px solid rgba(245, 158, 11, 0.22);
    border-radius: 10px;
    padding: 10px 12px;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
body.dark-mode .qa-interventions-banner {
    background: rgba(245, 158, 11, 0.1);
    border-color: rgba(245, 158, 11, 0.32);
}

.qa-interventions-header {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    color: #b45309;
    font-weight: 500;
    padding-bottom: 4px;
    border-bottom: 1px dashed rgba(245, 158, 11, 0.25);
}
body.dark-mode .qa-interventions-header { color: #fbbf24; }

.qa-intervention-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 4px;
}
.qa-intervention-row .qa-shift-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--qa-type-color);
    flex-shrink: 0;
}
.qa-intervention-meta {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    min-width: 0;
}
.qa-intervention-title {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-primary, #111827);
}
body.dark-mode .qa-intervention-title { color: var(--text-primary, #f3f4f6); }
.qa-intervention-sub {
    font-size: 11px;
    color: var(--text-secondary, #6b7280);
}
.qa-intervention-actions {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    justify-content: flex-end;
}
.qa-intervention-verb {
    font-size: 12px;
    padding: 5px 10px;
    white-space: nowrap;
}

/* Read-only: no fixes are presented to viewers */
.quota-assignment-modal.qa-readonly .qa-interventions-banner {
    display: none;
}

/* Slim empty-state hint shown below the interventions banner when the
   grid has nothing to draw and the banner is the CTA. */
.qa-workbench-empty-hint {
    margin: 12px 0;
    padding: 10px 14px;
    border-radius: 8px;
    background: var(--surface-secondary, #f9fafb);
    color: var(--text-secondary, #6b7280);
    font-size: 13px;
    display: flex;
    gap: 8px;
    align-items: flex-start;
}
.qa-workbench-empty-hint i {
    color: var(--text-tertiary, #9ca3af);
    margin-top: 3px;
}
body.dark-mode .qa-workbench-empty-hint {
    background: rgba(255, 255, 255, 0.04);
}

/* ============================================================
   WORKBENCH INSPECTORS — Phase 2
   Right-rail panel mounted over the modal body. Three variants
   share the chrome; the body class .qa-inspector-<variant> lets
   us tweak per-mode if needed.
   ============================================================ */

/* Grid clickability — member labels and empty cells become buttons */
.qa-grid-member-btn {
    appearance: none;
    background: transparent;
    border: none;
    padding: 6px 8px;
    text-align: left;
    color: inherit;
    font: inherit;
    cursor: pointer;
    width: 100%;
    border-radius: 6px;
    transition: background 0.15s;
}
.qa-grid-member-btn:hover {
    background: var(--surface-tertiary, #f3f4f6);
}
body.dark-mode .qa-grid-member-btn:hover {
    background: rgba(255, 255, 255, 0.06);
}
.qa-grid-cell.qa-grid-cell-empty {
    cursor: pointer;
    background: transparent;
    border: none;
    color: var(--text-tertiary, #9ca3af);
}
/* The empty cell is the primary way to place a shift, but a full-strength +
   in every cell of a 7-day grid is louder than the shifts themselves. Keep it
   faint at rest so assigned cells dominate, and bring it up on hover/focus
   where it becomes an obvious target. (user 2026-08-11: "i dont like dots") */
.qa-cell-add {
    font-size: 1rem;
    line-height: 1;
    opacity: 0.28;
    transition: opacity 0.12s ease;
}
.qa-grid-cell.qa-grid-cell-empty:hover .qa-cell-add,
.qa-grid-cell.qa-grid-cell-empty:focus-visible .qa-cell-add {
    opacity: 1;
}
.qa-grid-cell.qa-grid-cell-empty:hover {
    color: var(--text-secondary, #6b7280);
    background: var(--surface-tertiary, #f3f4f6);
    border-radius: 4px;
}
.qa-grid-cell.qa-grid-cell-empty:focus-visible {
    outline: 2px solid var(--accent, #0284c7);
    outline-offset: -2px;
    border-radius: 4px;
}
body.dark-mode .qa-grid-cell.qa-grid-cell-empty:hover {
    background: rgba(255, 255, 255, 0.04);
}

/* Inspector panel — fixed inside modal-content. Slides in from right. */
.qa-inspector {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 360px;
    max-width: 92vw;
    background: var(--surface-primary, #ffffff);
    border-left: 1px solid var(--border-subtle, #e5e7eb);
    box-shadow: -8px 0 24px -12px rgba(0, 0, 0, 0.18);
    display: flex;
    flex-direction: column;
    z-index: 20;
    animation: qa-inspector-in 180ms ease-out;
}
@keyframes qa-inspector-in {
    from { transform: translateX(16px); opacity: 0; }
    to { transform: translateX(0); opacity: 1; }
}
body.dark-mode .qa-inspector {
    background: var(--surface-primary, #0f172a);
    border-color: rgba(255, 255, 255, 0.08);
    box-shadow: -8px 0 24px -12px rgba(0, 0, 0, 0.5);
}

.qa-inspector-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 16px;
    border-bottom: 1px solid var(--border-subtle, #e5e7eb);
}
body.dark-mode .qa-inspector-header {
    border-color: rgba(255, 255, 255, 0.06);
}

.qa-inspector-close {
    appearance: none;
    background: transparent;
    border: none;
    width: 32px;
    height: 32px;
    border-radius: var(--radius-full, 9999px);
    cursor: pointer;
    color: var(--text-tertiary, #9ca3af);
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.qa-inspector-close:hover {
    background: var(--surface-tertiary, #f3f4f6);
    color: var(--text-primary, #111827);
}
body.dark-mode .qa-inspector-close:hover {
    background: rgba(255, 255, 255, 0.06);
    color: var(--text-primary, #f3f4f6);
}

.qa-inspector-body {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 12px 16px 80px;
}

/* Header variants share the same flex pattern */
.qa-insp-member-head,
.qa-insp-cell-head,
.qa-insp-day-head {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
    flex: 1 1 auto;
}
.qa-insp-member-head {
    flex-direction: row;
    align-items: center;
    gap: 10px;
}
.qa-insp-member-meta { display: flex; flex-direction: column; min-width: 0; }
.qa-insp-member-name,
.qa-insp-cell-type,
.qa-insp-day-date {
    font-size: 15px;
    font-weight: 600;
    color: var(--text-primary, #111827);
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.qa-insp-cell-type .qa-shift-dot {
    background: var(--qa-type-color);
}
.qa-insp-member-sub,
.qa-insp-cell-sub,
.qa-insp-day-sub {
    font-size: 12px;
    color: var(--text-secondary, #6b7280);
}
body.dark-mode .qa-insp-member-name,
body.dark-mode .qa-insp-cell-type,
body.dark-mode .qa-insp-day-date {
    color: var(--text-primary, #f3f4f6);
}

.qa-insp-draft-pill {
    margin-left: 6px;
    padding: 1px 6px;
    border-radius: 6px;
    background: var(--accent-primary, #3b82f6);
    color: #fff;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

/* Sections inside the body */
.qa-insp-section {
    padding: 14px 0;
    border-bottom: 1px solid var(--border-subtle, #f3f4f6);
}
.qa-insp-section:last-child { border-bottom: none; }
body.dark-mode .qa-insp-section { border-color: rgba(255, 255, 255, 0.05); }

.qa-insp-section-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 10px;
}
.qa-insp-section-title {
    font-size: 12px;
    font-weight: 600;
    color: var(--text-secondary, #6b7280);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin: 0 0 10px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.qa-insp-section-head .qa-insp-section-title { margin: 0; }
.qa-insp-section-title i { color: var(--text-tertiary, #9ca3af); font-size: 11px; }
body.dark-mode .qa-insp-section-title { color: var(--text-secondary, #9ca3af); }

.qa-insp-empty {
    padding: 12px;
    border-radius: 8px;
    background: var(--surface-secondary, #f9fafb);
    color: var(--text-secondary, #6b7280);
    font-size: 12px;
}
body.dark-mode .qa-insp-empty {
    background: rgba(255, 255, 255, 0.04);
}

/* Quota period chips (mini version of the toolbar chips) */
.qa-insp-period-chips {
    display: inline-flex;
    gap: 2px;
    padding: 2px;
    background: var(--surface-secondary, #f3f4f6);
    border-radius: 6px;
}
.qa-insp-period-chip {
    appearance: none;
    background: transparent;
    border: none;
    padding: 4px 8px;
    font-size: 11px;
    font-weight: 500;
    color: var(--text-secondary, #6b7280);
    border-radius: 4px;
    cursor: pointer;
}
.qa-insp-period-chip.active {
    background: var(--surface-primary, #ffffff);
    color: var(--accent-primary, #3b82f6);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
}
body.dark-mode .qa-insp-period-chips { background: rgba(255, 255, 255, 0.06); }
body.dark-mode .qa-insp-period-chip.active {
    background: var(--surface-tertiary, #374151);
    color: var(--accent-primary, #60a5fa);
}

/* Quota rows in the inspector */
.qa-insp-quota-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 0;
}
.qa-insp-quota-label {
    display: flex;
    align-items: center;
    gap: 6px;
    width: 100px;
    flex-shrink: 0;
    font-size: 13px;
    color: var(--text-primary, #111827);
}
body.dark-mode .qa-insp-quota-label { color: var(--text-primary, #f3f4f6); }
.qa-insp-quota-label .qa-shift-dot {
    width: 8px; height: 8px; border-radius: 50%;
    background: var(--qa-type-color);
}
.qa-insp-quota-progress {
    flex: 1 1 auto;
    min-width: 0;
}
.qa-insp-quota-bar {
    height: 4px;
    background: var(--surface-tertiary, #e5e7eb);
    border-radius: 2px;
    overflow: hidden;
    margin-bottom: 4px;
}
.qa-insp-quota-fill {
    height: 100%;
    width: var(--qa-fill-pct, 0%);
    background: var(--qa-type-color, var(--accent-primary, #3b82f6));
    transition: width 0.2s ease;
}
body.dark-mode .qa-insp-quota-bar { background: rgba(255, 255, 255, 0.08); }
.qa-insp-quota-meta {
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: 11px;
    color: var(--text-secondary, #6b7280);
}
.qa-insp-quota-used { flex: 1 1 auto; }
.qa-insp-hour-input {
    width: 50px;
    padding: 2px 4px;
    border: 1px solid var(--border-subtle, #d1d5db);
    border-radius: 4px;
    font-size: 12px;
    text-align: right;
    background: var(--surface-primary, #ffffff);
    color: var(--text-primary, #111827);
}
.qa-insp-hour-input:focus {
    outline: none;
    border-color: var(--accent-primary, #3b82f6);
    box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.15);
}
body.dark-mode .qa-insp-hour-input {
    background: var(--surface-secondary, #1f2937);
    border-color: rgba(255, 255, 255, 0.1);
    color: var(--text-primary, #f3f4f6);
}
.qa-insp-quota-suffix {
    color: var(--text-tertiary, #9ca3af);
}

/* Day toggles */
.qa-insp-field {
    margin: 10px 0;
}
.qa-insp-field-label {
    display: block;
    font-size: 12px;
    color: var(--text-secondary, #6b7280);
    margin-bottom: 6px;
}
.qa-insp-day-row {
    display: flex;
    gap: 4px;
}
/* Fallback buttons only: the row is the setup weekday picker (.day-pill)
   since 2026-09-29. */
.qa-insp-day-toggle:not(.day-pill) {
    appearance: none;
    background: var(--surface-secondary, #f3f4f6);
    border: 1px solid var(--border-subtle, #e5e7eb);
    color: var(--text-primary, #111827);
    border-radius: 6px;
    padding: 6px 0;
    font-size: 11px;
    font-weight: 500;
    cursor: pointer;
    flex: 1;
    transition: all 0.15s;
}
.qa-insp-day-toggle:not(.day-pill).off {
    background: transparent;
    color: var(--text-tertiary, #9ca3af);
    text-decoration: line-through;
    border-style: dashed;
}
.qa-insp-day-toggle:not(.day-pill):not(.off):hover {
    border-color: var(--accent-primary, #3b82f6);
}
body.dark-mode .qa-insp-day-toggle:not(.day-pill) {
    background: rgba(255, 255, 255, 0.04);
    border-color: rgba(255, 255, 255, 0.08);
    color: var(--text-primary, #f3f4f6);
}
body.dark-mode .qa-insp-day-toggle:not(.day-pill).off {
    background: transparent;
    color: var(--text-tertiary, #6b7280);
}

.qa-insp-checkbox {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    color: var(--text-primary, #111827);
    margin: 10px 0;
    cursor: pointer;
}
body.dark-mode .qa-insp-checkbox { color: var(--text-primary, #f3f4f6); }
.qa-insp-stepper-field {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}
.qa-insp-stepper-field input {
    width: 60px;
    padding: 4px 6px;
    border: 1px solid var(--border-subtle, #d1d5db);
    border-radius: 4px;
    font-size: 13px;
    text-align: right;
    background: var(--surface-primary, #ffffff);
    color: var(--text-primary, #111827);
}
body.dark-mode .qa-insp-stepper-field input {
    background: var(--surface-secondary, #1f2937);
    border-color: rgba(255, 255, 255, 0.1);
    color: var(--text-primary, #f3f4f6);
}

/* Leave bars */
.qa-insp-leave-row {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 6px 0;
    font-size: 12px;
}
.qa-insp-leave-label {
    width: 70px;
    color: var(--text-secondary, #6b7280);
}
.qa-insp-leave-bar {
    flex: 1 1 auto;
    height: 6px;
    background: var(--surface-tertiary, #e5e7eb);
    border-radius: 3px;
    overflow: hidden;
}
.qa-insp-leave-fill {
    height: 100%;
    width: var(--qa-leave-pct, 0%);
    background: var(--accent-success, #14b8a6);
    transition: width 0.2s ease;
}
body.dark-mode .qa-insp-leave-bar { background: rgba(255, 255, 255, 0.08); }
.qa-insp-leave-meta {
    color: var(--text-tertiary, #9ca3af);
    flex-shrink: 0;
    min-width: 60px;
    text-align: right;
}
.qa-insp-leave-hint {
    font-size: 11px;
    color: var(--text-tertiary, #9ca3af);
    margin-top: 8px;
    font-style: italic;
}

/* Phase 4 — pending-proposals pill in the section header */
.qa-insp-pending-pill {
    padding: 2px 8px;
    border-radius: 999px;
    background: rgba(245, 158, 11, 0.15);
    color: #b45309;
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
body.dark-mode .qa-insp-pending-pill {
    background: rgba(245, 158, 11, 0.22);
    color: #fbbf24;
}

/* Phase 4 — date picker + propose button row */
.qa-insp-propose-row {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 12px;
}
.qa-insp-propose-date {
    flex: 1 1 auto;
    padding: 5px 8px;
    border: 1px solid var(--border-subtle, #d1d5db);
    border-radius: 6px;
    font-size: 12px;
    background: var(--surface-primary, #ffffff);
    color: var(--text-primary, #111827);
}
body.dark-mode .qa-insp-propose-date {
    background: var(--surface-secondary, #1f2937);
    border-color: rgba(255, 255, 255, 0.1);
    color: var(--text-primary, #f3f4f6);
}
.qa-insp-leave-banner {
    padding: 10px 12px;
    background: rgba(245, 158, 11, 0.1);
    border: 1px solid rgba(245, 158, 11, 0.25);
    border-radius: 8px;
    font-size: 13px;
    color: #b45309;
    margin-bottom: 12px;
}
body.dark-mode .qa-insp-leave-banner {
    background: rgba(245, 158, 11, 0.15);
    color: #fbbf24;
}

/* Cell-inspector reasons + alternates */
.qa-insp-reason-list {
    list-style: none;
    padding: 0;
    margin: 0;
}
.qa-insp-reason-list li {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 6px 0;
    font-size: 13px;
    color: var(--text-primary, #111827);
    line-height: 1.4;
}
body.dark-mode .qa-insp-reason-list li { color: var(--text-primary, #f3f4f6); }
.qa-insp-reason-list li i {
    color: var(--text-tertiary, #9ca3af);
    margin-top: 3px;
    flex-shrink: 0;
    width: 14px;
    text-align: center;
}
.qa-insp-reason-list li:first-child i {
    color: var(--accent-success, #14b8a6);
}

.qa-insp-alt-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 0;
    border-bottom: 1px solid var(--border-subtle, #f3f4f6);
}
.qa-insp-alt-row:last-child { border-bottom: none; }
body.dark-mode .qa-insp-alt-row { border-color: rgba(255, 255, 255, 0.04); }
.qa-insp-alt-row .member-avatar {
    width: 28px;
    height: 28px;
    font-size: 11px;
    flex-shrink: 0;
}
.qa-insp-alt-meta {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    min-width: 0;
}
.qa-insp-alt-name {
    font-size: 13px;
    color: var(--text-primary, #111827);
}
body.dark-mode .qa-insp-alt-name { color: var(--text-primary, #f3f4f6); }
.qa-insp-alt-sub {
    font-size: 11px;
    color: var(--text-secondary, #6b7280);
}

.qa-insp-danger {
    padding-top: 16px;
}

/* Day inspector — eligibility rows */
.qa-insp-eligibility-row {
    padding: 10px;
    border-radius: 8px;
    border-left: 3px solid var(--qa-type-color, #94a3b8);
    background: var(--surface-secondary, #f9fafb);
    margin-bottom: 8px;
}
.qa-insp-eligibility-row.eligible {
    background: rgba(20, 184, 166, 0.06);
    border-left-color: var(--accent-success, #14b8a6);
}
body.dark-mode .qa-insp-eligibility-row {
    background: rgba(255, 255, 255, 0.04);
}
body.dark-mode .qa-insp-eligibility-row.eligible {
    background: rgba(20, 184, 166, 0.12);
}
.qa-insp-elig-head {
    display: flex;
    align-items: center;
    gap: 8px;
}
.qa-insp-elig-name {
    flex: 1 1 auto;
    font-size: 13px;
    font-weight: 500;
    color: var(--text-primary, #111827);
}
body.dark-mode .qa-insp-elig-name { color: var(--text-primary, #f3f4f6); }
.qa-insp-elig-verdict {
    font-size: 11px;
    color: var(--text-secondary, #6b7280);
    display: inline-flex;
    align-items: center;
    gap: 4px;
}
.qa-insp-eligibility-row.eligible .qa-insp-elig-verdict {
    color: var(--accent-success, #14b8a6);
}
.qa-insp-elig-reasons {
    list-style: none;
    padding: 0;
    margin: 8px 0 0;
}
.qa-insp-elig-reasons li {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 3px 0;
    font-size: 12px;
    color: var(--text-secondary, #6b7280);
}
.qa-insp-elig-reasons li i {
    width: 12px;
    color: var(--text-tertiary, #9ca3af);
}

/* ── Manual placement: per-row assign action + label field ────────────
   Turns each eligibility row into an actionable "Assign" control so an
   admin can hand-place a shift on an empty cell (wired to manualAssign in
   quota-assignment-modal.js). */
.qa-insp-elig-meta {
    margin-top: 4px;
    font-size: 11px;
    color: var(--text-tertiary, #9ca3af);
}
.qa-insp-elig-actions {
    margin-top: 8px;
    display: flex;
    justify-content: flex-end;
}
.qa-insp-assign-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.qa-insp-assign-btn i { font-size: 11px; }
/* Blocked-row assign uses the secondary look already, but tint the warning
   glyph so "Assign anyway" reads as an override, not a happy path. */
.qa-insp-eligibility-row:not(.eligible) .qa-insp-assign-btn i {
    color: var(--status-flex, #d97706);
}
.qa-day-assign-label {
    width: 100%;
    margin-top: 2px;
}
.qa-insp-hint {
    margin: 6px 0 0;
    font-size: 11px;
    color: var(--text-tertiary, #9ca3af);
}
/* Text-only deeplink button used in the empty-state ("Add one"). */
.qa-btn-link {
    background: none;
    border: none;
    padding: 0;
    color: var(--accent-primary, #3b82f6);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
    text-decoration: underline;
}
.qa-btn-link:hover { opacity: 0.85; }

/* Manual (hand-placed) assignment markers. A corner dot on the grid card +
   a "Manual" pill and label line in the cell inspector so a hand-placed
   shift always reads as intentional, not auto-generated. */
.qa-grid-cell-manual {
    position: relative;
}
.qa-grid-cell-manual::after {
    content: "";
    position: absolute;
    top: 3px;
    right: 3px;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.25);
}
.qa-insp-manual-pill {
    margin-left: 6px;
    padding: 1px 6px;
    border-radius: 6px;
    background: var(--surface-tertiary, #e5e7eb);
    color: var(--text-secondary, #6b7280);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    display: inline-flex;
    align-items: center;
    gap: 3px;
}
.qa-insp-manual-pill i { font-size: 9px; }
body.dark-mode .qa-insp-manual-pill {
    background: rgba(255, 255, 255, 0.1);
    color: var(--text-secondary, #9ca3af);
}
.qa-insp-cell-label {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-primary, #111827);
}
body.dark-mode .qa-insp-cell-label { color: var(--text-primary, #f3f4f6); }

/* Read-only — inspector chrome still renders, but writes are disabled
   via the `disabled` attribute on inputs and section-level write actions
   are hidden. */
.quota-assignment-modal.qa-readonly .qa-insp-danger,
.quota-assignment-modal.qa-readonly .qa-insp-swap-btn {
    display: none;
}

/* Push the grid left when an inspector is open so cells aren't hidden.
   We keep it simple: the modal-content gets right padding when an
   inspector is present (selected via :has). Fallback for browsers that
   don't support :has — the modal scrolls horizontally if needed. */
.qa-workbench:has(~ .qa-inspector),
.quota-assignment-modal-content:has(.qa-inspector) .qa-workbench {
    padding-right: 380px;
}
@media (max-width: 640px) {
    .qa-inspector { width: 100%; }
    .quota-assignment-modal-content:has(.qa-inspector) .qa-workbench {
        padding-right: 4px;
    }
}

/* ============================================
   NEXT-STEP CARD (2026-08-23)
   ============================================
   Shown at the top of Team Hours after a successful "Save Hours". The owner
   reported the flow as incomplete — "8 Quotas saved? Shouldn't there be a
   preview and edit step" — and the cause was navigational, not missing
   features: the preview and edit stages exist on Distribute, but Team Hours
   was the only tab in the modal with no onward deeplink, so the flow appeared
   to terminate on a toast that then vanished.
   Styled as a calm informational card, NOT a success banner: the save already
   reported itself on the button and in the toast, and a second celebratory
   green block would double-count one action. */
.qa-next-step-card {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 12px 14px;
    margin: 0 0 14px;
    border: 1px solid var(--primary-200, #99f6e4);
    border-left: 3px solid var(--primary-500, #14b8a6);
    border-radius: var(--radius-md, 10px);
    background: var(--primary-50, #f0fdfa);
}
.qa-next-step-text {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 0.8125rem;
    line-height: 1.5;
    color: var(--text-primary, #111827);
}
.qa-next-step-card .qa-btn {
    flex: 0 0 auto;
    white-space: nowrap;
}
/* Narrow modal: stack so the CTA keeps its full tap target instead of being
   squeezed against the text. */
@media (max-width: 640px) {
    .qa-next-step-card {
        flex-direction: column;
        align-items: stretch;
        gap: 10px;
    }
}
body.dark-mode .qa-next-step-card {
    border-color: var(--primary-800, #115e59);
    border-left-color: var(--primary-500, #14b8a6);
    background: #112834;
    background: color-mix(in srgb, var(--primary-500, #14b8a6) 10%, var(--surface-secondary, #111827));
}
body.dark-mode .qa-next-step-text {
    color: var(--text-primary, #f1f5f9);
}

/* ============================================
   CRON DRAFT REVIEW (review-before-publish)
   ============================================ */
/* Banner above the tab strip: prominent but calm. A cron draft is expected
   behaviour, not a fault, so it uses the primary (teal) family rather than
   the amber caution token — amber stays reserved for "something is off". */
.qa-draft-banner {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0 0 12px;
    padding: 10px 14px;
    border-radius: var(--radius-md, 8px);
    font-size: 0.8125rem;
    line-height: 1.4;
    color: var(--text-primary, #1e293b);
    background: rgba(20, 184, 166, 0.1);
    background: color-mix(in srgb, var(--primary-500, #14b8a6) 10%, transparent);
    border: 1px solid rgba(20, 184, 166, 0.3);
    border: 1px solid color-mix(in srgb, var(--primary-500, #14b8a6) 30%, transparent);
}
.qa-draft-banner > i {
    color: var(--primary-600, #0d9488);
    flex: 0 0 auto;
}
.qa-draft-banner-text {
    flex: 1 1 auto;
    min-width: 0;
}
.qa-draft-banner .qa-draft-banner-review {
    flex: 0 0 auto;
    white-space: nowrap;
}
body.dark-mode .qa-draft-banner {
    color: var(--text-primary, #e2e8f0);
    background: rgba(20, 184, 166, 0.14);
    background: color-mix(in srgb, var(--primary-500, #14b8a6) 14%, transparent);
    border-color: rgba(20, 184, 166, 0.4);
    border-color: color-mix(in srgb, var(--primary-500, #14b8a6) 40%, transparent);
}

/* Review pane */
.qa-draft-review-meta {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin: 0 0 14px;
    padding: 10px 14px;
    border-radius: var(--radius-md, 8px);
    background: var(--surface-secondary, #f9fafb);
    border: 1px solid var(--border-color, #e5e7eb);
    font-size: 0.8125rem;
    line-height: 1.5;
    color: var(--text-primary, #1f2937);
}
.qa-draft-review-source i {
    color: var(--primary-600, #0d9488);
    margin-right: 6px;
}
.qa-draft-review-when {
    color: var(--text-secondary, #4b5563);
}
body.dark-mode .qa-draft-review-meta {
    background: var(--surface-secondary, #111827);
    border-color: var(--border-color, #374151);
    color: var(--text-primary, #e5e7eb);
}
body.dark-mode .qa-draft-review-when {
    color: var(--text-secondary, #9ca3af);
}

/* Inline notice: the pane's only status channel (owner ruling: no toasts). */
.qa-draft-review-notice {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 8px;
    margin: 0 0 14px;
    padding: 10px 14px;
    border-radius: var(--radius-md, 8px);
    font-size: 0.8125rem;
    line-height: 1.5;
    background: rgba(20, 184, 166, 0.1);
    background: color-mix(in srgb, var(--primary-500, #14b8a6) 10%, transparent);
    border: 1px solid rgba(20, 184, 166, 0.3);
    border: 1px solid color-mix(in srgb, var(--primary-500, #14b8a6) 30%, transparent);
    color: var(--text-primary, #1f2937);
}
.qa-draft-review-notice-error {
    background: rgba(220, 38, 38, 0.08);
    background: color-mix(in srgb, var(--status-busy, #dc2626) 8%, transparent);
    border-color: rgba(220, 38, 38, 0.3);
    border-color: color-mix(in srgb, var(--status-busy, #dc2626) 30%, transparent);
}
.qa-draft-review-notice-error > i {
    color: var(--status-busy, #dc2626);
}
.qa-draft-review-notice-codes {
    flex-basis: 100%;
    font-size: 0.8125rem;
    color: var(--text-secondary, #4b5563);
}
body.dark-mode .qa-draft-review-notice {
    color: var(--text-primary, #e5e7eb);
}
body.dark-mode .qa-draft-review-notice-codes {
    color: var(--text-secondary, #9ca3af);
}

/* Workbench ack gate sits directly above the workbench action bar. */
.qa-workbench-ack-gate {
    margin: 12px 0 0;
}

/* Recurring form: "Publish drafts" fieldset */
.qa-re-publish-line {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    font-size: 0.8125rem;
    color: var(--text-primary, #1f2937);
}
.qa-re-publish-line .qa-re-commitlead {
    width: 64px;
}
.qa-re-publish-note {
    margin: 6px 0 0;
    font-size: 0.8125rem;
    line-height: 1.5;
    color: var(--text-secondary, #4b5563);
}
.qa-re-autoack-row {
    align-items: flex-start;
    line-height: 1.45;
}
.qa-re-autoack-row input[type="checkbox"] {
    margin-top: 2px;
    flex: 0 0 auto;
}
body.dark-mode .qa-re-publish-line {
    color: var(--text-primary, #e5e7eb);
}
body.dark-mode .qa-re-publish-note {
    color: var(--text-secondary, #9ca3af);
}

/* Per-row draft editing. The pencil is a sibling of .qa-why-btn and inherits
   its shape deliberately: the two controls sit next to each other on the same
   row and reading as one pair of small round affordances is the point. Only
   .qa-why-btn carries `margin-left: auto` (it is the first of the pair), so
   the pencil must NOT repeat it or the two would each claim the free space
   and split apart. */
.qa-draft-row-edit {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    border: none;
    background: var(--surface-tertiary, #f3f4f6);
    color: var(--text-tertiary, #9ca3af);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.6875rem;
    transition: all 0.15s;
    flex-shrink: 0;
}
/* When the row has no recorded reason there is no .qa-why-btn to push us
   right, so the pencil takes over the spacer duty. */
.qa-preview-shift-row > .qa-draft-row-edit:first-of-type {
    margin-left: auto;
}
.qa-draft-row-edit:hover {
    background: var(--primary-100, #ccfbf1);
    color: var(--primary-600, #0d9488);
}
body.dark-mode .qa-draft-row-edit {
    background: var(--surface-secondary, #374151);
    color: var(--text-tertiary, #9ca3af);
}
body.dark-mode .qa-draft-row-edit:hover {
    background: var(--primary-900, #134e4a);
    color: var(--primary-300, #5eead4);
}

/* An alternate whose local time for this shift falls in the sleep band. The
   moon glyph is the signal; this only tints the sub-line so the name stays
   legible. Amber, not red: choosing them is allowed, it just needs an
   acknowledgement. */
.qa-insp-alt-sleep .qa-insp-alt-sub {
    color: var(--status-tentative, #d97706);
}
body.dark-mode .qa-insp-alt-sleep .qa-insp-alt-sub {
    color: var(--status-tentative, #fbbf24);
}

/* Touch targets. Placed at the END of the sheet on purpose: a coarse-pointer
   block earlier in this file (and late blocks in style.css) win on source
   order, so these must come last to be authoritative for these controls. */
@media (max-width: 640px), (pointer: coarse) {
    .qa-draft-banner .qa-draft-banner-review,
    .qa-draft-review-actions .qa-btn,
    #qa-draft-back {
        min-height: 44px;
    }
    .qa-ack-row {
        min-height: 44px;
        align-items: center;
    }
    .qa-ack-row input[type="checkbox"],
    .qa-re-autoack-row input[type="checkbox"] {
        width: var(--checkbox-size, 18px);
        height: var(--checkbox-size, 18px);
    }
    /* The pencil and the swap/drop buttons are the whole per-row edit flow on
       touch, so they get real targets. The 22px visual circle is preserved by
       growing the BOX, not the glyph. */
    .qa-draft-row-edit {
        min-width: 44px;
        min-height: 44px;
        background: transparent;
    }
    body.dark-mode .qa-draft-row-edit {
        background: transparent;
    }
    .qa-insp-alt-row .qa-draft-swap-btn,
    #qa-draft-row-drop {
        min-height: 44px;
    }
}

/* Flexible-timing row in the coverage-type editor (2026-09-01) */
.qa-flexible-row {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 2px 0 10px;
  font-size: 0.8125rem;
  color: var(--text-secondary, #475569);
  cursor: pointer;
}
.qa-flexible-row input[type="checkbox"] {
  margin-top: 2px;
  accent-color: var(--primary-500, #14b8a6);
}
.dark-mode .qa-flexible-row { color: var(--text-secondary, #94a3b8); }

/* Sync-status chip (2026-09-01, stage A): one persistent header signal
   instead of a toast per push outcome. */
.qa-sync-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 26px;
  padding: 0 10px;
  border-radius: var(--radius-full, 999px);
  border: 1px solid transparent;
  font-size: 0.75rem;
  font-weight: 600;
  flex: 0 0 auto;
  background: var(--slate-100, #f1f5f9);
  color: var(--text-secondary, #475569);
  cursor: default;
}
.qa-sync-chip-ok { color: var(--success-600, #16a34a); background: rgba(34, 197, 94, 0.1); }
.qa-sync-chip-busy { color: var(--primary-600, #0d9488); background: rgba(20, 184, 166, 0.1); }
.qa-sync-chip-failed {
  color: #b45309;
  background: rgba(245, 158, 11, 0.14);
  border-color: rgba(245, 158, 11, 0.4);
  cursor: pointer;
}
.qa-sync-chip-failed:hover { background: rgba(245, 158, 11, 0.24); }
.dark-mode .qa-sync-chip { background: rgba(148, 163, 184, 0.12); color: var(--text-secondary, #94a3b8); }
.dark-mode .qa-sync-chip-ok { color: #4ade80; background: rgba(34, 197, 94, 0.12); }
.dark-mode .qa-sync-chip-failed { color: #fbbf24; background: rgba(245, 158, 11, 0.14); }

/* Acceptance tracker (2026-09-01, stage A) */
.qa-acceptance-rollup {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  padding: 8px 12px;
  margin-bottom: 10px;
  border-radius: var(--radius-md, 10px);
  background: var(--slate-50, #f8fafc);
  border: 1px solid var(--slate-200, #e2e8f0);
  font-size: 0.8125rem;
  font-weight: 600;
}
.qa-acceptance-rollup .qa-accept-ok { color: var(--success-600, #16a34a); }
/* 'scheduled' is the settled default under approved-unless-contested
   (2026-09-07): brand teal, not the amber that used to say "waiting". */
.qa-acceptance-rollup .qa-accept-wait { color: var(--primary-700, #0f766e); }
/* Rows the server never acknowledged (2026-09-14): on this device only. */
.qa-acceptance-rollup .qa-accept-local { color: var(--warning-color, #b45309); }
.qa-acceptance-rollup .qa-accept-cover { color: var(--danger-600, #dc2626); }
.qa-acceptance-rollup .qa-accept-sep { color: var(--slate-300, #cbd5e1); margin: 0 2px; }
.qa-acceptance-rollup i { margin-right: 4px; }
.dark-mode .qa-acceptance-rollup { background: rgba(148, 163, 184, 0.08); border-color: rgba(148, 163, 184, 0.2); }

/* Scheduled (published, not yet explicitly confirmed by the member) cell:
   under approved-unless-contested (2026-09-07) this IS a settled shift, so it
   paints exactly like a confirmed one. The class stays for the inspector and
   tests; only "needs cover" and drafts look different. */
.qa-grid-cell.qa-grid-cell-awaiting {
  opacity: 1;
  box-shadow: none;
}
.qa-insp-acceptance-note { font-size: 0.8125rem; color: var(--text-secondary, #475569); margin: 0 0 8px; }
.qa-insp-acceptance-note.qa-insp-accepted { color: var(--success-600, #16a34a); margin-bottom: 0; }

/* Pre-flight feasibility + frame note (2026-09-01, stage B) */
.qa-feasibility {
  margin-bottom: 14px;
  padding: 10px 14px;
  border-radius: var(--radius-md, 10px);
  background: rgba(245, 158, 11, 0.08);
  border: 1px solid rgba(245, 158, 11, 0.35);
  font-size: 0.8125rem;
  color: var(--text-secondary, #475569);
}
/* NOT AN ERROR (2026-09-07). A fixed clock-time window that suits nobody
   across several timezones is the NORMAL state of a distributed team - it
   is the problem this product exists to solve, not a mistake the admin has
   made. It painted RED (danger), which reads as "you broke something" and
   pushes people to go and change working hours that are perfectly correct.
   The copy now leads with the fix, and the colour follows the copy: an
   informational slate note, no alarm. The amber base is kept for the
   partial case ("suits some, not all"), which IS a real trade-off worth a
   caution. */
.qa-feasibility-blocked {
  background: var(--slate-50, #f8fafc);
  border-color: var(--slate-300, #cbd5e1);
}
.qa-feasibility-title { font-weight: 700; color: #b45309; margin-bottom: 4px; }
.qa-feasibility-blocked .qa-feasibility-title { color: var(--slate-700, #334155); }
body.dark-mode .qa-feasibility-blocked {
  background: rgba(148, 163, 184, 0.08);
  border-color: rgba(148, 163, 184, 0.28);
}
body.dark-mode .qa-feasibility-blocked .qa-feasibility-title { color: var(--slate-200, #e2e8f0); }
.qa-feasibility-title i { margin-right: 6px; }
.qa-feasibility-list { margin: 0 0 6px; padding-left: 18px; }
.qa-feasibility-list li { margin: 2px 0; }
.qa-feasibility-hint { font-size: 0.75rem; opacity: 0.9; }
.dark-mode .qa-feasibility { color: var(--text-secondary, #94a3b8); }
.qa-preview-frame-note {
  font-size: 0.75rem;
  color: var(--text-tertiary, #64748b);
  margin: 2px 0 8px;
}
.qa-preview-frame-note i { margin-right: 5px; }

/* Step numbers ON the stage tabs (2026-09-24). The separate checklist strip
   repeated the tab row's four names on a second row; the tab now carries its
   own number, or a check once that stage is done, in place of its icon. */
#quota-assignment-modal .qa-tab-stepped > i { display: none; }
.qa-tab-step {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--slate-200, #e2e8f0);
  color: var(--text-secondary, #475569);
  font-size: 0.6875rem;
  font-weight: 700;
}
.qa-tab-step i { font-size: 0.625rem; opacity: 1; }
.qa-tab.active .qa-tab-step { background: var(--primary-500, #14b8a6); color: #fff; }
.qa-tab-done .qa-tab-step { background: rgba(20, 184, 166, 0.15); color: var(--primary-600, #0d9488); }
.qa-tab-done.active .qa-tab-step { background: var(--primary-500, #14b8a6); color: #fff; }
.dark-mode .qa-tab-step { background: rgba(148, 163, 184, 0.18); color: var(--text-secondary, #94a3b8); }
.dark-mode .qa-tab.active .qa-tab-step { background: var(--primary-500, #14b8a6); color: #0f172a; }
.dark-mode .qa-tab-done .qa-tab-step { background: rgba(20, 184, 166, 0.2); color: var(--primary-400, #2dd4bf); }

/* Preview shortfall headline (stage D) */
.qa-preview-headline {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 10px 14px;
  margin-bottom: 10px;
  border-radius: var(--radius-md, 10px);
  background: rgba(245, 158, 11, 0.1);
  border: 1px solid rgba(245, 158, 11, 0.4);
  color: #92400e;
  font-size: 0.875rem;
  font-weight: 600;
}
.qa-preview-headline-empty { background: rgba(220, 38, 38, 0.07); border-color: rgba(220, 38, 38, 0.35); color: var(--danger-600, #dc2626); }
.qa-preview-headline i { margin-top: 2px; }
.dark-mode .qa-preview-headline { color: #fbbf24; }

/* Draft edit controls on preview rows (stage C) */
.qa-preview-reassign {
  max-width: 110px;
  font-size: 0.6875rem;
  padding: 2px 4px;
  border-radius: 6px;
  border: 1px solid var(--slate-200, #e2e8f0);
  background: var(--surface, #fff);
  color: inherit;
}
.qa-preview-drop-btn {
  border: none;
  background: none;
  color: var(--text-tertiary, #94a3b8);
  cursor: pointer;
  padding: 2px 6px;
  border-radius: 6px;
}
.qa-preview-drop-btn:hover { color: var(--danger-600, #dc2626); background: rgba(220, 38, 38, 0.08); }
.dark-mode .qa-preview-reassign { background: rgba(15, 23, 42, 0.4); border-color: rgba(148, 163, 184, 0.25); }

/* ============================================
   HEADER ALIGNMENT + DROPDOWN CLAMP (2026-09-01)
   Owner, phone screenshot: "upper area alignment is off" — the title read
   "Quota &" with the rest clipped, and the board dropdown hung past the
   right edge of the modal.
   ROOT 1: .qa-header h2 is `flex: 0 0 auto` (desktop rule) while the mobile
   rule gives it overflow:hidden + ellipsis. Refusing to shrink AND clipping
   itself means the title truncates instead of the row reflowing, on every
   phone width.
   ROOT 2: .qa-board-dropdown is `left: 0` on a trigger that sits at the RIGHT
   of the header, so a min(340px, 90vw) panel starts at the trigger and runs
   off-screen. Anchor it to the trigger's right edge instead.
   ============================================ */
@media (max-width: 640px) {
  /* Let the title shrink before it clips; the ellipsis stays as a backstop
     for genuinely narrow screens rather than being the default outcome. */
  .qa-header h2 {
    flex: 1 1 auto;
    min-width: 0;
  }
  /* The chip row (plan badge, board selector, sync chip) keeps its own line
     when the title needs the width, instead of shouldering it out. */
  .qa-header-left {
    row-gap: 8px;
  }
  .qa-board-selector { margin-left: auto; }
}

/* Right-anchored so the panel opens INSIDE the modal on every width. */
.qa-board-dropdown {
  left: auto;
  right: 0;
  max-width: calc(100vw - 32px);
}

/* Dismissible read-only note (2026-09-01, owner: "should be able to cancel x
   that text for a fuller view"). The note explains a state; it is not a gate,
   so it can be closed to reclaim the panel on a phone. */
.qa-readonly-note { position: relative; padding-right: 34px; }
.qa-readonly-dismiss {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 26px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: none;
  border-radius: 50%;
  color: var(--text-tertiary, #94a3b8);
  cursor: pointer;
  font-size: 0.875rem;
}
.qa-readonly-dismiss:hover { background: rgba(148, 163, 184, 0.18); color: var(--text-secondary, #475569); }

/* ══════════════════════════════════════════════════════════════════════
   HEADER ANATOMY (2026-09-07) — one chrome with Fairness / Insights
   (css/panel-chrome.css): brand tile + title + subtitle, the plan / Beta
   pills as micro-chips beside the title, group selector + sync chip in a
   tools cluster, the house close control. Grid so the phone can drop the
   tools onto their own row without the title wrapping around them.
   ══════════════════════════════════════════════════════════════════════ */
#quota-assignment-modal .qa-header {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  grid-template-areas: "brand tools close";
  align-items: center;
  gap: 12px;
  padding: 12px 20px 10px;
  border-bottom: 1px solid var(--border-color, #e2e8f0);
  background: var(--surface-primary, #fff);
}
#quota-assignment-modal .qa-header-left {
  grid-area: brand;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: nowrap;
  min-width: 0;
}
#quota-assignment-modal .qa-brand-icon {
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm, 8px);
  background: rgba(20, 184, 166, 0.12);
  background: color-mix(in srgb, var(--primary-500, #14b8a6) 12%, transparent);
  color: var(--primary-600, #0d9488);
  font-size: 14px;
}
#quota-assignment-modal .qa-brand-text {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
#quota-assignment-modal .qa-header h2 {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.2;
  color: var(--text-primary, #1e293b);
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}
#quota-assignment-modal .qa-header h2 > i { display: none; } /* the tile carries the icon */
#quota-assignment-modal .qa-title-sub {
  display: block;
  font-size: 11px;
  font-weight: 500;
  color: var(--text-secondary, #64748b);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Plan pill: a label, not a verdict — tinted teal outline, sentence case. */
#quota-assignment-modal .qa-header .qa-badge {
  height: 20px;
  padding: 0 8px;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--primary-700, #0f766e);
  background: rgba(20, 184, 166, 0.12);
  background: color-mix(in srgb, var(--primary-500, #14b8a6) 12%, transparent);
  border: 1px solid rgba(20, 184, 166, 0.3);
  border: 1px solid color-mix(in srgb, var(--primary-500, #14b8a6) 30%, transparent);
  box-shadow: none;
}
#quota-assignment-modal .qa-header .beta-badge {
  height: 20px;
  display: inline-flex;
  align-items: center;
  padding: 0 8px;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0;
  line-height: 1;
  border-radius: var(--radius-full, 999px);
}
#quota-assignment-modal .qa-header-tools {
  grid-area: tools;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
  min-width: 0;
}
#quota-assignment-modal .qa-header-tools:empty { display: none; }
#quota-assignment-modal .qa-header .modal-header-actions {
  grid-area: close;
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
#quota-assignment-modal .qa-header-tools .qa-board-selector-btn {
  height: 34px;
  border-radius: var(--radius-sm, 8px);
}
/* Sync banner: a state strip between header and tabs, not a bar above the title. */
#quota-assignment-modal .qa-sync-banner {
  margin: 0;
  padding: 6px 20px;
  border-radius: 0;
  border-left: 0;
  border-right: 0;
  border-top: 0;
  font-size: 0.8125rem;
}
/* ══════════════════════════════════════════════════════════════════════
   PHONE DENSITY (2026-09-07) — owner, from a 390px screenshot: "wasted
   space ... theres lots of wasted space including the group picker and
   space between tabs. check all areas and redesign as necessary to be
   space efficient and allow maximum viewable area of the relevant info".

   MEASURED BEFORE, at 390x844 with the panel open on Schedule:
     header       53 -> 135   82px   (title wrapped, Beta on its own line)
     tools row   135 -> 179   44px   (a whole band for ONE group picker)
     sync banner 188 -> 256   68px   (three lines of prose)
     tabs        256 -> 300   44px
     checklist   300 -> 403  103px   (4 steps wrapped onto two lines)
     CONTENT     403 -> 844  441px   = 52% of the screen

   The chrome all still SAYS the same things. What changes is that no band
   is spent on a single control and nothing wraps to buy a second line:
   the group picker rides the header row it used to sit under, the sync
   note is one truncating line (full text in its title/aria), and the
   step checklist scrolls sideways instead of wrapping.
   ══════════════════════════════════════════════════════════════════════ */
@media (max-width: 640px) {
  /* ONE header row: brand | tools | close. The tools cluster no longer
     gets a band of its own - the group picker is the only thing in it,
     and a 44px strip holding one right-drifting button was the single
     biggest avoidable loss on the phone. */
  #quota-assignment-modal .qa-header {
    grid-template-columns: minmax(0, 1fr) auto auto;
    grid-template-areas: "brand tools close";
    column-gap: 8px;
    row-gap: 0;
    padding: 8px 12px;
  }

  /* The brand tile is decoration; at 390px it competes with the title for
     the row. Keep it (it carries the panel's identity in the shared
     chrome) but at a size that does not push the title into a wrap. */
  #quota-assignment-modal .qa-brand-icon {
    width: 26px;
    height: 26px;
    font-size: 12px;
  }

  /* Title and plan pill share one line and never wrap. The h2 is a flex
     row; letting it wrap is what put "Business plan" and "Beta" on
     separate lines above the subtitle. */
  #quota-assignment-modal .qa-header h2 {
    flex-wrap: nowrap;
    gap: 6px;
    font-size: 14px;
    min-width: 0;
  }
  #quota-assignment-modal .qa-header h2 .qa-title-text {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  /* THE PLAN PILL IS NOT WORTH THE TITLE. Measured at 390px: the h2 had
     151px, "Quota & Assignment" needs 133px, and "Business plan" was taking
     81px of it - so the panel's own name ellipsed to "Quot..." to show a
     tier label that the read-only banner underneath states in a full
     sentence anyway ("Coverage planning is a Business feature"). The pill
     stays (it is guarded, and it is the at-a-glance tier marker) but it
     gives up its second word, and the title takes the space back. */
  /* THE PLAN PILL IS NOT WORTH THE TITLE. Measured at 390px: the h2 had
     151px, "Quota & Assignment" needs 133px, and "Business plan" was taking
     81px of it - so the panel's own name ellipsed to "Quot..." to show a
     tier label that the read-only banner underneath states in a full
     sentence anyway ("Coverage planning is a Business feature"). The pill
     stays (it is guarded, and it is the at-a-glance tier marker) but on a
     phone it shows the TIER only. The word "plan" is carried by a ::after
     that the phone drops, so the DOM text stays "Business plan" for the
     guard, the desktop and the accessible name. */
  #quota-assignment-modal .qa-header .qa-badge {
    flex: 0 0 auto;
    height: 18px;
    padding: 0 6px;
    font-size: 0.625rem;
    white-space: nowrap;
    /* Hide the DOM text and paint the short word instead - clipping the real
       text would cut it mid-word ("Busines...") which reads as a defect. */
    font-size: 0;
  }
  #quota-assignment-modal .qa-header .qa-badge::before {
    content: 'Business';
    font-size: 0.625rem;
  }
  #quota-assignment-modal .qa-header h2 .qa-title-text { flex: 1 1 auto; }

  /* The subtitle repeats what the Schedule tab then shows in full. On a
     phone it is the first line to give up: hidden, not deleted, so the
     desktop chrome and any screen-reader path keep it. */
  #quota-assignment-modal .qa-title-sub { display: none; }

  /* THE TITLE OUTRANKS THE PICKER. First attempt let the tools cluster take
     its natural width, and at 390px "Quota & Assignment" ellipsed to
     "Quot..." — the panel's own name, unreadable, to make room for a group
     name that is also shown on the board behind it. The brand column keeps
     its intrinsic width and the picker is the element that gives way. */
  #quota-assignment-modal .qa-header-left { flex-shrink: 0; }
  #quota-assignment-modal .qa-header-tools {
    justify-content: flex-end;
    flex-wrap: nowrap;
    min-width: 0;
    /* NOT overflow:hidden (2026-09-24, owner: "the folder at the top shows
       no groups"). The group dropdown is positioned inside this cluster, so
       clipping the cluster clipped every option: the picker opened to
       nothing, and a phone could not change group at all. */
  }
  /* THE PICKER DROPS TO ITS ICON. The row simply does not hold everything at
     390px: 26 (tile) + 133 (the title's intrinsic width) + 62 (plan pill)
     + 112 (picker) + 44 (close) + gaps = ~391 into 382. The picker is what
     gives, because the group it names is ALSO named on the board behind
     this panel and again at the top of its own dropdown - so the name here
     is the only genuinely redundant word in the row. Icon + chevron keep it
     reading as a control; aria-label carries the group for a screen reader. */
  #quota-assignment-modal .qa-header-tools .qa-board-selector-btn {
    height: 30px;
    min-width: 0;
    padding: 0 6px;
    gap: 3px;
    font-size: 0.75rem;
    white-space: nowrap;
  }
  #quota-assignment-modal .qa-header-tools .qa-board-selector-btn > span {
    display: none;
  }

  /* The close control was a 44px outlined box - a desktop-weight affordance
     that, beside a 26px brand tile and an 18px pill, read as the loudest
     thing in the header. Plain icon, still a full tap target. */
  #quota-assignment-modal .qa-header .modal-header-actions .icon-button {
    width: 32px;
    height: 32px;
    border: none;
    box-shadow: none;
    background: none;
  }

  /* Sync state: two lines, then a tap for the rest (2026-09-24). One
     truncated line cut every reason off before its instruction ("...admin
     rights on this group to change i..."), and a title tooltip does not
     exist on a phone. */
  #quota-assignment-modal .qa-sync-banner {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    padding: 5px 12px;
    font-size: 0.75rem;
    line-height: 1.3;
    cursor: pointer;
  }
  #quota-assignment-modal .qa-sync-banner > span {
    min-width: 0;
    overflow: hidden;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
  }
  #quota-assignment-modal .qa-sync-banner.qa-sync-banner-open > span {
    display: block;
    -webkit-line-clamp: unset;
    line-clamp: none;
  }
  #quota-assignment-modal .qa-sync-banner i { margin-top: 2px; }
  #quota-assignment-modal .qa-sync-banner > i { flex: 0 0 auto; }

  /* Tabs: the gap between them was set for a mouse. Tighten the padding
     and let the strip scroll rather than reserving height for a wrap. */
  #quota-assignment-modal .qa-tabs {
    padding: 0 4px;
    gap: 0;
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
  }
  #quota-assignment-modal .qa-tabs::-webkit-scrollbar { display: none; }
  #quota-assignment-modal .qa-tab {
    padding: 9px 6px;
    gap: 4px;
    font-size: 0.8125rem;
    white-space: nowrap;
    flex: 0 0 auto;
  }


  /* Content gets the reclaimed height; its own padding was tuned for a
     desktop card, not a 390px column. */
  #quota-assignment-modal .qa-tab-content { padding: 12px; }
}

/* ── TEAM HOURS member rows, on a phone (2026-09-07) ───────────────────
   Measured at 390px: .member-info had 114px for 127px of text, so
   "UTC+2 · Amsterdam, Netherlands" ran under the "40.5 HRS/WK" badge. The
   badge is flex-shrink:0 and the name/timezone already ellipsis, but the
   row simply asked for more than it had. The avatar gives up 8px, the
   padding and gaps tighten, and the location line drops to the offset
   alone when it cannot fit - the city is already on the board behind. */
@media (max-width: 640px) {
  #quota-assignment-modal .qa-member-card-header {
    gap: 8px;
    padding: 10px;
  }
  #quota-assignment-modal .qa-member-card-header .member-selection-item { gap: 8px; }
  #quota-assignment-modal .qa-member-card-header .member-avatar {
    width: 32px;
    height: 32px;
    font-size: 0.8125rem;
  }
  #quota-assignment-modal .qa-member-total-badge {
    padding: 3px 8px;
    font-size: 0.6875rem;
    /* The longest row ("UTC+2 · Amsterdam, Netherlands") still ran right up
       to the badge with no breathing room. The badge cannot shrink (it is a
       number), so it takes the gap on its own leading edge and the info
       column ellipses one character earlier instead of colliding. */
    margin-left: 8px;
  }
  /* Both lines must actually be allowed to ellipsis - the column has to be
     permitted to be narrower than its content for text-overflow to fire. */
  #quota-assignment-modal .qa-member-card-header .member-info { min-width: 0; }
  /* The count sits beside the label, not wedged after a giant tick. */
  #quota-assignment-modal .qa-members-header {
    gap: 8px;
    flex-wrap: wrap;
  }
  #quota-assignment-modal .qa-members-header-left { gap: 10px; min-width: 0; }

  /* ── DISTRIBUTE: the schedule period, on one row ──────────────────────
     The phone rule stacked From, To and the calendar button as three
     full-width rows - about 200px to enter a date range, with the icon
     button orphaned underneath looking like it belonged to nothing. Two
     date fields fit side by side at 390px, and the button belongs on the
     same line as the fields it picks for. This OVERRIDES the generic
     .qa-date-range-row column rule for this panel only, so other users of
     that class keep their stacking. */
  #quota-assignment-modal .qa-date-range-row {
    flex-direction: row;
    /* NOT align-items:flex-end here. quota-date-align-and-business-tier
       forbids it on this selector, and rightly: in the COLUMN layout this
       rule replaces, flex-end is a cross-axis (horizontal) rule that
       right-shoved the whole From/To cluster - the 2026-06-29 defect. The
       bottom-alignment wanted here is only for the calendar button beside
       two labelled inputs, so it is expressed as align-self on that button
       alone (below) and the row keeps the inherited flex-start. */
    align-items: stretch;
    flex-wrap: nowrap;
    gap: 8px;
  }
  #quota-assignment-modal .qa-date-range-row .qa-control-group {
    flex: 1 1 0;
    min-width: 0;
  }
  #quota-assignment-modal .qa-date-range-row .qa-control-group input[type="date"] {
    width: 100%;
    min-width: 0;
    box-sizing: border-box;
  }
  #quota-assignment-modal .qa-calendar-picker-btn {
    flex: 0 0 auto;
    align-self: flex-end;
  }
}

/* At the TIGHTEST width the row still cannot hold the tier pill AND the
   panel's name (measured: title clipped at 320 with every other saving
   already made). The name wins - it is what tells you where you are, and
   the tier is stated in full one band below by the read-only banner
   ("Coverage planning is a Business feature"), so nothing is lost. */
@media (max-width: 359px) {
  #quota-assignment-modal .qa-header .qa-badge { display: none; }
}
body.dark-mode #quota-assignment-modal .qa-header {
  background: var(--surface-primary, #1e293b);
  border-bottom-color: var(--border-color, rgba(148, 163, 184, 0.22));
}
body.dark-mode #quota-assignment-modal .qa-brand-icon {
  background: rgba(45, 212, 191, 0.14);
  color: #5eead4;
}
body.dark-mode #quota-assignment-modal .qa-header .qa-badge {
  color: #5eead4;
  background: rgba(45, 212, 191, 0.14);
  border-color: rgba(94, 234, 212, 0.35);
}

/* ═══════════════════════════════════════════════════════════════════════
   COMMIT CONFIRMATION OVERVIEW (2026-09-14)
   Owner: "Commit this draft looks underdeveloped. Shouldn't it be more like
   proposal confirmation. Or have some kinda attractive overview". The
   commit dialog now carries the same family of confirmation as the
   event/proposal sheet (css/confirm-dialog.css .proposal-preview-card):
   a banner with the headline count and period, coverage-type chips, the
   members and their load, a per-day coverage strip, a warnings band, and
   the honest "who is told" footer. Mobile first; the desktop rule only
   widens the dialog. The overview lives INSIDE ConfirmDialog's message
   element, so the width lift is done with :has() from the content box.
   ═══════════════════════════════════════════════════════════════════════ */
.confirm-dialog-content:has(.qa-commit-overview) {
  max-width: 600px;
  width: calc(100vw - 24px);
  /* The overview is taller than a phone; the box scrolls inside so the
     title stays at the top and Cancel / Commit stay reachable. */
  max-height: calc(100vh - 24px);
  max-height: calc(100dvh - 24px);
  overflow-y: auto;
  overscroll-behavior: contain;
}
/* Inside the scrolling box the title stays at the top and the actions at
   the bottom, so focusing Commit on open does not scroll the overview
   away (measured: the box opened at its bottom on a phone). */
.confirm-dialog-content:has(.qa-commit-overview) .confirm-dialog-header {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--card-bg-primary, #fff);
}
.confirm-dialog-content:has(.qa-commit-overview) .confirm-dialog-actions {
  position: sticky;
  bottom: 0;
  z-index: 2;
  background: var(--card-bg-primary, #fff);
  padding-top: 10px;
  box-shadow: 0 -8px 16px -12px rgba(15, 23, 42, 0.35);
}
body.dark-mode .confirm-dialog-content:has(.qa-commit-overview) .confirm-dialog-header,
body.dark-mode .confirm-dialog-content:has(.qa-commit-overview) .confirm-dialog-actions {
  background: var(--card-bg-primary, #1e293b);
}
#confirm-dialog-message:has(.qa-commit-overview) {
  margin: 0;
  line-height: 1.4;
}
.qa-commit-overview {
  --qa-co-teal: var(--primary-600, #0d9488);
  --qa-co-ink: var(--text-primary, #0f172a);
  --qa-co-muted: var(--text-secondary, #64748b);
  --qa-co-line: var(--border-color, #e2e8f0);
  --qa-co-band: rgba(20, 184, 166, 0.07);
  display: flex;
  flex-direction: column;
  gap: 14px;
  text-align: left;
  color: var(--qa-co-ink);
  font-size: 14px;
}
.qa-co-head {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 16px;
  border-radius: 14px;
  border: 1.5px solid var(--primary-200, #99f6e4);
  background: linear-gradient(180deg, rgba(20, 184, 166, 0.12) 0%, rgba(20, 184, 166, 0.03) 100%);
}
.qa-co-headline {
  display: flex;
  align-items: baseline;
  gap: 8px;
  color: var(--qa-co-ink);
}
.qa-co-count {
  font-size: 34px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--qa-co-teal);
  font-variant-numeric: tabular-nums;
}
.qa-co-count-label {
  font-size: 18px;
  font-weight: 700;
}
.qa-co-period {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  color: var(--qa-co-ink);
}
.qa-co-period i { color: var(--qa-co-teal); }
.qa-co-muted { color: var(--qa-co-muted); font-weight: 500; }
.qa-co-section { display: flex; flex-direction: column; gap: 8px; }
.qa-co-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--qa-co-muted);
}
.qa-co-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.qa-co-type {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid rgba(148, 163, 184, 0.4);
  border: 1px solid color-mix(in srgb, var(--qa-type-color, #94a3b8) 40%, transparent);
  background: rgba(148, 163, 184, 0.12);
  background: color-mix(in srgb, var(--qa-type-color, #94a3b8) 12%, transparent);
  font-weight: 600;
  min-height: 34px;
}
.qa-co-type b { font-weight: 800; }
.qa-co-members {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--qa-co-line);
  border-radius: 12px;
  overflow: hidden;
}
.qa-co-member {
  display: grid;
  grid-template-columns: 32px 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  min-height: 48px;
}
.qa-co-member + .qa-co-member { border-top: 1px solid var(--qa-co-line); }
.qa-co-member-noaccount { background: rgba(245, 158, 11, 0.06); }
.qa-co-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 700;
  color: #fff;
  background: linear-gradient(135deg, var(--primary-500, #14b8a6), var(--primary-700, #0f766e));
}
.qa-co-member-noaccount .qa-co-avatar { background: linear-gradient(135deg, #94a3b8, #64748b); }
.qa-co-member-name { font-weight: 600; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.qa-co-tag {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 2px 6px;
  border-radius: 6px;
  background: rgba(245, 158, 11, 0.16);
  color: #92400e;
}
.qa-co-member-load { font-weight: 600; white-space: nowrap; font-variant-numeric: tabular-nums; }
.qa-co-days {
  display: flex;
  gap: 6px;
  align-items: flex-end;
  padding: 10px 10px 6px;
  border: 1px solid var(--qa-co-line);
  border-radius: 12px;
  overflow-x: auto;
}
.qa-co-day {
  flex: 1 0 28px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  min-width: 28px;
}
.qa-co-day-bar {
  width: 100%;
  max-width: 22px;
  border-radius: 6px 6px 3px 3px;
  background: var(--qa-co-teal);
}
.qa-co-day-empty .qa-co-day-bar { background: var(--qa-co-line); }
.qa-co-day-num { font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums; }
.qa-co-day-empty .qa-co-day-num { color: var(--qa-co-muted); }
.qa-co-day-wd { font-size: 10.5px; font-weight: 600; color: var(--qa-co-muted); text-transform: uppercase; }
.qa-co-band {
  border-radius: 12px;
  padding: 10px 12px;
  border: 1px solid rgba(245, 158, 11, 0.4);
  background: rgba(245, 158, 11, 0.09);
}
.qa-co-band-high { border-color: rgba(220, 38, 38, 0.35); background: rgba(220, 38, 38, 0.07); }
.qa-co-band-title { font-weight: 700; display: flex; align-items: center; gap: 8px; color: #92400e; }
.qa-co-band-high .qa-co-band-title { color: #991b1b; }
.qa-co-notes { list-style: none; margin: 6px 0 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.qa-co-note { padding-left: 14px; position: relative; color: var(--qa-co-ink); }
.qa-co-note::before { content: ''; position: absolute; left: 2px; top: 8px; width: 6px; height: 6px; border-radius: 50%; background: #d97706; }
.qa-co-note-high::before { background: #dc2626; }
.qa-co-note-info::before { background: #94a3b8; }
.qa-co-note-ack { font-weight: 600; padding-left: 0; display: flex; gap: 6px; align-items: center; }
.qa-co-note-ack::before { display: none; }
.qa-co-note-ack .fa-circle-check { color: #15803d; }
.qa-co-note-ack .fa-circle-exclamation { color: #dc2626; }
.qa-co-footer {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-top: 12px;
  border-top: 1px solid var(--qa-co-line);
}
.qa-co-notify { display: flex; align-items: flex-start; gap: 10px; font-weight: 600; }
.qa-co-notify i { margin-top: 2px; color: var(--qa-co-teal); }
.qa-co-notify-off { color: #92400e; }
.qa-co-notify-off i { color: #d97706; }
.qa-co-notify-noaccount { color: var(--qa-co-muted); }
.qa-co-notify-noaccount i { color: #d97706; }

/* Phone: full-width sheet, comfortable targets, strip scrolls. */
@media (max-width: 480px) {
  .confirm-dialog-content:has(.qa-commit-overview) {
    width: calc(100vw - 16px);
    max-width: none;
  }
  .qa-commit-overview { gap: 12px; font-size: 15px; }
  .qa-co-count { font-size: 38px; }
  .qa-co-member { grid-template-columns: 36px 1fr; padding: 12px; }
  .qa-co-member-load { grid-column: 2; }
  .qa-co-avatar { width: 36px; height: 36px; }
  .qa-co-type { min-height: 40px; padding: 8px 14px; }
}

/* Dark palette (the modal already keys on body.dark-mode). */
body.dark-mode .qa-commit-overview {
  --qa-co-ink: var(--text-primary, #f1f5f9);
  --qa-co-muted: var(--text-secondary, #94a3b8);
  --qa-co-line: var(--border-color, #334155);
}
body.dark-mode .qa-co-head { border-color: rgba(20, 184, 166, 0.45); background: linear-gradient(180deg, rgba(20, 184, 166, 0.18) 0%, rgba(20, 184, 166, 0.04) 100%); }
body.dark-mode .qa-co-tag { background: rgba(245, 158, 11, 0.22); color: #fcd34d; }
body.dark-mode .qa-co-band-title { color: #fcd34d; }
body.dark-mode .qa-co-band-high .qa-co-band-title { color: #fca5a5; }
body.dark-mode .qa-co-notify-off { color: #fcd34d; }

/* CONTROLS KEEP THEIR SIZE; THE ROW IS THE TAP TARGET (2026-09-24).
   style.css's coarse-pointer floor gives every checkbox and radio a 44x44
   minimum. On a phone that drew "Fair distribution", "Allow gaps" and the
   week-balance checkbox as 44px discs next to 14px member checkboxes in the
   same list. The 44px target belongs to the LABEL the control sits in, so
   the whole row answers a tap and the control itself stays control-sized.
   :where() keeps the size at low specificity so a component that sizes its
   own control still wins. */
@media (pointer: coarse) {
  #quota-assignment-modal input[type="checkbox"],
  #quota-assignment-modal input[type="radio"] {
    min-width: 0;
    min-height: 0;
  }
  :where(#quota-assignment-modal) input[type="checkbox"],
  :where(#quota-assignment-modal) input[type="radio"] {
    width: var(--checkbox-size, 18px);
    height: var(--checkbox-size, 18px);
    flex: 0 0 auto;
  }
  #quota-assignment-modal label:has(> input[type="checkbox"]),
  #quota-assignment-modal label:has(> input[type="radio"]) {
    min-height: 44px;
    align-items: center;
  }
}

/* ONE SCROLL ON A PHONE (2026-09-24). The member list's 500px cap made a
   scroller inside the panel's own scroller; on a 390px column a single
   card nearly fills it, so the list scrolled while the page did not. */
@media (max-width: 640px) {
  #quota-assignment-modal .qa-member-list {
    max-height: none;
    overflow: visible;
  }
}

/* History is the one tab that is not a step; on a phone it drops to its
   icon so all five fit at 390px (it was clipped to "Hi"). The text node
   stays in the DOM, so the button's accessible name is still "History". */
@media (max-width: 640px) {
  #quota-assignment-modal .qa-tab[data-tab="history"] { font-size: 0; gap: 0; }
  #quota-assignment-modal .qa-tab[data-tab="history"] > i { font-size: 0.875rem; }
}
@media (max-width: 380px) {
  #quota-assignment-modal .qa-tab { font-size: 0.75rem; padding: 9px 5px; }
}

/* ══════════════════════════════════════════════════════════════════════
   ASSIGN TAB, REWORKED (2026-09-24, owner-approved plan, phases 2-3).
   One row per member: tick, avatar, name + zone, total hours saved on the
   Hours tab. The per-type hours read as text beneath (full type names, not
   SH/OC/SUP), with priority on the same line. Rules fold into one line and
   the feasibility note is one line that opens to fix buttons.
   ══════════════════════════════════════════════════════════════════════ */
#quota-assignment-modal .qa-link-btn {
  border: none;
  background: none;
  padding: 0;
  font: inherit;
  font-weight: 600;
  color: var(--primary-600, #0d9488);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}
#quota-assignment-modal .qa-link-btn i { margin-right: 4px; }

#quota-assignment-modal .qa-member-req-card { padding: 4px 12px 10px; margin-bottom: 6px; }
#quota-assignment-modal .qa-req-row {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  cursor: pointer;
}
#quota-assignment-modal .qa-req-row .member-avatar {
  width: 28px;
  height: 28px;
  flex: 0 0 auto;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.6875rem;
  font-weight: 700;
  color: #fff;
  background: var(--primary-500, #14b8a6);
}
#quota-assignment-modal .qa-req-who {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1 1 auto;
}
#quota-assignment-modal .qa-req-who .member-name {
  font-weight: 600;
  font-size: 0.875rem;
  color: var(--text-primary, #0f172a);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
#quota-assignment-modal .qa-req-who .member-tz {
  font-size: 0.75rem;
  color: var(--text-tertiary, #64748b);
}
#quota-assignment-modal .qa-req-total {
  flex: 0 0 auto;
  font-weight: 700;
  font-size: 0.875rem;
  color: var(--text-primary, #0f172a);
}
#quota-assignment-modal .qa-req-detail {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 12px;
  padding-left: 28px;
}
#quota-assignment-modal .qa-req-hours {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
  flex: 1 1 auto;
  min-width: 0;
  font-size: 0.8125rem;
  color: var(--text-secondary, #475569);
}
#quota-assignment-modal .qa-req-hours-item {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  white-space: nowrap;
}
#quota-assignment-modal .qa-req-hours-item .qa-shift-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--qa-type-color, var(--slate-400, #94a3b8));
}
#quota-assignment-modal .qa-req-hours-none { color: #b45309; font-weight: 600; }
#quota-assignment-modal .qa-req-priority {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
  min-height: 0;
  font-size: 0.75rem;
  color: var(--text-tertiary, #64748b);
}
#quota-assignment-modal .qa-req-priority select {
  min-height: 32px;
  padding: 2px 6px;
  font-size: 0.8125rem;
}
#quota-assignment-modal .qa-hours-link-row { margin: 8px 0 4px; font-size: 0.8125rem; }

#quota-assignment-modal .qa-period-note {
  margin: 6px 0 0;
  font-size: 0.75rem;
  color: var(--text-tertiary, #64748b);
}

/* Feasibility: one line, opens to the list and its fixes. */
#quota-assignment-modal details.qa-feasibility { padding: 8px 12px; margin: 12px 0; }
#quota-assignment-modal details.qa-feasibility > summary {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  cursor: pointer;
  list-style: none;
  font-size: 0.8125rem;
}
#quota-assignment-modal details.qa-feasibility > summary::-webkit-details-marker { display: none; }
#quota-assignment-modal .qa-disclosure-caret {
  margin-left: auto;
  flex: 0 0 auto;
  font-size: 0.6875rem;
  color: var(--text-tertiary, #64748b);
  transition: transform 0.15s ease;
}
#quota-assignment-modal details[open] > summary .qa-disclosure-caret { transform: rotate(180deg); }
#quota-assignment-modal details.qa-feasibility[open] > summary { margin-bottom: 8px; }
#quota-assignment-modal .qa-feasibility-list { list-style: none; padding: 0; margin: 0 0 8px; }
#quota-assignment-modal .qa-feasibility-list li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 10px;
  margin: 0 0 6px;
  font-size: 0.8125rem;
}

/* Rules: folded by default; the summary says what is on. */
#quota-assignment-modal .qa-rules {
  margin: 12px 0;
  border: 1px solid var(--border-subtle, #e5e7eb);
  border-radius: var(--radius-md, 10px);
  background: var(--surface-secondary, #f9fafb);
}
#quota-assignment-modal .qa-rules-summary {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 36px 10px 12px;
  min-height: 44px;
  cursor: pointer;
  list-style: none;
  position: relative;
}
#quota-assignment-modal .qa-rules-summary::-webkit-details-marker { display: none; }
#quota-assignment-modal .qa-rules-summary .qa-disclosure-caret {
  position: absolute;
  right: 14px;
  top: 50%;
  margin-top: -6px;
}
#quota-assignment-modal .qa-rules-title { font-weight: 600; font-size: 0.875rem; color: var(--text-primary, #0f172a); }
#quota-assignment-modal .qa-rules-state { font-size: 0.75rem; color: var(--text-tertiary, #64748b); }
#quota-assignment-modal .qa-rules-body { padding: 0 12px 10px; }
#quota-assignment-modal .qa-rules-body .qa-coverage-options {
  display: flex;
  flex-wrap: wrap;
  gap: 0 16px;
}
#quota-assignment-modal .qa-rules-body .qa-coverage-options label {
  display: inline-flex;
  gap: 8px;
  font-size: 0.875rem;
}
#quota-assignment-modal .qa-rules-body .qa-smoothing-control { margin-top: 4px; }

body.dark-mode #quota-assignment-modal .qa-rules,
.dark-mode #quota-assignment-modal .qa-rules {
  background: rgba(148, 163, 184, 0.06);
  border-color: rgba(148, 163, 184, 0.18);
}
body.dark-mode #quota-assignment-modal .qa-req-who .member-name,
body.dark-mode #quota-assignment-modal .qa-req-total,
body.dark-mode #quota-assignment-modal .qa-rules-title { color: var(--text-primary, #f1f5f9); }
body.dark-mode #quota-assignment-modal .qa-link-btn { color: var(--primary-400, #2dd4bf); }
body.dark-mode #quota-assignment-modal .qa-req-hours-none { color: #fbbf24; }

/* Create schedule stays in reach on a phone: pinned to the bottom of the
   panel's scroll area instead of sitting below every section. */
@media (max-width: 640px) {
  #quota-assignment-modal .qa-distribute-setup ~ .qa-action-bar.qa-action-centered {
    position: sticky;
    bottom: 0;
    z-index: 2;
    margin: 0 -12px;
    padding: 10px 12px calc(10px + env(safe-area-inset-bottom, 0px));
    background: var(--surface-primary, #fff);
    border-top: 1px solid var(--border-subtle, #e5e7eb);
  }
  #quota-assignment-modal .qa-distribute-setup ~ .qa-action-bar.qa-action-centered .qa-btn { width: 100%; }
  body.dark-mode #quota-assignment-modal .qa-distribute-setup ~ .qa-action-bar.qa-action-centered {
    background: var(--slate-900, #0f172a);
    border-color: rgba(148, 163, 184, 0.18);
  }
}

/* ONE HEADING STYLE (2026-09-24). Section labels were ALL CAPS with
   letter-spacing ("SCHEDULING PERIOD", "SET ALL MEMBERS TO (PER COVERAGE
   TYPE):") while tab titles and card names were sentence case, so the
   panel read in two voices. Sentence case throughout. */
#quota-assignment-modal .qa-section-label {
  text-transform: none;
  letter-spacing: normal;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--text-secondary, #475569);
}
body.dark-mode #quota-assignment-modal .qa-section-label { color: var(--text-secondary, #94a3b8); }

/* The panel's own checkboxes and radios take the brand colour, not the
   browser's default blue (member ticks sat blue beside teal radios). */
#quota-assignment-modal input[type="checkbox"],
#quota-assignment-modal input[type="radio"] { accent-color: var(--primary-500, #14b8a6); }
body.dark-mode #quota-assignment-modal .qa-req-priority select {
  background: var(--slate-800, #1e293b);
  color: var(--text-primary, #f1f5f9);
  border-color: rgba(148, 163, 184, 0.3);
}

/* ══════════════════════════════════════════════════════════════════════
   HEADER ON THE VISIBLE SCREEN + THE GROUP NAMED (2026-09-26)
   Owner, phone screenshots: "group selects alignment is off also the header
   should be at the top with an x. Remove the business pill so we can
   display the group selected."
   ROOT 1: the sheet was 94vh / 100vh. On Android Chrome `vh` is the LARGE
   viewport (URL bar hidden), so with the bottom URL bar showing, a sheet
   pinned to the bottom was taller than the screen and its header - picker
   and close - slid off the top. dvh is the viewport actually visible.
   ROOT 2: the dropdown was right-anchored to the picker at a fixed 340px, so
   on a phone its left edge ran past the sheet. It now spans the header row.
   ROOT 3: the plan pill is gone (index.html), so the picker shows the group
   name again; the title keeps priority and the name ellipsizes.
   ══════════════════════════════════════════════════════════════════════ */
@supports (height: 1dvh) {
  #quota-assignment-modal .modal-content {
    height: 94dvh;
    max-height: 94dvh;
  }
}
#quota-assignment-modal .qa-header {
  position: relative;
  flex-shrink: 0;
}
@media (max-width: 640px) {
  /* The title keeps its full width; the picker takes what is left and its
     group name ellipsizes ("Close Team…") rather than the panel's name. */
  #quota-assignment-modal .qa-header {
    grid-template-columns: auto minmax(0, 1fr) auto;
    padding: 10px 12px;
  }
  #quota-assignment-modal .qa-header-tools { justify-content: flex-end; min-width: 0; }
  #quota-assignment-modal .qa-header-tools .qa-board-selector { min-width: 0; max-width: 100%; }
  #quota-assignment-modal .qa-header-tools .qa-board-selector { position: static; margin-left: 0; }
  #quota-assignment-modal .qa-header-tools .qa-board-dropdown {
    top: calc(100% - 4px);
    left: 12px;
    right: 12px;
    width: auto;
    max-width: none;
  }
  #quota-assignment-modal .qa-header-tools .qa-board-selector-btn {
    height: 32px;
    padding: 0 8px;
    gap: 6px;
    max-width: 100%;
    min-width: 0;
  }
  #quota-assignment-modal .qa-header-tools .qa-board-selector-btn > span {
    display: inline-block;
    flex: 0 1 auto;
    min-width: 0;
    max-width: 140px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}

/* Custom scheduling period (2026-09-26): From/To under the period window.
   Takes its own full row of the wrapping toolbar so the two date fields
   never squeeze the arrows. */
#quota-assignment-modal .qa-custom-period {
  flex: 1 1 100%;
  display: flex;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 8px 10px;
}
#quota-assignment-modal .qa-custom-period-field {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 130px;
  min-width: 0;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-secondary, #64748b);
}
#quota-assignment-modal .qa-custom-period-field input[type="date"] {
  width: 100%;
  min-width: 0;
  box-sizing: border-box;
  height: 36px;
  padding: 0 8px;
  border: 1px solid var(--border-subtle, #e5e7eb);
  border-radius: 8px;
  background: var(--surface-primary, #ffffff);
  color: var(--text-primary, #1e293b);
  font: inherit;
  font-size: 13px;
  font-weight: 500;
}
#quota-assignment-modal .qa-custom-period-len {
  flex: 0 0 auto;
  padding-bottom: 9px;
  font-size: 12px;
  color: var(--text-secondary, #64748b);
}
body.dark-mode #quota-assignment-modal .qa-custom-period-field input[type="date"] {
  background: var(--surface-primary, #0f172a);
  border-color: rgba(255, 255, 255, 0.12);
  color: var(--text-primary, #e2e8f0);
  color-scheme: dark;
}

/* Save Hours refuses a row outside 0..period max and marks it (2026-09-26). */
#quota-assignment-modal .qa-hour-input.qa-input-invalid {
  outline: 2px solid var(--danger-500, #ef4444);
  outline-offset: -2px;
  color: var(--danger-600, #dc2626);
}

/* ══════════════════════════════════════════════════════════════════════
   PHONE: THE PANEL IS THE SCREEN (2026-09-28)
   Owner, phone screenshot of Coverage: "Quota has unnecessary unused space
   on mobile too, maximize viewing area". Measured at 410x732:
   - the sheet was 94dvh, leaving a dead strip above it, with a 24px radius
     on every corner;
   - Coverage spent 127px on a toolbar: a "Coverage" heading that repeats
     the tab just above it, then Add Type and One per region on two rows.
   The sheet now fills the visible screen (dvh, so Android's URL bar cannot
   push the header off the top - the 09-26 bug), the repeated heading goes
   (the selected tab still names the step, and the heading keeps its text
   for screen readers), and the two buttons share one row.
   ══════════════════════════════════════════════════════════════════════ */
@media (max-width: 640px) {
  #quota-assignment-modal .modal-content {
    width: 100%;
    max-width: 100%;
    height: 100vh;
    max-height: 100vh;
    margin: 0;
    border-radius: 0;
  }
  #quota-assignment-modal .qa-tab-toolbar.qa-coverage-toolbar {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-bottom: 12px;
  }
  #quota-assignment-modal .qa-coverage-toolbar .qa-tab-title {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
  #quota-assignment-modal .qa-shift-type-item { padding: 8px 12px; gap: 10px; }
  #quota-assignment-modal .qa-shift-types-list { margin-bottom: 14px; }
}
@supports (height: 1dvh) {
  @media (max-width: 640px) {
    #quota-assignment-modal .modal-content { height: 100dvh; max-height: 100dvh; }
  }
}
||||||| parent of 5c83eb39 (feat(quota): a Publish cell prints the shift's hours on the member's clock, not a code)

/* ============================================================
   CLOCK CELLS (owner-approved redesign 2026-09-28)
   A shift cell prints its start and end on the member's clock
   (or the schedule clock, per .qa-grid-clock), the shift type
   rides as a top colour bar, and amber = outside their hours.
   The code chip ("S+1") it replaces needed the legend to read.
   ============================================================ */
.qa-grid-clock {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 10px;
  font-size: 0.75rem;
  color: var(--slate-600, #475569);
}
.qa-grid-clock-label {
  font-weight: 600;
  margin-right: 2px;
}
.qa-grid-clock-btn {
  min-height: 32px;
  padding: 0 12px;
  border-radius: 16px;
  border: 1px solid var(--slate-200, #e2e8f0);
  background: #ffffff;
  color: var(--slate-700, #334155);
  font: inherit;
  cursor: pointer;
}
.qa-grid-clock-btn[aria-pressed="true"] {
  border-color: #0d9488;
  background: #f0fdfa;
  color: #0f766e;
  font-weight: 600;
}
body.dark-mode .qa-grid-clock { color: var(--slate-300, #cbd5e1); }
body.dark-mode .qa-grid-clock-btn {
  background: rgba(255, 255, 255, 0.04);
  border-color: rgba(148, 163, 184, 0.3);
  color: var(--slate-300, #cbd5e1);
}
body.dark-mode .qa-grid-clock-btn[aria-pressed="true"] {
  background: rgba(20, 184, 166, 0.16);
  border-color: #2dd4bf;
  color: #5eead4;
}

.qa-legend-swatch.qa-legend-bar {
  min-width: 18px;
  width: 18px;
  height: 14px;
  padding: 0;
  box-shadow: inset 0 3px 0 var(--qa-type-color, #14b8a6), inset 0 0 0 1px var(--qa-type-color, #14b8a6);
}
.qa-legend-swatch.qa-legend-outside {
  min-width: 18px;
  width: 18px;
  height: 14px;
  padding: 0;
  background: #fef3c7;
  box-shadow: inset 0 0 0 1px #f59e0b;
}
body.dark-mode .qa-legend-swatch.qa-legend-outside { background: rgba(245, 158, 11, 0.22); }

.qa-grid-member-hours {
  display: block;
  padding: 0 8px 2px;
  font-size: 0.6875rem;
  font-weight: 500;
  text-transform: none;
  color: var(--slate-500, #64748b);
}

.qa-grid-cell.qa-cell-clock {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  width: 100%;
  min-width: 44px;
  height: auto;
  min-height: 44px;
  padding: 6px 2px 3px;
  overflow: hidden;
  font-size: 0.6875rem;
  font-weight: 600;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
  background-color: #e6f7f5;
  background-color: color-mix(in srgb, var(--qa-type-color, #14b8a6) 12%, #fff);
  color: #134e4a;
  border: 1px solid #99f6e4;
  border-color: #99f6e4;
  border-color: color-mix(in srgb, var(--qa-type-color, #14b8a6) 40%, #fff);
}
.qa-grid-cell.qa-cell-clock::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 3px;
  background: var(--qa-type-color, #14b8a6);
}
.qa-grid-cell.qa-cell-clock .qa-cell-t { display: block; white-space: nowrap; }
.qa-grid-cell.qa-cell-clock .qa-cell-t small { font-size: 0.5625rem; font-weight: 700; margin-left: 1px; }
.qa-grid-cell.qa-cell-clock.qa-cell-outside {
  background-color: #fef3c7;
  border-color: #fcd34d;
  color: #78350f;
}
body.dark-mode .qa-grid-cell.qa-cell-clock {
  background-color: rgba(20, 184, 166, 0.12);
  background-color: color-mix(in srgb, var(--qa-type-color, #14b8a6) 18%, #0f172a);
  border-color: rgba(148, 163, 184, 0.25);
  color: #e2e8f0;
}
body.dark-mode .qa-grid-cell.qa-cell-clock.qa-cell-outside {
  background-color: rgba(245, 158, 11, 0.2);
  border-color: rgba(245, 158, 11, 0.55);
  color: #fcd34d;
}
@media (max-width: 480px) {
  .qa-grid-cell.qa-cell-clock { min-width: 40px; font-size: 0.625rem; }
}

/* A day list ("Mon/Tue/Wed/Thu/Fri/Sat") has no break point, so on a
   phone it ran UNDER the fix button beside it (measured 412px, 2026-09-28).
   Let it break, and on a phone put the fixes on their own line. */
.qa-intervention-title { overflow-wrap: anywhere; }
@media (max-width: 640px) {
  .qa-intervention-row { flex-wrap: wrap; }
  .qa-intervention-actions { flex-basis: 100%; padding-left: 20px; flex-wrap: wrap; }
  .qa-intervention-meta { flex: 1 1 0; }
}

/* ── Share & export (2026-09-28) ─────────────────────────────── */
.qa-export {
  margin: 4px 0 16px;
  padding: 14px;
  border: 1px solid var(--slate-200, #e2e8f0);
  border-radius: var(--radius-md, 12px);
  background: #ffffff;
}
.qa-export-heading {
  margin: 0 0 2px;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--slate-900, #0f172a);
}
.qa-export-note {
  margin: 0 0 10px;
  font-size: 0.75rem;
  color: var(--slate-600, #475569);
}
.qa-export-list {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--slate-200, #e2e8f0);
  border-radius: var(--radius-md, 12px);
  overflow: hidden;
}
.qa-export-row {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 56px;
  padding: 8px 12px;
  border: 0;
  border-top: 1px solid var(--slate-100, #f1f5f9);
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.qa-export-row:first-child { border-top: 0; }
.qa-export-row:hover,
.qa-export-row:focus-visible { background: var(--slate-50, #f8fafc); outline: none; }
.qa-export-row:focus-visible { box-shadow: inset 0 0 0 2px #14b8a6; }
.qa-export-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  border-radius: 10px;
  background: #f0fdfa;
  color: #0f766e;
}
.qa-export-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.qa-export-title { font-size: 0.875rem; font-weight: 600; color: var(--slate-900, #0f172a); }
.qa-export-sub { font-size: 0.75rem; color: var(--slate-600, #475569); }
body.dark-mode .qa-export { background: rgba(15, 23, 42, 0.4); border-color: rgba(148, 163, 184, 0.25); }
body.dark-mode .qa-export-heading,
body.dark-mode .qa-export-title { color: #f1f5f9; }
body.dark-mode .qa-export-note,
body.dark-mode .qa-export-sub { color: #94a3b8; }
body.dark-mode .qa-export-list { border-color: rgba(148, 163, 184, 0.25); }
body.dark-mode .qa-export-row { border-top-color: rgba(148, 163, 184, 0.15); }
body.dark-mode .qa-export-row:hover,
body.dark-mode .qa-export-row:focus-visible { background: rgba(255, 255, 255, 0.04); }
body.dark-mode .qa-export-icon { background: rgba(20, 184, 166, 0.16); color: #5eead4; }
.qa-export-feed { margin-top: 10px; padding: 10px 12px; border-radius: var(--radius-md, 12px); background: var(--slate-50, #f8fafc); }
.qa-export-feed-note { margin: 0 0 8px; font-size: 0.75rem; color: var(--slate-600, #475569); }
.qa-export-feed-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.qa-export-feed-actions .qa-btn { min-height: 44px; display: inline-flex; align-items: center; text-decoration: none; }
body.dark-mode .qa-export-feed { background: rgba(255, 255, 255, 0.04); }
body.dark-mode .qa-export-feed-note { color: #94a3b8; }

/* ============================================================
   ASSIGN: COVERAGE BOARD + DAY TIMELINE (2026-09-28)
   Shift type x day, one cell per slot: initials (amber when
   outside their hours) or an open, striped cell. A day header
   opens that day as per-person hour cells with the shifts on top.
   ============================================================ */
.qa-cover-summary { display: flex; flex-direction: column; gap: 8px; margin: 4px 0 12px; }
.qa-cover-count { font-size: 0.9375rem; color: var(--slate-800, #1e293b); }
.qa-cover-count strong { font-size: 1.375rem; font-weight: 700; margin-right: 2px; }
.qa-cover-meta { color: var(--slate-600, #475569); font-size: 0.8125rem; }
.qa-cover-bar { display: flex; height: 8px; border-radius: 4px; overflow: hidden; background: var(--slate-100, #f1f5f9); }
.qa-cover-in { background: #14b8a6; }
.qa-cover-out { background: #f59e0b; }
.qa-cover-keys { display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: 0.75rem; color: var(--slate-600, #475569); }
.qa-cover-keys > span { display: inline-flex; align-items: center; gap: 5px; }
.qa-key { display: inline-block; width: 12px; height: 12px; border-radius: 3px; }
.qa-key-in { background: #ccfbf1; box-shadow: inset 0 0 0 1px #5eead4; }
.qa-key-out { background: #fde68a; box-shadow: inset 0 0 0 1px #f59e0b; }
.qa-key-open { background: repeating-linear-gradient(135deg, #fed7aa 0 3px, #fff7ed 3px 6px); box-shadow: inset 0 0 0 1px #f59e0b; }
.qa-cover-fair .qa-fairness-dot { margin: 0; }

.qa-cover-board-wrap { overflow-x: auto; margin-bottom: 12px; -webkit-overflow-scrolling: touch; }
.qa-cover-board { border-collapse: separate; border-spacing: 3px; min-width: 100%; }
.qa-cover-board th, .qa-cover-board td { padding: 0; text-align: center; vertical-align: middle; }
.qa-cover-board th.qa-cover-corner { font-size: 0.6875rem; font-weight: 600; color: var(--slate-500, #64748b); text-align: left; }
.qa-cover-day {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  width: 100%; min-width: 38px; min-height: 44px; padding: 2px 0;
  border: 0; border-radius: 8px; background: transparent; cursor: pointer;
  font: inherit; font-size: 0.6875rem; font-weight: 600; color: var(--slate-700, #334155);
}
.qa-cover-day small { font-size: 0.75rem; font-weight: 500; }
.qa-cover-day.is-today { color: #0f766e; }
.qa-cover-day.is-open { background: #f0fdfa; box-shadow: inset 0 0 0 2px #14b8a6; color: #0f766e; }
.qa-cover-board th.qa-cover-type {
  position: sticky; left: 0; z-index: 1; min-width: 76px; max-width: 110px;
  padding: 0 6px 0 8px; text-align: left; background: var(--surface-primary, #ffffff);
  box-shadow: inset 3px 0 0 var(--qa-type-color, #14b8a6);
}
.qa-cover-type-name { display: block; font-size: 0.75rem; font-weight: 600; color: var(--slate-800, #1e293b); overflow-wrap: anywhere; }
.qa-cover-type-time { display: block; font-size: 0.6875rem; font-weight: 400; color: var(--slate-500, #64748b); }
.qa-cover-board td { min-width: 38px; }
.qa-cover-slot {
  display: flex; align-items: center; justify-content: center;
  width: 100%; min-width: 38px; min-height: 44px; margin: 0 0 2px;
  border: 0; border-radius: 6px; cursor: pointer;
  font: inherit; font-size: 0.75rem; font-weight: 700;
  background: #ccfbf1; color: #115e59;
}
.qa-cover-slot:last-child { margin-bottom: 0; }
.qa-cover-slot.is-outside { background: #fde68a; color: #78350f; }
.qa-cover-slot.is-open {
  background: repeating-linear-gradient(135deg, #fff7ed 0 4px, #ffffff 4px 8px);
  box-shadow: inset 0 0 0 1px #d97706; color: #b45309; font-weight: 500;
}
.qa-cover-slot:focus-visible, .qa-cover-day:focus-visible { outline: 2px solid #0d9488; outline-offset: 1px; }
.qa-cover-none { color: var(--slate-300, #cbd5e1); }
.qa-assign-fixes { margin-bottom: 12px; border-radius: var(--radius-md, 12px); transition: box-shadow 0.2s; }
.qa-assign-fixes.is-flash { box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.45); }
.qa-preview-local { display: block; font-size: 0.6875rem; font-weight: 500; color: var(--slate-600, #475569); }
.qa-preview-local.is-outside { color: #b45309; }

.qa-timeline {
  margin: 0 0 14px; padding: 12px; border-radius: var(--radius-md, 12px);
  border: 1px solid var(--slate-200, #e2e8f0); background: var(--surface-primary, #ffffff);
}
.qa-tl-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; font-size: 0.875rem; }
.qa-tl-close { width: 44px; height: 44px; border: 0; border-radius: 22px; background: transparent; color: var(--slate-500, #64748b); cursor: pointer; }
.qa-tl-row { display: grid; grid-template-columns: 84px minmax(0, 1fr); column-gap: 8px; align-items: center; padding: 5px 0; border-bottom: 1px solid var(--slate-100, #f1f5f9); }
.qa-tl-who { min-width: 0; }
.qa-tl-name { display: block; font-size: 0.75rem; font-weight: 600; color: var(--slate-800, #1e293b); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.qa-tl-zone { display: block; font-size: 0.625rem; color: var(--slate-500, #64748b); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.qa-tl-axis { border-bottom: 0; padding: 0; }
.qa-tl-ticks { display: flex; justify-content: space-between; font-size: 0.625rem; color: var(--slate-500, #64748b); }
.qa-tl-track { position: relative; display: grid; grid-template-columns: repeat(24, minmax(0, 1fr)); gap: 1px; height: 30px; }
.qa-tl-covered .qa-tl-track { height: 16px; }
.qa-tl-cell { display: block; border-radius: 2px; background: #f1f5f9; }
.qa-tl-cell.is-work { background: #dcfce7; }
.qa-tl-cell.is-off { background: #f1f5f9; }
.qa-tl-cell.is-night { background: #cbd5e1; }
.qa-tl-cell.is-unknown { background: repeating-linear-gradient(90deg, #f1f5f9 0 2px, #ffffff 2px 4px); }
.qa-tl-cell.is-one { background: #5eead4; }
.qa-tl-cell.is-many { background: #14b8a6; }
.qa-tl-cell.is-none { background: #f1f5f9; }
.qa-tl-cell.is-gap { background: repeating-linear-gradient(135deg, #fed7aa 0 3px, #fff7ed 3px 6px); box-shadow: inset 0 0 0 1px #f59e0b; }
.qa-tl-bar {
  position: absolute; top: 9px; height: 12px; border-radius: 6px;
  background: #0f766e; color: #ffffff; font-size: 0.5625rem; font-weight: 600; line-height: 12px;
  padding: 0 5px; box-sizing: border-box; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.qa-tl-bar.is-outside { background: #b45309; }
.qa-tl-keys { display: flex; flex-wrap: wrap; gap: 6px 12px; margin-top: 8px; font-size: 0.6875rem; color: var(--slate-600, #475569); }
.qa-tl-keys > span { display: inline-flex; align-items: center; gap: 4px; }
.qa-tl-k-work { background: #dcfce7; }
.qa-tl-k-off { background: #f1f5f9; box-shadow: inset 0 0 0 1px #e2e8f0; }
.qa-tl-k-night { background: #cbd5e1; }

body.dark-mode .qa-cover-count { color: #e2e8f0; }
body.dark-mode .qa-cover-meta, body.dark-mode .qa-cover-keys, body.dark-mode .qa-tl-keys { color: #94a3b8; }
body.dark-mode .qa-cover-bar { background: rgba(255, 255, 255, 0.08); }
body.dark-mode .qa-cover-day { color: #cbd5e1; }
body.dark-mode .qa-cover-day.is-open { background: rgba(20, 184, 166, 0.16); color: #5eead4; }
/* Today keeps its colour in dark mode (2026-09-29): the plain dark rule
   above outranked .qa-cover-day.is-today, so today looked like any day. */
body.dark-mode .qa-cover-day.is-today { color: #5eead4; }
/* The keys match the dark cells they explain (2026-09-29). */
body.dark-mode .qa-key-in { background: rgba(20, 184, 166, 0.22); box-shadow: inset 0 0 0 1px rgba(94, 234, 212, 0.45); }
body.dark-mode .qa-key-out { background: rgba(245, 158, 11, 0.25); box-shadow: inset 0 0 0 1px rgba(245, 158, 11, 0.6); }
body.dark-mode .qa-key-open { background: repeating-linear-gradient(135deg, rgba(245, 158, 11, 0.18) 0 3px, transparent 3px 6px); box-shadow: inset 0 0 0 1px rgba(245, 158, 11, 0.6); }
body.dark-mode .qa-cover-board th.qa-cover-type { background: var(--surface-primary, #0f172a); }
body.dark-mode .qa-cover-type-name, body.dark-mode .qa-tl-name { color: #e2e8f0; }
body.dark-mode .qa-cover-slot { background: rgba(20, 184, 166, 0.22); color: #99f6e4; }
body.dark-mode .qa-cover-slot.is-outside { background: rgba(245, 158, 11, 0.25); color: #fcd34d; }
body.dark-mode .qa-cover-slot.is-open { background: repeating-linear-gradient(135deg, rgba(245, 158, 11, 0.18) 0 4px, transparent 4px 8px); color: #fcd34d; }
body.dark-mode .qa-timeline { background: rgba(15, 23, 42, 0.4); border-color: rgba(148, 163, 184, 0.25); }
body.dark-mode .qa-tl-row { border-bottom-color: rgba(148, 163, 184, 0.12); }
body.dark-mode .qa-tl-cell.is-work { background: rgba(34, 197, 94, 0.28); }
body.dark-mode .qa-tl-cell.is-off, body.dark-mode .qa-tl-cell.is-none { background: rgba(255, 255, 255, 0.06); }
body.dark-mode .qa-tl-cell.is-night { background: rgba(0, 0, 0, 0.45); }
/* No white stripes on a dark card (2026-09-29). */
body.dark-mode .qa-tl-cell.is-unknown { background: repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.08) 0 2px, transparent 2px 4px); }
body.dark-mode .qa-tl-cell.is-gap { background: repeating-linear-gradient(135deg, rgba(245, 158, 11, 0.18) 0 3px, transparent 3px 6px); box-shadow: inset 0 0 0 1px rgba(245, 158, 11, 0.6); }
body.dark-mode .qa-preview-local { color: #94a3b8; }
body.dark-mode .qa-preview-local.is-outside { color: #fcd34d; }
body.dark-mode .qa-tl-k-work { background: rgba(34, 197, 94, 0.28); }
body.dark-mode .qa-tl-k-off { background: rgba(255, 255, 255, 0.06); box-shadow: inset 0 0 0 1px rgba(148, 163, 184, 0.3); }
body.dark-mode .qa-tl-k-night { background: rgba(0, 0, 0, 0.45); box-shadow: inset 0 0 0 1px rgba(148, 163, 184, 0.3); }

/* ============================================================
   TOUCH TARGETS ON A PHONE (2026-09-28 launch audit)
   Every control in the panel is at least 44 x 44 px at <=640px. Measured at
   412px before this block: all of these already were, through scattered
   phone rules, EXCEPT the icon-only History tab (26 wide) and the grid's
   "Each person's time / UTC" clock toggle (32 tall). The block states the
   floor once, for the whole list, so a later base-size change cannot
   quietly undo it. Minimums only: no display or position changes, so a
   control hidden elsewhere (read-only mode) stays hidden. Measured after:
   the five tabs still fit a 360px strip without scrolling.
   ============================================================ */
@media (max-width: 640px) {
  #quota-assignment-modal .qa-icon-btn,
  #quota-assignment-modal .qa-why-btn,
  #quota-assignment-modal .qa-preview-drop-btn,
  #quota-assignment-modal .qa-exclusion-chip-remove,
  #quota-assignment-modal .qa-inspector-close,
  #quota-assignment-modal .qa-readonly-dismiss,
  #quota-assignment-modal .qa-sync-chip,
  #quota-assignment-modal .qa-step-btn,
  #quota-assignment-modal .qa-grid-clock-btn,
  #quota-assignment-modal .qa-tab {
    min-width: 44px;
    min-height: 44px;
  }
  /* The History tab is an icon alone on a phone: centre it in its 44px. */
  #quota-assignment-modal .qa-tab { justify-content: center; }
}

/* An overnight shift from the day before, continuing into this day's
   timeline from 00:00 (2026-09-28). Square on the left: it did not start here. */
.qa-tl-bar.is-continued {
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
  opacity: 0.85;
}

/* Phone tap targets the 09-28 sweep missed (pass 2, measured at 412px):
   hour inputs 30px, priority select 32px, reassign select 20px tall, and
   the empty "add a shift" grid cell 32x40. */
@media (max-width: 640px) {
  #quota-assignment-modal .qa-hour-input,
  #quota-assignment-modal .qa-req-priority select.qa-priority-select,
  #quota-assignment-modal .qa-preview-reassign { min-height: 44px; }
  #quota-assignment-modal .qa-grid-cell.qa-grid-cell-empty { min-width: 40px; min-height: 44px; }
}

/* A publish refused for leave (2026-09-29 launch audit): the notice stays
   above the schedule until the clashing shift is moved, and the shift itself
   carries a red ring in the grid and on the board. */
.qa-leave-refusal {
    display: flex;
    gap: 10px;
    align-items: flex-start;
    margin: 0 0 12px 0;
    padding: 10px 12px;
    border-radius: 8px;
    border: 1px solid rgba(220, 38, 38, 0.4);
    background: rgba(220, 38, 38, 0.07);
    color: var(--text-primary, #1f2937);
    font-size: 13px;
    line-height: 1.45;
}
.qa-leave-refusal > i { color: var(--danger-600, #dc2626); margin-top: 2px; }
body.dark-mode .qa-leave-refusal {
    background: rgba(248, 113, 113, 0.12);
    border-color: rgba(248, 113, 113, 0.45);
    color: var(--text-primary, #e5e7eb);
}
body.dark-mode .qa-leave-refusal > i { color: #f87171; }
.qa-leave-conflict {
    outline: 2px solid var(--danger-600, #dc2626) !important;
    outline-offset: 1px;
}
body.dark-mode .qa-leave-conflict { outline-color: #f87171 !important; }
.qa-acceptance-rollup .qa-accept-sending { color: var(--text-secondary, #475569); }
.qa-timeline-title:focus { outline: none; }
.qa-timeline-title:focus-visible { outline: 2px solid var(--primary-color, #2563eb); outline-offset: 2px; }
/* A coverage type's skipped weekdays (2026-09-29, fourth pass): a line on
   its Coverage card, with the way back as a text button. */
.qa-skipped-days {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 12px;
    margin-top: 4px;
    font-size: 12px;
    color: var(--text-secondary, #475569);
}
.qa-skipped-days-text { min-width: 0; }
.qa-skipped-days .qa-skipped-days-restore { min-height: 24px; }
body.dark-mode .qa-skipped-days { color: #cbd5e1; }
/* "Select all" on Hours read about 1.9:1 in dark mode (fourth pass). */
body.dark-mode .qa-select-all-wrap,
.dark-mode .qa-select-all-wrap { color: #cbd5e1; }
/* "Treat it as arranged?" (2026-09-29): one card per repeating busy block
   that kept someone off a shift, in the draft review. */
.qa-busy-questions {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin: 10px 0;
}
.qa-busy-q {
    border: 1px solid var(--border-color, #cbd5e1);
    border-left: 3px solid var(--primary-color, #2563eb);
    border-radius: 10px;
    padding: 10px 12px;
    background: var(--surface-color, #ffffff);
    color: var(--text-primary, #111827);
}
.qa-busy-q-text {
    display: flex;
    gap: 8px;
    align-items: baseline;
    margin: 0;
    font-size: 14px;
    font-weight: 600;
    overflow-wrap: anywhere;
}
.qa-busy-q-help {
    margin: 4px 0 0;
    font-size: 12px;
    color: var(--text-secondary, #475569);
}
.qa-busy-q-actions {
    display: flex;
    gap: 8px;
    margin-top: 8px;
}
.qa-busy-q-actions .qa-btn { min-height: 36px; min-width: 64px; }
.qa-busy-q-status:empty { display: none; }
.qa-busy-q-status {
    margin: 6px 0 0;
    font-size: 12px;
    color: var(--text-secondary, #475569);
}
.qa-busy-q.is-answered .qa-busy-q-actions { display: none; }
body.dark-mode .qa-busy-q {
    background: #0f172a;
    border-color: #334155;
    border-left-color: #60a5fa;
    color: #f1f5f9;
}
body.dark-mode .qa-busy-q-help,
body.dark-mode .qa-busy-q-status { color: #cbd5e1; }

/* 2026-10-05: Assign says the period already has a published schedule, and an
   empty draft says there is nothing to publish (quota-assignment-modal.js
   _renderPreview). Info tone, not a warning: nothing is wrong. */
.qa-published-context {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 12px;
    margin: 0 0 12px;
    padding: 10px 12px;
    border-radius: 10px;
    background: rgba(20, 184, 166, 0.07);
    border: 1px solid rgba(20, 184, 166, 0.28);
    font-size: 14px;
    line-height: 1.4;
}
.qa-published-context > span { flex: 1 1 240px; }
.qa-published-context > i { color: rgb(13, 148, 136); }
body.dark-mode .qa-published-context {
    background: rgba(20, 184, 166, 0.12);
    border-color: rgba(20, 184, 166, 0.36);
}
.qa-empty-draft-note {
    margin: 12px 0 0;
    font-size: 14px;
    color: var(--text-secondary, inherit);
    text-align: right;
}
