/* "Quiet Instrument" design tokens — see DESIGN.md. Legacy names kept as
   aliases so existing var() references pick up the new palette. */
:root {
  /* neutrals (warm) */
  --canvas: #f6f4ef;
  --surface-raised: #fdfcf9;
  --border-strong: #cfc8b8;
  /* ink */
  --ink: #1b2432;
  --ink-2: #5a6474;
  --ink-3: #98a0ac;
  /* accent & brass */
  --accent: #042f66;
  --accent-soft: #e8eef7;
  --brass: #a8905a;
  --brass-soft: #f3eddf;
  /* fills (between surface and border) */
  --fill: #f1eee5;
  /* leave pigments */
  --leave-vacation: #2e7d74;
  --leave-vacation-2: #5aa198;
  --leave-sick-2: #c79a55;
  --leave-emergency-2: #c26a55;
  --leave-vacation-soft: #dcebe9;
  --leave-sick: #b07c2a;
  --leave-sick-soft: #f2e7d3;
  --leave-emergency: #a8432f;
  --leave-emergency-soft: #f1deda;
  --leave-unpaid: #7a8494;
  /* vessel polarity */
  --yin-bg: #0e2a47;
  --yin-fg: #fdfbf4;
  --yang-bg: #e9e0c6;
  --yang-fg: #1b2432;
  /* semantic */
  --success-soft: #dfede4;
  --warning: #b07c2a;
  --warning-soft: #f2e7d3;
  --error: #a8432f;
  --error-soft: #f1deda;
  --info: #3a5f8a;
  --info-soft: #e2eaf2;
  /* typography */
  --font-ui: "Work Sans", system-ui, -apple-system, sans-serif;
  --font-data: "IBM Plex Mono", ui-monospace, SFMono-Regular, monospace;
  --text-2xs: 0.6875rem;
  --text-xs: 0.75rem;
  --text-sm: 0.8125rem;
  --text-base: 0.875rem;
  --text-lg: 1.25rem;
  --text-stat: 1.75rem;
  /* radii & shadows */
  --r-sm: 4px;
  --r-md: 8px;
  --r-lg: 12px;
  --shadow-card: 0 1px 2px rgba(27, 36, 50, 0.05);
  --shadow-pop: 0 12px 32px rgba(27, 36, 50, 0.14);
  /* legacy aliases (remapped) */
  --brand-navy: var(--accent);
  --brand-gold: var(--brass);
  --surface: var(--canvas);
  --card: #ffffff;
  --text: var(--ink);
  --muted: var(--ink-2);
  --border: #e7e2d6;
  --danger: var(--error);
  --success: #2e7d52;
}

/* Dark theme — same token names, night values (see DESIGN.md). Applied by the
   navbar toggle / prefers-color-scheme via data-theme on <html>. */
[data-theme='dark'] {
  --canvas: #14181f;
  --card: #1b212b;
  --surface-raised: #1f2631;
  --fill: #262d38;
  --border: #2a3240;
  --border-strong: #3a4454;
  --ink: #e8e6de;
  --ink-2: #9ba4b0;
  --ink-3: #6b7482;
  --accent: #8fb0dc;
  --accent-soft: #1e2a3c;
  /* Solid action surfaces (primary buttons) need a darker blue than the
     text/link accent so white labels keep their contrast. */
  --brand-navy: #2e4d7b;
  --brass: #c4ac74;
  --brass-soft: #2a2617;
  --leave-vacation: #3f9a8e;
  --leave-vacation-soft: #17302d;
  --leave-vacation-2: #57b3a6;
  --leave-sick: #ce9c4b;
  --leave-sick-soft: #32270f;
  --leave-sick-2: #d9b070;
  --leave-emergency: #c56a55;
  --leave-emergency-soft: #331b15;
  --leave-emergency-2: #d28a78;
  --leave-unpaid: #8a94a4;
  --yin-bg: #1d4066;
  --yin-fg: #e8eef7;
  --yang-bg: #3a3427;
  --yang-fg: #e8e6de;
  --success: #57a97e;
  --success-soft: #16281e;
  --warning: #ce9c4b;
  --warning-soft: #32270f;
  --error: #c56a55;
  --error-soft: #331b15;
  --info: #6e93be;
  --info-soft: #1a2634;
  --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-pop: 0 12px 32px rgba(0, 0, 0, 0.55);
  color-scheme: dark;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: var(--font-ui);
  color: var(--text);
  background: var(--surface);
  min-height: 100vh;
}

/* data / numerals — tabular mono everywhere numbers must align */
.mono,
.num {
  font-family: var(--font-data);
  font-variant-numeric: tabular-nums;
}

a {
  color: inherit;
  text-decoration: none;
}

.navbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.6rem 1.25rem;
  background: var(--card);
  color: var(--ink);
  border-bottom: 1px solid var(--border);
  box-shadow: var(--shadow-card);
}

.navbar-brand {
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.navbar-links {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.navbar-user {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  margin-left: auto;
}

.navbar-user-label {
  font-size: 0.85rem;
  opacity: 0.92;
  white-space: nowrap;
}

.navbar-logout-btn,
.navbar-password-btn {
  padding: 0.35rem 0.75rem;
  font-size: 0.85rem;
}

.theme-toggle-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: var(--ink-2);
  cursor: pointer;
  padding: 0;
}

.theme-toggle-btn:hover {
  background: var(--fill);
  color: var(--ink);
}

/* Reminder center bell (navbar, all signed-in pages).
   Count renders as quiet brass mono for every severity — see DESIGN.md. */
.navbar-reminders {
  position: relative;
  margin-left: auto;
}

.navbar-reminders + .navbar-user {
  margin-left: 0;
}

/* Page-scoped activity-log dropdown (attendance) — sits next to the bell
   and reuses the bell/panel styling. */
.navbar-activity {
  position: relative;
  margin-left: auto;
}

.navbar-reminders + .navbar-activity,
.navbar-activity ~ .navbar-reminders {
  margin-left: 0;
}

.navbar-activity + .navbar-user {
  margin-left: 0;
}

.navbar-activity[open] .reminders-bell {
  background: var(--fill);
  color: var(--ink);
}

.reminders-bell {
  list-style: none;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  color: var(--ink-2);
  background: transparent;
  cursor: pointer;
}

.reminders-bell::-webkit-details-marker {
  display: none;
}

.reminders-bell:hover,
.navbar-reminders[open] .reminders-bell {
  background: var(--fill);
  color: var(--ink);
}

/* No-alarm policy (DESIGN.md): the reminder count is quiet brass mono text,
   never a red badge — red is reserved for actual expiries inside the panel. */
.reminders-badge {
  position: absolute;
  top: -6px;
  right: -8px;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 17px;
  height: 17px;
  padding: 0 4px;
  border-radius: 999px;
  border: 1px solid var(--brass);
  background: var(--brass-soft);
  color: var(--brass);
  font-family: var(--font-data);
  font-size: 0.66rem;
  font-weight: 500;
  line-height: 1;
}

.reminders-badge--expired,
.reminders-badge--soon {
  background: var(--brass-soft);
}

.reminders-panel {
  position: absolute;
  right: 0;
  top: calc(100% + 10px);
  width: min(340px, calc(100vw - 2rem));
  max-height: 420px;
  overflow-y: auto;
  padding: 0.8rem 0.9rem;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--card);
  color: var(--text);
  box-shadow: 0 12px 32px rgba(15, 23, 42, 0.18);
  z-index: 80;
}

.reminders-section + .reminders-section {
  margin-top: 0.7rem;
  padding-top: 0.65rem;
  border-top: 1px solid var(--border);
}

.reminders-section-title {
  margin: 0 0 0.4rem;
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
}

.reminders-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.32rem;
}

.reminders-row {
  display: flex;
  align-items: baseline;
  gap: 0.45rem;
  font-size: 0.85rem;
  line-height: 1.35;
}

.reminders-dot {
  flex: none;
  align-self: center;
  width: 8px;
  height: 8px;
  border-radius: 50%;
}

/* Match the staff-directory HR alert dot colors. */
.reminders-dot--expired {
  background: var(--error);
}

.reminders-dot--soon {
  background: var(--warning);
}

/* "Changed by the agent" is news, not a deadline — so it never borrows the
   expiry palette. Brass is the app's mark for time passing, which is exactly
   what a new entry is; an already-seen one keeps its place in the column as a
   hairline ring, so the list still reads as a column of dots. */
.reminders-dot--new {
  background: var(--brass);
}

.reminders-dot--quiet {
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--border-strong);
}

.reminders-staff-link {
  color: var(--brand-navy);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}

.reminders-staff-link:hover {
  text-decoration: underline;
}

.reminders-item-text {
  color: var(--muted);
}

/* Immigration rows: name (truncating) on the left, date pinned right. Without
   this the label's nowrap pushes the date out of the column and it wraps one
   word — or one digit — per line. */
.reminders-row-label {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.reminders-item-kind {
  font-weight: 400;
  color: var(--muted);
}

.reminders-row-date {
  flex: none;
  margin-left: auto;
  white-space: nowrap;
}

.reminders-more {
  display: inline-block;
  margin-top: 0.4rem;
  font-size: 0.8rem;
  color: var(--brand-navy);
}

.reminders-empty {
  margin: 0.2rem 0;
  font-size: 0.85rem;
  color: var(--muted);
}

.reminders-footer {
  margin-top: 0.7rem;
  padding-top: 0.7rem;
  border-top: 1px solid var(--border);
  text-align: right;
}

.reminders-send-digest-btn {
  font-size: 0.8rem;
  padding: 0.3rem 0.7rem;
}

.login-page-body {
  min-height: 100vh;
  background: var(--page-bg, var(--canvas));
}

.login-page {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: calc(100vh - 2rem);
  padding: 1rem;
}

.login-page .login-card {
  width: min(100%, 24rem);
}

.users-table td.actions-col {
  white-space: nowrap;
}

.users-table td.users-actions-col {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  align-items: center;
}

.users-table .danger-text {
  color: var(--danger);
}

.audit-log-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.audit-log-list li {
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--border-subtle, var(--border));
  font-size: 0.9rem;
}

.audit-log-list li:last-child {
  border-bottom: none;
}

.audit-log-meta {
  color: var(--text-muted, var(--ink-2));
  font-size: 0.8rem;
}

.nav-link {
  padding: 0.45rem 0.85rem;
  border-radius: var(--r-md);
  color: var(--ink-2);
  font-size: 0.875rem;
}

.nav-link:hover {
  background: var(--fill);
  color: var(--ink);
}

.nav-link.active {
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 500;
}

.page {
  max-width: 1600px;
  margin: 0 auto;
  padding: 1.25rem;
}

.page-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1rem;
}

.page-title {
  margin: 0;
  font-size: 1.35rem;
  letter-spacing: -0.01em;
}

.page-subtitle {
  margin: 0.25rem 0 0;
  color: var(--muted);
}

.toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: center;
}

.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.06);
}

.controls-card {
  padding: 1rem;
  margin-bottom: 1rem;
}

label {
  font-size: 0.875rem;
  color: var(--muted);
  display: block;
  margin-bottom: 0.25rem;
}

input,
select,
textarea,
button {
  font: inherit;
}

input,
select,
textarea {
  width: 100%;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--card);
}

button,
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  padding: 0.55rem 0.95rem;
  border: none;
  border-radius: 8px;
  background: var(--brand-navy);
  color: #fff;
  cursor: pointer;
}

button.secondary,
.btn.secondary {
  background: var(--card);
  color: var(--text);
  border: 1px solid var(--border-strong);
}

button.danger,
.btn.danger {
  background: var(--danger);
}

button:hover,
.btn:hover {
  filter: brightness(1.05);
}

.field-inline {
  min-width: 180px;
}

/* Dashboard integrations card (Lot 17). */
.dashboard-integration-hint {
  margin: 0 0 0.5rem;
  color: var(--ink-2);
  font-size: var(--text-xs);
}

.dashboard-integration-row {
  display: flex;
  gap: 0.4rem;
  flex-wrap: wrap;
  margin-bottom: 0.5rem;
}

.dashboard-feed-url {
  flex: 1;
  min-width: 0;
  font-family: var(--font-data);
  font-size: var(--text-xs);
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  background: var(--surface-raised);
  color: var(--ink);
}

.dashboard-integration-btn {
  padding: 0.3rem 0.7rem;
  font-size: var(--text-xs);
  border-radius: var(--r-md);
}

/* Dashboard leave-request review card (Lot 16). */
.dashboard-request {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding: 0.55rem 0;
  border-bottom: 1px solid var(--border);
}

.dashboard-request:last-child {
  border-bottom: none;
}

.dashboard-request-summary {
  font-size: var(--text-base);
  line-height: 1.45;
}

.dashboard-request-meta {
  display: inline-block;
  margin-left: 0.35rem;
  color: var(--ink-2);
  font-size: var(--text-xs);
}

.dashboard-request-actions {
  display: flex;
  gap: 0.4rem;
  flex-wrap: wrap;
}

.dashboard-request-btn {
  padding: 0.3rem 0.7rem;
  font-size: var(--text-xs);
  border-radius: var(--r-md);
}

.dashboard-request-btn--reject {
  color: var(--error);
  border-color: var(--error);
}

/* Pending leave requests shown in the staff profile modal (Lot 16). */
.staff-profile-pending-requests {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  margin: 0.5rem 0;
}

.staff-profile-pending-request {
  padding: 0.4rem 0.7rem;
  border-radius: var(--r-md);
  border: 1px solid var(--brass);
  background: var(--brass-soft);
  color: var(--ink);
  font-size: var(--text-sm);
}

/* Leave-type pigment dots — replace the retired emoji icons (DESIGN.md). */
.leave-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 2px;
  flex-shrink: 0;
  vertical-align: baseline;
}

.leave-dot--vacation {
  background: var(--leave-vacation);
}

.leave-dot--sick {
  background: var(--leave-sick);
}

.leave-dot--emergency {
  background: var(--leave-emergency);
}

.leave-dot--unpaid {
  background: repeating-linear-gradient(45deg, var(--leave-unpaid) 0 2px, transparent 2px 4px);
}

/* Inline form error — persistent, unlike toasts (see StaffVacationsApi.showFormError). */
.form-error {
  margin: 0.6rem 0 0;
  padding: 0.5rem 0.7rem;
  border-radius: var(--r-md);
  border: 1px solid var(--error);
  background: var(--error-soft);
  color: var(--error);
  font-size: var(--text-sm);
}

.form-error[hidden] {
  display: none;
}

.timeline-card {
  padding: 0.5rem;
  min-height: 520px;
}

#timeline {
  min-height: 480px;
  border-radius: 8px;
}

.badge {
  display: inline-block;
  padding: 0.2rem 0.55rem;
  border-radius: 999px;
  font-size: 0.8rem;
  color: #fff;
  font-weight: 600;
}

.table-wrap {
  overflow: auto;
}

table {
  width: 100%;
  border-collapse: collapse;
}

th,
td {
  padding: 0.75rem;
  border-bottom: 1px solid var(--border);
  text-align: left;
  vertical-align: middle;
}

th {
  background: var(--card);
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-2);
  border-bottom: 1px solid var(--border-strong);
}

tr:hover td {
  background: var(--surface-raised);
}

.status-pill {
  display: inline-block;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 600;
}

.status-pill.active {
  background: var(--success-soft);
  color: var(--success);
}

.status-pill.inactive {
  background: var(--error-soft);
  color: var(--error);
}

.staff-admin-tools {
  margin-top: 0.85rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
}

.staff-admin-hint {
  margin: 0 0 0.5rem;
  font-size: 0.82rem;
  color: var(--muted);
}

.staff-admin-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.5rem 0.75rem;
}

.staff-admin-row label {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--muted);
}

.staff-row-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem 0.55rem;
  align-items: center;
}

/* Manage staff / departments tables — compact rows for desktop browsing */
#manage-section .table-wrap th,
#manage-section .table-wrap td {
  padding: 0.35rem 0.65rem;
}

#manage-section .table-wrap th {
  padding-top: 0.45rem;
  padding-bottom: 0.45rem;
  font-size: 0.78rem;
}

#manage-section .table-wrap td {
  font-size: 0.9rem;
  line-height: 1.35;
}

#manage-section .status-toggle input {
  width: 2.1rem;
  height: 1.1rem;
}

#manage-section .status-toggle-label {
  font-size: 0.75rem;
  min-width: 2.8rem;
}

.status-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  cursor: pointer;
  user-select: none;
}

.status-toggle input {
  width: 2.4rem;
  height: 1.25rem;
  margin: 0;
  accent-color: var(--brand-navy);
  cursor: pointer;
}

.status-toggle-label {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--muted);
  min-width: 3.2rem;
}

.status-toggle input:not(:checked) + .status-toggle-label {
  color: var(--error);
}

.status-toggle input:checked + .status-toggle-label {
  color: var(--success);
}

.tabs {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 1rem;
  flex-wrap: wrap;
}

.tab-btn {
  background: var(--fill);
  color: var(--text);
}

.tab-btn.active {
  background: var(--brand-navy);
  color: #fff;
}

.tab-panel {
  display: none;
}

.tab-panel.active {
  display: block;
}

.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 0.85rem;
  margin-bottom: 1rem;
}

.form-actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.login-card {
  max-width: 420px;
  margin: 4rem auto;
  padding: 1.5rem;
}

.login-error {
  margin: 0.75rem 0 0;
  padding: 0.65rem 0.75rem;
  border-radius: 8px;
  background: var(--error-soft);
  color: var(--error);
  font-size: 0.9rem;
}

.login-error.hidden {
  display: none;
}

.hidden {
  display: none !important;
}

#toast-container {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  z-index: 1000;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.toast {
  background: var(--brand-navy);
  color: #fff;
  padding: 0.75rem 1rem;
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.18);
  transition: opacity 0.3s ease, transform 0.3s ease;
}

.toast-error {
  background: var(--danger);
}

.toast-success {
  background: var(--success);
}

.toast-info {
  background: var(--ink);
}

.toast-persistent {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  max-width: min(26rem, calc(100vw - 2rem));
  padding: 0.75rem 0.5rem 0.75rem 1rem;
}

.toast-persistent .toast-body {
  flex: 1;
  font-size: 0.875rem;
  line-height: 1.45;
  min-width: 0;
}

.toast-title {
  margin: 0 0 0.5rem;
  font-weight: 600;
}

.toast-list {
  margin: 0;
  padding-left: 1.1rem;
  max-height: min(16rem, 45vh);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.toast-list li {
  padding-right: 0.25rem;
}

.toast-dismiss {
  flex-shrink: 0;
  margin: 0;
  padding: 0.15rem 0.4rem;
  border: none;
  border-radius: 4px;
  background: transparent;
  color: inherit;
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
  opacity: 0.8;
}

.toast-dismiss:hover {
  opacity: 1;
  background: rgba(255, 255, 255, 0.12);
}

.toast-hide {
  opacity: 0;
  transform: translateY(8px);
}

.empty-state {
  padding: 2rem;
  text-align: center;
  color: var(--muted);
}

.link-button {
  background: none;
  border: none;
  color: var(--brand-navy);
  padding: 0;
  text-decoration: underline;
  cursor: pointer;
}

@media (max-width: 768px) {
  .page-title {
    font-size: 1.35rem;
  }

  .navbar {
    flex-direction: column;
    align-items: flex-start;
  }
}

@media (min-width: 1200px) {
  .timeline-card {
    min-height: 680px;
  }

  #timeline {
    min-height: 640px;
  }

  .page-title {
    font-size: 2rem;
  }
}

.dashboard-summary {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 1rem;
  padding: 1rem 1.25rem;
  margin-bottom: 1rem;
}

