/*
 * Design tokens — single source of truth for color, spacing, radius,
 * shadow, typography and motion across the whole app. Every stylesheet in
 * the app should read from these custom properties rather than introducing
 * new magic numbers or one-off colors.
 *
 * Milestone 22 (mobile responsiveness): the app uses a single mobile-first
 * breakpoint at 600px (`@media (max-width: 600px)`), applied here and in
 * styles.css/ScheduleGrid.css. 600px sits comfortably above both target
 * phone widths (375px iPhone SE, 414px larger phones) with margin, while
 * staying well below tablet widths (768px+) where this app's desktop-style
 * layouts still read fine. The Electron shell's window has a hard
 * `minWidth: 960` (src/main/index.ts, unchanged), so it can never cross this
 * breakpoint — the rules below are inert there and only ever apply to the
 * web/PWA at phone width. A literal 600px is used directly in each media
 * query (custom properties aren't usable as media-query values).
 */

:root {
  /* ---- Neutral scale (warm slate) — light mode ---- */
  --gray-0: #ffffff;
  --gray-50: #faf6f0;
  --gray-100: #f1ece3;
  --gray-200: #e4dcd0;
  --gray-300: #d3c7b7;
  --gray-400: #ac9f8f;
  --gray-500: #8a7d6f;
  --gray-600: #6b6058;
  --gray-700: #4d443c;
  --gray-800: #362f29;
  --gray-900: #2b2420;

  /* ---- Amber accent scale — light mode ---- */
  --amber-50: #fdf2e3;
  --amber-100: #fbe4c2;
  --amber-300: #eab160;
  --amber-500: #d97706;
  --amber-600: #b45309;
  --amber-700: #92400e;

  /* ---- Semantic surfaces ---- */
  --color-bg: var(--gray-50);
  --color-surface: var(--gray-0);
  --color-surface-muted: var(--gray-100);
  --color-surface-raised: var(--gray-0);
  --color-text: var(--gray-900);
  --color-text-muted: var(--gray-600);
  --color-text-subtle: var(--gray-500);
  --color-border: var(--gray-200);
  --color-border-strong: var(--gray-300);

  /* ---- Accent (brand) ---- */
  --color-accent-subtle: var(--amber-50);
  --color-accent-muted: var(--amber-100);
  --color-accent: var(--amber-600);
  --color-accent-hover: var(--amber-700);
  --color-accent-active: var(--amber-700);
  --color-accent-contrast: #ffffff;
  --color-accent-text: var(--amber-700);

  /* ---- Semantic status colors (used consistently for success/warning/danger states) ---- */
  --color-success: #1e7a34;
  --color-success-bg: #e4f5e6;
  --color-success-border: #bfe4c4;

  --color-warning: #92620a;
  --color-warning-bg: #fbeecb;
  --color-warning-border: #f0d999;

  --color-danger: #b3261e;
  --color-danger-bg: #fbeceb;
  --color-danger-border: #f3c6c2;

  /* ---- Spacing scale ---- */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-7: 32px;
  --space-8: 40px;

  /* ---- Radius ---- */
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 16px;
  --radius-pill: 999px;
  /* Subtle corner rounding for the frameless main window itself (applied to
     #root below) — Windows 10 doesn't round frameless windows the way
     Windows 11 does, so the app clips its own corners in CSS. Deliberately
     small/subtle, distinct from the card-level --radius-lg. */
  --radius-window: 8px;

  /* ---- Shadow ---- */
  --shadow-xs: 0 1px 2px rgba(30, 20, 10, 0.06);
  --shadow-sm: 0 1px 3px rgba(30, 20, 10, 0.08);
  --shadow-md: 0 6px 20px rgba(30, 20, 10, 0.12);
  --shadow-lg: 0 16px 40px rgba(30, 20, 10, 0.18);

  /* ---- Typography ---- */
  --font-sans: 'Segoe UI', system-ui, -apple-system, sans-serif;
  --text-xs: 0.72rem;
  --text-sm: 0.85rem;
  --text-base: 0.95rem;
  --text-lg: 1.1rem;
  --text-xl: 1.35rem;
  --text-2xl: 1.7rem;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;

  /* ---- Motion ---- */
  --transition-fast: 130ms;
  --transition-base: 180ms;
  --transition-slow: 240ms;
  --ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
  --ease-emphasized: cubic-bezier(0.2, 0, 0, 1);

  /* ---- Focus ring ---- */
  --focus-ring-color: var(--amber-600);
  --focus-ring: 0 0 0 3px var(--color-accent-subtle), 0 0 0 1px var(--focus-ring-color);
}

