/* PracticeForceOne® UI Styles */
:root {
  --primary: #2563eb;
  --primary-dark: #1d4ed8;
  --success: #16a34a;
  --danger: #dc2626;

  /* WCAG 1.4.3 (AA) — alert TEXT sits on a pale tint, not on white, so the base status colours
     fall short there even though they pass elsewhere. Measured on the served build:
         #dc2626 on #fef2f2 = 4.41:1   #d97706 on #fffbeb = 3.07:1   #16a34a on #f0fdf4 = 3.15:1
     These tint-specific tokens are one step darker and clear 4.5:1. They are SEPARATE tokens
     rather than a change to --danger/--warning/--success, because those also colour buttons and
     borders where the backdrop is different and the current values are already fine.
     ⛔ They are overridden in BOTH high-contrast blocks below — hardcoding the darker hex into
     .alert-* would have silently cut high contrast off from its own deliberately tuned palette. */
  --danger-on-tint: #b91c1c;   /* 5.91:1 on #fef2f2 */
  --warning-on-tint: #b45309;  /* 4.84:1 on #fffbeb */
  --success-on-tint: #15803d;  /* 4.79:1 on #f0fdf4 */
  --error: #dc2626;
  --warning: #d97706;
  /* --white was referenced 26 times and defined nowhere, so `background: var(--white)` was invalid at
     computed-value time and resolved to `unset` — and `background` is NOT inherited, so its initial
     value is TRANSPARENT. 25 of the 26 uses are backgrounds on cards and panels, including the patient
     chart's identity, timeline, KPI and search cards, which sit on a --gray-50/--gray-100 page. They
     rendered grey while still carrying a border, radius and box-shadow: the card elevation was there
     and the surface under it was not.
     WHY A LITERAL HERE IS CORRECT AND NOT A THEMING MISTAKE. This file is the legacy FLAT palette of
     literals (--primary, the gray scale) for pages that do not load the theme system. The themed path
     is css/variables/colors.css --color-white feeding the semantic --card-bg, which dark.css remaps to
     --color-gray-900. Defining --white as a literal would be wrong for a themed page — so I measured:
     all NINE html files that reference bare var(--white) load styles.css only, with zero references to
     theme-manager, css/themes/ or data-theme. There is no dark rendering here to spoil.
     ⚠ IF ONE OF THOSE PAGES EVER ADOPTS THE THEME SYSTEM, its card backgrounds should move to
     --card-bg rather than keep this token, or it will render a light surface in dark mode. */
  --white: #ffffff;
  --gray-50: #f9fafb;
  --gray-100: #f3f4f6;
  --gray-200: #e5e7eb;
  --gray-300: #d1d5db;
  --gray-400: #9ca3af;
  --gray-500: #6b7280;
  /* --gray-600 was MISSING from the middle of this scale while 198 call sites referenced it, 197 of
     them as `color`. A var() naming an undefined custom property with no fallback is INVALID AT
     COMPUTED-VALUE TIME, which resolves to `unset`; `color` is inherited, so every one of those sites
     inherited the body colour instead of rendering muted. De-emphasised text was drawing at full
     strength across 44+ pages, which flattens the visual hierarchy everywhere it appears.
     THE VALUE IS DERIVED, NOT CHOSEN. Two independent lines agree: (1) the other NINE entries of this
     scale are the Tailwind gray palette exactly (50 #f9fafb through 900 #111827), and Tailwind's 600 is
     #4b5563; (2) of the 55 sites that pass an explicit fallback for this token, 37 already say #4b5563.
     The minority fallbacks are neighbours of the gap rather than disagreement - #6b7280 IS --gray-500
     and #374151 IS --gray-700, i.e. call sites reaching one step light or dark for a token that was
     not there. Filling the gap makes those 197 sites render what they always asked for. */
  --gray-600: #4b5563;
  --gray-700: #374151;
  --gray-800: #1f2937;
  --gray-900: #111827;
  --button-height: 2.5rem;
  --button-height-sm: 2rem;
  --button-gap: 0.5rem;
  --button-radius: 0.375rem;
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  background: var(--gray-100);
  color: var(--gray-900);
  line-height: 1.5;
}

/* Auth Layout */
.auth-container {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
}

.auth-card {
  background: white;
  border-radius: 0.5rem;
  box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1);
  padding: 2rem;
  width: 100%;
  max-width: 400px;
}

.auth-logo {
  text-align: center;
  margin-bottom: 1.5rem;
}

.auth-logo h1 {
  font-size: 1.5rem;
  color: var(--primary);
}

.auth-logo p {
  color: var(--gray-500);
  font-size: 0.875rem;
}

/* Forms */
.form-group {
  margin-bottom: 1rem;
  position: relative;
}

.form-group label {
  display: block;
  font-weight: 500;
  margin-bottom: 0.25rem;
  color: var(--gray-700);
}

.form-group input, .form-group select, .form-group textarea {
  width: 100%;
  padding: 0.625rem 0.75rem;
  border: 1px solid var(--gray-300);
  border-radius: 0.375rem;
  font-size: 1rem;
  transition: border-color 0.15s, box-shadow 0.15s;
}

.form-group input:focus, .form-group select:focus, .form-group textarea:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
}

.date-field-with-picker {
  align-items: stretch;
  display: inline-flex;
  gap: 0.35rem;
  max-width: 100%;
  width: 100%;
}

.date-field-with-picker .date-picker-entry {
  flex: 1 1 auto;
  min-width: 0;
}

.date-field-with-picker .date-picker-entry::-webkit-calendar-picker-indicator {
  display: none;
}

.date-picker-button {
  align-items: center;
  background: var(--gray-50);
  border: 1px solid var(--gray-300);
  border-radius: 0.375rem;
  color: var(--gray-700);
  cursor: pointer;
  display: inline-flex;
  flex: 0 0 2.55rem;
  justify-content: center;
  min-height: 2.55rem;
  padding: 0;
}

.date-picker-button svg {
  height: 1.05rem;
  width: 1.05rem;
}

.date-picker-button:hover {
  background: var(--gray-100);
  border-color: var(--gray-400);
  color: var(--primary-dark);
}

.date-picker-button:focus-visible {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
  outline: none;
}

.line-items-table .date-field-with-picker {
  gap: 0.2rem;
}

.line-items-table .date-picker-button {
  flex-basis: 2rem;
  min-height: 2rem;
}

/* Toggle Labels for checkboxes */
.toggle-label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  cursor: pointer;
  font-weight: normal;
}

.toggle-label input[type="checkbox"] {
  /* !important is required to survive the checkbox sizing guard at the end of this file.
     That guard neutralises width/padding on checkboxes because ~20 containers apply
     text-input sizing to them; this rule is the opposite case - a DELIBERATE size for a
     touch-friendly toggle. Any future intentional checkbox sizing needs !important for
     the same reason; bin/check-control-alignment.mjs explains the arrangement. */
  width: 1.25rem !important;
  height: 1.25rem !important;
  cursor: pointer;
  accent-color: var(--primary);
}

.toggle-label span {
  color: var(--gray-700);
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  padding: 0 1rem;
  font-size: 0.875rem;
  font-weight: 500;
  text-align: center;
  text-decoration: none;
  border: 1px solid transparent;
  border-radius: var(--button-radius);
  cursor: pointer;
  line-height: 1.2;
  min-height: var(--button-height);
  position: relative;
  user-select: none;
  vertical-align: middle;
  white-space: nowrap;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.42),
    inset 0 -1px 0 rgba(0,0,0,0.10),
    0 3px 6px rgba(17,24,39,0.18),
    0 1px 2px rgba(17,24,39,0.12);
  transition:
    background-color 0.12s ease, border-color 0.12s ease,
    box-shadow 0.10s ease, color 0.12s ease,
    transform 0.10s cubic-bezier(0.2, 0, 0.4, 1);
}

.btn:hover {
  transform: translateY(-1px);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.48),
    inset 0 -1px 0 rgba(0,0,0,0.12),
    0 5px 10px rgba(17,24,39,0.22),
    0 2px 4px rgba(17,24,39,0.14);
}

.btn:active {
  transform: translateY(2px);
  box-shadow:
    inset 0 2px 6px rgba(17,24,39,0.22),
    inset 0 1px 2px rgba(17,24,39,0.16),
    0 1px 1px rgba(17,24,39,0.10);
  transition:
    box-shadow 0.05s ease,
    transform 0.05s cubic-bezier(0.4, 0, 1, 1);
}