.summary-stat {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.summary-value {
  font-family: var(--font-data);
  font-size: 1.4rem;
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.summary-label {
  font-size: 0.8rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.summary-stat-warn.has-issues {
  cursor: pointer;
}

.summary-stat-warn.has-issues .summary-value {
  color: var(--danger);
}

.timeline-group-label {
  padding: 0.1rem 0.35rem 0.1rem 0.2rem;
  min-width: 148px;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: flex-start;
}

.group-title-row {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  min-width: 0;
  width: 100%;
}

.group-identity {
  display: flex;
  flex-direction: column;
  gap: 0;
  min-width: 0;
  flex: 1;
}

.group-badges {
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
  flex-shrink: 0;
}

.group-name-row {
  display: flex;
  align-items: baseline;
  gap: 0.15rem;
  min-width: 0;
}

.group-name {
  font-weight: 600;
  font-size: 0.78rem;
  line-height: 1.15;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

button.group-name.linklike {
  margin: 0;
  padding: 0;
  border: none;
  background: none;
  text-align: left;
  font-family: inherit;
  cursor: pointer;
  max-width: 100%;
}

button.group-name.linklike:hover,
button.group-name.linklike:focus-visible {
  color: var(--brand-navy);
  text-decoration: underline;
}

.group-pending-days {
  flex-shrink: 0;
  font-size: 0.68rem;
  font-weight: 500;
  line-height: 1.15;
  color: var(--muted);
  white-space: nowrap;
}

.group-meta {
  font-size: 0.64rem;
  line-height: 1.1;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.reconciliation-card {
  padding: 1rem;
  margin-bottom: 1rem;
  border-left: 4px solid var(--danger);
}

.reconciliation-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.75rem;
}

.reconciliation-header h2 {
  margin: 0;
  font-size: 1rem;
}

.reconciliation-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.65rem;
}

.reconciliation-item {
  padding: 0.65rem 0.75rem;
  background: var(--surface-raised);
  border-radius: 8px;
  border: 1px solid var(--border);
}

.reconciliation-item p {
  margin: 0.35rem 0 0;
  font-size: 0.85rem;
  color: var(--muted);
}

.vis-item.board-yin-bg {
  background-color: rgba(14, 42, 71, 0.10) !important;
  border: none !important;
}

.vis-item.board-yang-bg {
  background-color: rgba(168, 144, 90, 0.16) !important;
  border: none !important;
}

.vis-item.board-yin-bg .vis-item-content,
.vis-item.board-yang-bg .vis-item-content {
  visibility: hidden;
}

/* Shared leave presentation — timeline + profile calendar */
.leave-vacation,
.spvc-bar--vacation {
  background-color: var(--leave-vacation);
}

.leave-sick,
.spvc-bar--sick {
  background-color: var(--leave-sick);
}

.leave-emergency,
.spvc-bar--emergency {
  background-color: var(--leave-emergency);
}

.leave-unpaid:not(.leave-absence):not(.leave-vacation):not(.leave-sick):not(.leave-emergency),
.spvc-bar--unpaid:not(.spvc-bar--absence):not(.spvc-bar--vacation):not(.spvc-bar--sick):not(.spvc-bar--emergency) {
  background: repeating-linear-gradient(
    -45deg,
    var(--border),
    var(--border) 2px,
    var(--leave-unpaid) 2px,
    var(--leave-unpaid) 4px
  );
}

/* Booked "Unpaid" keeps the full slate hatch above — it is a decision, and it
   reads as firmly as a paid bar does. An off day no leave column claimed is a
   hole in the record, not a decision: it washes out to a pale hatch so the two
   are never mistaken for each other on the same row. */
.leave-absence:not(.leave-vacation):not(.leave-sick):not(.leave-emergency),
.spvc-bar--absence:not(.spvc-bar--vacation):not(.spvc-bar--sick):not(.spvc-bar--emergency) {
  background: repeating-linear-gradient(
    -45deg,
    var(--card),
    var(--card) 2px,
    color-mix(in srgb, var(--leave-unpaid) 32%, var(--card)) 2px,
    color-mix(in srgb, var(--leave-unpaid) 32%, var(--card)) 4px
  );
}

.leave-historical,
.spvc-bar--historical {
  opacity: 1;
}

.leave-tentative,
.spvc-bar--tentative {
  border: 2px dashed color-mix(in srgb, var(--ink) 45%, transparent);
  opacity: 0.55;
}

/* Planned (confirmed) = soft fill + pigment outline; history stays solid. */
.leave-confirmed.leave-vacation,
.spvc-bar--confirmed.spvc-bar--vacation {
  background-color: var(--leave-vacation-soft);
  border: 2px solid var(--leave-vacation);
}

/* Employment departure (not a leave type) */
.leave-departure-marker.leave-departure-confirmed,
.leave-swatch.leave-departure.leave-departure-marker.leave-departure-confirmed {
  background-color: var(--ink-2);
  border: 2px solid var(--ink);
}

.leave-departure-marker.leave-departure-tentative,
.leave-swatch.leave-departure.leave-departure-marker.leave-departure-tentative {
  background-color: var(--ink-3);
  border: 2px dashed var(--ink-2);
  opacity: 0.85;
}

.vis-item.leave-departure-marker {
  z-index: 2;
}

.vis-item.leave-departure-marker .vis-item-content {
  color: #fff;
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.vis-item.leave-departure-after {
  background-color: rgba(100, 116, 139, 0.12) !important;
  border: none !important;
}

/* Employment start (arrival) — mirror of the departure visuals. */
.vis-item.leave-arrival-marker {
  background-color: var(--success) !important;
  border: 2px solid var(--success) !important;
  color: #fff !important;
}

.vis-item.leave-arrival-before {
  background: repeating-linear-gradient(
    -45deg,
    rgba(100, 116, 139, 0.28),
    rgba(100, 116, 139, 0.28) 4px,
    transparent 4px,
    transparent 9px
  ) !important;
  border: none !important;
}

.vis-item.leave-departure-after.leave-departure-tentative {
  background: repeating-linear-gradient(
    -45deg,
    rgba(148, 163, 184, 0.08),
    rgba(148, 163, 184, 0.08) 4px,
    rgba(100, 116, 139, 0.14) 4px,
    rgba(100, 116, 139, 0.14) 8px
  ) !important;
}

.vis-item.leave-departure-after .vis-item-content {
  visibility: hidden;
}

.leave-swatch.leave-departure.leave-departure-after.leave-departure-confirmed {
  background-color: rgba(100, 116, 139, 0.35);
}

.group-departure-hint {
  font-size: 0.72rem;
  color: var(--muted);
  font-weight: 500;
}

.timeline-departure-hint {
  margin: 0 0 0.75rem;
  font-size: 0.8rem;
  line-height: 1.45;
  color: var(--muted);
}

.timeline-group-departure {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.35rem;
  height: 1.35rem;
  padding: 0;
  margin-left: 0.15rem;
  border: none;
  border-radius: 4px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  opacity: 0.65;
}

.timeline-group-departure:hover {
  color: var(--brand-navy);
  opacity: 1;
}

.leave-confirmed.leave-sick,
.spvc-bar--confirmed.spvc-bar--sick {
  background-color: var(--leave-sick-soft);
  border: 2px solid var(--leave-sick);
}

.leave-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem 0.85rem;
  align-items: center;
  font-size: 0.72rem;
  color: var(--muted);
}

.leave-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}

.leave-legend-swatch {
  display: inline-block;
  width: 1.1rem;
  height: 0.55rem;
  border-radius: 999px;
  flex-shrink: 0;
}

.leave-swatch.leave-vacation { background-color: var(--leave-vacation); }
.leave-swatch.leave-sick { background-color: var(--leave-sick); }
.leave-swatch.leave-emergency { background-color: var(--leave-emergency); }
.leave-swatch.leave-absence { background: var(--leave-unpaid); }
.leave-swatch.leave-tentative { border: 2px dashed var(--ink-2); background: var(--info-soft); opacity: 0.55; }
.leave-swatch.leave-confirmed { background: var(--leave-vacation-soft); border: 2px solid var(--leave-vacation); }

.board-yin-swatch { background: rgba(14, 42, 71, 0.35); }
.board-yang-swatch { background: rgba(168, 144, 90, 0.45); }

/* Timeline page layout (aligned with attendance command bar) */
body:has(.timeline-page) {
  overflow: hidden;
  height: 100dvh;
  display: flex;
  flex-direction: column;
}

body:has(.timeline-page) .navbar {
  flex-shrink: 0;
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
}

body:has(.timeline-page) .timeline-page {
  flex: 1;
  min-height: 0;
  min-width: 0;
  width: 100%;
  max-width: 100%;
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  padding: 0.4rem 0.75rem 0.5rem;
  margin: 0;
  overflow: hidden;
}

body:has(.timeline-page) .timeline-command-bar {
  flex-shrink: 0;
  min-width: 0;
  width: 100%;
  max-width: 100%;
}

.timeline-command-bar {
  flex-shrink: 0;
  padding: 0.65rem 0.85rem;
  border-radius: 12px;
}

.timeline-command-bar--compact {
  padding: 0.4rem 0.55rem;
}

.timeline-toolbar {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  min-height: 2.1rem;
  flex-wrap: nowrap;
}

.timeline-toolbar-filters {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  flex-shrink: 0;
}

.timeline-toolbar-filters select {
  max-width: 8.25rem;
  min-width: 0;
  padding: 0.28rem 0.4rem;
  font-size: 0.76rem;
  border-radius: 6px;
}

/* Presence options carry a count suffix ("Upcoming leave · 12"). */
.timeline-toolbar-filters #presence-filter {
  max-width: 10.5rem;
}

.timeline-toolbar-filters .timeline-staff-search {
  width: 8.5rem;
  min-width: 0;
  padding: 0.28rem 0.5rem;
  font-size: 0.76rem;
  border-radius: 6px;
}

.timeline-range-toggle {
  display: inline-flex;
  align-items: stretch;
  gap: 0;
  padding: 0.15rem;
  border-radius: 7px;
  background: var(--fill);
  border: 1px solid var(--border);
  flex-shrink: 0;
}

.timeline-range-btn {
  border: none;
  border-radius: 5px;
  padding: 0.22rem 0.5rem;
  font-size: 0.72rem;
  font-weight: 600;
  line-height: 1.2;
  color: var(--muted);
  background: transparent;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.12s, color 0.12s, box-shadow 0.12s;
}

.timeline-range-btn:hover:not(.is-active) {
  color: var(--text);
  background: color-mix(in srgb, var(--card) 70%, transparent);
}

.timeline-range-btn.is-active {
  color: #fff;
  background: var(--brand-navy);
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.18);
}

.timeline-range-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.timeline-toolbar-spacer {
  flex: 1 1 auto;
  min-width: 0.25rem;
}

.timeline-toolbar-actions {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  flex-shrink: 0;
}

.timeline-toolbar-btn {
  padding: 0.3rem 0.55rem;
  font-size: 0.76rem;
  line-height: 1.2;
}

.timeline-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  padding: 0;
  border-radius: 6px;
  flex-shrink: 0;
}

.timeline-icon-btn--danger {
  color: var(--error);
  border-color: var(--error-soft);
}

.timeline-icon-btn--lock {
  color: var(--accent);
  border-color: var(--border-strong);
  background: var(--info-soft);
}

.timeline-unlock-menu.hidden,
.timeline-overflow-menu.hidden {
  display: none !important;
}

.timeline-toolbar-menu {
  position: relative;
}

.timeline-toolbar-menu > summary {
  list-style: none;
  cursor: pointer;
}

.timeline-toolbar-menu > summary::-webkit-details-marker {
  display: none;
}

.timeline-toolbar-menu[open] > summary {
  border-color: var(--brand-navy);
  color: var(--brand-navy);
}

.timeline-toolbar-menu-body {
  position: absolute;
  right: 0;
  top: calc(100% + 0.3rem);
  z-index: 30;
  min-width: 12rem;
  padding: 0.5rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--card);
  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12);
}

.timeline-overflow-menu-body button {
  width: 100%;
  margin-top: 0.35rem;
  font-size: 0.78rem;
}

.timeline-unlock-menu-body {
  min-width: 14rem;
}

.timeline-unlock-copy {
  margin: 0 0 0.45rem;
  font-size: 0.78rem;
  color: var(--muted);
}

.timeline-login-form {
  display: flex;
  align-items: center;
  gap: 0.35rem;
}

.timeline-login-form input[type="password"] {
  flex: 1;
  min-width: 0;
  max-width: 7rem;
  padding: 0.35rem 0.45rem;
  font-size: 0.8rem;
}

.timeline-toolbar-login-error {
  margin: 0.25rem 0 0;
  font-size: 0.78rem;
}

.timeline-grid-card {
  flex: 1;
  min-height: 12rem;
  min-width: 0;
  width: 100%;
  max-width: 100%;
  padding: 0.35rem;
  border-radius: 12px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.timeline-page #timeline {
  flex: 1;
  min-height: 0;
  min-width: 0;
  width: 100%;
  height: 100%;
  border-radius: 8px;
  overflow: hidden;
  position: relative;
  overscroll-behavior-x: contain;
  overscroll-behavior-y: auto;
}

.timeline-page .vis-timeline {
  font-family: var(--font-ui);
  border-color: var(--border);
  font-size: 0.7rem;
  width: 100% !important;
  max-height: 100%;
  overscroll-behavior-x: contain;
}

.timeline-page .vis-panel.vis-left,
.timeline-page .vis-panel.vis-center,
.timeline-page .vis-panel.vis-right {
  border-color: var(--border);
  overscroll-behavior-x: contain;
}

/* No native scrolling on the labels panel: it fights the vis redraws that
   reset its scrollTop (names drift from the rows, bottom unreachable).
   Wheel gestures route through the timeline scroll instead
   (setupTimelineVerticalScrollSync in timeline.js); vis still positions
   the panel programmatically. */
.timeline-page .vis-left.vis-panel.vis-vertical-scroll {
  overflow-y: hidden;
}

.timeline-page .vis-time-axis .vis-grid.vis-minor,
.timeline-page .vis-time-axis .vis-grid.vis-major {
  border-left-color: transparent;
}

/* Week boundaries (Saturday → Saturday): light blue dotted vertical lines (JS overlay on vis-content) */
.timeline-week-grid-overlay {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
  z-index: 0;
  overflow: hidden;
}

.timeline-week-grid-line {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 1px;
  background: repeating-linear-gradient(
    to bottom,
    var(--border-strong) 0,
    var(--border-strong) 5px,
    transparent 5px,
    transparent 12px
  );
  transform: translateX(-0.5px);
}

/* Custom header replaces native axis grid — no dotted week lines in the header */
.timeline-page .vis-time-axis .vis-grid.vis-saturday,
.timeline-page .vis-time-axis .vis-grid.vis-major,
.timeline-page .vis-time-axis .vis-grid.vis-minor {
  border-left-color: transparent !important;
  border-left-style: none !important;
}

.timeline-page .vis-panel.vis-center .vis-background .vis-grid.vis-vertical {
  border-left-style: dotted;
}

.timeline-page .vis-panel.vis-center .vis-background .vis-grid.vis-vertical.vis-minor,
.timeline-page .vis-panel.vis-center .vis-background .vis-grid.vis-vertical.vis-major {
  border-left-width: 1px;
  border-left-color: transparent;
}

.timeline-page .vis-panel.vis-center .vis-background .vis-grid.vis-vertical.vis-saturday {
  border-left-width: 1px;
  border-left-color: var(--border-strong);
}

.timeline-page[data-timeline-axis="week-coarse"] .vis-panel.vis-center .vis-background .vis-grid.vis-vertical.vis-major {
  border-left-style: dotted;
  border-left-color: var(--border-strong);
}

.timeline-page .vis-panel.vis-center .vis-background .vis-grid.vis-vertical.vis-odd {
  background: transparent;
}

.timeline-page .vis-panel.vis-center .vis-background .vis-grid.vis-vertical.vis-saturday,
.timeline-page .vis-panel.vis-center .vis-background .vis-grid.vis-vertical.vis-sunday {
  background: transparent;
}

.timeline-page .vis-panel.vis-center .vis-background .vis-grid.vis-vertical.vis-today,
.timeline-page .vis-time-axis .vis-grid.vis-today {
  background: rgba(168, 144, 90, 0.10);
  border-left-color: var(--brass) !important;
}

.timeline-page .vis-current-time {
  background-color: var(--brass);
  width: 2px;
  pointer-events: none;
  z-index: 1;
}

/* Native axis labels hidden — custom 3-row header in timeline.js */
.timeline-page .vis-time-axis .vis-text {
  display: none !important;
}

.timeline-page .vis-panel.vis-top {
  background: var(--surface-raised);
  min-height: 58px;
  position: relative;
  overflow: visible;
}

.timeline-month-band-overlay {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
  z-index: 5;
  overflow: hidden;
  background: var(--surface-raised);
  border-bottom: 1px solid var(--fill);
}

.timeline-axis-month-separator {
  position: absolute;
  top: 0;
  height: 100%;
  width: 1px;
  background: var(--fill);
  transform: translateX(-0.5px);
  pointer-events: none;
}

.timeline-axis-month-label {
  position: absolute;
  top: 0;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  transform: translateX(-50%);
  box-sizing: border-box;
  white-space: nowrap;
  font-weight: 600;
  font-size: 0.7rem;
  letter-spacing: 0.04em;
  color: var(--ink);
  padding: 0 4px;
  max-width: min(12rem, 40vw);
  overflow: hidden;
  text-overflow: ellipsis;
  z-index: 1;
}

.timeline-page .vis-panel.vis-top .vis-time-axis {
  overflow: visible !important;
}

.timeline-page .vis-panel.vis-top .vis-time-axis.vis-foreground {
  min-height: 58px;
  height: 58px !important;
  z-index: 1;
}

.timeline-custom-axis-overlay {
  position: absolute;
  top: 18px;
  left: 0;
  pointer-events: none;
  z-index: 4;
  overflow: hidden;
  box-sizing: border-box;
  padding: 4px 0;
}

.timeline-axis-day-col {
  position: absolute;
  top: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  height: 100%;
  box-sizing: border-box;
  overflow: hidden;
  padding: 2px 1px;
}

.timeline-page[data-timeline-axis-labels="lines-only"] .timeline-custom-axis-overlay {
  display: block;
}

/* Fine day column separators in the header row — always visible at every zoom */
.timeline-axis-day-col.timeline-axis-day-col--sep {
  border-left: 1px solid var(--fill);
  box-sizing: border-box;
}

.timeline-axis-weekday {
  font-size: 0.58rem;
  font-weight: 500;
  color: var(--ink-2);
  line-height: 1.1;
  max-width: 100%;
  overflow: hidden;
  text-overflow: clip;
  white-space: nowrap;
  min-width: 0;
}

.timeline-axis-date {
  font-size: 0.62rem;
  font-weight: 500;
  color: var(--ink-2);
  line-height: 1.1;
  max-width: 100%;
  overflow: hidden;
  text-overflow: clip;
  white-space: nowrap;
  min-width: 0;
}

.timeline-axis-day-col.timeline-axis-saturday {
  background: rgba(168, 144, 90, 0.14);
}

.timeline-axis-day-col.timeline-axis-saturday .timeline-axis-weekday,
.timeline-axis-day-col.timeline-axis-saturday .timeline-axis-date {
  color: var(--brass);
  font-weight: 600;
}

.timeline-axis-day-col.timeline-axis-saturday-date-only .timeline-axis-date {
  font-size: calc(0.62rem - 1px);
}

.timeline-page .vis-foreground .vis-group,
.timeline-page .vis-labelset .vis-label {
  /* Row separator as an inset shadow, NOT a border: a border adds 1px to
     every row's offsetHeight while vis-timeline sizes rows from content
     only — the accumulated pixels became bottom rows the vertical scroll
     could never reach. border-bottom: none also kills vis's own default
     row border, which has the same layout problem. */
  border-bottom: none;
  box-shadow: inset 0 -1px 0 var(--border);
  box-sizing: border-box;
  transition: background-color 0.12s ease;
}

.timeline-page .vis-label.timeline-row-hover,
.timeline-page .vis-panel.vis-center .vis-background .vis-group.timeline-row-hover,
.timeline-page .vis-foreground .vis-group.timeline-row-hover {
  background-color: var(--fill) !important;
}

/* Designation section separators (attendance position) — full row, left label + grid */
.timeline-page .vis-label.timeline-designation-header,
.timeline-page .vis-panel.vis-center .vis-background .vis-group.timeline-designation-header,
.timeline-page .vis-foreground .vis-group.timeline-designation-header {
  background: var(--border) !important;
  border-top: 1px solid var(--border-strong);
  border-bottom: 1px solid var(--border-strong);
}

.timeline-page .vis-label.timeline-designation-section--0:not(.timeline-designation-header),
.timeline-page .vis-panel.vis-center .vis-background .vis-group.timeline-designation-section--0:not(.timeline-designation-header),
.timeline-page .vis-foreground .vis-group.timeline-designation-section--0:not(.timeline-designation-header) {
  background-color: var(--card);
}

.timeline-page .vis-label.timeline-designation-section--1:not(.timeline-designation-header),
.timeline-page .vis-panel.vis-center .vis-background .vis-group.timeline-designation-section--1:not(.timeline-designation-header),
.timeline-page .vis-foreground .vis-group.timeline-designation-section--1:not(.timeline-designation-header) {
  background-color: var(--surface-raised);
}

/* Staff rows keep their height through relayouts: vis-timeline derives group
   height from the label inner, which stale inline clamps must never shrink. */
.timeline-page .vis-labelset .vis-label.timeline-staff-row .vis-inner {
  min-height: 32px;
  box-sizing: border-box;
  display: flex;
  align-items: center;
}

.timeline-page .vis-label.timeline-designation-header .vis-inner {
  height: 100%;
  min-height: 24px;
  padding: 0;
  align-items: stretch;
}

.timeline-designation-header-label {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: stretch;
}

.timeline-designation-header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.35rem;
  width: 100%;
  flex: 1;
  min-width: 0;
  padding: 0 0.45rem;
  box-sizing: border-box;
}

.timeline-designation-header-title {
  flex: 1;
  min-width: 0;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ink);
  text-transform: uppercase;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.timeline-designation-header-count {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.15rem;
  padding: 0.08rem 0.42rem;
  border-radius: 999px;
  font-size: 0.62rem;
  font-weight: 600;
  line-height: 1.2;
  color: var(--ink);
  background: var(--fill);
  border: 1px solid var(--border-strong);
}

.timeline-page .vis-panel.vis-center .vis-foreground .vis-item.vis-range {
  top: 5px !important;
}

.timeline-cursor-tooltip {
  position: fixed;
  z-index: 1200;
  max-width: min(22rem, calc(100vw - 1.5rem));
  padding: 0.45rem 0.65rem;
  border-radius: 8px;
  border: 1px solid var(--info);
  background: var(--info-soft);
  color: var(--info);
  font-size: 0.82rem;
  font-weight: 600;
  line-height: 1.35;
  pointer-events: none;
  box-shadow: 0 6px 18px rgba(15, 23, 42, 0.14);
}

.timeline-cursor-tooltip-body {
  display: block;
}

.timeline-cursor-tooltip-main {
  display: block;
}

/* Flight-ticket info on its own line, under a hairline separator */
.timeline-cursor-tooltip-flight {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.35rem;
  padding-top: 0.35rem;
  border-top: 1px solid color-mix(in srgb, var(--info) 30%, transparent);
  font-weight: 500;
}

.timeline-cursor-tooltip-flight .timeline-bar-flight {
  display: inline-flex;
  flex: none;
}

.timeline-cursor-tooltip-flight .timeline-bar-flight svg {
  width: 14px;
  height: 14px;
  display: block;
}

.timeline-page .vis-item.vis-range {
  border-radius: 4px;
  border-width: 1px;
  height: 22px !important;
  min-height: 22px !important;
  max-height: 22px !important;
  overflow: hidden;
}

.timeline-page .vis-item.vis-range .vis-item-content {
  padding: 0 5px;
  overflow: hidden;
  width: 100%;
  height: 100%;
  border-radius: inherit;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  /* Keep bar dates centered in the bar (override vis-timeline auto overflow shift) */
  left: 0 !important;
  transform: none !important;
}

/* Planned leave only — subtle in-bar grips hint at horizontal resize */
.timeline-page .vis-item.vis-range:not(.leave-historical) .vis-item-content {
  position: relative;
  padding: 0 11px;
}

.timeline-page .vis-item.vis-range:not(.leave-historical) .vis-item-content::before,
.timeline-page .vis-item.vis-range:not(.leave-historical) .vis-item-content::after {
  content: '';
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 2px;
  height: 10px;
  border-radius: 1px;
  background: currentColor;
  opacity: 0.42;
  pointer-events: none;
}

.timeline-page .vis-item.vis-range:not(.leave-historical) .vis-item-content::before {
  left: 4px;
}

.timeline-page .vis-item.vis-range:not(.leave-historical) .vis-item-content::after {
  right: 4px;
}

.timeline-page .vis-item.vis-range .timeline-bar-label {
  display: block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 600;
  line-height: 1;
  color: inherit;
  pointer-events: none;
  user-select: none;
}

.timeline-page .vis-item.vis-range .timeline-bar-label--hidden {
  display: none;
}

.timeline-page .vis-item.vis-range .timeline-bar-content {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  max-width: 100%;
  min-width: 0;
}

/* Flight-ticket badge: plane = covered, plane with slash = not covered. */
.timeline-page .vis-item.vis-range .timeline-bar-flight {
  display: inline-flex;
  flex: none;
  color: inherit;
  pointer-events: none;
  user-select: none;
}

.timeline-page .vis-item.vis-range .timeline-bar-flight svg {
  width: 13px;
  height: 13px;
  display: block;
}

.timeline-page .vis-item.vis-range .timeline-bar-flight--not-covered {
  opacity: 0.85;
}

.timeline-page .vis-item.vis-range .timeline-bar-flight--hidden {
  display: none;
}

.timeline-page[data-range-preset="month"] .vis-item.vis-range .timeline-bar-label {
  font-size: 0.7rem;
}

.timeline-page[data-range-preset="quarter"] .vis-item.vis-range .timeline-bar-label {
  font-size: 0.66rem;
}

.timeline-page[data-range-preset="semester"] .vis-item.vis-range .timeline-bar-label {
  font-size: 0.62rem;
}

/* Bar labels: white on solid pigments (DESIGN.md), ink on hatched patterns. */
.timeline-page .vis-item.vis-range {
  color: #fff;
}

/* Selection must keep the leave pigment — the library default repaints
   selected items yellow (#FFF785), which mangled tentative bars. These sit
   BEFORE the status-specific rules so confirmed/historical shades still win. */
.timeline-page .vis-item.leave-vacation {
  background-color: var(--leave-vacation) !important;
  border-color: var(--leave-vacation) !important;
}

.timeline-page .vis-item.leave-sick {
  background-color: var(--leave-sick) !important;
  border-color: var(--leave-sick) !important;
}

.timeline-page .vis-item.leave-emergency {
  background-color: var(--leave-emergency) !important;
  border-color: var(--leave-emergency) !important;
}

.timeline-page .vis-item.vis-selected:not(.leave-historical) {
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 55%, transparent);
}