:root[data-theme='dark'] {
  /* ---- Neutral scale — dark mode ----
     Milestone 11: re-anchored to the Mt Hood Lanes logo's deep forest green
     (sampled from the logo artwork as #19362b) rather than the generic warm
     slate used in earlier milestones. Hue drifts gradually from that forest
     green (~160°) at the dark/structural end of the scale toward the logo's
     cream/tan (~42°, sampled as #e0ccac) at the light/text end, so body text
     reads as a warm brand-appropriate cream instead of a flat off-white,
     while backgrounds/surfaces/borders read as a desaturated, sophisticated
     green-charcoal rather than a literal green wash. */
  --gray-0: #1b2823;
  --gray-50: #121c19;
  --gray-100: #24332c;
  --gray-200: #304138;
  --gray-300: #405446;
  --gray-400: #63735e;
  --gray-500: #8c957e;
  --gray-600: #b5b7a4;
  --gray-700: #ceccbb;
  --gray-800: #e2ded4;
  --gray-900: #f1efe9;

  /* ---- Amber/accent scale — dark mode ----
     Milestone 11: re-derived from the logo's brick-red/brown (sampled as
     #713025) rather than the earlier amber-on-black placeholder. The base
     brick hue is too dark/low-contrast to use verbatim as an interactive
     accent on a near-black background, so it's brightened and lifted for
     the mid/high steps (600/700) that carry buttons, links, active-tab
     text and the focus ring, while the low steps (50/100) stay dark, warm
     chip tints for subtle accent backgrounds. Variable names are unchanged
     (still --amber-*) since components only ever reference the semantic
     --color-accent-* tokens below, never the scale directly. */
  --amber-50: #32201a;
  --amber-100: #442a22;
  --amber-300: #cc8066;
  --amber-500: #ce5b3b;
  --amber-600: #b1492f;
  --amber-700: #d8775a;

  --color-bg: var(--gray-50);
  --color-surface: var(--gray-0);
  --color-surface-muted: var(--gray-100);
  --color-surface-raised: #202f29;
  --color-text: var(--gray-900);
  --color-text-muted: var(--gray-600);
  --color-text-subtle: var(--gray-500);
  --color-border: var(--gray-200);
  --color-border-strong: var(--gray-300);

  --color-accent-subtle: var(--amber-50);
  --color-accent-muted: var(--amber-100);
  --color-accent: var(--amber-600);
  --color-accent-hover: var(--amber-700);
  --color-accent-active: var(--amber-700);
  --color-accent-contrast: var(--gray-900);
  --color-accent-text: var(--amber-700);

  --color-success: #7fce93;
  --color-success-bg: #21351f;
  --color-success-border: #375a34;

  --color-warning: #f0c766;
  --color-warning-bg: #3a2e15;
  --color-warning-border: #5c4a20;

  --color-danger: #f2b8b5;
  --color-danger-bg: #3a2320;
  --color-danger-border: #5c332d;

  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.35);
  --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 6px 20px rgba(0, 0, 0, 0.45);
  --shadow-lg: 0 16px 40px rgba(0, 0, 0, 0.55);

  --focus-ring-color: var(--amber-700);
  --focus-ring: 0 0 0 3px var(--color-accent-subtle), 0 0 0 1px var(--focus-ring-color);
}

* {
  box-sizing: border-box;
}

html,
body,
#root {
  height: 100%;
}

body {
  margin: 0;
  /* Plain web/PWA default: a normal filled page background. The Electron
     shell overrides this to transparent below, since ITS window itself is
     transparent (see src/main/index.ts) so the corners #root clips show the
     desktop through, not a black/white rectangle. */
  background-color: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: 1.45;
  transition: color var(--transition-base) var(--ease-standard);
  /* Safety net, not a layout crutch: every horizontally-wide element in the
     app (the schedule grid, data tables) owns its own overflow-x:auto
     scroll container, so the page itself should never need to scroll
     sideways. This just guards against any stray 1px rounding/overflow
     rather than relying on it to hide a real layout bug. */
  overflow-x: hidden;
}

/* `is-electron-shell` is added to <body> at boot only when `window.api` is
   present (see main.tsx) — i.e. only inside the real Electron desktop app,
   never on the web/PWA, which has no window frame to fake rounded corners
   or transparency for. */
body.is-electron-shell {
  background-color: transparent;
}

#root {
  background-color: var(--color-bg);
  transition: background-color var(--transition-base) var(--ease-standard);
}

body.is-electron-shell #root {
  /* Visually rounds the frameless window's corners by clipping #root to the
     window bounds — see --radius-window. The window itself is transparent,
     so the four corner slivers outside this radius show the desktop behind
     the app rather than a hard-edged rectangle. */
  overflow: hidden;
  border-radius: var(--radius-window);
}

/* Consistent, visible keyboard focus everywhere — no component should rely
   on the browser default outline or suppress it without a replacement. */
:focus {
  outline: none;
}

:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
  border-radius: var(--radius-sm);
}

/* Respect the user's reduced-motion preference: collapse every transition
   and animation to effectively instant rather than removing the state
   change itself. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}
/* ==========================================================================
   Layout shells: whole-window wrapper + title bar, boot loading screen,
   auth screens, app shell/nav, page content container.
   ========================================================================== */

/*
 * Fills the frameless main window exactly (`#root` is clipped to the window
 * bounds with `overflow: hidden` + `border-radius` — see theme.css — to give
 * the illusion of rounded corners on Windows 10, which doesn't round
 * frameless windows itself the way Windows 11 does). `.title-bar` is a fixed
 * strip at the top; whatever renders below it (the loading screen, an auth
 * screen, or the authenticated app shell) takes the remaining height and
 * scrolls internally rather than growing past the window and being clipped.
 */
.app-window {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.title-bar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  height: 36px;
  padding: 0 var(--space-2) 0 var(--space-4);
  background: var(--color-surface-muted);
  border-bottom: 1px solid var(--color-border);
  /* The drag region that lets the frameless window be moved (and, natively,
     maximized on double-click) — see WindowControls.tsx for the no-drag
     carve-out that keeps the buttons themselves clickable. */
  -webkit-app-region: drag;
}

.title-bar-brand {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--text-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-muted);
  letter-spacing: 0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.title-bar-brand-mark {
  display: inline-flex;
  color: var(--color-accent);
  flex: 0 0 auto;
}