.btn:focus-visible {
  /* WCAG 1.4.11 asks 3:1 for a focus indicator. The previous value, rgba(37,99,235,0.22),
     composites to #cfddfb on white = 1.36:1 — present in the stylesheet and invisible on screen.
     Full-opacity --primary is 5.17:1, and because it is a token the high-contrast theme raises it
     to 11.2:1 automatically rather than needing a second rule. */
  outline: 3px solid var(--primary);
  outline-offset: 2px;
}

.btn[aria-pressed="true"],
.btn[aria-current="true"],
.btn.is-active,
.btn[data-active="true"] {
  border-color: var(--primary);
  box-shadow: inset 0 0 0 2px rgba(37,99,235,0.25), 0 2px 5px rgba(37,99,235,0.18);
}

.btn[aria-busy="true"],
.btn.is-loading,
.btn[data-loading="true"] {
  cursor: wait;
  opacity: 0.86;
  pointer-events: none;
}

.btn[aria-busy="true"]::after,
.btn.is-loading::after,
.btn[data-loading="true"]::after {
  animation: btn-affirmation-spin 0.7s linear infinite;
  border: 2px solid currentColor;
  border-radius: 999px;
  border-right-color: transparent;
  content: "";
  height: 0.9em;
  width: 0.9em;
}

.btn.is-success,
.btn[data-affirmation="success"] {
  border-color: var(--success);
  box-shadow: inset 0 0 0 2px rgba(22,163,74,0.24), 0 2px 5px rgba(22,163,74,0.18);
}

.btn.is-danger-confirm,
.btn[data-affirmation="danger"] {
  border-color: var(--danger);
  box-shadow: inset 0 0 0 2px rgba(220,38,38,0.22), 0 2px 5px rgba(220,38,38,0.16);
}

@keyframes btn-affirmation-spin {
  to {
    transform: rotate(360deg);
  }
}

.btn:disabled,
.btn[disabled] {
  cursor: not-allowed;
  opacity: 0.7;
  transform: none;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.2);
}