.vis-item.leave-vacation.leave-historical {
  background-color: var(--leave-vacation) !important;
  border-color: var(--leave-vacation) !important;
  color: #fff !important;
}

.vis-item.leave-sick,
.vis-item.leave-sick.leave-historical,
.vis-item.leave-sick.leave-unpaid {
  background: var(--leave-sick) !important;
  border-color: var(--leave-sick) !important;
  color: #fff !important;
}

.vis-item.leave-emergency.leave-historical {
  background-color: var(--leave-emergency) !important;
  border-color: var(--leave-emergency) !important;
  color: #fff !important;
}

/* `leave-unpaid` rides along on absence bars too (vacationItemClassName), so
   the strong hatch excludes `leave-absence` explicitly — otherwise the two
   would be one look again, which is exactly what the Unpaid column exists to
   stop. */
.vis-item.leave-unpaid:not(.leave-absence):not(.leave-vacation):not(.leave-sick):not(.leave-emergency) {
  background: repeating-linear-gradient(
    -45deg,
    var(--border),
    var(--border) 3px,
    var(--leave-unpaid) 3px,
    var(--leave-unpaid) 6px
  ) !important;
  border-color: var(--ink-2) !important;
  color: var(--ink) !important;
}

/* An unrecorded absence next to a booked Unpaid bar: pale hatch, dashed edge —
   the timeline says "nobody decided this yet" without shouting. */
.vis-item.leave-absence:not(.leave-vacation):not(.leave-sick):not(.leave-emergency) {
  background: repeating-linear-gradient(
    -45deg,
    var(--card),
    var(--card) 3px,
    color-mix(in srgb, var(--leave-unpaid) 32%, var(--card)) 3px,
    color-mix(in srgb, var(--leave-unpaid) 32%, var(--card)) 6px
  ) !important;
  border: 1px dashed var(--leave-unpaid) !important;
  color: var(--ink-2) !important;
}

/* Planned leave (not yet history): soft fill + pigment outline + ink text.
   History stays the solid filled bar — a plan reads as an outline that
   attendance "fills in" once the dates actually happened, so planned and
   historical dates are distinguishable at a glance. */
.timeline-page .vis-item.leave-vacation:not(.leave-historical) {
  background-color: var(--leave-vacation-soft) !important;
  border: 2px solid var(--leave-vacation) !important;
  color: var(--ink) !important;
}

.timeline-page .vis-item.leave-sick:not(.leave-historical) {
  background: var(--leave-sick-soft) !important;
  border: 2px solid var(--leave-sick) !important;
  color: var(--ink) !important;
}

.timeline-page .vis-item.leave-emergency:not(.leave-historical) {
  background: var(--leave-emergency-soft) !important;
  border: 2px solid var(--leave-emergency) !important;
  color: var(--ink) !important;
}

.vis-item.leave-tentative,
.timeline-page .vis-item.leave-tentative:not(.leave-historical) {
  border-style: dashed !important;
  opacity: 0.8;
}

.timeline-page .vis-item.vis-range.leave-historical,
.timeline-page .vis-item.vis-range.leave-tentative,
.timeline-page .vis-item.vis-range.leave-confirmed {
  cursor: pointer;
}

.timeline-page .vis-item.vis-range:not(.leave-historical) {
  cursor: grab;
}

.timeline-page .vis-item.vis-range.vis-selected:not(.leave-historical) {
  cursor: grabbing;
  z-index: 2;
}

.timeline-page .vis-item.vis-selected {
  overflow: visible;
  z-index: 4;
}

.timeline-page .vis-item.vis-selected .vis-delete {
  display: block;
  top: -9px;
  right: -9px;
  left: auto;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--error) !important;
  background-image: none !important;
  border: 2px solid var(--card);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  z-index: 6;
  pointer-events: auto;
  cursor: pointer;
}

.timeline-page .vis-item.vis-selected .vis-delete::after {
  content: '×';
  display: block;
  width: 100%;
  font: 600 12px/14px var(--font-ui);
  text-align: center;
  color: #fff;
}

.timeline-page .vis-item.leave-historical .vis-delete,
.timeline-page .vis-item.leave-departure-marker .vis-delete {
  display: none !important;
}

.timeline-page .vis-labelset .vis-label {
  border-right: 1px solid var(--border);
  padding: 0;
  box-sizing: border-box;
}

.timeline-page .vis-labelset .vis-label .vis-inner {
  min-height: 32px;
  height: 100%;
  /* vis's default 5px vertical padding pushes the inner's natural height
     past 32px, which vis then adopts as the row height — keep rows at the
     32px the design intends. */
  padding-top: 3px;
  padding-bottom: 3px;
  display: flex;
  align-items: center;
  box-sizing: border-box;
}

/* Designation header rows are pure section separators — keep them slim so
   more staff rows fit on screen. */
.timeline-page .vis-labelset .vis-label.timeline-designation-header .vis-inner {
  min-height: 24px;
}

.group-dept-dot {
  width: 0.4rem;
  height: 0.4rem;
  border-radius: 999px;
  flex-shrink: 0;
}

.group-actions {
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
  flex-shrink: 0;
  margin-left: auto;
}

.timeline-group-plan {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 1.35rem;
  height: 1.35rem;
  margin: 0;
  padding: 0;
  border: 1px solid var(--info-soft);
  border-radius: 6px;
  background: var(--info-soft);
  color: var(--info);
  box-shadow: 0 1px 2px rgba(58, 95, 138, 0.1);
  cursor: pointer;
  text-decoration: none;
  line-height: 0;
  opacity: 0;
  transition: opacity 0.12s ease, background-color 0.12s ease, border-color 0.12s ease;
}

.timeline-group-plan-icon {
  display: block;
  width: 0.72rem;
  height: 0.72rem;
}

.timeline-group-label:hover .timeline-group-plan,
.timeline-group-plan:focus-visible {
  opacity: 1;
}

.timeline-group-plan:hover {
  background: var(--info-soft);
  border-color: var(--leave-vacation-2);
}

.timeline-group-plan:focus-visible {
  outline: 2px solid #0891b2;
  outline-offset: 1px;
}

.timeline-plan-dialog {
  --plan-teal: var(--leave-vacation);
  --plan-teal-hover: #256a62;
  --plan-orange: var(--warning);
  --plan-orange-hover: #96691f;
  --plan-surface-muted: var(--fill);
  --plan-label: var(--ink-3);
  border: none;
  border-radius: 16px;
  padding: 0;
  width: min(100vw - 2rem, 32rem);
  max-width: 32rem;
  box-shadow: 0 20px 50px rgba(15, 23, 42, 0.2);
  overflow: hidden;
}

.timeline-plan-dialog::backdrop {
  background: rgba(15, 23, 42, 0.4);
  backdrop-filter: blur(3px);
}

.timeline-plan-form {
  padding: 1.35rem 1.5rem 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 1.15rem;
  background: var(--card);
}

.timeline-plan-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
}

.timeline-plan-header-text {
  min-width: 0;
}

.timeline-plan-staff-name {
  margin: 0;
  font-size: 1.35rem;
  font-weight: 600;
  line-height: 1.2;
  color: var(--text);
}

.timeline-plan-staff-role {
  margin: 0.2rem 0 0;
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--plan-teal);
}

.timeline-plan-close {
  flex-shrink: 0;
  width: 2rem;
  height: 2rem;
  border: none;
  border-radius: 8px;
  background: transparent;
  color: var(--ink-3);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  padding: 0;
}

.timeline-plan-close:hover {
  background: var(--plan-surface-muted);
  color: var(--text);
}

.timeline-plan-section {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}

.timeline-plan-section-label {
  margin: 0;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--plan-label);
}

.timeline-plan-segment {
  display: flex;
  gap: 0.35rem;
  padding: 0.3rem;
  background: var(--plan-surface-muted);
  border-radius: 12px;
}

.timeline-plan-segment-btn {
  flex: 1;
  border: none;
  border-radius: 10px;
  padding: 0.65rem 0.5rem;
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--ink-2);
  background: transparent;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, box-shadow 0.15s;
}

.timeline-plan-segment-btn:hover:not(.is-active) {
  color: var(--text);
  background: color-mix(in srgb, var(--card) 65%, transparent);
}

.timeline-plan-segment-btn.is-active {
  color: #fff;
  background: var(--plan-teal);
  box-shadow: 0 2px 8px rgba(46, 125, 116, 0.35);
}

.timeline-plan-status-toggle {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.65rem;
}

.timeline-plan-status-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  border: 2px solid transparent;
  border-radius: 12px;
  padding: 0.85rem 0.65rem;
  font-size: 0.88rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}

.timeline-plan-status-btn.tentative {
  color: var(--warning);
  background: var(--warning-soft);
}

.timeline-plan-status-btn.tentative.is-active {
  color: #fff;
  background: var(--plan-orange);
  border-color: var(--plan-orange);
  box-shadow: 0 2px 10px rgba(176, 124, 42, 0.35);
}

.timeline-plan-status-btn.confirmed {
  color: var(--success);
  background: var(--plan-surface-muted);
}

.timeline-plan-status-btn.confirmed.is-active {
  color: #fff;
  background: var(--success);
  border-color: var(--success);
  box-shadow: 0 2px 10px rgba(46, 125, 82, 0.3);
}

.timeline-plan-status-btn:not(.is-active):hover {
  filter: brightness(0.97);
}

.timeline-plan-status-icon {
  font-size: 1rem;
  line-height: 1;
}

.timeline-plan-dates-readonly input[type="date"] {
  background: var(--surface-muted, var(--canvas));
  color: var(--text-secondary, var(--ink-2));
  pointer-events: none;
}

.timeline-plan-split-toggle {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text-primary, var(--ink));
  cursor: pointer;
}

.timeline-plan-split-fields {
  margin-top: 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.timeline-plan-historical-hint {
  margin: 0.75rem 0 0;
  font-size: 0.8125rem;
  color: var(--text-secondary, var(--ink-2));
}

.timeline-plan-dates {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.85rem;
}

.timeline-plan-date-field {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.timeline-plan-date-field label {
  font-size: 0.82rem;
  font-weight: 500;
  color: var(--ink-2);
}

.timeline-plan-date-field input[type="date"],
.timeline-plan-form textarea {
  width: 100%;
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 0.65rem 0.75rem;
  font: inherit;
  font-size: 0.92rem;
  color: var(--text);
  background: var(--card);
}

.timeline-plan-date-field input[type="date"]:focus,
.timeline-plan-form textarea:focus {
  outline: 2px solid rgba(46, 125, 116, 0.35);
  outline-offset: 1px;
  border-color: var(--plan-teal);
}

.timeline-plan-form textarea {
  resize: vertical;
  min-height: 5.5rem;
  line-height: 1.45;
}

.timeline-plan-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 0.25rem;
  padding-top: 0.35rem;
}

.timeline-plan-delete {
  border: none;
  background: transparent;
  color: var(--danger);
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  padding: 0.45rem 0.25rem;
}

.timeline-plan-delete:hover {
  text-decoration: underline;
}

.timeline-plan-footer-actions {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  margin-left: auto;
}

.timeline-plan-cancel {
  border: none;
  border-radius: 10px;
  padding: 0.65rem 1.1rem;
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--text);
  background: var(--plan-surface-muted);
  cursor: pointer;
}

.timeline-plan-cancel:hover {
  background: var(--fill);
}

.timeline-plan-save {
  border: none;
  border-radius: 10px;
  padding: 0.65rem 1.25rem;
  font-size: 0.92rem;
  font-weight: 600;
  color: #fff;
  background: var(--plan-teal);
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(46, 125, 116, 0.3);
}

.timeline-plan-save:hover {
  background: var(--plan-teal-hover);
}

.vacation-row-historical td {
  color: var(--muted);
}

.muted-hint {
  font-size: 0.78rem;
  color: var(--muted);
  font-style: italic;
}

.import-result {
  margin-top: 1rem;
  padding: 0.85rem;
  background: var(--surface-raised);
  border-radius: 8px;
  font-size: 0.9rem;
}

.import-result pre {
  white-space: pre-wrap;
  margin: 0.5rem 0 0;
  font-size: 0.8rem;
}

.attendance-page {
  padding: 0.65rem 1rem 1.25rem;
}

/* Éditeur plein viewport : scroll uniquement dans le corps du tableau, en-têtes toujours visibles */
body:has(.attendance-page #editor-section:not(.hidden)) {
  overflow: hidden;
  height: 100dvh;
  display: flex;
  flex-direction: column;
}

body:has(.attendance-page #editor-section:not(.hidden)) .navbar {
  flex-shrink: 0;
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
}

body:has(.attendance-page #editor-section:not(.hidden)) .attendance-page {
  flex: 1;
  min-height: 0;
  min-width: 0;
  width: 100%;
  max-width: 100%;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  padding: 0.4rem 0.75rem 0.5rem;
  margin: 0;
}

body:has(.attendance-page #editor-section:not(.hidden)) .attendance-page #editor-section {
  flex: 1;
  min-height: 0;
  min-width: 0;
  width: 100%;
  max-width: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

body:has(.attendance-page #editor-section:not(.hidden)) .attendance-page #grid-section:not(.hidden) {
  flex: 1;
  min-height: 0;
  min-width: 0;
  width: 100%;
  max-width: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  margin-bottom: 0;
}

body:has(.attendance-page #editor-section:not(.hidden)) .attendance-page #editor-section .attendance-command-bar,
body:has(.attendance-page #editor-section:not(.hidden)) .attendance-page #empty-month {
  flex-shrink: 0;
  min-width: 0;
  max-width: 100%;
}

.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;
}

.attendance-command-bar {
  padding: 0.4rem 0.65rem 0.35rem;
  margin-bottom: 0.45rem;
}

/* Three zones: what you are looking at (month · search · sort), what needs
   attention (comments, departures), what you can do (More · finalize · save). */
.attendance-command-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.45rem 0.75rem;
}

.attendance-command-primary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem 0.4rem;
  min-width: 0;
  flex: 0 1 auto;
}

.attendance-command-primary > #month-select {
  width: auto;
  min-width: 9.5rem;
  max-width: 14rem;
  padding: 0.35rem 0.55rem;
  font-size: 0.82rem;
  font-weight: 600;
}

.attendance-command-notices {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  min-width: 0;
  flex: 1 1 auto;
  justify-content: center;
}

.attendance-command-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 0.35rem 0.5rem;
  flex-shrink: 0;
}

.attendance-command-actions button {
  padding: 0.38rem 0.75rem;
  font-size: 0.82rem;
}

.attendance-command-actions .save-status {
  font-size: 0.78rem;
  white-space: nowrap;
  padding-right: 0.15rem;
}

.admin-fields-btn.is-unlocked {
  border-color: var(--accent);
  color: var(--accent);
}

.attendance-more-menu {
  position: relative;
  font-size: 0.82rem;
}

.attendance-more-menu summary {
  list-style: none;
  cursor: pointer;
  padding: 0.38rem 0.65rem;
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  background: var(--card);
  color: var(--text);
  user-select: none;
}

.attendance-more-menu summary::-webkit-details-marker {
  display: none;
}

.attendance-more-menu[open] summary {
  border-color: var(--brand-navy);
  color: var(--brand-navy);
}

.attendance-more-menu-body {
  position: absolute;
  right: 0;
  top: calc(100% + 0.35rem);
  z-index: 20;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  min-width: 10.5rem;
  padding: 0.45rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--card);
  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12);
}

.attendance-more-menu-body button {
  width: 100%;
  font-size: 0.78rem;
  padding: 0.42rem 0.55rem;
  margin: 0;
}

.attendance-more-menu-divider {
  margin: 0.15rem 0;
  border: none;
  border-top: 1px solid var(--border);
}

/* Always open, like the Vacation timeline search: one less click, and no
   expanding panel to push the toolbar onto a second line. */
.attendance-grid-search-control {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  flex-shrink: 0;
}

.attendance-grid-search-input {
  width: 10.5rem;
  min-width: 0;
  padding: 0.35rem 0.55rem;
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  background: var(--card);
  font-size: 0.82rem;
}

.attendance-grid-search-input:focus {
  outline: 2px solid var(--brand-navy);
  outline-offset: 0;
  border-color: var(--brand-navy);
}

.attendance-grid-search-input:disabled {
  opacity: 0.55;
  cursor: not-allowed;
  background: var(--fill);
}

.attendance-search-meta {
  font-size: 0.72rem;
  color: var(--muted);
  white-space: nowrap;
  flex-shrink: 0;
  max-width: 7rem;
  overflow: hidden;
  text-overflow: ellipsis;
}

.attendance-sort-menu {
  position: relative;
  font-size: 0.82rem;
}

.attendance-sort-menu summary {
  list-style: none;
  cursor: pointer;
  padding: 0.38rem 0.65rem;
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  background: var(--card);
  color: var(--text);
  user-select: none;
}

.attendance-sort-menu summary::-webkit-details-marker {
  display: none;
}

.attendance-sort-menu summary.is-disabled {
  opacity: 0.45;
  pointer-events: none;
  cursor: default;
}

.attendance-sort-menu[open] summary {
  border-color: var(--brand-navy);
  color: var(--brand-navy);
}

.attendance-sort-menu summary.has-active-sort {
  border-color: var(--border-strong);
  background: var(--info-soft);
  color: var(--brand-navy);
}

.attendance-sort-menu-body {
  position: absolute;
  left: 0;
  top: calc(100% + 0.35rem);
  z-index: 20;
  min-width: 15rem;
  padding: 0.55rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--card);
  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12);
}

.attendance-sort-hint {
  margin: 0 0 0.55rem;
  font-size: 0.72rem;
  line-height: 1.35;
  color: var(--muted);
}

.attendance-sort-group + .attendance-sort-group {
  margin-top: 0.55rem;
  padding-top: 0.55rem;
  border-top: 1px solid var(--border);
}

.attendance-sort-label {
  display: block;
  margin-bottom: 0.3rem;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--brand-navy);
}

.attendance-sort-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.35rem;
}

.attendance-sort-actions button {
  width: 100%;
  font-size: 0.74rem;
  padding: 0.38rem 0.45rem;
  white-space: nowrap;
}

.attendance-sort-actions button.is-active {
  border-color: var(--brand-navy);
  background: var(--info-soft);
  color: var(--brand-navy);
}

.attendance-sort-week-hint {
  margin: 0 0 0.45rem;
  font-size: 0.68rem;
  line-height: 1.35;
  color: var(--muted);
}

.attendance-sort-week-picker {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  margin-bottom: 0.4rem;
}

.attendance-sort-week-picker-label {
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--brand-navy);
  flex-shrink: 0;
}

.attendance-sort-week-picker select {
  flex: 1;
  min-width: 0;
  font-size: 0.74rem;
  padding: 0.32rem 0.4rem;
}

.admin-pin-dialog {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 0;
  max-width: 22rem;
  width: calc(100% - 2rem);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.18);
}

.admin-pin-dialog::backdrop {
  background: rgba(15, 23, 42, 0.45);
}

.admin-pin-dialog form {
  padding: 1.1rem 1.15rem 1rem;
}

.admin-pin-title {
  margin: 0 0 0.35rem;
  font-size: 1.05rem;
}

.admin-pin-message {
  margin: 0 0 0.85rem;
  font-size: 0.82rem;
  color: var(--muted);
  line-height: 1.45;
}

.admin-pin-actions {
  margin-top: 0.85rem;
  justify-content: flex-end;
}

.leave-adjust-dialog {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 0;
  max-width: 24rem;
  width: calc(100% - 2rem);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.18);
}

.leave-adjust-dialog::backdrop {
  background: rgba(15, 23, 42, 0.45);
}

.leave-adjust-dialog form {
  padding: 1.1rem 1.15rem 1rem;
}

.leave-adjust-title {
  margin: 0 0 0.35rem;
  font-size: 1.05rem;
}

.leave-adjust-message {
  margin: 0 0 0.85rem;
  font-size: 0.82rem;
  color: var(--muted);
  line-height: 1.45;
}

/* What the timeline already planned for these days — a fact to check the
   choice against, so it sits apart from the question without competing. */
.leave-adjust-hint {
  /* Two facts may stack here (timeline plan, then what the row already holds). */
  white-space: pre-line;
  margin: -0.5rem 0 0;
  padding: 0.4rem 0.55rem;
  border-left: 2px solid var(--border-strong);
  background: var(--fill);
  border-radius: 0 4px 4px 0;
  font-size: 0.78rem;
  color: var(--ink-2);
  line-height: 1.4;
}

/* The four categories are the question; "Not now" is the way out of it. They
   sit on separate rows so the dismiss button never reads as a fifth type.
   Equal columns rather than flex: four buttons of one width read as one set of
   choices, and no category is emphasised by being wider than its neighbours. */
.leave-adjust-choices {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.45rem;
  margin-top: 0.85rem;
}

.leave-adjust-choices button {
  min-width: 0;
}

/* Unpaid is the exception among the four: the unpaid slate names it without
   competing with the paid categories for attention. */
.leave-adjust-choices .leave-adjust-unpaid {
  color: var(--leave-unpaid);
}

.leave-adjust-actions {
  margin-top: 0.55rem;
  padding-top: 0.55rem;
  border-top: 1px solid var(--border);
  gap: 0.45rem;
  justify-content: flex-end;
}

.leave-adjust-actions button {
  min-width: 5.5rem;
}

.unsaved-changes-dialog {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 0;
  max-width: 26rem;
  width: calc(100% - 2rem);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.18);
}

.unsaved-changes-dialog::backdrop {
  background: rgba(15, 23, 42, 0.45);
}

.unsaved-changes-dialog form {
  padding: 1.1rem 1.15rem 1rem;
}

.unsaved-changes-title {
  margin: 0 0 0.35rem;
  font-size: 1.05rem;
}

.unsaved-changes-message {
  margin: 0 0 0.85rem;
  font-size: 0.82rem;
  color: var(--muted);
  line-height: 1.45;
}

.unsaved-changes-actions {
  margin-top: 0.85rem;
  flex-wrap: wrap;
  gap: 0.45rem;
  justify-content: flex-end;
}

.unsaved-changes-actions button {
  flex: 1 1 auto;
  min-width: 6.5rem;
}

.tips-other-currency-input {
  width: 100%;
  box-sizing: border-box;
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  font-family: var(--font-data, ui-monospace, monospace);
  font-size: 1rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.tips-other-currency-input:focus {
  outline: none;
  border-color: var(--brass);
}

.tips-other-currency-error {
  margin: 0.4rem 0 0;
  font-size: 0.78rem;
  color: var(--error);
}

.finalize-check-dialog {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 0;
  max-width: 30rem;
  width: calc(100% - 2rem);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.18);
}

.finalize-check-dialog::backdrop {
  background: rgba(15, 23, 42, 0.45);
}

.finalize-check-dialog form {
  padding: 1.1rem 1.15rem 1rem;
}

.finalize-check-title {
  margin: 0 0 0.35rem;
  font-size: 1.05rem;
}

.finalize-check-message {
  margin: 0 0 0.85rem;
  font-size: 0.82rem;
  color: var(--muted);
  line-height: 1.45;
}

/* Index of what needs reading, in full ink: the list below scrolls, so a
   second family of findings must be announced before it can be scrolled to. */
.finalize-check-counts {
  margin: 0 0 0.7rem;
  font-size: 0.82rem;
  line-height: 1.45;
  color: var(--text);
}

/* One scroll for the whole check list, so two families of findings cannot
   stack into a dialog taller than the screen. */
.finalize-check-groups {
  margin: 0 0 0.85rem;
  max-height: 17rem;
  overflow-y: auto;
}