.window-controls {
  display: flex;
  align-items: stretch;
  gap: 2px;
  margin-left: auto;
  /* Carve this whole group back out of the title bar's drag region so the
     buttons stay clickable — see `.title-bar` above. */
  -webkit-app-region: no-drag;
}

.window-controls-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  border: none;
  background: transparent;
  color: var(--color-text-muted);
  cursor: pointer;
  transition:
    background-color var(--transition-fast) var(--ease-standard),
    color var(--transition-fast) var(--ease-standard);
}

.window-controls-btn:hover {
  background: var(--color-surface-raised);
  color: var(--color-text);
}

.window-controls-btn:focus-visible {
  outline: none;
  box-shadow: inset var(--focus-ring);
}

.window-controls-btn--close:hover {
  background: var(--color-danger);
  color: #fff;
}

.app-loading {
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  color: var(--color-text-muted);
}

.auth-screen {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-6);
  background:
    radial-gradient(circle at 15% 10%, var(--color-accent-subtle), transparent 45%), var(--color-bg);
}

.auth-card {
  width: 100%;
  max-width: 380px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: var(--space-7);
  display: flex;
  flex-direction: column;
  gap: 6px;
  animation: rise-in var(--transition-slow) var(--ease-emphasized);
}

.auth-card h1 {
  margin: 0 0 4px;
  font-size: var(--text-xl);
  letter-spacing: -0.01em;
}

.auth-logo {
  display: block;
  width: 100%;
  max-width: 200px;
  height: auto;
  margin: 0 auto var(--space-3);
}

/* Visually hidden but present for screen readers/document structure — see
   LoginPage.tsx's h1 for the current usage. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.auth-subtitle {
  margin: 0 0 var(--space-4);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}

.app-shell {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

/*
 * Milestone 22: `.app-nav` wraps two groups — `.app-nav-bar` (brand + the
 * mobile-only hamburger toggle) and `.app-nav-links` (every link, the theme
 * toggle, the user tag, logout). At desktop width both groups render as
 * `display: contents` — invisible to layout — so their children fall
 * straight into `.app-nav`'s own flex row exactly as before this
 * restructuring; the mobile breakpoint below turns them into a real
 * collapsible menu instead.
 */
.app-nav {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 2px;
  padding: var(--space-3) var(--space-5);
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  flex-wrap: wrap;
}

.app-nav-bar,
.app-nav-links {
  display: contents;
}

.app-nav-toggle {
  display: none;
}

.app-nav-brand {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: var(--font-weight-bold);
  margin-right: var(--space-5);
  color: var(--color-accent-text);
  font-size: var(--text-lg);
  letter-spacing: -0.01em;
  white-space: nowrap;
}

.app-nav-brand-mark {
  display: inline-block;
  width: 26px;
  height: 26px;
  object-fit: contain;
  flex: 0 0 auto;
}

.app-nav-link {
  padding: 8px 12px;
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
  text-decoration: none;
  font-size: var(--text-sm);
  font-weight: var(--font-weight-medium);
  transition:
    background-color var(--transition-fast) var(--ease-standard),
    color var(--transition-fast) var(--ease-standard);
}

.app-nav-link:hover {
  background: var(--color-surface-muted);
  color: var(--color-text);
}

.app-nav-link.active {
  background: var(--color-accent-subtle);
  color: var(--color-accent-text);
  font-weight: var(--font-weight-semibold);
}

.app-nav-spacer {
  flex: 1;
}

.app-nav-user {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  margin-right: var(--space-2);
  white-space: nowrap;
}

.app-content {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: var(--space-6);
  max-width: 1200px;
  width: 100%;
  margin: 0 auto;
  animation: fade-in var(--transition-slow) var(--ease-standard);
}

/* ==========================================================================
   Page scaffolding
   ========================================================================== */

.page h1 {
  margin-top: 0;
  font-size: var(--text-2xl);
  letter-spacing: -0.01em;
}

.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-5);
  gap: var(--space-3);
  flex-wrap: wrap;
}

.page-header h1 {
  margin-bottom: 0;
}

.section {
  margin-bottom: var(--space-5);
}

.section-top {
  margin-top: var(--space-5);
}

.form-top-gap {
  margin-top: var(--space-4);
}

.tag-inline-gap {
  margin-left: var(--space-2);
}

.error-tight {
  margin-top: var(--space-1);
}

.section-subtitle {
  color: var(--color-text-muted);
  margin: -6px 0 var(--space-4);
  font-size: var(--text-sm);
}

.card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-xs);
  padding: var(--space-5);
}

.card h2 {
  margin-top: 0;
  font-size: var(--text-lg);
}

/* ==========================================================================
   Forms
   ========================================================================== */

.field-label {
  display: block;
  font-size: var(--text-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
  margin-top: var(--space-3);
}

.text-input,
select.text-input,
textarea.text-input {
  display: block;
  width: 100%;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
  background: var(--color-bg);
  color: var(--color-text);
  font-family: inherit;
  font-size: var(--text-base);
  font-weight: 400;
  margin-top: 4px;
  transition:
    border-color var(--transition-fast) var(--ease-standard),
    box-shadow var(--transition-fast) var(--ease-standard);
}

.text-input::placeholder {
  color: var(--color-text-subtle);
}

.text-input:hover:not(:disabled) {
  border-color: var(--color-border-strong);
}

.text-input:focus-visible {
  border-color: var(--focus-ring-color);
}

.text-input:disabled {
  opacity: 0.65;
  cursor: not-allowed;
}

.checkbox-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-2);
  font-size: var(--text-base);
}