.btn-primary {
  background: linear-gradient(#3b82f6, var(--primary));
  border-color: #1d4ed8;
  color: white;
}

.btn-block {
  width: 100%;
}

.btn-primary:hover {
  background: linear-gradient(#2563eb, var(--primary-dark));
}

.btn-primary:active {
  background: linear-gradient(#1d4ed8, #1e40af);
}

.btn-primary:disabled {
  background: var(--gray-300);
  border-color: var(--gray-300);
}

.btn-secondary {
  background: linear-gradient(#ffffff, var(--gray-200));
  border-color: var(--gray-300);
  color: var(--gray-700);
}

.btn-secondary:hover {
  background: linear-gradient(var(--gray-50), var(--gray-300));
}

.btn-secondary:active {
  background: linear-gradient(var(--gray-200), var(--gray-300));
}

.btn-danger {
  background: linear-gradient(#ef4444, var(--danger));
  border-color: #b91c1c;
  color: white;
}

.btn-danger:hover {
  background: linear-gradient(#dc2626, #b91c1c);
}

.btn-danger:active {
  background: linear-gradient(#b91c1c, #991b1b);
}

/* Yellow, for a button that needs attention without reading as destructive (red) or as the
   one obvious next step (blue). Dark text, not white: white on amber fails contrast at this
   weight, and these labels have to be readable across a board of 20 cards. */
.btn-warning {
  background: linear-gradient(#fbbf24, #f59e0b);
  border-color: #b45309;
  color: #422006;
}

.btn-warning:hover {
  background: linear-gradient(#f59e0b, #d97706);
}

.btn-warning:active {
  background: linear-gradient(#d97706, #b45309);
}

.btn-sm {
  padding: 0 0.65rem;
  font-size: 0.78rem;
  min-height: var(--button-height-sm);
}

.btn-icon {
  aspect-ratio: 1;
  padding: 0;
  width: var(--button-height);
}

.btn-sm.btn-icon,
.btn-small.btn-icon {
  width: var(--button-height-sm);
}

.btn-group,
.header-actions,
.form-actions,
.modal-actions,
.table-actions,
.card-actions,
.page-actions,
.bulk-actions,
.testing-actions,
.verify-actions,
.posting-actions,
.claims-dashboard-bulk-actions,
.claim-data-correction-actions,
.claims-summary-actions,
.chart-item-actions,
.chart-row-actions,
.insurance-actions,
.portal-access-actions,
.uat-screenshot-actions,
.kanban-detail-actions,
.pre-review-context-actions,
.actions,
[class$="-actions"],
[class*="-actions "],
.action-buttons,
.btn-row,
.button-row,
[class$="-buttons"],
[class*="-buttons "],
[class$="-toolbar"],
[class*="-toolbar "] {
  --action-button-font-size: 0.875rem;
  --action-button-min-height: var(--button-height);
  --action-button-padding: 0 1rem;
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: var(--button-gap);
}

.btn-group .btn,
.header-actions .btn,
.form-actions .btn,
.modal-actions .btn,
.table-actions .btn,
.card-actions .btn,
.page-actions .btn,
.bulk-actions .btn,
.testing-actions .btn,
.verify-actions .btn,
.posting-actions .btn,
.claims-dashboard-bulk-actions .btn,
.claim-data-correction-actions .btn,
.claims-summary-actions .btn,
.chart-item-actions .btn,
.chart-row-actions .btn,
.insurance-actions .btn,
.portal-access-actions .btn,
.uat-screenshot-actions .btn,
.kanban-detail-actions .btn,
.pre-review-context-actions .btn,
.actions .btn,
[class$="-actions"] .btn,
[class*="-actions "] .btn,
.action-buttons .btn,
.btn-row .btn,
.button-row .btn,
[class$="-buttons"] .btn,
[class*="-buttons "] .btn,
[class$="-toolbar"] .btn,
[class*="-toolbar "] .btn {
  font-size: var(--action-button-font-size, 0.875rem) !important;
  margin-left: 0 !important;
  min-height: var(--action-button-min-height, var(--button-height)) !important;
  padding: var(--action-button-padding, 0 1rem) !important;
  /* Proximity sizing: buttons grouped together grow to equal width so adjacent
     and stacked buttons match instead of each sizing to its own label.
     min-width keeps labels from truncating; lone buttons (:only-child) keep
     their natural width and do not stretch full-width. */
  flex: 1 1 0 !important;
  min-width: max-content;
}

.btn-group .btn:only-child,
.header-actions .btn:only-child,
.form-actions .btn:only-child,
.modal-actions .btn:only-child,
.table-actions .btn:only-child,
.card-actions .btn:only-child,
.page-actions .btn:only-child,
.bulk-actions .btn:only-child,
.testing-actions .btn:only-child,
.verify-actions .btn:only-child,
.posting-actions .btn:only-child,
.claims-dashboard-bulk-actions .btn:only-child,
.claim-data-correction-actions .btn:only-child,
.claims-summary-actions .btn:only-child,
.chart-item-actions .btn:only-child,
.chart-row-actions .btn:only-child,
.insurance-actions .btn:only-child,
.portal-access-actions .btn:only-child,
.uat-screenshot-actions .btn:only-child,
.kanban-detail-actions .btn:only-child,
.pre-review-context-actions .btn:only-child,
.actions .btn:only-child,
[class$="-actions"] .btn:only-child,
[class*="-actions "] .btn:only-child,
.action-buttons .btn:only-child,
.btn-row .btn:only-child,
.button-row .btn:only-child,
[class$="-buttons"] .btn:only-child,
[class*="-buttons "] .btn:only-child,
[class$="-toolbar"] .btn:only-child,
[class*="-toolbar "] .btn:only-child {
  flex: 0 1 auto !important;
}

.btn-group > button:not(.btn),
.header-actions > button:not(.btn),
.form-actions > button:not(.btn),
.modal-actions > button:not(.btn),
.table-actions > button:not(.btn),
.card-actions > button:not(.btn),
.page-actions > button:not(.btn),
.bulk-actions > button:not(.btn),
.testing-actions > button:not(.btn),
.verify-actions > button:not(.btn),
.posting-actions > button:not(.btn),
.claims-dashboard-bulk-actions > button:not(.btn),
.claim-data-correction-actions > button:not(.btn),
.claims-summary-actions > button:not(.btn),
.chart-item-actions > button:not(.btn),
.chart-row-actions > button:not(.btn),
.insurance-actions > button:not(.btn),
.portal-access-actions > button:not(.btn),
.uat-screenshot-actions > button:not(.btn),
.kanban-detail-actions > button:not(.btn),
.pre-review-context-actions > button:not(.btn),
.actions > button:not(.btn),
[class$="-actions"] > button:not(.btn),
[class*="-actions "] > button:not(.btn),
.action-buttons > button:not(.btn),
.btn-row > button:not(.btn),
.button-row > button:not(.btn),
[class$="-buttons"] > button:not(.btn),
[class*="-buttons "] > button:not(.btn),
[class$="-toolbar"] > button:not(.btn),
[class*="-toolbar "] > button:not(.btn),
[class$="-actions"] > a:not(.btn),
[class*="-actions "] > a:not(.btn),
.action-buttons > a:not(.btn),
.btn-row > a:not(.btn),
.button-row > a:not(.btn),
[class$="-buttons"] > a:not(.btn),
[class*="-buttons "] > a:not(.btn),
[class$="-toolbar"] > a:not(.btn),
[class*="-toolbar "] > a:not(.btn) {
  align-items: center;
  cursor: pointer;
  display: inline-flex;
  font-size: var(--action-button-font-size, 0.875rem) !important;
  justify-content: center;
  line-height: 1.2;
  margin-left: 0 !important;
  min-height: var(--action-button-min-height, var(--button-height)) !important;
  padding: var(--action-button-padding, 0 1rem) !important;
  text-align: center;
  text-decoration: none;
  white-space: nowrap;
}

.data-table td.actions,
td.actions,
.uat-row-actions {
  --action-button-font-size: 0.78rem;
  --action-button-min-height: var(--button-height-sm);
  --action-button-padding: 0 0.65rem;
  align-items: center;
  justify-content: flex-start;
  white-space: normal;
}

.data-table td.actions .btn,
td.actions .btn,
.uat-row-actions .btn {
  flex: 0 0 auto;
}

.page-header > div:last-child,
.page-header .header-actions,
.page-header .page-actions {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: var(--button-gap);
  justify-content: flex-end;
}

/* Alerts */
.alert {
  padding: 0.75rem 1rem;
  border-radius: 0.375rem;
  margin-bottom: 1rem;
  display: none;
}

.alert.show {
  display: flex;
}

.alert-dismissible {
  align-items: flex-start;
  gap: 0.75rem;
}

.alert-message {
  flex: 1;
}

.alert-close {
  appearance: none;
  background: transparent;
  border: 0;
  color: currentColor;
  cursor: pointer;
  flex: 0 0 auto;
  font-size: 1.25rem;
  font-weight: 700;
  line-height: 1;
  opacity: 0.7;
  padding: 0 0.125rem;
}

.alert-close:hover,
.alert-close:focus {
  opacity: 1;
}

.alert-error {
  background: #fef2f2;
  color: var(--danger-on-tint);
  border: 1px solid #fecaca;
}

.alert-success {
  background: #f0fdf4;
  color: var(--success-on-tint);
  border: 1px solid #bbf7d0;
}

.alert-warning {
  background: #fffbeb;
  color: var(--warning-on-tint);
  border: 1px solid #fde68a;
}

.alert-info {
  background: #eff6ff;
  color: var(--primary-dark);
  border: 1px solid #bfdbfe;
}

/* Links */
.auth-links {
  text-align: center;
  margin-top: 1rem;
  font-size: 0.875rem;
}

.auth-links a {
  color: var(--primary);
  text-decoration: none;
}

.auth-links a:hover {
  text-decoration: underline;
}

/* App Layout */
.app-container {
  display: flex;
  min-height: 100vh;
}

:root {
  --sidebar-width-expanded: 232px;
  --sidebar-width-collapsed: 48px;
  --sidebar-bg: #ffffff;
  --sidebar-border: #d0d5dd;
  --sidebar-rule: #e4e7ec;
  --sidebar-brand: #111827;
  --sidebar-text: #344054;
  --sidebar-zone-text: #182230;
  --sidebar-subtext: #475467;
  --sidebar-muted: #667085;
  --sidebar-hover-bg: #f1f5f9;
  --sidebar-hover-text: #111827;
  --sidebar-active-bg: #eaf2ff;
  --sidebar-active-text: #174ea6;
  --sidebar-accent: #2563eb;
  --sidebar-control-bg: #f8fafc;
  --sidebar-control-border: #d0d5dd;
  --sidebar-scrollbar-track: #f1f5f9;
  --sidebar-scrollbar-thumb: #cbd5e1;
  --sidebar-text-muted: #667085;
}

.sidebar {
  width: var(--sidebar-width-expanded);
  background: var(--sidebar-bg);
  border-right: 1px solid var(--sidebar-border);
  box-shadow: 1px 0 8px rgba(15, 23, 42, 0.06);
  color: var(--sidebar-text);
  position: fixed;
  top: 0;
  left: 0;
  /* 100vh on iOS Safari includes the browser chrome, so a fixed 100vh
     sidebar runs past the visible viewport and its bottom items are cut
     off. 100dvh (dynamic viewport height) sizes to the actually-visible
     area; the 100vh line is the fallback for browsers without dvh. */
  height: 100vh;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  font-size: 0.8rem;
  transition: width 0.18s ease;
  overflow-x: hidden;
  z-index: 200;
}

.sidebar.collapsed {
  width: var(--sidebar-width-collapsed);
  overflow: visible;
}

.sidebar-header {
  padding: 0.5rem 0.75rem;
  border-bottom: 1px solid var(--sidebar-rule);
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.25rem;
}

.sidebar.collapsed .sidebar-header {
  padding: 0.5rem 0.25rem;
  justify-content: center;
}

.sidebar-toggle {
  background: var(--sidebar-control-bg);
  border: 1px solid var(--sidebar-control-border);
  color: var(--sidebar-muted);
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 3px;
  cursor: pointer;
  padding: 0;
  flex-shrink: 0;
}

.sidebar-toggle:hover {
  background: var(--sidebar-hover-bg);
  color: var(--sidebar-hover-text);
}

.sidebar-toggle .toggle-icon-expand { display: none; }
.sidebar.collapsed .sidebar-toggle .toggle-icon-collapse { display: none; }
.sidebar.collapsed .sidebar-toggle .toggle-icon-expand { display: inline-block; }

.sidebar-nav {
  flex: 1;
  /* min-height: 0 lets this flex child shrink below its content size so
     overflow-y actually scrolls; without it the nav grows to fit every
     menu item, pushing the lower items and the user footer off-screen. */
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 0.25rem 0;
  scrollbar-color: var(--sidebar-scrollbar-thumb) var(--sidebar-scrollbar-track);
  scrollbar-width: auto;
}

/* Custom scrollbar for sidebar */
.sidebar-nav::-webkit-scrollbar {
  width: 12px;
}

.sidebar-nav::-webkit-scrollbar-track {
  background: var(--sidebar-scrollbar-track);
}

.sidebar-nav::-webkit-scrollbar-thumb {
  background: var(--sidebar-scrollbar-thumb);
  border-radius: 6px;
}

.sidebar-nav::-webkit-scrollbar-thumb:hover {
  background: var(--sidebar-muted);
}

/* Labeled dividers size to their label; the separator rule is a border on
   the label itself so a 1px box can't clip a taller text child. */
.sidebar-divider {
  margin: 0.3rem 0.5rem 0.05rem;
}

/* Empty (label-less) dividers render as a plain 1px rule. */
.sidebar-divider:empty {
  height: 1px;
  background: var(--sidebar-rule);
  margin: 0.15rem 0.5rem;
}

.sidebar-divider span {
  display: block;
  font-size: 0.6rem;
  text-transform: uppercase;
  color: var(--sidebar-muted);
  padding: 0.3rem 0 0.1rem;
  letter-spacing: 0.03em;
  border-top: 1px solid var(--sidebar-rule);
}

.sidebar-header h1 {
  font-size: 0.9rem;
  color: var(--sidebar-brand);
  margin: 0;
}

.sidebar-command {
  margin: 0.5rem 0.6rem 0.35rem;
  border: 1px solid var(--sidebar-control-border);
  border-radius: 6px;
  background: var(--sidebar-control-bg);
  color: var(--sidebar-text);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.45rem 0.55rem;
  font-size: 0.72rem;
  text-align: left;
}

.sidebar-command:hover,
.sidebar-command:focus {
  border-color: #93c5fd;
  background: #eef4ff;
  color: var(--sidebar-active-text);
  /* Was `outline: none`. Measured, the remaining signals were 1.22:1 (border vs unfocused border),
     1.63:1 (border vs new background) and 1.10:1 (background vs page) — NOT ONE reached the 3:1 that
     WCAG 1.4.11 asks of a focus indicator. This is primary navigation, so a keyboard user had no way
     to see where they were. offset -2px keeps the ring inside the narrow rail rather than clipped. */
  outline: 2px solid var(--sidebar-accent);
  outline-offset: -2px;
}

.sidebar-command kbd {
  border: 1px solid var(--sidebar-control-border);
  border-radius: 4px;
  color: var(--sidebar-muted);
  font-size: 0.62rem;
  padding: 0.08rem 0.28rem;
}

.sidebar-expansion-controls {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.25rem;
  margin: 0 0.6rem 0.35rem;
}

.sidebar-expansion-controls button {
  border: 1px solid var(--sidebar-control-border);
  border-radius: 5px;
  background: var(--sidebar-control-bg);
  color: var(--sidebar-muted);
  cursor: pointer;
  font-size: 0.66rem;
  line-height: 1.2;
  padding: 0.3rem 0.35rem;
}

.sidebar-expansion-controls button:hover,
.sidebar-expansion-controls button:focus {
  border-color: #93c5fd;
  background: #eef4ff;
  color: var(--sidebar-active-text);
  /* Same measurement as .sidebar-command:focus above — no signal reached 3:1. */
  outline: 2px solid var(--sidebar-accent);
  outline-offset: -2px;
}

.sidebar-zone {
  margin: 0.15rem 0.35rem;
  position: relative;
}

.sidebar-zone-button,
.sidebar-nav a {
  display: flex;
  align-items: center;
  width: 100%;
  border: 0;
  border-radius: 5px;
  background: transparent;
  padding: 0.32rem 0.45rem;
  color: var(--sidebar-zone-text);
  text-decoration: none;
  transition: background-color 0.15s;
  font-size: 0.76rem;
  line-height: 1.2;
  cursor: pointer;
  text-align: left;
}

.sidebar-zone-button:hover,
.sidebar-zone-button:focus,
.sidebar-nav a:hover {
  background: var(--sidebar-hover-bg);
  color: var(--sidebar-hover-text);
  outline: none;
}

.sidebar-zone.active > .sidebar-zone-button {
  background: var(--sidebar-active-bg);
  color: var(--sidebar-active-text);
  box-shadow: inset 3px 0 0 var(--sidebar-accent);
  font-weight: 700;
}

.sidebar-nav a.sidebar-item.active,
.sidebar-zone-panel .sidebar-item.active,
.sidebar-flyout .sidebar-item.active {
  background: var(--sidebar-active-bg);
  color: var(--sidebar-active-text);
  font-weight: 600;
  box-shadow: inset 3px 0 0 var(--sidebar-accent);
  outline: none;
}

.sidebar-nav a.sidebar-item.active:hover,
.sidebar-zone-panel .sidebar-item.active:hover {
  background: var(--sidebar-active-bg);
  color: var(--sidebar-active-text);
}

.sidebar-zone-button svg,
.sidebar-nav a svg {
  margin-right: 0.35rem;
  width: 13px;
  height: 13px;
  flex-shrink: 0;
}

.sidebar-zone-chevron {
  margin-left: auto;
  transform: rotate(90deg);
  transition: transform 0.16s ease;
}

.sidebar-zone-button[aria-expanded="false"] .sidebar-zone-chevron {
  transform: rotate(0deg);
}

.sidebar-zone-panel {
  display: grid;
  gap: 0.05rem;
  padding: 0.08rem 0 0.16rem 1rem;
}

.sidebar-zone-panel[hidden] {
  display: none;
}

.sidebar-zone-panel .sidebar-item {
  color: var(--sidebar-subtext);
  font-size: 0.72rem;
  padding: 0.28rem 0.45rem;
}

/* WCAG 2.5.8 Target Size (Minimum), Level AA — 24x24 CSS px.
   Measured on the served build: every visible .sidebar-item rendered at 277x23 — ONE PIXEL short,
   in the primary navigation of every page. 0.72rem text plus 2 x 0.28rem padding lands at 23.
   Verified: under-24 count 7 -> 0 on rbac-admin and 14 -> 0 on cf-editor, sidebar box unchanged
   at 232x900, and no horizontal overflow introduced on either page. */
.sidebar-item {
  min-height: 24px;
}

.sidebar-flyout {
  display: none;
}

.sidebar-flyout-title {
  color: var(--sidebar-muted);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 0.35rem 0.55rem;
  text-transform: uppercase;
}

/* Collapsed mode: hide text labels, center icons, hide divider category labels */
.sidebar.collapsed .sidebar-label,
.sidebar.collapsed .sidebar-divider span {
  display: none;
}

.sidebar.collapsed .sidebar-command {
  display: none;
}

.sidebar.collapsed .sidebar-expansion-controls {
  display: none;
}

.sidebar.collapsed .sidebar-zone {
  margin: 0.2rem 0.3rem;
}

.sidebar.collapsed .sidebar-zone-button {
  justify-content: center;
  padding: 0.42rem 0.25rem;
}

.sidebar.collapsed .sidebar-zone-button,
.sidebar.collapsed .sidebar-nav a {
  justify-content: center;
  padding: 0.35rem 0.25rem;
}

.sidebar.collapsed .sidebar-zone-panel {
  display: none;
}

.sidebar.collapsed .sidebar-flyout.flyout-open {
  background: white;
  border: 1px solid var(--gray-200);
  border-radius: 8px;
  box-shadow: 0 14px 30px rgba(15, 23, 42, 0.18);
  display: block;
  left: calc(var(--sidebar-width-collapsed) + 8px);
  min-width: 220px;
  padding: 0.35rem;
  position: fixed;
  z-index: 500;
}

.sidebar.collapsed .sidebar-flyout .sidebar-item {
  color: var(--sidebar-text);
  justify-content: flex-start;
  padding: 0.45rem 0.55rem;
}

.sidebar.collapsed .sidebar-flyout .sidebar-item.active,
.sidebar.collapsed .sidebar-flyout .sidebar-item:hover {
  background: var(--sidebar-active-bg);
  color: var(--sidebar-active-text);
}

.sidebar.collapsed .sidebar-flyout .sidebar-label {
  display: inline;
}

.sidebar.collapsed .sidebar-nav a svg {
  margin-right: 0;
  width: 14px;
  height: 14px;
}

.sidebar.collapsed .sidebar-divider {
  margin: 0.25rem 0.5rem;
}

.sidebar.collapsed .sidebar-user {
  padding: 0.4rem 0.25rem;
  text-align: center;
}

.main-content {
  flex: 1;
  margin-left: var(--sidebar-width-expanded);
  padding: 1.5rem;
  padding-bottom: 3rem;
  min-height: 100vh;
  overflow-y: auto;
  transition: margin-left 0.18s ease;
}

body.sidebar-collapsed .main-content {
  margin-left: var(--sidebar-width-collapsed);
}

/* Header */
.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 1.5rem;
}

.page-header h2 {
  font-size: 1.5rem;
}

/* Page Version Badge */
.page-version-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-left: auto;
  font-size: 0.7rem;
  font-weight: normal;
  vertical-align: middle;
  white-space: nowrap;
}

.page-version-badge .page-id {
  background: #111827;
  color: white;
  padding: 0.22rem 0.48rem;
  border-radius: 3px;
  font-family: monospace;
  font-size: 0.65rem;
  font-weight: 800;
  letter-spacing: 0;
}

.page-version-badge .app-version {
  color: var(--gray-500);
  font-size: 0.65rem;
  font-family: monospace;
}

.page-version-badge .biz-date {
  color: var(--gray-600);
  font-size: 0.65rem;
  padding: 0.15rem 0.4rem;
  border-radius: 3px;
  background: var(--gray-100, #f1f5f9);
  font-family: monospace;
}
.page-version-badge .biz-date-override {
  background: #fef3c7;
  color: #92400e;
  font-weight: 600;
}

.sidebar-usage-date {
  background: #f8fafc;
  border: 1px solid var(--sidebar-control-border);
  border-radius: 6px;
  color: var(--sidebar-text-muted, #667085);
  font-size: 0.68rem;
  font-weight: 700;
  margin-bottom: 0.55rem;
  padding: 0.35rem 0.45rem;
}

.sidebar-usage-date.test-date-active {
  background: #fffbeb;
  border-color: #fbbf24;
  color: #92400e;
}

/* Deploy version for login page */
.deploy-version {
  position: fixed;
  bottom: 1rem;
  right: 1rem;
  font-size: 0.7rem;
  color: var(--gray-500);
  font-family: monospace;
  z-index: 100;
  background: rgba(255, 255, 255, 0.8);
  padding: 0.25rem 0.5rem;
  border-radius: 0.25rem;
}

/* Cards */
.card {
  background: white;
  border-radius: 0.5rem;
  box-shadow: 0 1px 3px rgba(0,0,0,0.1);
  padding: 1.5rem;
  margin-bottom: 1rem;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--gray-200);
}

/* Tables */
.table-container {
  overflow-x: auto;
  width: 100%;
}

table {
  width: 100%;
  border-collapse: collapse;
  table-layout: auto;
}

th, td {
  text-align: left;
  padding: 0.5rem 0.6rem;
  border-bottom: 1px solid var(--gray-200);
  font-size: 0.875rem;
  word-wrap: break-word;
  overflow-wrap: anywhere;
}

/* Worklist tables: tighten so 8-11 column tables fit common viewports without horizontal scroll */
.table-container table th,
.table-container table td {
  padding: 0.45rem 0.5rem;
  font-size: 0.82rem;
  vertical-align: top;
}
.table-container table td a {
  word-break: break-word;
}

th {
  font-weight: 600;
  color: var(--gray-700);
  background: var(--gray-50);
}

tr:hover {
  background: var(--gray-50);
}

/* Line Items Table (Services/Diagnoses) */
.line-items-table {
  font-size: 0.875rem;
  margin-bottom: 0.5rem;
}

.line-items-table th,
.line-items-table td {
  padding: 0.5rem 0.35rem;
  vertical-align: middle;
}

.line-items-table input[type="text"],
.line-items-table input[type="number"],
.line-items-table input[type="date"] {
  width: 100%;
  padding: 0.375rem 0.5rem;
  font-size: 0.8125rem;
  border: 1px solid var(--gray-300);
  border-radius: 0.25rem;
  min-width: 0;
}

.line-items-table input[type="text"]:focus,
.line-items-table input[type="number"]:focus,
.line-items-table input[type="date"]:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.1);
}

.line-items-table th.narrow,
.line-items-table td.narrow {
  width: 50px;
  text-align: center;
}

.line-items-table th.medium,
.line-items-table td.medium {
  width: 80px;
}

/* Specific column widths for services table */
.line-items-table td:nth-child(1) { width: 35px; text-align: center; }  /* # */
.line-items-table td:nth-child(2) { min-width: 100px; }  /* CPT/HCPCS */
.line-items-table td:nth-child(3),
.line-items-table td:nth-child(4),
.line-items-table td:nth-child(5),
.line-items-table td:nth-child(6) { width: 45px; }  /* M1-M4 */
.line-items-table td:nth-child(7) { width: 60px; }  /* DX Ptr */
.line-items-table td:nth-child(8) { width: 70px; }  /* Units */
.line-items-table td:nth-child(9) { width: 90px; }  /* Charge */
.line-items-table td:nth-child(10) { width: 50px; }  /* POS */
.line-items-table td:nth-child(11),
.line-items-table td:nth-child(12) { width: 120px; }  /* Dates */

/* Modal */
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0,0,0,0.5);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.modal-overlay.show,
.modal-overlay.active {
  display: flex;
}

.modal {
  background: white;
  border-radius: 0.5rem;
  padding: 1.5rem;
  width: 100%;
  max-width: 500px;
  max-height: 90vh;
  overflow-y: auto;
  overflow-x: hidden;
  box-sizing: border-box;
}

.modal * { box-sizing: border-box; }
.modal .form-group { min-width: 0; }
.modal .form-group input,
.modal .form-group select,
.modal .form-group textarea {
  width: 100%;
  box-sizing: border-box;
  min-width: 0;
}
.modal .table-container { overflow-x: auto; }
.modal pre { max-width: 100%; white-space: pre-wrap; word-break: break-word; }

.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1rem;
}

.modal-header h3 {
  font-size: 1.25rem;
}

.modal-close {
  background: none;
  border: none;
  font-size: 1.5rem;
  cursor: pointer;
  color: var(--gray-500);
}

.modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  margin-top: 1.5rem;
  padding-top: 1rem;
  border-top: 1px solid var(--gray-200);
}

/* Stats */
.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1rem;
  margin-bottom: 1.5rem;
}

.stat-card {
  background: white;
  border-radius: 0.5rem;
  padding: 1.25rem;
  box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}

.stat-card h3 {
  font-size: 0.875rem;
  color: var(--gray-500);
  margin-bottom: 0.25rem;
}

.stat-card .value {
  font-size: 1.5rem;
  font-weight: 600;
}

.reports-grid {
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)) !important;
}

/* Loading */
.loading {
  display: inline-block;
  width: 20px;
  height: 20px;
  border: 2px solid var(--gray-200);
  border-top-color: var(--primary);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

/* Responsive */
@media (max-width: 768px) {
  .app-container {
    display: block;
  }

  .sidebar {
    transform: translateX(-100%);
    transition: transform 0.3s;
    width: min(88vw, 320px);
    z-index: 350;
  }

  .sidebar.collapsed {
    width: min(88vw, 320px);
  }

  body.sidebar-mobile-open .sidebar {
    transform: translateX(0);
  }

  body.sidebar-mobile-open {
    overflow: hidden;
  }
  
  .main-content {
    margin-left: 0;
    padding: 4rem 1rem 2rem;
  }

  body.sidebar-collapsed .main-content {
    margin-left: 0;
  }

  .sidebar.collapsed .sidebar-label,
  .sidebar.collapsed .sidebar-divider span,
  .sidebar.collapsed .sidebar-flyout .sidebar-label {
    display: inline;
  }

  .sidebar.collapsed .sidebar-command {
    display: flex;
  }

  .sidebar.collapsed .sidebar-zone-panel {
    display: grid;
  }

  .sidebar.collapsed .sidebar-zone-panel[hidden] {
    display: none;
  }

  .sidebar.collapsed .sidebar-zone-button,
  .sidebar.collapsed .sidebar-nav a {
    justify-content: flex-start;
    padding: 0.42rem 0.45rem;
  }

  .sidebar.collapsed .sidebar-nav a svg,
  .sidebar.collapsed .sidebar-zone-button svg {
    margin-right: 0.35rem;
  }

  .page-header {
    align-items: flex-start;
    flex-direction: column;
    gap: 0.75rem;
  }

  .page-header > div:last-child,
  .page-header .header-actions,
  .page-header .page-actions {
    justify-content: flex-start;
    width: 100%;
  }

  .page-version-badge {
    margin-left: 0;
    white-space: normal;
  }
}

.mobile-sidebar-button {
  align-items: center;
  background: var(--sidebar-bg);
  border: 1px solid var(--sidebar-border);
  border-radius: 7px;
  box-shadow: 0 8px 18px rgba(15, 23, 42, 0.18);
  cursor: pointer;
  display: none;
  flex-direction: column;
  gap: 4px;
  height: 38px;
  justify-content: center;
  left: 0.75rem;
  position: fixed;
  top: 0.75rem;
  width: 38px;
  z-index: 360;
}

.mobile-sidebar-button span {
  background: var(--sidebar-brand);
  border-radius: 99px;
  height: 2px;
  width: 17px;
}

.sidebar-backdrop {
  background: rgba(15, 23, 42, 0.45);
  border: 0;
  display: none;
  inset: 0;
  position: fixed;
  z-index: 340;
}

body.sidebar-mobile-open .sidebar-backdrop {
  display: block;
}

.command-palette {
  align-items: flex-start;
  background: rgba(15, 23, 42, 0.42);
  display: flex;
  inset: 0;
  justify-content: center;
  padding-top: 12vh;
  position: fixed;
  z-index: 700;
}

.command-palette-panel {
  background: white;
  border: 1px solid var(--gray-200);
  border-radius: 10px;
  box-shadow: 0 24px 60px rgba(15, 23, 42, 0.25);
  max-width: calc(100vw - 2rem);
  overflow: hidden;
  width: 560px;
}

.command-palette-search {
  align-items: center;
  border-bottom: 1px solid var(--gray-200);
  display: flex;
  gap: 0.5rem;
  padding: 0.75rem;
}

.command-palette-search input {
  border: 0;
  flex: 1;
  font-size: 1rem;
  outline: none;
}

/* The rule above sets `border: 0` AND `outline: none` on the BASE style, not on a focus state, so this
   input had no focus indicator at ANY time — measured 0.00:1, the only control in the sheet with
   literally nothing. Every other `outline: none` here is paired with a border change that clears 3:1;
   this one had no replacement at all. Restoring an indicator on focus only, so the borderless look the
   design intends is preserved until the user is actually in the field. */
.command-palette-search input:focus {
  outline: 2px solid var(--primary);
  outline-offset: -2px;
}

.command-palette-search button {
  background: var(--gray-100);
  border: 1px solid var(--gray-200);
  border-radius: 5px;
  color: var(--gray-600);
  cursor: pointer;
  height: 28px;
  width: 28px;
}

.command-palette-hint {
  background: var(--gray-50);
  border-bottom: 1px solid var(--gray-200);
  color: var(--gray-500);
  font-size: 0.75rem;
  padding: 0.45rem 0.85rem;
}

.command-palette-results {
  max-height: 420px;
  overflow-y: auto;
  padding: 0.35rem;
}

.command-result {
  align-items: center;
  border-radius: 7px;
  color: var(--gray-800);
  display: flex;
  gap: 0.65rem;
  padding: 0.55rem 0.65rem;
  text-decoration: none;
}

.command-result:hover,
.command-result:focus,
.command-result.active {
  background: var(--gray-100);
  outline: none;
}

.command-result.active svg {
  color: var(--primary);
}

.command-result svg {
  color: var(--gray-500);
  flex: 0 0 auto;
  height: 16px;
  width: 16px;
}

.command-result span {
  display: grid;
  gap: 0.05rem;
  min-width: 0;
}

.command-result strong,
.command-result small {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.command-result small {
  color: var(--gray-500);
  font-size: 0.72rem;
}

.command-empty {
  color: var(--gray-500);
  padding: 1rem;
  text-align: center;
}

@media (max-width: 768px) {
  .mobile-sidebar-button {
    display: inline-flex;
  }

  .command-palette {
    padding: 4.5rem 0.75rem 0;
  }
}

/* User info in sidebar */
.sidebar-user {
  padding: 0.4rem 0.5rem;
  border-top: 1px solid var(--sidebar-rule);
  flex-shrink: 0;
  background: var(--sidebar-bg);
}

.sidebar-user .user-name {
  color: var(--sidebar-brand);
  font-weight: 500;
  font-size: 0.7rem;
}

.sidebar-user .user-email {
  font-size: 0.6rem;
  color: var(--sidebar-muted);
}

.sidebar-user .logout-btn {
  margin-top: 0.25rem;
  display: block;
  color: #b42318;
  text-decoration: none;
  font-size: 0.65rem;
  /* WCAG 2.5.8 target size. MEASURED on served build local.20260902.1113: this was the LAST
     crowded target left in the UI at 303x16 ("Sign out", rbac-admin + cf-editor). At 0.65rem with
     no padding the block collapsed to 16px tall. The earlier .sidebar-item { min-height: 24px }
     fix could not reach it — different class, so a rule keyed on the nav item never applied.
     line-height carries the height rather than padding so the single line stays centred and the
     collapsed-sidebar rules (which hide .sidebar-label) are untouched. */
  min-height: 24px;
  line-height: 24px;
}

.sidebar-user .logout-btn:hover {
  color: #7a271a;
}

/* WCAG 2.5.8 target size — `.field-hint` was an UNDEFINED CLASS.
   It is applied to four controls in kanban.html and had no rule anywhere in the stylesheet, so those
   controls fell back to browser defaults: the horizon <select> and the days <input> measured 154x19
   and 150x19 on served build local.20260902.1840 — both crowded, both under the 24px floor.
   min-height only ever GROWS a control, so this cannot shrink anything that already passes.
   FOUND BY WIDENING THE PAGE SET: my 2.5.8 run defaults to four pages and reported 0 crowded; adding
   five more pages (475 -> 696 targets) surfaced these two. A default page list is not a population. */
.field-hint {
  min-height: 24px;
}

/* Search */
.search-box {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

.search-box input {
  flex: 1;
}

/* Badge */
.badge {
  display: inline-block;
  padding: 0.125rem 0.5rem;
  font-size: 0.75rem;
  font-weight: 500;
  border-radius: 9999px;
}

.badge-success {
  background: #dcfce7;
  color: var(--success);
}

.badge-warning {
  background: #fef3c7;
  color: var(--warning);
}

.badge-danger {
  background: #fee2e2;
  color: var(--danger);
}

.badge-info {
  background: #dbeafe;
  color: var(--primary);
}

/* Practice Selector */
.practice-selector {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.practice-selector label {
  font-size: 0.875rem;
  color: var(--gray-500);
  font-weight: 500;
}

.practice-dropdown {
  padding: 0.5rem 2rem 0.5rem 0.75rem;
  font-size: 0.875rem;
  border: 1px solid var(--gray-300);
  border-radius: 0.375rem;
  background: white;
  color: var(--gray-800);
  cursor: pointer;
  min-width: 200px;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%236b7280' d='M3 5l3 3 3-3'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.75rem center;
}

.practice-dropdown:hover {
  border-color: var(--gray-500);
}

.practice-dropdown:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
}

/* Active row highlight */
tr.active-row {
  background: #eff6ff;
}

tr.active-row:hover {
  background: #dbeafe;
}

/* Status badges */
.status-badge {
  display: inline-block;
  padding: 0.25rem 0.75rem;
  font-size: 0.75rem;
  font-weight: 600;
  border-radius: 9999px;
  text-transform: uppercase;
}

.status-active {
  background: #dcfce7;
  color: var(--success);
}

.status-inactive {
  background: var(--gray-200);
  color: var(--gray-500);
}

/* Small button variant */
.btn-small {
  padding: 0 0.65rem;
  font-size: 0.78rem;
  min-height: var(--button-height-sm);
}

/* Coding lookup dropdown — used by ClinicalShared.attachCodingLookup on any page */
.coding-lookup-results {
  background: var(--white, #fff);
  border: 1px solid var(--gray-200, #e2e8f0);
  border-radius: 7px;
  box-shadow: 0 10px 24px rgba(15,23,42,0.14);
  display: none;
  left: 0;
  max-height: min(260px, 42vh);
  overflow: auto;
  position: absolute;
  right: 0;
  top: calc(100% + 4px);
  z-index: 200;
}
.coding-lookup-results.dropup {
  bottom: calc(100% + 4px);
  top: auto;
}
.coding-lookup-results.active { display: block; }
.coding-lookup-row {
  align-items: flex-start;
  background: none;
  border: none;
  border-bottom: 1px solid var(--gray-100, #f1f5f9);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding: 0.55rem 0.75rem;
  text-align: left;
  width: 100%;
}
.coding-lookup-row:hover, .coding-lookup-row:focus { background: var(--gray-50, #f8fafc); }
.coding-lookup-row strong { font-size: 0.875rem; }
.coding-lookup-row span { color: var(--gray-700, #374151); font-size: 0.8rem; }
.coding-lookup-row em { color: var(--gray-500, #64748b); font-size: 0.7rem; font-style: normal; }
.coding-lookup-empty { color: var(--gray-500, #64748b); font-size: 0.8rem; padding: 0.65rem; }

/* ============================================================================
   CHECKBOX / RADIO SIZING GUARD  (AgentCF 2026-07-27)
   Founder screenshot: on the Clinical Screenings section every checkbox floated
   mid-column with its text pushed onto the next line.
   Cause: 20 different containers across the app carry a `<container> input {
   width:100% }` rule intended for text inputs. It also matches checkboxes and
   radios, stretching the control to the full column so its glyph centres and the
   following text wraps. A stretched checkbox is never wanted, anywhere.
   Those rules live in per-page <style> blocks that load AFTER this file, so the
   guard needs !important to reach them; it is safe because a grep of every
   stylesheet found NO page that deliberately sizes a checkbox or radio.
   Fixes the CF section grids plus payers.html and claims.html, which had the
   same latent defect.
   ========================================================================== */
   The width was only part of it. The GLOBAL `.form-group input` rule in this same
   file (width:100% + padding:0.625rem 0.75rem + 1px border) is written for text
   inputs and matches every checkbox in every .form-group app-wide, so the control
   was also being padded and bordered like a text box. Reset all three; the native
   control draws itself. `flex:none` stops it stretching inside a flex label. */
input[type="checkbox"], input[type="radio"] {
  width: auto !important;
  height: auto;
  padding: 0 !important;
  flex: none;
}

/* A <label> that CONTAINS its own control is an inline control, not a field
   caption, so it must not inherit the small bold caption styling that grid
   layouts apply to `.form-group label`. Alignment is already correct without
   this (the width guard above does that); this restores readable text and
   vertical centring. :has() is progressive enhancement - where it is
   unsupported the layout is still right, just styled as a caption. */
.form-group label:has(> input[type="checkbox"]),
.form-group label:has(> input[type="radio"]) {
  display: flex; align-items: center; gap: 0.45rem;
  font-size: 0.875rem; font-weight: 400; color: var(--gray-700, #374151);
  margin-bottom: 0; cursor: pointer;
}

/* ── CF runtime rendering (moved from cf.html, AgentUI 2026-07-27) ──────────────
   cf-runtime.js emits .cf-page / .cf-section-grid markup, but these rules lived INLINE in
   cf.html and were duplicated in cf-editor.html. Any NEW host of the shared runtime silently
   lost the layout: the portal CF intake rendered every field stacked in one column, because
   .cf-section-grid had no display:grid — the runtime sets grid-template-columns inline and
   assumes the host supplies the rest. A shared runtime must not depend on each host
   remembering to copy its CSS.                                                            */
.cf-status { display:inline-block; padding:0.1rem 0.5rem; border-radius:999px; font-size:0.72rem; font-weight:600; background:var(--gray-100,#f3f4f6); color:var(--gray-700,#374151); text-transform:capitalize; }
.cf-status.signed, .cf-status.checked_out, .cf-status.billed, .cf-status.active { background:#dcfce7; color:#14532d; }
.cf-status.in_progress, .cf-status.intake_in_progress, .cf-status.draft { background:#fef9c3; color:#854d0e; }
.cf-status.ready_for_provider, .cf-status.intake_complete { background:#dbeafe; color:#1e40af; }
.cf-view { display:none; }
.cf-view.active { display:block; }
.cf-tabs { display:flex; flex-wrap:wrap; row-gap:0.15rem; gap:0; border-bottom:2px solid var(--gray-200,#e5e7eb); margin-bottom:1.25rem; min-width:0; max-width:100%; }
.cf-tab { background:none; border:none; border-bottom:3px solid transparent; color:var(--gray-600,#6b7280); cursor:pointer; font-size:0.875rem; font-weight:600; margin-bottom:-2px; padding:0.6rem 1.1rem; white-space:nowrap; }
.cf-tab:hover { color:var(--primary,#2563eb); }
.cf-tab.active { border-bottom-color:var(--primary,#2563eb); color:var(--primary,#2563eb); }
.cf-page { display:none; }
.cf-page.active { display:block; }
.cf-section-grid { display:grid; gap:0.75rem 1rem; }
.cf-section-grid .form-group { margin:0; }
.cf-section-grid .form-group label { font-size:0.78rem; color:var(--gray-600,#6b7280); font-weight:600; margin-bottom:0.2rem; display:block; }
.cf-section-grid input:not([type=checkbox]):not([type=radio]), .cf-section-grid select, .cf-section-grid textarea { width:100%; box-sizing:border-box; }
.cf-range-track { display:flex; align-items:center; gap:0.6rem; }
.cf-range-track input[type=range] { flex:1; }
.cf-range-track output { min-width:2rem; text-align:center; font-weight:700; }
.cf-config-badge { font-size:0.72rem; color:var(--gray-500,#9ca3af); }
.cf-typeahead { position:relative; }
.cf-typeahead-panel { display:none; position:absolute; top:100%; left:0; right:0; z-index:40; background:#fff; border:1px solid var(--gray-200,#e5e7eb); border-radius:8px; box-shadow:0 6px 18px rgba(15,23,42,0.12); max-height:260px; overflow:auto; }
.cf-typeahead-panel.active { display:block; }
.cf-typeahead-row { display:block; width:100%; text-align:left; background:none; border:none; border-bottom:1px solid var(--gray-100,#f3f4f6); padding:0.45rem 0.6rem; font-size:0.82rem; cursor:pointer; }
.cf-typeahead-row:hover { background:var(--surface-2,#f5f8ff); }
.cf-typeahead-empty { padding:0.45rem 0.6rem; font-size:0.8rem; color:var(--gray-500,#9ca3af); }
.cf-computed { background:var(--gray-50,#f9fafb); font-weight:600; text-align:center; }
.cf-readonly { background:var(--gray-50,#f9fafb); color:var(--gray-700,#374151); } /* review fields: left-aligned, normal weight — like a normal field, non-editable */
.cf-toolbar { display:flex; gap:0.6rem; align-items:center; flex-wrap:wrap; margin-bottom:0.75rem; }
.cf-muted { color:var(--gray-500,#9ca3af); font-size:0.8rem; }


/* Checkbox rows: one left-aligned box column, wrapped label text beside it (AgentUI 2026-07-28).
   MEASURED, after two wrong guesses: the box was rendering 780px WIDE and squeezing the consent
   text into a 59px column at the far right — which is what "the checkboxes should be aligned to
   the left" actually described, and it also made the consents page 2.1 screens tall.
   The app-wide `input[type=checkbox] { width: auto !important }` guard is not enough here: `auto`
   on a block-level flex item fills the line. The box needs an EXPLICIT width, and the text needs
   to be the element that flexes. */
.cf-check { display: flex; align-items: flex-start; gap: .5rem; line-height: 1.4; }
.cf-check input[type="checkbox"] {
  width: 1rem !important;
  height: 1rem;
  flex: 0 0 1rem;
  margin: .18rem 0 0;
}
.cf-check > span { flex: 1 1 auto; min-width: 0; }

/* copyFrom control — a small inline action on the field's own label, e.g. "Same as patient". */
.cf-copyfrom {
  margin-left: .5rem; padding: .1rem .45rem; font-size: .72rem; font-weight: 600;
  color: var(--primary, #2563eb); background: var(--surface-2, #eef2ff);
  border: 1px solid var(--border, #c7d2fe); border-radius: 4px; cursor: pointer; vertical-align: middle;
}
.cf-copyfrom:hover { background: var(--primary, #2563eb); color: #fff; }

/* medicationSearchList: catalog typeahead results (AgentUI 2026-07-28). */
.cf-msl-results {
  position: absolute; top: 100%; left: 0; right: 0; z-index: 40; margin-top: 2px;
  max-height: 260px; overflow-y: auto; background: var(--surface, #fff);
  border: 1px solid var(--border, #d1d5db); border-radius: 6px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .12);
}
.cf-msl-option {
  display: block; width: 100%; text-align: left; padding: .45rem .6rem;
  font-size: .85rem; line-height: 1.35; background: none; border: none;
  border-bottom: 1px solid var(--border-light, #f1f5f9); cursor: pointer; color: var(--text, #111);
}
.cf-msl-option:last-child { border-bottom: none; }
.cf-msl-option:hover, .cf-msl-option:focus { background: var(--surface-2, #eef2ff); }

/* ---------------------------------------------------------------------------
   INPUT HINTS ARE BLUE, NOT GREY.
   Founder 2026-08-04: "the fields that have input examples which are light gray,
   that's hard to distinguish from actual data. Make all the defaulted hints blue
   throughout all screens."

   styles.css is loaded by 75 of the 85 UI pages and had NO placeholder rule at all, so
   every hint fell back to the browser default - a grey close enough to entered text that a
   clinician cannot tell an example from a real value at a glance. On a clinical screen that
   is a safety question, not a styling preference.

   Deliberately softer than --primary (#2563eb): a hint rendered in full link-blue reads as
   an entered value or something clickable. This is unmistakably blue and unmistakably not
   data. Change it here and it changes everywhere.

   opacity:1 is required - Firefox applies its own opacity to placeholders and would
   re-grey this.
   --------------------------------------------------------------------------- */
:root {
  --input-hint: #4a7fd4;
}

input::placeholder,
textarea::placeholder,
select::placeholder,
.form-control::placeholder,
[contenteditable][data-placeholder]::before {
  color: var(--input-hint);
  opacity: 1;
}

input::-webkit-input-placeholder,
textarea::-webkit-input-placeholder { color: var(--input-hint); opacity: 1; }

input::-moz-placeholder,
textarea::-moz-placeholder { color: var(--input-hint); opacity: 1; }

input:-ms-input-placeholder,
textarea:-ms-input-placeholder { color: var(--input-hint); opacity: 1; }

/* THE WAY TO THE BOARD IS ALWAYS LIGHT GREEN (founder 2026-08-06: "I want all Kanban buttons to
   be light green. And none in the top row next to the practice dropdown."). One selector covers
   every static link to the board across all screens; the runtime adds .btn-kanban to buttons it
   renders (definition-driven detail actions labelled Kanban, the EncounterCF list button).
   Light green = navigation to the board, everywhere — and never in a page-header. */
a.btn[href*="/ui/kanban.html"],
.btn-kanban {
  background: #dcfce7;
  border-color: #86efac;
  color: #166534;
}
a.btn[href*="/ui/kanban.html"]:hover,
.btn-kanban:hover {
  background: #bbf7d0;
  border-color: #4ade80;
  color: #14532d;
}


/* ============================================================================
 * HIGH CONTRAST — the legacy palette's half of the accommodation
 * ----------------------------------------------------------------------------
 * css/themes/high-contrast.css overrides 91 tokens in the DESIGN SYSTEM vocabulary
 * (--color-text-primary, --color-surface, ...). This sheet reads a different one
 * (--gray-700, --white, --primary), and the measured overlap between them is FIVE
 * tokens, all --sidebar-*. So on the 87 pages that load only this file, selecting
 * high contrast changed nothing at all.
 *
 * Linking the theme file here would NOT have fixed that: it would produce a toggle
 * that visibly engages and changes nothing, which is harder to discover than an
 * honest absence. The overrides have to name tokens this sheet actually reads.
 *
 * Values are COMPUTED, not chosen by eye:
 *   text          >= 7:1  (WCAG 1.4.6 AAA, which the theme's own header claims)
 *   UI borders    >= 3:1  (WCAG 1.4.11 non-text contrast)
 *   surfaces      exempt  (they are the background the ratios are measured against)
 * 32 of 32 tokens clear their applicable threshold; the check lives in
 * bin/prove-theme-reaches-the-page.mjs, which must go from 0 changed properties to
 * non-zero on login/register/forgot-password/reset-password.
 *
 * Keyed on BOTH selectors the design system uses, so one signal switches both
 * vocabularies and they can never disagree about whether the theme is on.
 * ========================================================================== */
[data-theme="high-contrast"],
.theme-high-contrast {
  /* surfaces — subtle fills flatten to the page background */
  --gray-50: #ffffff;
  --gray-100: #ffffff;
  --sidebar-bg: #ffffff;
  --sidebar-control-bg: #ffffff;

  /* borders — a hairline that is actually visible (4.5:1), structure in pure black */
  --gray-200: #767676;
  --gray-300: #000000;
  --gray-400: #000000;
  --sidebar-border: #000000;
  --sidebar-rule: #000000;
  --sidebar-control-border: #000000;

  /* text — every grey collapses to black (21:1) */
  --gray-500: #000000;
  --gray-600: #000000;
  --gray-700: #000000;
  --gray-800: #000000;
  --gray-900: #000000;
  --sidebar-text: #000000;
  --sidebar-text-muted: #000000;
  --sidebar-subtext: #000000;
  --sidebar-muted: #000000;
  --sidebar-brand: #000000;
  --sidebar-zone-text: #000000;
  --sidebar-hover-text: #000000;

  /* accents and status — darkened only as far as 7:1 requires, so they stay
     DISTINGUISHABLE from body text and from each other rather than all going black */
  --primary: #0000cc;        /* 11.2:1 */
  --primary-dark: #000099;   /* 14.4:1 */
  --sidebar-accent: #0000cc; /* 11.2:1 */
  --input-hint: #000099;     /* 14.4:1 */
  --danger: #a10000;         /*  8.3:1 */
  --danger-on-tint: #a10000;   /* 7.63:1 on the alert tint */
  --warning-on-tint: #7a4100;  /* 7.84:1 */
  --success-on-tint: #006622;  /* 6.86:1 */
  --success: #006622;        /*  7.2:1 — green is the weakest colour at AA */
  --warning: #7a4100;        /*  8.1:1 */

  /* interaction states must remain PERCEPTIBLE, not merely compliant */
  --sidebar-hover-bg: #e0e0e0;
  --sidebar-active-bg: #000099;
  --sidebar-active-text: #ffffff;  /* 14.4:1 on the inverted row */
}


/* ============================================================================
 * HIGH CONTRAST — honouring the OPERATING SYSTEM preference
 * ----------------------------------------------------------------------------
 * A user who has already asked their OS for more contrast should not also have to
 * find a toggle. css/themes/high-contrast.css honours prefers-contrast; this sheet
 * did not, so on the 87 pages that load only styles.css the preference was ignored.
 *
 * An explicit theme choice beats the system default — but only for a theme this sheet can
 * actually DELIVER.
 *
 * ⛔ CORRECTED 2026-08-31. This was scoped `:root:not([data-theme])`, i.e. suppressed by ANY
 * explicit choice. Measured: styles.css has ZERO dark rules, so a user who chose dark got a
 * light page AND lost this accommodation — data-theme="dark" suppressed the query while
 * delivering nothing. Suppressing an accommodation in favour of a theme that renders nothing
 * leaves the user with neither, which is strictly worse than either.
 *
 * Now suppressed only by the two themes this sheet implements: light (the default appearance,
 * an explicit request for it) and high-contrast (the block above already applies it). A choice
 * this sheet cannot render no longer costs the user their operating system accommodation.
 *
 * ⚠ These declarations MIRROR the block above. A media query cannot be added to a
 * selector list, so they must appear twice. They were GENERATED from that block, and
 * prove-theme-reaches-the-page.mjs asserts the two declare the same 32 tokens —
 * if they ever diverge, that check fails rather than the drift going unnoticed.
 * ========================================================================== */
@media (prefers-contrast: more) {
  :root:not([data-theme="light"]):not([data-theme="high-contrast"]) {
    /* surfaces — subtle fills flatten to the page background */
    --gray-50: #ffffff;
    --gray-100: #ffffff;
    --sidebar-bg: #ffffff;
    --sidebar-control-bg: #ffffff;
  
    /* borders — a hairline that is actually visible (4.5:1), structure in pure black */
    --gray-200: #767676;
    --gray-300: #000000;
    --gray-400: #000000;
    --sidebar-border: #000000;
    --sidebar-rule: #000000;
    --sidebar-control-border: #000000;
  
    /* text — every grey collapses to black (21:1) */
    --gray-500: #000000;
    --gray-600: #000000;
    --gray-700: #000000;
    --gray-800: #000000;
    --gray-900: #000000;
    --sidebar-text: #000000;
    --sidebar-text-muted: #000000;
    --sidebar-subtext: #000000;
    --sidebar-muted: #000000;
    --sidebar-brand: #000000;
    --sidebar-zone-text: #000000;
    --sidebar-hover-text: #000000;
  
    /* accents and status — darkened only as far as 7:1 requires, so they stay
       DISTINGUISHABLE from body text and from each other rather than all going black */
    --primary: #0000cc;        /* 11.2:1 */
    --primary-dark: #000099;   /* 14.4:1 */
    --sidebar-accent: #0000cc; /* 11.2:1 */
    --input-hint: #000099;     /* 14.4:1 */
    --danger: #a10000;         /*  8.3:1 */
    --danger-on-tint: #a10000;   /* 7.63:1 on the alert tint */
    --warning-on-tint: #7a4100;  /* 7.84:1 */
    --success-on-tint: #006622;  /* 6.86:1 */
    --success: #006622;        /*  7.2:1 — green is the weakest colour at AA */
    --warning: #7a4100;        /*  8.1:1 */
  
    /* interaction states must remain PERCEPTIBLE, not merely compliant */
    --sidebar-hover-bg: #e0e0e0;
    --sidebar-active-bg: #000099;
    --sidebar-active-text: #ffffff;  /* 14.4:1 on the inverted row */
  }
}

/* Flashing / pulsing animation for unsaved collection entry button (e.g. Add Diagnosis) */
@keyframes cf-btn-flash {
  0% {
    box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.7);
    transform: scale(1);
  }
  50% {
    box-shadow: 0 0 0 7px rgba(16, 185, 129, 0.15);
    transform: scale(1.03);
    filter: brightness(1.15);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(16, 185, 129, 0);
    transform: scale(1);
  }
}

.cf-btn-flash {
  animation: cf-btn-flash 1.1s infinite ease-in-out !important;
  font-weight: 700 !important;
  border-color: #059669 !important;
}