.finalize-check-group + .finalize-check-group {
  margin-top: 0.85rem;
}

.finalize-check-group-title {
  margin: 0 0 0.3rem;
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-2);
}

.finalize-check-group .finalize-check-message {
  margin-bottom: 0.4rem;
}

.finalize-check-list {
  margin: 0;
  padding: 0.6rem 0.75rem 0.6rem 1.6rem;
  border: 1px solid color-mix(in srgb, var(--warning) 35%, var(--border));
  background: color-mix(in srgb, var(--warning) 10%, transparent);
  border-radius: 8px;
  font-size: 0.82rem;
  line-height: 1.5;
}

.finalize-check-list li + li {
  margin-top: 0.3rem;
}

.finalize-check-actions {
  margin-top: 0.85rem;
  flex-wrap: wrap;
  gap: 0.45rem;
  justify-content: flex-end;
}

.finalize-check-actions button {
  flex: 1 1 auto;
  min-width: 6.5rem;
}

.staff-profile-dialog {
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 0;
  max-width: 56rem;
  width: calc(100% - 1.5rem);
  max-height: calc(100vh - 2rem);
  box-shadow: 0 16px 48px rgba(15, 23, 42, 0.2);
}

.staff-profile-dialog::backdrop {
  background: rgba(15, 23, 42, 0.45);
}

.staff-profile-shell {
  display: flex;
  flex-direction: column;
  max-height: calc(100vh - 2rem);
}

.staff-profile-header {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 1rem 1.1rem 0.85rem;
  border-bottom: 1px solid var(--border);
  background: var(--surface-raised);
}

.staff-profile-identity {
  display: flex;
  align-items: flex-start;
  gap: 0.85rem;
  flex: 1;
  min-width: 0;
}

.staff-profile-avatar-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  flex-shrink: 0;
}

.staff-profile-avatar {
  width: 3.5rem;
  height: 3.5rem;
  border-radius: 50%;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--fill);
  border: 2px solid #fff;
  box-shadow: 0 0 0 1px var(--border);
}

.staff-profile-photo {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.staff-profile-initials {
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ink-2);
  user-select: none;
}

.staff-profile-photo-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.25rem;
  max-width: 6.5rem;
}

.staff-profile-photo-btn {
  font-size: 0.65rem;
  padding: 0.2rem 0.4rem;
  line-height: 1.2;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.staff-profile-heading {
  flex: 1;
  min-width: 0;
}

.staff-profile-title {
  margin: 0;
  font-size: 1.2rem;
  line-height: 1.2;
}

.staff-profile-meta {
  margin: 0.2rem 0 0;
  font-size: 0.84rem;
  color: var(--muted);
}

.staff-profile-submeta {
  margin: 0.15rem 0 0;
  font-size: 0.82rem;
  color: var(--muted);
}

.staff-profile-close-btn {
  border: none;
  background: transparent;
  font-size: 1.5rem;
  line-height: 1;
  padding: 0 0.2rem;
  color: var(--muted);
  cursor: pointer;
}

.staff-profile-close-btn:hover {
  color: var(--accent);
}

.staff-profile-body {
  overflow: auto;
  padding: 1rem 1.1rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.staff-profile-columns {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 1rem;
}

.staff-profile-panel {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 0.85rem;
  background: var(--card);
}

.staff-profile-panel-wide {
  grid-column: 1 / -1;
}

.staff-profile-section-title {
  margin: 0 0 0.65rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}

.staff-profile-section-title-spaced {
  margin-top: 1rem;
}

.staff-profile-fields {
  display: grid;
  gap: 0.45rem;
}

.staff-profile-fields label {
  margin: 0.35rem 0 0;
  font-size: 0.75rem;
}

.staff-profile-fields input,
.staff-profile-fields textarea,
.staff-profile-panel-wide textarea {
  width: 100%;
  padding: 0.45rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 0.875rem;
}

.staff-profile-vacation-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 0.75rem;
  margin-bottom: 0.65rem;
}

.staff-profile-vacation-header .staff-profile-section-title {
  margin-bottom: 0;
}

.staff-profile-vacation-add-btn {
  font-size: 0.8rem;
  padding: 0.35rem 0.65rem;
  white-space: nowrap;
}

.staff-profile-vacation-add {
  margin-bottom: 0.75rem;
  padding: 0.75rem;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-raised);
}

.staff-profile-vacation-add-fields {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(10.5rem, 1fr));
  gap: 0.5rem 0.75rem;
}

.staff-profile-vacation-add-row-wide {
  grid-column: 1 / -1;
}

.staff-profile-vacation-add-row label {
  display: block;
  margin: 0 0 0.25rem;
  font-size: 0.75rem;
  color: var(--muted);
}

.staff-profile-vacation-add-row input,
.staff-profile-vacation-add-row select {
  width: 100%;
  padding: 0.45rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 0.875rem;
}

.staff-profile-vacation-add-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 0.5rem;
  margin-top: 0.65rem;
}

.staff-profile-vacation-calendar {
  margin-top: 0.15rem;
}

.staff-profile-leave-wrap {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.staff-profile-leave-toolbar {
  display: flex;
  justify-content: flex-end;
}

.staff-profile-panel-attendance {
  border-color: color-mix(in srgb, var(--brand-navy) 12%, var(--border));
  background: var(--card);
}

.staff-profile-attendance-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.35rem 0.75rem;
  margin-bottom: 0.85rem;
}

.staff-profile-attendance-title {
  margin: 0;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent);
}

.staff-profile-attendance-month {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  background: var(--fill);
  border: 1px solid var(--border);
}

.staff-profile-attendance-fields {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
}

.staff-profile-attendance-field label {
  display: block;
  margin: 0 0 0.35rem;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--muted);
}

.staff-profile-attendance-field input,
.staff-profile-attendance-field textarea {
  width: 100%;
  padding: 0.45rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 0.875rem;
}

.staff-profile-attendance-period-wrap input[type="date"] {
  max-width: 14rem;
}

/* Attendance spans the row above; the two employment-period panels sit
   side by side underneath — start on the left, end on the right. */
.staff-profile-editors {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 0.85rem;
  align-items: start;
}

.staff-profile-editors > .staff-profile-panel {
  margin: 0;
}

.staff-profile-editors > .staff-profile-panel-attendance {
  grid-column: 1 / -1;
}

@media (max-width: 760px) {
  .staff-profile-editors {
    grid-template-columns: 1fr;
  }
}

.staff-profile-panel-departure,
.staff-profile-panel-employment {
  border-color: color-mix(in srgb, var(--brand-navy) 12%, var(--border));
  background: var(--card);
}

.staff-profile-panel-departure .staff-profile-departure-hint,
.staff-profile-panel-employment .staff-profile-departure-hint {
  margin: -0.35rem 0 0.85rem;
}

.staff-profile-panel-departure select {
  width: 100%;
  max-width: 14rem;
  padding: 0.45rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 0.875rem;
  background: var(--card);
}

.staff-profile-panel-departure input[type="date"],
.staff-profile-panel-employment input[type="date"] {
  max-width: 14rem;
}

.staff-profile-panel-departure input:disabled,
.staff-profile-panel-departure select:disabled,
.staff-profile-panel-employment input:disabled {
  background: var(--fill);
  color: var(--muted);
}

.staff-profile-field-hint {
  margin: 0.35rem 0 0;
  font-size: 0.72rem;
  line-height: 1.4;
  color: var(--muted);
}

.staff-profile-details {
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--card);
}

.staff-profile-details summary {
  cursor: pointer;
  padding: 0.55rem 0.75rem;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--muted);
  list-style: none;
  user-select: none;
}

.staff-profile-details summary::-webkit-details-marker {
  display: none;
}

.staff-profile-details summary::before {
  content: '▸ ';
  display: inline-block;
  transition: transform 0.15s ease;
}

.staff-profile-details[open] summary::before {
  transform: rotate(90deg);
}

.staff-profile-details-body {
  padding: 0 0.75rem 0.75rem;
}

.staff-profile-panel-nested {
  padding: 0.65rem 0.7rem;
  background: var(--surface-raised);
}

.staff-profile-columns-compact {
  gap: 0.65rem;
}

.staff-profile-fields-compact {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.35rem 0.65rem;
}

.staff-profile-fields-compact .staff-profile-notes-label,
.staff-profile-fields-compact #staff-profile-notes {
  grid-column: 1 / -1;
}

.staff-profile-fields-compact label {
  margin-top: 0.15rem;
}

.staff-profile-documents,
.staff-profile-comment-history {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.staff-profile-document,
.staff-profile-history-item {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.5rem 0.6rem;
  background: var(--surface-raised);
}

.staff-profile-document-name,
.staff-profile-history-month {
  display: block;
  font-size: 0.82rem;
  font-weight: 600;
}

.staff-profile-document-sub {
  display: block;
  margin-top: 0.15rem;
  font-size: 0.75rem;
  color: var(--muted);
}

/* Staff profile — annual vacation mini-calendars */
.spvc-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 0.75rem;
  margin-bottom: 0.65rem;
}

.spvc-year-nav {
  display: flex;
  align-items: baseline;
  gap: 0.65rem;
  flex-wrap: wrap;
}

.spvc-year-label {
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--accent);
  line-height: 1.2;
}

.spvc-filter-caption {
  display: block;
  margin-bottom: 0.2rem;
  font-size: 0.68rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
}

.spvc-filter-label--year {
  flex: 0 0 5.5rem;
  max-width: 6rem;
}

.spvc-year-controls {
  display: flex;
  align-items: center;
  gap: 0.25rem;
}

.spvc-nav-btn {
  border: 1px solid var(--border);
  background: var(--card);
  color: var(--accent);
  border-radius: 6px;
  padding: 0.2rem 0.45rem;
  font-size: 0.78rem;
  line-height: 1.2;
  cursor: pointer;
}

.spvc-nav-btn:hover {
  border-color: var(--border-strong);
  background: var(--surface-raised);
}

.spvc-nav-btn.spvc-today {
  font-weight: 600;
}

.spvc-filter-label {
  margin: 0;
  flex: 1 1 10rem;
  max-width: 14rem;
}

.spvc-filter {
  width: 100%;
  padding: 0.35rem 0.5rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 0.75rem;
  background: var(--card);
  color: var(--accent);
}

.spvc-empty-year {
  margin: 0 0 0.5rem;
}

.spvc-month-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.85rem 0.65rem;
}

.spvc-month-grid--window {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.spvc-month {
  min-width: 0;
}

.spvc-month-name {
  margin: 0 0 0.35rem;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--ink);
}

.spvc-month-dow {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 1px;
  margin-bottom: 0.2rem;
}

.spvc-dow {
  text-align: center;
  font-size: 0.58rem;
  font-weight: 600;
  color: var(--ink-3);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.spvc-dow--weekend {
  color: var(--warning);
}

.spvc-month-weeks {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.spvc-week {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 1px;
  position: relative;
  min-height: calc(1.15rem + var(--spvc-bar-rows, 1) * 0.42rem);
}

.spvc-day {
  position: relative;
  z-index: 1;
  min-height: 1.15rem;
  padding: 0.1rem 0.05rem 0.5rem;
  text-align: center;
  border-radius: 4px;
  background: var(--card);
}

.spvc-day--pad {
  background: transparent;
  min-height: 0;
  padding: 0;
}

.spvc-day--weekend {
  background: var(--surface-raised);
}

.spvc-day-num {
  font-size: 0.62rem;
  line-height: 1.1;
  color: var(--ink-2);
  font-weight: 500;
}

.spvc-week-bars {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0.12rem;
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 1px;
  height: calc(var(--spvc-bar-rows, 1) * 0.38rem);
  pointer-events: none;
  z-index: 2;
}

.spvc-bar {
  align-self: end;
  height: 0.34rem;
  margin: 0 1px;
  border-radius: 999px;
  transform: translateY(calc(var(--bar-track, 0) * -0.36rem));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--card) 35%, transparent) inset;
}

.spvc-bar--tentative {
  box-sizing: border-box;
}

.spvc-bar--unpaid {
  background-color: var(--ink-2);
}

.spvc-legend {
  margin-bottom: 0.55rem;
}

.spvc-layout {
  display: block;
}

.spvc-main {
  min-width: 0;
}

.spvc-recap {
  margin-bottom: 0.75rem;
  border: 1px solid color-mix(in srgb, var(--accent) 22%, var(--border));
  border-radius: 10px;
  padding: 0.7rem 0.8rem;
  background: var(--info-soft);
}

.spvc-recap-header {
  margin-bottom: 0.55rem;
}

.spvc-recap-title {
  margin: 0;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--accent);
}

.spvc-recap-source {
  margin: 0.2rem 0 0;
  font-size: 0.68rem;
  color: var(--muted);
}

.spvc-recap-metrics {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.45rem;
  margin-bottom: 0.55rem;
}

.spvc-metric {
  padding: 0.45rem 0.5rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: color-mix(in srgb, var(--card) 85%, transparent);
}

.spvc-metric--pending {
  border-color: color-mix(in srgb, var(--accent) 35%, var(--border));
  background: var(--card);
}

.spvc-metric-label {
  display: block;
  font-size: 0.64rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
}

.spvc-metric-value {
  display: block;
  margin-top: 0.15rem;
  font-size: 1rem;
  font-weight: 600;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

.spvc-metric--pending .spvc-metric-value {
  color: var(--accent);
}

.spvc-metric-hint {
  display: block;
  margin-top: 0.1rem;
  font-size: 0.62rem;
  color: var(--muted);
  line-height: 1.3;
}

.spvc-recap-list--compact {
  padding-top: 0.45rem;
  border-top: 1px solid var(--border);
}

.spvc-recap-list {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.spvc-recap-row {
  display: flex;
  justify-content: space-between;
  gap: 0.5rem;
  font-size: 0.72rem;
}

.spvc-recap-row dt {
  margin: 0;
  color: var(--muted);
}

.spvc-recap-row dd {
  margin: 0;
  font-weight: 600;
  color: var(--accent);
}

.spvc-recap-row--highlight {
  padding-bottom: 0.35rem;
  margin-bottom: 0.15rem;
  border-bottom: 1px solid var(--border);
}

.spvc-recap-row--highlight dd {
  color: var(--accent);
}

.spvc-day-icon {
  position: absolute;
  left: 0.05rem;
  bottom: 0.05rem;
  font-size: 0.48rem;
  line-height: 1;
  pointer-events: none;
}

@media (max-width: 900px) {
  .spvc-month-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .staff-profile-attendance-grid {
    grid-template-columns: 1fr;
  }

  .staff-profile-fields-compact {
    grid-template-columns: 1fr;
  }

  .spvc-recap-metrics {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 520px) {
  .spvc-month-grid,
  .spvc-month-grid--window {
    grid-template-columns: 1fr;
  }

  .spvc-filter-label {
    max-width: none;
    flex-basis: 100%;
  }

  .staff-profile-columns {
    grid-template-columns: 1fr;
  }
}

.staff-profile-document {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.65rem;
}

.staff-profile-document-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
}

.staff-profile-doc-link,
.staff-profile-doc-delete {
  font-size: 0.75rem;
  padding: 0.25rem 0.5rem;
}

.staff-profile-upload {
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
  display: grid;
  gap: 0.4rem;
}

.staff-profile-upload-row {
  display: grid;
  gap: 0.25rem;
}

.staff-profile-history-text {
  margin: 0.35rem 0 0;
  font-size: 0.82rem;
  line-height: 1.45;
  white-space: pre-wrap;
}

.staff-profile-empty {
  margin: 0;
  font-size: 0.82rem;
  color: var(--muted);
}

.staff-profile-footer {
  padding: 0.75rem 1.1rem 1rem;
  border-top: 1px solid var(--border);
  justify-content: flex-end;
}

/* A save in flight on an already-filled dialog: the content is still valid, so
   it stays legible and only stops responding. */
.staff-profile-dialog.is-busy {
  pointer-events: none;
  opacity: 0.72;
}

/* Waiting for a member's data on a freshly-opened dialog. There is nothing to
   read yet, so the body is held blank at the height a loaded profile occupies
   (~62rem, measured) — the dialog no longer opens small and then jumps. No
   shimmer: DESIGN.md, Motion. */
.staff-profile-dialog.is-pending {
  pointer-events: none;
}

.staff-profile-dialog.is-pending .staff-profile-shell {
  min-height: min(62rem, calc(100vh - 2rem));
}

.staff-profile-dialog.is-pending .staff-profile-body > * {
  visibility: hidden;
}

.staff-profile-dialog.is-pending .staff-profile-body::before {
  content: 'Loading…';
  display: block;
  padding: 2rem 0;
  text-align: center;
  font-family: var(--font-data);
  font-size: var(--text-sm);
  color: var(--ink-3);
}

.attendance-grid .grid-staff-name {
  display: inline;
  padding: 0;
  border: none;
  background: none;
  font: inherit;
  font-weight: 600;
  color: var(--accent);
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--accent) 35%, transparent);
  text-underline-offset: 2px;
  cursor: pointer;
}

.attendance-grid .grid-staff-name:hover {
  text-decoration-color: var(--accent);
}

.attendance-grid .grid-staff-name:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 2px;
}

.attendance-grid .grid-staff-name-cell {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  flex-wrap: wrap;
  max-width: 100%;
}

/* Row flags — a comment written on the month, a departure landing in it.
   Neutral ink on purpose: they inform, they do not alarm. */
.attendance-grid .grid-row-flag {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  border-radius: var(--r-sm);
  background: none;
  line-height: 0;
  color: var(--ink-3);
  cursor: pointer;
}

.attendance-grid .grid-row-flag-comment {
  color: var(--ink-2);
}

.attendance-grid .grid-row-flag-departure {
  color: var(--ink);
}

.attendance-grid .grid-row-flag:hover {
  color: var(--accent);
}

.attendance-grid .grid-row-flag:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.attendance-grid tr.grid-row-highlight td {
  background: var(--brass-soft);
  transition: background 0.4s ease;
}

@media (max-width: 720px) {
  .staff-profile-columns {
    grid-template-columns: 1fr;
  }
}

.attendance-grid .admin-select-shell {
  display: block;
  width: 100%;
  cursor: pointer;
}

.attendance-grid .admin-select-shell select:disabled {
  opacity: 1;
  color: inherit;
  -webkit-text-fill-color: inherit;
  cursor: pointer;
  pointer-events: none;
}

@media (max-width: 720px) {
  body:has(.attendance-page #editor-section:not(.hidden)) .attendance-page {
    padding: 0.35rem 0.45rem 0.45rem;
  }

  .attendance-command-row {
    flex-direction: column;
    align-items: stretch;
  }

  .attendance-command-actions,
  .attendance-command-notices {
    justify-content: flex-start;
  }

  .attendance-command-primary > #month-select {
    flex: 1;
    max-width: none;
  }

  .attendance-grid-search-control {
    flex: 1 1 8rem;
  }

  .attendance-grid-search-input {
    flex: 1;
    width: auto;
  }
}

@media (max-width: 768px) {
  body:has(.attendance-page #editor-section:not(.hidden)) .navbar {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.75rem;
  }

  body:has(.attendance-page #editor-section:not(.hidden)) .navbar-links {
    flex: 1 1 auto;
    justify-content: flex-end;
  }
}

.attendance-grid-card {
  padding: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  min-height: 0;
  min-width: 0;
  width: 100%;
  max-width: 100%;
}

.attendance-grid-search-empty {
  margin: 0;
  padding: 0.45rem 0.85rem;
  font-size: 0.8125rem;
  color: var(--muted);
  border-bottom: 1px solid var(--border);
  background: var(--warning-soft);
}

/* Comments & departures menu — the command bar's middle zone, so the
   sheet keeps every pixel of vertical space for crew rows. Summary = one icon
   + count per kind, counts in brass mono (the house style for counts, never a
   red badge). Body = who is concerned, clickable, plus an optional filter. */
.attendance-flags-menu summary {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

.attendance-flags-count {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  color: var(--muted);
}

.attendance-flags-count b {
  font-family: var(--font-data);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--brass);
}

.attendance-flags-body {
  gap: 0;
  min-width: 19rem;
  max-width: 24rem;
  max-height: 24rem;
  overflow-y: auto;
  padding: 0.5rem;
}

.attendance-flags-section + .attendance-flags-section {
  margin-top: 0.5rem;
  padding-top: 0.5rem;
  border-top: 1px solid var(--border);
}

.attendance-flags-section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0 0.35rem 0.25rem;
}

.attendance-flags-section-head h3 {
  margin: 0;
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--ink-2);
}

.attendance-flags-filter {
  padding: 0;
  border: none;
  background: none;
  font-family: inherit;
  font-size: var(--text-xs);
  color: var(--accent);
  cursor: pointer;
  white-space: nowrap;
}

.attendance-flags-filter:hover {
  text-decoration: underline;
}

.attendance-flags-filter[aria-pressed='true'] {
  font-weight: 500;
}

.attendance-flags-item {
  display: flex;
  flex-direction: column;
  align-items: stretch; /* the global button rule centers flex children */
  gap: 0.1rem;
  width: 100%;
  padding: 0.3rem 0.35rem;
  border: none;
  border-radius: var(--r-sm);
  background: none;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}

.attendance-flags-item:hover {
  background: var(--surface-raised);
}

.attendance-flags-item-name {
  font-size: var(--text-base);
  font-weight: 500;
  color: var(--text);
}

.attendance-flags-item-detail {
  font-size: var(--text-xs);
  line-height: 1.35;
  color: var(--muted);
}

.attendance-flags-hint {
  margin: 0.5rem 0 0;
  padding: 0.45rem 0.35rem 0;
  border-top: 1px solid var(--border);
  font-size: var(--text-xs);
  line-height: 1.4;
  color: var(--ink-3);
}

.attendance-grid-wrap {
  flex: 1;
  min-height: 0;
  min-width: 0;
  width: 100%;
  max-width: 100%;
  overflow-x: auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  background: var(--card);
}

.attendance-grid {
  width: 100%;
  min-width: max-content;
  table-layout: auto;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 0.85rem;
  --sticky-col-1-width: 5rem;
  --sticky-col-2-width: 5.5rem;
  --week-yin-width: 4.4rem;
  --week-days-width: 2.65rem;
  --week-pair-width: calc(var(--week-yin-width) + var(--week-days-width));
  --col-leave-width: 3.1rem;
  --col-calc-width: 4.75rem;
  --col-manual-width: 4.75rem;
  --grid-value-font-size: 0.62rem;
  --grid-value-line-height: 1.25;
}

.attendance-grid th,
.attendance-grid td {
  border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  padding: 0;
  vertical-align: middle;
}

.attendance-grid thead th {
  background: var(--fill);
  padding: 0.35rem 0.25rem;
  font-size: 0.72rem;
}

/* Sticky header rows — z-index below corner/name columns */
.attendance-grid thead tr:first-child th:not(.sticky-col) {
  position: sticky;
  top: 0;
  z-index: 2;
}

/* Corner cells (NAME + DESIGNATION): sticky top + left, always on top when scrolling */
.attendance-grid thead .sticky-col {
  position: sticky;
  top: 0;
  z-index: 5;
  background: var(--fill);
  box-shadow: 2px 0 5px rgba(15, 23, 42, 0.08);
}

.attendance-grid th.col-data {
  font-size: 0.62rem;
  line-height: 1.15;
  padding: 0.25rem 0.12rem;
  white-space: normal;
  text-align: center;
  font-weight: 600;
  vertical-align: middle;
  hyphens: auto;
}