.checkbox-row input[type='checkbox'] {
  width: 16px;
  height: 16px;
  accent-color: var(--color-accent);
}

.form-grid {
  display: grid;
  gap: 2px;
}

.form-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-5);
}

.form-error {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--color-danger-bg);
  border: 1px solid var(--color-danger-border);
  color: var(--color-danger);
  padding: 9px 12px;
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  margin-bottom: var(--space-2);
  animation: rise-in var(--transition-base) var(--ease-standard);
}

.form-success {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--color-success-bg);
  border: 1px solid var(--color-success-border);
  color: var(--color-success);
  padding: 9px 12px;
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  margin-bottom: var(--space-2);
  animation: rise-in var(--transition-base) var(--ease-standard);
}

.color-swatch {
  display: inline-block;
  width: 20px;
  height: 20px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
  vertical-align: middle;
}

.color-input {
  display: block;
  width: 64px;
  height: 36px;
  padding: 2px;
  margin-top: 4px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
  background: var(--color-bg);
  cursor: pointer;
}

/* ==========================================================================
   Buttons
   ========================================================================== */

.btn {
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  padding: 9px 16px;
  font-size: var(--text-base);
  font-family: inherit;
  font-weight: var(--font-weight-semibold);
  cursor: pointer;
  background: var(--color-surface-muted);
  color: var(--color-text);
  transition:
    background-color var(--transition-fast) var(--ease-standard),
    border-color var(--transition-fast) var(--ease-standard),
    color var(--transition-fast) var(--ease-standard),
    transform var(--transition-fast) var(--ease-standard);
}

.btn:hover:not(:disabled) {
  background: var(--color-border);
}

.btn:active:not(:disabled) {
  transform: translateY(1px);
}

.btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.btn-primary {
  background: var(--color-accent);
  color: var(--color-accent-contrast);
}

.btn-primary:hover:not(:disabled) {
  background: var(--color-accent-hover);
}

.btn-link {
  background: none;
  border-color: transparent;
  color: var(--color-accent-text);
  padding: 5px 8px;
}

.btn-link:hover:not(:disabled) {
  background: var(--color-accent-subtle);
}

.btn-danger {
  background: var(--color-danger-bg);
  border-color: var(--color-danger-border);
  color: var(--color-danger);
}

.btn-danger:hover:not(:disabled) {
  background: var(--color-danger-border);
}

.btn-toggle {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  color: var(--color-text-muted);
}

.btn-toggle:hover:not(:disabled) {
  color: var(--color-text);
  border-color: var(--color-border-strong);
}

.btn-toggle.active {
  background: var(--color-accent);
  color: var(--color-accent-contrast);
  border-color: var(--color-accent);
}

.assign-mode-toggle {
  display: flex;
  gap: 6px;
  margin: var(--space-4) 0;
}

/* ==========================================================================
   Tables
   ========================================================================== */

table.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}

table.data-table th,
table.data-table td {
  text-align: left;
  padding: 10px 12px;
  border-bottom: 1px solid var(--color-border);
}

table.data-table th {
  color: var(--color-text-muted);
  font-weight: var(--font-weight-semibold);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

table.data-table tbody tr {
  transition: background-color var(--transition-fast) var(--ease-standard);
}

table.data-table tbody tr:hover {
  background: var(--color-surface-muted);
}

table.data-table tbody tr:last-child td {
  border-bottom: none;
}

/* ==========================================================================
   Tags / badges — semantic status colors reused everywhere a status is shown.
   ========================================================================== */

.tag {
  display: inline-flex;
  align-items: center;
  padding: 3px 9px;
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: var(--font-weight-semibold);
  background: var(--color-surface-muted);
  color: var(--color-text-muted);
  border: 1px solid transparent;
  white-space: nowrap;
}

.tag + .tag {
  margin-left: 4px;
}

.tag-accent {
  background: var(--color-accent-subtle);
  color: var(--color-accent-text);
  border-color: var(--color-accent-muted);
}

.tag-success {
  background: var(--color-success-bg);
  color: var(--color-success);
  border-color: var(--color-success-border);
}

.tag-warning {
  background: var(--color-warning-bg);
  color: var(--color-warning);
  border-color: var(--color-warning-border);
}

.tag-danger {
  background: var(--color-danger-bg);
  color: var(--color-danger);
  border-color: var(--color-danger-border);
}

.tag-salaried {
  background: var(--color-accent-subtle);
  color: var(--color-accent-text);
  border-color: var(--color-accent-muted);
}

.tag-inactive {
  background: var(--color-danger-bg);
  color: var(--color-danger);
  border-color: var(--color-danger-border);
}

.tag-timeoff {
  background: var(--color-danger-bg);
  color: var(--color-danger);
  border: 1px solid var(--color-danger-border);
  display: block;
  width: fit-content;
  margin-bottom: var(--space-2);
}

.tag-status-pending {
  background: var(--color-warning-bg);
  color: var(--color-warning);
  border-color: var(--color-warning-border);
}

.tag-status-approved {
  background: var(--color-success-bg);
  color: var(--color-success);
  border-color: var(--color-success-border);
}

.tag-status-denied {
  background: var(--color-danger-bg);
  color: var(--color-danger);
  border-color: var(--color-danger-border);
}

/* ==========================================================================
   Tabs (department tabs, time-off status filter)
   ========================================================================== */

.department-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  margin-bottom: var(--space-5);
  border-bottom: 1px solid var(--color-border);
}