.attendance-grid th.col-leave,
.attendance-grid td.cell-leave {
  width: var(--col-leave-width);
  min-width: var(--col-leave-width);
  max-width: var(--col-leave-width);
}

/* Unpaid sits beside the three paid columns but is not one of them — the slate
   figures carry that on their own. No extra rule down its left edge: every cell
   already draws a border-right, so adding one here stacked two lines and read
   as a heavier separator than the rest of the grid. */
.attendance-grid th.col-leave-unpaid {
  color: var(--leave-unpaid);
}

.attendance-grid td.cell-leave-unpaid input {
  color: var(--leave-unpaid);
}

.attendance-grid th.col-calc,
.attendance-grid td.cell-calc {
  width: var(--col-calc-width);
  min-width: var(--col-calc-width);
  max-width: var(--col-calc-width);
}

.attendance-grid th.col-manual,
.attendance-grid td.cell-manual {
  width: var(--col-manual-width);
  min-width: var(--col-manual-width);
  max-width: var(--col-manual-width);
}

.attendance-grid .sticky-col {
  position: sticky;
  left: 0;
  background: var(--card);
  padding: 0.35rem 0.5rem;
  width: max-content;
  white-space: nowrap;
}

.attendance-grid tbody .sticky-col {
  z-index: 3;
  background: var(--card);
}

/* The grid always holds a row per crew member; the search and the
   comments/departures filter hide rows rather than rebuild the table. */
.attendance-grid tbody tr.is-filtered-out {
  display: none;
}

.attendance-grid tbody tr:hover td {
  background: var(--fill);
}

.attendance-grid tbody tr:hover .sticky-col {
  background: var(--fill);
}

.attendance-grid tbody .sticky-col-2 {
  box-shadow: 2px 0 5px rgba(15, 23, 42, 0.06);
}

.attendance-grid .sticky-col-1 {
  width: max-content;
  min-width: 0;
}

.attendance-grid .sticky-col-2 {
  left: var(--sticky-col-1-width);
  width: max-content;
  min-width: 0;
}

.staff-profile-attendance-period-wrap {
  margin-bottom: 1rem;
}

.staff-profile-attendance-period-wrap input[type="date"] {
  width: 100%;
  max-width: 14rem;
}

.staff-profile-field-hint {
  font-size: 0.8rem;
  color: var(--muted);
  margin: 0.35rem 0 0;
  line-height: 1.4;
}

.add-staff-month-hint {
  font-size: 0.8rem;
  color: var(--muted);
  margin: -0.25rem 0 0.75rem;
}

.attendance-grid .staff-designation {
  font-size: 0.75rem;
  color: var(--muted);
  padding: 0.2rem 0.25rem;
}

.attendance-grid select.grid-designation,
.attendance-grid select.grid-dive-flag,
.attendance-grid select.grid-vessel {
  width: 100%;
  max-width: 100%;
  font-size: 0.68rem;
  font-weight: 600;
  border: 1px solid transparent;
  background-color: transparent;
  color: inherit;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath fill='%2394a3b8' d='M1 1l4 4 4-4' stroke='%2394a3b8' stroke-width='0.5' fill-rule='evenodd'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.1rem center;
  background-size: 0.42rem 0.26rem;
  padding: 0.18rem 0.5rem 0.18rem 0.06rem;
}

.attendance-grid select.grid-designation,
.attendance-grid select.grid-dive-flag {
  text-transform: uppercase;
}

.attendance-grid select.grid-vessel {
  text-align: center;
  /* Safari ignores text-align for the closed value of a select — needs text-align-last */
  text-align-last: center;
  font-weight: 500;
  text-transform: none;
  font-size: var(--grid-value-font-size);
  line-height: var(--grid-value-line-height);
  border-radius: 3px;
}

.attendance-grid select.grid-dive-flag {
  text-align: center;
  text-align-last: center;
  padding-left: 0.5rem;
  padding-right: 0.5rem;
}

.attendance-grid select.grid-vessel.vessel-yin {
  background-color: var(--accent-soft);
  color: var(--accent);
  font-weight: 600;
}

.attendance-grid select.grid-vessel.vessel-yang {
  background-color: var(--brass-soft);
  color: var(--yang-fg);
  font-weight: 600;
}

.attendance-grid select.grid-vessel.vessel-no-days {
  font-style: italic;
  font-weight: 400;
}

.attendance-grid select.grid-vessel.vessel-no-days.vessel-yin {
  color: var(--ink-3);
}

.attendance-grid select.grid-vessel.vessel-no-days.vessel-yang {
  color: var(--brass);
}

/* Week slot with no date: the column is inert — no vessel, no caret to invite a pick */
.attendance-grid select.grid-vessel:disabled {
  color: var(--border-strong);
  opacity: 1;
  cursor: default;
  background-image: none;
}

.attendance-grid select.grid-designation:focus,
.attendance-grid select.grid-dive-flag:focus,
.attendance-grid select.grid-vessel:focus {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
  background: var(--card);
}

.attendance-grid td.cell-ab-editable {
  padding: 0.1rem;
  text-align: center;
}

.week-header-inner {
  display: flex;
  flex-direction: column;
  gap: 0.28rem;
  min-width: 0;
  width: 100%;
  max-width: var(--week-pair-width);
  padding: 0.05rem 0;
}

.week-tours-stack {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}

.week-tour-row {
  display: flex;
  align-items: center;
  gap: 0.28rem;
  min-width: 0;
  padding: 0.12rem 0.28rem 0.14rem;
  border-radius: 4px;
  border: 1px solid rgba(15, 23, 42, 0.08);
  background: var(--surface-raised);
}

.week-tour-row.week-tour-yang {
  border-left: 2px solid var(--brand-gold);
  background: var(--brass-soft);
}

.week-tour-row.week-tour-yin {
  border-left: 2px solid var(--accent);
  background: var(--accent-soft);
}

.week-tour-row.is-set .week-tour-input {
  font-weight: 600;
  color: inherit;
}

.week-tour-row.is-maintenance {
  background: var(--brass-soft);
  border-color: #e0d3ac;
}

.week-tour-row.is-maintenance .week-tour-input {
  color: var(--warning);
  font-weight: 600;
  letter-spacing: 0.04em;
}

.week-tour-chip-badge {
  flex: 0 0 auto;
  min-width: 1.85rem;
  font-size: 0.58rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1;
  text-align: left;
}

.week-tour-yang .week-tour-chip-badge {
  color: var(--brass);
}

.week-tour-yin .week-tour-chip-badge {
  color: var(--accent);
}

.week-tour-input {
  flex: 1;
  min-width: 0;
  border: none;
  background: transparent;
  text-align: center;
  font-size: 0.72rem;
  font-weight: 500;
  padding: 0.06rem 0.04rem;
  color: var(--text);
}

.week-tour-input::placeholder {
  color: var(--border-strong);
  font-weight: 400;
}

.week-tour-input:focus {
  outline: none;
  background: color-mix(in srgb, var(--card) 85%, transparent);
  border-radius: 2px;
}

.week-date-chip {
  display: block;
  position: relative;
  width: 100%;
  padding: 0.1rem 0.2rem;
  border-radius: 4px;
  border: 1px dashed rgba(15, 23, 42, 0.12);
  background: color-mix(in srgb, var(--card) 55%, transparent);
}

.week-date-chip.is-set {
  border-style: solid;
  border-color: rgba(4, 47, 102, 0.15);
  background: var(--card);
}

.week-date-chip .week-start {
  display: block;
  width: 100%;
  min-width: 0;
  box-sizing: border-box;
  border: none;
  background: transparent;
  font-size: 0.68rem;
  font-weight: 500;
  line-height: 1.25;
  padding: 0.08rem 0;
  color: var(--text);
  cursor: pointer;
}

.week-date-chip .week-start::-webkit-datetime-edit {
  padding: 0;
}

/* An empty week slot must read as empty. Safari paints today's date in grey as
   the placeholder of a blank date input, so the slot looks like a real week;
   Chrome paints dd/mm/yyyy. Blank the native text in both and show our own —,
   matching the tour inputs. Typing restores the native text. */
.week-date-chip:not(.is-set) .week-start {
  color: transparent;
}

.week-date-chip:not(.is-set)::after {
  content: '—';
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.68rem;
  line-height: 1.25;
  color: var(--border-strong);
  pointer-events: none;
}

.week-date-chip:not(.is-set):focus-within .week-start {
  color: var(--text);
}

.week-date-chip:not(.is-set):focus-within::after {
  content: none;
}

.week-date-chip .week-start::-webkit-calendar-picker-indicator {
  margin: 0;
  padding: 0;
  cursor: pointer;
  opacity: 0.75;
}

.week-date-chip .week-start:focus {
  outline: none;
}

.attendance-grid th.week-header {
  width: var(--week-pair-width);
  min-width: var(--week-pair-width);
  max-width: var(--week-pair-width);
  box-sizing: border-box;
}

.attendance-grid th.week-header.week-slot-empty,
.attendance-grid td.week-slot-empty {
  background: var(--fill);
}

.attendance-grid thead th.week-slot-empty {
  background: var(--border);
}

.attendance-grid td.week-slot-empty input {
  color: var(--muted);
}

.attendance-grid td.week-slot-empty input:not(:placeholder-shown),
.attendance-grid td.week-slot-empty input:focus {
  color: inherit;
}

.week-label {
  display: flex;
  flex-direction: column;
  gap: 0.08rem;
  font-weight: 600;
  font-size: 0.65rem;
  text-transform: none;
  letter-spacing: 0;
}

.week-label input {
  font-weight: 500;
  padding: 0.15rem 0.2rem;
  font-size: 0.72rem;
  min-width: 0;
  max-width: 100%;
}

.week-label input[type="date"] {
  font-size: 0.68rem;
}

.attendance-grid input[type="text"],
.attendance-grid input[type="number"],
.attendance-grid input[type="date"] {
  width: 100%;
  border: none;
  background: transparent;
  padding: 0.35rem 0.4rem;
  border-radius: 0;
}

/* Excel-style: type numbers manually, no stepper arrows */
.attendance-grid input[type="number"] {
  -moz-appearance: textfield;
  appearance: textfield;
}

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

.attendance-grid .week-label input {
  padding: 0.15rem 0.2rem;
  font-size: 0.72rem;
}

.attendance-grid .week-label input[type="date"] {
  font-size: 0.68rem;
}

.attendance-grid input:focus {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
  background: var(--card);
}

.cell-vessel {
  width: var(--week-yin-width);
  min-width: var(--week-yin-width);
  max-width: var(--week-yin-width);
}

.attendance-grid .cell-vessel input,
.attendance-grid .cell-vessel select.grid-vessel {
  text-align: center;
  font-weight: 500;
  padding: 0.18rem 0.5rem 0.18rem 0.06rem;
  letter-spacing: 0;
}

.attendance-grid .cell-days input,
.attendance-grid .cell-days input.grid-days {
  text-align: center;
  padding: 0.22rem 0.08rem;
}

.attendance-grid .cell-days input.grid-days.is-days-partial {
  color: var(--muted);
  font-weight: 400;
  font-size: var(--grid-value-font-size);
  line-height: var(--grid-value-line-height);
}

.attendance-grid .cell-days input.grid-days.is-days-full {
  color: var(--text);
  font-weight: 600;
  font-size: var(--grid-value-font-size);
  line-height: var(--grid-value-line-height);
}

.cell-days {
  width: var(--week-days-width);
  min-width: var(--week-days-width);
  max-width: var(--week-days-width);
}

.cell-calc,
.col-calc {
  background: var(--surface-raised);
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.attendance-grid .calc-readonly {
  padding: 0.22rem 0.1rem;
  color: var(--muted);
}

.attendance-grid .cell-leave input,
.attendance-grid .cell-manual input {
  width: 100%;
  min-width: 0;
  padding: 0.22rem 0.1rem;
  text-align: center;
}

.attendance-grid .cell-manual input {
  padding: 0.22rem 0.12rem;
}

/* Same typography for every numeric / vessel value in the grid body */
.attendance-grid td.calc-readonly,
.attendance-grid td.cell-calc,
.attendance-grid td.cell-vessel select.grid-vessel,
.attendance-grid td.cell-days input,
.attendance-grid td.cell-leave input,
.attendance-grid td.cell-manual input,
.attendance-grid td.cell-ab-editable select.grid-dive-flag {
  font-size: var(--grid-value-font-size);
  line-height: var(--grid-value-line-height);
  font-variant-numeric: tabular-nums;
}

.save-status.is-dirty {
  color: var(--warning);
  font-weight: 600;
}

/* Weekly tips editor */
body.tips-editor-open {
  overflow: hidden;
}

.tips-page-main {
  padding-top: 0.35rem;
  padding-bottom: 0.75rem;
}

.tips-page #tips-workspace {
  display: block;
}

.tips-editor {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  overflow: hidden;
}

.tips-editor--page {
  position: static;
  inset: auto;
  z-index: auto;
  display: block;
  flex: none;
  min-height: auto;
  overflow: visible;
}

/* Standalone page: scroll the document, not a nested pane (wheel over cards/tables). */
body.tips-page .tips-editor-body {
  flex: none;
  overflow: visible;
  overscroll-behavior: auto;
  min-height: auto;
}

.tips-editor.hidden {
  display: none;
}

.tips-editor .card {
  padding: 0.6rem 0.75rem;
}

.tips-editor-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 0.65rem 1rem;
  margin: 0.5rem 0.75rem 0;
  flex-shrink: 0;
}

.tips-editor-title {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 600;
  line-height: 1.25;
}

.tips-editor-subtitle,
.tips-editor-meta {
  margin: 0.2rem 0 0;
  color: var(--muted);
  font-size: 0.78rem;
  line-height: 1.35;
}

.tips-editor-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 0.3rem 0.45rem;
  flex-shrink: 0;
}

.tips-editor-actions button {
  padding: 0.32rem 0.65rem;
  font-size: 0.78rem;
}

.tips-editor-actions .save-status {
  font-size: 0.74rem;
  white-space: nowrap;
  padding-right: 0.15rem;
}

.tips-editor-body {
  flex: 1;
  overflow: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: 0.5rem 0.75rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}

.tips-editor-main {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.55rem;
  align-items: start;
  min-width: 0;
}

.tips-editor-sources {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  min-width: 0;
}

@media (min-width: 960px) {
  .tips-editor-main {
    grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.1fr);
  }

  .tips-staff-card {
    grid-column: 2;
    grid-row: 1;
  }

  .tips-editor-sources {
    grid-column: 1;
    grid-row: 1;
  }
}

.tips-controls-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem 0.75rem;
  align-items: flex-end;
}

.tips-controls-row label {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  margin: 0;
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.tips-controls-row select {
  min-width: 9rem;
  width: auto;
  padding: 0.3rem 0.5rem;
  font-size: 0.8125rem;
  font-weight: 500;
  text-transform: none;
  letter-spacing: normal;
}

.tips-controls-row > button {
  padding: 0.32rem 0.7rem;
  font-size: 0.8125rem;
}

.tips-summary-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(7.25rem, 1fr));
  gap: 0.35rem;
  margin-top: 0.55rem;
  padding-top: 0.55rem;
  border-top: 1px solid var(--border);
}

.tips-summary-grid > div {
  padding: 0.3rem 0.45rem;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: 6px;
}

.tips-summary-grid strong {
  display: block;
  margin-top: 0.1rem;
  font-size: 0.875rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1.25;
}

.tips-summary-label {
  display: block;
  font-size: 0.64rem;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  line-height: 1.2;
}

.tips-panel h3,
.tips-staff-card h3,
.tips-exchange-card h3 {
  margin: 0 0 0.35rem;
  font-size: 0.85rem;
  font-weight: 600;
  line-height: 1.3;
}

.tips-staff-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.45rem;
  flex-wrap: wrap;
}

.tips-staff-heading-title {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  flex-wrap: wrap;
}

.tips-staff-heading-actions {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  flex-shrink: 0;
}

.tips-staff-heading-actions button {
  font-size: 0.72rem;
  padding: 0.2rem 0.55rem;
}

.tips-staff-edit-hint {
  margin: 0 0 0.35rem;
  font-size: 0.72rem;
  color: var(--muted);
  line-height: 1.35;
}

.tips-staff-days-input {
  width: 3.25rem;
  max-width: 100%;
  padding: 0.15rem 0.3rem;
  font-size: 0.8rem;
  text-align: right;
}

.tips-staff-actions-col {
  width: 2rem;
  padding-left: 0.15rem !important;
  padding-right: 0.15rem !important;
  text-align: center;
  vertical-align: middle;
}

.tips-remove-staff-btn {
  min-width: 1.6rem;
  padding: 0.1rem 0.35rem;
  line-height: 1.2;
}

.tips-staff-count-badge {
  display: inline-flex;
  align-items: center;
  padding: 0.08rem 0.45rem;
  border-radius: 999px;
  font-size: 0.68rem;
  font-weight: 600;
  color: var(--muted);
  background: var(--fill);
  border: 1px solid var(--border);
  letter-spacing: normal;
  text-transform: none;
}

.tips-panel-cash-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.35rem;
}

.tips-panel-cash .tips-panel-cash-header h3 {
  margin: 0;
}

.tips-cash-total {
  font-size: 0.85rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.tips-exchange-table {
  width: auto;
  min-width: 16rem;
  max-width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
}

.tips-exchange-table th,
.tips-exchange-table td {
  border: 1px solid var(--border);
  padding: 0.5rem 0.7rem;
  text-align: left;
  vertical-align: middle;
}

.tips-exchange-table thead th {
  background: var(--fill);
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--muted);
}

.tips-rate-input {
  width: 7rem;
  min-width: 0;
}

.tips-rate-fixed {
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.tips-currency-select {
  width: 100%;
  min-width: 4.5rem;
}

.tips-rate-warning {
  margin: 1rem 0 0;
  padding: 0.55rem 0.75rem;
  border-radius: 8px;
  border: 1px solid color-mix(in srgb, var(--warning, var(--warning)) 35%, var(--border));
  background: color-mix(in srgb, var(--warning, var(--warning)) 12%, transparent);
  color: var(--text);
  font-size: 0.8rem;
  line-height: 1.45;
}

.tips-rate-warning.hidden {
  display: none;
}

.tips-cabin-table,
.tips-staff-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8125rem;
}

.tips-cabin-table th,
.tips-staff-table th,
.tips-cabin-table td,
.tips-staff-table td {
  border: 1px solid var(--border);
  padding: 0.2rem 0.35rem;
  text-align: left;
  vertical-align: middle;
}

.tips-cabin-table thead th,
.tips-staff-table thead th {
  background: var(--fill);
  padding: 0.28rem 0.35rem;
  font-size: 0.68rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--muted);
  white-space: nowrap;
}

.tips-cabin-table td:has(input),
.tips-cabin-table td:has(select) {
  padding: 0.15rem 0.3rem;
}

.add-staff-month-dialog {
  /* A modal must never hand its scroll to the page behind it. Without this,
     a wheel that reaches either end of a tall dialog carries on into whatever
     scrolls underneath (on Immigration and Attendance that is the sheet), and
     because the browser latches a gesture to the target it picked, the dialog
     then sits frozen for the rest of the gesture: it reads as "scrolling has
     stopped working". Clicking a field is what usually sets it off, since
     bringing the field into view parks the dialog at one end of its scroll.
     Same reasoning as `.staff-profile-edit-dialog`, applied to the shared
     recipe so every dialog built on it is covered. */
  overscroll-behavior: contain;
  max-width: 28rem;
  border: none;
  border-radius: 12px;
  padding: 1.25rem 1.35rem;
}

.add-staff-month-dialog::backdrop {
  background: rgba(15, 23, 42, 0.45);
}

.add-staff-month-title {
  margin: 0 0 0.35rem;
  font-size: 1.1rem;
}

.add-staff-month-hint,
.add-staff-month-empty {
  margin: 0 0 0.85rem;
  font-size: 0.8125rem;
  color: var(--muted);
  line-height: 1.45;
}

.add-staff-month-dialog label {
  display: block;
  margin-bottom: 0.35rem;
  font-size: 0.8125rem;
  font-weight: 600;
}

.add-staff-month-dialog select,
.add-staff-month-dialog input[type="text"],
.add-staff-month-dialog input[type="month"] {
  width: 100%;
  margin-bottom: 0.75rem;
  box-sizing: border-box;
}

.add-staff-month-actions {
  margin-top: 0.25rem;
}

.tips-cabin-table-footer {
  margin-top: 0.35rem;
}

.tips-add-row-btn {
  padding: 0.25rem 0.55rem;
  font-size: 0.75rem;
}

.tips-cabin-actions-col {
  width: 1.85rem;
  padding-left: 0.15rem !important;
  padding-right: 0.15rem !important;
  text-align: center;
  vertical-align: middle;
}

.tips-remove-row-btn {
  min-width: 1.5rem;
  width: 1.5rem;
  height: 1.5rem;
  padding: 0;
  line-height: 1;
  font-size: 1rem;
}

.tips-cabin-input.tips-equ-usd-synced,
.tips-equ-usd-synced.tips-cabin-input {
  background: var(--surface-muted, var(--canvas));
  color: var(--text-secondary, var(--ink-2));
}

.tips-cabin-input,
.tips-inline-input,
.tips-carried-input,
.tips-rate-input,
.tips-cash-input,
.tips-currency-select {
  width: 100%;
  min-width: 0;
  box-sizing: border-box;
  padding: 0.25rem 0.4rem;
  font-size: 0.8125rem;
  border-radius: 5px;
}

.tips-carried-input,
.tips-base-amount-input {
  margin-top: 0.1rem;
}

.tips-summary-editable {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}

.tips-summary-hint {
  font-size: 0.66rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  line-height: 1.25;
}

.tips-cash-inline {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 0.3rem 0.4rem;
}

.tips-cash-inline label {
  display: flex;
  flex-direction: column;
  gap: 0.12rem;
  margin: 0;
  font-size: 0.64rem;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.tips-cash-inline .tips-cash-input {
  padding: 0.2rem 0.35rem;
  font-size: 0.78rem;
}

.tips-staff-table-wrap {
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--card);
}

.tips-staff-table {
  margin: 0;
}

.tips-staff-table thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  box-shadow: 0 1px 0 var(--border);
}

.tips-staff-table .num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.tips-staff-table td.empty-state {
  padding: 1.25rem 1rem;
  text-align: center;
}

.tips-amount-cell {
  min-width: 9rem;
}

.tips-amount-cell .tips-inline-input {
  min-width: 6.5rem;
}

.tips-amount-hint {
  display: block;
  margin-top: 0.2rem;
  font-size: 0.72rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.tips-signature-cell {
  min-width: 4.5rem;
  height: 1.35rem;
}

@media (max-width: 720px) {
  .tips-editor-header {
    flex-direction: column;
    align-items: stretch;
  }

  .tips-editor-actions {
    justify-content: flex-start;
  }

  .tips-cash-inline {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* ——— Staff directory (Manage) ——— */

.manage-staff-panel {
  padding: 0.85rem 1rem 1rem;
}

.manage-page-title {
  margin: 0;
  font-size: 1.35rem;
}

.manage-header-compact {
  margin-bottom: 0.75rem;
}

.manage-header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1rem;
  flex-wrap: wrap;
  margin-bottom: 0.65rem;
}

.manage-header-actions {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  flex-wrap: wrap;
}

.manage-toolbar-compact {
  margin-bottom: 0.45rem;
}

.manage-hint-details {
  margin-bottom: 0.65rem;
  font-size: 0.78rem;
  color: var(--muted);
}

.manage-hint-details summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--brand-navy);
}