.department-tab {
  position: relative;
  border: none;
  background: none;
  font-family: inherit;
  padding: 10px 18px;
  font-size: var(--text-base);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-muted);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  transition:
    color var(--transition-fast) var(--ease-standard),
    border-color var(--transition-fast) var(--ease-standard);
}

.department-tab:hover {
  color: var(--color-text);
}

.department-tab.active {
  color: var(--color-accent-text);
  border-bottom-color: var(--color-accent);
}

/* ==========================================================================
   Week navigator
   ========================================================================== */

.week-nav {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-bottom: var(--space-5);
}

.week-nav-label {
  font-weight: var(--font-weight-semibold);
  min-width: 190px;
  text-align: center;
}

/* ==========================================================================
   My Schedule — a single employee's read-only day-by-day week view.
   ========================================================================== */

.my-schedule-days {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-4);
}

.my-schedule-day {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.my-schedule-day-header {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 2px;
}

.my-schedule-day-label {
  font-weight: var(--font-weight-semibold);
  font-size: var(--text-base);
}

.my-schedule-status-tag {
  display: block;
  width: fit-content;
}

.my-schedule-off {
  color: var(--color-text-muted);
  font-size: var(--text-sm);
  margin: 0;
}

.my-schedule-shift {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.my-schedule-shift-department {
  font-size: var(--text-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Shift cards are read-only here (no assign/edit dialog behind them) —
   drop the clickable affordance the schedule board's interactive grid uses. */
.my-schedule-day .shift-card {
  cursor: default;
}

.my-schedule-day .shift-card:hover {
  box-shadow: var(--shadow-xs);
  transform: none;
  background: var(--color-surface);
}

/* ==========================================================================
   Modals — fade + rise transitions on open.
   ========================================================================== */

.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(20, 14, 8, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
  padding: var(--space-4);
  animation: fade-in var(--transition-base) var(--ease-standard);
}

.modal-card {
  width: 100%;
  max-width: 440px;
  max-height: 90vh;
  overflow-y: auto;
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: var(--space-6);
  animation: rise-in var(--transition-slow) var(--ease-emphasized);
}

.modal-card h2 {
  margin-top: 0;
  font-size: var(--text-lg);
}

.modal-subtitle {
  color: var(--color-text-muted);
  margin-top: -8px;
  font-size: var(--text-sm);
}

.shift-template-note {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.unavailability-panel {
  background: var(--color-warning-bg);
  color: var(--color-warning);
  border: 1px solid var(--color-warning-border);
  border-radius: var(--radius-md);
  padding: var(--space-3);
  font-size: var(--text-sm);
}

.unavailability-panel ul {
  margin: var(--space-1) 0 0;
  padding-left: var(--space-4);
}

/* ==========================================================================
   Template picker (assign-shift dialog)
   ========================================================================== */

.template-picker-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  max-height: 320px;
  overflow-y: auto;
}

.template-picker-option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  border: 1px solid var(--color-border);
  border-left: 4px solid var(--color-accent);
  border-radius: var(--radius-sm);
  background: var(--color-surface-muted);
  color: var(--color-text);
  padding: 10px 12px;
  font-size: var(--text-base);
  font-family: inherit;
  cursor: pointer;
  transition:
    background-color var(--transition-fast) var(--ease-standard),
    transform var(--transition-fast) var(--ease-standard);
}

.template-picker-option:hover:not(:disabled) {
  background: var(--color-accent-subtle);
}

.template-picker-option:active:not(:disabled) {
  transform: scale(0.99);
}

.template-picker-option:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.template-picker-time {
  color: var(--color-text-muted);
  font-size: var(--text-sm);
  white-space: nowrap;
  margin-left: var(--space-3);
}

.anchor-time-field {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3);
}

.custom-shift-form {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* ==========================================================================
   Empty / loading states — every list/page shows one of these instead of a
   raw "Loading..." text node or a silently blank container.
   ========================================================================== */

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-2);
  padding: var(--space-7) var(--space-4);
  color: var(--color-text-muted);
  animation: fade-in var(--transition-base) var(--ease-standard);
}

.empty-state-icon {
  display: inline-flex;
  line-height: 1;
  opacity: 0.75;
  color: var(--color-text-muted);
}

.empty-state-title {
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
  font-size: var(--text-base);
}

.empty-state-body {
  font-size: var(--text-sm);
  max-width: 360px;
}

.loading-state {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-5) var(--space-2);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}

.spinner {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 2px solid var(--color-border);
  border-top-color: var(--color-accent);
  animation: spin 0.7s linear infinite;
  flex-shrink: 0;
}

@media (prefers-reduced-motion: reduce) {
  .spinner {
    animation-duration: 1.4s;
  }
}

/* ==========================================================================
   Keyframes
   ========================================================================== */

@keyframes fade-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes rise-in {
  from {
    opacity: 0;
    transform: translateY(6px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

/* ==========================================================================
   Mobile responsiveness (Milestone 22) — single breakpoint at 600px, see the
   comment atop theme.css for why. Two concerns are handled here:
   (1) layout — employee-facing screens (auth, My Schedule, Request Time
   Off, the AppLayout nav) get real phone-width layouts instead of just
   "doesn't overflow"; manager-only admin pages get a lighter pass so tables
   and forms aren't actively broken; (2) iOS/touch: form control font-size
   is bumped to 16px (below that, iOS Safari auto-zooms the whole page on
   focus) and small interactive elements get a ~44px minimum touch target.
   The Electron shell's window can't shrink below 960px wide (see
   src/main/index.ts), so none of this ever applies there.
   ========================================================================== */

@media (max-width: 600px) {
  /* ---- iOS zoom-on-focus fix — every text input/select/textarea ---- */
  .text-input,
  select.text-input,
  textarea.text-input {
    font-size: 16px;
  }

  /* ---- Touch targets — buttons, links-as-buttons, nav items, tabs ---- */
  .btn,
  .btn-link,
  .app-nav-link,
  .department-tab {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
  }

  .btn-link {
    padding: 10px 12px;
  }

  .color-input {
    height: 44px;
  }

  input[type='checkbox'],
  input[type='radio'] {
    width: 20px;
    height: 20px;
  }

  .checkbox-row {
    min-height: 44px;
  }

  /* The "Closed" checkbox on the Store Hours admin table isn't wrapped in a
     label (see StoreHoursAdminPage.tsx's `.table-checkbox-tap`), so give its
     own wrapper a bigger tap area rather than relying on the ~20px box. */
  .table-checkbox-tap {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
  }

  /* ---- Page chrome — reclaim side padding for narrow viewports ---- */
  .app-content {
    padding: var(--space-4);
  }

  /* ---- AppLayout nav — a manager's full link set (7 items) stacked
     one-per-row would eat almost the entire phone viewport before any page
     content is visible, so collapse it behind a hamburger toggle instead:
     the brand bar always shows, the link list opens as a full-width
     dropdown only on demand. ---- */
  .app-nav {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 0;
  }

  .app-nav-bar,
  .app-nav-links.open {
    display: flex;
  }

  .app-nav-bar {
    align-items: center;
    justify-content: space-between;
    padding: var(--space-3) var(--space-4);
  }

  .app-nav-brand {
    margin: 0;
  }

  .app-nav-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    color: var(--color-text);
    cursor: pointer;
    flex: 0 0 auto;
  }

  .app-nav-toggle:hover {
    background: var(--color-surface-muted);
  }

  .app-nav-links {
    display: none;
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-1);
    padding: 0 var(--space-4) var(--space-3);
  }

  .app-nav-spacer {
    display: none;
  }

  .app-nav-link {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    width: 100%;
    box-sizing: border-box;
    padding: 12px var(--space-3);
  }

  .app-nav-user {
    margin: var(--space-2) 0 0;
  }

  .app-nav-links > .btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
  }

  /* ---- Auth screens (Login / First-run setup) ---- */
  .auth-screen {
    padding: var(--space-4);
  }

  .auth-card {
    padding: var(--space-5);
  }

  /* ---- Week navigator (My Schedule + Schedule Board) — the label's fixed
     min-width plus two buttons doesn't fit a phone width side by side, so
     put the label on its own full-width row and split the buttons evenly
     beneath it. ---- */
  .week-nav {
    flex-wrap: wrap;
    gap: var(--space-2);
  }

  .week-nav-label {
    order: -1;
    width: 100%;
    min-width: 0;
  }

  .week-nav .btn {
    flex: 1 1 0;
  }

  /* ---- Data tables (time-off/unavailability history, admin CRUD lists) —
     scroll horizontally within the table itself rather than forcing the
     whole page to scroll sideways, the same fallback pattern already used
     for the manager Schedule Board's grid. ---- */
  table.data-table {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  table.data-table th,
  table.data-table td {
    white-space: nowrap;
  }

  /* ---- Modals — reclaim padding at phone width ---- */
  .modal-overlay {
    padding: var(--space-3);
  }

  .modal-card {
    padding: var(--space-4);
  }
}

/* ==========================================================================
   PWA update toast (Milestone 23) — shown on the web/PWA build only, once a
   new deploy's service worker has taken over in the background (see
   src/renderer/src/pwa/pwaUpdate.ts). Fixed to the bottom of the viewport,
   centered, and deliberately small/quiet so it never blocks the app's own
   UI — a manager mid-edit on the Schedule Board should barely notice it
   until they choose to act on it.
   ========================================================================== */

.pwa-update-toast {
  position: fixed;
  left: 50%;
  bottom: var(--space-5);
  transform: translateX(-50%);
  z-index: 60;
  display: flex;
  align-items: center;
  gap: var(--space-4);
  max-width: calc(100vw - var(--space-6) * 2);
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface-raised);
  color: var(--color-text);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  animation: rise-in var(--transition-slow) var(--ease-emphasized);
}

.pwa-update-toast-message {
  font-size: var(--text-sm);
  font-weight: var(--font-weight-medium);
  white-space: nowrap;
}

.pwa-update-toast-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
}

.pwa-update-toast-refresh {
  padding: 6px 14px;
  font-size: var(--text-sm);
}

@media (max-width: 600px) {
  .pwa-update-toast {
    left: var(--space-4);
    right: var(--space-4);
    bottom: var(--space-4);
    transform: none;
    max-width: none;
    flex-wrap: wrap;
  }

  .pwa-update-toast-message {
    white-space: normal;
  }
}