.manage-hint-details p {
  margin: 0.35rem 0 0;
  line-height: 1.45;
}

.staff-directory-table {
  table-layout: fixed;
  width: 100%;
}

/* Percent widths sum to 100% — avoids uneven gaps from mixing rem + % */
.staff-directory-table .staff-col-name {
  width: 21%;
}

.staff-directory-table .staff-col-full-name {
  width: 29%;
}

.staff-directory-table .staff-col-designation {
  width: 18%;
}

.staff-directory-table .staff-col-pending {
  width: 12%;
}

.staff-directory-table .staff-col-active {
  width: 13%;
}

.staff-directory-table .staff-col-actions {
  width: 7%;
}

/* Compact rhythm, and the same on every column (name ↔ full name ↔ designation
   ↔ …). This belongs to the table recipe rather than to the Manage page: the
   immigration workspace reuses `.staff-directory-table` and was inheriting the
   loose 0.75rem default instead, which made its rows twice the height of the
   directory's for the same kind of data. */
.staff-directory-table th,
.staff-directory-table td {
  padding-left: 0.75rem;
  padding-right: 0.75rem;
}

.staff-directory-table th {
  padding-top: 0.45rem;
  padding-bottom: 0.45rem;
}

.staff-directory-table td {
  padding-top: 0.35rem;
  padding-bottom: 0.35rem;
}

.staff-directory-table td:first-child,
.staff-directory-table .designation-col {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.staff-directory-table th[data-sort-key] {
  cursor: pointer;
  user-select: none;
}

.staff-directory-table th[data-sort-key]:hover {
  color: var(--ink);
}

.staff-directory-table th[data-sort-key].sorted {
  color: var(--accent);
}

.staff-directory-table th[aria-sort='ascending']::after {
  content: ' ↑';
}

.staff-directory-table th[aria-sort='descending']::after {
  content: ' ↓';
}

.staff-directory-table .num-col {
  text-align: right;
  white-space: nowrap;
}

.staff-directory-table td.num-col {
  font-family: var(--font-data);
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
}

.staff-directory-table th.num-col {
  text-align: right;
}

.staff-directory-table .full-name-col {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.staff-directory-table .active-col {
  white-space: nowrap;
  text-align: center;
}

.staff-directory-table th.active-col {
  text-align: center;
}

#manage-section .staff-directory-table .status-toggle {
  flex-wrap: nowrap;
  justify-content: center;
  width: 100%;
}

#manage-section .staff-directory-table .status-toggle-label {
  display: inline-block;
  min-width: 3.55rem;
  text-align: left;
}

.staff-directory-name {
  font-weight: 600;
  color: var(--brand-navy);
  text-decoration: none;
}

.staff-directory-name:hover {
  text-decoration: underline;
}

/* HR expiry alert next to the name: small dot + count.
   Colors match the staff-hub document badges (expired / expires soon). */
.staff-hr-alert {
  display: inline-flex;
  align-items: center;
  gap: 0.22rem;
  margin-left: 0.45rem;
  font-size: 0.72rem;
  font-weight: 600;
  white-space: nowrap;
  cursor: default;
}

.staff-hr-alert::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
}

.staff-hr-alert-expired {
  color: var(--error);
}

.staff-hr-alert-soon {
  color: var(--warning);
}

.staff-directory-table .actions-col {
  text-align: center;
}

.staff-directory-table th.actions-col {
  text-align: center;
}

.staff-row-menu {
  position: relative;
  display: inline-block;
}

.staff-row-menu-trigger {
  list-style: none;
  cursor: pointer;
  font-size: 1.1rem;
  line-height: 1;
  padding: 0.15rem 0.35rem;
  border-radius: 6px;
  color: var(--muted);
  user-select: none;
}

.staff-row-menu-trigger::-webkit-details-marker {
  display: none;
}

.staff-row-menu-trigger:hover {
  background: var(--fill);
  color: var(--brand-navy);
}

.staff-row-menu-body {
  position: absolute;
  right: 0;
  z-index: 20;
  min-width: 7rem;
  margin-top: 0.2rem;
  padding: 0.35rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--card);
  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12);
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.15rem;
}

.staff-row-menu-body .link-button {
  text-align: left;
  padding: 0.35rem 0.5rem;
  border-radius: 4px;
}

.staff-row-menu-body .link-button:hover {
  background: var(--fill);
}

.staff-row-menu-danger {
  color: var(--danger);
}

.staff-form-dialog .form-grid {
  margin-top: 0.5rem;
}

.staff-profile-edit-dialog {
  max-width: 32rem;
}

.staff-profile-edit-form {
  margin-top: 0.35rem;
  grid-template-columns: minmax(6rem, 0.85fr) minmax(0, 2.15fr);
}

.staff-profile-edit-form .staff-profile-edit-notes {
  grid-column: 1 / -1;
}

.staff-profile-edit-form label {
  display: block;
  margin-bottom: 0.25rem;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--muted);
}

.staff-profile-edit-form input,
.staff-profile-edit-form select,
.staff-profile-edit-form textarea {
  width: 100%;
  box-sizing: border-box;
}

.staff-profile-edit-form .staff-profile-edit-contact {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.65rem 0.85rem;
}

.staff-profile-edit-actions {
  grid-column: 1 / -1;
  margin-bottom: 0;
}


/* ——— Staff record hub ——— */

.staff-hub-page .page {
  max-width: 1100px;
}

.staff-hub-card {
  padding: 1rem 1.1rem;
}

.staff-hub-header-compact {
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
  margin-bottom: 0.85rem;
}

.staff-hub-header-main {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

.staff-hub-title-row {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  max-width: 100%;
}

.staff-hub-title-row .page-title {
  margin: 0;
}

.staff-hub-edit-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  padding: 0;
  margin: 0 0 0 0.1rem;
  border: none;
  border-radius: 4px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  flex-shrink: 0;
  opacity: 0.55;
  transition: color 0.15s ease, opacity 0.15s ease;
}

.staff-hub-edit-btn:hover {
  color: var(--brand-navy);
  opacity: 1;
}

.staff-hub-edit-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  opacity: 1;
}

.staff-hub-submeta {
  margin: 0.15rem 0 0;
  font-size: 0.82rem;
  color: var(--muted);
}

.staff-hub-back {
  font-size: 0.84rem;
  font-weight: 600;
  color: var(--muted);
  text-decoration: none;
}

.staff-hub-back:hover {
  color: var(--brand-navy);
}

.staff-hub-identity {
  display: flex;
  align-items: center;
  gap: 0.85rem;
}

.staff-hub-avatar {
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  background: var(--fill);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  flex-shrink: 0;
}

.staff-hub-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.staff-hub-initials {
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--brand-navy);
}

.staff-hub-heading .page-title {
  margin: 0;
  font-size: 1.45rem;
}

.staff-hub-meta {
  margin: 0.2rem 0 0;
  font-size: 0.88rem;
  color: var(--muted);
}

.staff-hub-timeline-btn {
  align-self: flex-start;
  font-size: 0.84rem;
}

.staff-hub-section-title {
  margin: 0 0 0.35rem;
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--brand-navy);
}

.staff-hub-directory-hint {
  margin: 0 0 0.75rem;
  font-size: 0.8rem;
  color: var(--muted);
  line-height: 1.45;
}

.staff-hub-field-hint {
  margin: 0.2rem 0 0;
  font-size: 0.72rem;
  color: var(--muted);
  line-height: 1.35;
}

.staff-hub-directory-common-name {
  grid-column: span 1;
}

.staff-hub-directory-full-name {
  grid-column: span 3;
}

.staff-hub-directory-fields {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0.65rem 0.85rem;
}

.staff-hub-directory-fields label {
  display: block;
  margin-bottom: 0.25rem;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--muted);
}

.staff-hub-directory-fields input,
.staff-hub-directory-fields select,
.staff-hub-directory-fields textarea {
  width: 100%;
  box-sizing: border-box;
}

.staff-hub-directory-notes {
  grid-column: 1 / -1;
}

.staff-hub-directory-actions {
  margin-top: 0.75rem;
  margin-bottom: 0;
}

.staff-hub-avatar-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  flex-shrink: 0;
}

.staff-hub-photo-actions {
  display: flex;
  gap: 0.55rem;
}

.staff-hub-photo-btn {
  border: none;
  background: transparent;
  padding: 0;
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
}

.staff-hub-photo-btn:hover {
  color: var(--brand-navy);
  text-decoration: underline;
}

.staff-hub-photo-btn-danger:hover {
  color: var(--danger);
}

.staff-hub-contact-card {
  margin-top: 0.75rem;
}

.staff-hub-contact-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 1rem;
}

.staff-hub-detail-list {
  margin: 0;
  display: grid;
  gap: 0.5rem;
}

.staff-hub-detail-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
}

.staff-hub-detail-row dt {
  font-size: 0.8rem;
  color: var(--muted);
}

.staff-hub-detail-row dd {
  margin: 0;
  font-size: 0.875rem;
  text-align: right;
  overflow-wrap: anywhere;
}

.staff-hub-stint-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.5rem;
}

.staff-hub-stint-line {
  font-size: 0.875rem;
}

.staff-hub-stint-muted {
  color: var(--muted);
  font-size: 0.8rem;
}

.staff-hub-stint-notes {
  margin: 0.15rem 0 0;
  font-size: 0.78rem;
  color: var(--muted);
  line-height: 1.4;
}

.staff-hub-doc-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.staff-hub-doc-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.55rem 0;
  border-top: 1px solid var(--border);
}

.staff-hub-doc-row:first-child {
  border-top: none;
  padding-top: 0;
}

.staff-hub-doc-main {
  min-width: 0;
}

.staff-hub-doc-name-line {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.45rem;
}

.staff-hub-doc-name {
  font-size: 0.875rem;
  font-weight: 600;
  overflow-wrap: anywhere;
}

.staff-hub-doc-chip {
  display: inline-block;
  padding: 0.08rem 0.5rem;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface);
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--muted);
  white-space: nowrap;
}

.staff-hub-doc-badge {
  display: inline-block;
  padding: 0.08rem 0.5rem;
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 600;
  white-space: nowrap;
}

.staff-hub-doc-badge-expired {
  color: var(--error);
  background: color-mix(in srgb, var(--danger) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--danger) 35%, var(--border));
}

.staff-hub-doc-badge-soon {
  color: var(--warning);
  background: color-mix(in srgb, var(--warning) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--warning) 40%, var(--border));
}

.staff-hub-doc-meta {
  margin: 0.2rem 0 0;
  font-size: 0.78rem;
  color: var(--muted);
}

.staff-hub-doc-actions {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-shrink: 0;
  padding-top: 0.15rem;
}

.staff-hub-doc-action {
  border: none;
  background: transparent;
  padding: 0;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
}

.staff-hub-doc-action:hover {
  color: var(--brand-navy);
  text-decoration: underline;
}

.staff-hub-doc-action-danger:hover {
  color: var(--danger);
}

.staff-hub-doc-empty {
  margin: 0;
  font-size: 0.85rem;
  color: var(--muted);
}

.staff-hub-doc-edit-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
}

.staff-hub-doc-edit-form input,
.staff-hub-doc-edit-form select,
.staff-hub-doc-upload input,
.staff-hub-doc-upload select {
  width: auto;
}

.staff-hub-doc-edit-form input[type="text"] {
  flex: 1 1 10rem;
  min-width: 0;
}

.staff-hub-doc-edit-actions {
  display: flex;
  gap: 0.5rem;
}

.staff-hub-doc-upload {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.85rem;
  padding-top: 0.85rem;
  border-top: 1px solid var(--border);
}

.staff-hub-doc-upload input[type="file"] {
  flex: 1 1 12rem;
  min-width: 0;
  font-size: 0.8rem;
}

.staff-hub-doc-upload input[type="text"] {
  flex: 1 1 9rem;
  min-width: 0;
}

.staff-hub-training-notes {
  margin: 0.2rem 0 0;
  font-size: 0.78rem;
  color: var(--muted);
  line-height: 1.4;
}

a.staff-hub-training-cert:hover {
  color: var(--brand-navy);
  border-color: var(--brand-navy);
  text-decoration: underline;
}

.staff-hub-skill-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
}

.staff-hub-skill-chip {
  display: inline-block;
  padding: 0.25rem 0.7rem;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--card);
  font-family: inherit;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
}

button.staff-hub-skill-chip {
  cursor: pointer;
}

button.staff-hub-skill-chip:hover {
  border-color: var(--brand-navy);
}

/* Level intensity: basic = plain, then progressively stronger navy tint. */
.staff-hub-skill-chip-basic {
  color: var(--muted);
}

.staff-hub-skill-chip-intermediate {
  border-color: color-mix(in srgb, var(--brand-navy) 25%, var(--border));
  background: color-mix(in srgb, var(--brand-navy) 4%, var(--card));
}

.staff-hub-skill-chip-advanced {
  border-color: color-mix(in srgb, var(--brand-navy) 45%, var(--border));
  background: color-mix(in srgb, var(--brand-navy) 8%, var(--card));
  color: var(--brand-navy);
}

.staff-hub-skill-chip-expert {
  border-color: color-mix(in srgb, var(--brand-navy) 70%, var(--border));
  background: color-mix(in srgb, var(--brand-navy) 13%, var(--card));
  color: var(--brand-navy);
}

.staff-hub-skill-hint {
  margin: 0.5rem 0 0;
  font-size: 0.72rem;
  color: var(--muted);
}

.staff-hub-skill-edit-form {
  margin-top: 0.85rem;
  padding-top: 0.85rem;
  border-top: 1px solid var(--border);
}

.staff-hub-skill-delete:hover {
  color: var(--danger);
  border-color: var(--danger);
}

.staff-hub-leave-card {
  margin-top: 0.75rem;
  padding: 1.1rem 1.15rem;
}

.staff-hub-header-compact + .staff-hub-leave-card {
  margin-top: 0;
}

.staff-leave-dashboard {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.staff-leave-dashboard-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding-bottom: 0.15rem;
  border-bottom: 1px solid var(--border);
}

.staff-leave-dashboard-title {
  margin: 0;
  font-size: 1rem;
  font-weight: 600;
  color: var(--brand-navy);
  letter-spacing: -0.01em;
}

.staff-leave-year-filter {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  margin: 0;
}

.staff-leave-year-filter-label {
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
}

.staff-leave-year-select {
  min-width: 5.5rem;
  padding: 0.35rem 0.55rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--card);
  font-size: 0.84rem;
  font-weight: 600;
  color: var(--brand-navy);
}

.staff-leave-kpi-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.65rem;
}

.staff-leave-kpi-row--two {
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
}

.staff-leave-dashboard-tools {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
}

.staff-leave-dashboard-actions:empty {
  display: none;
}

.staff-leave-dashboard-actions .staff-profile-vacation-add-btn {
  padding: 0.35rem 0.7rem;
  font-size: 0.8rem;
  white-space: nowrap;
}

.staff-profile-leave-toolbar:empty {
  display: none;
}

.staff-leave-hero-delta {
  font-size: 0.8rem;
  color: var(--accent);
  line-height: 1.35;
}

.staff-leave-hero-delta strong {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.staff-leave-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.5rem;
  padding: 0.55rem 0.7rem;
  border-radius: 10px;
  border: 1px solid color-mix(in srgb, var(--border) 85%, transparent);
  background: var(--surface-raised);
  font-size: 0.8rem;
  color: var(--muted);
}

.staff-leave-chips-year {
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  color: var(--muted);
  padding-right: 0.15rem;
}

.staff-leave-chips-total {
  font-weight: 600;
  color: var(--brand-navy);
  font-variant-numeric: tabular-nums;
}

.staff-leave-chips-total--planned {
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
}

.staff-leave-chips-none {
  color: var(--muted);
}

.staff-leave-chips-sep {
  width: 1px;
  align-self: stretch;
  margin: 0.1rem 0.3rem;
  background: var(--border);
}

.staff-leave-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.2rem 0.55rem;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--card);
  color: var(--text);
  white-space: nowrap;
}

.staff-leave-chip strong {
  font-weight: 600;
  color: var(--brand-navy);
  font-variant-numeric: tabular-nums;
}

.staff-leave-chip--planned {
  border-style: dashed;
}

.staff-leave-coming-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
}

.staff-leave-coming-range {
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--muted);
  white-space: nowrap;
}

.staff-leave-panel.staff-leave-panel--coming {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  min-height: 0;
}

.staff-leave-panel--coming .staff-leave-section-label {
  margin-bottom: 0;
}

.staff-leave-kpi {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  padding: 0.75rem 0.85rem;
  border-radius: 12px;
  border: 1px solid color-mix(in srgb, var(--border) 85%, transparent);
  background: var(--card);
  box-shadow: 0 1px 2px rgb(15 23 42 / 4%);
  min-height: 4.5rem;
}

.staff-leave-kpi--balance {
  background: var(--surface-raised);
}

.staff-leave-kpi--pending {
  border-color: color-mix(in srgb, var(--accent) 22%, var(--border));
  background: var(--info-soft);
}

.staff-leave-kpi--next {
  background: var(--surface-raised);
}

.staff-leave-kpi-label {
  font-size: 0.68rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
}

.staff-leave-kpi-value {
  font-family: var(--font-data);
  font-size: 1.35rem;
  font-weight: 400;
  line-height: 1.15;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.staff-leave-kpi--pending .staff-leave-kpi-value {
  color: var(--accent);
}

.staff-leave-kpi-value--compact {
  font-size: 0.92rem;
  font-weight: 600;
  line-height: 1.35;
}

.staff-leave-kpi-value--muted {
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--muted);
}

.staff-leave-kpi-foot {
  margin-top: auto;
  font-size: 0.72rem;
  color: var(--muted);
  line-height: 1.35;
}

.staff-leave-breakdown {
  padding: 0.75rem 0.85rem;
  border-radius: 12px;
  border: 1px solid var(--border);
  background: var(--surface-raised);
}

.staff-leave-section-label {
  margin: 0 0 0.55rem;
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
}

.staff-leave-metrics {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 0.5rem 0.65rem;
  margin: 0;
}

.staff-leave-metric {
  margin: 0;
  min-width: 0;
}

.staff-leave-metric-label {
  margin: 0;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--muted);
  line-height: 1.3;
}

.staff-leave-metric-value {
  margin: 0.15rem 0 0;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--brand-navy);
  font-variant-numeric: tabular-nums;
}

.staff-leave-panels {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: 0.75rem;
  align-items: start;
}

.staff-leave-panel {
  padding: 0.75rem 0.85rem;
  border-radius: 12px;
  border: 1px solid var(--border);
  background: var(--card);
  min-height: 8rem;
}

.staff-leave-panel--timeline {
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
}

.staff-leave-empty {
  margin: 0.25rem 0 0;
  font-size: 0.84rem;
  color: var(--muted);
  line-height: 1.45;
}

.staff-leave-upcoming-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.staff-leave-upcoming-item {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 0.55rem;
  padding: 0.5rem 0.55rem;
  border-radius: 8px;
  background: var(--surface-raised);
  border: 1px solid transparent;
}

.staff-leave-upcoming-item:hover {
  border-color: color-mix(in srgb, var(--border) 70%, transparent);
  background: var(--fill);
}

.staff-leave-upcoming-status {
  width: 0.45rem;
  height: 0.45rem;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--ink-3);
}

.staff-leave-upcoming-status--confirmed {
  background: var(--accent);
}

.staff-leave-upcoming-status--tentative {
  background: var(--card);
  border: 2px solid var(--accent);
  box-sizing: border-box;
}

.staff-leave-upcoming-status--historical {
  background: var(--ink-2);
}

.staff-leave-upcoming-body {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  min-width: 0;
}

.staff-leave-upcoming-dates {
  font-size: 0.84rem;
  font-weight: 600;
  color: var(--brand-navy);
  line-height: 1.3;
}

.staff-leave-upcoming-meta {
  font-size: 0.72rem;
  color: var(--muted);
  line-height: 1.3;
}

.staff-leave-upcoming-days {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--brand-navy);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.staff-leave-minibar {
  padding: 0.55rem 0.15rem 0.15rem;
  border-radius: 10px;
  background: var(--surface-raised);
  border: 1px solid color-mix(in srgb, var(--border) 80%, transparent);
}

.staff-leave-minibar-months {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.25rem;
  margin-bottom: 0.45rem;
  font-size: 0.68rem;
  font-weight: 600;
  color: var(--muted);
  text-align: center;
}

.staff-leave-minibar-track {
  position: relative;
  height: 0.75rem;
  border-radius: 6px;
  background: var(--fill);
  overflow: hidden;
}

.staff-leave-minibar-seg {
  position: absolute;
  top: 1px;
  bottom: 1px;
  border-radius: 4px;
}

.staff-leave-legend {
  margin: 0;
  padding-top: 0.15rem;
  gap: 0.45rem 0.75rem;
  font-size: 0.68rem;
}

@media (max-width: 900px) {
  .staff-leave-kpi-row,
  .staff-leave-kpi-row--two {
    grid-template-columns: 1fr;
  }

  .staff-leave-metrics {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .staff-leave-panels {
    grid-template-columns: 1fr;
  }

  .staff-hub-directory-fields {
    grid-template-columns: minmax(6rem, 1fr) minmax(0, 3fr);
  }

  .staff-hub-directory-common-name,
  .staff-hub-directory-full-name {
    grid-column: auto;
  }
}

@media (max-width: 520px) {
  .staff-hub-directory-fields,
  .staff-profile-edit-form {
    grid-template-columns: 1fr;
  }

  .staff-hub-timeline-btn {
    width: 100%;
    text-align: center;
  }
}

/* Global HR dashboard (Roadmap Lot 13, admin-only). */
.dashboard-denied-card,
.dashboard-loading-card {
  padding: 1.5rem;
}

.dashboard-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1rem;
}

.dashboard-card {
  padding: 1rem 1.1rem;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.dashboard-card-title {
  margin: 0 0 0.15rem;
  font-size: 1.05rem;
}

.dashboard-kpi-value {
  margin: 0;
  font-family: var(--font-data);
  font-size: var(--text-stat);
  font-weight: 400;
  line-height: 1.1;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.dashboard-kpi-value--compact {
  font-size: 1.4rem;
}

.dashboard-kpi-value--danger {
  color: var(--danger);
}

.dashboard-kpi-value--warning {
  color: var(--warning);
}

.dashboard-kpi-label {
  margin: 0 0 0.5rem;
  font-size: 0.8rem;
  color: var(--muted);
}

.dashboard-kpi-row {
  display: flex;
  gap: 1.5rem;
  margin-bottom: 0.25rem;
}

.dashboard-section-label {
  margin: 0.5rem 0 0.4rem;
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
}

.dashboard-chip-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.dashboard-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.25rem 0.6rem;
  border-radius: 999px;
  background: var(--fill);
  font-size: 0.8rem;
}

.dashboard-chip-label {
  color: var(--text);
}

.dashboard-chip-value {
  font-weight: 600;
  color: var(--brand-navy);
}

.dashboard-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.dashboard-list-row {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  font-size: 0.85rem;
  line-height: 1.35;
}

.dashboard-list-link {
  color: var(--brand-navy);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}

.dashboard-list-link:hover {
  text-decoration: underline;
}

.dashboard-list-detail {
  color: var(--muted);
}

.dashboard-dot {
  flex: none;
  align-self: center;
  width: 8px;
  height: 8px;
  border-radius: 50%;
}

.dashboard-dot--expired {
  background: var(--error);
}

.dashboard-dot--soon {
  background: var(--warning);
}

.dashboard-empty {
  margin: 0;
  font-size: 0.85rem;
  color: var(--muted);
}

.dashboard-card-link {
  align-self: flex-start;
  margin-top: 0.4rem;
  font-size: 0.85rem;
  padding: 0.4rem 0.8rem;
}

/* ============================================================
   Printable planning view (/print.html, Lot 18)
   ============================================================ */

.print-page {
  background: var(--canvas);
}

.print-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.6rem 1.25rem;
  background: var(--card);
  border-bottom: 1px solid var(--border);
}