/* ==========================================================================
   Print (Milestone 10) — the Schedule Board's "Print Schedule" button calls
   `window.print()` directly; there is no separate print-preview render. All
   interactive app chrome is hidden here so only PrintSchedule.tsx's
   purpose-built table (kept hidden on screen, shown here — see
   components/PrintSchedule/PrintSchedule.css) ends up on the page.
   ========================================================================== */

@media print {
  .title-bar,
  .app-nav,
  .page-header,
  .department-tabs,
  .week-nav,
  .overlap-banner,
  .schedule-grid-wrapper,
  .modal-overlay,
  .pwa-update-toast {
    display: none !important;
  }

  #root {
    overflow: visible !important;
    height: auto !important;
    border-radius: 0 !important;
    background: #fff !important;
  }

  body,
  .app-window,
  .app-shell,
  .app-content {
    height: auto !important;
    overflow: visible !important;
    background: #fff !important;
  }

  .app-content {
    padding: 0 !important;
    max-width: none !important;
    margin: 0 !important;
  }
}
/* ==========================================================================
   Card-based schedule grid — the core screen of the app. A CSS grid (not an
   HTML table) so each employee/day intersection reads as a comfortable
   card cell rather than a cramped spreadsheet cell, while still supporting
   proper grid semantics (role="grid") and keyboard navigation.
   ========================================================================== */

.schedule-grid-wrapper {
  overflow-x: auto;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  padding: var(--space-2);
}

.schedule-grid {
  display: grid;
  min-width: 780px;
}

/*
 * Each row spans every column track via CSS Grid's `subgrid` (inheriting the
 * exact column sizing `.schedule-grid` defines inline) rather than the
 * simpler `display: contents` used before the drag-and-drop reordering
 * feature — `display: contents` gives a row no box at all, so it can't
 * receive the `transform`/`transition` a dragged row needs to visually lift
 * and glide between other rows. `grid-column: 1 / -1` makes the row itself
 * span the full width; `subgrid` then lets its own cells (the employee cell
 * + one per day) align to the parent's tracks exactly as before.
 */
.schedule-grid-row {
  display: grid;
  grid-template-columns: subgrid;
  grid-column: 1 / -1;
}

/* ---- Header row ---- */

.schedule-grid-corner,
.schedule-grid-col-header {
  position: sticky;
  top: 0;
  background: var(--color-surface);
  z-index: 2;
  padding: var(--space-2) var(--space-3) var(--space-3);
}

.schedule-grid-corner {
  color: var(--color-text-muted);
  font-weight: var(--font-weight-semibold);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  display: flex;
  align-items: flex-end;
}

.schedule-grid-col-header {
  border-radius: var(--radius-sm);
}

.schedule-grid-day-header {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.schedule-grid-day-header-label {
  font-size: var(--text-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
}

.schedule-grid-day-header-closed .schedule-grid-day-header-label {
  color: var(--color-text-muted);
}

/* ---- Employee row header ---- */

.schedule-grid-employee-cell {
  position: sticky;
  left: 0;
  background: var(--color-surface);
  z-index: 1;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  font-weight: var(--font-weight-semibold);
  padding: var(--space-3);
  border-top: 1px solid var(--color-border);
  min-width: 160px;
}

/*
 * Drag handle for persistent Schedule Board row reordering — a dedicated
 * grip rather than the whole row/cell, so clicking the employee's name area
 * doesn't accidentally start a drag and clicking a day cell still opens its
 * assign/edit dialog normally. `touch-action: none` stops the browser from
 * treating a touch-drag on the handle as a page scroll gesture (this app is
 * used on phones — see Milestone 22); the ~44px touch target matches the
 * convention already used for other small interactive controls below.
 */
.schedule-grid-drag-handle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin: -10px -8px -10px -12px;
  border: none;
  background: none;
  color: var(--color-text-muted);
  cursor: grab;
  touch-action: none;
  border-radius: var(--radius-sm);
  flex-shrink: 0;
}

.schedule-grid-drag-handle:hover {
  color: var(--color-text);
  background: var(--color-surface-muted);
}

.schedule-grid-drag-handle:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--focus-ring-color);
}

.schedule-grid-drag-handle:active {
  cursor: grabbing;
}

.schedule-grid-employee-name {
  overflow-wrap: anywhere;
}

/* ---- Hours badges (day column header + closed states) ---- */

.hours-badge {
  display: inline-block;
  width: fit-content;
  padding: 3px 8px;
  border-radius: var(--radius-sm);
  font-size: var(--text-xs);
  font-weight: var(--font-weight-medium);
  text-transform: none;
  letter-spacing: normal;
  color: var(--color-text-muted);
  background: var(--color-surface-muted);
}

.hours-badge-event {
  background: var(--color-accent-subtle);
  color: var(--color-accent-text);
  font-weight: var(--font-weight-semibold);
}

.hours-badge-closed {
  background: var(--color-danger-bg);
  color: var(--color-danger);
  font-weight: var(--font-weight-semibold);
}

.hours-badge-unknown {
  font-style: italic;
}

/* ---- Grid cells ---- */

.schedule-grid-cell {
  min-width: 168px;
  padding: var(--space-2);
  border-top: 1px solid var(--color-border);
  border-left: 1px solid var(--color-border);
  display: flex;
  flex-direction: column;
  gap: 6px;
  border-radius: var(--radius-sm);
  transition: background-color var(--transition-fast) var(--ease-standard);
}

.schedule-grid-cell:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--focus-ring-color);
  background: var(--color-accent-subtle);
}

.schedule-grid-cell-blocked {
  background: var(--color-danger-bg);
}