.print-back {
  color: var(--accent);
  font-size: var(--text-base);
}

.print-controls-middle {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.print-month-label {
  min-width: 5.2rem;
  text-align: center;
  font-size: var(--text-base);
}

.print-sheet {
  max-width: 1400px;
  margin: 1rem auto;
  padding: 1.25rem 1.5rem;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
}

.print-sheet-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.9rem;
}

.print-title {
  margin: 0;
  font-size: 1.15rem;
  letter-spacing: -0.01em;
}

.print-subtitle {
  margin: 0.15rem 0 0;
  color: var(--ink-2);
  font-size: var(--text-sm);
}

.print-meta {
  color: var(--ink-3);
  font-size: var(--text-xs);
}

.print-loading {
  color: var(--ink-2);
  padding: 1rem 0;
}

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

.print-grid th,
.print-grid td {
  border: 1px solid var(--border);
  padding: 0;
  height: 22px;
}

.print-name-head,
.print-name {
  width: 130px;
  padding: 0 6px !important;
  text-align: left;
  font-size: 11px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.print-name {
  font-weight: 500;
}

.print-day-head {
  text-align: center;
  font-size: 8.5px;
  line-height: 1.15;
  color: var(--ink-2);
  border-bottom: 1px solid var(--border-strong) !important;
}

.print-day-head .print-day-letter {
  display: block;
  font-weight: 400;
  color: var(--ink-3);
}

.print-day-head--saturday,
.print-cell--saturday {
  background: var(--brass-soft);
}

.print-day-head--today {
  color: var(--brass);
  font-weight: 600;
}

.print-cell--today {
  box-shadow: inset 2px 0 0 var(--brass);
}

.print-group-row td {
  background: var(--fill);
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-2);
  padding: 2px 6px !important;
}

.print-cell--vacation { background: var(--leave-vacation); }
.print-cell--sick { background: var(--leave-sick); }
.print-cell--emergency { background: var(--leave-emergency); }

.print-cell--unpaid {
  background: repeating-linear-gradient(45deg, var(--leave-unpaid) 0 3px, var(--card) 3px 6px);
}

/* Unclaimed off day — same hatch, washed out, so print keeps the same
   decision-vs-gap reading as the screen. */
.print-cell--absence {
  background: repeating-linear-gradient(
    45deg,
    color-mix(in srgb, var(--leave-unpaid) 32%, var(--card)) 0 3px,
    var(--card) 3px 6px
  );
}

.print-cell--departed {
  background: repeating-linear-gradient(45deg, var(--ink-3) 0 2px, var(--card) 2px 6px);
}

.print-cell--tentative {
  opacity: 0.55;
  background-image: repeating-linear-gradient(45deg, transparent 0 3px, var(--card) 3px 5px);
}

.print-legend {
  display: flex;
  gap: 1.1rem;
  flex-wrap: wrap;
  margin-top: 0.8rem;
  font-size: 11px;
  color: var(--ink-2);
}

.print-swatch {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 2px;
  margin-right: 5px;
  vertical-align: -2px;
  border: 1px solid var(--border);
}

.print-swatch--unpaid {
  background: repeating-linear-gradient(45deg, var(--leave-unpaid) 0 3px, var(--card) 3px 6px);
}

.print-swatch--absence {
  background: repeating-linear-gradient(
    45deg,
    color-mix(in srgb, var(--leave-unpaid) 32%, var(--card)) 0 3px,
    var(--card) 3px 6px
  );
}

.print-swatch--tentative {
  opacity: 0.55;
  background-image: repeating-linear-gradient(45deg, transparent 0 3px, var(--card) 3px 5px);
}

@page {
  size: A4 landscape;
  margin: 10mm;
}

@media print {
  .print-controls,
  #toast-container {
    display: none !important;
  }

  .print-page {
    background: #fff;
  }

  .print-sheet {
    max-width: none;
    margin: 0;
    padding: 0;
    border: none;
    border-radius: 0;
  }

  .print-grid th,
  .print-grid td {
    height: 18px;
    print-color-adjust: exact;
    -webkit-print-color-adjust: exact;
  }

  .print-group-row {
    break-inside: avoid;
  }

  .print-grid tr {
    break-inside: avoid;
  }
}

/* ============================================================
   Weekly crew lists (/crew.html, Lot 19)
   ============================================================ */

.crew-main {
  max-width: 1400px;
}

.crew-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: nowrap;
  gap: 0.75rem;
  padding: 0.55rem 1rem;
  margin-bottom: 0.9rem;
  position: relative;
}

@media (max-width: 1080px) {
  .crew-toolbar {
    flex-wrap: wrap;
  }
}

.crew-toolbar-week {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  min-width: 0;
}

.crew-week-label {
  font-size: var(--text-base);
}

.crew-status-chip {
  padding: 0.15rem 0.6rem;
  border-radius: 999px;
  font-size: var(--text-xs);
  font-weight: 500;
  background: var(--fill);
  color: var(--ink-2);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.crew-status-chip--final {
  background: var(--success-soft);
  color: var(--success);
}

.crew-meta {
  color: var(--ink-3);
  font-size: var(--text-xs);
}

.crew-toolbar-actions {
  display: flex;
  gap: 0.45rem;
  flex-wrap: wrap;
}

.crew-completeness {
  margin: 0 0 0.9rem;
  padding: 0.5rem 0.8rem;
  border-radius: var(--r-md);
  border: 1px solid var(--brass);
  background: var(--brass-soft);
  color: var(--ink);
  font-size: var(--text-sm);
}

.crew-columns {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 0.9rem;
  align-items: start;
}

.crew-column {
  padding: 0.9rem 1rem;
}

.crew-column--pool {
  background: var(--surface-raised);
}

.crew-column-title {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.6rem;
  font-size: var(--text-base);
  font-weight: 600;
}

.vessel-chip {
  display: inline-block;
  border-radius: var(--r-sm);
  padding: 2px 10px;
  font: 600 11px/1.6 var(--font-ui);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.vessel-chip--yin {
  background: var(--yin-bg);
  color: var(--yin-fg);
}

.vessel-chip--yang {
  background: var(--yang-bg);
  color: var(--yang-fg);
}

.crew-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.crew-empty {
  color: var(--ink-3);
  font-size: var(--text-sm);
  padding: 0.3rem 0;
}

.crew-chip {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--card);
}

.crew-chip--on-leave {
  opacity: 0.75;
  border-style: dashed;
}

/* Assigned rows are one compact line, sheet-style: name left,
   designation pushed to the right edge, remove button last. */
.crew-chip--assigned {
  flex-direction: row;
  align-items: center;
  gap: 0.45rem;
  padding: 0.25rem 0.45rem 0.25rem 0.6rem;
}

.crew-chip--assigned .crew-chip-designation,
.crew-chip--pool .crew-chip-main .crew-chip-designation {
  margin-left: auto;
  text-align: right;
  flex-shrink: 0;
}

.crew-chip--assigned .crew-assign-btn--remove {
  flex-shrink: 0;
}

/* Was not on this boat last week — light green card, the Excel convention. */
.crew-chip--changed {
  background: var(--success-soft);
}

/* Pool rows: name + designation on the first line, availability tags and
   the Yin/Yang buttons below. */
.crew-chip--pool .crew-chip-sub {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  flex-wrap: wrap;
}

.crew-chip-main {
  display: flex;
  align-items: baseline;
  gap: 0.45rem;
  flex-wrap: wrap;
}

.crew-chip-name {
  font-weight: 500;
  font-size: var(--text-base);
}

.crew-chip-designation {
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-3);
}

.crew-chip-badges {
  display: flex;
  gap: 0.3rem;
  flex-wrap: wrap;
}

.crew-chip-badges:empty {
  display: none;
}

.crew-badge {
  display: inline-block;
  padding: 0.1rem 0.45rem;
  border-radius: 999px;
  font-size: var(--text-2xs);
  font-weight: 500;
}

.crew-badge--leave {
  background: var(--error-soft);
  color: var(--error);
}

.crew-badge--returns {
  background: var(--leave-vacation-soft);
  color: var(--leave-vacation);
}

.crew-badge--pending {
  background: var(--brass-soft);
  color: var(--brass);
}

.crew-badge--starts {
  background: var(--success-soft);
  color: var(--success);
}

.crew-badge--last-day {
  background: var(--warning-soft);
  color: var(--warning);
}

/* Inactive in the directory, still on this saved week — a neutral fact about
   the record, not an alert: the plan is history and stays as it was. */
.crew-badge--inactive {
  background: var(--fill);
  color: var(--ink-2);
}

.crew-chip-actions {
  display: flex;
  gap: 0.3rem;
}

.crew-assign-btn {
  padding: 0.15rem 0.55rem;
  font-size: var(--text-xs);
  border-radius: var(--r-sm);
  border: 1px solid var(--border-strong);
  background: var(--card);
  color: var(--ink);
  cursor: pointer;
}

.crew-assign-btn:hover {
  background: var(--fill);
}

.crew-assign-btn--remove {
  color: var(--error);
  border-color: var(--error);
}

.crew-reset-btn {
  color: var(--error);
  border-color: var(--error);
}

/* Per-vessel cruise metadata inputs (tour + guest split). */
.crew-vessel-meta {
  display: flex;
  gap: 0.35rem;
  flex-wrap: nowrap;
  margin: -0.2rem 0 0.6rem;
}

.crew-meta-input {
  flex: 1;
  min-width: 0;
  width: auto;
  padding: 0.3rem 0.45rem;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--card);
  color: var(--ink);
  font-size: var(--text-sm);
}

.crew-meta-input::placeholder {
  color: var(--ink-3);
  font-family: var(--font-ui);
  font-size: var(--text-xs);
}

/* Numeric spinners eat half the field at this size. */
.crew-meta-input::-webkit-outer-spin-button,
.crew-meta-input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.crew-meta-input[type='number'] {
  -moz-appearance: textfield;
  appearance: textfield;
}

/* Distribution sheet — hidden on screen, this is the ONLY thing that prints. */
/* Month-end finalization — compact inline group in the command-bar actions row. */
.attendance-finalization {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.78rem;
  color: var(--ink-2);
}

.attendance-finalization[hidden] {
  display: none;
}

.attendance-final-chip {
  padding: 0.12rem 0.5rem;
  border-radius: 999px;
  background: var(--success-soft);
  color: var(--success);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.attendance-signoff-chip {
  display: inline-block;
  padding: 0.1rem 0.5rem;
  border-radius: 999px;
  background: var(--fill);
  color: var(--ink-2);
  font-size: 0.72rem;
  font-weight: 500;
  white-space: nowrap;
}

.crew-sheet {
  display: none;
}

.crew-sheet-title {
  margin: 0 0 5mm;
  font-size: 15pt;
  font-weight: 600;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.crew-sheet-boats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8mm;
  align-items: start;
}

.crew-sheet-boat-title {
  margin: 0;
  padding: 2mm 3mm;
  border-radius: 4px;
  font-size: 12pt;
  font-weight: 600;
}

.crew-sheet-boat--yang .crew-sheet-boat-title {
  background: #e9e0c6;
  color: #1b2432;
}

.crew-sheet-boat--yin .crew-sheet-boat-title {
  background: #0e2a47;
  color: #fdfbf4;
}

.crew-sheet-count {
  font-weight: 500;
  font-size: 10pt;
}

.crew-sheet-guests {
  margin: 1.5mm 0 0;
  font-size: 9.5pt;
  color: #5a6474;
}

.crew-sheet-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 2mm;
}

.crew-sheet-table td {
  padding: 1.4mm 1mm;
  border-bottom: 0.3pt solid #c8c2b2;
  font-size: 10pt;
}

.crew-sheet-name {
  font-weight: 500;
  color: #1b2432;
}

/* Was not on this boat last week — light green row, same convention as
   the old Excel sheet. Fixed palette, the shared sheet must not depend
   on the theme. */
.crew-sheet-row--changed td {
  background: #d9ead3;
}

.crew-sheet-note {
  margin: 4mm 0 0;
  font-size: 8.5pt;
  color: #5a6474;
}

.crew-sheet-note-swatch {
  display: inline-block;
  width: 8pt;
  height: 8pt;
  margin-right: 4px;
  vertical-align: -1pt;
  background: #d9ead3;
  border: 0.3pt solid #c8c2b2;
}

.crew-sheet-designation {
  text-align: right;
  font-size: 7.5pt;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #5a6474;
}

@media print {
  /* Only the distribution sheet prints — no app chrome, no page furniture. */
  .crew-page .navbar,
  .crew-page .crew-toolbar,
  .crew-page .crew-completeness,
  .crew-page .crew-columns,
  .crew-page #toast-container {
    display: none !important;
  }

  .crew-page {
    background: #fff;
  }

  .crew-page .crew-main {
    margin: 0;
    padding: 0;
    max-width: none;
  }

  .crew-page .crew-sheet {
    display: block;
    print-color-adjust: exact;
    -webkit-print-color-adjust: exact;
  }

  .crew-page .crew-sheet tr {
    break-inside: avoid;
  }
}

/* Keep the navbar on one line: tighter links, no wrapping. */
.navbar-links {
  flex-wrap: nowrap;
}

.navbar .nav-link {
  padding: 0.4rem 0.55rem;
  white-space: nowrap;
}

.navbar-brand {
  white-space: nowrap;
}

.navbar-user-label {
  font-size: 0.8rem;
}

@media (max-width: 1180px) {
  .navbar-brand {
    display: none;
  }
}

/* Crew week selection controls (calendar jump + saved plans menu).
   The date range button IS the calendar trigger; the input stays hidden. */
.crew-week-display {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.35rem 0.7rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  background: var(--card);
  color: var(--ink);
  font-family: var(--font-data);
  font-variant-numeric: tabular-nums;
  font-size: var(--text-sm);
  white-space: nowrap;
  cursor: pointer;
}

.crew-week-display:hover {
  background: var(--fill);
}

.crew-week-display svg {
  color: var(--ink-3);
  flex-shrink: 0;
}

.crew-week-input-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.crew-this-week-btn {
  padding: 0.3rem 0.7rem;
  font-size: var(--text-xs);
}

.crew-saved-plans {
  max-width: 12rem;
  padding: 0.3rem 0.5rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  background: var(--card);
  color: var(--ink);
  font-size: var(--text-xs);
}

/* Lot 20 — staff hub compliance */

/* Section labels grouping the (now longer) edit dialogs — the DESIGN.md
   uppercase 11px micro-label, with a hairline to separate groups. */
.staff-profile-edit-section {
  grid-column: 1 / -1;
  margin: 0.35rem 0 -0.35rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--border);
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
}

.staff-profile-edit-section-first {
  margin-top: 0;
  padding-top: 0;
  border-top: none;
}

/* Street address takes the full row of its group grid. */
.staff-profile-edit-contact .staff-profile-edit-span {
  grid-column: 1 / -1;
}

/* Both edit dialogs carry more fields since Lot 20 — a little more width
   keeps the two-column groups readable. */
.staff-profile-edit-dialog {
  max-width: 36rem;
}

/* Neutral "Missing" pill — missing data is a gap, not an emergency. */
.staff-hub-doc-badge-muted {
  color: var(--muted);
  background: var(--fill);
  border: 1px solid var(--border);
}

/* Address block in the Contact & employment card. */
.staff-hub-address-block {
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.5;
  overflow-wrap: anywhere;
}

.staff-hub-emergency-line {
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.5;
  overflow-wrap: anywhere;
}

.staff-hub-emergency-name {
  font-weight: 600;
}

.staff-hub-emergency-relation {
  color: var(--muted);
  font-size: 0.8rem;
  margin-right: 0.15rem;
}

/* "Admin only" tag next to the Family panel title. */
.staff-hub-admin-tag {
  display: inline-block;
  margin-left: 0.35rem;
  padding: 0.05rem 0.45rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--fill);
  font-size: 0.62rem;
  letter-spacing: 0.06em;
  color: var(--muted);
}

/* Card header: title left, Edit HR details right — the action is visible
   before reading the rows (owner feedback 2026-07-20). */
.staff-hub-compliance-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.35rem;
}

.staff-hub-compliance-header .staff-hub-section-title {
  margin-bottom: 0;
}

.staff-hub-flights-hint {
  margin: 0.3rem 0 0;
  font-size: 0.75rem;
}

.staff-hub-compliance-header .secondary {
  font-size: 0.8rem;
  padding: 0.35rem 0.75rem;
}

/* ============================================================
   Lot 20 delta — staff directory VISA / MEDICAL columns (admin)
   ============================================================ */

/* Widths active only while manage.js has inserted the two compliance cols:
   name 21→15, full name 29→20, designation 18→13, pending 12→7, active 13→11,
   actions 7→6 — plus 2 × 14% renewal columns = 100%. */
.staff-directory-table:has(.staff-col-compliance) .staff-col-name {
  width: 15%;
}

.staff-directory-table:has(.staff-col-compliance) .staff-col-full-name {
  width: 20%;
}

.staff-directory-table:has(.staff-col-compliance) .staff-col-designation {
  width: 13%;
}

.staff-directory-table:has(.staff-col-compliance) .staff-col-pending {
  width: 7%;
}

.staff-directory-table:has(.staff-col-compliance) .staff-col-active {
  width: 11%;
}

.staff-directory-table:has(.staff-col-compliance) .staff-col-actions {
  width: 6%;
}

.staff-directory-table .staff-col-compliance {
  width: 14%;
}

/* Renewal dates scan like a tide table: Plex Mono, right-aligned, color only
   when something needs attention (error past, warning within threshold). */
.staff-directory-table .compliance-date-col {
  text-align: right;
  white-space: nowrap;
}

/* The header centres over its column — right-aligned labels read as though
   they belong to the column on their left. The values stay right-aligned. */
.immigration-table thead th.compliance-date-col {
  text-align: center;
}

.staff-directory-table td.compliance-date-col {
  font-family: var(--font-data);
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
}

.staff-compliance-date--expired {
  color: var(--error);
  font-weight: 500;
}

.staff-compliance-date--soon {
  color: var(--warning);
  font-weight: 500;
}

/* Lot 21 — immigration workspace (/immigration.html). Same data-surface recipe
   as the staff directory, but carrying every column of the agent's report, so
   the table is wider than the viewport and scrolls inside .table-wrap. Fixed
   pixel widths (not percentages) keep the columns honest while it scrolls. */
.immigration-table {
  table-layout: fixed;
  min-width: 1720px;
  /* `separate`, not the inherited `collapse`: a collapsed table has no cell
     boxes of its own, so neither the frozen column's shadow nor the group
     rules paint. The attendance grid switches for the same reason. Spacing is
     zeroed so the rows still read as one continuous sheet, and the row rules
     move to the cells (a collapsed <tr> border does not survive either). */
  border-collapse: separate;
  border-spacing: 0;
  /* One type scale for the sheet: text cells inherit --text-base, the mono
     columns drop to --text-sm. Three sizes on one row read as three tables. */
  font-size: var(--text-base);
}

/* The controls sit in their own bar so the sheet below can scroll under a
   frozen header — the shape Attendance already uses. */
/* Full-viewport sheet, exactly as the attendance editor: the page itself does
   not scroll, only the table body does, so the header rows stay put and the
   sheet always reaches the bottom of the window instead of stopping at a fixed
   height with dead space under it. Scoped to the loaded page so the "loading"
   and "no access" cards keep the ordinary page flow. */
.immigration-page {
  padding: 0.4rem 0.75rem 0.5rem;
}

body:has(.immigration-page #immigration-content:not(.hidden)) {
  overflow: hidden;
  height: 100dvh;
  display: flex;
  flex-direction: column;
}

body:has(.immigration-page #immigration-content:not(.hidden)) .navbar {
  flex-shrink: 0;
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
}

body:has(.immigration-page #immigration-content:not(.hidden)) .immigration-page {
  flex: 1;
  min-height: 0;
  min-width: 0;
  width: 100%;
  max-width: 100%;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  margin: 0;
}

body:has(.immigration-page #immigration-content:not(.hidden)) #immigration-content {
  flex: 1;
  min-height: 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

body:has(.immigration-page #immigration-content:not(.hidden)) .immigration-command-bar {
  flex-shrink: 0;
  min-width: 0;
  max-width: 100%;
}

body:has(.immigration-page #immigration-content:not(.hidden)) .immigration-sheet {
  flex: 1;
  min-height: 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  margin-bottom: 0;
}

.immigration-command-bar {
  padding: 0.4rem 0.65rem;
  margin-bottom: 0.45rem;
}

.immigration-command-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.45rem 0.75rem;
}

.immigration-command-primary,
.immigration-command-secondary {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  min-width: 0;
}

/* Control sizing copied from the attendance command bar, not re-chosen: the
   page-default input is 39px tall against that bar's 28px, which by itself
   made this header sit a dozen pixels lower than the one it is meant to
   match. Same padding, same font size, same border treatment. */
.immigration-command-primary > input[type='search'] {
  width: 14rem;
  min-width: 0;
  max-width: 100%;
  padding: 0.35rem 0.55rem;
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  background: var(--card);
  font-size: 0.82rem;
}

.immigration-command-primary > input[type='search']:focus {
  outline: 2px solid var(--brand-navy);
  outline-offset: 0;
  border-color: var(--brand-navy);
}

.immigration-command-primary > select {
  width: auto;
  padding: 0.35rem 0.55rem;
  font-size: 0.82rem;
  font-weight: 600;
}

.immigration-sheet {
  padding: 0;
  overflow: hidden;
}

/* The sheet scrolls inside the card, so the header can stick to its top. It
   takes the height the flex column gives it rather than a `calc(100vh - …)`
   guess, which went stale as soon as anything above changed height. */
.immigration-table-wrap {
  flex: 1;
  min-height: 0;
  overflow: auto;
}

/* Frozen header, both tiers. The group row sits above the label row, so it
   takes the lower offset and the higher z-index goes to whatever also
   freezes horizontally (the name column). */
.immigration-table thead th {
  position: sticky;
  z-index: 2;
  background: var(--fill);
}

.immigration-table thead .immigration-group-row th {
  top: 0;
}

/* The label row pins directly below the group row. Its offset is the group
   row's measured height (`syncStickyHeaderOffset` sets the variable) — a
   hardcoded value leaves a gap at other font sizes, and body rows scroll
   through the gap. The fallback only has to be close. */
.immigration-table thead tr:last-child th {
  top: var(--immigration-group-height, 20px);
  box-shadow: 0 1px 0 var(--border-strong);
}

/* Group boundaries: a rule down the left edge of each document block, so the
   five blocks stay separable once the table has been scrolled sideways. */
.immigration-table th.immigration-group-start,
.immigration-table td.immigration-group-start {
  border-left: 1px solid var(--border-strong);
}

/* With `separate` borders the row rule has to live on the cells. */
.immigration-table tbody td {
  border-bottom: 1px solid var(--border);
}

.immigration-table thead th {
  border-bottom: none;
}

/* The name cell holds a flag dot beside the button, so it lays out as a row. */
.immigration-table td.immigration-sticky-col {
  display: flex;
  align-items: center;
}

.immigration-table {
  --immigration-col-1-width: 118px;
}

.immigration-table .immigration-col-name { width: var(--immigration-col-1-width); }
/* ~15 characters, then an ellipsis. A wrapped name doubles its row's height,
   and with a frozen name column beside it the short name already identifies
   the person; the full value stays in the title. */
.immigration-table .immigration-col-fullname { width: 168px; }
.immigration-table .immigration-col-ref { width: 118px; }
.immigration-table .immigration-col-state { width: 132px; }
.immigration-table .immigration-col-occupation { width: 168px; }
/* Wide enough for the longest rendered date ("27 Sep 2026") in Plex Mono —
   a clipped date is worse than no date, and these must never ellipsize. */
.immigration-table .immigration-col-date { width: 116px; }

/* Document grouping above the column labels — without it, three columns all
   called "Number" say nothing about which permit they belong to. */
.immigration-table .immigration-group {
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-2);
  text-align: left;
  padding-top: 0.35rem;
  padding-bottom: 0.05rem;
  border-bottom: 1px solid var(--border);
}

/* The staff block is context, not a document: no rule under it. */
.immigration-table .immigration-group--plain {
  color: var(--ink-3);
  border-bottom-color: transparent;
}

/* Every body cell stays on one line: with 16 columns a single wrapping value
   ("CRUISE DIRECTOR") would double the height of its row and break the scan.
   Long values ellipsize and tell the rest through their title attribute. */
.immigration-table tbody td {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.immigration-table .immigration-state,
.immigration-table .immigration-occupation {
  color: var(--ink-2);
}

/* Permit / visa / passport numbers: mono, so they can be compared character by
   character against whatever the agent has open beside this page. */
.immigration-table .immigration-ref {
  font-family: var(--font-data);
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* A date that is informational only (the permit fee) never takes a colour. */
.immigration-date--plain {
  color: var(--ink-2);
}

/* No name on file yet — muted, like every other unknown value on the row. */
.immigration-name--unknown {
  color: var(--ink-3);
}

/* A scan slot in the update dialog: what is on file, and what you can do. It
   sits inside the block of the document it belongs to, so it no longer has to
   name it ("Work permit scan" → "Scan") — the heading above already did. */
.immigration-file-row {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.4rem 0.5rem;
  margin-top: 0.15rem;
  padding-top: 0.5rem;
  border-top: 1px solid var(--border);
  font-size: var(--text-sm);
}

.immigration-file-label {
  flex: none;
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-3);
}

.immigration-file-state {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--ink);
}

.immigration-file-row.is-empty .immigration-file-state {
  color: var(--ink-3);
}

.immigration-file-actions {
  flex: none;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.immigration-file-actions .link-button {
  font-size: var(--text-xs);
}

.immigration-file-upload {
  padding: 0.15rem 0.5rem;
  font-size: var(--text-xs);
}

/* Archiving is destructive-shaped even though nothing is deleted, so it sits
   apart from the fields above rather than reading as one more of them. */
.immigration-archive-row {
  grid-column: 1 / -1;
  margin-top: 0.35rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--border);
}

.immigration-archive-toggle {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-size: var(--text-base);
  color: var(--ink);
  cursor: pointer;
}

.immigration-archive-toggle input {
  width: auto;
  margin: 0;
}

/* Report actions menu. The generic `.link-button` it used to borrow is an
   underlined 16px link: two of them wrapped onto four lines inside a 7rem
   popover and read as raw HTML rather than as part of the app. */
.immigration-menu {
  position: relative;
  display: inline-block;
}

.immigration-menu-trigger {
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: 1px solid transparent;
  border-radius: 6px;
  color: var(--ink-2);
  cursor: pointer;
  user-select: none;
}

.immigration-menu-trigger::-webkit-details-marker {
  display: none;
}

.immigration-menu-trigger:hover,
.immigration-menu[open] > .immigration-menu-trigger {
  background: var(--fill);
  border-color: var(--border-strong);
  color: var(--ink);
}

.immigration-menu-trigger:focus-visible {
  outline: 2px solid var(--brand-navy);
  outline-offset: 1px;
}

.immigration-menu-body {
  position: absolute;
  right: 0;
  z-index: 20;
  width: 17rem;
  margin-top: 0.3rem;
  padding: 0.25rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--card);
  box-shadow: 0 12px 32px rgba(27, 36, 50, 0.14);
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}

.immigration-menu-item {
  display: flex;
  flex-direction: column;
  /* Buttons carry `align-items: center` from the UA sheet, which centres both
     lines inside the popover instead of aligning them to its left edge. */
  align-items: flex-start;
  gap: 0.1rem;
  width: 100%;
  padding: 0.4rem 0.55rem;
  border: none;
  border-radius: 5px;
  background: none;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}

.immigration-menu-item:hover,
.immigration-menu-item:focus-visible {
  background: var(--surface-raised);
  outline: none;
}

.immigration-menu-label {
  font-size: var(--text-base);
  font-weight: 500;
  color: var(--ink);
}

/* Says which way the file travels — the one thing worth spelling out here. */
.immigration-menu-hint {
  font-size: var(--text-xs);
  line-height: 1.35;
  color: var(--ink-3);
}

/* Import preview — a plain, scannable account of what is about to happen. */
.immigration-import-body {
  max-height: 45vh;
  overflow-y: auto;
  margin: 0.5rem 0 1rem;
}

.immigration-import-summary {
  margin: 0 0 0.75rem;
  font-size: var(--text-base);
  color: var(--ink);
}

.immigration-import-heading {
  margin: 0.9rem 0 0.3rem;
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-2);
}

.immigration-import-heading.is-warning {
  color: var(--warning);
}

.immigration-import-list {
  margin: 0;
  padding-left: 1.1rem;
  font-size: var(--text-sm);
  color: var(--ink-2);
}

.immigration-import-list li {
  margin: 0.1rem 0;
}

/* An outstanding permit decision, flagged on the name: the standing column is
   gone, but this one is work waiting and has to stay visible. Warning tone,
   the same an approaching renewal uses — red stays for what has lapsed. */
.immigration-name-flag {
  display: inline-block;
  flex: none;
  width: 6px;
  height: 6px;
  margin-right: 0.35rem;
  border-radius: 50%;
  background: var(--warning);
}

/* Former staff: quiet throughout. Their papers are meant to have lapsed, so
   the dates stay legible for the record but carry no warning colour. */
.immigration-date--former {
  color: var(--ink-3);
}

.immigration-row--former td {
  color: var(--ink-3);
}

/* The name column freezes: the table is twice the viewport wide, and without
   it you lose track of whose row you are reading — and of the way into the
   record, which is the name itself. Same pattern as the attendance grid. */
/* Two frozen columns — name and name on permit — exactly the attendance
   grid's arrangement, down to the shadow: one soft drop on the right edge of
   the frozen block, nothing between the two columns inside it. The group
   header spans both, so the STAFF box and the frozen block end together
   instead of breaking mid-way. */
.immigration-table th.immigration-sticky-col,
.immigration-table td.immigration-sticky-col {
  position: sticky;
  left: 0;
  z-index: 3;
  background: var(--card);
}

.immigration-table thead th.immigration-sticky-col,
.immigration-table thead th.immigration-sticky-col-2 {
  background: var(--fill);
}

.immigration-table th.immigration-sticky-col-2,
.immigration-table td.immigration-sticky-col-2 {
  position: sticky;
  left: var(--immigration-col-1-width);
  z-index: 3;
  background: var(--card);
}

/* The right edge of the frozen block, wherever it falls. */
.immigration-table tbody .immigration-sticky-edge {
  box-shadow: 2px 0 5px rgba(15, 23, 42, 0.06);
}

.immigration-table thead th.immigration-sticky-col,
.immigration-table thead th.immigration-sticky-col-2 {
  z-index: 5;
}

/* The label row already carries the rule under the header, so the edge cell
   states both shadows — a second `box-shadow` would replace the first. */
.immigration-table thead tr:last-child th.immigration-sticky-edge {
  box-shadow: 0 1px 0 var(--border-strong), 2px 0 5px rgba(15, 23, 42, 0.08);
}

.immigration-table thead .immigration-group-row th.immigration-sticky-edge {
  box-shadow: 2px 0 5px rgba(15, 23, 42, 0.08);
}

/* A cell spanning both frozen columns must measure exactly their combined
   width, padding included, or the group header overhangs the block it labels. */
.immigration-table th,
.immigration-table td {
  box-sizing: border-box;
  /* 0.5rem sideways, as the attendance grid — the shared 0.75rem made these
     columns visibly airier than the sheet they sit beside in the nav. */
  padding-left: 0.5rem;
  padding-right: 0.5rem;
}

/* The opaque background above would otherwise swallow the row hover. */
.immigration-table tbody tr:hover td.immigration-sticky-col,
.immigration-table tbody tr:hover td.immigration-sticky-col-2 {
  background: var(--surface-raised);
}

/* The name IS the control that opens the record — styled as text, not as a
   button, so the column still reads as a column. */
.immigration-name-btn {
  all: unset;
  cursor: pointer;
  color: var(--accent);
  font: inherit;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  display: block;
}

.immigration-name-btn:hover {
  text-decoration: underline;
}

.immigration-name-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 3px;
}



/* Counts sit in the header row, next to the title — brass-free, ink by default
   and pigment only on the expired / expiring parts. */
.immigration-counts {
  font-family: var(--font-data);
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
}

/* Each figure is also the way to the names behind it. It has to stay reading
   as a counts line, not as a row of buttons, so the control is invisible until
   the pointer is on it — the affordance is the underline on hover, nothing
   more. Colour comes from the tone class the count already carried. */
.immigration-count-chip {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  cursor: pointer;
  border-radius: 0;
  text-decoration: underline;
  text-decoration-color: transparent;
  text-underline-offset: 3px;
  transition: text-decoration-color 150ms ease-out;
}

.immigration-count-chip:hover {
  text-decoration-color: currentColor;
}

.immigration-count-chip:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.immigration-count-sep {
  color: var(--ink-3);
  margin: 0 0.35rem;
}

/* The empty state is a sentence, not a data cell: it may wrap, and it is not
   subject to the single-line rule the rest of the body follows. */
.immigration-table td.immigration-empty {
  white-space: normal;
  overflow: visible;
  padding: 1rem 0.75rem;
  color: var(--ink-2);
  font-size: var(--text-base);
  max-width: 70ch;
}

.immigration-footnote {
  flex-shrink: 0;
  margin: 0.4rem 0 0;
  padding: 0 0.5rem 0.35rem;
  font-size: var(--text-xs);
  color: var(--ink-3);
}

/* Fourteen fields need more room than the 448px staff dialog. A <dialog> is
   shrink-to-fit, so an auto-fit grid inside it would keep collapsing to one
   column no matter how high max-width goes — set an explicit width instead. */
.immigration-dialog {
  width: 36rem;
  max-width: calc(100vw - 2rem);
  background: var(--card);
  color: var(--ink);
  /* The footer below pins itself to the bottom of the scrollport and carries
     its own bottom padding, so the dialog gives up its own: otherwise the bar
     and its resting place differ and it jumps at the end of the scroll. */
  padding-bottom: 0;
}

/* Who the record is, before any document. A rule under it, because the identity
   is the one thing on this screen that is not a field. */
.immigration-dialog-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.85rem;
  padding-bottom: 0.65rem;
  border-bottom: 1px solid var(--border-strong);
}

.immigration-dialog-title {
  margin: 0;
  font-size: var(--text-lg);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.immigration-dialog-sub {
  margin: 0.15rem 0 0;
  font-size: var(--text-xs);
  color: var(--ink-2);
}

/* Only shown when there is something to say — an ordinary crew member on the
   roster carries no chip at all. */
.immigration-dialog-standing {
  flex: none;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  background: var(--fill);
  color: var(--ink-2);
  font-size: var(--text-2xs);
  font-weight: 500;
  white-space: nowrap;
}

.immigration-dialog-standing.is-warning {
  background: var(--warning-soft);
  color: var(--warning);
}

.immigration-form {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin: 0;
}

/* One document per block. The dialog used to be a single flat grid with
   micro-labels floating in it, which put a permit number, a medical date and an
   archive checkbox at the same reading level. */
.immigration-section {
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--card);
}

.immigration-section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.4rem 0.8rem;
  border-bottom: 1px solid var(--border);
  border-radius: var(--r-md) var(--r-md) 0 0;
  background: var(--surface-raised);
}

.immigration-section-title {
  margin: 0;
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink);
}

/* The block's verdict, so a section can be judged before it is read. The dates
   themselves are in the fields below — this says what they mean. */
.immigration-section-status {
  font-family: var(--font-data);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.immigration-section-status.is-muted {
  color: var(--ink-3);
}

.immigration-section-body {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.65rem 0.8rem;
  padding: 0.7rem 0.8rem 0.75rem;
}

.immigration-field--full {
  grid-column: 1 / -1;
}

/* Two single-date documents side by side — neither fills a row of its own. */
.immigration-section-pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.75rem;
}

@media (max-width: 40rem) {
  .immigration-section-pair {
    grid-template-columns: 1fr;
  }
}

/* Labels drop to the quietest voice in the dialog: the section heading is the
   loud one, and the value in the field is what the eye should land on. */
.immigration-form label {
  margin-bottom: 0.2rem;
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--ink-2);
}

/* Spacing between fields is the grid's job now, not the input's. */
.immigration-dialog .immigration-form input,
.immigration-dialog .immigration-form select {
  margin-bottom: 0;
}

/* End of contract, seen by anyone who is not an admin: the company decides it,
   so the agent gets the facts and no controls. */
.immigration-readout-list {
  grid-column: 1 / -1;
  display: grid;
  gap: 0.3rem;
  margin: 0;
}

.immigration-readout-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
}

.immigration-readout-row dt {
  font-size: var(--text-xs);
  color: var(--ink-2);
}

.immigration-readout-row dd {
  margin: 0;
  font-size: var(--text-base);
  text-align: right;
  color: var(--ink);
}

.immigration-readout--unset {
  color: var(--ink-3);
}

.immigration-readout-todo {
  margin: 0.1rem 0 0;
  font-size: var(--text-xs);
  color: var(--warning);
  text-align: right;
}

.immigration-readout-empty {
  grid-column: 1 / -1;
  margin: 0;
  font-size: var(--text-base);
  color: var(--ink-2);
}

.immigration-readout-note {
  grid-column: 1 / -1;
  margin: 0.5rem 0 0;
  padding-top: 0.55rem;
  border-top: 1px solid var(--border);
  font-size: var(--text-xs);
  line-height: 1.45;
  color: var(--ink-2);
}

/* Pinned to the bottom of the dialog's scrollport and bled over the dialog's
   own side padding (1.35rem), so the bar spans edge to edge and no field
   scrolls through beside or beneath it. Six document blocks put Save a long
   way down otherwise. */
.immigration-dialog-actions {
  position: sticky;
  bottom: 0;
  z-index: 1;
  align-items: center;
  margin: 0.35rem -1.35rem 0;
  padding: 0.6rem 1.35rem 1.25rem;
  background: var(--card);
  border-top: 1px solid var(--border);
}

.immigration-dialog-footnote {
  margin-left: auto;
  font-size: var(--text-xs);
  color: var(--ink-3);
}

/* Lot 20 — staff hub compact Leave strip (replaces the full leave dashboard
   on the hub only; the attendance quick modal keeps the full panel). */
.staff-hub-leave-strip {
  display: flex;
  align-items: flex-start;
  gap: 1.5rem;
  flex-wrap: wrap;
}

.staff-hub-leave-strip .staff-hub-section-title {
  margin: 0;
  min-width: 8rem;
}

.staff-hub-leave-stats {
  display: flex;
  gap: 2.5rem;
  flex-wrap: wrap;
}

.staff-hub-leave-stat {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.staff-hub-leave-label {
  font-size: var(--text-2xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-2);
}

.staff-hub-leave-value {
  font-size: 1rem;
  color: var(--ink);
}

.staff-hub-leave-value.mono {
  font-family: var(--font-data);
  font-variant-numeric: tabular-nums;
}

.staff-hub-leave-muted {
  color: var(--ink-3);
}

.staff-hub-leave-foot {
  font-size: var(--text-xs);
  color: var(--ink-3);
}

/* Immigration compliance: two panels on one line, kept to a readable width
   instead of stretching across the whole card. */
.staff-hub-compliance-grid {
  grid-template-columns: repeat(auto-fit, minmax(15rem, 22rem));
}

/* Immigration panels: title line with a small inline Edit, and the in-place
   two-date edit form (owner decision 2026-07-20 — edit where the data lives). */
.staff-hub-panel-title-line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.staff-hub-panel-title-line .staff-profile-section-title {
  margin-bottom: 0;
}

.staff-hub-panel-edit-btn {
  font-size: 0.72rem;
  padding: 0.15rem 0.55rem;
}

.staff-hub-panel-edit-form {
  display: grid;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

.staff-hub-panel-edit-field {
  display: grid;
  grid-template-columns: 7rem 1fr;
  align-items: center;
  gap: 0.5rem;
  font-size: var(--text-xs);
  color: var(--ink-2);
}

.staff-hub-panel-edit-actions {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.25rem;
}

.staff-hub-panel-edit-actions button {
  font-size: 0.78rem;
  padding: 0.3rem 0.8rem;
}

/* Staff hub UX pass */

/* Edit profile dialog: modest widening so the two-column groups breathe. */
.staff-profile-edit-dialog {
  max-width: 40rem;
}

/* Bug fix: the admin-only wrapper is a plain div inside the form grid and
   used to collapse into a single narrow cell. It now spans the full form
   width, and its inner section labels + field groups lay out exactly like
   the manager sections (they carry the same grid-column: 1 / -1 rules). */
.staff-profile-edit-form #staff-edit-hr-sections {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.85rem;
}

/* The "Admin only" tag sits inline after the section label text — never
   broken across lines. */
.staff-hub-admin-tag {
  white-space: nowrap;
}

/* Narrow fallback: collapse the field groups (and the admin wrapper) to a
   single column together with the form itself. */
@media (max-width: 520px) {
  .staff-profile-edit-form .staff-profile-edit-contact,
  .staff-profile-edit-form #staff-edit-hr-sections {
    grid-template-columns: 1fr;
  }
}

/* Notes panel on the Contact & employment card — directory notes with the
   author's line breaks preserved. */
.staff-hub-notes-block {
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.5;
  white-space: pre-line;
  overflow-wrap: anywhere;
}

/* Staff hub: Leave + Flights share the top row; long values keep one line. */
.staff-hub-top-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(15rem, 20rem);
  gap: 1rem;
  align-items: stretch;
}

.staff-hub-top-row .staff-hub-card {
  margin: 0;
}

@media (max-width: 860px) {
  .staff-hub-top-row {
    grid-template-columns: 1fr;
  }
}

/* Detail rows never wrap: labels stay put, long values ellipsize on one
   line (full text remains readable in the edit dialog). */
.staff-hub-detail-row dt {
  flex: none;
  white-space: nowrap;
}

.staff-hub-detail-row dd {
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  overflow-wrap: normal;
}

/* One-line detail rows, properly: every level of the grid/flex chain must be
   allowed to shrink below its content (min-width: 0), otherwise nowrap text
   widens the panel and bleeds under the neighbouring card instead of
   ellipsizing. The full value stays available as a hover tooltip (set in
   staffPage.js). */
.staff-hub-contact-grid > .staff-profile-panel {
  min-width: 0;
}

.staff-hub-contact-grid .staff-hub-detail-list,
.staff-hub-contact-grid .staff-hub-detail-row {
  min-width: 0;
  max-width: 100%;
}

/* ============================================================
   Staff hub — readable field layout (owner feedback 2026-07-20)
   Cards are for READING: label above value, values get the full
   panel width and wrap on word boundaries — nothing truncates.
   ============================================================ */

/* Contact card only (the Immigration card keeps its tabular date rows):
   6-column grid, Identity double-width, history spans the full row. */
#staff-hub-contact-panel .staff-hub-contact-grid {
  grid-template-columns: repeat(6, minmax(0, 1fr));
}

#staff-hub-contact-panel .staff-profile-panel {
  grid-column: span 2;
  min-width: 0;
}

#staff-hub-contact-panel .staff-hub-panel--wide {
  grid-column: span 4;
}

#staff-hub-contact-panel .staff-hub-panel--full {
  grid-column: 1 / -1;
}

.staff-hub-field-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 0.65rem 1.25rem;
}

/* Vertical variant: one field per line (Contact, Key dates). */
.staff-hub-field-grid--stack {
  grid-template-columns: minmax(0, 1fr);
}

.staff-hub-field {
  min-width: 0;
}

.staff-hub-field-label {
  display: block;
  font-size: var(--text-xs);
  color: var(--muted);
  margin-bottom: 0.1rem;
}

.staff-hub-field-value {
  font-size: 0.875rem;
  color: var(--ink);
  overflow-wrap: break-word;
}

/* Tablet: two panels per row, Identity still full-width. */
@media (max-width: 980px) {
  #staff-hub-contact-panel .staff-hub-contact-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  #staff-hub-contact-panel .staff-profile-panel {
    grid-column: span 1;
  }
  #staff-hub-contact-panel .staff-hub-panel--wide,
  #staff-hub-contact-panel .staff-hub-panel--full {
    grid-column: 1 / -1;
  }
}

@media (max-width: 600px) {
  #staff-hub-contact-panel .staff-hub-contact-grid {
    grid-template-columns: 1fr;
  }
  #staff-hub-contact-panel .staff-profile-panel {
    grid-column: 1 / -1;
  }
}

/* ——— Edit profile: sticky save bar + unsaved-changes guard ——— */

/* The DIALOG stays the scroll container (its UA max-height + overflow), so the
   wheel scrolls the form from anywhere over the modal — title, footer and
   padding included. An inner scroller would leave those areas inert and chain
   the scroll to the page behind the modal instead.
   overscroll-behavior stops that chaining at the ends of the form too. */
.staff-profile-edit-dialog {
  overscroll-behavior: contain;
  /* The footer carries its own bottom padding and must end flush with the
     dialog, so the dialog's bottom padding and the form's bottom margin both
     go — otherwise the pinned bar and its resting place differ and it jumps
     at the end of the scroll. */
  padding-bottom: 0;
}

.staff-profile-edit-dialog .staff-profile-edit-form {
  margin-bottom: 0;
}

/* Pinned to the bottom of the dialog's scrollport, bled over the dialog's own
   padding (1.25rem 1.35rem) so the bar spans edge to edge and nothing scrolls
   through beside or beneath it. Its own padding-bottom replaces the dialog's
   and keeps the buttons clear of the edge. */
.staff-profile-edit-form .staff-profile-edit-footer {
  position: sticky;
  bottom: 0;
  z-index: 1;
  grid-column: 1 / -1;
  margin: 0.35rem -1.35rem 0;
  padding: 0.6rem 1.35rem 1.25rem;
  background: var(--card);
  border-top: 1px solid var(--border);
}

.staff-profile-edit-form .staff-profile-edit-footer .form-error {
  margin: 0 0 0.5rem;
}

.staff-profile-edit-form .staff-profile-edit-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0;
}

/* Quiet ochre marker — the form has changes that are not on the server yet.
   Not an error, so no clay/red per the red-discipline rule. */
.staff-profile-edit-dirty {
  margin-left: auto;
  font-size: 0.75rem;
  color: var(--warning);
}