.schedule-grid-day-header-closed {
  background: var(--color-surface-muted);
}

/* ---- Shift card ---- */

.shift-card {
  display: flex;
  flex-direction: column;
  width: 100%;
  border: 1px solid var(--color-border);
  border-left: 4px solid var(--shift-color, var(--color-accent));
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text);
  padding: 7px 9px;
  font-family: inherit;
  font-size: var(--text-sm);
  text-align: left;
  cursor: pointer;
  box-shadow: var(--shadow-xs);
  transition:
    transform var(--transition-fast) var(--ease-standard),
    box-shadow var(--transition-fast) var(--ease-standard),
    background-color var(--transition-fast) var(--ease-standard);
}

.shift-card:hover {
  box-shadow: var(--shadow-sm);
  transform: translateY(-1px);
  background: var(--color-surface-muted);
}

.shift-card-time {
  font-weight: var(--font-weight-semibold);
  font-size: var(--text-sm);
}

.shift-card-edited,
.shift-card-custom {
  margin-top: 1px;
  font-size: var(--text-xs);
  font-weight: var(--font-weight-medium);
  color: var(--color-text-subtle);
}

.shift-card-edited {
  color: var(--color-accent-text);
  font-weight: var(--font-weight-semibold);
}

.shift-card-tags {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 3px;
}

.shift-card-anchor-note {
  margin-top: 1px;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  font-style: italic;
}

/* ---- Preference indicator ---- */

.preference-indicator {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  font-size: 0.65rem;
  font-weight: var(--font-weight-bold);
  line-height: 1;
  cursor: default;
}

.preference-indicator-matches {
  background: var(--color-success-bg);
  color: var(--color-success);
}

.preference-indicator-partial {
  background: var(--color-warning-bg);
  color: var(--color-warning);
}

.preference-indicator-outside {
  background: var(--color-danger-bg);
  color: var(--color-danger);
}

/* ---- Add / assign trigger ---- */

.schedule-grid-add-cell {
  display: block;
  width: 100%;
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-sm);
  background: none;
  color: var(--color-text-muted);
  font-family: inherit;
  padding: 6px;
  font-size: var(--text-xs);
  font-weight: var(--font-weight-medium);
  cursor: pointer;
  transition:
    border-color var(--transition-fast) var(--ease-standard),
    color var(--transition-fast) var(--ease-standard),
    background-color var(--transition-fast) var(--ease-standard);
}

.schedule-grid-add-cell:hover {
  border-color: var(--color-accent);
  border-style: solid;
  color: var(--color-accent-text);
  background: var(--color-accent-subtle);
}

.tag-timeoff-cell {
  align-self: flex-start;
}

/* ---- Overlap banner ---- */

.overlap-banner {
  background: var(--color-danger-bg);
  border: 1px solid var(--color-danger-border);
  color: var(--color-danger);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-5);
  animation: rise-in var(--transition-base) var(--ease-standard);
}

.overlap-banner-title {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 4px;
}

.overlap-banner-list {
  margin: 0;
  padding-left: 20px;
  font-size: var(--text-sm);
}
/* ==========================================================================
   Print-only weekly schedule (Milestone 10) — a purpose-built table layout
   for physically posting one department's week, entirely separate from the
   on-screen `ScheduleGrid` CSS grid. `.print-schedule` stays hidden on
   screen and is revealed only inside `@media print` (the rest of the app's
   chrome is hidden the other way around — see the print rules at the bottom
   of styles.css). Colors here are hardcoded black/white/gray rather than
   the theme's custom properties: the printed page must stay legible on a
   grayscale printer regardless of whether the app is currently in light or
   dark mode on screen.
   ========================================================================== */

.print-schedule {
  display: none;
}

/* Landscape fits 7 day columns + an employee column far better than portrait. */
@page {
  size: landscape;
  margin: 12mm;
}

@media print {
  .print-schedule {
    display: block;
    color: #000;
    background: #fff;
    font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
  }

  .print-schedule-header {
    margin-bottom: 10px;
  }

  .print-schedule-title {
    margin: 0;
    font-size: 18pt;
    font-weight: 700;
    color: #000;
  }

  .print-schedule-subtitle {
    margin: 2px 0 0;
    font-size: 11pt;
    color: #222;
  }

  .print-schedule-empty {
    font-size: 11pt;
    color: #333;
  }

  .print-schedule-table {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
  }

  .print-schedule-table th,
  .print-schedule-table td {
    border: 1px solid #444;
    padding: 6px 8px;
    text-align: left;
    vertical-align: top;
    font-size: 9.5pt;
    color: #000;
  }

  .print-schedule-table thead {
    display: table-header-group;
    background: #eee;
  }

  .print-schedule-table tr {
    page-break-inside: avoid;
  }

  .print-schedule-employee-col {
    width: 13%;
    font-weight: 600;
  }

  .print-day-label {
    font-weight: 700;
    font-size: 10pt;
  }

  .print-day-hours {
    font-weight: 400;
    font-size: 8.5pt;
    color: #333;
    margin-top: 2px;
  }

  .print-shift + .print-shift {
    margin-top: 5px;
    padding-top: 5px;
    border-top: 1px dashed #999;
  }

  .print-shift-time {
    font-weight: 700;
  }

  .print-shift-labels {
    font-size: 8pt;
    font-style: italic;
    color: #333;
  }

  .print-shift-empty {
    color: #888;
  }
}
